While looking into PR 37565 I began to wonder if we need to modify how we handle optimization flag handling. Currently we have OVERRIDE_OPTIONS, C_COMMON_OVERRIDE_OPTIONS, and OPTIMIZATION_OPTIONS to set or override the optimization flags a user gives. One proposal to fix 37565 was to split OVERRIDE_OPTIONS into OVERRIDE_OPTIONS_ALWAYS and OVERRIDE_OPTIONS_ONCE which would create two new macros.
But I was wondering if a cleaner method to deal with these options would be to get rid of all these macros and use target functions to access flag values. My idea is that we would never change the values of the flags that are set by the user but instead would have a target overridable function that returns the value for a given flag by default but in which the return value could be overridden for some flags on some targets. So instead of if (flag_var_tracking) we would have if (targetm.get_optimization_flag_value(OPT_fvar_tracking)) The default behaviour of get_optimization_flag_value when passed OPT_fvar_tracking would be to return the value of flag_var_tracking but if a particular target didn't support this optimization they could have a target specific version of get_optimization_flag_value that always returned 0 for OPT_fvar_tracking. That way we don't have to use OVERRIDE_OPTIONS to set flag_var_tracking to 0 or worry about it getting reset by the __optimize__ attribute. Here is a patch to define the target overridable get_optimization_flag_value function as well as a set_optimization_flag_value function. I also modified opth-gen.awk and optc-gen.awk to make the flags static so that the rest of the compiler would have to use these functions. Obviously the compiler won't build after applying this patch because we would have to change all the flag references but I thought I would send this proposal out before doing any more work in that direction. What do people think? Does this seem like a reasonable direction to go? Does anyone see any blockers to this idea? If we wanted to proceed down this path it seems like we could either do it with a big bang approach (making flags static and change all accesses) or gradually by not making the flags static and gradually introducing the use of the get_optimization_flag_value function over time. 2009-05-29 Steve Ellcey <s...@cup.hp.com> PR middle-end/37565 PR target/37106 * opth-gen.awk: Remove extern decls of flags. Add decls for default_get_optimization_flag_value and set_optimization_flag_value. * optc-gen.awk: Make flags static. Define default_get_optimization_flag_value and set_optimization_flag_value. * target.h (gcc_target): Add get_optimization_flag_value. * target-def.h (TARGET_GET_OPTIMIZATION_FLAG_VALUE): New. Index: optc-gen.awk =================================================================== --- optc-gen.awk (revision 147259) +++ optc-gen.awk (working copy) @@ -534,6 +534,29 @@ print " if (targetm.target_option.print print " targetm.target_option.print (file, indent, ptr);"; print "}"; +print ""; +print "int"; +print "default_get_flag_value(enum opt_code code)"; +print "{"; +print "#ifdef ENABLE_CHECKING"; +for (i = 0; i < n_opts; i++) { + enum = "OPT_" opts[i]; + if (opts[i] == "finline-limit=" || opts[i] == "Wlarger-than=") { + enum = enum "eq"; + } + gsub ("[^A-Za-z0-9]", "_", enum); + name = var_name(flags[i]); + if (name == "") { + print " if (code == " enum ") gcc_unreachable ();"; + } + else { + print " if (code == " enum " && cl_options[(int) code].flag_var != &" name ") gcc_unreachable ();"; + } +} +print "#endif"; +print " gcc_assert(cl_options[(int) code].flag_var);"; +print " return *(cl_options[(int) code].flag_var);"; +print "}"; print "#endif"; }