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