Message ID | 54204DA9.1050802@redhat.com |
---|---|
State | New |
Headers | show |
On Mon, 2014-09-22 at 12:26 -0400, Andrew MacLeod wrote: > After being reminded of the tm.h issues brought up last november (here: > https://gcc.gnu.org/ml/gcc-patches/2013-11/msg01731.html ), I started > looking back into it. > > The general summary is the any header file which has a conditional on a > target macro could be affected by include file reordering... ie, if a > header file has > #ifdef BLAH > <whatever> > > and we move the header files around a bit, it wouldn't be immediately > obvious if the order where changes and BLAH was define later in the > include structure. The results for this header files would be different > because <whatever> would no longer be in the preprocess source, and it > may take a long time to discover the difference. > > Josephs solution was to identify these and instead put a default > definition in default.h ... then change all the uses to #if instead.. ie, > #if BLAH > > This way we can ensure that the definition has been seen and it will be > a compile error if not. > > > I looked at all the target macros listed by Joseph, and decide to start > with the ones which are used *only* in an "if defined" situation in a .h > files of some sort. > ie > #ifdef > #ifndef > or #if define() > > If this happens in a .c file, then changing the order of .h's shouldn't > matter. (Unless the .c file is doing something really screwy. So for > the moment, ignoring that.) There appears to be a particular implicit order in which headers must be included. I notice that e.g. tm.h has: #ifndef GCC_TM_H #define GCC_TM_H so if we're going with this "no header file includes any other header file" model, would it make sense to add something like: #ifndef GCC_TM_H #error tm.h must have been included by this point /* We need tm.h here so that we can see: BAR, BAZ, QUUX, etc. */ #endif to header files needing it, thus expressing the expected dependencies explicitly? > So looking at only .h files, I found a number of default definitions in > rtl.h, which this patch moves to defaults.h. I was going to #error if > defaults.h wasn't included, but found that to be unnecessary since it > uses some of those macros and would cause a compile failure anyway if it > wasn't included. All the other uses of these particular macros use the > #if model, so no further adjustment is required for them. > > This patch bootstraps on x86_64-unknown-linux-gnu, and regressions are > running. Assuming no issues show up, OK for mainline? > > The remaining macros I will have a closer look at and most will likely > need the full treatment moving from #ifdef to the #if model. I plan to > do these next. The macros which fit this category for potential header > trouble (along with their usage count) are: > > 2 USE_COLLECT2 > 3 TARGET_TERMINATE_DW2_EH_FRAME_INFO > 3 TARGET_HAVE_CTORS_DTORS > 3 REGMODE_NATURAL_SIZE > 4 CC_STATUS_MDEP_INIT > 4 CC_STATUS_MDEP_INIT > 4 MODE_BASE_REG_REG_CLASS > 4 REGNO_MODE_OK_FOR_REG_BASE_P > 5 MODE_BASE_REG_CLASS > 5 XCOFF_DEBUGGING_INFO > 6 VMS_DEBUGGING_INFO > 6 TARGET_ASM_OUTPUT_ANCHOR > 6 EH_FRAME_SECTION_NAME > 8 MODE_CODE_BASE_REG_CLASS > 9 HARD_REGNO_CALLER_SAVE_MODE > 9 HARD_REGNO_CALL_PART_CLOBBERED > 9 SDB_DEBUGGING_INFO > 9 CC_STATUS_MDEP > 9 REGNO_MODE_CODE_OK_FOR_BASE_P > 10 SECONDARY_RELOAD_CLASS > 10 TARGET_VXWORKS_RTP > 14 NO_DOT_IN_LABEL > 14 REGNO_MODE_OK_FOR_BASE_P > 17 STACK_REGS > 19 TARGET_ASM_DESTRUCTOR > 20 OBJECT_FORMAT_ELF > 20 TARGET_ASM_CONSTRUCTOR > 24 NO_DOLLAR_IN_LABEL > 26 DBX_DEBUGGING_INFO > 30 CPLUSPLUS_CPP_SPEC > 42 ASM_OUTPUT_DEF > > > >
On Mon, 22 Sep 2014, Andrew MacLeod wrote: > Josephs solution was to identify these and instead put a default definition in > default.h ... then change all the uses to #if instead.. ie, > #if BLAH > > This way we can ensure that the definition has been seen and it will be a > compile error if not. No, my suggestion was that whenever possible we should change preprocessor conditionals - #ifdef or #if - into C conditionals - "if (MACRO)". Changing from #ifdef to #if does nothing to make a missing tm.h include produce an error - the undefined macro simply quietly gets treated as 0 in preprocessor conditionals. To get an error from #if in such cases, you'd need to build GCC with -Wundef (together with existing -Werror), and I'd guess there are plenty of places that are not -Wundef clean at present. Now, I think moves of defaults to defaults.h are generally a good idea, and that moving from defined/undefined to true/false semantics are also a good idea - even if the way the macro is used means you can't take the further step of converting from #if to if (). They don't solve the problem of making a missing tm.h include immediately visible, but they *do* potentially help with future automatic refactoring to convert target macros into hooks. Obviously such moves do require checking the definitions and uses of the macros in question; you need to make sure you catch all places that use #ifdef / #if defined etc. on the macro (and make sure they have the same default). And if you're changing the semantics of the macro from defined / undefined to true / false, you need to watch out for any existing definitions with an empty expansion, or an expansion to 0, etc.
On Mon, 22 Sep 2014, David Malcolm wrote: > There appears to be a particular implicit order in which headers must be > included. I notice that e.g. tm.h has: > > #ifndef GCC_TM_H > #define GCC_TM_H > > so if we're going with this "no header file includes any other header > file" model, would it make sense to add something like: > > #ifndef GCC_TM_H > #error tm.h must have been included by this point > /* We need tm.h here so that we can see: BAR, BAZ, QUUX, > etc. */ > #endif > > to header files needing it, thus expressing the expected dependencies > explicitly? In principle, yes. In practice, some headers have definitions that depend on tm.h but for most users this doesn't matter. For example, flags.h depends on SWITCHABLE_TARGET. (I think the fix there is to make most users use options.h instead, and move miscellaneous declarations from flags.h to other headers.) In some cases, the target macro may be used only in a macro expansion. (BITS_PER_UNIT isn't strictly a target macro any more, but when it was its uses in tree.h were an example of that. tree.h still depends on the target macros NO_DOLLAR_IN_LABEL, NO_DOT_IN_LABEL and TARGET_DLLIMPORT_DECL_ATTRIBUTES, however, but we shouldn't make all tree.h users include tm.h.)
On 09/22/2014 01:02 PM, Joseph S. Myers wrote: > On Mon, 22 Sep 2014, Andrew MacLeod wrote: > >> Josephs solution was to identify these and instead put a default definition in >> default.h ... then change all the uses to #if instead.. ie, >> #if BLAH >> >> This way we can ensure that the definition has been seen and it will be a >> compile error if not. > No, my suggestion was that whenever possible we should change preprocessor > conditionals - #ifdef or #if - into C conditionals - "if (MACRO)". > > Changing from #ifdef to #if does nothing to make a missing tm.h include > produce an error - the undefined macro simply quietly gets treated as 0 in > preprocessor conditionals. To get an error from #if in such cases, you'd > need to build GCC with -Wundef (together with existing -Werror), and I'd > guess there are plenty of places that are not -Wundef clean at present. really... I've always just assumed #if XXX would be like #if xx > YY and that would give you an error if there was a problem with the expression. How incredibly lame :-). Me too for not knowing that I suppose. > > Now, I think moves of defaults to defaults.h are generally a good idea, > and that moving from defined/undefined to true/false semantics are also a > good idea - even if the way the macro is used means you can't take the > further step of converting from #if to if (). They don't solve the > problem of making a missing tm.h include immediately visible, but they > *do* potentially help with future automatic refactoring to convert target > macros into hooks. > > Obviously such moves do require checking the definitions and uses of the > macros in question; you need to make sure you catch all places that use > #ifdef / #if defined etc. on the macro (and make sure they have the same > default). And if you're changing the semantics of the macro from defined > / undefined to true / false, you need to watch out for any existing > definitions with an empty expansion, or an expansion to 0, etc. > > and turning target macros into a C "if ()" isn't always an option... if() and target hooks arent exactly easy either.. if redefine the macro in terms of a target hook, but then you are pushing the resolution out to run time... ie: #ifndef NO_DOT_IN_LABEL #define AUTO_TEMP_NAME "_.tmp_" #else #ifndef NO_DOLLAR_IN_LABEL #define AUTO_TEMP_NAME "__$tmp_" #else #define AUTO_TEMP_NAME "__tmp_" #endif becomes something like: #define AUTO_TEMP_NAME (!no_dot_in_label_hook() ? "_.tmp_" : (!no_dollar_in_label_hook() ? "_$tmp_" : "__tmp_")) a C if () has similar issues, but at least can be optimized #define AUTO_TEMP_NAME (!NO_DOT_IN_LABEL ? "_.tmp_" : (!NO_DOLLAR_IN_LABEL ? "_$tmp_" : "__tmp_")) I'm not crazy about most of the options we have... Slightly orthogonal to this, but more related to what I'm actually trying to accomplish in the short term... (man there are a lot of rat holes one can descend...) maybe we can provide a fe-tm.h which is generated from tm.h and contains a #define for each of macro that the front ends consume... so during a build, we have a generator something like: #include "tm.h" <...> fprintf (fe_defaults, "#define NO_DOLLAR_IN_LABEL %s\n", properly_reformat_macro_string (#NO_DOLLAR_IN_LABEL)); or something like that, and define all the macros that are required by the front end this way. Then there are no backeend include dependencies to compile the front ends (as far as target macros go) Everywhere that includes tm.h in the front ends would instead include fe-tm.h. I've been struggling with exactly how to separate the front end in a practical way. I'm currently experimenting with providing a fe-interface.[ch] files which contain copies of the prototypes for whatever backend routines are needed, as well as prototypes for wrappers to access BE structures so that we don't need to expose all the gory bits to the front end. I have managed to remove function.h by providing just a few access routines and a couple of prototypes from function.h If I continue to pursue that, we would end up with fe-interface.h which contains a list of all the back end data structures and routines which are used. (ignoring tree.[ch] for the moment since it's a beast of its own...) a "fe-tm.h" or the equivalent would fit with that model. we could then look at all these interface requirements as a whole and perhaps figure out a better way of structuring them... Andrew
On Tue, 23 Sep 2014, Andrew MacLeod wrote: > if() and target hooks arent exactly easy either.. Indeed - but I think the modularity goal is for the vast bulk of target macros to become hooks (not necessarily a one-to-one conversion, in some cases the right representation of the semantics may need to be rethought as part of the conversion to a hook). Among other things a hook has defined return type, defined argument type and uses all its arguments at the call site, so avoiding various cases of failure to build depending on the configured target because of warnings depending on the target macros in use. There are about 680 target macros at present. My most recent data indicates 154 of them are used in front ends (144 if you ignore front end drivers) - list appended (may have false positives and false negatives). If a few do not become hooks, the implication is that there are limited, well-defined parts of the compiler (RTL parts?) that need to be built separately for each target in a multi-target configuration. For proper front end and back end separation there would be other issues to deal with as well, such as how option handling presently expects all options to go in a single OPT_* enum and a single array of option data (and the generated options header has contents relating to all parts of the compiler visible everywhere). > if redefine the macro in terms of a target hook, but then you are pushing the > resolution out to run time... ie: Yes. In the bulk of cases this should not have significant performance impact (and there is always the option of getting LTO to devirtualize them). > maybe we can provide a fe-tm.h which is generated from tm.h and contains a > #define for each of macro that the front ends consume... > so during a build, we have a generator something like: > > #include "tm.h" > <...> > fprintf (fe_defaults, "#define NO_DOLLAR_IN_LABEL %s\n", > properly_reformat_macro_string (#NO_DOLLAR_IN_LABEL)); Target macros often use other macros that may be defined in tm.h; I don't think there's any ready way for a generator to extract macro definitions. > I've been struggling with exactly how to separate the front end in a practical > way. I'm currently experimenting with providing a fe-interface.[ch] files To a first approximation, 154 hook conversion patches. There are ways to reduce that number. I've been adding various target macro references to c-cppbuilting.c lately in order to predefine macros with -fbuilding-libgcc to reduce use of tm.h in code built for the target. It may well be possible for more of the predefined macros currently defined through c-cppbuiltin.c to move to cppbuiltin.c (this makes them visible when Fortran is being preprocessed, but at least for -fbuilding-libgcc that's harmless - no-one should actually use -fbuilding-libgcc for Fortran). In other cases, you may be able to avoid the target macro in the front end without changing it to a hook elsewhere. For example, if a front end refers to INT_TYPE_SIZE, this can change to TYPE_PRECISION (integer_type_node) unless it's in code that may execute before integer_type_node is set up. In other cases, many macros may convert to a single hook. That would be the case with stdint.h types, for example - you don't want separate hooks for each of INT_FAST8_TYPE, INT_LEAST32_TYPE, etc.; there have been some past discussions of appropriate hook design in such cases. Much easier than avoiding target macro use in front ends would be a clean separation of target macros used in the driver from those used elsewere. Of the 78 target macros use in the driver (mostly *_SPEC), only about 12 are used elsewhere. It would be quite plausible for the driver's target macros to go in driver/config/. To do that, you'd need refactoring code that understands the structure of .h files at the preprocessor level, so it can tell when a macro is being conditionally defined / undefined / redefined, copy the conditionals along with the definition, and also copy out other macros on which those conditionals depend. Some cleanup would no doubt be needed first - eliminating uses of a few macros in code built for the target, moving macros used in multiple places to hooks in targetm_common - but much less than for stopping front ends using target macros. (There would also be a need to ensure every target gets a set of driver/config headers used in the driver that corresponds appropriately to the set of config/ headers used elsewhere.) I think many (hundreds) of target macros could be converted to hooks through such a semi-automated refactoring process with tools understanding the preprocessor structure of .h files. The main obstructions I see to doing so are: (a) target macros used in code built for the target (which I've been working on lately; I'd welcome more people picking up pieces from the list at <https://gcc.gnu.org/wiki/Top-Level_Libgcc_Migration>, especially (i) libobjc (PR 24775), (ii) architecture-specific cases); (b) target macros used in the driver (but as noted above, a separate refactoring could separate most of those from the main tm.h, once those used in other places are dealt with separately); (c) target macros used in #if, directly or indirectly through being in the expansion of another macro used in #if (where many could readily be converted to the pattern of a single default definition in defaults.h, so that it's easy for the refactoring process to tell how to convert to a hook). ADA_LONG_TYPE_SIZE FrontEnd ADJUST_FIELD_ALIGN FrontEnd MiddleEnd Target ASM_COMMENT_START Defaults FrontEnd MiddleEnd ASM_FORMAT_PRIVATE_NAME Defaults FrontEnd MiddleEnd ASM_OUTPUT_DEF Defaults FrontEnd MiddleEnd ATTRIBUTE_ALIGNED_VALUE Defaults FrontEnd BIGGEST_ALIGNMENT Defaults FrontEnd MiddleEnd BIGGEST_FIELD_ALIGNMENT FrontEnd MiddleEnd Target BITS_BIG_ENDIAN FrontEnd MiddleEnd BITS_PER_WORD Defaults FrontEnd MiddleEnd Target BOOL_TYPE_SIZE Defaults FrontEnd MiddleEnd BYTES_BIG_ENDIAN Defaults FrontEnd MiddleEnd CHAR16_TYPE FrontEnd CHAR32_TYPE FrontEnd CHAR_TYPE_SIZE Defaults FrontEnd MiddleEnd CPLUSPLUS_CPP_SPEC Defaults FrontEndDriver CTORS_SECTION_ASM_OP FrontEnd MiddleEnd C_COMMON_OVERRIDE_OPTIONS FrontEnd DATA_ABI_ALIGNMENT FrontEnd MiddleEnd DEFAULT_ABI FrontEnd DOLLARS_IN_IDENTIFIERS FrontEnd DONT_USE_BUILTIN_SETJMP FrontEnd MiddleEnd DOUBLE_TYPE_SIZE Defaults FrontEnd MiddleEnd DTORS_SECTION_ASM_OP FrontEnd MiddleEnd DWARF2_UNWIND_INFO Defaults FrontEnd MiddleEnd Target DWARF_ALT_FRAME_RETURN_COLUMN FrontEnd MiddleEnd DWARF_FRAME_REGISTERS Defaults FrontEnd MiddleEnd EH_FRAME_SECTION_NAME Defaults FrontEnd MiddleEnd EH_RETURN_STACKADJ_RTX FrontEnd MiddleEnd EH_TABLES_CAN_BE_READ_ONLY Defaults FrontEnd MiddleEnd FLOAT_TYPE_SIZE Defaults FrontEnd MiddleEnd FLOAT_WORDS_BIG_ENDIAN Defaults FrontEnd MiddleEnd FUNCTION_BOUNDARY Defaults FrontEnd MiddleEnd HANDLE_PRAGMA_PACK_WITH_EXPANSION FrontEnd HAVE_sync_compare_and_swaphi FrontEnd HAVE_sync_compare_and_swapqi FrontEnd HAVE_sync_compare_and_swapsi FrontEnd INIT_ARRAY_SECTION_ASM_OP FrontEnd MiddleEnd INIT_SECTION_ASM_OP FrontEnd MiddleEnd INT16_TYPE Defaults FrontEnd INT32_TYPE Defaults FrontEnd INT64_TYPE Defaults FrontEnd INT8_TYPE Defaults FrontEnd INTMAX_TYPE Defaults FrontEnd INTPTR_TYPE Defaults FrontEnd INT_FAST16_TYPE Defaults FrontEnd INT_FAST32_TYPE Defaults FrontEnd INT_FAST64_TYPE Defaults FrontEnd INT_FAST8_TYPE Defaults FrontEnd INT_LEAST16_TYPE Defaults FrontEnd INT_LEAST32_TYPE Defaults FrontEnd INT_LEAST64_TYPE Defaults FrontEnd INT_LEAST8_TYPE Defaults FrontEnd INT_TYPE_SIZE Defaults FrontEnd MiddleEnd JCR_SECTION_NAME Defaults FrontEnd JMP_BUF_SIZE FrontEnd MiddleEnd LIBSTDCXX FrontEndDriver LIBSTDCXX_STATIC FrontEndDriver LONG_DOUBLE_TYPE_SIZE Defaults FrontEnd MiddleEnd Target LONG_LONG_TYPE_SIZE Defaults FrontEnd MiddleEnd Target LONG_TYPE_SIZE Defaults FrontEnd MiddleEnd MAIN_STACK_BOUNDARY FrontEnd MALLOC_ABI_ALIGNMENT Defaults FrontEnd MiddleEnd MATH_LIBRARY FrontEndDriver MATH_LIBRARY_PROFILE FrontEndDriver MAX_BITS_PER_WORD Defaults FrontEnd MiddleEnd MAX_FIXED_MODE_SIZE Defaults FrontEnd MiddleEnd MAX_OFILE_ALIGNMENT Defaults FrontEnd MiddleEnd MAX_STACK_ALIGNMENT Defaults FrontEnd MiddleEnd MINIMUM_ATOMIC_ALIGNMENT FrontEnd MODIFIED_WCHAR_TYPE FrontEnd MODIFY_JNI_METHOD_CALL FrontEnd MULTIPLE_SYMBOL_SPACES Defaults FrontEnd NO_DOLLAR_IN_LABEL Defaults Driver FrontEnd MiddleEnd NO_DOT_IN_LABEL Defaults Driver FrontEnd MiddleEnd NO_IMPLICIT_EXTERN_C FrontEnd OBJC_GEN_METHOD_LABEL FrontEnd OBJC_JBLEN FrontEnd OFFS_ASSIGNIVAR_FAST FrontEnd OFFS_MSGSEND_FAST FrontEnd PARM_BOUNDARY Defaults FrontEnd MiddleEnd PCC_BITFIELD_TYPE_MATTERS FrontEnd MiddleEnd Target PCC_STATIC_STRUCT_RETURN FrontEnd MiddleEnd PID_TYPE Defaults FrontEnd POINTER_SIZE Defaults FrontEnd MiddleEnd PREFERRED_STACK_BOUNDARY Defaults FrontEnd MiddleEnd PTRDIFF_TYPE Defaults FrontEnd PUSH_ARGS_REVERSED Defaults FrontEnd MiddleEnd Pmode Defaults FrontEnd MiddleEnd REGISTER_PREFIX FrontEnd MiddleEnd REGISTER_TARGET_PRAGMAS FrontEnd SHORT_TYPE_SIZE Defaults FrontEnd MiddleEnd SIG_ATOMIC_TYPE Defaults FrontEnd SIZE_TYPE Defaults FrontEnd MiddleEnd STACK_CHECK_MAX_VAR_SIZE Defaults FrontEnd MiddleEnd STACK_GROWS_DOWNWARD Defaults FrontEnd MiddleEnd STACK_POINTER_REGNUM FrontEnd MiddleEnd STDC_0_IN_SYSTEM_HEADERS FrontEnd STRICT_ALIGNMENT Defaults FrontEnd MiddleEnd SUPPORTS_INIT_PRIORITY Defaults FrontEnd SUPPORTS_ONE_ONLY Defaults FrontEnd MiddleEnd SUPPORTS_WEAK Defaults FrontEnd Target TARGET_64BIT Driver FrontEnd MiddleEnd Target TARGET_ALIGN_NATURAL FrontEnd Target TARGET_CAN_SPLIT_STACK FrontEndDriver TARGET_CPU_CPP_BUILTINS FrontEnd TARGET_DECLSPEC Defaults FrontEnd TARGET_DEC_EVAL_METHOD Defaults FrontEnd TARGET_DLLIMPORT_DECL_ATTRIBUTES Defaults FrontEnd MiddleEnd TARGET_EXECUTABLE_SUFFIX Driver FrontEnd Target TARGET_FLT_EVAL_METHOD Defaults FrontEnd MiddleEnd TARGET_FLT_EVAL_METHOD_NON_DEFAULT FrontEnd TARGET_FORMAT_TYPES FrontEnd TARGET_N_FORMAT_TYPES FrontEnd TARGET_OBJECT_SUFFIX Driver FrontEnd Target TARGET_OBJFMT_CPP_BUILTINS FrontEnd TARGET_OPTF FrontEnd TARGET_OS_CPP_BUILTINS FrontEnd TARGET_OVERRIDES_FORMAT_ATTRIBUTES FrontEnd TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT FrontEnd TARGET_OVERRIDES_FORMAT_INIT FrontEnd TARGET_PTRMEMFUNC_VBIT_LOCATION Defaults FrontEnd MiddleEnd TARGET_SOLARIS FrontEndDriver TARGET_USE_JCR_SECTION Defaults FrontEnd Target TARGET_USE_LOCAL_THUNK_ALIAS_P Defaults FrontEnd TARGET_VTABLE_DATA_ENTRY_DISTANCE Defaults FrontEnd TARGET_VTABLE_ENTRY_ALIGN Defaults FrontEnd TARGET_VTABLE_USES_DESCRIPTORS Defaults FrontEnd TARGET_VXWORKS_RTP FrontEndDriver TARGET_WEAK_NOT_IN_ARCHIVE_TOC Defaults FrontEnd TEXT_SECTION_ASM_OP FrontEnd MiddleEnd TIME_LIBRARY FrontEndDriver TRAMPOLINE_ALIGNMENT Defaults FrontEnd MiddleEnd TRAMPOLINE_SIZE FrontEnd MiddleEnd UINT16_TYPE Defaults FrontEnd UINT32_TYPE Defaults FrontEnd UINT64_TYPE Defaults FrontEnd UINT8_TYPE Defaults FrontEnd UINTMAX_TYPE Defaults FrontEnd UINTPTR_TYPE Defaults FrontEnd UINT_FAST16_TYPE Defaults FrontEnd UINT_FAST32_TYPE Defaults FrontEnd UINT_FAST64_TYPE Defaults FrontEnd UINT_FAST8_TYPE Defaults FrontEnd UINT_LEAST16_TYPE Defaults FrontEnd UINT_LEAST32_TYPE Defaults FrontEnd UINT_LEAST64_TYPE Defaults FrontEnd UINT_LEAST8_TYPE Defaults FrontEnd UNITS_PER_WORD Defaults FrontEnd MiddleEnd Target USE_GLD FrontEndDriver WCHAR_TYPE_SIZE Defaults FrontEnd WIDEST_HARDWARE_FP_SIZE FrontEnd Target WINT_TYPE Defaults FrontEnd WORDS_BIG_ENDIAN Defaults FrontEnd MiddleEnd
* defaults.h (HAVE_PRE_INCREMENT, HAVE_PRE_DECREMENT, HAVE_POST_INCREMENT, HAVE_POST_DECREMENT, HAVE_POST_MODIFY_DISP, HAVE_POST_MODIFY_REG, HAVE_PRE_MODIFY_DISP, HAVE_PRE_MODIFY_REG, USE_LOAD_POST_INCREMENT, USE_LOAD_POST_DECREMENT, USE_LOAD_PRE_INCREMENT, USE_LOAD_PRE_DECREMENT, USE_STORE_POST_INCREMENT, USE_STORE_POST_DECREMENT, USE_STORE_PRE_INCREMENT, USE_STORE_PRE_DECREMENT, HARD_FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_IS_FRAME_POINTER, HARD_FRAME_POINTER_IS_ARG_POINTER): Relocate from rtl.h. * rtl.h: Move default definitions to defaults.h. (AUTO_INC_DEC): Adjust defintion check to assumed defaults exist. Index: defaults.h =================================================================== *** defaults.h (revision 215355) --- defaults.h (working copy) *************** see the files COPYING3 and COPYING.RUNTI *** 1168,1173 **** --- 1168,1264 ---- #define DEFAULT_PCC_STRUCT_RETURN 1 #endif + #ifndef HAVE_PRE_INCREMENT + #define HAVE_PRE_INCREMENT 0 + #endif + + #ifndef HAVE_PRE_DECREMENT + #define HAVE_PRE_DECREMENT 0 + #endif + + #ifndef HAVE_POST_INCREMENT + #define HAVE_POST_INCREMENT 0 + #endif + + #ifndef HAVE_POST_DECREMENT + #define HAVE_POST_DECREMENT 0 + #endif + + #ifndef HAVE_POST_MODIFY_DISP + #define HAVE_POST_MODIFY_DISP 0 + #endif + + #ifndef HAVE_POST_MODIFY_REG + #define HAVE_POST_MODIFY_REG 0 + #endif + + #ifndef HAVE_PRE_MODIFY_DISP + #define HAVE_PRE_MODIFY_DISP 0 + #endif + + #ifndef HAVE_PRE_MODIFY_REG + #define HAVE_PRE_MODIFY_REG 0 + #endif + + /* Some architectures do not have complete pre/post increment/decrement + instruction sets, or only move some modes efficiently. These macros + allow us to tune autoincrement generation. */ + + #ifndef USE_LOAD_POST_INCREMENT + #define USE_LOAD_POST_INCREMENT(MODE) HAVE_POST_INCREMENT + #endif + + #ifndef USE_LOAD_POST_DECREMENT + #define USE_LOAD_POST_DECREMENT(MODE) HAVE_POST_DECREMENT + #endif + + #ifndef USE_LOAD_PRE_INCREMENT + #define USE_LOAD_PRE_INCREMENT(MODE) HAVE_PRE_INCREMENT + #endif + + #ifndef USE_LOAD_PRE_DECREMENT + #define USE_LOAD_PRE_DECREMENT(MODE) HAVE_PRE_DECREMENT + #endif + + #ifndef USE_STORE_POST_INCREMENT + #define USE_STORE_POST_INCREMENT(MODE) HAVE_POST_INCREMENT + #endif + + #ifndef USE_STORE_POST_DECREMENT + #define USE_STORE_POST_DECREMENT(MODE) HAVE_POST_DECREMENT + #endif + + #ifndef USE_STORE_PRE_INCREMENT + #define USE_STORE_PRE_INCREMENT(MODE) HAVE_PRE_INCREMENT + #endif + + #ifndef USE_STORE_PRE_DECREMENT + #define USE_STORE_PRE_DECREMENT(MODE) HAVE_PRE_DECREMENT + #endif + + /* If HARD_FRAME_POINTER_REGNUM is defined, then a special dummy reg + is used to represent the frame pointer. This is because the + hard frame pointer and the automatic variables are separated by an amount + that cannot be determined until after register allocation. We can assume + that in this case ELIMINABLE_REGS will be defined, one action of which + will be to eliminate FRAME_POINTER_REGNUM into HARD_FRAME_POINTER_REGNUM. */ + #ifndef HARD_FRAME_POINTER_REGNUM + #define HARD_FRAME_POINTER_REGNUM FRAME_POINTER_REGNUM + #endif + + #ifndef HARD_FRAME_POINTER_IS_FRAME_POINTER + #define HARD_FRAME_POINTER_IS_FRAME_POINTER \ + (HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM) + #endif + + #ifndef HARD_FRAME_POINTER_IS_ARG_POINTER + #define HARD_FRAME_POINTER_IS_ARG_POINTER \ + (HARD_FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM) + #endif + + + + #ifdef GCC_INSN_FLAGS_H /* Dependent default target macro definitions Index: rtl.h =================================================================== *** rtl.h (revision 215355) --- rtl.h (working copy) *************** do { \ *** 2390,2399 **** /* Indicate whether the machine has any sort of auto increment addressing. If not, we can avoid checking for REG_INC notes. */ ! #if (defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT) \ ! || defined (HAVE_POST_INCREMENT) || defined (HAVE_POST_DECREMENT) \ ! || defined (HAVE_PRE_MODIFY_DISP) || defined (HAVE_POST_MODIFY_DISP) \ ! || defined (HAVE_PRE_MODIFY_REG) || defined (HAVE_POST_MODIFY_REG)) #define AUTO_INC_DEC #endif --- 2390,2399 ---- /* Indicate whether the machine has any sort of auto increment addressing. If not, we can avoid checking for REG_INC notes. */ ! #if (HAVE_PRE_INCREMENT || HAVE_PRE_DECREMENT \ ! || HAVE_POST_INCREMENT || HAVE_POST_DECREMENT \ ! || HAVE_PRE_MODIFY_DISP || HAVE_POST_MODIFY_DISP \ ! || HAVE_PRE_MODIFY_REG || HAVE_POST_MODIFY_REG) #define AUTO_INC_DEC #endif *************** do { \ *** 2408,2482 **** #else #define FIND_REG_INC_NOTE(INSN, REG) 0 #endif - - #ifndef HAVE_PRE_INCREMENT - #define HAVE_PRE_INCREMENT 0 - #endif - - #ifndef HAVE_PRE_DECREMENT - #define HAVE_PRE_DECREMENT 0 - #endif - - #ifndef HAVE_POST_INCREMENT - #define HAVE_POST_INCREMENT 0 - #endif - - #ifndef HAVE_POST_DECREMENT - #define HAVE_POST_DECREMENT 0 - #endif - - #ifndef HAVE_POST_MODIFY_DISP - #define HAVE_POST_MODIFY_DISP 0 - #endif - - #ifndef HAVE_POST_MODIFY_REG - #define HAVE_POST_MODIFY_REG 0 - #endif - - #ifndef HAVE_PRE_MODIFY_DISP - #define HAVE_PRE_MODIFY_DISP 0 - #endif - - #ifndef HAVE_PRE_MODIFY_REG - #define HAVE_PRE_MODIFY_REG 0 - #endif - - - /* Some architectures do not have complete pre/post increment/decrement - instruction sets, or only move some modes efficiently. These macros - allow us to tune autoincrement generation. */ - - #ifndef USE_LOAD_POST_INCREMENT - #define USE_LOAD_POST_INCREMENT(MODE) HAVE_POST_INCREMENT - #endif - - #ifndef USE_LOAD_POST_DECREMENT - #define USE_LOAD_POST_DECREMENT(MODE) HAVE_POST_DECREMENT - #endif - - #ifndef USE_LOAD_PRE_INCREMENT - #define USE_LOAD_PRE_INCREMENT(MODE) HAVE_PRE_INCREMENT - #endif - - #ifndef USE_LOAD_PRE_DECREMENT - #define USE_LOAD_PRE_DECREMENT(MODE) HAVE_PRE_DECREMENT - #endif - - #ifndef USE_STORE_POST_INCREMENT - #define USE_STORE_POST_INCREMENT(MODE) HAVE_POST_INCREMENT - #endif - - #ifndef USE_STORE_POST_DECREMENT - #define USE_STORE_POST_DECREMENT(MODE) HAVE_POST_DECREMENT - #endif - - #ifndef USE_STORE_PRE_INCREMENT - #define USE_STORE_PRE_INCREMENT(MODE) HAVE_PRE_INCREMENT - #endif - - #ifndef USE_STORE_PRE_DECREMENT - #define USE_STORE_PRE_DECREMENT(MODE) HAVE_PRE_DECREMENT - #endif /* Nonzero when we are generating CONCATs. */ extern int generating_concat_p; --- 2408,2413 ---- *************** extern GTY(()) rtx cc0_rtx; *** 2954,2979 **** extern GTY(()) rtx ret_rtx; extern GTY(()) rtx simple_return_rtx; - /* If HARD_FRAME_POINTER_REGNUM is defined, then a special dummy reg - is used to represent the frame pointer. This is because the - hard frame pointer and the automatic variables are separated by an amount - that cannot be determined until after register allocation. We can assume - that in this case ELIMINABLE_REGS will be defined, one action of which - will be to eliminate FRAME_POINTER_REGNUM into HARD_FRAME_POINTER_REGNUM. */ - #ifndef HARD_FRAME_POINTER_REGNUM - #define HARD_FRAME_POINTER_REGNUM FRAME_POINTER_REGNUM - #endif - - #ifndef HARD_FRAME_POINTER_IS_FRAME_POINTER - #define HARD_FRAME_POINTER_IS_FRAME_POINTER \ - (HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM) - #endif - - #ifndef HARD_FRAME_POINTER_IS_ARG_POINTER - #define HARD_FRAME_POINTER_IS_ARG_POINTER \ - (HARD_FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM) - #endif - /* Index labels for global_rtl. */ enum global_rtl_index { --- 2885,2890 ----