1#  Copyright (C) 2003-2018 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 "{";
83
84n_opt_char = 4;
85n_opt_short = 0;
86n_opt_int = 0;
87n_opt_enum = 0;
88n_opt_other = 0;
89var_opt_char[0] = "optimize";
90var_opt_char[1] = "optimize_size";
91var_opt_char[2] = "optimize_debug";
92var_opt_char[3] = "optimize_fast";
93var_opt_range["optimize"] = "0, 255";
94var_opt_range["optimize_size"] = "0, 1";
95var_opt_range["optimize_debug"] = "0, 1";
96var_opt_range["optimize_fast"] = "0, 1";
97
98# Sort by size to mimic how the structure is laid out to be friendlier to the
99# cache.
100
101for (i = 0; i < n_opts; i++) {
102	if (flag_set_p("(Optimization|PerFunction)", flags[i])) {
103		name = var_name(flags[i])
104		if(name == "")
105			continue;
106
107		if(name in var_opt_seen)
108			continue;
109
110		var_opt_seen[name]++;
111		otype = var_type_struct(flags[i]);
112		if (otype ~ "^((un)?signed +)?int *$")
113			var_opt_int[n_opt_int++] = name;
114
115		else if (otype ~ "^((un)?signed +)?short *$")
116			var_opt_short[n_opt_short++] = name;
117
118		else if (otype ~ ("^enum +[_" alnum "]+ *"))
119			var_opt_enum[n_opt_enum++] = name;
120
121		else if (otype ~ "^((un)?signed +)?char *$") {
122			var_opt_char[n_opt_char++] = name;
123			if (otype ~ "^unsigned +char *$")
124				var_opt_range[name] = "0, 255"
125			else if (otype ~ "^signed +char *$")
126				var_opt_range[name] = "-128, 127"
127		}
128		else
129			var_opt_other[n_opt_other++] = name;
130	}
131}
132
133for (i = 0; i < n_opt_char; i++) {
134	name = var_opt_char[i];
135	if (var_opt_range[name] != "")
136		print "  gcc_assert (IN_RANGE (opts->x_" name ", " var_opt_range[name] "));";
137}
138
139print "";
140for (i = 0; i < n_opt_other; i++) {
141	print "  ptr->x_" var_opt_other[i] " = opts->x_" var_opt_other[i] ";";
142}
143
144for (i = 0; i < n_opt_int; i++) {
145	print "  ptr->x_" var_opt_int[i] " = opts->x_" var_opt_int[i] ";";
146}
147
148for (i = 0; i < n_opt_enum; i++) {
149	print "  ptr->x_" var_opt_enum[i] " = opts->x_" var_opt_enum[i] ";";
150}
151
152for (i = 0; i < n_opt_short; i++) {
153	print "  ptr->x_" var_opt_short[i] " = opts->x_" var_opt_short[i] ";";
154}
155
156for (i = 0; i < n_opt_char; i++) {
157	print "  ptr->x_" var_opt_char[i] " = opts->x_" var_opt_char[i] ";";
158}
159
160print "}";
161
162print "";
163print "/* Restore optimization options from a structure.  */";
164print "void";
165print "cl_optimization_restore (struct gcc_options *opts, struct cl_optimization *ptr)";
166print "{";
167
168for (i = 0; i < n_opt_other; i++) {
169	print "  opts->x_" var_opt_other[i] " = ptr->x_" var_opt_other[i] ";";
170}
171
172for (i = 0; i < n_opt_int; i++) {
173	print "  opts->x_" var_opt_int[i] " = ptr->x_" var_opt_int[i] ";";
174}
175
176for (i = 0; i < n_opt_enum; i++) {
177	print "  opts->x_" var_opt_enum[i] " = ptr->x_" var_opt_enum[i] ";";
178}
179
180for (i = 0; i < n_opt_short; i++) {
181	print "  opts->x_" var_opt_short[i] " = ptr->x_" var_opt_short[i] ";";
182}
183
184for (i = 0; i < n_opt_char; i++) {
185	print "  opts->x_" var_opt_char[i] " = ptr->x_" var_opt_char[i] ";";
186}
187
188print "  targetm.override_options_after_change ();";
189print "}";
190
191print "";
192print "/* Print optimization options from a structure.  */";
193print "void";
194print "cl_optimization_print (FILE *file,";
195print "                       int indent_to,";
196print "                       struct cl_optimization *ptr)";
197print "{";
198
199print "  fputs (\"\\n\", file);";
200for (i = 0; i < n_opt_other; i++) {
201	print "  if (ptr->x_" var_opt_other[i] ")";
202	print "    fprintf (file, \"%*s%s (%#lx)\\n\",";
203	print "             indent_to, \"\",";
204	print "             \"" var_opt_other[i] "\",";
205	print "             (unsigned long)ptr->x_" var_opt_other[i] ");";
206	print "";
207}
208
209for (i = 0; i < n_opt_int; i++) {
210	print "  if (ptr->x_" var_opt_int[i] ")";
211	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
212	print "             indent_to, \"\",";
213	print "             \"" var_opt_int[i] "\",";
214	print "             ptr->x_" var_opt_int[i] ");";
215	print "";
216}
217
218for (i = 0; i < n_opt_enum; i++) {
219	print "  fprintf (file, \"%*s%s (%#x)\\n\",";
220	print "           indent_to, \"\",";
221	print "           \"" var_opt_enum[i] "\",";
222	print "           (int) ptr->x_" var_opt_enum[i] ");";
223	print "";
224}
225
226for (i = 0; i < n_opt_short; i++) {
227	print "  if (ptr->x_" var_opt_short[i] ")";
228	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
229	print "             indent_to, \"\",";
230	print "             \"" var_opt_short[i] "\",";
231	print "             ptr->x_" var_opt_short[i] ");";
232	print "";
233}
234
235for (i = 0; i < n_opt_char; i++) {
236	print "  if (ptr->x_" var_opt_char[i] ")";
237	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
238	print "             indent_to, \"\",";
239	print "             \"" var_opt_char[i] "\",";
240	print "             ptr->x_" var_opt_char[i] ");";
241	print "";
242}
243
244print "}";
245
246print "";
247print "/* Print different optimization variables from structures provided as arguments.  */";
248print "void";
249print "cl_optimization_print_diff (FILE *file,";
250print "                            int indent_to,";
251print "                            struct cl_optimization *ptr1,";
252print "                            struct cl_optimization *ptr2)";
253print "{";
254
255print "  fputs (\"\\n\", file);";
256for (i = 0; i < n_opt_other; i++) {
257	print "  if (ptr1->x_" var_opt_other[i] " != ptr2->x_" var_opt_other[i] ")";
258	print "    fprintf (file, \"%*s%s (%#lx/%#lx)\\n\",";
259	print "             indent_to, \"\",";
260	print "             \"" var_opt_other[i] "\",";
261	print "             (unsigned long)ptr1->x_" var_opt_other[i] ",";
262	print "             (unsigned long)ptr2->x_" var_opt_other[i] ");";
263	print "";
264}
265
266for (i = 0; i < n_opt_int; i++) {
267	print "  if (ptr1->x_" var_opt_int[i] " != ptr2->x_" var_opt_int[i] ")";
268	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
269	print "             indent_to, \"\",";
270	print "             \"" var_opt_int[i] "\",";
271	print "             ptr1->x_" var_opt_int[i] ",";
272	print "             ptr2->x_" var_opt_int[i] ");";
273	print "";
274}
275
276for (i = 0; i < n_opt_enum; i++) {
277	print "  if (ptr1->x_" var_opt_enum[i] " != ptr2->x_" var_opt_enum[i] ")";
278	print "  fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
279	print "           indent_to, \"\",";
280	print "           \"" var_opt_enum[i] "\",";
281	print "           (int) ptr1->x_" var_opt_enum[i] ",";
282	print "           (int) ptr2->x_" var_opt_enum[i] ");";
283	print "";
284}
285
286for (i = 0; i < n_opt_short; i++) {
287	print "  if (ptr1->x_" var_opt_short[i] " != ptr2->x_" var_opt_short[i] ")";
288	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
289	print "             indent_to, \"\",";
290	print "             \"" var_opt_short[i] "\",";
291	print "             ptr1->x_" var_opt_short[i] ",";
292	print "             ptr2->x_" var_opt_short[i] ");";
293	print "";
294}
295
296for (i = 0; i < n_opt_char; i++) {
297	print "  if (ptr1->x_" var_opt_char[i] " != ptr2->x_" var_opt_char[i] ")";
298	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
299	print "             indent_to, \"\",";
300	print "             \"" var_opt_char[i] "\",";
301	print "             ptr1->x_" var_opt_char[i] ",";
302	print "             ptr2->x_" var_opt_char[i] ");";
303	print "";
304}
305
306print "}";
307
308
309print "";
310print "/* Save selected option variables into a structure.  */"
311print "void";
312print "cl_target_option_save (struct cl_target_option *ptr, struct gcc_options *opts)";
313print "{";
314
315n_target_char = 0;
316n_target_short = 0;
317n_target_int = 0;
318n_target_enum = 0;
319n_target_other = 0;
320
321if (have_save) {
322	for (i = 0; i < n_opts; i++) {
323		if (flag_set_p("Save", flags[i])) {
324			name = var_name(flags[i])
325			if(name == "")
326				name = "target_flags";
327
328			if(name in var_save_seen)
329				continue;
330
331			var_save_seen[name]++;
332			otype = var_type_struct(flags[i])
333			if (otype ~ "^((un)?signed +)?int *$")
334				var_target_int[n_target_int++] = name;
335
336			else if (otype ~ "^((un)?signed +)?short *$")
337				var_target_short[n_target_short++] = name;
338
339			else if (otype ~ ("^enum +[_" alnum "]+ *$"))
340				var_target_enum[n_target_enum++] = name;
341
342			else if (otype ~ "^((un)?signed +)?char *$") {
343				var_target_char[n_target_char++] = name;
344				if (otype ~ "^unsigned +char *$")
345					var_target_range[name] = "0, 255"
346				else if (otype ~ "^signed +char *$")
347					var_target_range[name] = "-128, 127"
348				if (otype == var_type(flags[i]))
349					var_target_range[name] = ""
350			}
351			else
352				var_target_other[n_target_other++] = name;
353		}
354	}
355} else {
356	var_target_int[n_target_int++] = "target_flags";
357}
358
359have_assert = 0;
360for (i = 0; i < n_target_char; i++) {
361	name = var_target_char[i];
362	if (var_target_range[name] != "") {
363		have_assert = 1;
364		print "  gcc_assert (IN_RANGE (opts->x_" name ", " var_target_range[name] "));";
365	}
366}
367
368if (have_assert)
369	print "";
370
371print "  if (targetm.target_option.save)";
372print "    targetm.target_option.save (ptr, opts);";
373print "";
374
375for (i = 0; i < n_extra_target_vars; i++) {
376	print "  ptr->x_" extra_target_vars[i] " = opts->x_" extra_target_vars[i] ";";
377}
378
379for (i = 0; i < n_target_other; i++) {
380	print "  ptr->x_" var_target_other[i] " = opts->x_" var_target_other[i] ";";
381}
382
383for (i = 0; i < n_target_enum; i++) {
384	print "  ptr->x_" var_target_enum[i] " = opts->x_" var_target_enum[i] ";";
385}
386
387for (i = 0; i < n_target_int; i++) {
388	print "  ptr->x_" var_target_int[i] " = opts->x_" var_target_int[i] ";";
389}
390
391for (i = 0; i < n_target_short; i++) {
392	print "  ptr->x_" var_target_short[i] " = opts->x_" var_target_short[i] ";";
393}
394
395for (i = 0; i < n_target_char; i++) {
396	print "  ptr->x_" var_target_char[i] " = opts->x_" var_target_char[i] ";";
397}
398
399print "}";
400
401print "";
402print "/* Restore selected current options from a structure.  */";
403print "void";
404print "cl_target_option_restore (struct gcc_options *opts, struct cl_target_option *ptr)";
405print "{";
406
407for (i = 0; i < n_extra_target_vars; i++) {
408	print "  opts->x_" extra_target_vars[i] " = ptr->x_" extra_target_vars[i] ";";
409}
410
411for (i = 0; i < n_target_other; i++) {
412	print "  opts->x_" var_target_other[i] " = ptr->x_" var_target_other[i] ";";
413}
414
415for (i = 0; i < n_target_enum; i++) {
416	print "  opts->x_" var_target_enum[i] " = ptr->x_" var_target_enum[i] ";";
417}
418
419for (i = 0; i < n_target_int; i++) {
420	print "  opts->x_" var_target_int[i] " = ptr->x_" var_target_int[i] ";";
421}
422
423for (i = 0; i < n_target_short; i++) {
424	print "  opts->x_" var_target_short[i] " = ptr->x_" var_target_short[i] ";";
425}
426
427for (i = 0; i < n_target_char; i++) {
428	print "  opts->x_" var_target_char[i] " = ptr->x_" var_target_char[i] ";";
429}
430
431# This must occur after the normal variables in case the code depends on those
432# variables.
433print "";
434print "  if (targetm.target_option.restore)";
435print "    targetm.target_option.restore (opts, ptr);";
436
437print "}";
438
439print "";
440print "/* Print optimization options from a structure.  */";
441print "void";
442print "cl_target_option_print (FILE *file,";
443print "                        int indent,";
444print "                        struct cl_target_option *ptr)";
445print "{";
446
447print "  fputs (\"\\n\", file);";
448for (i = 0; i < n_target_other; i++) {
449	print "  if (ptr->x_" var_target_other[i] ")";
450	if (host_wide_int[var_target_other[i]] == "yes")
451		print "    fprintf (file, \"%*s%s (%#\" HOST_WIDE_INT_PRINT \"x)\\n\",";
452	else
453		print "    fprintf (file, \"%*s%s (%#x)\\n\",";
454	print "             indent, \"\",";
455	print "             \"" var_target_other[i] "\",";
456	if (host_wide_int[var_target_other[i]] == "yes")
457		print "             ptr->x_" var_target_other[i] ");";
458	else
459		print "             (unsigned long)ptr->x_" var_target_other[i] ");";
460	print "";
461}
462
463for (i = 0; i < n_target_enum; i++) {
464	print "  if (ptr->x_" var_target_enum[i] ")";
465	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
466	print "             indent, \"\",";
467	print "             \"" var_target_enum[i] "\",";
468	print "             ptr->x_" var_target_enum[i] ");";
469	print "";
470}
471
472for (i = 0; i < n_target_int; i++) {
473	print "  if (ptr->x_" var_target_int[i] ")";
474	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
475	print "             indent, \"\",";
476	print "             \"" var_target_int[i] "\",";
477	print "             ptr->x_" var_target_int[i] ");";
478	print "";
479}
480
481for (i = 0; i < n_target_short; i++) {
482	print "  if (ptr->x_" var_target_short[i] ")";
483	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
484	print "             indent, \"\",";
485	print "             \"" var_target_short[i] "\",";
486	print "             ptr->x_" var_target_short[i] ");";
487	print "";
488}
489
490for (i = 0; i < n_target_char; i++) {
491	print "  if (ptr->x_" var_target_char[i] ")";
492	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
493	print "             indent, \"\",";
494	print "             \"" var_target_char[i] "\",";
495	print "             ptr->x_" var_target_char[i] ");";
496	print "";
497}
498
499print "";
500print "  if (targetm.target_option.print)";
501print "    targetm.target_option.print (file, indent, ptr);";
502print "}";
503
504print "";
505print "/* Print different target option variables from structures provided as arguments.  */";
506print "void";
507print "cl_target_option_print_diff (FILE *file,";
508print "                             int indent ATTRIBUTE_UNUSED,";
509print "                             struct cl_target_option *ptr1 ATTRIBUTE_UNUSED,";
510print "                             struct cl_target_option *ptr2 ATTRIBUTE_UNUSED)";
511print "{";
512
513print "  fputs (\"\\n\", file);";
514for (i = 0; i < n_target_other; i++) {
515	print "  if (ptr1->x_" var_target_other[i] " != ptr2->x_" var_target_other[i] ")";
516	if (host_wide_int[var_target_other[i]] == "yes")
517		print "    fprintf (file, \"%*s%s (%#\" HOST_WIDE_INT_PRINT \"x/%#\" HOST_WIDE_INT_PRINT \"x)\\n\",";
518	else
519		print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
520	print "             indent, \"\",";
521	print "             \"" var_target_other[i] "\",";
522	if (host_wide_int[var_target_other[i]] == "yes") {
523		print "             ptr1->x_" var_target_other[i] ",";
524		print "             ptr2->x_" var_target_other[i] ");";
525	}
526	else {
527		print "             (unsigned long)ptr1->x_" var_target_other[i] ",";
528		print "             (unsigned long)ptr2->x_" var_target_other[i] ");";
529	}
530	print "";
531}
532
533for (i = 0; i < n_target_enum; i++) {
534	print "  if (ptr1->x_" var_target_enum[i] " != ptr2->x_" var_target_enum[i] ")";
535	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
536	print "             indent, \"\",";
537	print "             \"" var_target_enum[i] "\",";
538	print "             ptr1->x_" var_target_enum[i] ",";
539	print "             ptr2->x_" var_target_enum[i] ");";
540	print "";
541}
542
543for (i = 0; i < n_target_int; i++) {
544	print "  if (ptr1->x_" var_target_int[i] " != ptr2->x_" var_target_int[i] ")";
545	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
546	print "             indent, \"\",";
547	print "             \"" var_target_int[i] "\",";
548	print "             ptr1->x_" var_target_int[i] ",";
549	print "             ptr2->x_" var_target_int[i] ");";
550	print "";
551}
552
553for (i = 0; i < n_target_short; i++) {
554	print "  if (ptr1->x_" var_target_short[i] " != ptr2->x_" var_target_short[i] ")";
555	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
556	print "             indent, \"\",";
557	print "             \"" var_target_short[i] "\",";
558	print "             ptr1->x_" var_target_short[i] ",";
559	print "             ptr2->x_" var_target_short[i] ");";
560	print "";
561}
562
563for (i = 0; i < n_target_char; i++) {
564	print "  if (ptr1->x_" var_target_char[i] " != ptr2->x_" var_target_char[i] ")";
565	print "    fprintf (file, \"%*s%s (%#x/%#x)\\n\",";
566	print "             indent, \"\",";
567	print "             \"" var_target_char[i] "\",";
568	print "             ptr1->x_" var_target_char[i] ",";
569	print "             ptr2->x_" var_target_char[i] ");";
570	print "";
571}
572
573print "}";
574
575print "";
576print "/* Compare two target options  */";
577print "bool";
578print "cl_target_option_eq (struct cl_target_option const *ptr1 ATTRIBUTE_UNUSED,";
579print "                     struct cl_target_option const *ptr2 ATTRIBUTE_UNUSED)";
580print "{";
581n_target_val = 0;
582n_target_str = 0;
583n_target_array = 0;
584
585for (i = 0; i < n_target_save; i++) {
586	var = target_save_decl[i];
587	sub (" *=.*", "", var);
588	name = var;
589	type = var;
590	sub("^.*[ *]", "", name)
591	sub(" *" name "$", "", type)
592	if (target_save_decl[i] ~ "^const char \\*+[_" alnum "]+$")
593		var_target_str[n_target_str++] = name;
594	else {
595		if (target_save_decl[i] ~ " .*\\[.+\\]+$") {
596			size = name;
597			sub("[^\\[]+\\[", "", size);
598			sub("\\]$", "", size);
599			sub("\\[.+", "", name)
600			sub(" [^ ]+$", "", type)
601			var_target_array[n_target_array] = name
602			var_target_array_type[n_target_array] = type
603			var_target_array_size[n_target_array++] = size
604		}
605		else {
606			var_target_val_type[n_target_val] = type;
607			var_target_val[n_target_val++] = name;
608		}
609	}
610}
611if (have_save) {
612	for (i = 0; i < n_opts; i++) {
613		if (flag_set_p("Save", flags[i])) {
614			name = var_name(flags[i])
615			if(name == "")
616				name = "target_flags";
617
618			if(name in var_list_seen)
619				continue;
620
621			var_list_seen[name]++;
622			otype = var_type_struct(flags[i])
623			if (otype ~ "^const char \\**$")
624				var_target_str[n_target_str++] = "x_" name;
625			else {
626				var_target_val_type[n_target_val] = otype;
627				var_target_val[n_target_val++] = "x_" name;
628			}
629		}
630	}
631} else {
632	var_target_val_type[n_target_val] = "int";
633	var_target_val[n_target_val++] = "x_target_flags";
634}
635
636for (i = 0; i < n_target_str; i++) {
637	name = var_target_str[i]
638	print "  if (ptr1->" name" != ptr2->" name;
639	print "      && (!ptr1->" name" || !ptr2->" name
640	print "          || strcmp (ptr1->" name", ptr2->" name ")))";
641	print "    return false;";
642}
643for (i = 0; i < n_target_array; i++) {
644	name = var_target_array[i]
645	size = var_target_array_size[i]
646	type = var_target_array_type[i]
647	print "  if (ptr1->" name" != ptr2->" name "";
648	print "      || memcmp (ptr1->" name ", ptr2->" name ", " size " * sizeof(" type ")))"
649	print "    return false;";
650}
651for (i = 0; i < n_target_val; i++) {
652	name = var_target_val[i]
653	print "  if (ptr1->" name" != ptr2->" name ")";
654	print "    return false;";
655}
656
657print "  return true;";
658
659print "}";
660
661print "";
662print "/* Hash target options  */";
663print "hashval_t";
664print "cl_target_option_hash (struct cl_target_option const *ptr ATTRIBUTE_UNUSED)";
665print "{";
666print "  inchash::hash hstate;";
667for (i = 0; i < n_target_str; i++) {
668	name = var_target_str[i]
669	print "  if (ptr->" name")";
670	print "    hstate.add (ptr->" name", strlen (ptr->" name"));";
671	print "  else";
672	print "    hstate.add_int (0);";
673}
674for (i = 0; i < n_target_array; i++) {
675	name= var_target_array[i]
676	size = var_target_array_size[i]
677	type = var_target_array_type[i]
678	print "  hstate.add_int (" size ");";
679	print "  hstate.add (ptr->" name ", sizeof (" type ") * " size ");";
680}
681for (i = 0; i < n_target_val; i++) {
682	name = var_target_val[i]
683	print "  hstate.add_hwi (ptr->" name");";
684}
685print "  return hstate.end ();";
686print "}";
687
688print "";
689print "/* Stream out target options  */";
690print "void";
691print "cl_target_option_stream_out (struct output_block *ob ATTRIBUTE_UNUSED,";
692print "                             struct bitpack_d *bp ATTRIBUTE_UNUSED,";
693print "                             struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
694print "{";
695for (i = 0; i < n_target_str; i++) {
696	name = var_target_str[i]
697	print "  bp_pack_string (ob, bp, ptr->" name", true);";
698}
699for (i = 0; i < n_target_array; i++) {
700	name = var_target_array[i]
701	size = var_target_array_size[i]
702	print "  for (unsigned i = 0; i < " size "; i++)"
703	print "    bp_pack_value (bp, ptr->" name "[i], 64);";
704}
705for (i = 0; i < n_target_val; i++) {
706	name = var_target_val[i]
707	print "  bp_pack_value (bp, ptr->" name", 64);";
708}
709print "}";
710
711print "";
712print "/* Stream in target options  */";
713print "void";
714print "cl_target_option_stream_in (struct data_in *data_in ATTRIBUTE_UNUSED,";
715print "                            struct bitpack_d *bp ATTRIBUTE_UNUSED,";
716print "                            struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
717print "{";
718for (i = 0; i < n_target_str; i++) {
719	name = var_target_str[i]
720	print "  ptr->" name" = bp_unpack_string (data_in, bp);";
721	print "  if (ptr->" name")";
722	print "    ptr->" name" = xstrdup (ptr->" name");";
723}
724for (i = 0; i < n_target_array; i++) {
725	name = var_target_array[i]
726	size = var_target_array_size[i]
727	print "  for (int i = " size " - 1; i >= 0; i--)"
728	print "    ptr->" name "[i] = (" var_target_array_type[i] ") bp_unpack_value (bp, 64);";
729}
730for (i = 0; i < n_target_val; i++) {
731	name = var_target_val[i]
732	print "  ptr->" name" = (" var_target_val_type[i] ") bp_unpack_value (bp, 64);";
733}
734
735print "}";
736
737n_opt_val = 4;
738var_opt_val[0] = "x_optimize"
739var_opt_val_type[0] = "char "
740var_opt_val[1] = "x_optimize_size"
741var_opt_val_type[1] = "char "
742var_opt_val[2] = "x_optimize_debug"
743var_opt_val_type[2] = "char "
744var_opt_val[3] = "x_optimize_fast"
745var_opt_val_type[3] = "char "
746for (i = 0; i < n_opts; i++) {
747	if (flag_set_p("(Optimization|PerFunction)", flags[i])) {
748		name = var_name(flags[i])
749		if(name == "")
750			continue;
751
752		if(name in var_opt_list_seen)
753			continue;
754
755		var_opt_list_seen[name]++;
756
757		otype = var_type_struct(flags[i])
758		var_opt_val_type[n_opt_val] = otype;
759		var_opt_val[n_opt_val++] = "x_" name;
760		var_opt_hash[n_opt_val] = flag_set_p("Optimization", flags[i]);
761	}
762}
763print "";
764print "/* Hash optimization options  */";
765print "hashval_t";
766print "cl_optimization_hash (struct cl_optimization const *ptr ATTRIBUTE_UNUSED)";
767print "{";
768print "  inchash::hash hstate;";
769for (i = 0; i < n_opt_val; i++) {
770	if (!var_opt_hash[i])
771		continue;
772	name = var_opt_val[i]
773	print "  hstate.add_hwi (ptr->" name");";
774}
775print "  return hstate.end ();";
776print "}";
777
778print "";
779print "/* Stream out optimization options  */";
780print "void";
781print "cl_optimization_stream_out (struct bitpack_d *bp,";
782print "                            struct cl_optimization *ptr)";
783print "{";
784for (i = 0; i < n_opt_val; i++) {
785	name = var_opt_val[i]
786	print "  bp_pack_value (bp, ptr->" name", 64);";
787}
788print "}";
789
790print "";
791print "/* Stream in optimization options  */";
792print "void";
793print "cl_optimization_stream_in (struct bitpack_d *bp,";
794print "                           struct cl_optimization *ptr)";
795print "{";
796for (i = 0; i < n_opt_val; i++) {
797	name = var_opt_val[i]
798	print "  ptr->" name" = (" var_opt_val_type[i] ") bp_unpack_value (bp, 64);";
799}
800print "}";
801}
802