Should GMP 4.1+ and MPFR 2.2+ be needed when we're not building gfortran?

2006-11-06 Thread Doug Gregor

Hello,

The configure changes on the trunk require GMP 4.1+ and MPFR 2.2+. If  
I understand things correctly, these libraries are only needed for  
gfortran. Would it be possible to disable the checks for GMP and MPFR  
when building with --enable-languages=[something not including  
fortran] ?


Please CC me on any replies; I'm not on the main GCC list.

Cheers,
Doug


Re: Re: Canonical type nodes, or, comptypes considered harmful

2006-11-07 Thread Doug Gregor

On 11/7/06, Richard Kenner <[EMAIL PROTECTED]> wrote:

>   typedef int foo;
>   typedef foo* foo_p;
>
> In a truly canonical type-node environment, "foo" would have the same
> type node as "int" (so we couldn't produce the name "foo" in
> diagnostics), and "foo_p" would have the same type node as "int*".

But what about when you have multiple integer types that have the same
range?  Certainly you can't treat all of them as the same because they
have different alias sets and it's ciritical for efficient code generation
that this be the case.

Or would you consider these different types?


These are different types. For instance, "int" and "long" are distinct
types in C++, even if both map onto 32-bit integers.

 Cheers,
 Doug


Re: Canonical type nodes, or, comptypes considered harmful

2006-11-07 Thread Doug Gregor

On 11/7/06, Dale Johannesen <[EMAIL PROTECTED]> wrote:


On Nov 7, 2006, at 11:47 AM, Douglas Gregor wrote:

> I just read Nathan's discussion [1] on changing GCC's type system
> to use canonical type nodes, where the comparison between two types
> requires only a pointer comparison. Right now, we use "comptypes",
> which typically needs to do deep structural checks to determine if
> two types are equivalent, because we often clone _TYPE nodes.

One difficulty is that compatibility of types in C is not transitive,
especially when you're compiling more than one translation unit at a
time.
See the thread "IMA vs tree-ssa" in Feb-Mar 2004.  Geoff Keating and
Joseph Myers give good examples.


In that discussion, there was mention of submitting a defect report to
the C commit about this intransitivity. Has this defect report been
resolved?

 Cheers,
 Doug


Re: Re: Canonical type nodes, or, comptypes considered harmful

2006-11-07 Thread Doug Gregor

On 11/7/06, Mike Stump <[EMAIL PROTECTED]> wrote:

Anyway, in C++, the entire template mechanism was rife with building
up duplicates.  I'd propose that this problem can (and should be
addressed) and that we can do it incrementally.  Start with a hello
world, then in comptypes, check to see when it says yes, they are the
same, but the address equality checker says they might not be the
same, print a warning.  Fix the dup builders until no warnings.  Then
rebuild the world and repeat.  :-)  Work can be checked in, as dups
are eliminated.


It's a good plan.

Now, how much do we worry about the fact that we won't be printing
typedef names when we combine duplicate nodes? If we don't care, our
job is much easier. If we do care, then we need to introduce a system
for equivalence classes to keep those typedef names, which will
complicate matters a bit.


I did an extensive investigation in this area years ago, templates
were the worse offender at that time.   !=
 type stuff.


Templates also have the opposite problem, because they do some strange
sharing, e.g., X == X (where T1 and T2 are template type
parameters from different templates). It makes for some strange
diagnostics in ConceptGCC, but without concepts it doesn't seem
harmful.

Since we know that type canonicalization is incremental, could we work
toward type canonicalization in the GCC 4.3 time frame?

 Cheers,
 Doug


Re: Re: Canonical type nodes, or, comptypes considered harmful

2006-11-08 Thread Doug Gregor

On 11/8/06, Mike Stump <[EMAIL PROTECTED]> wrote:

On Nov 7, 2006, at 7:13 PM, Doug Gregor wrote:
> Now, how much do we worry about the fact that we won't be printing
> typedef names

The only potential language gotcha I can think of is:

5 If the typedef declaration defines an unnamed  class  (or  enum),  the
   first  typedef-name  declared by the declaration to be that class
type
   (or enum type) is used to denote the class type  (or  enum  type)
for
   linkage purposes only (_basic.link_).  [Example:
   typedef struct { } *ps, S;  // S is the class name for linkage
purposes
 --end example]

we still gotta get that right.  I think this just changes the
underlying type and doesn't have any typedef bits to it.


Right. If we want to remember that the struct { } was originally
anonymous, we could just set a flag on the RECORD_TYPE.


As for warning/error messages, I'd hate to regress on that front.
Doug, as a heavy template user, I'm sure you've see plenty of warning/
error messages...  How important is the typedef name in your experience?


As Benjamin said, it's very important, and we're not doing so well on
that front now. std::string is a particularly nasty case, because we
tend to print out the full template name rather than the typedef name.
Users would love us if we got this right :)


I agree, it will complicate things if we want the typedef name
around.  I'm thinking of an inverse mapping that takes us from tuple
(context,type) to typedef name.  I want to boost the typedef name
out, kinda like a flyweight pattern, but inverted, instead of
boosting the invariant out, I want to raise the variant (the typedef
name) out of the type.  Imagine if we had a map (tuple(context, type)
-> typedef name, and when we wanted the possible typedef name, we
take the type and the context in which we got the type and look it up
in the map.  If not found, no typedef name.  If found, it is the
typedef name we're interested in.  The benefit of this scheme would
be that constant time type equality operators remain constant time.
Producing error messages is slow, but we don't care about that.


Interesting idea; the constant time comparison could be win against
the almost-linear time we get with a union-find data structure.
However, this approach could have some odd side effects when there are
multiple mappings within one context. For instance, we could have
something like:

 typedef int foo_t;
 typedef int bar_t;

 foo_t* x = strlen("oops");

The error message that pops out would likely reference "bar_t *"
rather than "foo_t *" or "int *", because bar_t was the last mapping
from "int" that would be in the context. The example above is silly,
but when we're instantiating a template, it's common to have lots of
typedef names that all instantiate to the same type.

This approach wouldn't help with the implementation of concepts,
because we need to be able to take two distinct types (say, template
type parameters T and U) and consider them equivalent in the type
system. We can't literally combine T and U into a single canonical
type node, because they start out as different types. Granted, we
could layer a union-find implementation (that better supports
concepts) on top of this approach.

For reference, here's the union-find implementation: we add a new kind
of _TYPE node that is just a new name for an existing type. This new
type node (let's call it TYPE_ALIAS_TYPE) only contains two things: a
name and a pointer to the underlying type. Now, we use TYPE_ALIAS_TYPE
in the AST, but whenever we need to do some kind of structural check
on the tree node, we need to follow the chain of TYPE_ALIAS_TYPEs to
get to the canonical type node, which I would call the
"representative" of the equivalence class of types. Any code that does
something like:

 type = TREE_TYPE (exp);
 if (TREE_CODE (type) == REFERENCE_TYPE)
   type = TREE_TYPE (type);

would need to be modified to get the representation of "type" before
looking at its TREE_CODE, e.g.,

 type = type_representative (TREE_TYPE (exp));
 if (TREE_CODE (type) == REFERENCE_TYPE)
   type = TREE_TYPE (type);

We could find all of these places by "poisoning" TREE_CODE for
TYPE_ALIAS_TYPE nodes, then patch up the compiler to make the
appropriate type_representative calls. We'd want to save the original
type for diagnostics.

An alternative to poisoning TREE_CODE would be to have TREE_TYPE do
the mapping itself and have another macro to access the original
(named) type:

 #define TREE_TYPE(NODE) type_representative ((NODE)->common.type)
 #define TREE_ORIGINAL_TYPE(NODE) ((NODE)->common.type)

There are other macros like TREE_TYPE that would also need this
change, but TREE_TYPE should cover most of it.

When implementing concepts, *every* _TYPE node can have a
representative that is different from

Re: Canonical type nodes, or, comptypes considered harmful

2006-11-10 Thread Doug Gregor

On 11/9/06, Mike Stump <[EMAIL PROTECTED]> wrote:

On Nov 8, 2006, at 5:59 AM, Doug Gregor wrote:
> However, this approach could have some odd side effects when there are
> multiple mappings within one context. For instance, we could have
> something like:
>
>  typedef int foo_t;
>  typedef int bar_t;
>
>  foo_t* x = strlen("oops");

x is a decl, the decl has a type, the context of that instance of the
type is x.

map(int,x) == foo_t.

It is this, because we know that foo_x was used to create x and we
set map(int,x) equal to foo_t as it is created.


Ah, I understand now. When you wrote "context", I was thinking of some
coarse-grained approach to context, e.g., a scope or a block. With
variable-level granularity, your idea certainly works.


> The error message that pops out would likely reference "bar_t *"

map(int,x) doesn't yield bar_t.


Right, got it.


> We can't literally combine T and U into a single canonical
> type node, because they start out as different types.

?


To get a truly canonical type node, whenever we create a new type that
may be equivalent to an existing type, we need to find that existing
type node at the time that we create the new type, e.g.,

 typedef int foo_t;

When we create the decl for "foo_t", it's TREE_TYPE will be "int" (the
canonical type node) and with its context we know the name the user
wrote ("foo_t"). When we create "foo_t*", the idea is the same: find
the canonical type node (int*) and its context will till us the actual
type written ("foo_t *"). All the time, we're finding the canonical
type node for a particular type ("foo_t *") before we go and create a
new type node.

With concepts, there are cases where we end up creating two different
type nodes that we later find out should have been the same type node.
Here's an example:

 template
 where LessThanComparable && SameType
 const T& weird_min(const T& t, const U& u) {
   return t < u? t : u;
 }

When we parse the template header, we create two different type nodes
for T and U. Then we start parsing the where clause, and create a type
node for LessThanComparable. Now we hit the SameType requirement,
which says that T and U are the same type. It's a little late to make
T and U actually have the same type node (unless we want to re-parse
the template or re-write the AST).


> Granted, we could layer a union-find implementation (that better
> supports
> concepts) on top of this approach.

Ah, but once you break the fundamental quality that different
addresses implies different types, you limit things to structural
equality and that is slow.


Not necessarily. If you have an efficient way to map from a type to
its canonical type node, then you pay for that mapping but not for a
structural equality check. In a union-find data structure, the mapping
amounts to a bit of pointer chasing... but in most cases it's only one
pointer hop. Actually, without concepts we can guarantee that it's
only one pointer hop... with concepts, we need to keep a little more
information around in the AST and we sometimes have more than one
pointer hop to find the answer.

I already use a union-find data structure inside ConceptGCC, because I
don't have the option to map to a canonical type when type nodes are
initially created. But, since there are no canonical type nodes in GCC
now, I have to use a hash table that hashes based on structural
properties to keep track of the canonical type nodes. *Any* system
that gives us canonical type nodes in GCC would be a huge benefit for
ConceptGCC.

 Cheers,
 Doug


Re: Canonical type nodes, or, comptypes considered harmful

2006-11-10 Thread Doug Gregor

On 08 Nov 2006 03:45:26 +0100, Gabriel Dos Reis
<[EMAIL PROTECTED]> wrote:

[EMAIL PROTECTED] (Richard Kenner) writes:

| > Like when int and long have the same range on a platform?
| > The answer is they are different, even when they imply the same object
| > representation.
| >
| > The notion of unified type nodes is closer to syntax than semantics.
|
| I'm more than a little confused, then, as to what we are talking about
| canonicalizing.  We already have only one pointer to each type, for example.

yes, but it is not done systematically.  Furthermore, we don't unify
function types -- because for some reasons, it was decided they would
hold default arguments.


... and exception specifications, and some attributes that are really
meant to go on the declaration.

So, until we bring our types into line with C++'s type system, we're
going to have to retain some level of structural checking. Based on
Dale's suggestion, I'm inclined to add a new flag
"requires_structural_comparison" to every type. This will only be set
true for cases where either GCC's internal representation or the
language forces us into structural equality testing. For C++, I think
we're only forced into structural equality testing where GCC's
internal representation doesn't match C++'s view of type equality. For
C, it looks like array types like int[10] require structural equality
testing (but my understanding of the C type system is rather weak).

 Cheers,
 Doug


Re: Canonical type nodes, or, comptypes considered harmful

2006-11-10 Thread Doug Gregor

On 10 Nov 2006 19:15:45 +0100, Gabriel Dos Reis
<[EMAIL PROTECTED]> wrote:

"Doug Gregor" <[EMAIL PROTECTED]> writes:
| With concepts, there are cases where we end up creating two different
| type nodes that we later find out should have been the same type node.
| Here's an example:
|
|   template
|   where LessThanComparable && SameType
|   const T& weird_min(const T& t, const U& u) {
| return t < u? t : u;
|   }
|
| When we parse the template header, we create two different type nodes
| for T and U. Then we start parsing the where clause, and create a type
| node for LessThanComparable. Now we hit the SameType requirement,
| which says that T and U are the same type. It's a little late to make
| T and U actually have the same type node (unless we want to re-parse
| the template or re-write the AST).

I don't think that implies rewriting the AST or reparsing.  The
same-type constraints reads to me that "it is assume T and U have the
same canonical type", e.g. the predicate SameType translates to
the constraints

 TYPE_CANONICAL(T) == TYPE_CANONICAL(U)

this equation can be added the constraint set without reparsing (it is
a semantic constraint).


Yes, but there are types built from 'T' and 'U' that also need to be
"merged" in this way. For instance, say we have built the types T* and
U* before seeing that same-type constraint. Now, we also need
TYPE_CANONICAL (T*) == TYPE_CANONICAL (U*).
And TYPE_CANONICAL(LessThanComparable) ==
TYPE_CANONICAL(LessThanComparable).
If you know about all of these other types that have been built from T
and U, you can use Nelson and Oppen's algorithm to update the
TYPE_CANONICAL information relatively quickly. If you don't have that
information... you're stuck with structural checks or rewriting the
AST to eliminate the duplicated nodes.

 Cheers,
 Doug


Re: Canonical type nodes, or, comptypes considered harmful

2006-11-10 Thread Doug Gregor

On 10 Nov 2006 20:12:27 +0100, Gabriel Dos Reis
<[EMAIL PROTECTED]> wrote:

"Doug Gregor" <[EMAIL PROTECTED]> writes:
I don't see why you need to merge the types, as opposed to setting
their canonical types.


I have union-find on the mind, so I'm using the terms interchangeably.
Setting their canonical types to the same value merges the equivalence
classes of types.


| For instance, say we have built the types T* and
| U* before seeing that same-type constraint. Now, we also need
| TYPE_CANONICAL (T*) == TYPE_CANONICAL (U*).
| And TYPE_CANONICAL(LessThanComparable) ==
| TYPE_CANONICAL(LessThanComparable).
| If you know about all of these other types that have been built from T
| and U, you can use Nelson and Oppen's algorithm to update the
| TYPE_CANONICAL information relatively quickly. If you don't have that
| information...

In a template definition, one has that information.


?

Our same-type constraint says SameType.

We can easily set TYPE_CANONICAL for T and U.

We also need to set the TYPE_CANONICAL fields of LessThanComparable
and LessThanComparable to the same value.

How do we get from 'T' to 'LessThanComparable'?

 Cheers,
 Doug


Re: [PATCH] Re: Canonical type nodes, or, comptypes considered harmful

2006-11-27 Thread Doug Gregor

On 11/22/06, Mike Stump <[EMAIL PROTECTED]> wrote:

ensure if doesn't fall over, if you structure it that way, however,
if instead you just warn:

[snip code using warnings]

or even maybe just a note, it'll make it just a bit safer in the
short term.  People can then watch for these messages and report
them.  I've been known to do this type of code before and the warning
definitely was nicer as the complex cases came in after release in my
case.


I like the idea of making it a warning. To get the warning, of course,
we need to slow down compilation significantly to do the checking,
hence ENABLE_CHECKING. Now, one thing we need to keep in mind here is
that the failure mode is pretty bad when the canonical types are
wrong. I am concerned that, no matter how much code we cram through
with this checking enabled, we're going to miss some cases. Most
likely, we'll end up rejecting valid code that used to work; when
we're unlucky, we'll miscompile code that used to work. Ugh.

So, here's a variant that might just work: add a flag variable
flag_check_canonical_types.  When it's true, we do the complete
structural checking, verify it against the canonical types result, and
warn if they differ. (This is what we do now when
VERIFY_CANONICAL_TYPES is defined).

When it's false, we just use canonical types for fast comparison of types.

So, we pay for one extra branch in comptypes, but when we miscompile
the user's code we can tell them to add "-fcheck-canonical-types" to
their command line and report the resulting warnings. Their code will
now compile correctly (albeit with warnings, since we're using
structural type comparison), and the warnings will tell us what we
need to fix for the next version.

For the hook into --enable-checking, we use:

 int flag_check_canonical_types =
 #ifdef ENABLE_CHECKING
   1
 #else
   0
 #endif
 ;


Other than that, this looks like a nice step in the right direction,
thanks.


Thanks!

 Cheers,
 Doug


[PATCH] Canonical types (1/3)

2006-11-28 Thread Doug Gregor

This patch introduces canonical types into GCC, which allow us to
compare two types very efficiently and results in an overall
compile-time performance improvement. I have been seeing 3-5%
improvements in compile time on the G++ and libstdc++ test suites,
5-10% on template-heavy (but realistic) code in Boost, and up to 85%
improvement for extremely template-heavy metaprogramming.

Canonical types also make the GCC type system more regular.  In GCC,
we often create many different variants of the same type that are all
considered equivalent (e.g., comptypes returns true for both). For
instance, "int" and a typedef of "int" will have separate INTEGER_TYPE
nodes, but these will compare equal when we're performing type
checking. Unfortunately, we need to perform a deep comparison,
checking cv-qualifiers, attributes, precision, alignment,
etc. Canonical types add a new field to every type which points to a
representative of the equivalent class of types: all types in GCC that
are equivalent will point to the same canonical type, so we can use
the canonical types to quickly check type equivalence. Canonical types
were discussed in this thread:

 http://gcc.gnu.org/ml/gcc/2006-11/msg00192.html

This patch adds two new fields to every _TYPE, and maintains those
fields throughout the C, C++, Objective-C and Objective-C++ front
ends. The first field is TYPE_CANONICAL, which is the canonical type
of each type. The second field is TYPE_STRUCTURAL_EQUALITY: when this
bit is set, it means that TYPE_CANONICAL cannot be used reliably for
type equality checking, so we must perform structural tests. We use
TYPE_STRUCTURAL_EQUALITY when we create a new type node for which we
can't find the canonical type. Over time, we should work to eliminate
TYPE_STRUCTURAL_EQUALITY, because each case that requires it also
means that we're wasting memory for duplicated type nodes and wasting
cycles performing deep comparisons.

There is some danger in introducing canonical types: if we fail to
canonicalize properly, types won't compare equal when they should, and
we'll break code. To mitigate this problem, I have added a flags
-f(no-)check-canonical-types. When enabled, GCC will check the
canonical types against the structural types; where they differ, it
will print a warning and use the structural information. When
disabled, we only use canonical types... and get better compile-time
performance. Canonical type checking is disabled by default for normal
builds, enabled by default when --enable-checking is present. Note,
however, that this flag is temporary: after a major release or two,
when we're sure that we have our canonical type system, we can
eliminate it.

Bootstrapped C, C++, Objective-C, Objective-C++, Java on
i686-pc-linux-gnu. Tested C, C++, Objective-C, Objective-C++, and
libstdc++ test suites; no new regressions. I've spot-checked some
template-heavy Boost libraries; no regressions there, either.

This is part one of three, containing changes to the parts of the
compiler that are shared amount the C family of languages.

Okay for mainline?

 Cheers,
 Doug Gregor
 Open Systems Lab @ Indiana University

2006-11-28  Douglas Gregor  <[EMAIL PROTECTED]>

* builtins.c (std_gimplify_va_arg_expr): Keep track of the
canonical type when building a variant with a different alignment.
* c-common.c (flag_check_canonical_types): New.
(c_common_nodes_and_builtins): Since variants of void_type_node
get built before it is given a name, we need to give those
variants the name, too.
(handle_packed_attribute): When building the type variant, set the
canonical type appropriately.
(handle_unused_attribute): When building the type variant, set the
canonical type appropriately.
(handle_aligned_attribute): Ditto.
(handle_deprecated_attribute): Ditto.
(complete_array_type): We need to work with the canonical main
type of the array, from which we will build the qualified version.
* c-common.h (flag_check_canonical_types): New.
* c.opt (fcheck-canonical-types): New.
* c-opts.c (c_common_handle_option): Handle
-f(no-)check-canonical-types.
* print-tree.c (print_node): Display canonical type information
for each type.
* stor-layout.c (layout_type): When we don't know the
alignment of a type for which we're building an array, we end up
guessing wrong, so make the type require structural equality.
* tree.c (make_node_stat): When we build a new type, it is its
own canonical type.
(build_type_attribute_qual_variant): When building an attribute
variant, its canonical type is the non-attribute variant. However,
if the attributes are target-dependent and they differ, we need to
use structural equality checks for this type.
(build_qualified_type): Ditto.

[C++ PATCH] Canonical types (2/3)

2006-11-28 Thread Doug Gregor

This patch introduces canonical types into GCC; see the first part of
this patch for a complete description.

This is part two of three, containing changes to the C++ front end.

Okay for mainline?

 Cheers,
 Doug Gregor
 Open Systems Lab @ Indiana University

2006-11-28  Douglas Gregor  <[EMAIL PROTECTED]>

* typeck.c (structural_comptypes): Renamed from "comptypes".
(comptypes): Use canonical type information to perform fast type
comparison. When flag_check_canonical_types, verify that the
canonical type comparison returns the same results as we would see
from the current, structural check. Support COMPARE_STRUCTURAL
when we need structural checks.
* decl.c (typename_compare): Fix comment.
(build_typename_type): TYPENAME_TYPE nodes require structural
equality checks, because they resolve different based on the
current class type.
(make_unbound_class_template): UNBOUND_CLASS_TEMPLATE nodes
require structural equality checks (for now).
(build_ptrmemfunc_type): Build the canonical pointer to member
function type.
(compute_array_index_type): Whenever we build a new index type
to represent the size of an array in a template, we need to mark
this index type as requiring structural equality. This goes for
arrays with value-dependent sizes with the current ABI, or all
arrays with ABI-1.
* tree.c (cplus_array_hash): New.
(struct cplus_array_info): New.
(cplus_array_compare): New.
(cplus_array_htab): New.
(build_cplus_array_type_1): Use a hash table to cache the array
types we build. Build the canonical array type for each array
type.
(cp_build_qualified_type_real): When building a cv-qualified array
type, use the hash table of array types and build canonical array
types as necessary.
(bind_template_template_parm): BOUND_TEMPLATE_TEMPLATE_PARM nodes
use structural equality (for now).
(handle_java_interface_attribute): Keep track of the canonical
type.
* cp-tree.h (COMPARE_STRUCTURAL): New.
* pt.c (canonical_template_parms): New.
(canonical_type_parameter): New.
(process_template_parm): Find the canonical type parameter.
(lookup_template_class): When we have named the primary template
type, set the canonical type for our template class to the primary
template type. If any of the template arguments need structural
equality checks, the template class needs structural equality
checks.
(tsubst): When reducing the level of a template template
parameter, we require structural equality tests for the resulting
parameter because its template parameters have not had their types
canonicalized. When reducing a template type parameter, find the
canonical reduced type parameter.
(any_template_arguments_need_structural_equality_p): New.
* name-lookup.c (pushdecl_maybe_friend): When creating a new type
for a TYPE_DECL, make its canonical type the original type.
Index: typeck.c
===
--- typeck.c	(revision 119271)
+++ typeck.c	(working copy)
@@ -927,11 +927,10 @@ comp_array_types (tree t1, tree t2, bool
   return true;
 }
 
-/* Return true if T1 and T2 are related as allowed by STRICT.  STRICT
-   is a bitwise-or of the COMPARE_* flags.  */
+/* Subroutine in comptypes.  */
 
-bool
-comptypes (tree t1, tree t2, int strict)
+static bool
+structural_comptypes (tree t1, tree t2, int strict)
 {
   if (t1 == t2)
 return true;
@@ -1090,6 +1089,65 @@ comptypes (tree t1, tree t2, int strict)
   return targetm.comp_type_attributes (t1, t2);
 }
 
+/* Return true if T1 and T2 are related as allowed by STRICT.  STRICT
+   is a bitwise-or of the COMPARE_* flags.  */
+
+bool
+comptypes (tree t1, tree t2, int strict)
+{
+  if (strict == COMPARE_STRICT)
+{
+  bool result;
+
+  if (t1 == t2)
+	return true;
+
+  if (t1 == error_mark_node || t2 == error_mark_node)
+	return false;
+
+  if (TYPE_STRUCTURAL_EQUALITY (t1) || TYPE_STRUCTURAL_EQUALITY (t2))
+	/* At least one of the types requires structural equality, so
+	   perform a deep check. */
+	return structural_comptypes (t1, t2, strict);
+
+  if (flag_check_canonical_types)
+	{
+	  result = structural_comptypes (t1, t2, strict);
+
+	  if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
+	{
+	  /* The two types are structurally equivalent, but their
+		 canonical types were different. This is a failure of the
+		 canonical type propagation code.*/
+	  warning(0,
+		  "canonical types differ for identical types %T and %T", 
+		  t1, t2);
+	  debug_tree (t1);
+	  debug_tree (t2);
+	}
+	  else if (!result && TYPE_CANONICAL (t1) == TYPE_CA

[Objective-C PATCH] Canonical types (3/3)

2006-11-28 Thread Doug Gregor

This patch introduces canonical types into GCC. See the first part of
this patch for a complete explanation.

This is part three of three, containing changes to the Objective-C
(and, thus, Objective-C++) front end.

Okay for mainline?

 Cheers,
 Doug Gregor
 Open Systems Lab @ Indiana University

2006-11-28  Douglas Gregor  <[EMAIL PROTECTED]>

* objc-act.c (objc_build_volatilized_type): Keep track of
canonical types.
(objc_get_protocol_qualified_type): Ditto.
Index: objc-act.c
===
--- objc-act.c	(revision 119271)
+++ objc-act.c	(working copy)
@@ -908,6 +908,11 @@ objc_build_volatilized_type (tree type)
   t = build_variant_type_copy (type);
   TYPE_VOLATILE (t) = 1;
 
+  /* Set up the canonical type information. */
+  if (TYPE_CANONICAL (type) != type)
+TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
+  TYPE_STRUCTURAL_EQUALITY (t) = TYPE_STRUCTURAL_EQUALITY (type);
+
   return t;
 }
 
@@ -1364,13 +1369,26 @@ objc_get_protocol_qualified_type (tree i
 
   if (protocols)
 {
-  type = build_variant_type_copy (type);
+  tree orig_type = type;
+  type = build_variant_type_copy (orig_type);
+
+  /* Set up the canonical type information. */
+  TYPE_CANONICAL (type) = TYPE_CANONICAL (orig_type);
+  TYPE_STRUCTURAL_EQUALITY (type) = TYPE_STRUCTURAL_EQUALITY (orig_type);
 
   /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
 	 to the pointee.  */
   if (is_ptr)
 	{
-	  TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
+	  tree orig_pointee_type = TREE_TYPE (type);
+	  TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
+
+  /* Set up the canonical type information. */
+	  TYPE_CANONICAL (type) = 
+	TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
+	  TYPE_STRUCTURAL_EQUALITY (type) = 
+	TYPE_STRUCTURAL_EQUALITY (orig_pointee_type);
+
 	  TYPE_POINTER_TO (TREE_TYPE (type)) = type;
 	  type = TREE_TYPE (type);
 	}


We're out of tree codes: Now what?

2007-03-12 Thread Doug Gregor




We're out of tree codes; now what?

2007-03-12 Thread Doug Gregor

[This is a re-send of my previous e-mail; my apologies, yet again, for
the e-mail mangling on my end. Those responsible have been sacked.]

With the introduction of the variadic templates patch, we now have
more than 255 tree codes in GCC. This causes the mainline
Objective-C++ compiler to fail to build:

 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31134

We've known for a long time that we would eventually hit the limit on
the number of tree codes in GCC, and the variadic templates patch
happened to win the 8-bit tree-code lottery. Reverting the variadic
templates patch is not a solution: we'll hit this limit again, and
next time it will be with a feature that you find crucial. Reducing
the number of tree codes we use also seems infeasible: combining two
somewhat-similar entities into a single tree code is a short-term fix
with long-term problems, including poor readability and a greater
likelihood of bugs.

We need more tree codes. With GCC's current structure, that means
increasing the number of bits allocated for tree codes in the
tree_base struct. This will increase GCC's memory footprint. It's
unfortunate, but is it avoidable? I suspect it is not, without a major
restructuring of the compiler.

The patch below makes the CODE field of the tree_base struct 16 bits,
and adds suitable padding to fill out a 32-bit word. Elsewhere, the
limit on tree codes is raised to 512. Tested i686-pc-linux-gnu; no
regressions with C, C++, Objective C, Objective-C++, or Java.

Note: I've also sent this to gcc-patches, because there is a patch in
it. However, let's keep the discussion on [EMAIL PROTECTED]

 Cheers,
 Doug

:ADDPATCH C:

2007-03-12  Douglas Gregor  <[EMAIL PROTECTED]>

   * tree.c (tree_contains_struct): Permit 512 tree codes.
   * tree.h (tree_contains_struct): Ditto.
   (MAX_TREE_CODES): Ditto.
   (struct tree_base): Make CODE 16 bits, instead of 8 bits. Add
   SPARE member to store remaining padding bits.

Index: tree.c
===
--- tree.c  (revision 122840)
+++ tree.c  (working copy)
@@ -168,7 +168,7 @@ static unsigned int attribute_hash_list
tree global_trees[TI_MAX];
tree integer_types[itk_none];

-unsigned char tree_contains_struct[256][64];
+unsigned char tree_contains_struct[512][64];

/* Number of operands for each OpenMP clause.  */
unsigned const char omp_clause_num_ops[] =
Index: tree.h
===
--- tree.h  (revision 122840)
+++ tree.h  (working copy)
@@ -41,7 +41,7 @@ enum tree_code {

#undef DEFTREECODE

-extern unsigned char tree_contains_struct[256][64];
+extern unsigned char tree_contains_struct[512][64];
#define CODE_CONTAINS_STRUCT(CODE, STRUCT)
(tree_contains_struct[(CODE)][(STRUCT)])

/* Number of language-independent tree codes.  */
@@ -80,7 +80,7 @@ extern const char *const tree_code_class
#define TREE_CODE_CLASS_STRING(CLASS)\
tree_code_class_strings[(int) (CLASS)]

-#define MAX_TREE_CODES 256
+#define MAX_TREE_CODES 512
extern const enum tree_code_class tree_code_type[];
#define TREE_CODE_CLASS(CODE)  tree_code_type[(int) (CODE)]

@@ -363,7 +363,7 @@ union tree_ann_d;

struct tree_base GTY(())
{
-  ENUM_BITFIELD(tree_code) code : 8;
+  ENUM_BITFIELD(tree_code) code : 16;

  unsigned side_effects_flag : 1;
  unsigned constant_flag : 1;
@@ -392,6 +392,8 @@ struct tree_base GTY(())
  unsigned lang_flag_6 : 1;
  unsigned visited : 1;

+  unsigned spare : 24;
+
  /* FIXME tuples: Eventually, we need to move this somewhere external to
 the trees.  */
  union tree_ann_d *ann;


Re: We're out of tree codes; now what?

2007-03-12 Thread Doug Gregor

On 3/12/07, Steven Bosscher <[EMAIL PROTECTED]> wrote:

On 3/12/07, David Edelsohn <[EMAIL PROTECTED]> wrote:
> I thought that the Tuples conversion was suppose to address this
> in the long term.

The tuples conversion is only going to make things worse in the short term.

Doug, isn't there a lang_tree bit you can make available, and use it
to make the tree code field 9 bits wide?  I know this is also not
quite optimal,


It's going to have a big performance impact. To extract a 9-bit value,
the compiler will need to do a lot of masking every time it accesses
the TREE_CODE. We need the size of CODE to match the size of a
built-in integer type, which means we need to either expand the
structure or find 8 (!) free bits to shuffle.


but adding 24 bits like this is an invitation to
everyone to start using those bits, and before you know it we're stuck
with a larger-than-necessary tree structure... :-(


Yep, that's what got us where we are today. We said, "oh, we'll never
need more than 256 codes, let's use the other 24 bits for flags!"

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-12 Thread Doug Gregor

On 3/12/07, Mike Stump <[EMAIL PROTECTED]> wrote:

That said, we
all realize we are _not_ asking Doug to please re-implement the C++
frontend to our design to fix this issue.  I'd be against that.


Thank you :)


I'm hoping that might allow us to reduce the pressure enough so that
we can fit back down into 8 bits, so as to avoid the memory size
increase and (the unmeasured) slowdowns that would result.  Objective-
C/C++ would slow down, but, faced with the slowdown that would be
certain if we didn't do this, I don't see how we could not.  The
benefit, all other languages would not, which is still important to us.

The good news, in Objective-C 2.0, we only need 1 more tree code.

If we did do this, we'd have to put in a mandate, no more new tree
codes (unless you rewrite the Objective or C++ FE to stop using a code).


That's the trick... I don't see how we're going to get away with not
adding some more tree codes to the C++ FE to support C++0x features.

I'll see if I can implement the 9-bit solution, to see what the actual
performance impact is.

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-14 Thread Doug Gregor

Hi Mike,

[I'm replying in this thread to the Objective-C patch you posted in
the type-traits discussion, because both that post and this one are
about reducing the number of tree codes]

On 3/13/07, Mike Stump <[EMAIL PROTECTED]> wrote:

I just converted the Objective-C front-end to free up enough tree
codes so that Objective-C++ can compile again.  I know it can be
done.  If you want a new tree code, you can convert some other tree
code into a subcode. pick one one.


Thanks for doing this!


For ideas, please see the below patch.  I glanced at the C++ front
end, I see 8 tree codes (all the tcc_type codes) that you can reclaim
using the technique below.

For those that want to begin reviewing it, have at it, I'd be
interested in, do we even want to go in this direction (we don't have
hard numbers on the compile time costs yet, I don't think)?  If so,
any better way to do this in the short term?


Emboldened by your patch, I took a quick swing at introducing subcodes
for the simplest tcc_type node in the C++ front end - TYPEOF_TYPE. The
patch is attached. Here are some observations:

 - C++ already uses the LANG_TYPE tree code, although certainly not
the way it was intended: UNKNOWN_TYPE is #define'd to LANG_TYPE. This
is probably keeping Objective-C++ from working with your patch (I
didn't try it).

 - C++ already uses TYPE_LANG_SPECIFIC, for class types and for
pointers to member functions. Those are both based on RECORD_TYPE
nodes (ugh). That's okay: it turns out that we can use
TYPE_LANG_SPECIFIC for RECORD_TYPE nodes and LANG_TYPE nodes with no
problems whatsoever.

 - If C++ uses LANG_TYPE, and Objective C uses LANG_TYPE, we're
heading for a collision with Objective-C++. Either we'll need use
different top-level codes (LANG_TYPE vs. OBJC_LANG_TYPE, for example),
or we need to consolidate LANG_TYPE by making the subtype codes
extensible by Objective-C++ (just like normal tree codes are). The
latter seems like the right thing to do.

 - We're also heading toward collisions with lang_type_class, etc.,
but those are easy to fix.

 - It doesn't seem to happen in the Objective-C front end, but in the
C++ front end we have a lot of large switches on the TREE_CODE of a
type. With subcodes, these switches become very clunky. We go from
something like this:

 switch (TREE_CODE (t))
 {
   case TYPEOF_TYPE:
 /* Handle `typeof' */
 break;

   default:
 /* Default case */
 break;
 }

  to a two-level solution:

 switch (TREE_CODE (t))
 {
   case LANG_TYPE:
 switch (LANG_TYPE_SUBCODE (t))
 {
   case TYPEOF_TYPE_SUBCODE:
  /* Handle `typeof' */
  break;
   default:
 /* Default case. */
 break;
 }
break;

   default:
 /* Default case */
 break;
 }

Notice how I had to duplicate the code in the default case? The
situation gets worse when the TYPEOF_TYPE case was combined with other
cases (more duplication) or there was a fall-through either into or
out of the TYPEOF_TYPE case. The latter doesn't happen often with
TYPEOF_TYPE, but it does with other C++ _TYPE nodes.

While reviewing your Objective-C patch, the approach seemed very
clean. The data structures were more explicit than they are today (I
immediately started thinking, "hey, we could use this to shrink the
size of the common bits for types!"), and the few comparisons against
existing _TYPE nodes just because predicate checks.

Unfortunately, it doesn't look like the approach transfers well to the
C++ front end, where the two-level structure forced on us by subcodes
becomes unwieldy pretty quickly. I fear that the code duplication in
switch statements for default and fall-through cases is going to cause
maintenance headaches for a long time to come.

Still, please take a peek at the attached patch to decide for
yourself... I may have missed something obvious. The patch itself
doesn't actually save any nodes, because it introduces a real
UNKNOWN_TYPE node while removing the TYPEOF_TYPE node. But, it makes
TYPEOF_TYPE a subcode'd type, and the other tcc_type nodes (including
UNKNOWN_TYPE) could then be subcode'd for an actual savings. Browse
through the patch to see if the effort is well-spent.

My conclusion from this is that, even if we don't store it in
tree_base, we really, really want a TREE_CODE that is > 8 bits, or we
want *gasp* separate codes for tcc_type vs. tcc_expression. If it
doesn't work in a switch statement, it's not a viable solution for the
C++ front end.


Just FYI on your patch:

+struct lang_type_header GTY(()) {
+  BOOL_BITFIELD subcode : 3;
+};

That should be an ENUM_BITFIELD (subcode);

 Cheers,
 Doug
Index: cp-tree.def
===
--- cp-tree.def	(revision 122840)
+++ cp-tree.def	(working copy)
@@ -166,7 +166,7 @@ DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "te
 
 /* The ordering of the following codes

Re: We're out of tree codes; now what?

2007-03-14 Thread Doug Gregor

On 3/14/07, Richard Guenther <[EMAIL PROTECTED]> wrote:

#define LANG_TYPE_CODE (t) (TREE_CODE (t) == LANG_TYPE ?
LANG_TYPE_SUBCODE (t) : INVALID_SUBCODE)

and then INVALID_SUBCODE will fall through to the default case as well.


But that doesn't put the subcodes and the codes into the same
"namespace". We want to be able to write:

 switch (TREE_CODE (t))
 {
   case FUNCTION_TYPE:
 /* do something with function types. */
break;

   case TYPEOF_TYPE_SUBCODED:
 /* do something with TYPEOF_TYPE. */
break;
 }

even though FUNCTION_TYPE is (and will always be) a top-level tree
code, whereas TYPEOF_TYPE should be subcoded and stashed away in a
LANG_TYPE.

Of course, one could use TREE_CODE to see through the difference
between these two, e.g.,

 #define TREE_CODE(NODE)
   ((enum tree_code) (NODE)->base.code == LANG_TYPE?
   (enum tree_code)((TYPE_LANG_SPECIFIC (NODE)->base.subcode +
LAST_AND_UNUSED_TREE_CODE))
   : (enum tree_code) (NODE)->base.code)

Then, the opposite for TREE_SET_CODE:
 #define TREE_SET_CODE(NODE, VALUE)
((VALUE) >= LAST_AND_USED_TREE_CODE)?
   ((NODE)->base.code = LANG_TYPE, get_type_lang_specific
(NODE)->base.subcode = (VALUE) - LAST_AND_USED_TREE_CODE)
: ((NODE)->base.code = (VALUE))

Yuck.

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-19 Thread Doug Gregor

On 3/12/07, Richard Kenner <[EMAIL PROTECTED]> wrote:

> It's going to have a big performance impact. To extract a 9-bit value,
> the compiler will need to do a lot of masking every time it accesses
> the TREE_CODE.

"a lot masking" means at most two additional instructions, one if we
put it in the right place.  I'd be shocked if we could even measure
this, let alone be a "big" performance impact.


I went ahead and implemented this, to see what the real impact would
be. The following patch frees up TREE_LANG_FLAG_5, and uses that extra
bit for the tree code.

On tramp3d, memory usage remains the same (obviously), and the
performance results are not as bad as I had imagined:

8-bit tree code, --enable-checking:

real1m56.776s
user1m54.995s
sys 0m0.541s

9-bit tree code, --enable-checking:

real2m16.095s
user2m12.132s
sys 0m0.562s

8-bit tree code, --disable-checking:

real0m55.693s
user0m43.734s
sys 0m0.414s

9-bit tree code, --disable-checking:

real0m58.821s
user0m46.122s
sys 0m0.443s

So, about 16% slower with --enable-checking, 5% slower with --disable-checking.

Subcodes might still be the way to go, but I'm feeling less bad about
the 9-bit tree code option.

 Cheers,
 Doug

2007-03-19  Douglas Gregor  <[EMAIL PROTECTED]>

* java-tree.h (HAS_BEEN_ALREADY_PARSED_P): Move to TREE_PROTECTED.

2007-03-19  Douglas Gregor  <[EMAIL PROTECTED]>

* tree.c (tree_contains_struct): Support 512 tree codes.
* tree.h (tree_contains_struct): Ditto.
(MAX_TREE_CODES): We now support 512 tree codes.
(struct tree_base): Make "code" 9 bits, remove lang_flag_5.
(TREE_LANG_FLAG_5): Remove.
(BINFO_FLAG_5): Remove.
* print-tree.c (print_node): Don't print TREE_LANG_FLAG_5.

2007-03-19  Douglas Gregor  <[EMAIL PROTECTED]>

* cp-tree.h (C_IS_RESERVED_WORD): Move to TREE_PROTECTED.
(BINFO_PRIMARY_P): Move to BINFO_FLAG_6.
(DECL_VTABLE_OR_VTT_P): Move to nothrow_flag.

Index: java/java-tree.h
===
--- java/java-tree.h(revision 122993)
+++ java/java-tree.h(working copy)
@@ -48,7 +48,6 @@ struct JCF;
   3: HAS_FINALIZER (in RECORD_TYPE)
   4: IS_A_COMMAND_LINE_FILENAME_P (in IDENTIFIER_NODE)
  IS_ARRAY_LENGTH_ACCESS (in INDIRECT_REF)
-   5: HAS_BEEN_ALREADY_PARSED_P (in IDENTIFIER_NODE)
   6: CAN_COMPLETE_NORMALLY (in statement nodes)

   Usage of TYPE_LANG_FLAG_?:
@@ -1521,7 +1520,7 @@ extern tree *type_map;
#define IS_A_COMMAND_LINE_FILENAME_P(ID) TREE_LANG_FLAG_4 (ID)

/* True if filename ID has already been parsed */
-#define HAS_BEEN_ALREADY_PARSED_P(ID) TREE_LANG_FLAG_5 (ID)
+#define HAS_BEEN_ALREADY_PARSED_P(ID) TREE_PROTECTED (ID)

/* True if TYPE (a TREE_TYPE denoting a class type) was found to
   feature a finalizer method. */
Index: tree.c
===
--- tree.c  (revision 122993)
+++ tree.c  (working copy)
@@ -168,7 +168,7 @@ static unsigned int attribute_hash_list
tree global_trees[TI_MAX];
tree integer_types[itk_none];

-unsigned char tree_contains_struct[256][64];
+unsigned char tree_contains_struct[512][64];

/* Number of operands for each OpenMP clause.  */
unsigned const char omp_clause_num_ops[] =
Index: tree.h
===
--- tree.h  (revision 122993)
+++ tree.h  (working copy)
@@ -41,7 +41,7 @@ enum tree_code {

#undef DEFTREECODE

-extern unsigned char tree_contains_struct[256][64];
+extern unsigned char tree_contains_struct[512][64];
#define CODE_CONTAINS_STRUCT(CODE, STRUCT)
(tree_contains_struct[(CODE)][(STRUCT)])

/* Number of language-independent tree codes.  */
@@ -80,7 +80,7 @@ extern const char *const tree_code_class
#define TREE_CODE_CLASS_STRING(CLASS)\
tree_code_class_strings[(int) (CLASS)]

-#define MAX_TREE_CODES 256
+#define MAX_TREE_CODES 512
extern const enum tree_code_class tree_code_type[];
#define TREE_CODE_CLASS(CODE)   tree_code_type[(int) (CODE)]

@@ -363,7 +363,7 @@ union tree_ann_d;

struct tree_base GTY(())
{
-  ENUM_BITFIELD(tree_code) code : 8;
+  ENUM_BITFIELD(tree_code) code : 9;

  unsigned side_effects_flag : 1;
  unsigned constant_flag : 1;
@@ -388,7 +388,8 @@ struct tree_base GTY(())
  unsigned lang_flag_2 : 1;
  unsigned lang_flag_3 : 1;
  unsigned lang_flag_4 : 1;
-  unsigned lang_flag_5 : 1;
+  /* NOTE: lang_flag_5 is intentionally absent; it was been used for the 9th
+ bit of code.  */
  unsigned lang_flag_6 : 1;
  unsigned visited : 1;

@@ -485,6 +486,12 @@ struct gimple_stmt GTY(())
   CALL_FROM_THUNK_P in
   CALL_EXPR

+   C_IS_RESERVED_WORD in
+ IDENTIFIER_NODE (C++ only)
+
+   HAS_BEEN_ALREADY_PARSED_P in
+ IDENTIFIER_NODE (Java only)
+
   side_effects_flag:

   TREE_SIDE_EFFECTS in
@@ -549,6 +556,9 @@ struct gimple_stmt GTY(())
   TREE_THIS_NOTRAP in
  (ALIGN/MISA

Re: We're out of tree codes; now what?

2007-03-19 Thread Doug Gregor

On 3/19/07, Steven Bosscher <[EMAIL PROTECTED]> wrote:

On 3/19/07, Doug Gregor <[EMAIL PROTECTED]> wrote:
> I went ahead and implemented this, to see what the real impact would
> be. The following patch frees up TREE_LANG_FLAG_5, and uses that extra
> bit for the tree code.
>
> On tramp3d, memory usage remains the same (obviously), and the
> performance results are not as bad as I had imagined:
>
> 8-bit tree code, --enable-checking:
>
> real1m56.776s
> user1m54.995s
> sys 0m0.541s
>
> 9-bit tree code, --enable-checking:
>
> real2m16.095s
> user2m12.132s
> sys 0m0.562s
>
> 8-bit tree code, --disable-checking:
>
> real0m55.693s
> user0m43.734s
> sys 0m0.414s
>
> 9-bit tree code, --disable-checking:
>
> real0m58.821s
> user0m46.122s
> sys 0m0.443s
>
> So, about 16% slower with --enable-checking, 5% slower with 
--disable-checking.

Just because I'm curious and you have a built tree ready...  Does the
patch that Alex sent to gcc-patches the other day help reduce this 5%
penalty?

See the patch here:
http://gcc.gnu.org/ml/gcc-patches/2007-03/msg01234.html


Unfortunately, this patch doesn't bootstrap for me on i686-pc-linux-gnu:

/home/dgregor/Projects/mainlinegcc-build/./prev-gcc/xgcc
-B/home/dgregor/Projects/mainlinegcc-build/./prev-gcc/
-B/home/dgregor/Projects/mainlinegcc-install/i686-pc-linux-gnu/bin/
-I../../mainlinegcc/libcpp -I. -I../../mainlinegcc/libcpp/../include
-I../../mainlinegcc/libcpp/include  -O2 -g -fomit-frame-pointer -W
-Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes
-Wold-style-definition -Wmissing-format-attribute -pedantic
-Wno-long-long -Werror -I../../mainlinegcc/libcpp -I.
-I../../mainlinegcc/libcpp/../include
-I../../mainlinegcc/libcpp/include  -c -o expr.o -MT expr.o -MMD -MP
-MF .deps/expr.Po ../../mainlinegcc/libcpp/expr.c
../../mainlinegcc/libcpp/expr.c: In function '_cpp_parse_expr':
../../mainlinegcc/libcpp/expr.c:701: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See http://gcc.gnu.org/bugs.html> for instructions.


There are other bitfield optimization related bugs (Roger Sayle should
know more about those) that we can give a higher priority if we decide
to go with the 9 bit tree code field.  IMHO this is still the better
solution than the subcodes idea.


I strongly agree. Subcodes look like they'll either end up being
complicated (e.g., what I did with TYPEOF_TYPE as a subcode), slow
(the LANG_TREE_CODE option puts a branch into the equivalent of
TREE_CODE), or both.

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-19 Thread Doug Gregor

On 3/19/07, Nicholas Nethercote <[EMAIL PROTECTED]> wrote:

As an interested outsider:  GCC's compile-time speed has been gradually
decreasing for a while now.  It seems to be acknowledged as an undesirable
thing, but not much has happened to change it.  AIUI, this is largely
because it's very difficult.  Nonetheless, seeing a 5% slow-down caused by
fixing a data structure design bogon is disappointing.


GCC has also been getting improved functionality, better
optimizations, and better language support. Some of these improvements
are going to cost us at compile time, because better optimizations can
require more time, and today's languages require more work to compile
and optimize than yesterday's. No, I don't want my compiler to be 5%
slower, but I'll give up 5% for better standards conformance and
improved code generation.

It's not all bad news, either. Canonical types got us 3-5% speedup in
the C++ front end (more on template-heavy code), so I figure I have at
least a 3% speedup credit I can apply against the 9-bit code patch.
That brings this patch under 2% net slow-down, so we should just put
it in now :)

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-19 Thread Doug Gregor

On 19 Mar 2007 19:12:35 -0500, Gabriel Dos Reis <[EMAIL PROTECTED]> wrote:

similar justifications for yet another small% of slowdown have been
given routinely for over 5 years now.  small% build up; and when they
build up, they don't not to be convincing ;-)


But what is the solution? We can complain about performance all we
want (and we all love to do this), but without a plan to fix it we're
just wasting effort. Shall we reject every patch that causes a slow
down? Hold up releases if they are slower than their predecessors?
Stop work on extensions, optimizations, and bug fixes until we get our
compile-time performance back to some predetermined level?

We have hit a hard limit in the design of GCC. We need to either use
more memory, use more compilation time, re-architect non-trivial
portions of GCC, remove functionality, or come up with something very,
very clever. Pick one, but if the pick the last one, you have to
specify what "something very, very clever" is, because we seem to be
running short on ideas.

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-20 Thread Doug Gregor

On 3/20/07, Brooks Moses <[EMAIL PROTECTED]> wrote:

Steven Bosscher wrote:
> On 3/20/07, Mark Mitchell <[EMAIL PROTECTED]> wrote:
>>  I think it's fair for front ends to pay for their
>> largesse.  There are also relatively cheap changes in the C++ front end
>> to salvage a few codes, and postpone the day of reckoning.
>
> I think that day of reckoning will come very soon again, with more
> C++0x work, more autovect work, OpenMP 3.0, and the tuples and LTO
> projects, etc., all requiring more tree codes.

For that matter, does increasing the tree code limit to 512 codes
instead of 256 actually put off the day of reckoning enough to be worth it?


I think so. It took us, what, 10 years to go through 256 codes? Even
if we accelerate the pace of development significantly, we'll still
get a few years out of 512 codes. All the while, we should be hunting
to eliminate more of the "common" bits in tree_base (moving them into
more specific substructures, like decl_common), allowing the tree code
to increase in size. When we hit that 16-bit tree code, we'll get a
small bump in performance when all of the masking logic just
disappears. 16 bits is my goal, 9 bits is today's fix.

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-20 Thread Doug Gregor

On 3/20/07, Jakub Jelinek <[EMAIL PROTECTED]> wrote:

On Tue, Mar 20, 2007 at 08:56:10AM -0400, Kaveh R. GHAZI wrote:
> We've been considering two solutions, the 9 bit codes vs the subcode
> alternative.
>
> The 9 bit solution is considered simpler and without any memory penalty
> but slows down the compiler and doesn't increase the number of codes very
> much.  The subcodes solution increases memory usage (and possibly also
> slows down the compiler) and is more complex and changes are more
> pervasive.

But the subcodes approach would be only applied to the less often used
codes and ideally within the frontends only.


Even if we only use subcodes for the less often used codes, I think we
still take the performance hit. The problem is that it's very messy to
deal with a two-level code structure inside, e.g., the C++ front end.
I did a little experiment with a very rarely used tree code
(TYPEOF_TYPE), and the results weren't promising:

 http://gcc.gnu.org/ml/gcc/2007-03/msg00493.html

My conclusion was that, for maintainability reasons, we would need to
make the subcode approach look like there are no subcodes, by making a
LANG_TREE_CODE used in the front-ends that turns an 8-bit code and
optional 8-bit subcode into a 16-bit code. It's doable, but it's going
to have a non-trivial cost, certainly. And sooner or later, all of the
language-specific nodes will use subcodes, as the middle-end gets a
bigger and bigger share of the 256 codes we have.


So the memory hit shouldn't be
as big as e.g. going to 16 bit tree codes if that means increasing the size
of most of the trees the compiler uses.


Yes, this is true.

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-20 Thread Doug Gregor

On 3/20/07, Steven Bosscher <[EMAIL PROTECTED]> wrote:

On 3/20/07, Doug Gregor <[EMAIL PROTECTED]> wrote:
> > So the memory hit shouldn't be
> > as big as e.g. going to 16 bit tree codes if that means increasing the size
> > of most of the trees the compiler uses.
>
> Yes, this is true.

But this could be solved if all LANG_TREE_x bits could move to
language specific trees, could it?


Yes, absolutely.

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-20 Thread Doug Gregor

On 3/20/07, Kaveh R. GHAZI <[EMAIL PROTECTED]> wrote:

Would you please consider testing the 16 bit tree code as you did for 8 vs
9 bits?  Perhaps you could also measure memory usage for all three
solutions?


I've measured the 8 vs. 9-bit solutions: they have identical memory footprints.


 I think that would give us a complete picture to make an
informed decision.


Sorry, I thought I'd reported these numbers already. Here's a quick
summary for tramp3d:

8-bit codes: Total162M100M   1732k
16-bit codes: Total164M108M   1732k

Results of -fmem-report on i686-pc-linux-gnu follow.

 Cheers,
 Doug

8-bit tree codes (same with 9-bit tree codes):

Memory still allocated at the end of the compilation process
Size   AllocatedUsedOverhead
8   1780k487k 41k
16  2368k705k 37k
64  3384k   2168k 33k
128 1580k180k 13k
256  700k224k   5600
512  364k243k   2912
1024  52k 32k416
2048 116k104k928
4096  36k 36k288
8192  32k 32k128
16384 16k 16k 32
32768480k480k480
65536320k320k160
131072128k128k 32
262144512k512k 64
5227M 10M273k
44   720k194k   7200
104   31M 29M280k
92  1564k899k 13k
8015M 15M141k
88 10196k   5014k 89k
2419M 10M248k
48  1100k480k 10k
284 2676k   2203k 20k
72  1824k980k 16k
28  9504k   2516k111k
112 7664k   7444k 67k
32  8944k   5904k104k
12  7616k571k133k
40  7084k   3039k 76k
Total162M100M   1732k

String pool
entries 153082
identifiers 153082 (100.00%)
slots   262144
bytes   3817k (222k overhead)
table size  1024k
coll/search 0.9452
ins/search  0.2494
avg. entry  25.53 bytes (+/- 51.64)
longest entry   493

??? tree nodes created

(No per-node statistics)
Type hash: size 65521, 35719 elements, 1.118019 collisions
DECL_DEBUG_EXPR  hash: size 1021, 0 elements, 1.307168 collisions
DECL_VALUE_EXPR  hash: size 1021, 0 elements, 0.00 collisions
no search statistics
[EMAIL PROTECTED] Desktop]$ total: 432961 kB

16-bit tree codes:

Memory still allocated at the end of the compilation process
Size   AllocatedUsedOverhead
8   1748k487k 40k
16  2440k705k 38k
3213M   6664k167k
6422M 15M227k
128 1496k175k 13k
256  708k229k   5664
512  368k237k   2944
1024  48k 31k384
2048 112k104k896
4096  32k 32k256
8192  32k 32k128
16384 16k 16k 32
32768480k480k480
65536320k320k160
131072128k128k 32
262144512k512k 64
44  1936k741k 18k
108   33M 30M297k
96  1644k941k 14k
8418M 16M169k
92 10032k   4540k 88k
52  1888k743k 18k
284 2632k   2197k 20k
72  1748k988k 15k
2822M 12M273k
116 7948k   7711k 69k
36  5896k   2337k 63k
12  7256k571k127k
40  5400k   2375k 58k
Total164M108M   1732k

String pool
entries 153082
identifiers 153082 (100.00%)
slots   262144
bytes   3817k (222k overhead)
table size  1024k
coll/search 0.9452
ins/search  0.2494
avg. entry  25.53 bytes (+/- 51.64)
longest entry   493

??? tree nodes created

(No per-node statistics)
Type hash: size 65521, 35719 elements, 1.112485 collisions
DECL_DEBUG_EXPR  hash: size 251, 0 elements, 1.259857 collisions
DECL_VALUE_EXPR  hash: size 1021, 0 elements, 0.00 collisions
no search statistics
total: 452701 kB


Re: We're out of tree codes; now what?

2007-03-20 Thread Doug Gregor

On 3/20/07, Dan Nicolaescu <[EMAIL PROTECTED]> wrote:

"Doug Gregor" <[EMAIL PROTECTED]> writes:

  > On 3/20/07, Kaveh R. GHAZI <[EMAIL PROTECTED]> wrote:
  > > Would you please consider testing the 16 bit tree code as you did for 8 vs
  > > 9 bits?  Perhaps you could also measure memory usage for all three
  > > solutions?
  >
  > I've measured the 8 vs. 9-bit solutions: they have identical memory 
footprints.
  >
  > >  I think that would give us a complete picture to make an
  > > informed decision.
  >
  > Sorry, I thought I'd reported these numbers already. Here's a quick
  > summary for tramp3d:
  >
  > 8-bit codes: Total162M100M   1732k
  > 16-bit codes: Total164M108M   1732k

Unfortunately these stats do not reflect the actual memory use, this
is the memory that is still in use when the compilation process is
done. What you want is to compile gcc with
--enable-gather-detailed-mem-stats and then -fmem-report will give you
memory usage for all tree types.


I don't have time to do this right now, but as part of these tests I
used the little tool on the tramp3d page to determine the maximum
total virtual memory usage. It's not the complete information we want,
but it shows us a little more of the picture:

 8-bit codes: total: 432961 kB
 16-bit codes: total: 452701 kB

 Cheers,
 Doug


Re: SoC Project: Incremental Parsing (of C++)

2007-03-20 Thread Doug Gregor

On 20 Mar 2007 17:04:56 -0500, Gabriel Dos Reis <[EMAIL PROTECTED]> wrote:

That defered parsing might work with C (I don't really know), but it
certainly is problematic with C++ because there are bindings that
need to be in overload sets, and you cannot accurately capture those if
you don't parse the function bodies.  Sadly.


What if you were able to "roll back" name lookup, so that it was able
to resolve names as if it were at an earlier point in the translation
unit? If one were to, say, annotate declarations with their position
in the translation unit (line and column number, in the trivial case),
and then modify name lookup so that we could say, "find the name foo
as if we were looking from line number 50, column 3," it might be
possible to parse function bodies later on.

It seems feasible in principle; making it work is an entirely different matter.

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-21 Thread Doug Gregor

On 3/21/07, Mark Mitchell <[EMAIL PROTECTED]> wrote:

Yes, that's true.  Here, however, we have two paths in front of us:
9-bit tree codes, or some language-dependent subcodes.  The benefit of
9-bit tree codes is that they're easy to understand; the benefit of
subcodes is that they might be faster, but, then again, they might use
more memory.  I'd be interested in understanding the tradeoff.

> Subcodes require a bigger 'tree' data structure so there will be a
> memory usage hit, I don't think there's disagreement about that.

I thought the plan was to this in TYPE_LANG_SPECIFIC, etc., so that it's
not a generic effect on all trees?


I think this makes sense. All subcoded types would have their primary
TREE_CODE be LANG_TYPE. The subcode itself would live in
TYPE_LANG_SPECIFIC, along with any additional information we need for
that specific type node.

I suspect we would see a small increase in memory usage, because
subcoded types would have to allocate some memory for
TYPE_LANG_SPECIFIC to point at (it'll be only 4 bytes in most cases).
That said, the tree_type struct desperately needs refactoring, because
there are a lot of fields in there that I suspect aren't used by the
majority of types in the C++ front end, especially those that only
exist in templates (like TYPENAME_TYPE). Something akin to the DECL
hierarchy refactoring is needed.

I'll take a shot at an updated subcode implementation, since I already
have part of it working.

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-22 Thread Doug Gregor

On 3/22/07, Steven Bosscher <[EMAIL PROTECTED]> wrote:

On 3/22/07, Doug Gregor <[EMAIL PROTECTED]> wrote:
> The results, compile time:

For what test case?


All the numbers I've reported are for tramp3d, compiled with -O2
-funroll-loops -ffast-math on i686-pc-linux-gnu.


Did the 9-bit tree code include Alexandre Oliva's latest bitfield
optimization improvements patch
(http://gcc.gnu.org/ml/gcc-patches/2007-03/msg01397.html)?


It did not. Here are the 8-bit and 9-bit numbers with that patch:

--enable-bootstrap, --disable-checking, Alexandre's patch, 8-bit tree codes:

real0m51.815s
user0m41.282s
sys 0m0.470s

--enable-bootstrap, --disable-checking, Alexandre's patch, 9-bit tree codes:

real0m54.627s
user0m43.574s
sys 0m0.406s

Looks like a 1% improvement. Not bad, but not spectacular.


What about the 16-bit tree code?


I don't have these around, and I mistakenly updated my tree, so the
numbers below are, unfortunately, incomparable to the numbers above.
The disturbing fact is that mainline seems to be significantly slower
now than it was in my previous tests (from just a few days ago), and
the slowdown (20%) is much greater than any of the slowdowns we've
been discussing in this thread. Has anyone else noticed this, or
perhaps it's something in my environment?


Anyway, today's results for tramp3d, run a couple times until the
numbers stabilized:

8-bit tree code, --enable-bootstrap, --disable-checking:

real0m50.445s
user0m49.648s   baseline
sys 0m0.481s

9-bit tree code, ---enable-bootstrap, -disable-checking:

real0m53.550s
user0m52.645s6% slower
sys 0m0.477s

9-bit tree code, ---enable-bootstrap, -disable-checking, with
Alexandre's latest patch:

real0m52.787s
user0m52.304s5% slower
sys 0m0.464s

16-bit tree code, --enable-bootstrap, --disable-checking:

real0m50.965s
user0m50.315s1% slower
sys 0m0.477s

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-22 Thread Doug Gregor

On 3/22/07, Mark Mitchell <[EMAIL PROTECTED]> wrote:

Doug, thanks for doing all the experiments!

OK, we've got to pick our poison.

1. We can go to 9-bit codes.  They're slower, independent of checking.
Maybe we can make bitfields go faster, and get some of that back.  Of
course, if we can make bitfields go faster, GCC would probably still go
even faster with 8-bit codes than it will with 9-bit codes, since all
the other bitfield accesses in GCC will go faster.  The good news is
that this is simple, from a coding perspective, and probably uses no
more memory.

2. We can go to 16-bit codes.  They're slower than 8-bit codes, perhaps
because they use more memory, but not much -- and certainly seem less
slower than 9-bit codes.  This is just as simple, from a coding
perspective as (1).

3. We can go to subcodes.  These are no slower and use no less memory
for production compilers, but they make checking compilers unbelievably
slow.  (Frankly, I already find checking painful.  I run tests that way,
of course, but I'm always amazed how much faster release-branch
compilers go.)  They're complex.

I think I'm inclined to agree with Mike: I'm starting to prefer (2).
It's a simple solution, and pretty efficient.


I, too, prefer solution (2).

I'd like to tweak it in two ways:

 (a) We should put a comment in struct tree_base like the following:

 /* There are 24 remaining padding bits in this structure. DO NOT USE
THESE BITS.
 When we are able to remove 8 more bits, the size of all tree
nodes will shrink by
 one word, improving memory usage by ~4%.  */

 (b) We should accept the part of the 9-bit code patch that removes
lang_flag_5 from tree_base, and try to encourage movement away from
using the lang_flag_x bits in tree_base. One day, we'll kill all of
those bits and get our word back in tree_base, just like the comment
above says.

 Cheers,
 Doug


Re: We're out of tree codes; now what?

2007-03-23 Thread Doug Gregor

On 3/23/07, Kaveh R. GHAZI <[EMAIL PROTECTED]> wrote:

When I brought up the 16-bit option earlier, Jakub replied that x86 would
get hosed worse because it's 16-bit accesses are not as efficient as it's
8 or 32 bit ones.

http://gcc.gnu.org/ml/gcc/2007-03/msg00763.html

I assume you tested on Darwin?  Can you tell me if it was ppc or x86?


I tested on x86 (i686-pc-linux-gnu; processor is an Intel Core 2 Duo
E6600) and found a 1% slowdown with 16-bit codes vs. 8-bit codes.

 Cheers,
 Doug


Closing bugs in Bugzilla

2007-03-28 Thread Doug Gregor

Hello,

What is the protocol for confirming, taking ownership of, and closing
bug reports in Bugzilla? I'd like to close out some bugs for which
I've already committed the patches (20599 and 29993, at least) and
take ownership of several others, but I am unable to do anything but
comment on the bug reports.

 Cheers,
 Doug


Re: Closing bugs in Bugzilla

2007-03-28 Thread Doug Gregor

On 28 Mar 2007 07:21:13 -0700, Ian Lance Taylor <[EMAIL PROTECTED]> wrote:

> What is the protocol for confirming, taking ownership of, and closing
> bug reports in Bugzilla? I'd like to close out some bugs for which
> I've already committed the patches (20599 and 29993, at least) and
> take ownership of several others, but I am unable to do anything but
> comment on the bug reports.

If you sign up for bugzilla using your gcc.gnu.org e-mail address, you
will have the ability to close bug reports and make other changes.
This ability is reserved to people with gcc.gnu.org accounts.


Ah, I wasn't using my gcc.gnu.org address. Thank you!

 Cheers,
 Doug


[Announce] C++0x branch in GCC Subversion repository

2007-04-24 Thread Doug Gregor

Hello,

I have just created a new branch for development of C++0x-specific
features in the GNU C++ front end. The branch is branches/cxx0x-branch
in Subversion, and information about this branch is available at
http://gcc.gnu.org/projects/cxx0x.html.

The intent of this branch is to collect all of the C++0x features into
a single place, so that users of this branch can get a better feel for
the C++0x language and we can work on handling interactions among
C++0x features. Most implementations of C++0x features should still go
into mainline, when possible, but on the branch we have a little more
freedom to commit partially-implemented features.

Jason Merrill and I will maintain this branch. As features on this
branch mature, we hope to merge them into the mainline compiler under
the "experimental" C++0x mode.

 Cheers,
 Doug


C++ front end: NON_DEPENDENT_EXPR and lvalue_p_1

2007-04-26 Thread Doug Gregor

A question for the C++ maintainers considering the lvalue-ness of
NON_DEPENDENT_EXPR expressions...

As part of tightening up our checking of non-dependent expressions
within templates (and necessary step for C++0x, and a good idea in
C++98 anyway), I bumped into this bit of code in lvalue_p_1:

   case NON_DEPENDENT_EXPR:
 /* We must consider NON_DEPENDENT_EXPRs to be lvalues so that
 things like "&E" where "E" is an expression with a
 non-dependent type work. It is safe to be lenient because an
 error will be issued when the template is instantiated if "E"
 is not an lvalue.  */
 return clk_ordinary;

In C++98, it's okay to assume that any non-dependent expression is an
lvalue, because lvalues can be used anywhere where rvalues can be
used. As the comment says, the worst thing that happens is that we
issue a diagnostic late (at instantiation time), which we're allowed
to do.

C++0x changes things. First of all, we need to be able to fully
type-check non-dependent expressions within templates to make concepts
work properly, so it is no longer safe to be lenient here. A more
immediate concern is rvalue references: since you can now overload on
lvalues vs. rvalues, treating all NON_DEPENDENT_EXPRs as lvalues means
that we could end up picking the wrong overload when type-checking a
template. I don't have a test case on hand, but I'm pretty certain I
could create an error-on-valid-code inside a template. (I have one
such test case, but it currently relies on concepts).

Now, one cannot determine the lvalueness of a NON_DEPENDENT_EXPR from
its operand, because the operand is the tree that the parser has
produced, not the tree that has resulted from semantic analysis. And,
of course, the type of the NON_DEPENDENT_EXPR is only a type... it
doesn't contain lvalue or rvalue information.

So, I think the right answer is to add a field to NON_DEPENDENT_EXPR
that essentially caches the result of lvalue_p_1 for the expression it
represents. We'll need to know what the result of lvalue_p_1 is for
both treat_class_rvalues_as_lvalues true and false. The logic for this
can probably be built right into build_min_non_dep.

Does this seem like the right way to go?

 - Doug


Re: XML dump for GCC

2008-01-07 Thread Doug Gregor
Hello Brian,

How does this compare to GCC-XML?

  http://www.gccxml.org/HTML/Index.html

  - Doug

On Jan 4, 2008 10:42 AM, Brian M. Ames <[EMAIL PROTECTED]> wrote:
> Hello,
>
> I have substantially completed an extension that would allow dumps to be
> emitted as XML.  I would like to contribute it to the FSF for inclusion in
> the GCC distribution.  Please let me know if there is interest in this.
>
> Thanks,
>
> Brian M. Ames
>
>


Re: -Wparentheses lumps too much together

2008-01-11 Thread Doug Gregor
On Dec 19, 2007 3:02 PM,  <[EMAIL PROTECTED]> wrote:
> My specific candidate for exclusion from -Wall is this one:
>
> if (a && b || c && d)
>
> which yields (as you know) advice to parenthesize the two && pairs.

To make this discussion a bit more concrete, the attached patch
removes this particular warning from -Wparentheses and puts it into a
new warning, -Wprecedence, that is not enabled by -Wall. This is
slightly more fine-grained than what -Wparentheses does now. Opinions?

  - Doug

2008-01-11  Douglas Gregor  <[EMAIL PROTECTED]>

* invoke.texi: Document Wprecedence.

2008-01-11  Douglas Gregor  <[EMAIL PROTECTED]>

* gcc.dg/Wparentheses-1.c: Use -Wprecedence
* gcc.dg/Wparentheses-5.c: Ditto.
* g++.dg/warn/Wparentheses-8.C: Ditto.
* g++.dg/warn/Wparentheses-17.C: Ditto.
* g++.dg/warn/Wparentheses-5.C: Ditto.

2008-01-11  Douglas Gregor  <[EMAIL PROTECTED]>

* typeck.c (build_x_binary_op): Call warn_about_parentheses if
either warn_parentheses or warn_precedence.
(convert_for_assignment): Ditto.

2008-01-11  Douglas Gregor  <[EMAIL PROTECTED]>

* c.opt (Wprecedence): Add new warning category.
* c-typeck.c (parser_build_binary_op): Call warn_about_parentheses
if either warn_parentheses or warn_precedence.
(c-common.c): Use Wprecedence for the warning about && and ||.


Wprecedence.patch
Description: Binary data


may_alias attribute and type identity (PR c++/34935)

2008-01-24 Thread Doug Gregor
PR c++/34935 illustrates a problem with the way attributes interact
with type identity. The example in question looks something like this:

  typedef int X __attribute((may_alias));

  void foo(X);
  void foo(int);

The fundamental question here is whether 'X' is a new type distinct
from 'int', or whether 'X' is really just a typedef of 'int' that adds
the 'may_alias' attribute. The failure in PR c++/34935 comes from the
canonical types system having a different answer to this question than
the normal type-comparison function in the C++ front end
(structural_comptypes). Canonical types says that 'int' and 'X' are
the same type, which says that this code is fine: we're just declaring
the function "foo" twice in the same way. structural_comptypes says
that 'int' and 'X' are distinct types, which says that this code is
still fine... we're declaring two overloaded functions named "foo".
The oddity, for me, is that structural_comptypes isn't deciding that
'X' and 'int' are different because it's looking at attributes or
anything like that: it decides they are different because they have
different TYPE_MAIN_VARIANTs, and it doesn't bother to look at the
guts of the INTEGER_TYPE nodes to see that they are the same.

So, I *think* that structural_comptypes need to compare the guts of
INTEGER_TYPE nodes, but Richard Guenther's comment on the PR indicates
that it's canonical types that are wrong. Which one is it?

Note that this is pretty tied up with Mark Mitchell's discussion of
semantic and non-semantic attributes, here:

  http://gcc.gnu.org/ml/gcc/2006-10/msg00318.html

  - Doug


[C++ PATCH] Re: may_alias attribute and type identity (PR c++/34935, PR c++/34936)

2008-01-24 Thread Doug Gregor
On Jan 24, 2008 11:41 AM, Jakub Jelinek <[EMAIL PROTECTED]> wrote:
> On Thu, Jan 24, 2008 at 04:06:47PM +0100, Richard Guenther wrote:
> > On Jan 24, 2008 3:58 PM, Doug Gregor <[EMAIL PROTECTED]> wrote:
> > The middle-end type system (useless_type_conversion_p) says that
> > pointers to int and pointers to int __attribute__((may_alias)) are
> > distinct (you can't use one in place of the other without changning
> > semantics) - because the pointed to types have different alias sets.
> >
> > Now, for rvalues that doesn't matter, so indeed a value of type
> > int and a value of type int __attribute__((may_alias)) can be used
> > in place of each other.  So I stand corrected and they should indeed
> > have the same canonical type.
>
> See also http://gcc.gnu.org/PR34936.  Is int __attribute__((may_alias))
> supposed to be mangled the same as int?  And if so, it should for cp/call.c
> purposes be treated the same as well.

I just started venturing down this rabbit hole when I saw your note.
Since we previously ignored the may_alias attribute, we ended up
treating "int" and its may_alias typedef as identical nodes; that also
seems like the right answer from the perspective of C++, because I
think we want these types to mangle the same, act identical in
overload resolution, etc. However, both the mangler (PR 34936) and the
structural type checking routines (PR 34935) are unprepared for
attribute-qualified typedefs like these, because they depend on the
TYPE_MAIN_VARIANT being equivalent to one the predefined type nodes
(which isn't the case with attribute-qualified typedefs).

The canonical type system gets this right: it sees the types as
equivalent, and always gives us a path from the typedef'd,
attribute-qualified versions of types back to the predefined type
nodes (which are the canonical versions, by design). So, I'm fixing
both PRs by using canonical types. With 34935, we end up just relying
on canonical types to compare INTEGER_TYPE, FIXED_POINT_TYPE, and
REAL_TYPE nodes, because there's no other way to do it without
fundamentally changing how attribute-qualified typedefs are
represented. With 34936, we just map the builtin type down to its
canonical form, which will be one of the predefined type nodes.

The attached patch fixes both PRs. Regression tests are still running
on i686-pc-linux-gnu, but assuming no problems crop up... okay for
mainline?

  - Doug

2008-01-24  Douglas Gregor  <[EMAIL PROTECTED]>
Jakub Jelinek  <[EMAIL PROTECTED]>

PR c++/34935
PR c++/34936
* typeck.c (structural_comptypes): Handle comparisons of
VOID_TYPE, BOOLEAN_TYPE, INTEGER_TYPE, FIXED_POINT_TYPE, and
REAL_TYPE nodes.
* mangle.c (write_builtin_type): Map down to the canonical type,
which will be one of the predefined type nodes.

2008-01-24  Douglas Gregor  <[EMAIL PROTECTED]>
Jakub Jelinek  <[EMAIL PROTECTED]>

PR c++/34935
PR c++/34936
* g++.dg/ext/alias-canon.C: New.
* g++.dg/ext/alias-mangle.C: New.
Index: cp/typeck.c
===
--- cp/typeck.c	(revision 131778)
+++ cp/typeck.c	(working copy)
@@ -976,6 +976,30 @@ structural_comptypes (tree t1, tree t2, 
   /* Compare the types.  Break out if they could be the same.  */
   switch (TREE_CODE (t1))
 {
+case VOID_TYPE:
+case BOOLEAN_TYPE:
+  /* All void and bool types are the same.  */
+  break;
+
+case INTEGER_TYPE:
+case FIXED_POINT_TYPE:
+case REAL_TYPE:
+  /* With these nodes, we can't determine type equivalence by
+	 looking at what is stored in the nodes themselves, because
+	 two nodes might have different TYPE_MAIN_VARIANTs but still
+	 represent the same type.  For example, wchar_t and int could
+	 have the same properties (TYPE_PRECISION, TYPE_MIN_VALUE,
+	 TYPE_MAX_VALUE, etc.), but have different TYPE_MAIN_VARIANTs
+	 and are distinct types. On the other hand, int and the
+	 following typedef
+
+   typedef int INT __attribute((may_alias));
+
+	 have identical properties, different TYPE_MAIN_VARIANTs, but
+	 represent the same type.  The canonical type system keeps
+	 track of equivalence in this case, so we fall back on it.  */
+  return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
+
 case TEMPLATE_TEMPLATE_PARM:
 case BOUND_TEMPLATE_TEMPLATE_PARM:
   if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
Index: cp/mangle.c
===
--- cp/mangle.c	(revision 131778)
+++ cp/mangle.c	(working copy)
@@ -1768,6 +1768,9 @@ write_CV_qualifiers_for_type (const tree
 static void
 write_builtin_type (tree type)
 {
+  if (TYPE_CANONICAL (type))
+type = TYPE_CANONICAL (type);
+
   switch (TREE_CODE (type))
 {
 

Re: c++0x concepts in gcc call

2008-01-25 Thread Doug Gregor
On Jan 21, 2008 8:08 PM, Benjamin Kosnik <[EMAIL PROTECTED]> wrote:
> Jason Merrill, Doug Gregor, and I invite all interested GCC hackers to
> discuss implementation of the compiler and library parts of the
> C++0x concepts proposals. This is to be a brainstorming session, where
> we discuss the best way to complete the work, what can be taken from
> existing branches, and how to smoothly transition between a
> concept-enabled standard library and the current libstdc++.

Some notes from the discussion in this call:

Organization:
 - We'll start a fresh branch in the FSF repository dedicated to concepts
   (it's branches/cxx0x-concepts-branch). Initially, Doug and Jason
   will be maintainers of this branch
 - We want to minimize the distance between this branch and mainline:
   * All non-concepts C++0x features will still go into mainline
   (unless they depend on concepts)
   * Type-checking of constrained templates depends on improved
   type-checking of C++98 templates (particularly, checking of
   non-dependent expressions), so we'll try to do all of this work in
   mainline
   * Doug will merge from mainline to branch regularly
 - Will salvage what we can from ConceptGCC: concept-checking,
   archetype generation, and parsing bits will be useful; type-checking
   of constrained templates needs to be reworked significantly.
 - We're not going to commit to any schedule, but it'll be a multi-year effort
 - We're going to delay any decisions about library issues for
   now. They won't matter until the front end supports enough of concepts
   to permit their use in the library

C++ front end:
 - Concepts representation:
* Concepts, concept maps will be RECORD_TYPEs to reuse as much of
  that logic as is possible
* Archetypes will probably need their own, new tree nodes
 - Same-type constraints and mapping to archetypes caused a lot of
   trouble in ConceptGCC: canonical types could simplify this
 - Constrained templates will create many new nodes in the internal
   representation that don't need to be around after a constrained
   template is type-checked; we might need to consider a stricter memory
   management scheme
 - Performance of the generated code was a problem with ConceptGCC,
   which Doug blames on the inliner. We should consider a limited form of
   inlining in the instantiation of constrained templates to avoid
   swamping the inliner with the forwarding functions in constrained
   templates.

For more information about the concepts branch, see
http://gcc.gnu.org/projects/cxx0x.html#concepts

For more information about ConceptGCC, see
http://www.generic-programming.org/software/ConceptGCC/

  - Doug


Re: c++0x concepts in gcc call

2008-01-27 Thread Doug Gregor
On Jan 27, 2008 8:23 PM, Gerald Pfeifer <[EMAIL PROTECTED]> wrote:
> On Fri, 25 Jan 2008, Doug Gregor wrote:
> > Organization:
> >  - We'll start a fresh branch in the FSF repository dedicated to concepts
> >(it's branches/cxx0x-concepts-branch). Initially, Doug and Jason
> >will be maintainers of this branch
>
> Thanks for documenting this in svn.html!  Just one quip: in the patch
> you documented this new branch but removed the reference to the old
> cxx0x-branch.
>
> Shouldn't that be moved to the "Inactive Development Branches" instead?

I was planning to kill the cxx0x-branch outright, because it has
nothing that isn't available on mainline (except a not-nearly-complete
delegating constructors implementation), and will not be used. If this
would be better handled by moving the entry to "Inactive Development
Branches", I'll certainly do that. But there isn't really anything of
value in the cxx0x-branch to keep around.

  - Doug


Re: GCC 4.3.0 Status Report (2008-01-28)

2008-01-28 Thread Doug Gregor
On Mon, Jan 28, 2008 at 5:22 AM, Richard Guenther <[EMAIL PROTECTED]> wrote:
>
>  Status
>  ==
>
>  We are in Stage 3 and the trunk is open for regression and documentation
>  fixes only.  When we reach zero open P1 regressions, we will create a
>  release candidate for 4.3.0, branch and announce the opening of Stage 1
>  for 4.4.

The may_alias patch here

  http://gcc.gnu.org/ml/gcc-patches/2008-01/msg01161.html

fixes a regression against older versions of GCC (pre-4.0) along with
another problem (that we never got right before). The regression
itself will only show up under --enable-checking, so this is one of
those low-risk, low-reward patches. But, it's simple and it fixes two
PRs. Okay to commit?

  - Doug


Re: c++0x concepts in gcc call

2008-01-29 Thread Doug Gregor
On Mon, Jan 28, 2008 at 5:38 PM, Gerald Pfeifer <[EMAIL PROTECTED]> wrote:
> On Sun, 27 Jan 2008, Doug Gregor wrote:
>  > I was planning to kill the cxx0x-branch outright, because it has
>  > nothing that isn't available on mainline (except a not-nearly-complete
>  > delegating constructors implementation), and will not be used. If this
>  > would be better handled by moving the entry to "Inactive Development
>  > Branches", I'll certainly do that.
>
>  Yes, for historical reasons it would be nice to have that branch
>  documented there, with a note that/when it was merged into mainline
>  as for some of the other examples there.

Okay, done.

>  Gerald
>
>  PS: Nice patch of yours that fixes seven PRs at once. :-)

Now it's nine PRs :)

  - Doug

Index: svn.html
N===
RCS file: /cvs/gcc/wwwdocs/htdocs/svn.html,v
retrieving revision 1.73
diff -u -r1.73 svn.html
--- svn.html28 Jan 2008 15:19:04 -  1.73
+++ svn.html29 Jan 2008 17:37:47 -
@@ -779,7 +779,12 @@
 [EMAIL PROTECTED]>
   

-
+  cxx0x-branch
+  This branch was for developed of C++0x features, and all
+  features developed on this branch have been merged to
+  mainline. Future C++0x features will be developed against mainline
+  or, in the case of concepts, on
+  the cxx0x-concepts-branch.
 

 


Re: GCC 4.3 branch created, 4.4 opens for stage1

2008-02-18 Thread Doug Gregor
On Feb 18, 2008 6:18 PM, Jakub Jelinek <[EMAIL PROTECTED]> wrote:
> Hi!
>
> As I've mentioned last week, I've created branches/gcc-4_3-branch.
> The trunk is now 4.4 stage 1, the branch is open for regression bugfixes
> and documentation fixes only, but additionally all checkings require
> RM approval in addition to normal approval.
> Before the release candidate is cut, it would be good to fix the 4 P1
> bugs we have now:
> PR34950 - Jason/Mark, could you help with this?  It is 4.2/4.3
>   regression, so perhaps doesn't need to hold the rc
> PR35218 - I believe the latest patch worked for the tester,
>   so we now have a patch and just need an approval?
> PR35232 - I'm not sure I'm comfortable with a big reload patch
>   this late
> PR35239 - Rask, do you have a patch for this?
> and:
> libjava bootstrap problem on i?86-darwin8* - can anyone who can reproduce
>   it please try 
> http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00265.html
>   ? Can we have a bugzilla bug for it?
> ppc-linux -maltivec stuff - assuming a solution is agreed on quickly
>
> Anything else I'm forgetting?

I'd love to get the fix for c++/35022 into this release. It's a
regression marked as an ice-on-invalid, but slight variations on that
test show several issues with variadic templates. The patch is here:

  http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00575.html

The fix itself will only affect code when we're in C++0x mode, so it's
very low-risk. With this fix, nearly all of the non-error-recovery
issues with variadic templates will have been solved, so we'll have a
pretty solid start at C++0x out there for people to start working
with.

  - Doug


Google Summer of Code 2008

2008-03-03 Thread Doug Gregor
I see that it is time to submit applications to be a mentor
organization for the Google Summer of Code. I've updated the GSoC wiki
page at:

  http://gcc.gnu.org/wiki/SummerOfCode

with a class of projects I'm interested in; others should do the same.

I'll be happy to mentor C++0x projects for GCC, should any
applications for those projects come in.

Who is responsible for actually submitting GCC's application to GSoC,
and who has done so in the past?

  - Doug


Google Summer of Code 2008

2008-03-03 Thread Doug Gregor
I see that it is time to submit applications to be a mentor
organization for the Google Summer of Code. I've updated the GSoC wiki
page at:

  http://gcc.gnu.org/wiki/SummerOfCode

with a class of projects I'm interested in; others should do the same.

I'll be happy to mentor C++0x projects for GCC, should any
applications for those projects come in.

Who is responsible for actually submitting GCC's application to GSoC,
and who has done so in the past?

  - Doug


Re: C++0x rvalue references get clobbered somehow

2008-03-19 Thread Doug Gregor
Hello,

On Wed, Mar 19, 2008 at 4:23 AM, Lukas Mai <[EMAIL PROTECTED]> wrote:
>  I'm having problems with g++-4.3.0 and C++0x. Disclaimer: I don't
>  understand rvalue references, but since I need (indirect) argument
>  forwarding, I copied and modified an example from the web.
>  (I believe detail_region::fw is equivalent to std::forward.)
>
>  Here's (a simplified version of) my code. Details like destructors,
>  dynamic memory management, etc are gone; it's just generic object
>  construction.
[snip code]
>
>  This code works fine (and prints 123) when compiled with
>  g++ -std=c++0x -O2 (or -Os or -O). However, without optimization
>  it produces output like -1207981096. This number changes if
>  different function calls are used at the location marked XXX.
>
>  Somehow args.head loses its value between construction (in alloc)
>  and use (in capply), but only if optimizations are not enabled.
>
>  I think args.head should be bound to the temporary value 123,
>  which should stay alive until the next statement. But something
>  seems to overwrite it before p is initialized.

I think you've tripped across a bug in the C++0x standard. GCC is
implementing exactly what the C++0x standard currently says, but
that's not what we want rvalue references to do :)

The issue, I believe, is that when forwarding built-in types like
integers, the compiler will end up making extra temporaries... and
tuple::head will end up being bound to a temporary that doesn't
live long enough for your code to work (at -O0). This issue is being
tracked as GCC bug 34022, here:

  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34022

But the important part is that it is core issue 664 for C++0x, tracked here:

  http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#664

Current status: the Core Working Group of the C++ committee agrees
that there is a problem, and what the general solution is, but we
don't yet have the wording to update the C++ standard (and, then, GCC)
to fix the problem. Note that, if I tweak your example to use the
following test case, it works (because we don't make more temporaries
of class type; just of built-in types):

struct X {
  X(int value ) : value(value) {}

  int value;
};

int main() {
   using awesome::region;

   region r;
   X *p = r.alloc(X(123));
   cout << p->value << '\n';
}

  - Doug


Re: Question regarding C++ frontend

2008-05-03 Thread Doug Gregor
On Fri, May 2, 2008 at 11:39 AM, Peter Collingbourne <[EMAIL PROTECTED]> wrote:
>  In the C++ frontend, record_types maintain list(s) of the parameters
>  which were used to instantiate the type, one list for each "level" of
>  the instantiation.  I would like to know how to determine the list of
>  parameters that were used to instantiate "this" type e.g. in the case of
>  a type foo::bar I would like the tree_vec containing the type
>  "long".  Note that we can't always simply extract the last list of
>  parameters e.g. for the type foo::baz the tree_vec required would
>  be empty or null whereas the tree_vec available has a single level for
>  "int".

INNERMOST_TEMPLATE_ARGS can be used to get at the "innermost" TREE_VEC
of template arguments for a class template specialzation such as
foo::bar. CLASSTYPE_USE_TEMPLATE != 0 tells you whether a
RECORD_TYPE is actually a template

  - Doug


Re: gcc-in-cxx branch created

2008-06-18 Thread Doug Gregor
On Wed, Jun 18, 2008 at 2:01 AM, Ian Lance Taylor <[EMAIL PROTECTED]> wrote:
> As I promised at the summit today, I have created the branch
> gcc-in-cxx (I originally said gcc-in-c++, but I decided that it was
> better to avoid possible meta-characters).  The goal of this branch is
> to develop a version of gcc which is compiled with C++.  Here are my
> presentation slides in PDF format: http://airs.com/ian/cxx-slides.pdf .

I, personally, think this would be a great step forward from a
maintainability perspective, especially if we use those C++ features
that can help eliminate many of the macros we currently have in GCC.

The first step seems to be to make sure that GCC compiles as C++ now
(I know there's been work in this direction), and for us to make sure
that this property is maintained in the mainline compiler. The C++
front end would be a good place to start moving toward C++.

  - Doug


Re: gcc-in-cxx: Garbage Collecting STL Containers

2008-06-25 Thread Doug Gregor
On Wed, Jun 25, 2008 at 10:49 AM, Tom Tromey <[EMAIL PROTECTED]> wrote:
>> "Daniel" == Daniel Jacobowitz <[EMAIL PROTECTED]> writes:
>
>>> On Wed, Jun 25, 2008 at 08:35:41AM -0600, Tom Tromey wrote:
>>> I think most of the needed changes will be in gengtype.  If you aren't
>>> familiar with what this does, read gcc/doc/gty.texi.
>
> Daniel> Also - I may regret saying this but - doesn't gengtype have a
> Daniel> simplistic C parser in it?  How upset is it likely to get on C++
> Daniel> input?
>
> Yeah, it does -- see gengtype-parse.c.
> I haven't done extensive hacking there; I don't really know how upset
> it will be.  I assume it won't work the first time :)

It turns out that we already have a parser capable of handling C++...
why not just build gengtype on top of the C++ front end?

  - Doug


Re: New branch for STL Advisor

2008-07-14 Thread Doug Gregor
On Mon, Jul 14, 2008 at 7:20 PM, Benjamin Kosnik <[EMAIL PROTECTED]> wrote:
> In particular, design. The using bits seem pretty straightforward. It
> would be nice if you could provide some detail in terms of scope (what
> are the algorithms or data structures you intend to instrument),
> and how this fits into the existing debug mode functionality. Do you
> need the debug mode functionality, or are just piggy-backing off this
> existing structure?

This ties in with the main question I had... typically, a profiling
layer is used on larger inputs where it is important that the
profiling code itself have very low overhead. Piggybacking on the
debug mode is a definite performance-killer, so I hope that the
profiling version of the library will be in its own inline namespace
alongside the parallel and debug modes.

My vote for the command-line switch is -fprofile-stdlib.

  - Doug


Re: [cxx0x-branch] Rvalue references vs RVO

2007-05-08 Thread Doug Gregor

I'm CC'ing Howard, the master of the rvalue reference, and Russell,
the author of the rvalue references patch... see below for my take on
this.

On 5/7/07, Sylvain Pion <[EMAIL PROTECTED]> wrote:

I have done some experiments with the rvalue reference feature on the 
cxx0x-branch.


Great!


I am wondering: is this behavior (2 extra copies) required by the 
rvalue-reference
specifications, or would gcc be allowed to do better?


In my understanding, GCC is allowed to elide the constructor, and should do so.


Even if the whole point of rvalue-reference copies is that they are supposed to 
be
cheap (can we count on them to be fully optimized by the lower level optimizers,
in principle?), it would probably be better to still be allowed to skip the 2 
extra
copies completely using the RVO, even for objects defining an rvalue-ref copy
constructor, right?


Right. I've hacked up a fix (for ConceptGCC, but would be almost the
same on cxx0x-branch) that elides the move constructor. The patch is
below... it fixes your test case and doesn't cause any regressions.
But, I'd like to hear back from Howard and Russell before going
through with it on cxx0x-branch.


BTW, http://gcc.gnu.org/projects/cxx0x.html does not yet mention the rvalue 
reference patch.


We're waiting on one little copyright assignment detail.

 - Doug

2007-05-08  Douglas Gregor  <[EMAIL PROTECTED]>

* g++.dg/cpp0x/rvo.C: New.

2007-05-08  Douglas Gregor  <[EMAIL PROTECTED]>

* decl.c (move_fn_p): New.
* call.c (build_over_call): In C++0x mode, we can elide move
constructors as well as copy constructors.
* cp-tree.h (DECL_MOVE_CONSTRUCTOR_P): New.
(move_fn_p): Declare.

Index: gcc/testsuite/g++.dg/cpp0x/rvo.C
===
--- gcc/testsuite/g++.dg/cpp0x/rvo.C(revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/rvo.C(revision 0)
@@ -0,0 +1,25 @@
+// { dg-do "run" }
+// { dg-options "-std=c++0x" }
+// Contributed by Sylvain Pion
+static int rvalue_constructions = 0;
+
+struct A {
+  A () { }
+  A (const A&) { }
+  A (A&&)  { ++rvalue_constructions; }
+  ~A (){ }
+};
+
+A f() {  return A(); }
+
+extern "C" {
+  void abort(void);
+}
+
+int main()
+{
+  A c = f();
+
+  if (rvalue_constructions != 0)
+abort();
+}
Index: gcc/cp/decl.c
===
--- gcc/cp/decl.c   (revision 534)
+++ gcc/cp/decl.c   (working copy)
@@ -9242,6 +9242,53 @@ copy_fn_p (tree d)
  return result;
}

+/* D is a constructor or overloaded `operator='.
+
+   Let T be the class in which D is declared. Then, this function
+   returns true when D is a move constructor or move assignment
+   operator, false otherwise.  */
+
+bool
+move_fn_p (tree d)
+{
+  tree args;
+  tree arg_type;
+  bool result = false;
+
+  gcc_assert (DECL_FUNCTION_MEMBER_P (d));
+
+  if (TREE_CODE (d) == TEMPLATE_DECL
+  || (DECL_TEMPLATE_INFO (d)
+ && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d
+/* Instantiations of template member functions are never copy
+   functions.  Note that member functions of templated classes are
+   represented as template functions internally, and we must
+   accept those as copy functions.  */
+return 0;
+
+  args = FUNCTION_FIRST_USER_PARMTYPE (d);
+  if (!args)
+return 0;
+
+  arg_type = TREE_VALUE (args);
+  if (arg_type == error_mark_node)
+return 0;
+
+  if (TREE_CODE (arg_type) == REFERENCE_TYPE
+  && TYPE_REF_IS_RVALUE (arg_type)
+  && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)),
+  DECL_CONTEXT (d)))
+result = true;
+
+  args = TREE_CHAIN (args);
+
+  if (args && args != void_list_node && !TREE_PURPOSE (args))
+/* There are more non-optional args.  */
+return false;
+
+  return result;
+}
+
/* Remember any special properties of member function DECL.  */

void grok_special_member_properties (tree decl)
Index: gcc/cp/call.c
===
--- gcc/cp/call.c   (revision 534)
+++ gcc/cp/call.c   (working copy)
@@ -5078,7 +5078,9 @@ build_over_call (struct z_candidate *can

  if (! flag_elide_constructors)
/* Do things the hard way.  */;
-  else if (cand->num_convs == 1 && DECL_COPY_CONSTRUCTOR_P (fn))
+  else if (cand->num_convs == 1
+   && (DECL_COPY_CONSTRUCTOR_P (fn)
+   || (flag_cpp0x && DECL_MOVE_CONSTRUCTOR_P (fn
{
  tree targ;
  arg = argarray[num_artificial_parms_for (fn)];
Index: gcc/cp/cp-tree.h
===
--- gcc/cp/cp-tree.h(revision 534)
+++ gcc/cp/cp-tree.h(working copy)
@@ -1871,6 +1871,10 @@ struct lang_decl GTY(())
#define DECL_COPY_CONSTRUCTOR_P(NODE) \
  (DECL_CONSTRUCTOR_P (NODE) && copy_fn_p (NODE) > 0)

+/* Nonzero if NODE (a FUNCTION_DECL) is a move constructor.  */
+#define DECL_MOVE_CONSTRUCTOR_P(NODE) \
+  (DECL

Re: I'm sorry, but this is unacceptable (union members and ctors)

2007-06-18 Thread Doug Gregor

On 6/16/07, michael.a <[EMAIL PROTECTED]> wrote:

You are of course free to demonstrate how placement new could circumnavigate
the need of unions.


Boost.Variant implements discriminated unions using placement new:

 http://www.boost.org/doc/html/variant.html

Of course, you would have to mimic the techniques it is using and/or
change your code to use Boost.Variant. But, since you've relied on an
extension to C++, you'll have to change your code to make it portable
anyway.

 - Doug


Re: RFH: GPLv3

2007-07-12 Thread Doug Gregor

On 7/12/07, Basile STARYNKEVITCH <[EMAIL PROTECTED]> wrote:

Mark Mitchell wrote:
> 3. After GCC 4.2.1 is released, we will renumber the branch to GCC 4.3.
>   What would have been GCC 4.2.2 will instead be GCC 4.3.3, to try to
> emphasize the GPLv3 switch.  The GCC mainline will then be GCC 4.4.

I find this surprising and a bit confusing! My first reaction (maybe not enough 
thought) is that most users don't care
much about GCC source code, only about its functionality (making an executable 
from C or C++ source code). I am not very
sure that a "minor" change on the GCC source code license should affect so 
significantly the version numbering.


I had the same reaction. A new major release of GCC implies new
features and other technical enhancements, not just a new license.
Just imagine the flood of user questions and complaints when they
download GCC 4.3, expecting to find their favorite new feature that
they were told would be in GCC 4.3, and "all I got was this crummy new
license." Shouldn't we at least have some carrot with this stick?

Could we ask the SC to reconsider the change in the GCC major version
numbering for GPLv3? Or, at the very least, explain why it is
important to change the major version number for a mere license
change?

Why not just change the license on mainline for the GCC 4.3 release
(whenever it happens), and leave GCC 4.2 as the last release series
using GPLv2?

 - Doug


Re: RFH: GPLv3

2007-07-12 Thread Doug Gregor

On 7/12/07, David Edelsohn <[EMAIL PROTECTED]> wrote:

>>>>> Doug Gregor writes:

Doug> Could we ask the SC to reconsider the change in the GCC major version
Doug> numbering for GPLv3? Or, at the very least, explain why it is
Doug> important to change the major version number for a mere license
Doug> change?

To avoid confusion among GCC users who do not expect a bug fix
release to introuduce a new license.


I agree with Ian on this one... to users, the new license just doesn't
matter. It needs to be prominently stated in the release nodes, in the
README, etc., but it's the technical changes that matter to GCC users.

It seems obvious to me that it would be easiest to just move today's
mainline over to GPLv3, and have every GCC release >= 4.3 be GPLv3. We
could then either cut off the GCC 4.2 branch entirely or leave it
GPLv2. Then there are no surprises for anyone.

 - Doug


Re: RFH: GPLv3

2007-07-12 Thread Doug Gregor

On 7/12/07, Dave Korn <[EMAIL PROTECTED]> wrote:

On 12 July 2007 15:29, Doug Gregor wrote:
> I had the same reaction. A new major release of GCC

  Ok, hadn't you better both stop right there.  "Major" release?
"significantly" affect the version numbering?  We're going from 4.2 to 4.3.
That's the MINOR release number that's changing.


*Sigh*

We could haggle over terminology, and while you are technically right,
you've side-stepped the point.

Each GCC release series changes either the minor or the major version
number, but to users the effect is the same. New features come in, old
features are changed/fixed/deprecated/removed, and there is some
porting effort involved that is not there when the subminor/patchlevel
version changes within a release series. For C++ programmers, the
"minor" release of GCC 3.4 was a major porting effort, while the
"major" release of GCC 4.0 didn't affect their code much because most
of that work was in the middle-end that users don't see.

Hence, from a GCC user's perspective, each new release series is a
"major" release, because it indicates that things are going to change,
and they are probably going to have to port their code, retest, re-run
benchmarks, etc. That's "major" to them (us).

So, feel free to re-read my note from the perspective that a "major"
release is something that has an impact on users, and "minor" is
something that typically does not. But, please, let's not haggle over
terminology.

 - Doug


Re: C++ ABI: name mangling of operator new [bug 6057]

2007-07-26 Thread Doug Gregor

Hi Richard,

On 7/26/07, Richard Smith <[EMAIL PROTECTED]> wrote:


About five years ago, I reported a bug about an ICE when
trying to mangle expressions involving operator new.

  http://gcc.gnu.org/ml/gcc-patches/2002-03/msg01417.html
  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=6057

A three line example exhibiting the ICE is:

  template  struct helper {};
  template  void check( helper* );
  int main() { check(0); }

As I understand it, the reason that this has never been
fixed is that a full fix requires either an extension/change
to the ABI which presumably requires collaboration between
the eight organisations that produced it.

I'm wondering whether there's any prospect of this
happening, and if not, whether GCC should use the vendor
extension syntax (v  ) to provide a fix?


This kind of thing came up that the last C++ committee meeting, as
part of core issue 339:

 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#339

Name mangling is part of the problem, but not all of it. There is also
the issue of what happens when there is an error in the expression
"new T": is it part of the Substitution Failure Is Not An Error
(SFINAE) rule, meaning that the function would not enter the overload
set, or does it trigger an error immediately? That's actually the more
complicated issue.

As for GCC... I think we realize that we do have to fix these
problems. That means we'll need name mangling for all of the
expressions (and will have to extend the C++ ABI for this; vendor
extensions would not be useful), and we'll have to update a lot of the
type-checking for expressions in the C++ front end to propagate and
obey tsubst_flags_t.

 - Doug


Re: C++ ABI: name mangling of operator new [bug 6057]

2007-07-26 Thread Doug Gregor

On 7/26/07, Richard Smith <[EMAIL PROTECTED]> wrote:

Doug Gregor wrote:
> This kind of thing came up that the last C++ committee meeting, as
> part of core issue 339:
>
>   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#339
>
> Name mangling is part of the problem, but not all of it. There is also
> the issue of what happens when there is an error in the expression
> "new T": is it part of the Substitution Failure Is Not An Error
> (SFINAE) rule, meaning that the function would not enter the overload
> set, or does it trigger an error immediately? That's actually the more
> complicated issue.

Thanks for pointing DR 339 out to me; whilst I had read it
before, it was before the note from the Apr 2007 meeting was
added.

Although the 'compromise proposal' appears to avoid all of
these problems by making my example illegal, it would appear
that N2235 'Generalized Constant Expressions' reintroduces
many of them again.  To give an example,


I'm sorry, I should have read that DR text more carefully before
pointing. We discussed DR 339 again last week in Toronto, and the
resolution was different from the April 2007 resolution.

Now, we're saying that any expressions are valid in sizeof, decltype,
and constant expressions. If those expressions fail to type-check
during substitution, it will be a SFINAE case. That's why we need both
name mangling additions to the ABI and more work to obey
tsubst_flags_t throughout a much larger part of the compiler.

 - Doug


Re: C++ ABI: name mangling of operator new [bug 6057]

2007-07-26 Thread Doug Gregor

On 7/26/07, Richard Smith <[EMAIL PROTECTED]> wrote:

  template 
  class is_default_constructible {
template  struct helper {};
typedef char no; typedef char yes[2];
static no fn(...);
static yes fn( helper* );
  public:
static const bool value = sizeof(fn(0)) == sizeof(yes);
  };


I believe that should work with the (new) proposed resolution to DR 339.

 - Doug


Inconsistent error/pedwarn: ISO C++

2007-09-20 Thread Doug Gregor
We can't seem to decide whether ISO C++ really forbids comparisons
between pointers and integers or not. The first two are for == and !=,
the second two are for <, >, <=, >=. Why the inconsistency?

typeck.c:   error ("ISO C++ forbids comparison between pointer
and integer");
typeck.c:   error ("ISO C++ forbids comparison between pointer
and integer");
typeck.c:   pedwarn ("ISO C++ forbids comparison between
pointer and integer");
typeck.c:   pedwarn ("ISO C++ forbids comparison between
pointer and integer");

  - Doug


Make/bootstrap failure on i386-apple-darwin8.10.1 (Intel Core Duo)

2007-10-02 Thread Doug Gregor
For the last few days I've been unable to make or bootstrap on
i386-apple-darwin8.10.1. It doesn't seem to be a problem on my
Core2-based Mac Pro, but on my Intel Core Duo (MacBook Pro) the build
fails with the error message below.

Perhaps we're trying to use Core2-only instructions on this platform?
Is there a workaround?

  - Doug

/Users/dgregor/Projects/mainlinegcc-build/./gcc/xgcc
-B/Users/dgregor/Projects/mainlinegcc-build/./gcc/
-B/Users/dgregor/Projects/mainlinegcc-install/i386-apple-darwin8.10.1/bin/
-B/Users/dgregor/Projects/mainlinegcc-install/i386-apple-darwin8.10.1/lib/
-isystem 
/Users/dgregor/Projects/mainlinegcc-install/i386-apple-darwin8.10.1/include
-isystem 
/Users/dgregor/Projects/mainlinegcc-install/i386-apple-darwin8.10.1/sys-include
-g -fkeep-inline-functions -O2  -O2 -g -O2   -DIN_GCC-W -Wall
-Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes
-Wold-style-definition  -isystem ./include  -fPIC -pipe -g
-DHAVE_GTHR_DEFAULT -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED   -I. -I.
-I../.././gcc -I../../../mainlinegcc/libgcc
-I../../../mainlinegcc/libgcc/. -I../../../mainlinegcc/libgcc/../gcc
-I../../../mainlinegcc/libgcc/../include  -DHAVE_CC_TLS -o
unwind-dw2_s.o -MT unwind-dw2_s.o -MD -MP -MF unwind-dw2_s.dep
-DSHARED -fexceptions -c
../../../mainlinegcc/libgcc/../gcc/unwind-dw2.c
:3825:operands given don't match any known 386 instruction
:5178:operands given don't match any known 386 instruction
:5198:operands given don't match any known 386 instruction
:6196:operands given don't match any known 386 instruction
:7709:operands given don't match any known 386 instruction
:7835:operands given don't match any known 386 instruction
:8030:operands given don't match any known 386 instruction
:8126:operands given don't match any known 386 instruction
:8310:operands given don't match any known 386 instruction
:8390:operands given don't match any known 386 instruction
:8491:operands given don't match any known 386 instruction
make[3]: *** [unwind-dw2_s.o] Error 1
make[2]: *** [all-stage1-target-libgcc] Error 2
make[1]: *** [stage1-bubble] Error 2
make: *** [all] Error 2


Re: Make/bootstrap failure on i386-apple-darwin8.10.1 (Intel Core Duo)

2007-10-03 Thread Doug Gregor
On 10/2/07, Jack Howarth <[EMAIL PROTECTED]> wrote:
>   The fink packaging for gcc42/gcc43 builds fine on Macintel when we use...
>
> --with-arch=nocona --with-tune=generic --host=i686-apple-darwin8

This gets further, failing now for a very different reason:

cc  -O2 -g -O2 -m64 -O2  -O2 -g -O2   -DIN_GCC-W -Wall
-Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes
-Wold-style-definition  -isystem ./include  -fPIC -pipe -g
-DHAVE_GTHR_DEFAULT -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED   -I. -I.
-I../../.././gcc -I../../../../mainlinegcc/libgcc
-I../../../../mainlinegcc/libgcc/.
-I../../../../mainlinegcc/libgcc/../gcc
-I../../../../mainlinegcc/libgcc/../include   -o _muldi3.o -MT
_muldi3.o -MD -MP -MF _muldi3.dep -DL_muldi3 -c
../../../../mainlinegcc/libgcc/../gcc/libgcc2.c \
  -fvisibility=hidden -DHIDE_EXPORTS
In file included from ../../../../mainlinegcc/libgcc/../gcc/libgcc2.c:65:
../../../../mainlinegcc/libgcc/../gcc/libgcc2.h:176: error: unknown
machine mode 'libgcc_cmp_return'
../../../../mainlinegcc/libgcc/../gcc/libgcc2.h:177: error: unknown
machine mode 'libgcc_shift_count'

  - Doug


Re: Help understanding overloaded templates

2007-11-16 Thread Doug Gregor
On 11/15/07, Rob Quill <[EMAIL PROTECTED]> wrote:
> Hi,
>
> I was wondering if anyone could help me make sense of the
> more_specialized_fn() function in pt.c (line 13281).
>
> Specifically, I am trying to understand what each of the are:
>
>   tree decl1 = DECL_TEMPLATE_RESULT (pat1);

This is the actual FUNCTION_DECL node that represents the function
template. It's just like another other (non-template) FUNCTION_DECL,
except that it's associated with a template and will use some of the
template parameters in its definition and declaration.

>   tree targs1 = make_tree_vec (DECL_NTPARMS (pat1));

DECL_NTPARMS is the number of template parameters, so we're just
making a vector that long.

>   tree tparms1 = DECL_INNERMOST_TEMPLATE_PARMS (pat1);

For member templates, this pulls out just the innermost template parameters.

>   tree args1 = TYPE_ARG_TYPES (TREE_TYPE (decl1));

This is the list of function parameter types. e.g., in a function template

  template
  void f(T*, int, float);

this would be a TREE_LIST containing the types T*,, int, and float.

> and how the function is supposed to deal with variadic functions in
> terms of these. That is to say, if a function is variadic, how is that
> represented in these data structures?

By "variadic" I assume you mean C-style variadic functions, e.g.,

  template void f(T x, ...);

and not the C++0x variadic templates.

The presence of an ellipsis is indicated by the last node in the
TREE_LIST being void_list_node; if there is no ellipsis, the last
parameter's TREE_CHAIN will simply be NULL_TREE.

  - Doug


Re: GCC 4.3.0 Status Report (2007-11-27)

2007-11-27 Thread Doug Gregor
On Nov 27, 2007 4:19 PM, Mark Mitchell <[EMAIL PROTECTED]> wrote:
> 1. I noticed that there are quite a few P2 ICE reports regarding
>variadic templates.  Doug Gregor, would you please look into these?

There are patches for a few of these issues (two P2s and a P3) that
still need review; see the links below. I'm swamped until the end of
the week, but I'll take a shot at fixing more of these after Saturday.

>Jason, would you be able to review Doug's patches (as the arrive),
>given that you've looked at much of the rest of his code?

There are a few variadic templates patches still to be reviewed:

  http://gcc.gnu.org/ml/gcc-patches/2007-11/msg00323.html
  http://gcc.gnu.org/ml/gcc-patches/2007-11/msg00973.html
  http://gcc.gnu.org/ml/gcc-patches/2007-11/msg00970.html

   - Doug


Re: -Wparentheses lumps too much together

2007-12-19 Thread Doug Gregor
On Dec 19, 2007 3:02 PM,  <[EMAIL PROTECTED]> wrote:
> One last point.  In looking for the rationale behind this warning, I searched
> for examples of it.  I didn't find any discussion on this list.  What I did
> find were many examples of people rototilling perfectly fine code, "improving"
> it by adding unneeded parenthesis specifically so that it would compile
> cleanly with -Wall.  I think that's a shame: a waste of effort at best.
>
> I ask you, please, to consider splitting advice about operator precedence from
> advice about mismatched if/else branches, and to exclude advice about
> making sure && is parenthesized ahead of || from -Wall.  -Wall is the
> standard for "good, clean code" in many projects.  This warning doesn't
> belong there.

For what it is worth, I completely agree with everything you have said
here. This warning oversteps the bounds of what -Wall should do, and
forces people to change perfectly good, clean code. Operator
precedence is an important concept that any C or C++ programmer should
know, and we're not helping anyone by pretending that programmer's
won't understand this concept.

We should certainly remove the warning from -Wall, and perhaps remove
it entirely.

  - Doug