Home | History | Annotate | Line # | Download | only in gcc
      1 #  Copyright (C) 2003-2022 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 file.
     22 #
     23 
     24 # This program uses functions from opt-functions.awk and code from
     25 # opt-read.awk.
     26 #
     27 # Usage: awk -f opt-functions.awk -f opt-read.awk -f optc-save-gen.awk \
     28 #            [-v header_name=header.h] < inputfile > options-save.cc
     29 
     30 # Dump that array of options into a C file.
     31 END {
     32 print "/* This file is auto-generated by optc-save-gen.awk.  */"
     33 print ""
     34 n_headers = split(header_name, headers, " ")
     35 for (i = 1; i <= n_headers; i++)
     36 	print "#include " quote headers[i] quote
     37 print "#include " quote "opts.h" quote
     38 print "#include " quote "intl.h" quote
     39 print ""
     40 print "#include " quote "flags.h" quote
     41 print "#include " quote "target.h" quote
     42 print "#include " quote "inchash.h" quote
     43 print "#include " quote "hash-set.h" quote
     44 print "#include " quote "vec.h" quote
     45 print "#include " quote "input.h" quote
     46 print "#include " quote "alias.h" quote
     47 print "#include " quote "symtab.h" quote
     48 print "#include " quote "inchash.h" quote
     49 print "#include " quote "tree.h" quote
     50 print "#include " quote "fold-const.h" quote
     51 print "#include " quote "tree-ssa-alias.h" quote
     52 print "#include " quote "is-a.h" quote
     53 print "#include " quote "predict.h" quote
     54 print "#include " quote "function.h" quote
     55 print "#include " quote "basic-block.h" quote
     56 print "#include " quote "gimple-expr.h" quote
     57 print "#include " quote "gimple.h" quote
     58 print "#include " quote "data-streamer.h" quote
     59 print "#include " quote "ipa-ref.h" quote
     60 print "#include " quote "cgraph.h" quote
     61 print ""
     62 
     63 if (n_extra_c_includes > 0) {
     64 	for (i = 0; i < n_extra_c_includes; i++) {
     65 		print "#include " quote extra_c_includes[i] quote
     66 	}
     67 	print ""
     68 }
     69 
     70 have_save = 0;
     71 if (n_extra_target_vars)
     72 	have_save = 1
     73 
     74 for (i = 0; i < n_opts; i++) {
     75 	if (flag_set_p("Save", flags[i]))
     76 		have_save = 1;
     77 }
     78 
     79 print "/* Save optimization variables into a structure.  */"
     80 print "void";
     81 print "cl_optimization_save (struct cl_optimization *ptr, struct gcc_options *opts,";
     82 print "		      struct gcc_options *opts_set)";
     83 print "{";
     84 
     85 n_opt_char = 4;
     86 n_opt_short = 0;
     87 n_opt_int = 0;
     88 n_opt_enum = 0;
     89 n_opt_string = 0;
     90 n_opt_other = 0;
     91 var_opt_char[0] = "optimize";
     92 var_opt_char[1] = "optimize_size";
     93 var_opt_char[2] = "optimize_debug";
     94 var_opt_char[3] = "optimize_fast";
     95 var_opt_range["optimize"] = "0, 255";
     96 var_opt_range["optimize_size"] = "0, 2";
     97 var_opt_range["optimize_debug"] = "0, 1";
     98 var_opt_range["optimize_fast"] = "0, 1";
     99 
    100 # Sort by size to mimic how the structure is laid out to be friendlier to the
    101 # cache.
    102 
    103 for (i = 0; i < n_opts; i++) {
    104 	if (flag_set_p("(Optimization|PerFunction)", flags[i])) {
    105 		name = var_name(flags[i])
    106 		if(name == "")
    107 			continue;
    108 
    109 		if(name in var_opt_seen)
    110 			continue;
    111 
    112 		var_opt_seen[name]++;
    113 		otype = var_type_struct(flags[i]);
    114 		if (otype ~ "^((un)?signed +)?int *$")
    115 			var_opt_int[n_opt_int++] = name;
    116 
    117 		else if (otype ~ "^((un)?signed +)?short *$")
    118 			var_opt_short[n_opt_short++] = name;
    119 
    120 		else if (otype ~ ("^enum +[_" alnum "]+ *")) {
    121 			var_opt_enum_type[n_opt_enum] = otype;
    122 			var_opt_enum[n_opt_enum++] = name;
    123 		}
    124 		else if (otype ~ "^((un)?signed +)?char *$") {
    125 			var_opt_char[n_opt_char++] = name;
    126 			if (otype ~ "^unsigned +char *$")
    127 				var_opt_range[name] = "0, 255"
    128 			else if (otype ~ "^signed +char *$")
    129 				var_opt_range[name] = "-128, 127"
    130 		}
    131 		else if (otype ~ "^const char \\**$") {
    132 			var_opt_string[n_opt_string++] = name;
    133 			string_options_names[name]++
    134 		}
    135 		else
    136 			var_opt_other[n_opt_other++] = name;
    137 	}
    138 }
    139 
    140 for (i = 0; i < n_opt_char; i++) {
    141 	name = var_opt_char[i];
    142 	if (var_opt_range[name] != "")
    143 		print "  gcc_assert (IN_RANGE (opts->x_" name ", " var_opt_range[name] "));";
    144 }
    145 
    146 print "";
    147 for (i = 0; i < n_opt_other; i++) {
    148 	print "  ptr->x_" var_opt_other[i] " = opts->x_" var_opt_other[i] ";";
    149 }
    150 
    151 for (i = 0; i < n_opt_int; i++) {
    152 	print "  ptr->x_" var_opt_int[i] " = opts->x_" var_opt_int[i] ";";
    153 }
    154 
    155 for (i = 0; i < n_opt_enum; i++) {
    156 	print "  ptr->x_" var_opt_enum[i] " = opts->x_" var_opt_enum[i] ";";
    157 }
    158 
    159 for (i = 0; i < n_opt_short; i++) {
    160 	print "  ptr->x_" var_opt_short[i] " = opts->x_" var_opt_short[i] ";";
    161 }
    162 
    163 for (i = 0; i < n_opt_char; i++) {
    164 	print "  ptr->x_" var_opt_char[i] " = opts->x_" var_opt_char[i] ";";
    165 }
    166 
    167 for (i = 0; i < n_opt_string; i++) {
    168 	print "  ptr->x_" var_opt_string[i] " = opts->x_" var_opt_string[i] ";";
    169 }
    170 
    171 print "";
    172 print "  unsigned HOST_WIDE_INT mask = 0;";
    173 
    174 j = 0;
    175 k = 0;
    176 for (i = 0; i < n_opt_other; i++) {
    177 	print "  if (opts_set->x_" var_opt_other[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    178 	j++;
    179 	if (j == 64) {
    180 		print "  ptr->explicit_mask[" k "] = mask;";
    181 		print "  mask = 0;";
    182 		j = 0;
    183 		k++;
    184 	}
    185 }
    186 
    187 for (i = 0; i < n_opt_int; i++) {
    188 	print "  if (opts_set->x_" var_opt_int[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    189 	j++;
    190 	if (j == 64) {
    191 		print "  ptr->explicit_mask[" k "] = mask;";
    192 		print "  mask = 0;";
    193 		j = 0;
    194 		k++;
    195 	}
    196 }
    197 
    198 for (i = 0; i < n_opt_enum; i++) {
    199 	print "  if (opts_set->x_" var_opt_enum[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    200 	j++;
    201 	if (j == 64) {
    202 		print "  ptr->explicit_mask[" k "] = mask;";
    203 		print "  mask = 0;";
    204 		j = 0;
    205 		k++;
    206 	}
    207 }
    208 
    209 for (i = 0; i < n_opt_short; i++) {
    210 	print "  if (opts_set->x_" var_opt_short[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    211 	j++;
    212 	if (j == 64) {
    213 		print "  ptr->explicit_mask[" k "] = mask;";
    214 		print "  mask = 0;";
    215 		j = 0;
    216 		k++;
    217 	}
    218 }
    219 
    220 for (i = 0; i < n_opt_char; i++) {
    221 	print "  if (opts_set->x_" var_opt_char[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    222 	j++;
    223 	if (j == 64) {
    224 		print "  ptr->explicit_mask[" k "] = mask;";
    225 		print "  mask = 0;";
    226 		j = 0;
    227 		k++;
    228 	}
    229 }
    230 
    231 for (i = 0; i < n_opt_string; i++) {
    232 	print "  if (opts_set->x_" var_opt_string[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    233 	j++;
    234 	if (j == 64) {
    235 		print "  ptr->explicit_mask[" k "] = mask;";
    236 		print "  mask = 0;";
    237 		j = 0;
    238 		k++;
    239 	}
    240 }
    241 
    242 if (j != 0) {
    243 	print "  ptr->explicit_mask[" k "] = mask;";
    244 }
    245 
    246 print "}";
    247 
    248 print "";
    249 print "/* Restore optimization options from a structure.  */";
    250 print "void";
    251 print "cl_optimization_restore (struct gcc_options *opts, struct gcc_options *opts_set,";
    252 print "			 struct cl_optimization *ptr)";
    253 print "{";
    254 
    255 for (i = 0; i < n_opt_other; i++) {
    256 	print "  opts->x_" var_opt_other[i] " = ptr->x_" var_opt_other[i] ";";
    257 }
    258 
    259 for (i = 0; i < n_opt_int; i++) {
    260 	print "  opts->x_" var_opt_int[i] " = ptr->x_" var_opt_int[i] ";";
    261 }
    262 
    263 for (i = 0; i < n_opt_enum; i++) {
    264 	print "  opts->x_" var_opt_enum[i] " = ptr->x_" var_opt_enum[i] ";";
    265 }
    266 
    267 for (i = 0; i < n_opt_short; i++) {
    268 	print "  opts->x_" var_opt_short[i] " = ptr->x_" var_opt_short[i] ";";
    269 }
    270 
    271 for (i = 0; i < n_opt_char; i++) {
    272 	print "  opts->x_" var_opt_char[i] " = ptr->x_" var_opt_char[i] ";";
    273 }
    274 
    275 for (i = 0; i < n_opt_string; i++) {
    276 	print "  opts->x_" var_opt_string[i] " = ptr->x_" var_opt_string[i] ";";
    277 }
    278 
    279 print "";
    280 print "  unsigned HOST_WIDE_INT mask;";
    281 
    282 j = 64;
    283 k = 0;
    284 for (i = 0; i < n_opt_other; i++) {
    285 	if (j == 64) {
    286 		print "  mask = ptr->explicit_mask[" k "];";
    287 		k++;
    288 		j = 0;
    289 	}
    290 	print "  opts_set->x_" var_opt_other[i] " = (mask & 1) != 0;";
    291 	print "  mask >>= 1;"
    292 	j++;
    293 }
    294 
    295 for (i = 0; i < n_opt_int; i++) {
    296 	if (j == 64) {
    297 		print "  mask = ptr->explicit_mask[" k "];";
    298 		k++;
    299 		j = 0;
    300 	}
    301 	print "  opts_set->x_" var_opt_int[i] " = (mask & 1) != 0;";
    302 	print "  mask >>= 1;"
    303 	j++;
    304 }
    305 
    306 for (i = 0; i < n_opt_enum; i++) {
    307 	if (j == 64) {
    308 		print "  mask = ptr->explicit_mask[" k "];";
    309 		k++;
    310 		j = 0;
    311 	}
    312 	print "  opts_set->x_" var_opt_enum[i] " = static_cast<" var_opt_enum_type[i] ">((mask & 1) != 0);";
    313 	print "  mask >>= 1;"
    314 	j++;
    315 }
    316 
    317 for (i = 0; i < n_opt_short; i++) {
    318 	if (j == 64) {
    319 		print "  mask = ptr->explicit_mask[" k "];";
    320 		k++;
    321 		j = 0;
    322 	}
    323 	print "  opts_set->x_" var_opt_short[i] " = (mask & 1) != 0;";
    324 	print "  mask >>= 1;"
    325 	j++;
    326 }
    327 
    328 for (i = 0; i < n_opt_char; i++) {
    329 	if (j == 64) {
    330 		print "  mask = ptr->explicit_mask[" k "];";
    331 		k++;
    332 		j = 0;
    333 	}
    334 	print "  opts_set->x_" var_opt_char[i] " = (mask & 1) != 0;";
    335 	print "  mask >>= 1;"
    336 	j++;
    337 }
    338 
    339 for (i = 0; i < n_opt_string; i++) {
    340 	if (j == 64) {
    341 		print "  mask = ptr->explicit_mask[" k "];";
    342 		k++;
    343 		j = 0;
    344 	}
    345 	print "  opts_set->x_" var_opt_string[i] " = (mask & 1) ? \"\" : nullptr;";
    346 	print "  mask >>= 1;"
    347 	j++;
    348 }
    349 
    350 print "  targetm.override_options_after_change ();";
    351 print "}";
    352 
    353 print "";
    354 print "/* Print optimization options from a structure.  */";
    355 print "void";
    356 print "cl_optimization_print (FILE *file,";
    357 print "                       int indent_to,";
    358 print "                       struct cl_optimization *ptr)";
    359 print "{";
    360 
    361 print "  fputs (\"\\n\", file);";
    362 for (i = 0; i < n_opt_other; i++) {
    363 	print "  if (ptr->x_" var_opt_other[i] ")";
    364 	print "    fprintf (file, \"%*s%s (%#lx)\\n\",";
    365 	print "             indent_to, \"\",";
    366 	print "             \"" var_opt_other[i] "\",";
    367 	print "             (unsigned long)ptr->x_" var_opt_other[i] ");";
    368 	print "";
    369 }
    370 
    371 for (i = 0; i < n_opt_int; i++) {
    372 	print "  if (ptr->x_" var_opt_int[i] ")";
    373 	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
    374 	print "             indent_to, \"\",";
    375 	print "             \"" var_opt_int[i] "\",";
    376 	print "             ptr->x_" var_opt_int[i] ");";
    377 	print "";
    378 }
    379 
    380 for (i = 0; i < n_opt_enum; i++) {
    381 	print "  fprintf (file, \"%*s%s (%#x)\\n\",";
    382 	print "           indent_to, \"\",";
    383 	print "           \"" var_opt_enum[i] "\",";
    384 	print "           (int) ptr->x_" var_opt_enum[i] ");";
    385 	print "";
    386 }
    387 
    388 for (i = 0; i < n_opt_short; i++) {
    389 	print "  if (ptr->x_" var_opt_short[i] ")";
    390 	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
    391 	print "             indent_to, \"\",";
    392 	print "             \"" var_opt_short[i] "\",";
    393 	print "             ptr->x_" var_opt_short[i] ");";
    394 	print "";
    395 }
    396 
    397 for (i = 0; i < n_opt_char; i++) {
    398 	print "  if (ptr->x_" var_opt_char[i] ")";
    399 	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
    400 	print "             indent_to, \"\",";
    401 	print "             \"" var_opt_char[i] "\",";
    402 	print "             ptr->x_" var_opt_char[i] ");";
    403 	print "";
    404 }
    405 
    406 for (i = 0; i < n_opt_string; i++) {
    407 	print "  if (ptr->x_" var_opt_string[i] ")";
    408 	print "    fprintf (file, \"%*s%s (%s)\\n\",";
    409 	print "             indent_to, \"\",";
    410 	print "             \"" var_opt_string[i] "\",";
    411 	print "             ptr->x_" var_opt_string[i] ");";
    412 	print "";
    413 }
    414 
    415 print "}";
    416 
    417 print "";
    418 print "/* Print different optimization variables from structures provided as arguments.  */";
    419 print "void";
    420 print "cl_optimization_print_diff (FILE *file,";
    421 print "                            int indent_to,";
    422 print "                            struct cl_optimization *ptr1,";
    423 print "                            struct cl_optimization *ptr2)";
    424 print "{";
    425 
    426 print "  fputs (\"\\n\", file);";
    427 for (i = 0; i < n_opt_other; i++) {
    428 	print "  if (ptr1->x_" var_opt_other[i] " != ptr2->x_" var_opt_other[i] ")";
    429 	print "    fprintf (file, \"%*s%s (%#lx/%#lx)\\n\",";
    430 	print "             indent_to, \"\",";
    431 	print "             \"" var_opt_other[i] "\",";
    432 	print "             (unsigned long)ptr1->x_" var_opt_other[i] ",";
    433 	print "             (unsigned long)ptr2->x_" var_opt_other[i] ");";
    434 	print "";
    435 }
    436 
    437 for (i = 0; i < n_opt_int; i++) {
    438 	print "  if (ptr1->x_" var_opt_int[i] " != ptr2->x_" var_opt_int[i] ")";
    439 	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
    440 	print "             indent_to, \"\",";
    441 	print "             \"" var_opt_int[i] "\",";
    442 	print "             ptr1->x_" var_opt_int[i] ",";
    443 	print "             ptr2->x_" var_opt_int[i] ");";
    444 	print "";
    445 }
    446 
    447 for (i = 0; i < n_opt_enum; i++) {
    448 	print "  if (ptr1->x_" var_opt_enum[i] " != ptr2->x_" var_opt_enum[i] ")";
    449 	print "  fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
    450 	print "           indent_to, \"\",";
    451 	print "           \"" var_opt_enum[i] "\",";
    452 	print "           (int) ptr1->x_" var_opt_enum[i] ",";
    453 	print "           (int) ptr2->x_" var_opt_enum[i] ");";
    454 	print "";
    455 }
    456 
    457 for (i = 0; i < n_opt_short; i++) {
    458 	print "  if (ptr1->x_" var_opt_short[i] " != ptr2->x_" var_opt_short[i] ")";
    459 	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
    460 	print "             indent_to, \"\",";
    461 	print "             \"" var_opt_short[i] "\",";
    462 	print "             ptr1->x_" var_opt_short[i] ",";
    463 	print "             ptr2->x_" var_opt_short[i] ");";
    464 	print "";
    465 }
    466 
    467 for (i = 0; i < n_opt_char; i++) {
    468 	print "  if (ptr1->x_" var_opt_char[i] " != ptr2->x_" var_opt_char[i] ")";
    469 	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
    470 	print "             indent_to, \"\",";
    471 	print "             \"" var_opt_char[i] "\",";
    472 	print "             ptr1->x_" var_opt_char[i] ",";
    473 	print "             ptr2->x_" var_opt_char[i] ");";
    474 	print "";
    475 }
    476 
    477 for (i = 0; i < n_opt_string; i++) {
    478 	name = var_opt_string[i]
    479 	print "  if (ptr1->x_" name " != ptr2->x_" name "";
    480 	print "      && (!ptr1->x_" name" || !ptr2->x_" name
    481 	print "          || strcmp (ptr1->x_" name", ptr2->x_" name ")))";
    482 	print "    fprintf (file, \"%*s%s (%s/%s)\\n\",";
    483 	print "             indent_to, \"\",";
    484 	print "             \"" name "\",";
    485 	print "             ptr1->x_" name " ? ptr1->x_" name " : \"(null)\",";
    486 	print "             ptr2->x_" name " ? ptr2->x_" name " : \"(null)\");";
    487 	print "";
    488 }
    489 
    490 print "}";
    491 
    492 
    493 print "";
    494 print "/* Save selected option variables into a structure.  */"
    495 print "void";
    496 print "cl_target_option_save (struct cl_target_option *ptr, struct gcc_options *opts,";
    497 print "		       struct gcc_options *opts_set)";
    498 print "{";
    499 
    500 n_target_char = 0;
    501 n_target_short = 0;
    502 n_target_int = 0;
    503 n_target_enum = 0;
    504 n_target_string = 0;
    505 n_target_other = 0;
    506 
    507 if (have_save) {
    508 	for (i = 0; i < n_opts; i++) {
    509 		if (flag_set_p("Save", flags[i])) {
    510 			name = var_name(flags[i])
    511 			if(name == "")
    512 				name = "target_flags";
    513 
    514 			if(name in var_save_seen)
    515 				continue;
    516 
    517 			var_save_seen[name]++;
    518 			otype = var_type_struct(flags[i])
    519 			if (opt_args("Mask", flags[i]) != "" \
    520 			    || opt_args("InverseMask", flags[i]))
    521 				var_target_explicit_mask[name] = 1;
    522 
    523 			if (otype ~ "^((un)?signed +)?int *$")
    524 				var_target_int[n_target_int++] = name;
    525 
    526 			else if (otype ~ "^((un)?signed +)?short *$")
    527 				var_target_short[n_target_short++] = name;
    528 
    529 			else if (otype ~ ("^enum +[_" alnum "]+ *$")) {
    530 				var_target_enum_type[n_target_enum] = otype;
    531 				var_target_enum[n_target_enum++] = name;
    532 			}
    533 			else if (otype ~ "^((un)?signed +)?char *$") {
    534 				var_target_char[n_target_char++] = name;
    535 				if (otype ~ "^unsigned +char *$")
    536 					var_target_range[name] = "0, 255"
    537 				else if (otype ~ "^signed +char *$")
    538 					var_target_range[name] = "-128, 127"
    539 				if (otype == var_type(flags[i]))
    540 					var_target_range[name] = ""
    541 			}
    542 			else if (otype ~ "^const char \\**$") {
    543 				var_target_string[n_target_string++] = name;
    544 				string_options_names[name]++
    545 			}
    546 			else
    547 				var_target_other[n_target_other++] = name;
    548 		}
    549 	}
    550 } else {
    551 	var_target_int[n_target_int++] = "target_flags";
    552 	var_target_explicit_mask["target_flags"] = 1;
    553 }
    554 
    555 have_assert = 0;
    556 for (i = 0; i < n_target_char; i++) {
    557 	name = var_target_char[i];
    558 	if (var_target_range[name] != "") {
    559 		have_assert = 1;
    560 		print "  gcc_assert (IN_RANGE (opts->x_" name ", " var_target_range[name] "));";
    561 	}
    562 }
    563 
    564 if (have_assert)
    565 	print "";
    566 
    567 print "  if (targetm.target_option.save)";
    568 print "    targetm.target_option.save (ptr, opts, opts_set);";
    569 print "";
    570 
    571 for (i = 0; i < n_extra_target_vars; i++) {
    572 	print "  ptr->x_" extra_target_vars[i] " = opts->x_" extra_target_vars[i] ";";
    573 }
    574 
    575 for (i = 0; i < n_target_other; i++) {
    576 	print "  ptr->x_" var_target_other[i] " = opts->x_" var_target_other[i] ";";
    577 }
    578 
    579 for (i = 0; i < n_target_enum; i++) {
    580 	print "  ptr->x_" var_target_enum[i] " = opts->x_" var_target_enum[i] ";";
    581 }
    582 
    583 for (i = 0; i < n_target_int; i++) {
    584 	print "  ptr->x_" var_target_int[i] " = opts->x_" var_target_int[i] ";";
    585 }
    586 
    587 for (i = 0; i < n_target_short; i++) {
    588 	print "  ptr->x_" var_target_short[i] " = opts->x_" var_target_short[i] ";";
    589 }
    590 
    591 for (i = 0; i < n_target_char; i++) {
    592 	print "  ptr->x_" var_target_char[i] " = opts->x_" var_target_char[i] ";";
    593 }
    594 
    595 for (i = 0; i < n_target_string; i++) {
    596 	print "  ptr->x_" var_target_string[i] " = opts->x_" var_target_string[i] ";";
    597 }
    598 
    599 print "";
    600 
    601 j = 0;
    602 k = 0;
    603 for (i = 0; i < n_extra_target_vars; i++) {
    604 	if (j == 0 && k == 0) {
    605 		print "  unsigned HOST_WIDE_INT mask = 0;";
    606 	}
    607 	print "  if (opts_set->x_" extra_target_vars[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    608 	j++;
    609 	if (j == 64) {
    610 		print "  ptr->explicit_mask[" k "] = mask;";
    611 		print "  mask = 0;";
    612 		j = 0;
    613 		k++;
    614 	}
    615 }
    616 
    617 for (i = 0; i < n_target_other; i++) {
    618 	if (var_target_other[i] in var_target_explicit_mask) {
    619 		print "  ptr->explicit_mask_" var_target_other[i] " = opts_set->x_" var_target_other[i] ";";
    620 		continue;
    621 	}
    622 	if (j == 0 && k == 0) {
    623 		print "  unsigned HOST_WIDE_INT mask = 0;";
    624 	}
    625 	print "  if (opts_set->x_" var_target_other[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    626 	j++;
    627 	if (j == 64) {
    628 		print "  ptr->explicit_mask[" k "] = mask;";
    629 		print "  mask = 0;";
    630 		j = 0;
    631 		k++;
    632 	}
    633 }
    634 
    635 for (i = 0; i < n_target_enum; i++) {
    636 	if (j == 0 && k == 0) {
    637 		print "  unsigned HOST_WIDE_INT mask = 0;";
    638 	}
    639 	print "  if (opts_set->x_" var_target_enum[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    640 	j++;
    641 	if (j == 64) {
    642 		print "  ptr->explicit_mask[" k "] = mask;";
    643 		print "  mask = 0;";
    644 		j = 0;
    645 		k++;
    646 	}
    647 }
    648 
    649 for (i = 0; i < n_target_int; i++) {
    650 	if (var_target_int[i] in var_target_explicit_mask) {
    651 		print "  ptr->explicit_mask_" var_target_int[i] " = opts_set->x_" var_target_int[i] ";";
    652 		continue;
    653 	}
    654 	if (j == 0 && k == 0) {
    655 		print "  unsigned HOST_WIDE_INT mask = 0;";
    656 	}
    657 	print "  if (opts_set->x_" var_target_int[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    658 	j++;
    659 	if (j == 64) {
    660 		print "  ptr->explicit_mask[" k "] = mask;";
    661 		print "  mask = 0;";
    662 		j = 0;
    663 		k++;
    664 	}
    665 }
    666 
    667 for (i = 0; i < n_target_short; i++) {
    668 	if (j == 0 && k == 0) {
    669 		print "  unsigned HOST_WIDE_INT mask = 0;";
    670 	}
    671 	print "  if (opts_set->x_" var_target_short[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    672 	j++;
    673 	if (j == 64) {
    674 		print "  ptr->explicit_mask[" k "] = mask;";
    675 		print "  mask = 0;";
    676 		j = 0;
    677 		k++;
    678 	}
    679 }
    680 
    681 for (i = 0; i < n_target_char; i++) {
    682 	if (j == 0 && k == 0) {
    683 		print "  unsigned HOST_WIDE_INT mask = 0;";
    684 	}
    685 	print "  if (opts_set->x_" var_target_char[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    686 	j++;
    687 	if (j == 64) {
    688 		print "  ptr->explicit_mask[" k "] = mask;";
    689 		print "  mask = 0;";
    690 		j = 0;
    691 		k++;
    692 	}
    693 }
    694 
    695 for (i = 0; i < n_target_string; i++) {
    696 	if (j == 0 && k == 0) {
    697 		print "  unsigned HOST_WIDE_INT mask = 0;";
    698 	}
    699 	print "  if (opts_set->x_" var_target_string[i] ") mask |= HOST_WIDE_INT_1U << " j ";";
    700 	j++;
    701 	if (j == 64) {
    702 		print "  ptr->explicit_mask[" k "] = mask;";
    703 		print "  mask = 0;";
    704 		j = 0;
    705 		k++;
    706 	}
    707 }
    708 
    709 if (j != 0) {
    710 	print "  ptr->explicit_mask[" k "] = mask;";
    711 }
    712 has_target_explicit_mask = 0;
    713 if (j != 0 || k != 0) {
    714 	has_target_explicit_mask = 1;
    715 }
    716 
    717 print "}";
    718 
    719 print "";
    720 print "/* Restore selected current options from a structure.  */";
    721 print "void";
    722 print "cl_target_option_restore (struct gcc_options *opts, struct gcc_options *opts_set,";
    723 print "			  struct cl_target_option *ptr)";
    724 print "{";
    725 
    726 for (i = 0; i < n_extra_target_vars; i++) {
    727 	print "  opts->x_" extra_target_vars[i] " = ptr->x_" extra_target_vars[i] ";";
    728 }
    729 
    730 for (i = 0; i < n_target_other; i++) {
    731 	print "  opts->x_" var_target_other[i] " = ptr->x_" var_target_other[i] ";";
    732 }
    733 
    734 for (i = 0; i < n_target_enum; i++) {
    735 	print "  opts->x_" var_target_enum[i] " = ptr->x_" var_target_enum[i] ";";
    736 }
    737 
    738 for (i = 0; i < n_target_int; i++) {
    739 	print "  opts->x_" var_target_int[i] " = ptr->x_" var_target_int[i] ";";
    740 }
    741 
    742 for (i = 0; i < n_target_short; i++) {
    743 	print "  opts->x_" var_target_short[i] " = ptr->x_" var_target_short[i] ";";
    744 }
    745 
    746 for (i = 0; i < n_target_char; i++) {
    747 	print "  opts->x_" var_target_char[i] " = ptr->x_" var_target_char[i] ";";
    748 }
    749 
    750 for (i = 0; i < n_target_string; i++) {
    751 	print "  opts->x_" var_target_string[i] " = ptr->x_" var_target_string[i] ";";
    752 }
    753 
    754 print "";
    755 if (has_target_explicit_mask) {
    756 	print "  unsigned HOST_WIDE_INT mask;";
    757 }
    758 
    759 j = 64;
    760 k = 0;
    761 for (i = 0; i < n_extra_target_vars; i++) {
    762 	if (j == 64) {
    763 		print "  mask = ptr->explicit_mask[" k "];";
    764 		k++;
    765 		j = 0;
    766 	}
    767 	if (extra_target_var_types[i] ~ ("^enum +[_" alnum "]+ *$")) {
    768 		print "  opts_set->x_" extra_target_vars[i] " = static_cast<" extra_target_var_types[i] ">((mask & 1) != 0);";
    769 	}
    770 	else if (extra_target_var_types[i] ~ "^const char \\**$") {
    771 		print "  opts_set->x_" extra_target_vars[i] " = (mask & 1) ? \"\" : nullptr;";
    772 	}
    773 	else {
    774 		print "  opts_set->x_" extra_target_vars[i] " = (mask & 1) != 0;";
    775 	}
    776 	print "  mask >>= 1;"
    777 	j++;
    778 }
    779 
    780 for (i = 0; i < n_target_other; i++) {
    781 	if (var_target_other[i] in var_target_explicit_mask) {
    782 		print "  opts_set->x_" var_target_other[i] " = ptr->explicit_mask_" var_target_other[i] ";";
    783 		continue;
    784 	}
    785 	if (j == 64) {
    786 		print "  mask = ptr->explicit_mask[" k "];";
    787 		k++;
    788 		j = 0;
    789 	}
    790 	print "  opts_set->x_" var_target_other[i] " = (mask & 1) != 0;";
    791 	print "  mask >>= 1;"
    792 	j++;
    793 }
    794 
    795 for (i = 0; i < n_target_enum; i++) {
    796 	if (j == 64) {
    797 		print "  mask = ptr->explicit_mask[" k "];";
    798 		k++;
    799 		j = 0;
    800 	}
    801 	print "  opts_set->x_" var_target_enum[i] " = static_cast<" var_target_enum_type[i] ">((mask & 1) != 0);";
    802 	print "  mask >>= 1;"
    803 	j++;
    804 }
    805 
    806 for (i = 0; i < n_target_int; i++) {
    807 	if (var_target_int[i] in var_target_explicit_mask) {
    808 		print "  opts_set->x_" var_target_int[i] " = ptr->explicit_mask_" var_target_int[i] ";";
    809 		continue;
    810 	}
    811 	if (j == 64) {
    812 		print "  mask = ptr->explicit_mask[" k "];";
    813 		k++;
    814 		j = 0;
    815 	}
    816 	print "  opts_set->x_" var_target_int[i] " = (mask & 1) != 0;";
    817 	print "  mask >>= 1;"
    818 	j++;
    819 }
    820 
    821 for (i = 0; i < n_target_short; i++) {
    822 	if (j == 64) {
    823 		print "  mask = ptr->explicit_mask[" k "];";
    824 		k++;
    825 		j = 0;
    826 	}
    827 	print "  opts_set->x_" var_target_short[i] " = (mask & 1) != 0;";
    828 	print "  mask >>= 1;"
    829 	j++;
    830 }
    831 
    832 for (i = 0; i < n_target_char; i++) {
    833 	if (j == 64) {
    834 		print "  mask = ptr->explicit_mask[" k "];";
    835 		k++;
    836 		j = 0;
    837 	}
    838 	print "  opts_set->x_" var_target_char[i] " = (mask & 1) != 0;";
    839 	print "  mask >>= 1;"
    840 	j++;
    841 }
    842 
    843 for (i = 0; i < n_target_string; i++) {
    844 	if (j == 64) {
    845 		print "  mask = ptr->explicit_mask[" k "];";
    846 		k++;
    847 		j = 0;
    848 	}
    849 	print "  opts_set->x_" var_target_string[i] " = (mask & 1) ? \"\" : nullptr;";
    850 	print "  mask >>= 1;"
    851 	j++;
    852 }
    853 
    854 # This must occur after the normal variables in case the code depends on those
    855 # variables.
    856 print "";
    857 print "  if (targetm.target_option.restore)";
    858 print "    targetm.target_option.restore (opts, opts_set, ptr);";
    859 
    860 print "}";
    861 
    862 print "";
    863 print "/* Print optimization options from a structure.  */";
    864 print "void";
    865 print "cl_target_option_print (FILE *file,";
    866 print "                        int indent,";
    867 print "                        struct cl_target_option *ptr)";
    868 print "{";
    869 
    870 print "  fputs (\"\\n\", file);";
    871 for (i = 0; i < n_target_other; i++) {
    872 	print "  if (ptr->x_" var_target_other[i] ")";
    873 	hwi = host_wide_int[var_target_other[i]]
    874 	if (hwi == "yes")
    875 		print "    fprintf (file, \"%*s%s (%#\" HOST_WIDE_INT_PRINT \"x)\\n\",";
    876 	else
    877 		print "    fprintf (file, \"%*s%s (%#lx)\\n\",";
    878 	print "             indent, \"\",";
    879 	print "             \"" var_target_other[i] "\",";
    880 	if (hwi == "yes")
    881 		print "             ptr->x_" var_target_other[i] ");";
    882 	else
    883 		print "             (unsigned long)ptr->x_" var_target_other[i] ");";
    884 	print "";
    885 }
    886 
    887 for (i = 0; i < n_target_enum; i++) {
    888 	print "  if (ptr->x_" var_target_enum[i] ")";
    889 	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
    890 	print "             indent, \"\",";
    891 	print "             \"" var_target_enum[i] "\",";
    892 	print "             ptr->x_" var_target_enum[i] ");";
    893 	print "";
    894 }
    895 
    896 for (i = 0; i < n_target_int; i++) {
    897 	print "  if (ptr->x_" var_target_int[i] ")";
    898 	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
    899 	print "             indent, \"\",";
    900 	print "             \"" var_target_int[i] "\",";
    901 	print "             ptr->x_" var_target_int[i] ");";
    902 	print "";
    903 }
    904 
    905 for (i = 0; i < n_target_short; i++) {
    906 	print "  if (ptr->x_" var_target_short[i] ")";
    907 	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
    908 	print "             indent, \"\",";
    909 	print "             \"" var_target_short[i] "\",";
    910 	print "             ptr->x_" var_target_short[i] ");";
    911 	print "";
    912 }
    913 
    914 for (i = 0; i < n_target_char; i++) {
    915 	print "  if (ptr->x_" var_target_char[i] ")";
    916 	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
    917 	print "             indent, \"\",";
    918 	print "             \"" var_target_char[i] "\",";
    919 	print "             ptr->x_" var_target_char[i] ");";
    920 	print "";
    921 }
    922 
    923 for (i = 0; i < n_target_string; i++) {
    924 	print "  if (ptr->x_" var_target_string[i] ")";
    925 	print "    fprintf (file, \"%*s%s (%s)\\n\",";
    926 	print "             indent, \"\",";
    927 	print "             \"" var_target_string[i] "\",";
    928 	print "             ptr->x_" var_target_string[i] ");";
    929 	print "";
    930 }
    931 
    932 print "";
    933 print "  if (targetm.target_option.print)";
    934 print "    targetm.target_option.print (file, indent, ptr);";
    935 print "}";
    936 
    937 print "";
    938 print "/* Print different target option variables from structures provided as arguments.  */";
    939 print "void";
    940 print "cl_target_option_print_diff (FILE *file,";
    941 print "                             int indent ATTRIBUTE_UNUSED,";
    942 print "                             struct cl_target_option *ptr1 ATTRIBUTE_UNUSED,";
    943 print "                             struct cl_target_option *ptr2 ATTRIBUTE_UNUSED)";
    944 print "{";
    945 
    946 print "  fputs (\"\\n\", file);";
    947 for (i = 0; i < n_target_other; i++) {
    948 	print "  if (ptr1->x_" var_target_other[i] " != ptr2->x_" var_target_other[i] ")";
    949 	hwi = host_wide_int[var_target_other[i]]
    950 	if (hwi == "yes")
    951 		print "    fprintf (file, \"%*s%s (%#\" HOST_WIDE_INT_PRINT \"x/%#\" HOST_WIDE_INT_PRINT \"x)\\n\",";
    952 	else
    953 		print "    fprintf (file, \"%*s%s (%#lx/%#lx)\\n\",";
    954 	print "             indent, \"\",";
    955 	print "             \"" var_target_other[i] "\",";
    956 	if (hwi == "yes") {
    957 		print "             ptr1->x_" var_target_other[i] ",";
    958 		print "             ptr2->x_" var_target_other[i] ");";
    959 	}
    960 	else {
    961 		print "             (unsigned long)ptr1->x_" var_target_other[i] ",";
    962 		print "             (unsigned long)ptr2->x_" var_target_other[i] ");";
    963 	}
    964 	print "";
    965 }
    966 
    967 for (i = 0; i < n_target_enum; i++) {
    968 	print "  if (ptr1->x_" var_target_enum[i] " != ptr2->x_" var_target_enum[i] ")";
    969 	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
    970 	print "             indent, \"\",";
    971 	print "             \"" var_target_enum[i] "\",";
    972 	print "             ptr1->x_" var_target_enum[i] ",";
    973 	print "             ptr2->x_" var_target_enum[i] ");";
    974 	print "";
    975 }
    976 
    977 for (i = 0; i < n_target_int; i++) {
    978 	print "  if (ptr1->x_" var_target_int[i] " != ptr2->x_" var_target_int[i] ")";
    979 	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
    980 	print "             indent, \"\",";
    981 	print "             \"" var_target_int[i] "\",";
    982 	print "             ptr1->x_" var_target_int[i] ",";
    983 	print "             ptr2->x_" var_target_int[i] ");";
    984 	print "";
    985 }
    986 
    987 for (i = 0; i < n_target_short; i++) {
    988 	print "  if (ptr1->x_" var_target_short[i] " != ptr2->x_" var_target_short[i] ")";
    989 	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
    990 	print "             indent, \"\",";
    991 	print "             \"" var_target_short[i] "\",";
    992 	print "             ptr1->x_" var_target_short[i] ",";
    993 	print "             ptr2->x_" var_target_short[i] ");";
    994 	print "";
    995 }
    996 
    997 for (i = 0; i < n_target_char; i++) {
    998 	print "  if (ptr1->x_" var_target_char[i] " != ptr2->x_" var_target_char[i] ")";
    999 	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
   1000 	print "             indent, \"\",";
   1001 	print "             \"" var_target_char[i] "\",";
   1002 	print "             ptr1->x_" var_target_char[i] ",";
   1003 	print "             ptr2->x_" var_target_char[i] ");";
   1004 	print "";
   1005 }
   1006 
   1007 for (i = 0; i < n_target_string; i++) {
   1008 	name = var_target_string[i]
   1009 	print "  if (ptr1->x_" name " != ptr2->x_" name "";
   1010 	print "      && (!ptr1->x_" name" || !ptr2->x_" name
   1011 	print "          || strcmp (ptr1->x_" name", ptr2->x_" name ")))";
   1012 	print "    fprintf (file, \"%*s%s (%s/%s)\\n\",";
   1013 	print "             indent, \"\",";
   1014 	print "             \"" name "\",";
   1015 	print "             ptr1->x_" name " ? ptr1->x_" name " : \"(null)\",";
   1016 	print "             ptr2->x_" name " ? ptr2->x_" name " : \"(null)\");";
   1017 	print "";
   1018 }
   1019 
   1020 print "}";
   1021 
   1022 print "";
   1023 print "/* Compare two target options  */";
   1024 print "bool";
   1025 print "cl_target_option_eq (struct cl_target_option const *ptr1 ATTRIBUTE_UNUSED,";
   1026 print "                     struct cl_target_option const *ptr2 ATTRIBUTE_UNUSED)";
   1027 print "{";
   1028 n_target_val = 0;
   1029 n_target_str = 0;
   1030 n_target_array = 0;
   1031 
   1032 for (i = 0; i < n_target_save; i++) {
   1033 	var = target_save_decl[i];
   1034 	sub (" *=.*", "", var);
   1035 	name = var;
   1036 	type = var;
   1037 	sub("^.*[ *]", "", name)
   1038 	sub(" *" name "$", "", type)
   1039 	if (target_save_decl[i] ~ "^const char \\*+[_" alnum "]+$") {
   1040 		var_target_str[n_target_str++] = name;
   1041 		string_options_names[name]++
   1042 	}
   1043 	else {
   1044 		if (target_save_decl[i] ~ " .*\\[.+\\]+$") {
   1045 			size = name;
   1046 			sub("[^\\[]+\\[", "", size);
   1047 			sub("\\]$", "", size);
   1048 			sub("\\[.+", "", name)
   1049 			sub(" [^ ]+$", "", type)
   1050 			var_target_array[n_target_array] = name
   1051 			var_target_array_type[n_target_array] = type
   1052 			var_target_array_size[n_target_array++] = size
   1053 		}
   1054 		else {
   1055 			var_target_val_type[n_target_val] = type;
   1056 			var_target_val[n_target_val++] = name;
   1057 		}
   1058 	}
   1059 }
   1060 if (have_save) {
   1061 	for (i = 0; i < n_opts; i++) {
   1062 		if (flag_set_p("Save", flags[i])) {
   1063 			name = var_name(flags[i])
   1064 			if(name == "")
   1065 				name = "target_flags";
   1066 
   1067 			if(name in var_list_seen)
   1068 				continue;
   1069 
   1070 			var_list_seen[name]++;
   1071 			otype = var_type_struct(flags[i])
   1072 			if (otype ~ "^const char \\**$")
   1073 				var_target_str[n_target_str++] = "x_" name;
   1074 			else {
   1075 				var_target_val_type[n_target_val] = otype;
   1076 				var_target_val[n_target_val++] = "x_" name;
   1077 			}
   1078 		}
   1079 	}
   1080 } else {
   1081 	var_target_val_type[n_target_val] = "int";
   1082 	var_target_val[n_target_val++] = "x_target_flags";
   1083 }
   1084 
   1085 for (i = 0; i < n_target_str; i++) {
   1086 	name = var_target_str[i]
   1087 	print "  if (ptr1->" name" != ptr2->" name;
   1088 	print "      && (!ptr1->" name" || !ptr2->" name
   1089 	print "          || strcmp (ptr1->" name", ptr2->" name ")))";
   1090 	print "    return false;";
   1091 }
   1092 for (i = 0; i < n_target_array; i++) {
   1093 	name = var_target_array[i]
   1094 	size = var_target_array_size[i]
   1095 	type = var_target_array_type[i]
   1096 	print "  if (ptr1->" name" != ptr2->" name "";
   1097 	print "      || memcmp (ptr1->" name ", ptr2->" name ", " size " * sizeof(" type ")))"
   1098 	print "    return false;";
   1099 }
   1100 for (i = 0; i < n_target_val; i++) {
   1101 	name = var_target_val[i]
   1102 	print "  if (ptr1->" name" != ptr2->" name ")";
   1103 	print "    return false;";
   1104 }
   1105 
   1106 if (has_target_explicit_mask) {
   1107 	print "  for (size_t i = 0; i < sizeof (ptr1->explicit_mask) / sizeof (ptr1->explicit_mask[0]); i++)";
   1108 	print "    if (ptr1->explicit_mask[i] != ptr2->explicit_mask[i])";
   1109 	print "      return false;"
   1110 }
   1111 
   1112 for (i = 0; i < n_target_other; i++) {
   1113 	if (var_target_other[i] in var_target_explicit_mask) {
   1114 		print "  if (ptr1->explicit_mask_" var_target_other[i] " != ptr2->explicit_mask_" var_target_other[i] ")";
   1115 		print "    return false;";
   1116 	}
   1117 }
   1118 
   1119 for (i = 0; i < n_target_int; i++) {
   1120 	if (var_target_int[i] in var_target_explicit_mask) {
   1121 		print "  if (ptr1->explicit_mask_" var_target_int[i] " != ptr2->explicit_mask_" var_target_int[i] ")";
   1122 		print "    return false;";
   1123 	}
   1124 }
   1125 
   1126 print "  return true;";
   1127 
   1128 print "}";
   1129 
   1130 print "";
   1131 print "/* Hash target options  */";
   1132 print "hashval_t";
   1133 print "cl_target_option_hash (struct cl_target_option const *ptr ATTRIBUTE_UNUSED)";
   1134 print "{";
   1135 print "  inchash::hash hstate;";
   1136 for (i = 0; i < n_target_str; i++) {
   1137 	name = var_target_str[i]
   1138 	print "  if (ptr->" name")";
   1139 	print "    hstate.add (ptr->" name", strlen (ptr->" name"));";
   1140 	print "  else";
   1141 	print "    hstate.add_int (0);";
   1142 }
   1143 for (i = 0; i < n_target_array; i++) {
   1144 	name= var_target_array[i]
   1145 	size = var_target_array_size[i]
   1146 	type = var_target_array_type[i]
   1147 	print "  hstate.add_int (" size ");";
   1148 	print "  hstate.add (ptr->" name ", sizeof (" type ") * " size ");";
   1149 }
   1150 for (i = 0; i < n_target_val; i++) {
   1151 	name = var_target_val[i]
   1152 	print "  hstate.add_hwi (ptr->" name");";
   1153 }
   1154 if (has_target_explicit_mask) {
   1155 	print "  for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)";
   1156 	print "    hstate.add_hwi (ptr->explicit_mask[i]);";
   1157 }
   1158 
   1159 for (i = 0; i < n_target_other; i++) {
   1160 	if (var_target_other[i] in var_target_explicit_mask)
   1161 		print "  hstate.add_hwi (ptr->explicit_mask_" var_target_other[i] ");";
   1162 }
   1163 
   1164 for (i = 0; i < n_target_int; i++) {
   1165 	if (var_target_int[i] in var_target_explicit_mask)
   1166 		print "  hstate.add_hwi (ptr->explicit_mask_" var_target_int[i] ");";
   1167 }
   1168 
   1169 print "  return hstate.end ();";
   1170 print "}";
   1171 
   1172 print "";
   1173 print "/* Stream out target options  */";
   1174 print "void";
   1175 print "cl_target_option_stream_out (struct output_block *ob ATTRIBUTE_UNUSED,";
   1176 print "                             struct bitpack_d *bp ATTRIBUTE_UNUSED,";
   1177 print "                             struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
   1178 print "{";
   1179 for (i = 0; i < n_target_str; i++) {
   1180 	name = var_target_str[i]
   1181 	print "  bp_pack_string (ob, bp, ptr->" name", true);";
   1182 }
   1183 for (i = 0; i < n_target_array; i++) {
   1184 	name = var_target_array[i]
   1185 	size = var_target_array_size[i]
   1186 	print "  for (unsigned i = 0; i < " size "; i++)"
   1187 	print "    bp_pack_value (bp, ptr->" name "[i], 64);";
   1188 }
   1189 for (i = 0; i < n_target_val; i++) {
   1190 	name = var_target_val[i]
   1191 	print "  bp_pack_value (bp, ptr->" name", 64);";
   1192 }
   1193 
   1194 if (has_target_explicit_mask) {
   1195 	print "  for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)";
   1196 	print "    bp_pack_value (bp, ptr->explicit_mask[i], 64);";
   1197 }
   1198 
   1199 for (i = 0; i < n_target_other; i++) {
   1200 	if (var_target_other[i] in var_target_explicit_mask) {
   1201 		print "  bp_pack_value (bp, ptr->explicit_mask_" var_target_other[i] ", 64);";
   1202 	}
   1203 }
   1204 
   1205 for (i = 0; i < n_target_int; i++) {
   1206 	if (var_target_int[i] in var_target_explicit_mask) {
   1207 		print "  bp_pack_value (bp, ptr->explicit_mask_" var_target_int[i] ", 64);";
   1208 	}
   1209 }
   1210 
   1211 print "}";
   1212 
   1213 print "";
   1214 print "/* Stream in target options  */";
   1215 print "void";
   1216 print "cl_target_option_stream_in (struct data_in *data_in ATTRIBUTE_UNUSED,";
   1217 print "                            struct bitpack_d *bp ATTRIBUTE_UNUSED,";
   1218 print "                            struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
   1219 print "{";
   1220 for (i = 0; i < n_target_str; i++) {
   1221 	name = var_target_str[i]
   1222 	print "  ptr->" name" = bp_unpack_string (data_in, bp);";
   1223 	print "  if (ptr->" name")";
   1224 	print "    ptr->" name" = xstrdup (ptr->" name");";
   1225 }
   1226 for (i = 0; i < n_target_array; i++) {
   1227 	name = var_target_array[i]
   1228 	size = var_target_array_size[i]
   1229 	print "  for (int i = " size " - 1; i >= 0; i--)"
   1230 	print "    ptr->" name "[i] = (" var_target_array_type[i] ") bp_unpack_value (bp, 64);";
   1231 }
   1232 for (i = 0; i < n_target_val; i++) {
   1233 	name = var_target_val[i]
   1234 	print "  ptr->" name" = (" var_target_val_type[i] ") bp_unpack_value (bp, 64);";
   1235 }
   1236 
   1237 if (has_target_explicit_mask) {
   1238 	print "  for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)";
   1239 	print "    ptr->explicit_mask[i] = bp_unpack_value (bp, 64);";
   1240 }
   1241 
   1242 for (i = 0; i < n_target_other; i++) {
   1243 	if (var_target_other[i] in var_target_explicit_mask) {
   1244 		print "  ptr->explicit_mask_" var_target_other[i] " = bp_unpack_value (bp, 64);";
   1245 	}
   1246 }
   1247 
   1248 for (i = 0; i < n_target_int; i++) {
   1249 	if (var_target_int[i] in var_target_explicit_mask) {
   1250 		print "  ptr->explicit_mask_" var_target_int[i] " = bp_unpack_value (bp, 64);";
   1251 	}
   1252 }
   1253 
   1254 print "}";
   1255 
   1256 print "/* free heap memory used by target options  */";
   1257 print "void";
   1258 print "cl_target_option_free (struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
   1259 print "{";
   1260 for (i = 0; i < n_target_str; i++) {
   1261 	name = var_target_str[i]
   1262 	print "  if (ptr->" name")";
   1263 	print "    free (const_cast <char *>(ptr->" name"));";
   1264 }
   1265 print "}";
   1266 
   1267 n_opt_val = 4;
   1268 var_opt_val[0] = "x_optimize"
   1269 var_opt_val_type[0] = "char "
   1270 var_opt_hash[0] = 1;
   1271 var_opt_val[1] = "x_optimize_size"
   1272 var_opt_val_type[1] = "char "
   1273 var_opt_hash[1] = 1;
   1274 var_opt_val[2] = "x_optimize_debug"
   1275 var_opt_val_type[2] = "char "
   1276 var_opt_hash[2] = 1;
   1277 var_opt_val[3] = "x_optimize_fast"
   1278 var_opt_val_type[3] = "char "
   1279 var_opt_hash[3] = 1;
   1280 for (i = 0; i < n_opts; i++) {
   1281 	if (flag_set_p("(Optimization|PerFunction)", flags[i])) {
   1282 		name = var_name(flags[i])
   1283 		if(name == "")
   1284 			continue;
   1285 
   1286 		if(name in var_opt_list_seen)
   1287 			continue;
   1288 
   1289 		var_opt_list_seen[name]++;
   1290 
   1291 		otype = var_type_struct(flags[i])
   1292 		var_opt_val_type[n_opt_val] = otype;
   1293 		var_opt_val[n_opt_val] = "x_" name;
   1294 		var_opt_hash[n_opt_val] = flag_set_p("Optimization", flags[i]);
   1295 		var_opt_init[n_opt_val] = opt_args("Init", flags[i]);
   1296 		n_opt_val++;
   1297 	}
   1298 }
   1299 print "";
   1300 print "/* Hash optimization options  */";
   1301 print "hashval_t";
   1302 print "cl_optimization_hash (struct cl_optimization const *ptr ATTRIBUTE_UNUSED)";
   1303 print "{";
   1304 print "  inchash::hash hstate;";
   1305 for (i = 0; i < n_opt_val; i++) {
   1306 	if (!var_opt_hash[i])
   1307 		continue;
   1308 	name = var_opt_val[i]
   1309 	otype = var_opt_val_type[i];
   1310 	if (otype ~ "^const char \\**$")
   1311 	{
   1312 		print "  if (ptr->" name")";
   1313 		print "    hstate.add (ptr->" name", strlen (ptr->" name"));";
   1314 		print "  else";
   1315 		print "    hstate.add_int (0);";
   1316 	}
   1317 	else
   1318 		print "  hstate.add_hwi (ptr->" name");";
   1319 }
   1320 print "  for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)";
   1321 print "    hstate.add_hwi (ptr->explicit_mask[i]);";
   1322 print "  return hstate.end ();";
   1323 print "}";
   1324 
   1325 print "";
   1326 print "/* Compare two optimization options  */";
   1327 print "bool";
   1328 print "cl_optimization_option_eq (cl_optimization const *ptr1,";
   1329 print "                           cl_optimization const *ptr2)";
   1330 print "{";
   1331 for (i = 0; i < n_opt_val; i++) {
   1332 	if (!var_opt_hash[i])
   1333 		continue;
   1334 	name = var_opt_val[i]
   1335 	otype = var_opt_val_type[i];
   1336 	if (otype ~ "^const char \\**$")
   1337 	{
   1338 		print "  if (ptr1->" name" != ptr2->" name;
   1339 		print "      && (!ptr1->" name" || !ptr2->" name
   1340 		print "          || strcmp (ptr1->" name", ptr2->" name ")))";
   1341 		print "    return false;";
   1342 	}
   1343 	else
   1344 	{
   1345 		print "  if (ptr1->" name" != ptr2->" name ")";
   1346 		print "    return false;";
   1347 	}
   1348 }
   1349 print "  for (size_t i = 0; i < sizeof (ptr1->explicit_mask) / sizeof (ptr1->explicit_mask[0]); i++)";
   1350 print "    if (ptr1->explicit_mask[i] != ptr2->explicit_mask[i])";
   1351 print "      return false;"
   1352 print "  return true;";
   1353 print "}";
   1354 
   1355 print "";
   1356 print "/* Stream out optimization options  */";
   1357 print "void";
   1358 print "cl_optimization_stream_out (struct output_block *ob,";
   1359 print "                            struct bitpack_d *bp,";
   1360 print "                            struct cl_optimization *ptr)";
   1361 print "{";
   1362 for (i = 0; i < n_opt_val; i++) {
   1363 	name = var_opt_val[i]
   1364 	otype = var_opt_val_type[i];
   1365 	if (otype ~ "^const char \\**$")
   1366 		print "  bp_pack_string (ob, bp, ptr->" name", true);";
   1367 	else {
   1368 		if (otype ~ "^unsigned") {
   1369 			sgn = "unsigned";
   1370 		} else {
   1371 			sgn = "int";
   1372 		}
   1373 		if (name ~ "^x_param" && !(otype ~ "^enum ") && var_opt_init[i]) {
   1374 			print "  if (" var_opt_init[i] " > (" var_opt_val_type[i] ") 10)";
   1375 			print "    bp_pack_var_len_" sgn " (bp, ptr->" name" ^ " var_opt_init[i] ");";
   1376 			print "  else";
   1377 			print "    bp_pack_var_len_" sgn " (bp, ptr->" name");";
   1378 		} else {
   1379 			print "  bp_pack_var_len_" sgn " (bp, ptr->" name");";
   1380 		}
   1381 	}
   1382 }
   1383 print "  for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)";
   1384 print "    bp_pack_value (bp, ptr->explicit_mask[i], 64);";
   1385 print "}";
   1386 
   1387 print "";
   1388 print "/* Stream in optimization options  */";
   1389 print "void";
   1390 print "cl_optimization_stream_in (struct data_in *data_in ATTRIBUTE_UNUSED,";
   1391 print "                           struct bitpack_d *bp ATTRIBUTE_UNUSED,";
   1392 print "                           struct cl_optimization *ptr ATTRIBUTE_UNUSED)";
   1393 print "{";
   1394 for (i = 0; i < n_opt_val; i++) {
   1395 	name = var_opt_val[i]
   1396 	otype = var_opt_val_type[i];
   1397 	if (otype ~ "^const char \\**$") {
   1398 		print "  ptr->" name" = bp_unpack_string (data_in, bp);";
   1399 		print "  if (ptr->" name")";
   1400 		print "    ptr->" name" = xstrdup (ptr->" name");";
   1401 	}
   1402 	else {
   1403 		if (otype ~ "^unsigned") {
   1404 			sgn = "unsigned";
   1405 		} else {
   1406 			sgn = "int";
   1407 		}
   1408 		print "  ptr->" name" = (" var_opt_val_type[i] ") bp_unpack_var_len_" sgn " (bp);";
   1409 		if (name ~ "^x_param" && !(otype ~ "^enum ") && var_opt_init[i]) {
   1410 			print "  if (" var_opt_init[i] " > (" var_opt_val_type[i] ") 10)";
   1411 			print "    ptr->" name" ^= " var_opt_init[i] ";";
   1412 		}
   1413 	}
   1414 }
   1415 print "  for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)";
   1416 print "    ptr->explicit_mask[i] = bp_unpack_value (bp, 64);";
   1417 print "}";
   1418 print "/* Free heap memory used by optimization options  */";
   1419 print "void";
   1420 print "cl_optimization_option_free (struct cl_optimization *ptr ATTRIBUTE_UNUSED)";
   1421 print "{";
   1422 for (i = 0; i < n_opt_val; i++) {
   1423 	name = var_opt_val[i]
   1424 	otype = var_opt_val_type[i];
   1425 	if (otype ~ "^const char \\**$")
   1426 	{
   1427 	      print "  if (ptr->" name")";
   1428 	      print "    free (const_cast <char *>(ptr->" name"));";
   1429 	}
   1430 }
   1431 print "}";
   1432 
   1433 print "void";
   1434 print "cl_optimization_compare (gcc_options *ptr1, gcc_options *ptr2)"
   1435 print "{"
   1436 
   1437 # all these options are mentioned in PR92860
   1438 checked_options["flag_merge_constants"]++
   1439 checked_options["param_max_fields_for_field_sensitive"]++
   1440 checked_options["flag_omit_frame_pointer"]++
   1441 # arc exceptions
   1442 checked_options["TARGET_ALIGN_CALL"]++
   1443 checked_options["TARGET_CASE_VECTOR_PC_RELATIVE"]++
   1444 checked_options["arc_size_opt_level"]++
   1445 # arm exceptions
   1446 checked_options["arm_fp16_format"]++
   1447 
   1448 
   1449 for (i = 0; i < n_opts; i++) {
   1450 	name = var_name(flags[i]);
   1451 	if (name == "")
   1452 		continue;
   1453 
   1454 	# We do not want to compare warning-related options, since they
   1455 	# might have been modified by a #pragma GCC diagnostic.
   1456 	if (flag_set_p("Warning", flags[i]))
   1457 		continue;
   1458 
   1459 	if (name in checked_options)
   1460 		continue;
   1461 	checked_options[name]++
   1462 
   1463 	if (name in string_options_names || ("x_" name) in string_options_names) {
   1464 	  print "  if (ptr1->x_" name " != ptr2->x_" name "";
   1465 	  print "      && (!ptr1->x_" name" || !ptr2->x_" name
   1466 	  print "          || strcmp (ptr1->x_" name", ptr2->x_" name ")))";
   1467 	  print "    internal_error (\"%<global_options%> are modified in local context\");";
   1468 	}
   1469 	else {
   1470 	  print "  if (ptr1->x_" name " != ptr2->x_" name ")"
   1471 	  print "    internal_error (\"%<global_options%> are modified in local context\");";
   1472 	}
   1473 }
   1474 
   1475 print "}";
   1476 }
   1477