Should GMP 4.1+ and MPFR 2.2+ be needed when we're not building gfortran?
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
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
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
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
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
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
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
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
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
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)
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)
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)
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?
We're out of tree codes; now what?
[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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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++)
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?
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?
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?
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?
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
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
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
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
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
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
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)
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)
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
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
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)
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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]
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]
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]
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++
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)
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)
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
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)
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
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