[PATCH] Fix up LTO TARGET_OPTION_NODE handling on x86 (PR lto/64374)

Jakub Jelinek jakub@redhat.com
Tue Feb 24 19:48:00 GMT 2015


Hi!

As mentioned in the PR, the ix86_cmodel option is TargetSave,
but during option processing is adjusted from flag_pic, which is
for LTO a global option.
This causes a problem when some translation unit is compiled with LTO
without -fpic, and then the final link is done with -fpic - then
ix86_cmodel might be the non-_PIC CM_* even when flag_pic is on, which
greatly confuses the backend.

Fixed by adding a target hook to do such adjustments upon TARGET_OPTION_NODE
streaming in.

Unfortunately, for some reason I can't now really reproduce the ICE and the
testcase seems to be missing a function definition, but I've at least
verified it that without the patch there is inconsistent value of
ix86_cmodel while the patch fixes that.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2015-02-24  Jakub Jelinek  <jakub@redhat.com>

	PR lto/64374
	* target.def (target_option_stream_in): New target hook.
	* tree-streamer-in.c (streamer_read_tree_bitfields): Invoke
	targetm.target_option.post_stream_in if non-NULL.
	* doc/tm.texi.in: Add @hook TARGET_OPTION_POST_STREAM_IN.
	* doc/tm.texi: Updated.
	* config/i386/i386.c (ix86_function_specific_post_stream_in): New
	function.
	(TARGET_OPTION_POST_STREAM_IN): Redefine.

--- gcc/target.def.jj	2015-02-23 10:43:03.000000000 +0100
+++ gcc/target.def	2015-02-24 14:54:25.061494421 +0100
@@ -5501,6 +5501,15 @@ information in the @code{struct cl_targe
 function-specific options to the @code{struct gcc_options} structure.",
  void, (struct gcc_options *opts, struct cl_target_option *ptr), NULL)
 
+/* Function to update target-specific option information after being
+   streamed in.  */
+DEFHOOK
+(post_stream_in,
+ "This hook is called to update target-specific information in the\n\
+@code{struct cl_target_option} structure after it is streamed in from\n\
+LTO bytecode.",
+ void, (struct cl_target_option *ptr), NULL)
+
 /* Function to print any extra target state from the target options
    structure.  */
 DEFHOOK
--- gcc/tree-streamer-in.c.jj	2015-02-23 10:43:04.000000000 +0100
+++ gcc/tree-streamer-in.c	2015-02-24 15:40:14.470602155 +0100
@@ -559,7 +559,11 @@ streamer_read_tree_bitfields (struct lto
 
 #ifndef ACCEL_COMPILER
   if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
-    cl_target_option_stream_in (data_in, &bp, TREE_TARGET_OPTION (expr));
+    {
+      cl_target_option_stream_in (data_in, &bp, TREE_TARGET_OPTION (expr));
+      if (targetm.target_option.post_stream_in)
+	targetm.target_option.post_stream_in (TREE_TARGET_OPTION (expr));
+    }
 #endif
 
   if (code == OMP_CLAUSE)
--- gcc/doc/tm.texi.in.jj	2015-02-23 10:43:03.000000000 +0100
+++ gcc/doc/tm.texi.in	2015-02-24 15:19:14.919179569 +0100
@@ -7251,6 +7251,8 @@ on this implementation detail.
 
 @hook TARGET_OPTION_RESTORE
 
+@hook TARGET_OPTION_POST_STREAM_IN
+
 @hook TARGET_OPTION_PRINT
 
 @hook TARGET_OPTION_PRAGMA_PARSE
--- gcc/doc/tm.texi.jj	2015-02-23 10:43:03.000000000 +0100
+++ gcc/doc/tm.texi	2015-02-24 15:19:42.038736514 +0100
@@ -9905,6 +9905,12 @@ information in the @code{struct cl_targe
 function-specific options to the @code{struct gcc_options} structure.
 @end deftypefn
 
+@deftypefn {Target Hook} void TARGET_OPTION_POST_STREAM_IN (struct cl_target_option *@var{ptr})
+This hook is called to update target-specific information in the
+@code{struct cl_target_option} structure after it is streamed in from
+LTO bytecode.
+@end deftypefn
+
 @deftypefn {Target Hook} void TARGET_OPTION_PRINT (FILE *@var{file}, int @var{indent}, struct cl_target_option *@var{ptr})
 This hook is called to print any additional target-specific
 information in the @code{struct cl_target_option} structure for
--- gcc/config/i386/i386.c.jj	2015-02-23 10:43:04.000000000 +0100
+++ gcc/config/i386/i386.c	2015-02-24 15:18:18.495101374 +0100
@@ -2463,6 +2463,7 @@ static void ix86_function_specific_save
 					 struct gcc_options *opts);
 static void ix86_function_specific_restore (struct gcc_options *opts,
 					    struct cl_target_option *);
+static void ix86_function_specific_post_stream_in (struct cl_target_option *);
 static void ix86_function_specific_print (FILE *, int,
 					  struct cl_target_option *);
 static bool ix86_valid_target_attribute_p (tree, tree, tree, int);
@@ -4571,6 +4572,39 @@ ix86_function_specific_restore (struct g
     set_ix86_tune_features (ix86_tune, false);
 }
 
+/* Adjust target options after streaming them in.  This is mainly about
+   reconciling them with global options.  */
+
+static void
+ix86_function_specific_post_stream_in (struct cl_target_option *ptr)
+{
+  /* flag_pic is a global option, but ix86_cmodel is target saved option
+     partly computed from flag_pic.  If flag_pic is on, adjust x_ix86_cmodel
+     for PIC, or error out.  */
+  if (flag_pic)
+    switch (ptr->x_ix86_cmodel)
+      {
+      case CM_SMALL:
+	ptr->x_ix86_cmodel = CM_SMALL_PIC;
+	break;
+
+      case CM_MEDIUM:
+	ptr->x_ix86_cmodel = CM_MEDIUM_PIC;
+	break;
+
+      case CM_LARGE:
+	ptr->x_ix86_cmodel = CM_LARGE_PIC;
+	break;
+
+      case CM_KERNEL:
+	error ("code model %s does not support PIC mode", "kernel");
+	break;
+
+      default:
+	break;
+      }
+}
+
 /* Print the current options */
 
 static void
@@ -52007,6 +52041,9 @@ ix86_initialize_bounds (tree var, tree l
 #undef TARGET_OPTION_RESTORE
 #define TARGET_OPTION_RESTORE ix86_function_specific_restore
 
+#undef TARGET_OPTION_POST_STREAM_IN
+#define TARGET_OPTION_POST_STREAM_IN ix86_function_specific_post_stream_in
+
 #undef TARGET_OPTION_PRINT
 #define TARGET_OPTION_PRINT ix86_function_specific_print
 

	Jakub



More information about the Gcc-patches mailing list