Re: gcc-in-cxx update / multi-targeted gcc
In order to be able to use namespaces in my endeavour to support gcc with multiple targets, I've first done a merge from the gcc-in-cxx branch. For my initial implementation, I choose as configuration --target=m32r-elf --with-extra-target-list='sh64-elf arc-elf32' . I've found some issues with gcc-in-cxx both specific to these targets, and specific to (parts of) compiler passes that are only compiled for a subset of all tagets, which include one or more of the above mentioned three. You can find these in the branch: svn//gcc.gnu.org/svn/gcc/branches/multi-target-4_4-branch So far, I have only made gcc-in-cxx related and a few general checkins there. I haven't got to the stage where I could link the multi-targetted gcc together - it's still missing stuff like target option related variables. However, I have already noticed that you are pushing the target vector in a nonsentical direction: you are using target-specific enums, like enum reg_class . We can't have the target vector refer to these enums, since they are different for each target. Something which I miss in C++ is a way to declare that a function uses an integral type to pass an enum value (in arguments or return value), and then at function definition time only check that the integral type is sufficently large to hold the enum, and then for type checking purposes treat the parameter / return value as if it had been declared as this enum. FWIW, the target vector is more an obstruction than a help to make gcc multi-targeted. macros that change the way an rtl optimization pass work just fine - I then end up with different versions of the rtl optimization pass in different namespaces, which are accessed by pass lists which are initialized by code living in the same name space. My plan (I haven't started implementing this yet) for enum machine_mode is to have each number denote a mode with the same number of bits and mode class on all configured targets on which they denote a usable mode. I'm not sure yet if it will be helpful to diable modes not usable on a target by making them MODE_RANDOM. What are your thoughts on using gcc extensions for gcc-in-cxx ? We can work around the enum issues by liberally sprinkling casts all over the code, but we are really working against the language there. We could try to implement en extension to describe integral types used to pass enums, where the enums only need an unqualified name match. E.g. we could have: typedef int enum_reg_class __attribute__ ((enum (reg_class)); and have that be compatible with mips::enum reg_class for a funtion definition in the mips namespace, with spu::enum reg_class for a function definition in the spu namespace, and with plain enum reg_class anywhere. Another enum problem is enum attr_cpu / enum processor_type in the sh machine description. We need a variable (sh_cpu aka sh_cpu_attr) with this type to be visible inside the attributes generated by genattrtab. Choices to solve these kind of problems would be: - introduce another target header which is guaranteed to be included only after enum definitions from generator files are in effect. - allow the gcc extension of statement expressions to be used in target descriptions, so that a macro could provide an extern declaration of a variable before using its value.
Re: gcc-in-cxx update / multi-targeted gcc
On Wed, 29 Apr 2009, Joern Rennecke wrote: What are your thoughts on using gcc extensions for gcc-in-cxx ? I believe we agreed in a previous discussion to aim for building with the intersection of C++98/C++03 and C++ as supported by GCC 3.4 (including making sure at an appropriate point that it builds with a non-GCC compiler, probably an EDG-based one such as the Intel compiler). Though bearing in mind that PPL doesn't build with GCC before 4.0, the GCC version required for building with GCC might increase (though I think increasing beyond 4.1 would be a bad idea for some time yet). -- Joseph S. Myers jos...@codesourcery.com
Re: gcc-in-cxx update / multi-targeted gcc
Quoting Joseph S. Myers jos...@codesourcery.com: On Wed, 29 Apr 2009, Joern Rennecke wrote: What are your thoughts on using gcc extensions for gcc-in-cxx ? I believe we agreed in a previous discussion to aim for building with the intersection of C++98/C++03 and C++ as supported by GCC 3.4 (including making sure at an appropriate point that it builds with a non-GCC compiler, probably an EDG-based one such as the Intel compiler). Though bearing in mind that PPL doesn't build with GCC before 4.0, the GCC version required for building with GCC might increase (though I think increasing beyond 4.1 would be a bad idea for some time yet). I think we should distinguish here between the language we want to support for bootstrapping versus the language we want to be use for builds in general to allow convenient type checking, and to support configurations that are not essential for bootstrapping, like ones with multiple target architectures. When compiling for a single target, we could still use standard enums in the interface even where the enums are target dependent. Although that defeats the purpose of the target vector (it is not interchangeable with any other target vector), it allows you to bootstrap the compiler, and then you can use that compiler to build a multi-targeted gcc which requires the gcc extension. For the generated-enum-in-macro problem, we could use a plain integral type as the variable type and a cast to the enum when reading as a fallback mechanism. But allowing the statement expression for gcc would give better type checking.
Re: gcc-in-cxx update / multi-targeted gcc
On Wed, 29 Apr 2009, Joern Rennecke wrote: Quoting Joseph S. Myers jos...@codesourcery.com: On Wed, 29 Apr 2009, Joern Rennecke wrote: What are your thoughts on using gcc extensions for gcc-in-cxx ? I believe we agreed in a previous discussion to aim for building with the intersection of C++98/C++03 and C++ as supported by GCC 3.4 (including making sure at an appropriate point that it builds with a non-GCC compiler, probably an EDG-based one such as the Intel compiler). Though bearing in mind that PPL doesn't build with GCC before 4.0, the GCC version required for building with GCC might increase (though I think increasing beyond 4.1 would be a bad idea for some time yet). I think we should distinguish here between the language we want to support for bootstrapping versus the language we want to be use for builds in general to allow convenient type checking, and to support configurations that are not essential for bootstrapping, like ones with multiple target architectures. The question is not just one for bootstrapping a native compiler but also one of what compiler can be used to build a cross compiler (such as that with multiple targets), which is not bootstrapped in the usual GCC sense. There we presently document GCC 2.95 or later as required (and again I think requiring a version later than 4.1 would be a bad idea). -- Joseph S. Myers jos...@codesourcery.com
Re: gcc-in-cxx update / multi-targeted gcc
On Wed, 2009-04-29 at 13:21 +, Joseph S. Myers wrote: On Wed, 29 Apr 2009, Joern Rennecke wrote: Quoting Joseph S. Myers jos...@codesourcery.com: On Wed, 29 Apr 2009, Joern Rennecke wrote: What are your thoughts on using gcc extensions for gcc-in-cxx ? I believe we agreed in a previous discussion to aim for building with the intersection of C++98/C++03 and C++ as supported by GCC 3.4 (including making sure at an appropriate point that it builds with a non-GCC compiler, probably an EDG-based one such as the Intel compiler). Though bearing in mind that PPL doesn't build with GCC before 4.0, the GCC version required for building with GCC might increase (though I think increasing beyond 4.1 would be a bad idea for some time yet). I think we should distinguish here between the language we want to support for bootstrapping versus the language we want to be use for builds in general to allow convenient type checking, and to support configurations that are not essential for bootstrapping, like ones with multiple target architectures. The question is not just one for bootstrapping a native compiler but also one of what compiler can be used to build a cross compiler (such as that with multiple targets), which is not bootstrapped in the usual GCC sense. There we presently document GCC 2.95 or later as required (and again I think requiring a version later than 4.1 would be a bad idea). GCC (at least, the C port of it) is supposed to be compilable with any ISO C90 compiler; when did this change? Or are you saying that if you are using GCC you need at least 2.95. R.
Re: gcc-in-cxx update / multi-targeted gcc
On Wed, 29 Apr 2009, Richard Earnshaw wrote: The question is not just one for bootstrapping a native compiler but also one of what compiler can be used to build a cross compiler (such as that with multiple targets), which is not bootstrapped in the usual GCC sense. There we presently document GCC 2.95 or later as required (and again I think requiring a version later than 4.1 would be a bad idea). GCC (at least, the C port of it) is supposed to be compilable with any ISO C90 compiler; when did this change? Or are you saying that if you are using GCC you need at least 2.95. If you are building a non-C front end without bootstrapping you need at least 2.95: To build all languages in a cross-compiler or other configuration where 3-stage bootstrap is not performed, you need to start with an existing GCC binary (version 2.95 or later) because source code for language frontends other than C might use GCC extensions. (for Ada you need at least 3.4 whether building a cross compiler or bootstrapping and there's a recommendation to use the same version for building a cross compiler). -- Joseph S. Myers jos...@codesourcery.com
Re: gcc-in-cxx update / multi-targeted gcc
Joern Rennecke amyl...@spamcop.net writes: I've found some issues with gcc-in-cxx both specific to these targets, and specific to (parts of) compiler passes that are only compiled for a subset of all tagets, which include one or more of the above mentioned three. I'd be happy to see and approve your patches. Several people have made changes to the gcc-in-cxx branch. Just send them to gcc-patches as usual with [gcc-in-cxx] in the Subject. However, I have already noticed that you are pushing the target vector in a nonsentical direction: you are using target-specific enums, like enum reg_class . We can't have the target vector refer to these enums, since they are different for each target. I'm not sure why you are singling me out. I only added one use of enum reg_class to the target vector; there were already two other uses of enum reg_class, and many uses of enum machine_mode. If we decide that a multi-targeted gcc is a goal we want to support, it's certainly fine with me to change those enums to int and add casts where appropriate. (I'm not personally convinced that a multi-targeted gcc is particularly useful, though I don't object if there is a general desire to support it.) Something which I miss in C++ is a way to declare that a function uses an integral type to pass an enum value (in arguments or return value), and then at function definition time only check that the integral type is sufficently large to hold the enum, and then for type checking purposes treat the parameter / return value as if it had been declared as this enum. FWIW, the target vector is more an obstruction than a help to make gcc multi-targeted. macros that change the way an rtl optimization pass work just fine - I then end up with different versions of the rtl optimization pass in different namespaces, which are accessed by pass lists which are initialized by code living in the same name space. It is perhaps worth noting that the natural way to handle the target vector in C++ is to make a Target class with a set of virtual methods. Then methods like eh_return_filter_mode would use a covariant return type in specific implementations. Where the mode is a parameter it would still have to be changed to int. My plan (I haven't started implementing this yet) for enum machine_mode is to have each number denote a mode with the same number of bits and mode class on all configured targets on which they denote a usable mode. I'm not sure yet if it will be helpful to diable modes not usable on a target by making them MODE_RANDOM. I suspect that would indeed be the best approach for machine_mode in a multi-targeted gcc. What are your thoughts on using gcc extensions for gcc-in-cxx ? We can work around the enum issues by liberally sprinkling casts all over the code, but we are really working against the language there. We could try to implement en extension to describe integral types used to pass enums, where the enums only need an unqualified name match. E.g. we could have: typedef int enum_reg_class __attribute__ ((enum (reg_class)); and have that be compatible with mips::enum reg_class for a funtion definition in the mips namespace, with spu::enum reg_class for a function definition in the spu namespace, and with plain enum reg_class anywhere. I think you need to take a step back. What is a natural way to represent a register class in the machine independent code when writing in C++? I don't think it is to use an enum type. A register class is basically an object which implements methods like bool is_regno_in_class(unsigned int); HARD_REG_SET registers_in_class(); bool equals(Reg_class); bool is_superset_of(Reg_class); bool is_subset_of(Reg_classS); Obviously that is a long way off in gcc. But I don't see any need to add new features to the C++ frontend to support a style of programming which is inappropriate for C++. We can just convert between int and the enum types for now. Another enum problem is enum attr_cpu / enum processor_type in the sh machine description. We need a variable (sh_cpu aka sh_cpu_attr) with this type to be visible inside the attributes generated by genattrtab. Choices to solve these kind of problems would be: - introduce another target header which is guaranteed to be included only after enum definitions from generator files are in effect. - allow the gcc extension of statement expressions to be used in target descriptions, so that a macro could provide an extern declaration of a variable before using its value. A simple approach would be to have a way to say that the enum values for an attribute were already declared. Then instead of listing the values in the define_attr, we would just have a standard mapping from constants of the attribute to the enum names to use. We would have less error checking in the generator programs, but the errors would be caught when the generated code was compiled. Ian
Re: gcc-in-cxx update / multi-targeted gcc
On Wed, 29 Apr 2009, Ian Lance Taylor wrote: (I'm not personally convinced that a multi-targeted gcc is particularly useful, though I don't object if there is a general desire to support it.) I think the cleanups involved in using the target vector / class more, and other cleanups involved in the natural approach to multi-target GCC of which the target vector is a part, are more useful than the end result (for which compiling large parts of the compiler multiple times is an interesting approach - I'd always thought of the aim as being a multi-target compiler without target-independent files being built more than once). Other clearly worthwhile cleanups in what I thought of as the natural approach include completing the toplevel libgcc transition (so the copies of libgcc built for each target's multilibs get their configuration from configuring the libgcc directory for that target and multilib rather than from the gcc directory if that's configured once, and without including tm.h in target files any more). -- Joseph S. Myers jos...@codesourcery.com
Re: gcc-in-cxx update / multi-targeted gcc
On Wed, 29 Apr 2009, Joseph S. Myers wrote: On Wed, 29 Apr 2009, Richard Earnshaw wrote: If you are building a non-C front end without bootstrapping you need at least 2.95: To build all languages in a cross-compiler or other configuration where 3-stage bootstrap is not performed, you need to start with an existing GCC binary (version 2.95 or later) because source code for language frontends other than C might use GCC extensions. STRICT_WARN (i.e. -pedantic) was added to all the frontends (except Ada) many years ago. So this comment about use of extensions requiring gcc-2.95 might be obsolete. I suspect you may be able to cross-build all of non-ada GCC with any ISO C compiler right now (I haven't tried it though since I don't have access to an appropriate system.) --Kaveh
Re: gcc-in-cxx update / multi-targeted gcc
Quoting Ian Lance Taylor i...@google.com: I'm not sure why you are singling me out. You seemed to be actively working on the branch, and the c++ enum type checks provide a motivation to make changes. Also, this issue should be considered in general when people change their coding habits in order for the code to be c++ ready. If we decide that a multi-targeted gcc is a goal we want to support, it's certainly fine with me to change those enums to int and add casts where appropriate. OK. This is also the route I have followed so far. (I'm not personally convinced that a multi-targeted gcc is particularly useful, though I don't object if there is a general desire to support it.) As the number of cores integrated into each computing device increases, I think it is only natural that we'll see the emergence of specialized cores. E.g. we already see low power cores for base load/standby, superscalar out-of-order cores for sequential processing, and massively parallel architectures for media processing. Having a single compiler that can generate code for all target architectures in a computing device allows to shift (parts of) functions from one architecture to the other depending the nature of the processing task. This also increases the leverage for profile-based feedback and machine learning. It is perhaps worth noting that the natural way to handle the target vector in C++ is to make a Target class with a set of virtual methods. Yes, but unfortunately that requires ferrying around the this pointer. If we had virtual static member functions, that would be different. And you'd still have to decide on one function signature for each virtual function - having one target return a pointer to an 8 bit enum and another one return a pointer to a 16 bit enum by the same name just won't do. Then methods like eh_return_filter_mode would use a covariant return type in specific implementations. Where the mode is a parameter it would still have to be changed to int. The signature of these virtual functions would have to be defined with a type that is wide enough to fit all target's enums. And you couldn't fix a hook like ira_cover_classes this way. The caller has to know how wide each element is in the of the array the pointer to the first element of which is being returned. I think you need to take a step back. What is a natural way to represent a register class in the machine independent code when writing in C++? I don't think it is to use an enum type. Having all register classes in one enum gives you some things that you don't get with an compiler implementation language class for each register class. E.g. you can easily iterate over all register classes, and have bitmasks which act as sets of register classes. You can use them as indices in lookup tables. A register class is basically an object which implements methods like bool is_regno_in_class(unsigned int); HARD_REG_SET registers_in_class(); bool equals(Reg_class); bool is_superset_of(Reg_class); bool is_subset_of(Reg_classS); Obviously that is a long way off in gcc. Indeed. Expressing this as an actual C++ class would be incompatible with the current goal to be able to build GCC with a C compiler. Another enum problem is enum attr_cpu / enum processor_type in the sh machine description. We need a variable (sh_cpu aka sh_cpu_attr) with this type to be visible inside the attributes generated by genattrtab. Choices to solve these kind of problems would be: - introduce another target header which is guaranteed to be included only after enum definitions from generator files are in effect. - allow the gcc extension of statement expressions to be used in target descriptions, so that a macro could provide an extern declaration of a variable before using its value. A simple approach would be to have a way to say that the enum values for an attribute were already declared. Then instead of listing the values in the define_attr, we would just have a standard mapping from constants of the attribute to the enum names to use. We would have less error checking in the generator programs, but the errors would be caught when the generated code was compiled. I don't see how this would work. Remember, genattrtab needs to know about every value in the enumeration so that it can perform its optimizations. I also don't see how your proposal is simpler than adding another header file. FWIW, the current approach of using two enums in parallel works (awkward as it is) also for C++. It just needed adjustments because the two sets of enum constants are no longer interchangable, and a cast is now required when going from one enum to the other.
Re: gcc-in-cxx update / multi-targeted gcc
Quoting Joseph S. Myers jos...@codesourcery.com: I think the cleanups involved in using the target vector / class more, and other cleanups involved in the natural approach to multi-target GCC of which the target vector is a part, are more useful than the end result (for which compiling large parts of the compiler multiple times is an interesting approach - I'd always thought of the aim as being a multi-target compiler without target-independent files being built more than once). I remembered the reports of GCC getting slower due to the target macros introduced so far (was it some 5% ?). Therefore, tying a multi-targeted gcc to the previous elimination of all non-target-vector target specifics seemed like a bad idea. My approach still allows rtl passes that are present only once - all you have to do is remove it from / not place it in the list of files that are compiled for each target, and change the header files so that the declarations for functions defined in this file are not put in the target namespace. It might well be that slowdown when going all target-vector can be avoided by using different abstractions, or using them in different ways. But that'll be a gargantuous task; I am at more than a hundred target specific files now. Something also to consider is that it is quite common in C++ to compile the same code multiple times. I fact I toyed with the idea to drive the support for multiple targets using templates but I gave up on that because: - It's harder to transform the existing code to be encapsulated into template than to encapsulate it into a namespace. - Mangled names would be more complex, casing debugging nightmares. - It would probably result in ferrying around a this pointer, plus unknown abstraction penalties. - Keeping to a minimal set of one simple C++ feature makes the code easier to understand.
Re: gcc-in-cxx update / multi-targeted gcc
On Wednesday 29 April 2009 12:47:04 Joern Rennecke wrote: Something which I miss in C++ is a way to declare that a function uses an integral type to pass an enum value (in arguments or return value), and then at function definition time only check that the integral type is sufficently large to hold the enum, and then for type checking purposes treat the parameter / return value as if it had been declared as this enum. This is exactly N2764, which should be part of C++0x --- at least it seems to be in the draft around p.149. But not part of gcc 4.4. unfortunately. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf http://gcc.gnu.org/projects/cxx0x.html -- Kind regards, Esben
Re: gcc-in-cxx update / multi-targeted gcc
On Wednesday 29 April 2009 12:47:04 Joern Rennecke wrote: Something which I miss in C++ is a way to declare that a function uses an integral type to pass an enum value (in arguments or return value), and then at function definition time only check that the integral type is sufficently large to hold the enum, and then for type checking purposes treat the parameter / return value as if it had been declared as this enum. Esben Mose Hansen wrote: This is exactly N2764, which should be part of C++0x --- at least it seems to be in the draft around p.149. But not part of gcc 4.4. unfortunately. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf That is closely related, but it's not quite the same. For a multi-targeted gcc, we'd want generic code to operate on integral types that correspond to enum values defined by the various targets - but these will define these enums differently. If the generic code was in a library, and compilers for the different targets were built separately, then N2764 would work. However, when linking multiple targets together, enums with the same name for different targets are different types, so they can't all be the same type as the type used by the generic code. This is why I would like the generic code to use a separate type which is assignment-compatible with any of these enums if the enums definition is visible.