Home | History | Annotate | Line # | Download | only in gcc
opth-gen.awk revision 1.12
      1 #  Copyright (C) 2003-2020 Free Software Foundation, Inc.
      2 #  Contributed by Kelley Cook, June 2004.
      3 #  Original code from Neil Booth, May 2003.
      4 #
      5 # This program is free software; you can redistribute it and/or modify it
      6 # under the terms of the GNU General Public License as published by the
      7 # Free Software Foundation; either version 3, or (at your option) any
      8 # later version.
      9 # 
     10 # This program is distributed in the hope that it will be useful,
     11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 # GNU General Public License for more details.
     14 # 
     15 # You should have received a copy of the GNU General Public License
     16 # along with this program; see the file COPYING3.  If not see
     17 # <http://www.gnu.org/licenses/>.
     18 
     19 # This Awk script reads in the option records generated from 
     20 # opt-gather.awk, combines the flags of duplicate options and generates a
     21 # C header file.
     22 #
     23 # This program uses functions from opt-functions.awk and code from
     24 # opt-read.awk.
     25 # Usage: awk -f opt-functions.awk -f opt-read.awk -f opth-gen.awk \
     26 #            < inputfile > options.h
     27 
     28 # Dump out an enumeration into a .h file.
     29 # Combine the flags of duplicate options.
     30 END {
     31 print "/* This file is auto-generated by opth-gen.awk.  */"
     32 print ""
     33 print "#ifndef OPTIONS_H"
     34 print "#define OPTIONS_H"
     35 print ""
     36 print "#include \"flag-types.h\""
     37 print ""
     38 
     39 if (n_extra_h_includes > 0) {
     40 	for (i = 0; i < n_extra_h_includes; i++) {
     41 		print "#include " quote extra_h_includes[i] quote
     42 	}
     43 	print ""
     44 }
     45 
     46 print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)"
     47 print "#ifndef GENERATOR_FILE"
     48 print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)"
     49 print "struct GTY(()) gcc_options"
     50 print "#else"
     51 print "struct gcc_options"
     52 print "#endif"
     53 print "{"
     54 print "#endif"
     55 
     56 for (i = 0; i < n_extra_vars; i++) {
     57 	var = extra_vars[i]
     58 	sub(" *=.*", "", var)
     59 	orig_var = var
     60 	name = var
     61 	type = var
     62 	type_after = var
     63 	sub("^.*[ *]", "", name)
     64 	sub("\\[.*\\]$", "", name)
     65 	sub("\\[.*\\]$", "", type)
     66 	sub(" *" name "$", "", type)
     67 	sub("^.*" name, "", type_after)
     68 	var_seen[name] = 1
     69 	print "#ifdef GENERATOR_FILE"
     70 	print "extern " orig_var ";"
     71 	print "#else"
     72 	print "  " type " x_" name type_after ";"
     73 	print "#define " name " global_options.x_" name
     74 	print "#endif"
     75 }
     76 
     77 for (i = 0; i < n_opts; i++) {
     78 	if (flag_set_p("Save", flags[i]))
     79 		have_save = 1;
     80 
     81 	name = var_name(flags[i]);
     82 	if (name == "")
     83 		continue;
     84 
     85 	if (name in var_seen)
     86 		continue;
     87 
     88 	var_seen[name] = 1;
     89 	print "#ifdef GENERATOR_FILE"
     90 	print "extern " var_type(flags[i]) name ";"
     91 	print "#else"
     92 	print "  " var_type(flags[i]) "x_" name ";"
     93 	print "#define " name " global_options.x_" name
     94 	print "#endif"
     95 }
     96 for (i = 0; i < n_opts; i++) {
     97 	name = static_var(opts[i], flags[i]);
     98 	if (name != "") {
     99 		print "#ifndef GENERATOR_FILE"
    100 		print "  " var_type(flags[i]) "x_" name ";"
    101 		print "#define x_" name " do_not_use"
    102 		print "#endif"
    103 	}
    104 }
    105 for (i = 0; i < n_opts; i++) {
    106 	if (flag_set_p("SetByCombined", flags[i])) {
    107 		print "#ifndef GENERATOR_FILE"
    108 		print "  bool frontend_set_" var_name(flags[i]) ";"
    109 		print "#endif"
    110 	}
    111 }
    112 print "#ifndef GENERATOR_FILE"
    113 print "};"
    114 print "extern struct gcc_options global_options;"
    115 print "extern const struct gcc_options global_options_init;"
    116 print "extern struct gcc_options global_options_set;"
    117 print "#define target_flags_explicit global_options_set.x_target_flags"
    118 print "#endif"
    119 print "#endif"
    120 print ""
    121 
    122 # All of the optimization switches gathered together so they can be saved and restored.
    123 # This will allow attribute((cold)) to turn on space optimization.
    124 
    125 # Change the type of normal switches from int to unsigned char to save space.
    126 # Also, order the structure so that pointer fields occur first, then int
    127 # fields, and then char fields to provide the best packing.
    128 
    129 print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)"
    130 print ""
    131 print "/* Structure to save/restore optimization and target specific options.  */";
    132 print "struct GTY(()) cl_optimization";
    133 print "{";
    134 
    135 n_opt_char = 4;
    136 n_opt_short = 0;
    137 n_opt_int = 0;
    138 n_opt_enum = 0;
    139 n_opt_other = 0;
    140 var_opt_char[0] = "unsigned char x_optimize";
    141 var_opt_char[1] = "unsigned char x_optimize_size";
    142 var_opt_char[2] = "unsigned char x_optimize_debug";
    143 var_opt_char[3] = "unsigned char x_optimize_fast";
    144 
    145 for (i = 0; i < n_opts; i++) {
    146 	if (flag_set_p("(Optimization|PerFunction)", flags[i])) {
    147 		name = var_name(flags[i])
    148 		if(name == "")
    149 			continue;
    150 
    151 		if(name in var_opt_seen)
    152 			continue;
    153 
    154 		var_opt_seen[name]++;
    155 		otype = var_type_struct(flags[i]);
    156 		if (otype ~ "^((un)?signed +)?int *$")
    157 			var_opt_int[n_opt_int++] = otype "x_" name;
    158 
    159 		else if (otype ~ "^((un)?signed +)?short *$")
    160 			var_opt_short[n_opt_short++] = otype "x_" name;
    161 
    162 		else if (otype ~ "^((un)?signed +)?char *$")
    163 			var_opt_char[n_opt_char++] = otype "x_" name;
    164 
    165 		else if (otype ~ ("^enum +[_" alnum "]+ *$"))
    166 			var_opt_enum[n_opt_enum++] = otype "x_" name;
    167 
    168 		else
    169 			var_opt_other[n_opt_other++] = otype "x_" name;
    170 	}
    171 }
    172 
    173 for (i = 0; i < n_opt_other; i++) {
    174 	print "  " var_opt_other[i] ";";
    175 }
    176 
    177 for (i = 0; i < n_opt_int; i++) {
    178 	print "  " var_opt_int[i] ";";
    179 }
    180 
    181 for (i = 0; i < n_opt_enum; i++) {
    182 	print "  " var_opt_enum[i] ";";
    183 }
    184 
    185 for (i = 0; i < n_opt_short; i++) {
    186 	print "  " var_opt_short[i] ";";
    187 }
    188 
    189 for (i = 0; i < n_opt_char; i++) {
    190 	print "  " var_opt_char[i] ";";
    191 }
    192 
    193 print "};";
    194 print "";
    195 
    196 # Target and optimization save/restore/print functions.
    197 print "/* Structure to save/restore selected target specific options.  */";
    198 print "struct GTY(()) cl_target_option";
    199 print "{";
    200 
    201 n_target_char = 0;
    202 n_target_short = 0;
    203 n_target_int = 0;
    204 n_target_enum = 0;
    205 n_target_other = 0;
    206 
    207 for (i = 0; i < n_target_save; i++) {
    208 	if (target_save_decl[i] ~ "^((un)?signed +)?int +[_" alnum "]+$")
    209 		var_target_int[n_target_int++] = target_save_decl[i];
    210 
    211 	else if (target_save_decl[i] ~ "^((un)?signed +)?short +[_" alnum "]+$")
    212 		var_target_short[n_target_short++] = target_save_decl[i];
    213 
    214 	else if (target_save_decl[i] ~ "^((un)?signed +)?char +[_ " alnum "]+$")
    215 		var_target_char[n_target_char++] = target_save_decl[i];
    216 
    217 	else if (target_save_decl[i] ~ ("^enum +[_" alnum "]+ +[_" alnum "]+$")) {
    218 		var_target_enum[n_target_enum++] = target_save_decl[i];
    219 	}
    220 	else
    221 		var_target_other[n_target_other++] = target_save_decl[i];
    222 }
    223 
    224 if (have_save) {
    225 	for (i = 0; i < n_opts; i++) {
    226 		if (flag_set_p("Save", flags[i])) {
    227 			name = var_name(flags[i])
    228 			if(name == "")
    229 				name = "target_flags";
    230 
    231 			if(name in var_save_seen)
    232 				continue;
    233 
    234 			var_save_seen[name]++;
    235 			otype = var_type_struct(flags[i])
    236 			if (otype ~ "^((un)?signed +)?int *$")
    237 				var_target_int[n_target_int++] = otype "x_" name;
    238 
    239 			else if (otype ~ "^((un)?signed +)?short *$")
    240 				var_target_short[n_target_short++] = otype "x_" name;
    241 
    242 			else if (otype ~ "^((un)?signed +)?char *$")
    243 				var_target_char[n_target_char++] = otype "x_" name;
    244 
    245 			else if (otype ~ ("^enum +[_" alnum "]+ +[_" alnum "]+"))
    246 				var_target_enum[n_target_enum++] = otype "x_" name;
    247 
    248 			else
    249 				var_target_other[n_target_other++] = otype "x_" name;
    250 		}
    251 	}
    252 } else {
    253 	var_target_int[n_target_int++] = "int x_target_flags";
    254 }
    255 
    256 for (i = 0; i < n_target_other; i++) {
    257 	print "  " var_target_other[i] ";";
    258 }
    259 
    260 for (i = 0; i < n_target_enum; i++) {
    261 	print "  " var_target_enum[i] ";";
    262 }
    263 
    264 for (i = 0; i < n_target_int; i++) {
    265 	print "  " var_target_int[i] ";";
    266 }
    267 
    268 for (i = 0; i < n_target_short; i++) {
    269 	print "  " var_target_short[i] ";";
    270 }
    271 
    272 for (i = 0; i < n_target_char; i++) {
    273 	print "  " var_target_char[i] ";";
    274 }
    275 
    276 print "};";
    277 print "";
    278 print "";
    279 print "/* Save optimization variables into a structure.  */"
    280 print "extern void cl_optimization_save (struct cl_optimization *, struct gcc_options *);";
    281 print "";
    282 print "/* Restore optimization variables from a structure.  */";
    283 print "extern void cl_optimization_restore (struct gcc_options *, struct cl_optimization *);";
    284 print "";
    285 print "/* Print optimization variables from a structure.  */";
    286 print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);";
    287 print "";
    288 print "/* Print different optimization variables from structures provided as arguments.  */";
    289 print "extern void cl_optimization_print_diff (FILE *, int, cl_optimization *ptr1, cl_optimization *ptr2);";
    290 print "";
    291 print "/* Save selected option variables into a structure.  */"
    292 print "extern void cl_target_option_save (struct cl_target_option *, struct gcc_options *);";
    293 print "";
    294 print "/* Restore selected option variables from a structure.  */"
    295 print "extern void cl_target_option_restore (struct gcc_options *, struct cl_target_option *);";
    296 print "";
    297 print "/* Print target option variables from a structure.  */";
    298 print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);";
    299 print "";
    300 print "/* Print different target option variables from structures provided as arguments.  */";
    301 print "extern void cl_target_option_print_diff (FILE *, int, cl_target_option *ptr1, cl_target_option *ptr2);";
    302 print "";
    303 print "/* Compare two target option variables from a structure.  */";
    304 print "extern bool cl_target_option_eq (const struct cl_target_option *, const struct cl_target_option *);";
    305 print "";
    306 print "/* Free heap memory used by target option variables.  */";
    307 print "extern void cl_target_option_free (struct cl_target_option *);";
    308 print "";
    309 print "/* Hash option variables from a structure.  */";
    310 print "extern hashval_t cl_target_option_hash (const struct cl_target_option *);";
    311 print "";
    312 print "/* Hash optimization from a structure.  */";
    313 print "extern hashval_t cl_optimization_hash (const struct cl_optimization *);";
    314 print "";
    315 print "/* Compare two optimization options.  */";
    316 print "extern bool cl_optimization_option_eq (cl_optimization const *ptr1, cl_optimization const *ptr2);"
    317 print "";
    318 print "/* Free heap memory used by optimization options.  */";
    319 print "extern void cl_optimization_option_free (cl_optimization *ptr1);"
    320 print "";
    321 print "/* Generator files may not have access to location_t, and don't need these.  */"
    322 print "#if defined(UNKNOWN_LOCATION)"
    323 print "bool                                                                  "
    324 print "common_handle_option_auto (struct gcc_options *opts,                  "
    325 print "                           struct gcc_options *opts_set,              "
    326 print "                           const struct cl_decoded_option *decoded,   "
    327 print "                           unsigned int lang_mask, int kind,          "
    328 print "                           location_t loc,                            "
    329 print "                           const struct cl_option_handlers *handlers, "
    330 print "                           diagnostic_context *dc);                   "
    331 for (i = 0; i < n_langs; i++) {
    332     lang_name = lang_sanitized_name(langs[i]);
    333     print "bool"
    334     print lang_name "_handle_option_auto (struct gcc_options *opts,"
    335     print "                           struct gcc_options *opts_set,"
    336     print "                           size_t scode, const char *arg,"
    337     print "                           HOST_WIDE_INT value,"
    338     print "                           unsigned int lang_mask, int kind,"
    339     print "                           location_t loc,"
    340     print "                           const struct cl_option_handlers *handlers,"
    341     print "                           diagnostic_context *dc);"
    342 }
    343 print "void cpp_handle_option_auto (const struct gcc_options * opts, size_t scode,"
    344 print "                             struct cpp_options * cpp_opts);"
    345 print "void init_global_opts_from_cpp(struct gcc_options * opts,      "
    346 print "                               const struct cpp_options * cpp_opts);"    
    347 print "#endif";
    348 print "#endif";
    349 print "";
    350 
    351 for (i = 0; i < n_opts; i++) {
    352 	name = opt_args("Mask", flags[i])
    353 	if (name == "") {
    354 		opt = opt_args("InverseMask", flags[i])
    355 		if (opt ~ ",")
    356 			name = nth_arg(0, opt)
    357 		else
    358 			name = opt
    359 	}
    360 	if (name != "" && mask_bits[name] == 0) {
    361 		mask_bits[name] = 1
    362 		vname = var_name(flags[i])
    363 		mask = "MASK_"
    364 		mask_1 = "1U"
    365 		if (vname != "") {
    366 			mask = "OPTION_MASK_"
    367 			if (host_wide_int[vname] == "yes")
    368 				mask_1 = "HOST_WIDE_INT_1U"
    369 		} else
    370 			extra_mask_bits[name] = 1
    371 		print "#define " mask name " (" mask_1 " << " masknum[vname]++ ")"
    372 	}
    373 }
    374 for (i = 0; i < n_extra_masks; i++) {
    375 	if (extra_mask_bits[extra_masks[i]] == 0)
    376 		print "#define MASK_" extra_masks[i] " (1U << " masknum[""]++ ")"
    377 }
    378 
    379 for (var in masknum) {
    380 	if (var != "" && host_wide_int[var] == "yes") {
    381 		print "#if defined(HOST_BITS_PER_WIDE_INT) && " masknum[var] " > HOST_BITS_PER_WIDE_INT"
    382 		print "#error too many masks for " var
    383 		print "#endif"
    384 	}
    385 	else if (masknum[var] > 32) {
    386 		if (var == "")
    387 			print "#error too many target masks"
    388 		else
    389 			print "#error too many masks for " var
    390 	}
    391 }
    392 print ""
    393 
    394 for (i = 0; i < n_opts; i++) {
    395 	name = opt_args("Mask", flags[i])
    396 	if (name == "") {
    397 		opt = opt_args("InverseMask", flags[i])
    398 		if (opt ~ ",")
    399 			name = nth_arg(0, opt)
    400 		else
    401 			name = opt
    402 	}
    403 	if (name != "" && mask_macros[name] == 0) {
    404 		mask_macros[name] = 1
    405 		vname = var_name(flags[i])
    406 		mask = "OPTION_MASK_"
    407 		if (vname == "") {
    408 			vname = "target_flags"
    409 			mask = "MASK_"
    410 			extra_mask_macros[name] = 1
    411 		}
    412 		print "#define TARGET_" name \
    413 		      " ((" vname " & " mask name ") != 0)"
    414 		print "#define TARGET_" name "_P(" vname ")" \
    415 		      " (((" vname ") & " mask name ") != 0)"
    416 	}
    417 }
    418 for (i = 0; i < n_extra_masks; i++) {
    419 	if (extra_mask_macros[extra_masks[i]] == 0)
    420 		print "#define TARGET_" extra_masks[i] \
    421 		      " ((target_flags & MASK_" extra_masks[i] ") != 0)"
    422 }
    423 print ""
    424 
    425 for (i = 0; i < n_opts; i++) {
    426 	opt = opt_args("InverseMask", flags[i])
    427 	if (opt ~ ",") {
    428 		vname = var_name(flags[i])
    429 		mask = "OPTION_MASK_"
    430 		if (vname == "") {
    431 			vname = "target_flags"
    432 			mask = "MASK_"
    433 		}
    434 		print "#define TARGET_" nth_arg(1, opt) \
    435 		      " ((" vname " & " mask nth_arg(0, opt) ") == 0)"
    436 	}
    437 }
    438 print ""
    439 
    440 for (i = 0; i < n_langs; i++) {
    441         macros[i] = "CL_" lang_sanitized_name(langs[i])
    442 	s = substr("            ", length (macros[i]))
    443 	print "#define " macros[i] s " (1U << " i ")"
    444     }
    445 print "#define CL_LANG_ALL   ((1U << " n_langs ") - 1)"
    446 
    447 print ""
    448 print "enum opt_code"
    449 print "{"
    450 	
    451 for (i = 0; i < n_opts; i++)
    452 	back_chain[i] = "N_OPTS";
    453 
    454 enum_value = 0
    455 for (i = 0; i < n_opts; i++) {
    456 	# Combine the flags of identical switches.  Switches
    457 	# appear many times if they are handled by many front
    458 	# ends, for example.
    459 	while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
    460 		flags[i + 1] = flags[i] " " flags[i + 1];
    461 		i++;
    462 	}
    463 
    464 	len = length (opts[i]);
    465 	enum = opt_enum(opts[i])
    466 	enum_string = enum " = " enum_value ","
    467 
    468 	# Aliases do not get enumeration names.
    469 	if ((flag_set_p("Alias.*", flags[i]) \
    470 	     && !flag_set_p("SeparateAlias", flags[i])) \
    471 	    || flag_set_p("Ignore", flags[i])) {
    472 		enum_string = "/* " enum_string " */"
    473 	}
    474 
    475 	# If this switch takes joined arguments, back-chain all
    476 	# subsequent switches to it for which it is a prefix.  If
    477 	# a later switch S is a longer prefix of a switch T, T
    478 	# will be back-chained to S in a later iteration of this
    479 	# for() loop, which is what we want.
    480 	if (flag_set_p("Joined.*", flags[i])) {
    481 		for (j = i + 1; j < n_opts; j++) {
    482 			if (substr (opts[j], 1, len) != opts[i])
    483 				break;
    484 			back_chain[j] = enum;
    485 		}
    486 	}
    487 
    488 	s = substr("                                          ",
    489 		   length (enum_string))
    490 
    491 	if (help[i] == "")
    492 		hlp = "0"
    493 	else
    494 		hlp = "N_(\"" help[i] "\")";
    495 
    496 	print "  " enum_string s "/* -" opts[i] " */"
    497 	enum_value++
    498 }
    499 
    500 print "  N_OPTS,"
    501 print "  OPT_SPECIAL_unknown,"
    502 print "  OPT_SPECIAL_ignore,"
    503 print "  OPT_SPECIAL_warn_removed,"
    504 print "  OPT_SPECIAL_program_name,"
    505 print "  OPT_SPECIAL_input_file"
    506 print "};"
    507 print ""
    508 print "#ifdef GCC_C_COMMON_C"
    509 print "/* Mapping from cpp message reasons to the options that enable them.  */"
    510 print "#include <cpplib.h>"
    511 print "struct cpp_reason_option_codes_t"
    512 print "{"
    513 print "  /* cpplib message reason.  */"
    514 print "  const enum cpp_warning_reason reason;"
    515 print "  /* gcc option that controls this message.  */"
    516 print "  const int option_code;"
    517 print "};"
    518 print ""
    519 print "static const struct cpp_reason_option_codes_t cpp_reason_option_codes[] = {"
    520 for (i = 0; i < n_opts; i++) {
    521     # With identical flags, pick only the last one.  The
    522     # earlier loop ensured that it has all flags merged,
    523     # and a nonempty help text if one of the texts was nonempty.
    524     while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
    525         i++;
    526     }
    527     cpp_reason = nth_arg(0, opt_args("CppReason", flags[i]));
    528     if (cpp_reason != "") {
    529         cpp_reason = cpp_reason ",";
    530         printf("  {%-40s %s},\n", cpp_reason, opt_enum(opts[i]))
    531     }
    532 }
    533 printf("  {%-40s 0},\n", "CPP_W_NONE,")
    534 print "};"
    535 print "#endif"
    536 print ""
    537 print "#endif /* OPTIONS_H */"
    538 }
    539