1#  Copyright (C) 2003-2021 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.c
29
30# Dump that array of options into a C file.
31END {
32print "/* This file is auto-generated by optc-save-gen.awk.  */"
33print ""
34n_headers = split(header_name, headers, " ")
35for (i = 1; i <= n_headers; i++)
36	print "#include " quote headers[i] quote
37print "#include " quote "opts.h" quote
38print "#include " quote "intl.h" quote
39print ""
40print "#include " quote "flags.h" quote
41print "#include " quote "target.h" quote
42print "#include " quote "inchash.h" quote
43print "#include " quote "hash-set.h" quote
44print "#include " quote "vec.h" quote
45print "#include " quote "input.h" quote
46print "#include " quote "alias.h" quote
47print "#include " quote "symtab.h" quote
48print "#include " quote "inchash.h" quote
49print "#include " quote "tree.h" quote
50print "#include " quote "fold-const.h" quote
51print "#include " quote "tree-ssa-alias.h" quote
52print "#include " quote "is-a.h" quote
53print "#include " quote "predict.h" quote
54print "#include " quote "function.h" quote
55print "#include " quote "basic-block.h" quote
56print "#include " quote "gimple-expr.h" quote
57print "#include " quote "gimple.h" quote
58print "#include " quote "data-streamer.h" quote
59print "#include " quote "ipa-ref.h" quote
60print "#include " quote "cgraph.h" quote
61print ""
62
63if (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
70have_save = 0;
71if (n_extra_target_vars)
72	have_save = 1
73
74for (i = 0; i < n_opts; i++) {
75	if (flag_set_p("Save", flags[i]))
76		have_save = 1;
77}
78
79print "/* Save optimization variables into a structure.  */"
80print "void";
81print "cl_optimization_save (struct cl_optimization *ptr, struct gcc_options *opts,";
82print "		      struct gcc_options *opts_set)";
83print "{";
84
85n_opt_char = 4;
86n_opt_short = 0;
87n_opt_int = 0;
88n_opt_enum = 0;
89n_opt_string = 0;
90n_opt_other = 0;
91var_opt_char[0] = "optimize";
92var_opt_char[1] = "optimize_size";
93var_opt_char[2] = "optimize_debug";
94var_opt_char[3] = "optimize_fast";
95var_opt_range["optimize"] = "0, 255";
96var_opt_range["optimize_size"] = "0, 1";
97var_opt_range["optimize_debug"] = "0, 1";
98var_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
103for (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
140for (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
146print "";
147for (i = 0; i < n_opt_other; i++) {
148	print "  ptr->x_" var_opt_other[i] " = opts->x_" var_opt_other[i] ";";
149}
150
151for (i = 0; i < n_opt_int; i++) {
152	print "  ptr->x_" var_opt_int[i] " = opts->x_" var_opt_int[i] ";";
153}
154
155for (i = 0; i < n_opt_enum; i++) {
156	print "  ptr->x_" var_opt_enum[i] " = opts->x_" var_opt_enum[i] ";";
157}
158
159for (i = 0; i < n_opt_short; i++) {
160	print "  ptr->x_" var_opt_short[i] " = opts->x_" var_opt_short[i] ";";
161}
162
163for (i = 0; i < n_opt_char; i++) {
164	print "  ptr->x_" var_opt_char[i] " = opts->x_" var_opt_char[i] ";";
165}
166
167for (i = 0; i < n_opt_string; i++) {
168	print "  ptr->x_" var_opt_string[i] " = opts->x_" var_opt_string[i] ";";
169}
170
171print "";
172print "  unsigned HOST_WIDE_INT mask = 0;";
173
174j = 0;
175k = 0;
176for (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
187for (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
198for (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
209for (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
220for (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
231for (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
242if (j != 0) {
243	print "  ptr->explicit_mask[" k "] = mask;";
244}
245
246print "}";
247
248print "";
249print "/* Restore optimization options from a structure.  */";
250print "void";
251print "cl_optimization_restore (struct gcc_options *opts, struct gcc_options *opts_set,";
252print "			 struct cl_optimization *ptr)";
253print "{";
254
255for (i = 0; i < n_opt_other; i++) {
256	print "  opts->x_" var_opt_other[i] " = ptr->x_" var_opt_other[i] ";";
257}
258
259for (i = 0; i < n_opt_int; i++) {
260	print "  opts->x_" var_opt_int[i] " = ptr->x_" var_opt_int[i] ";";
261}
262
263for (i = 0; i < n_opt_enum; i++) {
264	print "  opts->x_" var_opt_enum[i] " = ptr->x_" var_opt_enum[i] ";";
265}
266
267for (i = 0; i < n_opt_short; i++) {
268	print "  opts->x_" var_opt_short[i] " = ptr->x_" var_opt_short[i] ";";
269}
270
271for (i = 0; i < n_opt_char; i++) {
272	print "  opts->x_" var_opt_char[i] " = ptr->x_" var_opt_char[i] ";";
273}
274
275for (i = 0; i < n_opt_string; i++) {
276	print "  opts->x_" var_opt_string[i] " = ptr->x_" var_opt_string[i] ";";
277}
278
279print "";
280print "  unsigned HOST_WIDE_INT mask;";
281
282j = 64;
283k = 0;
284for (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
295for (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
306for (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
317for (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
328for (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
339for (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
350print "  targetm.override_options_after_change ();";
351print "}";
352
353print "";
354print "/* Print optimization options from a structure.  */";
355print "void";
356print "cl_optimization_print (FILE *file,";
357print "                       int indent_to,";
358print "                       struct cl_optimization *ptr)";
359print "{";
360
361print "  fputs (\"\\n\", file);";
362for (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
371for (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
380for (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
388for (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
397for (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
406for (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
415print "}";
416
417print "";
418print "/* Print different optimization variables from structures provided as arguments.  */";
419print "void";
420print "cl_optimization_print_diff (FILE *file,";
421print "                            int indent_to,";
422print "                            struct cl_optimization *ptr1,";
423print "                            struct cl_optimization *ptr2)";
424print "{";
425
426print "  fputs (\"\\n\", file);";
427for (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
437for (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
447for (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
457for (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
467for (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
477for (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
490print "}";
491
492
493print "";
494print "/* Save selected option variables into a structure.  */"
495print "void";
496print "cl_target_option_save (struct cl_target_option *ptr, struct gcc_options *opts,";
497print "		       struct gcc_options *opts_set)";
498print "{";
499
500n_target_char = 0;
501n_target_short = 0;
502n_target_int = 0;
503n_target_enum = 0;
504n_target_string = 0;
505n_target_other = 0;
506
507if (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
555have_assert = 0;
556for (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
564if (have_assert)
565	print "";
566
567print "  if (targetm.target_option.save)";
568print "    targetm.target_option.save (ptr, opts, opts_set);";
569print "";
570
571for (i = 0; i < n_extra_target_vars; i++) {
572	print "  ptr->x_" extra_target_vars[i] " = opts->x_" extra_target_vars[i] ";";
573}
574
575for (i = 0; i < n_target_other; i++) {
576	print "  ptr->x_" var_target_other[i] " = opts->x_" var_target_other[i] ";";
577}
578
579for (i = 0; i < n_target_enum; i++) {
580	print "  ptr->x_" var_target_enum[i] " = opts->x_" var_target_enum[i] ";";
581}
582
583for (i = 0; i < n_target_int; i++) {
584	print "  ptr->x_" var_target_int[i] " = opts->x_" var_target_int[i] ";";
585}
586
587for (i = 0; i < n_target_short; i++) {
588	print "  ptr->x_" var_target_short[i] " = opts->x_" var_target_short[i] ";";
589}
590
591for (i = 0; i < n_target_char; i++) {
592	print "  ptr->x_" var_target_char[i] " = opts->x_" var_target_char[i] ";";
593}
594
595for (i = 0; i < n_target_string; i++) {
596	print "  ptr->x_" var_target_string[i] " = opts->x_" var_target_string[i] ";";
597}
598
599print "";
600
601j = 0;
602k = 0;
603for (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
617for (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
635for (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
649for (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
667for (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
681for (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
695for (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
709if (j != 0) {
710	print "  ptr->explicit_mask[" k "] = mask;";
711}
712has_target_explicit_mask = 0;
713if (j != 0 || k != 0) {
714	has_target_explicit_mask = 1;
715}
716
717print "}";
718
719print "";
720print "/* Restore selected current options from a structure.  */";
721print "void";
722print "cl_target_option_restore (struct gcc_options *opts, struct gcc_options *opts_set,";
723print "			  struct cl_target_option *ptr)";
724print "{";
725
726for (i = 0; i < n_extra_target_vars; i++) {
727	print "  opts->x_" extra_target_vars[i] " = ptr->x_" extra_target_vars[i] ";";
728}
729
730for (i = 0; i < n_target_other; i++) {
731	print "  opts->x_" var_target_other[i] " = ptr->x_" var_target_other[i] ";";
732}
733
734for (i = 0; i < n_target_enum; i++) {
735	print "  opts->x_" var_target_enum[i] " = ptr->x_" var_target_enum[i] ";";
736}
737
738for (i = 0; i < n_target_int; i++) {
739	print "  opts->x_" var_target_int[i] " = ptr->x_" var_target_int[i] ";";
740}
741
742for (i = 0; i < n_target_short; i++) {
743	print "  opts->x_" var_target_short[i] " = ptr->x_" var_target_short[i] ";";
744}
745
746for (i = 0; i < n_target_char; i++) {
747	print "  opts->x_" var_target_char[i] " = ptr->x_" var_target_char[i] ";";
748}
749
750for (i = 0; i < n_target_string; i++) {
751	print "  opts->x_" var_target_string[i] " = ptr->x_" var_target_string[i] ";";
752}
753
754print "";
755if (has_target_explicit_mask) {
756	print "  unsigned HOST_WIDE_INT mask;";
757}
758
759j = 64;
760k = 0;
761for (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
780for (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
795for (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
806for (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
821for (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
832for (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
843for (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.
856print "";
857print "  if (targetm.target_option.restore)";
858print "    targetm.target_option.restore (opts, opts_set, ptr);";
859
860print "}";
861
862print "";
863print "/* Print optimization options from a structure.  */";
864print "void";
865print "cl_target_option_print (FILE *file,";
866print "                        int indent,";
867print "                        struct cl_target_option *ptr)";
868print "{";
869
870print "  fputs (\"\\n\", file);";
871for (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
887for (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
896for (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
905for (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
914for (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
923for (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
932print "";
933print "  if (targetm.target_option.print)";
934print "    targetm.target_option.print (file, indent, ptr);";
935print "}";
936
937print "";
938print "/* Print different target option variables from structures provided as arguments.  */";
939print "void";
940print "cl_target_option_print_diff (FILE *file,";
941print "                             int indent ATTRIBUTE_UNUSED,";
942print "                             struct cl_target_option *ptr1 ATTRIBUTE_UNUSED,";
943print "                             struct cl_target_option *ptr2 ATTRIBUTE_UNUSED)";
944print "{";
945
946print "  fputs (\"\\n\", file);";
947for (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
967for (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
977for (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
987for (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
997for (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
1007for (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 " ? ptr1->x_" name " : \"(null)\");";
1017	print "";
1018}
1019
1020print "}";
1021
1022print "";
1023print "/* Compare two target options  */";
1024print "bool";
1025print "cl_target_option_eq (struct cl_target_option const *ptr1 ATTRIBUTE_UNUSED,";
1026print "                     struct cl_target_option const *ptr2 ATTRIBUTE_UNUSED)";
1027print "{";
1028n_target_val = 0;
1029n_target_str = 0;
1030n_target_array = 0;
1031
1032for (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}
1060if (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
1085for (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}
1092for (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}
1100for (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
1106if (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
1112for (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
1119for (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
1126print "  return true;";
1127
1128print "}";
1129
1130print "";
1131print "/* Hash target options  */";
1132print "hashval_t";
1133print "cl_target_option_hash (struct cl_target_option const *ptr ATTRIBUTE_UNUSED)";
1134print "{";
1135print "  inchash::hash hstate;";
1136for (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}
1143for (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}
1150for (i = 0; i < n_target_val; i++) {
1151	name = var_target_val[i]
1152	print "  hstate.add_hwi (ptr->" name");";
1153}
1154if (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
1159for (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
1164for (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
1169print "  return hstate.end ();";
1170print "}";
1171
1172print "";
1173print "/* Stream out target options  */";
1174print "void";
1175print "cl_target_option_stream_out (struct output_block *ob ATTRIBUTE_UNUSED,";
1176print "                             struct bitpack_d *bp ATTRIBUTE_UNUSED,";
1177print "                             struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
1178print "{";
1179for (i = 0; i < n_target_str; i++) {
1180	name = var_target_str[i]
1181	print "  bp_pack_string (ob, bp, ptr->" name", true);";
1182}
1183for (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}
1189for (i = 0; i < n_target_val; i++) {
1190	name = var_target_val[i]
1191	print "  bp_pack_value (bp, ptr->" name", 64);";
1192}
1193
1194if (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
1199for (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
1205for (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
1211print "}";
1212
1213print "";
1214print "/* Stream in target options  */";
1215print "void";
1216print "cl_target_option_stream_in (struct data_in *data_in ATTRIBUTE_UNUSED,";
1217print "                            struct bitpack_d *bp ATTRIBUTE_UNUSED,";
1218print "                            struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
1219print "{";
1220for (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}
1226for (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}
1232for (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
1237if (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
1242for (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
1248for (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
1254print "}";
1255
1256print "/* free heap memory used by target options  */";
1257print "void";
1258print "cl_target_option_free (struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
1259print "{";
1260for (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}
1265print "}";
1266
1267n_opt_val = 4;
1268var_opt_val[0] = "x_optimize"
1269var_opt_val_type[0] = "char "
1270var_opt_hash[0] = 1;
1271var_opt_val[1] = "x_optimize_size"
1272var_opt_val_type[1] = "char "
1273var_opt_hash[1] = 1;
1274var_opt_val[2] = "x_optimize_debug"
1275var_opt_val_type[2] = "char "
1276var_opt_hash[2] = 1;
1277var_opt_val[3] = "x_optimize_fast"
1278var_opt_val_type[3] = "char "
1279var_opt_hash[3] = 1;
1280for (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}
1299print "";
1300print "/* Hash optimization options  */";
1301print "hashval_t";
1302print "cl_optimization_hash (struct cl_optimization const *ptr ATTRIBUTE_UNUSED)";
1303print "{";
1304print "  inchash::hash hstate;";
1305for (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}
1320print "  for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)";
1321print "    hstate.add_hwi (ptr->explicit_mask[i]);";
1322print "  return hstate.end ();";
1323print "}";
1324
1325print "";
1326print "/* Compare two optimization options  */";
1327print "bool";
1328print "cl_optimization_option_eq (cl_optimization const *ptr1,";
1329print "                           cl_optimization const *ptr2)";
1330print "{";
1331for (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}
1349print "  for (size_t i = 0; i < sizeof (ptr1->explicit_mask) / sizeof (ptr1->explicit_mask[0]); i++)";
1350print "    if (ptr1->explicit_mask[i] != ptr2->explicit_mask[i])";
1351print "      return false;"
1352print "  return true;";
1353print "}";
1354
1355print "";
1356print "/* Stream out optimization options  */";
1357print "void";
1358print "cl_optimization_stream_out (struct output_block *ob,";
1359print "                            struct bitpack_d *bp,";
1360print "                            struct cl_optimization *ptr)";
1361print "{";
1362for (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}
1383print "  for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)";
1384print "    bp_pack_value (bp, ptr->explicit_mask[i], 64);";
1385print "}";
1386
1387print "";
1388print "/* Stream in optimization options  */";
1389print "void";
1390print "cl_optimization_stream_in (struct data_in *data_in ATTRIBUTE_UNUSED,";
1391print "                           struct bitpack_d *bp ATTRIBUTE_UNUSED,";
1392print "                           struct cl_optimization *ptr ATTRIBUTE_UNUSED)";
1393print "{";
1394for (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}
1415print "  for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)";
1416print "    ptr->explicit_mask[i] = bp_unpack_value (bp, 64);";
1417print "}";
1418print "/* Free heap memory used by optimization options  */";
1419print "void";
1420print "cl_optimization_option_free (struct cl_optimization *ptr ATTRIBUTE_UNUSED)";
1421print "{";
1422for (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}
1431print "}";
1432
1433print "void";
1434print "cl_optimization_compare (gcc_options *ptr1, gcc_options *ptr2)"
1435print "{"
1436
1437# all these options are mentioned in PR92860
1438checked_options["flag_merge_constants"]++
1439checked_options["param_max_fields_for_field_sensitive"]++
1440checked_options["flag_omit_frame_pointer"]++
1441checked_options["unroll_only_small_loops"]++
1442# arc exceptions
1443checked_options["TARGET_ALIGN_CALL"]++
1444checked_options["TARGET_CASE_VECTOR_PC_RELATIVE"]++
1445checked_options["arc_size_opt_level"]++
1446# arm exceptions
1447checked_options["arm_fp16_format"]++
1448checked_options["flag_ipa_ra"]++
1449# s390 exceptions
1450checked_options["param_max_completely_peel_times"]++
1451checked_options["param_max_completely_peeled_insns"]++
1452checked_options["param_max_unroll_times"]++
1453checked_options["param_max_unrolled_insns"]++
1454
1455
1456for (i = 0; i < n_opts; i++) {
1457	name = var_name(flags[i]);
1458	if (name == "")
1459		continue;
1460
1461	if (name in checked_options)
1462		continue;
1463	checked_options[name]++
1464
1465	if (name in string_options_names || ("x_" name) in string_options_names) {
1466	  print "  if (ptr1->x_" name " != ptr2->x_" name "";
1467	  print "      && (!ptr1->x_" name" || !ptr2->x_" name
1468	  print "          || strcmp (ptr1->x_" name", ptr2->x_" name ")))";
1469	  print "    internal_error (\"%<global_options%> are modified in local context\");";
1470	}
1471	else {
1472	  print "  if (ptr1->x_" name " != ptr2->x_" name ")"
1473	  print "    internal_error (\"%<global_options%> are modified in local context\");";
1474	}
1475}
1476
1477print "}";
1478}
1479