diff mbox

Rerog streaming of OPTIMIZATION_NODE

Message ID 20141115165720.GG31795@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Nov. 15, 2014, 4:57 p.m. UTC
Hi,
this patch implements OPTIMIZATION_NODE streaming same was as previous patch
did for TARGET_OPTION_NODE. Since the code turned out to be completely
analogous to the previous one I will go ahead and commit it as obvious.
It will help to make followup changes easier to follow.

I also tested this with forcing default optimization node on every function
with LTO.  It seems to just work, modulo inliner ignoring most of the flags and
happily dragging code from one set of optimization options to another.

Bootstrapped/regtested ppc64-linux and x86_64-linux, tested with Firefox, Comitted.

Honza

	* lto-streamer-out.c (hash_tree): Use cl_optimization_hash.
	* lto-streamer.h (cl_optimization_stream_out, cl_optimization_stream_in): Declare.
	* optc-save-gen.awk: Generate cl_optimization LTO streaming and hashing routines.
	* opth-gen.awk: Add prototype of cl_optimization_hash.
	* tree-streamer-in.c (unpack_ts_optimization): Remove.
	(streamer_unpack_tree_bitfields): Use cl_optimization_stream_in.
	* tree-streamer-out.c (pack_ts_optimization): Remove.
	(streamer_pack_tree_bitfields): Use cl_optimization_stream_out.

Comments

Jan-Benedict Glaw Nov. 15, 2014, 8:45 p.m. UTC | #1
On Sat, 2014-11-15 17:57:20 +0100, Jan Hubicka <hubicka@ucw.cz> wrote:
> Hi,
> this patch implements OPTIMIZATION_NODE streaming same was as previous patch
> did for TARGET_OPTION_NODE. Since the code turned out to be completely
> analogous to the previous one I will go ahead and commit it as obvious.
> It will help to make followup changes easier to follow.
> 
> I also tested this with forcing default optimization node on every function
> with LTO.  It seems to just work, modulo inliner ignoring most of the flags and
> happily dragging code from one set of optimization options to another.
> 
> Bootstrapped/regtested ppc64-linux and x86_64-linux, tested with Firefox, Comitted.
> 
> Honza
> 
> 	* lto-streamer-out.c (hash_tree): Use cl_optimization_hash.
> 	* lto-streamer.h (cl_optimization_stream_out, cl_optimization_stream_in): Declare.
> 	* optc-save-gen.awk: Generate cl_optimization LTO streaming and hashing routines.
> 	* opth-gen.awk: Add prototype of cl_optimization_hash.
> 	* tree-streamer-in.c (unpack_ts_optimization): Remove.
> 	(streamer_unpack_tree_bitfields): Use cl_optimization_stream_in.
> 	* tree-streamer-out.c (pack_ts_optimization): Remove.
> 	(streamer_pack_tree_bitfields): Use cl_optimization_stream_out.

The recent work, I'm not exactly sure if it's actually /this/ commit,
broke nios2-rtems, see eg. build
http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=376303

g++ -c   -g -O2 -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE  -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common  -DHAVE_CONFIG_H -I. -I. -I/home/jbglaw/repos/gcc/gcc -I/home/jbglaw/repos/gcc/gcc/. -I/home/jbglaw/repos/gcc/gcc/../include -I/home/jbglaw/repos/gcc/gcc/../libcpp/include  -I/home/jbglaw/repos/gcc/gcc/../libdecnumber -I/home/jbglaw/repos/gcc/gcc/../libdecnumber/dpd -I../libdecnumber -I/home/jbglaw/repos/gcc/gcc/../libbacktrace    -o optabs.o -MT optabs.o -MMD -MP -MF ./.deps/optabs.TPo /home/jbglaw/repos/gcc/gcc/optabs.c
gawk -f /home/jbglaw/repos/gcc/gcc/opt-functions.awk -f /home/jbglaw/repos/gcc/gcc/opt-read.awk \
       -f /home/jbglaw/repos/gcc/gcc/optc-save-gen.awk \
       -v header_name="config.h system.h coretypes.h tm.h" < optionlist > options-save.c
g++ -c   -g -O2 -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE  -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common  -DHAVE_CONFIG_H -I. -I. -I/home/jbglaw/repos/gcc/gcc -I/home/jbglaw/repos/gcc/gcc/. -I/home/jbglaw/repos/gcc/gcc/../include -I/home/jbglaw/repos/gcc/gcc/../libcpp/include  -I/home/jbglaw/repos/gcc/gcc/../libdecnumber -I/home/jbglaw/repos/gcc/gcc/../libdecnumber/dpd -I../libdecnumber -I/home/jbglaw/repos/gcc/gcc/../libbacktrace    -o options-save.o -MT options-save.o -MMD -MP -MF ./.deps/options-save.TPo options-save.c
options-save.c: In function ‘void cl_target_option_stream_in(data_in*, bitpack_d*, cl_target_option*)’:
options-save.c:1901:41: error: expected primary-expression before ‘enum’
   ptr->saved_custom_code_status[256] = (enum nios2_ccs_code saved_custom_code_status[256]) bp_unpack_value (bp, 64);
                                         ^
options-save.c:1901:41: error: expected ‘)’ before ‘enum’
options-save.c:1902:40: error: expected primary-expression before ‘int’
   ptr->saved_custom_code_index[256] = (int saved_custom_code_index[256]) bp_unpack_value (bp, 64);
                                        ^
options-save.c:1902:40: error: expected ‘)’ before ‘int’
options-save.c:1903:49: error: expected primary-expression before ‘int’
   ptr->saved_fpu_custom_code[n2fpu_code_num] = (int saved_fpu_custom_code[n2fpu_code_num]) bp_unpack_value (bp, 64);
                                                 ^
options-save.c:1903:49: error: expected ‘)’ before ‘int’
make[1]: *** [options-save.o] Error 1


(I just bisected it just now, it's this commit:

2014-11-14  Jan Hubicka  <hubicka@ucw.cz>

	* optc-save-gen.awk: Output cl_target_option_eq,
	cl_target_option_hash, cl_target_option_stream_out,
	cl_target_option_stream_in functions.
	* opth-gen.awk: Output prototypes for
	cl_target_option_eq and cl_target_option_hash.
	* lto-streamer.h (cl_target_option_stream_out,
	cl_target_option_stream_in): Declare.
	* tree.c (cl_option_hash_hash): Use cl_target_option_hash.
	(cl_option_hash_eq): Use cl_target_option_eq.
	* tree-streamer-in.c (unpack_value_fields): Stream in
	TREE_TARGET_OPTION.
	* lto-streamer-out.c (DFS::DFS_write_tree_body): Follow
	DECL_FUNCTION_SPECIFIC_TARGET.
	(hash_tree): Hash TREE_TARGET_OPTION; visit
	DECL_FUNCTION_SPECIFIC_TARGET.
	* tree-streamer-out.c (streamer_pack_tree_bitfields): Skip
	TS_TARGET_OPTION.
	(streamer_write_tree_body): Output TS_TARGET_OPTION.
)

MfG, JBG
Jan Hubicka Nov. 15, 2014, 9:56 p.m. UTC | #2
> 
> The recent work, I'm not exactly sure if it's actually /this/ commit,
> broke nios2-rtems, see eg. build
> http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=376303
> 
> g++ -c   -g -O2 -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE  -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common  -DHAVE_CONFIG_H -I. -I. -I/home/jbglaw/repos/gcc/gcc -I/home/jbglaw/repos/gcc/gcc/. -I/home/jbglaw/repos/gcc/gcc/../include -I/home/jbglaw/repos/gcc/gcc/../libcpp/include  -I/home/jbglaw/repos/gcc/gcc/../libdecnumber -I/home/jbglaw/repos/gcc/gcc/../libdecnumber/dpd -I../libdecnumber -I/home/jbglaw/repos/gcc/gcc/../libbacktrace    -o optabs.o -MT optabs.o -MMD -MP -MF ./.deps/optabs.TPo /home/jbglaw/repos/gcc/gcc/optabs.c
> gawk -f /home/jbglaw/repos/gcc/gcc/opt-functions.awk -f /home/jbglaw/repos/gcc/gcc/opt-read.awk \
>        -f /home/jbglaw/repos/gcc/gcc/optc-save-gen.awk \
>        -v header_name="config.h system.h coretypes.h tm.h" < optionlist > options-save.c
> g++ -c   -g -O2 -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE  -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common  -DHAVE_CONFIG_H -I. -I. -I/home/jbglaw/repos/gcc/gcc -I/home/jbglaw/repos/gcc/gcc/. -I/home/jbglaw/repos/gcc/gcc/../include -I/home/jbglaw/repos/gcc/gcc/../libcpp/include  -I/home/jbglaw/repos/gcc/gcc/../libdecnumber -I/home/jbglaw/repos/gcc/gcc/../libdecnumber/dpd -I../libdecnumber -I/home/jbglaw/repos/gcc/gcc/../libbacktrace    -o options-save.o -MT options-save.o -MMD -MP -MF ./.deps/options-save.TPo options-save.c
> options-save.c: In function ‘void cl_target_option_stream_in(data_in*, bitpack_d*, cl_target_option*)’:
> options-save.c:1901:41: error: expected primary-expression before ‘enum’
>    ptr->saved_custom_code_status[256] = (enum nios2_ccs_code saved_custom_code_status[256]) bp_unpack_value (bp, 64);
>                                          ^
> options-save.c:1901:41: error: expected ‘)’ before ‘enum’
> options-save.c:1902:40: error: expected primary-expression before ‘int’
>    ptr->saved_custom_code_index[256] = (int saved_custom_code_index[256]) bp_unpack_value (bp, 64);
>                                         ^
> options-save.c:1902:40: error: expected ‘)’ before ‘int’
> options-save.c:1903:49: error: expected primary-expression before ‘int’
>    ptr->saved_fpu_custom_code[n2fpu_code_num] = (int saved_fpu_custom_code[n2fpu_code_num]) bp_unpack_value (bp, 64);
>                                                  ^
> options-save.c:1903:49: error: expected ‘)’ before ‘int’
> make[1]: *** [options-save.o] Error 1

Yep, it is because my code does not handle streaming of arrays into the target optimization nodes.
I will take a look on why that array is really needed. It seems like a overkill?

Honza
> 
> 
> (I just bisected it just now, it's this commit:
> 
> 2014-11-14  Jan Hubicka  <hubicka@ucw.cz>
> 
> 	* optc-save-gen.awk: Output cl_target_option_eq,
> 	cl_target_option_hash, cl_target_option_stream_out,
> 	cl_target_option_stream_in functions.
> 	* opth-gen.awk: Output prototypes for
> 	cl_target_option_eq and cl_target_option_hash.
> 	* lto-streamer.h (cl_target_option_stream_out,
> 	cl_target_option_stream_in): Declare.
> 	* tree.c (cl_option_hash_hash): Use cl_target_option_hash.
> 	(cl_option_hash_eq): Use cl_target_option_eq.
> 	* tree-streamer-in.c (unpack_value_fields): Stream in
> 	TREE_TARGET_OPTION.
> 	* lto-streamer-out.c (DFS::DFS_write_tree_body): Follow
> 	DECL_FUNCTION_SPECIFIC_TARGET.
> 	(hash_tree): Hash TREE_TARGET_OPTION; visit
> 	DECL_FUNCTION_SPECIFIC_TARGET.
> 	* tree-streamer-out.c (streamer_pack_tree_bitfields): Skip
> 	TS_TARGET_OPTION.
> 	(streamer_write_tree_body): Output TS_TARGET_OPTION.
> )
> 
> MfG, JBG
> 
> -- 
>       Jan-Benedict Glaw      jbglaw@lug-owl.de              +49-172-7608481
>  Signature of:                      http://perl.plover.com/Questions.html
>  the second  :
Jan Hubicka Nov. 15, 2014, 11:36 p.m. UTC | #3
Jonah,
> Yep, it is because my code does not handle streaming of arrays into the target optimization nodes.
> I will take a look on why that array is really needed. It seems like a overkill?

I am looking into the nios2_register_custom_code and I do not quite understand
what it is good for?  If it tracks customs codes function wide, then perhaps
target part of cfun would be better place to home it.  It it is unit wide, then
saving/restoring does not seem to make much sense.

Can you, please, explain me why this needs to be stored into target option
structure?  If this is really needed, then we can always add a support for
streaming arrays, but I would preffer keeping that structure small and simple
;)

Honza
Jan-Benedict Glaw Nov. 15, 2014, 11:49 p.m. UTC | #4
Hi,

On Sun, 2014-11-16 00:36:27 +0100, Jan Hubicka <hubicka@ucw.cz> wrote:
> > Yep, it is because my code does not handle streaming of arrays
> > into the target optimization nodes.  I will take a look on why
> > that array is really needed. It seems like a overkill?
> 
> I am looking into the nios2_register_custom_code and I do not quite
> understand what it is good for?  If it tracks customs codes function
> wide, then perhaps target part of cfun would be better place to home
> it.  It it is unit wide, then saving/restoring does not seem to make
> much sense.
> 
> Can you, please, explain me why this needs to be stored into target
> option structure?  If this is really needed, then we can always add
> a support for streaming arrays, but I would preffer keeping that
> structure small and simple ;)

Port maintainers Cc'ed.

MfG, JBG
Sandra Loosemore Nov. 16, 2014, 1:46 a.m. UTC | #5
On 11/15/2014 04:49 PM, Jan-Benedict Glaw wrote:
> Hi,
>
> On Sun, 2014-11-16 00:36:27 +0100, Jan Hubicka <hubicka@ucw.cz> wrote:
>>> Yep, it is because my code does not handle streaming of arrays
>>> into the target optimization nodes.  I will take a look on why
>>> that array is really needed. It seems like a overkill?
>>
>> I am looking into the nios2_register_custom_code and I do not quite
>> understand what it is good for?  If it tracks customs codes function
>> wide, then perhaps target part of cfun would be better place to home
>> it.  It it is unit wide, then saving/restoring does not seem to make
>> much sense.
>>
>> Can you, please, explain me why this needs to be stored into target
>> option structure?  If this is really needed, then we can always add
>> a support for streaming arrays, but I would preffer keeping that
>> structure small and simple ;)
>
> Port maintainers Cc'ed.

I can explain why this is needed, at least.

The Nios II architecture optionally allows "custom instructions" that 
are typically used to implement floating-point operations.  The nios2 
GCC backend knows to generate these instructions if the user tells it 
what opcodes implement these instructions.  This is typically done by 
command-line options, but can also be done on a per-function basis by 
means of target attributes or pragmas -- see 
gcc/testsuite/gcc.target/nios2/custom-fp-* for examples.  The 
command-line options, attribute, and pragma support was a requirement 
from Altera, so yes, this is really needed.

-Sandra
Sandra Loosemore Nov. 19, 2014, 11:03 p.m. UTC | #6
On 11/15/2014 06:46 PM, Sandra Loosemore wrote:
> On 11/15/2014 04:49 PM, Jan-Benedict Glaw wrote:
>> Hi,
>>
>> On Sun, 2014-11-16 00:36:27 +0100, Jan Hubicka <hubicka@ucw.cz> wrote:
>>>> Yep, it is because my code does not handle streaming of arrays
>>>> into the target optimization nodes.  I will take a look on why
>>>> that array is really needed. It seems like a overkill?
>>>
>>> I am looking into the nios2_register_custom_code and I do not quite
>>> understand what it is good for?  If it tracks customs codes function
>>> wide, then perhaps target part of cfun would be better place to home
>>> it.  It it is unit wide, then saving/restoring does not seem to make
>>> much sense.
>>>
>>> Can you, please, explain me why this needs to be stored into target
>>> option structure?  If this is really needed, then we can always add
>>> a support for streaming arrays, but I would preffer keeping that
>>> structure small and simple ;)
>>
>> Port maintainers Cc'ed.
>
> I can explain why this is needed, at least.
>
> The Nios II architecture optionally allows "custom instructions" that
> are typically used to implement floating-point operations.  The nios2
> GCC backend knows to generate these instructions if the user tells it
> what opcodes implement these instructions.  This is typically done by
> command-line options, but can also be done on a per-function basis by
> means of target attributes or pragmas -- see
> gcc/testsuite/gcc.target/nios2/custom-fp-* for examples.  The
> command-line options, attribute, and pragma support was a requirement
> from Altera, so yes, this is really needed.

Ping.  Do we have any strategy or timeline for fixing this yet?  At the 
very least, if it is determined to impose a new restriction against 
using arrays in the saved option state, there must be a patch to clearly 
document what is permissible.  Otherwise I think the generic code must 
be fixed to support what the nios2 back end is already doing and which 
previously worked per the existing documentation.

-Sandra
Jan Hubicka Nov. 20, 2014, 4:34 a.m. UTC | #7
Sandra,
> >
> >I can explain why this is needed, at least.
> >
> >The Nios II architecture optionally allows "custom instructions" that
> >are typically used to implement floating-point operations.  The nios2
> >GCC backend knows to generate these instructions if the user tells it
> >what opcodes implement these instructions.  This is typically done by
> >command-line options, but can also be done on a per-function basis by
> >means of target attributes or pragmas -- see
> >gcc/testsuite/gcc.target/nios2/custom-fp-* for examples.  The
> >command-line options, attribute, and pragma support was a requirement
> >from Altera, so yes, this is really needed.
> 
> Ping.  Do we have any strategy or timeline for fixing this yet?  At
> the very least, if it is determined to impose a new restriction
> against using arrays in the saved option state, there must be a
> patch to clearly document what is permissible.  Otherwise I think
> the generic code must be fixed to support what the nios2 back end is
> already doing and which previously worked per the existing
> documentation.

I see three possible fixes:
 1) extend the AWk script to recognize arrays and stream them specially
    (it already recognizes string so it is not hard to do, just bit wasteful)
 2) add attribute to .opt file allowing user to specify his own
    compare/hash/stream-in/stream-out functions
 3) avoid using arrays in the backend.  I think it is doable - the target
    structure contains string representation of the arrays
    (nios2_custom_fpu_cfg_string) and therefore saved_custom_code_status/
    saved_custom_code_index does not really need to hit the LTO stream
    at all. Question is where to place them and I think target specific
    part of cfun is probably resonable choice.

As for AWk-fu, 2 is probably easier than 1, but both are not hard - one just
need to follow what is already done for strings and introduce third type of
variable.

Unless someone beats me, I will probably go for 1 since I am not very familiar
with the backend and array support may come handy in future.

As for timeline, I have a workshop next week and need to prepare draft for it.
So ideally I would like to work on this only after the workshop (ending
November 28). I would be also happy to help anyone interested to help (I am
just bit slow on portable AWK hacking).

Honza
> 
> -Sandra
Sandra Loosemore Nov. 20, 2014, 6 a.m. UTC | #8
On 11/19/2014 09:34 PM, Jan Hubicka wrote:
> [snip]
> I see three possible fixes:
>   1) extend the AWk script to recognize arrays and stream them specially
>      (it already recognizes string so it is not hard to do, just bit wasteful)
>   2) add attribute to .opt file allowing user to specify his own
>      compare/hash/stream-in/stream-out functions
>   3) avoid using arrays in the backend.  I think it is doable - the target
>      structure contains string representation of the arrays
>      (nios2_custom_fpu_cfg_string) and therefore saved_custom_code_status/
>      saved_custom_code_index does not really need to hit the LTO stream
>      at all. Question is where to place them and I think target specific
>      part of cfun is probably resonable choice.

Just to clarify here, nios2_custom_fpu_cfg_string doesn't hold the 
complete state information.  That option is used to specify some sets of 
predefined custom instructions that can be augmented with various 
-mcustom-foo= options for individual instructions foo (or you can just 
use the -mcustom-foo= options).  The arrays are used to hold the 
combined state of all these different options for error-checking and 
lookup purposes.  I think it is true that we could rewrite this code to 
reconstruct the arrays from the original options, but it's not something 
I'd really want to undertake if the generic streaming code can be fixed 
instead.

> As for AWk-fu, 2 is probably easier than 1, but both are not hard - one just
> need to follow what is already done for strings and introduce third type of
> variable.
>
> Unless someone beats me, I will probably go for 1 since I am not very familiar
> with the backend and array support may come handy in future.
>
> As for timeline, I have a workshop next week and need to prepare draft for it.
> So ideally I would like to work on this only after the workshop (ending
> November 28). I would be also happy to help anyone interested to help (I am
> just bit slow on portable AWK hacking).

OK.  I'm not so worried about getting this fixed by a certain date as 
about having a plan for fixing it.

-Sandra
Sandra Loosemore Dec. 19, 2014, 4:10 a.m. UTC | #9
On 11/19/2014 09:34 PM, Jan Hubicka wrote:
> [snip]
>
> As for timeline, I have a workshop next week and need to prepare draft for it.
> So ideally I would like to work on this only after the workshop (ending
> November 28). I would be also happy to help anyone interested to help (I am
> just bit slow on portable AWK hacking).

Has there been any progress on getting this fixed?  It's been over a 
month since this was reported and I see nios2-elf builds are still 
broken.  It's blocking me testing a fix for PR59710, among other things.

-Sandra
diff mbox

Patch

Index: lto-streamer-out.c
===================================================================
--- lto-streamer-out.c	(revision 217572)
+++ lto-streamer-out.c	(working copy)
@@ -948,7 +948,7 @@ 
     hstate.add_wide_int (cl_target_option_hash (TREE_TARGET_OPTION (t)));
 
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
-    hstate.add (t, sizeof (struct cl_optimization));
+    hstate.add_wide_int (cl_optimization_hash (TREE_OPTIMIZATION (t)));
 
   if (CODE_CONTAINS_STRUCT (code, TS_IDENTIFIER))
     hstate.merge_hash (IDENTIFIER_HASH_VALUE (t));
Index: lto-streamer.h
===================================================================
--- lto-streamer.h	(revision 217572)
+++ lto-streamer.h	(working copy)
@@ -844,7 +844,11 @@ 
 				 struct bitpack_d *,
 				 struct cl_target_option *);
 
+void cl_optimization_stream_out (struct bitpack_d *, struct cl_optimization *);
 
+void cl_optimization_stream_in (struct bitpack_d *, struct cl_optimization *);
+
+
 /* In lto-symtab.c.  */
 extern void lto_symtab_merge_decls (void);
 extern void lto_symtab_merge_symbols (void);
Index: optc-save-gen.awk
===================================================================
--- optc-save-gen.awk	(revision 217571)
+++ optc-save-gen.awk	(working copy)
@@ -551,4 +551,61 @@ 
 
 print "}";
 
+n_opt_val = 2;
+var_opt_val[0] = "x_optimize"
+var_opt_val_type[0] = "char "
+var_opt_val[1] = "x_optimize_size"
+var_opt_val_type[1] = "char "
+for (i = 0; i < n_opts; i++) {
+	if (flag_set_p("Optimization", flags[i])) {
+		name = var_name(flags[i])
+		if(name == "")
+			continue;
+
+		if(name in var_opt_list_seen)
+			continue;
+
+		var_opt_list_seen[name]++;
+
+		otype = var_type_struct(flags[i])
+		var_opt_val_type[n_opt_val] = otype;
+		var_opt_val[n_opt_val++] = "x_" name;
+	}
 }
+print "";
+print "/* Hash optimization options  */";
+print "hashval_t";
+print "cl_optimization_hash (struct cl_optimization const *ptr ATTRIBUTE_UNUSED)";
+print "{";
+print "  inchash::hash hstate;";
+for (i = 0; i < n_opt_val; i++) {
+	name = var_opt_val[i]
+	print "  hstate.add_wide_int (ptr->" name");";
+}
+print "  return hstate.end ();";
+print "}";
+
+print "";
+print "/* Stream out optimization options  */";
+print "void";
+print "cl_optimization_stream_out (struct bitpack_d *bp,";
+print "                            struct cl_optimization *ptr)";
+print "{";
+for (i = 0; i < n_opt_val; i++) {
+	name = var_opt_val[i]
+	print "  bp_pack_value (bp, ptr->" name", 64);";
+}
+print "}";
+
+print "";
+print "/* Stream in optimization options  */";
+print "void";
+print "cl_optimization_stream_in (struct bitpack_d *bp,";
+print "                           struct cl_optimization *ptr)";
+print "{";
+for (i = 0; i < n_opt_val; i++) {
+	name = var_opt_val[i]
+	print "  ptr->" name" = (" var_opt_val_type[i] ") bp_unpack_value (bp, 64);";
+}
+print "}";
+}
Index: opth-gen.awk
===================================================================
--- opth-gen.awk	(revision 217571)
+++ opth-gen.awk	(working copy)
@@ -299,6 +299,9 @@ 
 print "/* Hash option variables from a structure.  */";
 print "extern hashval_t cl_target_option_hash (const struct cl_target_option *);";
 print "";
+print "/* Hash optimization from a structure.  */";
+print "extern hashval_t cl_optimization_hash (const struct cl_optimization *);";
+print "";
 print "/* Anything that includes tm.h, does not necessarily need this.  */"
 print "#if !defined(GCC_TM_H)"
 print "#include \"input.h\" /* for location_t */"
Index: tree-streamer-in.c
===================================================================
--- tree-streamer-in.c	(revision 217571)
+++ tree-streamer-in.c	(working copy)
@@ -399,22 +399,7 @@ 
   vec_safe_push (all_translation_units, expr);
 }
 
-/* Unpack a TS_OPTIMIZATION tree from BP into EXPR.  */
 
-static void
-unpack_ts_optimization (struct bitpack_d *bp, tree expr)
-{
-  unsigned i, len;
-  struct cl_optimization *t = TREE_OPTIMIZATION (expr);
-
-  len = sizeof (struct cl_optimization);
-  for (i = 0; i < len; i++)
-    ((unsigned char *)t)[i] = bp_unpack_value (bp, 8);
-  if (bp_unpack_value (bp, 32) != 0x12345678)
-    fatal_error ("cl_optimization size mismatch in LTO reader and writer");
-}
-
-
 /* Unpack all the non-pointer fields of the TS_OMP_CLAUSE
    structure of expression EXPR from bitpack BP.  */
 
@@ -507,7 +492,7 @@ 
     unpack_ts_translation_unit_decl_value_fields (data_in, bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
-    unpack_ts_optimization (bp, expr);
+    cl_optimization_stream_in (bp, TREE_OPTIMIZATION (expr));
 
   if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
     {
Index: tree-streamer-out.c
===================================================================
--- tree-streamer-out.c	(revision 217571)
+++ tree-streamer-out.c	(working copy)
@@ -363,25 +363,7 @@ 
   bp_pack_string (ob, bp, TRANSLATION_UNIT_LANGUAGE (expr), true);
 }
 
-/* Pack a TS_OPTIMIZATION tree in EXPR to BP.  */
 
-static void
-pack_ts_optimization (struct bitpack_d *bp, tree expr)
-{
-  struct cl_optimization *t = TREE_OPTIMIZATION (expr);
-  unsigned i, len;
-
-  /* The cl_optimization is generated by the options
-     awk script, so we just recreate a byte-by-byte copy here. */
-
-  len = sizeof (struct cl_optimization);
-  for (i = 0; i < len; i++)
-    bp_pack_value (bp, ((unsigned char *)t)[i], 8);
-  /* Catch struct size mismatches between reader and writer. */
-  bp_pack_value (bp, 0x12345678, 32);
-}
-
-
 /* Pack all the non-pointer fields of the TS_OMP_CLAUSE structure
    of expression EXPR into bitpack BP.  */
 
@@ -473,7 +455,7 @@ 
     pack_ts_translation_unit_decl_value_fields (ob, bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
-    pack_ts_optimization (bp, expr);
+    cl_optimization_stream_out (bp, TREE_OPTIMIZATION (expr));
 
   if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
     bp_pack_var_len_unsigned (bp, vec_safe_length (BINFO_BASE_ACCESSES (expr)));