public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* LTO streaming of TARGET_OPTIMIZE_NODE
@ 2014-11-13  5:10 Jan Hubicka
  2014-11-13 10:58 ` Richard Biener
  2014-11-20 13:09 ` LTO streaming of TARGET_OPTIMIZE_NODE Bernd Schmidt
  0 siblings, 2 replies; 19+ messages in thread
From: Jan Hubicka @ 2014-11-13  5:10 UTC (permalink / raw)
  To: gcc-patches, rguenther, neil, joseph

Hi,
this patch adds infrastructure for proper streaming and merging of
TREE_TARGET_OPTION.  The catch is that TREE_TARGET_OPTION is autogenerated
structure.  For x86_64 it looks as follows:

/* Structure to save/restore selected target specific options.  */
struct GTY(()) cl_target_option
{
  HOST_WIDE_INT x_ix86_isa_flags_explicit;
  HOST_WIDE_INT x_ix86_target_flags_explicit;
  const char *x_ix86_arch_string;
  const char *x_ix86_recip_name;
  const char *x_ix86_tune_ctrl_string;
  const char *x_ix86_tune_memcpy_strategy;
  const char *x_ix86_tune_memset_strategy;
  const char *x_ix86_tune_string;
  HOST_WIDE_INT x_ix86_isa_flags;
  enum fpmath_unit x_ix86_fpmath;
  enum asm_dialect x_ix86_asm_dialect;
  ...
  enum stack_protector_guard x_ix86_stack_protector_guard;
  enum stringop_alg x_ix86_stringop_alg;
  enum tls_dialect x_ix86_tls_dialect;
  int x_ix86_branch_cost;
  int x_ix86_dump_tunes;
  ....
  int x_recip_mask;
  int x_target_flags;
  unsigned char arch;
  unsigned char arch_specified;
  unsigned char branch_cost;
  unsigned char schedule;
  unsigned char tune;
  unsigned char tune_defaulted;
};

The problem is that the strings prevents us from streaming the structure as a binary
blob like we do for optimization nodes (and we should not do that to make LTO streaming
stable across attribute tweaks in minor releases).

This patch extends the AWK generators to produce four functions:

/* Compare two target options  */
bool
cl_target_option_eq (struct cl_target_option const *ptr1,
                     struct cl_target_option const *ptr2)
{
  if (ptr1->x_ix86_arch_string != ptr2->x_ix86_arch_string
      && (!ptr1->x_ix86_arch_string || !ptr2->x_ix86_arch_string
          || strcmp (ptr1->x_ix86_arch_string, ptr2->x_ix86_arch_string)))
    return false;
....
    if (ptr1->x_ix86_isa_flags != ptr2->x_ix86_isa_flags)
    return false;
  if (ptr1->x_ix86_fpmath != ptr2->x_ix86_fpmath)
    return false;
  return true;
}

/* Hash target options  */
hashval_t
cl_target_option_hash (struct cl_target_option const *ptr)
{ 
  inchash::hash hstate;
  if (ptr->x_ix86_arch_string)
    hstate.add (ptr->x_ix86_arch_string, strlen (ptr->x_ix86_arch_string));
  else
    hstate.add_int (0);
...
  hstate.add_wide_int (ptr->x_ix86_fpmath);
  return hstate.end ();
}

/* Stream out target options  */
void
cl_target_option_stream_out (struct output_block *ob, struct cl_target_option *ptr)
{ 
  streamer_write_string (ob, ob->main_stream, ptr->x_ix86_arch_string, true);
...
  streamer_write_uhwi (ob, ptr->x_ix86_isa_flags);
  streamer_write_uhwi (ob, ptr->x_ix86_fpmath);
}

/* Stream in target options  */
void
cl_target_option_stream_in (struct lto_input_block *ib, struct data_in *data_in, struct cl_target_option *ptr)
{ 
  ptr->x_ix86_arch_string = strdup (streamer_read_string (data_in, ib));
...
  ptr->x_ix86_fpmath = (enum fpmath_unit ) streamer_read_uhwi (ib);
}

These allows us to properly stream, compare and hash the values.

There is some implementation lazyness - for example I stream all scalars as
unsigned HOST_WIDE_INT that seems to be the largest type used for variables
across the targets.

If other types are used, the type matching (I stole from other part of the awk
scripts) will need to be extended; for now it knows that const char * is a
string and needs special care but nothing else.

I have tested this with firefox and additional change to tree.c to always
initialize TARGET_OPTION_NODE for defined functions (so target units are
peorperly presered across units). This seems to work as intended - i.e. the
functions gets link-time optimized according to -march settings passed at
compile time.

I noticed that memory use is now 3.8GB instead of previous 2.8GB - this may be
tree merging problem caused by mismatching target settings but most probably it
is an unrelated stuff. I will look into it tomorrow.  I also plan to test this
on PPC (that currently fails to bootstrap).

Incrementally I would like to handle optimizations nodes same way and change
streaming format to be a set of assignments field_name=value.
This way we could behave sanely when some field is introduced or removed by
either defaulting it or ignoring it.

Bootstrapped/regtested x86_64-linux, seems sane?

	* 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.

	* lto.c (compare_tree_sccs_1): Compare cl_target_option_eq.
	
Index: optc-save-gen.awk
===================================================================
--- optc-save-gen.awk	(revision 217448)
+++ optc-save-gen.awk	(working copy)
@@ -39,6 +39,16 @@ print "#include " quote "intl.h" quote
 print ""
 print "#include " quote "flags.h" quote
 print "#include " quote "target.h" quote
+print "#include " quote "inchash.h" quote
+print "#include " quote "tree.h" quote
+print "#include " quote "tree-ssa-alias.h" quote
+print "#include " quote "is-a.h" quote
+print "#include " quote "predict.h" quote
+print "#include " quote "function.h" quote
+print "#include " quote "basic-block.h" quote
+print "#include " quote "gimple-expr.h" quote
+print "#include " quote "gimple.h" quote
+print "#include " quote "data-streamer.h" quote
 print ""
 
 if (n_extra_c_includes > 0) {
@@ -417,4 +427,120 @@ print "    targetm.target_option.print (
 
 print "}";
 
+print "";
+print "/* Compare two target options  */";
+print "bool";
+print "cl_target_option_eq (struct cl_target_option const *ptr1,";
+print "                     struct cl_target_option const *ptr2)";
+print "{";
+n_target_val = 0;
+n_target_str = 0;
+
+for (i = 0; i < n_target_save; i++) {
+	var = target_save_decl[i];
+	sub (" *=.*", "", var);
+	name = var;
+	type = var;
+	sub("^.*[ *]", "", name)
+	sub(" *" name "$", "", type)
+	if (target_save_decl[i] ~ "^const char \\*+[_" alnum "]+$")
+		var_target_str[n_target_str++] = name;
+	else {
+		var_target_val_type[n_target_val] = type;
+		var_target_val[n_target_val++] = name;
+	}
+}
+if (have_save) {
+	for (i = 0; i < n_opts; i++) {
+		if (flag_set_p("Save", flags[i])) {
+			name = var_name(flags[i])
+			if(name == "")
+				name = "target_flags";
+
+			if(name in var_list_seen)
+				continue;
+
+			var_list_seen[name]++;
+			otype = var_type_struct(flags[i])
+			if (otype ~ "^const char \\**$")
+				var_target_str[n_target_str++] = "x_" name;
+			else {
+				var_target_val_type[n_target_val] = otype;
+				var_target_val[n_target_val++] = "x_" name;
+			}
+		}
+	}
+} else {
+	var_target_val_type[n_target_val] = "int";
+	var_target_val[n_target_val++] = "x_target_flags";
+}
+
+for (i = 0; i < n_target_str; i++) {
+	name = var_target_str[i]
+	print "  if (ptr1->" name" != ptr2->" name;
+	print "      && (!ptr1->" name" || !ptr2->" name
+	print "          || strcmp (ptr1->" name", ptr2->" name ")))";
+	print "    return false;";
+}
+for (i = 0; i < n_target_val; i++) {
+	name = var_target_val[i]
+	print "  if (ptr1->" name" != ptr2->" name ")";
+	print "    return false;";
+}
+
+print "  return true;";
+
+print "}";
+
+print "";
+print "/* Hash target options  */";
+print "hashval_t";
+print "cl_target_option_hash (struct cl_target_option const *ptr)";
+print "{";
+print "  inchash::hash hstate;";
+for (i = 0; i < n_target_str; i++) {
+	name = var_target_str[i]
+	print "  if (ptr->" name")";
+	print "    hstate.add (ptr->" name", strlen (ptr->" name"));";
+	print "  else";
+	print "    hstate.add_int (0);";
+}
+for (i = 0; i < n_target_val; i++) {
+	name = var_target_val[i]
+	print "  hstate.add_wide_int (ptr->" name");";
+}
+print "  return hstate.end ();";
+print "}";
+
+print "";
+print "/* Stream out target options  */";
+print "void";
+print "cl_target_option_stream_out (struct output_block *ob, struct cl_target_option *ptr)";
+print "{";
+for (i = 0; i < n_target_str; i++) {
+	name = var_target_str[i]
+	print "  streamer_write_string (ob, ob->main_stream, ptr->" name", true);";
+}
+for (i = 0; i < n_target_val; i++) {
+	name = var_target_val[i]
+	print "  streamer_write_uhwi (ob, ptr->" name");";
+}
+print "}";
+
+print "";
+print "/* Stream in target options  */";
+print "void";
+print "cl_target_option_stream_in (struct lto_input_block *ib, struct data_in *data_in, struct cl_target_option *ptr)";
+print "{";
+for (i = 0; i < n_target_str; i++) {
+	name = var_target_str[i]
+	print "  ptr->" name" = strdup (streamer_read_string (data_in, ib));";
+}
+for (i = 0; i < n_target_val; i++) {
+	name = var_target_val[i]
+	print "  ptr->" name" = (" var_target_val_type[i] ") streamer_read_uhwi (ib);";
+}
+
+print "}";
+
 }
Index: tree-streamer-in.c
===================================================================
--- tree-streamer-in.c	(revision 217448)
+++ tree-streamer-in.c	(working copy)
@@ -506,9 +506,6 @@ unpack_value_fields (struct data_in *dat
   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
     unpack_ts_translation_unit_decl_value_fields (data_in, bp, expr);
 
-  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
-    gcc_unreachable ();
-
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
     unpack_ts_optimization (bp, expr);
 
@@ -1081,6 +1078,9 @@ streamer_read_tree_body (struct lto_inpu
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
     lto_input_ts_constructor_tree_pointers (ib, data_in, expr);
 
+  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
+    cl_target_option_stream_in (ib, data_in, TREE_TARGET_OPTION (expr));
+
   if (code == OMP_CLAUSE)
     lto_input_ts_omp_clause_tree_pointers (ib, data_in, expr);
 }
Index: lto-streamer.h
===================================================================
--- lto-streamer.h	(revision 217448)
+++ lto-streamer.h	(working copy)
@@ -832,6 +832,14 @@ bool reachable_from_this_partition_p (st
 				      lto_symtab_encoder_t);
 lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
 
+/* In options-save.c.  */
+void cl_target_option_stream_out (struct output_block *,
+				  struct cl_target_option *);
+
+void cl_target_option_stream_in (struct lto_input_block *,
+				 struct data_in *,
+				 struct cl_target_option *);
+
 
 /* In lto-symtab.c.  */
 extern void lto_symtab_merge_decls (void);
Index: tree.c
===================================================================
--- tree.c	(revision 217448)
+++ tree.c	(working copy)
@@ -11484,10 +11495,7 @@ cl_option_hash_hash (const void *x)
     }
 
   else if (TREE_CODE (t) == TARGET_OPTION_NODE)
-    {
-      p = (const char *)TREE_TARGET_OPTION (t);
-      len = sizeof (struct cl_target_option);
-    }
+    return cl_target_option_hash (TREE_TARGET_OPTION (t));
 
   else
     gcc_unreachable ();
@@ -11526,9 +11534,8 @@ cl_option_hash_eq (const void *x, const
 
   else if (TREE_CODE (xt) == TARGET_OPTION_NODE)
     {
-      xp = (const char *)TREE_TARGET_OPTION (xt);
-      yp = (const char *)TREE_TARGET_OPTION (yt);
-      len = sizeof (struct cl_target_option);
+      return cl_target_option_eq (TREE_TARGET_OPTION (xt),
+				  TREE_TARGET_OPTION (yt));
     }
 
   else
Index: opth-gen.awk
===================================================================
--- opth-gen.awk	(revision 217448)
+++ opth-gen.awk	(working copy)
@@ -293,6 +293,12 @@ print "";
 print "/* Print target option variables from a structure.  */";
 print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);";
 print "";
+print "/* Compare two target option variables from a structure.  */";
+print "extern bool cl_target_option_eq (const struct cl_target_option *, const struct cl_target_option *);";
+print "";
+print "/* Hash option variables from a structure.  */";
+print "extern hashval_t cl_target_option_hash (const struct cl_target_option *);";
+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: lto-streamer-out.c
===================================================================
--- lto-streamer-out.c	(revision 217448)
+++ lto-streamer-out.c	(working copy)
@@ -594,7 +594,7 @@ DFS::DFS_write_tree_body (struct output_
     {
       DFS_follow_tree_edge (DECL_VINDEX (expr));
       DFS_follow_tree_edge (DECL_FUNCTION_PERSONALITY (expr));
-      /* Do not DECL_FUNCTION_SPECIFIC_TARGET.  They will be regenerated.  */
+      DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_TARGET (expr));
       DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr));
     }
 
@@ -945,7 +945,7 @@ hash_tree (struct streamer_tree_cache_d
 			strlen (TRANSLATION_UNIT_LANGUAGE (t)));
 
   if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
-    gcc_unreachable ();
+    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));
@@ -1028,7 +1028,7 @@ hash_tree (struct streamer_tree_cache_d
     {
       visit (DECL_VINDEX (t));
       visit (DECL_FUNCTION_PERSONALITY (t));
-      /* Do not follow DECL_FUNCTION_SPECIFIC_TARGET.  */
+      visit (DECL_FUNCTION_SPECIFIC_TARGET (t));
       visit (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t));
     }
 
Index: lto/lto.c
===================================================================
--- lto/lto.c	(revision 217448)
+++ lto/lto.c	(working copy)
@@ -1377,7 +1377,8 @@ compare_tree_sccs_1 (tree t1, tree t2, t
       return false;
 
   if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
-    gcc_unreachable ();
+    if (cl_target_option_eq (TREE_TARGET_OPTION (t1), TREE_TARGET_OPTION (t2)))
+      return false;
 
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
     if (memcmp (TREE_OPTIMIZATION (t1), TREE_OPTIMIZATION (t2),
Index: tree-streamer-out.c
===================================================================
--- tree-streamer-out.c	(revision 217448)
+++ tree-streamer-out.c	(working copy)
@@ -472,9 +472,6 @@ streamer_pack_tree_bitfields (struct out
   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
     pack_ts_translation_unit_decl_value_fields (ob, bp, expr);
 
-  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
-    gcc_unreachable ();
-
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
     pack_ts_optimization (bp, expr);
 
@@ -963,6 +960,9 @@ streamer_write_tree_body (struct output_
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
     write_ts_constructor_tree_pointers (ob, expr, ref_p);
 
+  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
+    cl_target_option_stream_out (ob, TREE_TARGET_OPTION (expr));
+
   if (code == OMP_CLAUSE)
     write_ts_omp_clause_tree_pointers (ob, expr, ref_p);
 }

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2014-11-13  5:10 LTO streaming of TARGET_OPTIMIZE_NODE Jan Hubicka
@ 2014-11-13 10:58 ` Richard Biener
  2014-11-13 15:32   ` Jan Hubicka
  2014-11-20 13:09 ` LTO streaming of TARGET_OPTIMIZE_NODE Bernd Schmidt
  1 sibling, 1 reply; 19+ messages in thread
From: Richard Biener @ 2014-11-13 10:58 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches, Joseph S. Myers

On Thu, 13 Nov 2014, Jan Hubicka wrote:

> Hi,
> this patch adds infrastructure for proper streaming and merging of
> TREE_TARGET_OPTION.  The catch is that TREE_TARGET_OPTION is autogenerated
> structure.  For x86_64 it looks as follows:
> 
> /* Structure to save/restore selected target specific options.  */
> struct GTY(()) cl_target_option
> {
>   HOST_WIDE_INT x_ix86_isa_flags_explicit;
>   HOST_WIDE_INT x_ix86_target_flags_explicit;
>   const char *x_ix86_arch_string;
>   const char *x_ix86_recip_name;
>   const char *x_ix86_tune_ctrl_string;
>   const char *x_ix86_tune_memcpy_strategy;
>   const char *x_ix86_tune_memset_strategy;
>   const char *x_ix86_tune_string;
>   HOST_WIDE_INT x_ix86_isa_flags;
>   enum fpmath_unit x_ix86_fpmath;
>   enum asm_dialect x_ix86_asm_dialect;
>   ...
>   enum stack_protector_guard x_ix86_stack_protector_guard;
>   enum stringop_alg x_ix86_stringop_alg;
>   enum tls_dialect x_ix86_tls_dialect;
>   int x_ix86_branch_cost;
>   int x_ix86_dump_tunes;
>   ....
>   int x_recip_mask;
>   int x_target_flags;
>   unsigned char arch;
>   unsigned char arch_specified;
>   unsigned char branch_cost;
>   unsigned char schedule;
>   unsigned char tune;
>   unsigned char tune_defaulted;
> };
> 
> The problem is that the strings prevents us from streaming the structure as a binary
> blob like we do for optimization nodes (and we should not do that to make LTO streaming
> stable across attribute tweaks in minor releases).
> 
> This patch extends the AWK generators to produce four functions:
> 
> /* Compare two target options  */
> bool
> cl_target_option_eq (struct cl_target_option const *ptr1,
>                      struct cl_target_option const *ptr2)
> {
>   if (ptr1->x_ix86_arch_string != ptr2->x_ix86_arch_string
>       && (!ptr1->x_ix86_arch_string || !ptr2->x_ix86_arch_string
>           || strcmp (ptr1->x_ix86_arch_string, ptr2->x_ix86_arch_string)))
>     return false;
> ....
>     if (ptr1->x_ix86_isa_flags != ptr2->x_ix86_isa_flags)
>     return false;
>   if (ptr1->x_ix86_fpmath != ptr2->x_ix86_fpmath)
>     return false;
>   return true;
> }
> 
> /* Hash target options  */
> hashval_t
> cl_target_option_hash (struct cl_target_option const *ptr)
> { 
>   inchash::hash hstate;
>   if (ptr->x_ix86_arch_string)
>     hstate.add (ptr->x_ix86_arch_string, strlen (ptr->x_ix86_arch_string));
>   else
>     hstate.add_int (0);
> ...
>   hstate.add_wide_int (ptr->x_ix86_fpmath);
>   return hstate.end ();
> }
> 
> /* Stream out target options  */
> void
> cl_target_option_stream_out (struct output_block *ob, struct cl_target_option *ptr)
> { 
>   streamer_write_string (ob, ob->main_stream, ptr->x_ix86_arch_string, true);
> ...
>   streamer_write_uhwi (ob, ptr->x_ix86_isa_flags);
>   streamer_write_uhwi (ob, ptr->x_ix86_fpmath);
> }
> 
> /* Stream in target options  */
> void
> cl_target_option_stream_in (struct lto_input_block *ib, struct data_in *data_in, struct cl_target_option *ptr)
> { 
>   ptr->x_ix86_arch_string = strdup (streamer_read_string (data_in, ib));
> ...
>   ptr->x_ix86_fpmath = (enum fpmath_unit ) streamer_read_uhwi (ib);
> }
> 
> These allows us to properly stream, compare and hash the values.
> 
> There is some implementation lazyness - for example I stream all scalars as
> unsigned HOST_WIDE_INT that seems to be the largest type used for variables
> across the targets.
> 
> If other types are used, the type matching (I stole from other part of the awk
> scripts) will need to be extended; for now it knows that const char * is a
> string and needs special care but nothing else.
> 
> I have tested this with firefox and additional change to tree.c to always
> initialize TARGET_OPTION_NODE for defined functions (so target units are
> peorperly presered across units). This seems to work as intended - i.e. the
> functions gets link-time optimized according to -march settings passed at
> compile time.
> 
> I noticed that memory use is now 3.8GB instead of previous 2.8GB - this may be
> tree merging problem caused by mismatching target settings but most probably it
> is an unrelated stuff. I will look into it tomorrow.  I also plan to test this
> on PPC (that currently fails to bootstrap).
> 
> Incrementally I would like to handle optimizations nodes same way and change
> streaming format to be a set of assignments field_name=value.
> This way we could behave sanely when some field is introduced or removed by
> either defaulting it or ignoring it.

I'm not sure that idea is good ;)  Adding a version / checksum to
detect a mismatch early would be nice though.  Maybe just compute
a hash for the fields in the AWK script?

> Bootstrapped/regtested x86_64-linux, seems sane?

Sounds sane - I'd like to have a AWK capable person have a look
for non-portable stuff (did you check AIX? ;))

Some more comments below

> 	* 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.
> 
> 	* lto.c (compare_tree_sccs_1): Compare cl_target_option_eq.
> 	
> Index: optc-save-gen.awk
> ===================================================================
> --- optc-save-gen.awk	(revision 217448)
> +++ optc-save-gen.awk	(working copy)
> @@ -39,6 +39,16 @@ print "#include " quote "intl.h" quote
>  print ""
>  print "#include " quote "flags.h" quote
>  print "#include " quote "target.h" quote
> +print "#include " quote "inchash.h" quote
> +print "#include " quote "tree.h" quote
> +print "#include " quote "tree-ssa-alias.h" quote
> +print "#include " quote "is-a.h" quote
> +print "#include " quote "predict.h" quote
> +print "#include " quote "function.h" quote
> +print "#include " quote "basic-block.h" quote
> +print "#include " quote "gimple-expr.h" quote
> +print "#include " quote "gimple.h" quote
> +print "#include " quote "data-streamer.h" quote
>  print ""
>  
>  if (n_extra_c_includes > 0) {
> @@ -417,4 +427,120 @@ print "    targetm.target_option.print (
>  
>  print "}";
>  
> +print "";
> +print "/* Compare two target options  */";
> +print "bool";
> +print "cl_target_option_eq (struct cl_target_option const *ptr1,";
> +print "                     struct cl_target_option const *ptr2)";
> +print "{";
> +n_target_val = 0;
> +n_target_str = 0;
> +
> +for (i = 0; i < n_target_save; i++) {
> +	var = target_save_decl[i];
> +	sub (" *=.*", "", var);
> +	name = var;
> +	type = var;
> +	sub("^.*[ *]", "", name)
> +	sub(" *" name "$", "", type)
> +	if (target_save_decl[i] ~ "^const char \\*+[_" alnum "]+$")
> +		var_target_str[n_target_str++] = name;
> +	else {
> +		var_target_val_type[n_target_val] = type;
> +		var_target_val[n_target_val++] = name;
> +	}
> +}
> +if (have_save) {
> +	for (i = 0; i < n_opts; i++) {
> +		if (flag_set_p("Save", flags[i])) {
> +			name = var_name(flags[i])
> +			if(name == "")
> +				name = "target_flags";
> +
> +			if(name in var_list_seen)
> +				continue;
> +
> +			var_list_seen[name]++;
> +			otype = var_type_struct(flags[i])
> +			if (otype ~ "^const char \\**$")
> +				var_target_str[n_target_str++] = "x_" name;
> +			else {
> +				var_target_val_type[n_target_val] = otype;
> +				var_target_val[n_target_val++] = "x_" name;
> +			}
> +		}
> +	}
> +} else {
> +	var_target_val_type[n_target_val] = "int";
> +	var_target_val[n_target_val++] = "x_target_flags";
> +}
> +
> +for (i = 0; i < n_target_str; i++) {
> +	name = var_target_str[i]
> +	print "  if (ptr1->" name" != ptr2->" name;
> +	print "      && (!ptr1->" name" || !ptr2->" name
> +	print "          || strcmp (ptr1->" name", ptr2->" name ")))";
> +	print "    return false;";
> +}
> +for (i = 0; i < n_target_val; i++) {
> +	name = var_target_val[i]
> +	print "  if (ptr1->" name" != ptr2->" name ")";
> +	print "    return false;";
> +}
> +
> +print "  return true;";
> +
> +print "}";
> +
> +print "";
> +print "/* Hash target options  */";
> +print "hashval_t";
> +print "cl_target_option_hash (struct cl_target_option const *ptr)";
> +print "{";
> +print "  inchash::hash hstate;";
> +for (i = 0; i < n_target_str; i++) {
> +	name = var_target_str[i]
> +	print "  if (ptr->" name")";
> +	print "    hstate.add (ptr->" name", strlen (ptr->" name"));";
> +	print "  else";
> +	print "    hstate.add_int (0);";
> +}
> +for (i = 0; i < n_target_val; i++) {
> +	name = var_target_val[i]
> +	print "  hstate.add_wide_int (ptr->" name");";
> +}
> +print "  return hstate.end ();";
> +print "}";
> +
> +print "";
> +print "/* Stream out target options  */";
> +print "void";
> +print "cl_target_option_stream_out (struct output_block *ob, struct cl_target_option *ptr)";
> +print "{";
> +for (i = 0; i < n_target_str; i++) {
> +	name = var_target_str[i]
> +	print "  streamer_write_string (ob, ob->main_stream, ptr->" name", true);";
> +}
> +for (i = 0; i < n_target_val; i++) {
> +	name = var_target_val[i]
> +	print "  streamer_write_uhwi (ob, ptr->" name");";
> +}
> +print "}";
> +
> +print "";
> +print "/* Stream in target options  */";
> +print "void";
> +print "cl_target_option_stream_in (struct lto_input_block *ib, struct data_in *data_in, struct cl_target_option *ptr)";
> +print "{";
> +for (i = 0; i < n_target_str; i++) {
> +	name = var_target_str[i]
> +	print "  ptr->" name" = strdup (streamer_read_string (data_in, ib));";
> +}
> +for (i = 0; i < n_target_val; i++) {
> +	name = var_target_val[i]
> +	print "  ptr->" name" = (" var_target_val_type[i] ") streamer_read_uhwi (ib);";
> +}
> +
> +print "}";
> +
>  }
> Index: tree-streamer-in.c
> ===================================================================
> --- tree-streamer-in.c	(revision 217448)
> +++ tree-streamer-in.c	(working copy)
> @@ -506,9 +506,6 @@ unpack_value_fields (struct data_in *dat
>    if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
>      unpack_ts_translation_unit_decl_value_fields (data_in, bp, expr);
>  
> -  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> -    gcc_unreachable ();
> -
>    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
>      unpack_ts_optimization (bp, expr);
>  
> @@ -1081,6 +1078,9 @@ streamer_read_tree_body (struct lto_inpu
>    if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
>      lto_input_ts_constructor_tree_pointers (ib, data_in, expr);
>  
> +  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> +    cl_target_option_stream_in (ib, data_in, TREE_TARGET_OPTION (expr));
> +
>    if (code == OMP_CLAUSE)
>      lto_input_ts_omp_clause_tree_pointers (ib, data_in, expr);

Any reason you don't use bitpacks and stream it from 
[un]pack_value_fields?  We can happily pack strings there as well.
The 'body' streaming is for tree pointers only.

>  }
> Index: lto-streamer.h
> ===================================================================
> --- lto-streamer.h	(revision 217448)
> +++ lto-streamer.h	(working copy)
> @@ -832,6 +832,14 @@ bool reachable_from_this_partition_p (st
>  				      lto_symtab_encoder_t);
>  lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
>  
> +/* In options-save.c.  */
> +void cl_target_option_stream_out (struct output_block *,
> +				  struct cl_target_option *);
> +
> +void cl_target_option_stream_in (struct lto_input_block *,
> +				 struct data_in *,
> +				 struct cl_target_option *);
> +
>  
>  /* In lto-symtab.c.  */
>  extern void lto_symtab_merge_decls (void);
> Index: tree.c
> ===================================================================
> --- tree.c	(revision 217448)
> +++ tree.c	(working copy)
> @@ -11484,10 +11495,7 @@ cl_option_hash_hash (const void *x)
>      }
>  
>    else if (TREE_CODE (t) == TARGET_OPTION_NODE)
> -    {
> -      p = (const char *)TREE_TARGET_OPTION (t);
> -      len = sizeof (struct cl_target_option);
> -    }
> +    return cl_target_option_hash (TREE_TARGET_OPTION (t));
>  
>    else
>      gcc_unreachable ();
> @@ -11526,9 +11534,8 @@ cl_option_hash_eq (const void *x, const
>  
>    else if (TREE_CODE (xt) == TARGET_OPTION_NODE)
>      {
> -      xp = (const char *)TREE_TARGET_OPTION (xt);
> -      yp = (const char *)TREE_TARGET_OPTION (yt);
> -      len = sizeof (struct cl_target_option);
> +      return cl_target_option_eq (TREE_TARGET_OPTION (xt),
> +				  TREE_TARGET_OPTION (yt));
>      }
>  
>    else
> Index: opth-gen.awk
> ===================================================================
> --- opth-gen.awk	(revision 217448)
> +++ opth-gen.awk	(working copy)
> @@ -293,6 +293,12 @@ print "";
>  print "/* Print target option variables from a structure.  */";
>  print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);";
>  print "";
> +print "/* Compare two target option variables from a structure.  */";
> +print "extern bool cl_target_option_eq (const struct cl_target_option *, const struct cl_target_option *);";
> +print "";
> +print "/* Hash option variables from a structure.  */";
> +print "extern hashval_t cl_target_option_hash (const struct cl_target_option *);";
> +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: lto-streamer-out.c
> ===================================================================
> --- lto-streamer-out.c	(revision 217448)
> +++ lto-streamer-out.c	(working copy)
> @@ -594,7 +594,7 @@ DFS::DFS_write_tree_body (struct output_
>      {
>        DFS_follow_tree_edge (DECL_VINDEX (expr));
>        DFS_follow_tree_edge (DECL_FUNCTION_PERSONALITY (expr));
> -      /* Do not DECL_FUNCTION_SPECIFIC_TARGET.  They will be regenerated.  */
> +      DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_TARGET (expr));
>        DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr));
>      }
>  
> @@ -945,7 +945,7 @@ hash_tree (struct streamer_tree_cache_d
>  			strlen (TRANSLATION_UNIT_LANGUAGE (t)));
>  
>    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> -    gcc_unreachable ();
> +    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));
> @@ -1028,7 +1028,7 @@ hash_tree (struct streamer_tree_cache_d
>      {
>        visit (DECL_VINDEX (t));
>        visit (DECL_FUNCTION_PERSONALITY (t));
> -      /* Do not follow DECL_FUNCTION_SPECIFIC_TARGET.  */
> +      visit (DECL_FUNCTION_SPECIFIC_TARGET (t));
>        visit (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t));
>      }
>  
> Index: lto/lto.c
> ===================================================================
> --- lto/lto.c	(revision 217448)
> +++ lto/lto.c	(working copy)
> @@ -1377,7 +1377,8 @@ compare_tree_sccs_1 (tree t1, tree t2, t
>        return false;
>  
>    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> -    gcc_unreachable ();
> +    if (cl_target_option_eq (TREE_TARGET_OPTION (t1), TREE_TARGET_OPTION (t2)))
> +      return false;

I suppose that's the reason for the memory use - should be
!cl_target_option_eq I think ;)

>  
>    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
>      if (memcmp (TREE_OPTIMIZATION (t1), TREE_OPTIMIZATION (t2),
> Index: tree-streamer-out.c
> ===================================================================
> --- tree-streamer-out.c	(revision 217448)
> +++ tree-streamer-out.c	(working copy)
> @@ -472,9 +472,6 @@ streamer_pack_tree_bitfields (struct out
>    if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
>      pack_ts_translation_unit_decl_value_fields (ob, bp, expr);
>  
> -  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> -    gcc_unreachable ();
> -
>    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
>      pack_ts_optimization (bp, expr);
>  
> @@ -963,6 +960,9 @@ streamer_write_tree_body (struct output_
>    if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
>      write_ts_constructor_tree_pointers (ob, expr, ref_p);
>  
> +  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> +    cl_target_option_stream_out (ob, TREE_TARGET_OPTION (expr));
> +
>    if (code == OMP_CLAUSE)
>      write_ts_omp_clause_tree_pointers (ob, expr, ref_p);
>  }

Otherwise looks good.

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2014-11-13 10:58 ` Richard Biener
@ 2014-11-13 15:32   ` Jan Hubicka
  2014-11-14  0:54     ` Jan Hubicka
  0 siblings, 1 reply; 19+ messages in thread
From: Jan Hubicka @ 2014-11-13 15:32 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jan Hubicka, gcc-patches, Joseph S. Myers

> > 
> > Incrementally I would like to handle optimizations nodes same way and change
> > streaming format to be a set of assignments field_name=value.
> > This way we could behave sanely when some field is introduced or removed by
> > either defaulting it or ignoring it.
> 
> I'm not sure that idea is good ;)  Adding a version / checksum to
> detect a mismatch early would be nice though.  Maybe just compute
> a hash for the fields in the AWK script?

OK, lets see how to handle it incrementaly.
> 
> > Bootstrapped/regtested x86_64-linux, seems sane?
> 
> Sounds sane - I'd like to have a AWK capable person have a look
> for non-portable stuff (did you check AIX? ;))

Good idea, will do today :)
Basically all the AWK is cut&paste from the way save loop is generated, no
really new constructs in it.
> > +  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> > +    cl_target_option_stream_in (ib, data_in, TREE_TARGET_OPTION (expr));
> > +
> >    if (code == OMP_CLAUSE)
> >      lto_input_ts_omp_clause_tree_pointers (ib, data_in, expr);
> 
> Any reason you don't use bitpacks and stream it from 
> [un]pack_value_fields?  We can happily pack strings there as well.
> The 'body' streaming is for tree pointers only.

Hmm, I did not notice we have pack_string.  Will go with bitpacks then.
> > @@ -963,6 +960,9 @@ streamer_write_tree_body (struct output_
> >    if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
> >      write_ts_constructor_tree_pointers (ob, expr, ref_p);
> >  
> > +  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> > +    cl_target_option_stream_out (ob, TREE_TARGET_OPTION (expr));
> > +
> >    if (code == OMP_CLAUSE)
> >      write_ts_omp_clause_tree_pointers (ob, expr, ref_p);
> >  }
> 
> Otherwise looks good.

OK, I will update the changes above and test AIX today.
Incrementally I will send patch to disable the TARGET_OPTION_NODE regeeneration from attribute
and to stream TARGET_OPTION_NODE for all functions (this is tested on firefox and AIX by now
and works).

For optimization node I think I can follow exactly the same strategy (to avoid writting binary blobs
that are not portable). I plan to add Ipa and Late modifiers to the format to annotate flags that
affects only Ipa or Late codegen/optimization (ltrans).  This way we can add comparers for inliner
ignoring the flags that are not marked Late and streamer that streams only Ipa/Late.

If this plan sounds sane, I can do it today I believe.

Across stage3 early stage3 I can update IPA passes to not check global flags during LTO so
we can support correctly support different LTO flags (like -fno-inline) in the optimization
nodes...

Honza
> 
> Thanks,
> Richard.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2014-11-13 15:32   ` Jan Hubicka
@ 2014-11-14  0:54     ` Jan Hubicka
  2014-11-14  8:54       ` Richard Biener
  2014-11-14 18:15       ` [BUILDROBOT] error: ‘cl_target_option_stream_in’ was not declared in this scope (was: LTO streaming of TARGET_OPTIMIZE_NODE) Jan-Benedict Glaw
  0 siblings, 2 replies; 19+ messages in thread
From: Jan Hubicka @ 2014-11-14  0:54 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Biener, gcc-patches, Joseph S. Myers

Hi,
here is upated version with bitfields and also tested on PPC64-linux/aix.
I hacked configury to use system awk instead of gawk, so the changes are hopefully safe.

OK?
Honza

	* 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.

	* lto.c (compare_tree_sccs_1): Compare cl_target_option_eq.
Index: lto/lto.c
===================================================================
--- lto/lto.c	(revision 217513)
+++ lto/lto.c	(working copy)
@@ -1377,7 +1377,8 @@
       return false;
 
   if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
-    gcc_unreachable ();
+    if (!cl_target_option_eq (TREE_TARGET_OPTION (t1), TREE_TARGET_OPTION (t2)))
+      return false;
 
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
     if (memcmp (TREE_OPTIMIZATION (t1), TREE_OPTIMIZATION (t2),
Index: lto-streamer-out.c
===================================================================
--- lto-streamer-out.c	(revision 217513)
+++ lto-streamer-out.c	(working copy)
@@ -594,7 +594,7 @@
     {
       DFS_follow_tree_edge (DECL_VINDEX (expr));
       DFS_follow_tree_edge (DECL_FUNCTION_PERSONALITY (expr));
-      /* Do not DECL_FUNCTION_SPECIFIC_TARGET.  They will be regenerated.  */
+      DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_TARGET (expr));
       DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr));
     }
 
@@ -945,7 +945,7 @@
 			strlen (TRANSLATION_UNIT_LANGUAGE (t)));
 
   if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
-    gcc_unreachable ();
+    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));
@@ -1028,7 +1028,7 @@
     {
       visit (DECL_VINDEX (t));
       visit (DECL_FUNCTION_PERSONALITY (t));
-      /* Do not follow DECL_FUNCTION_SPECIFIC_TARGET.  */
+      visit (DECL_FUNCTION_SPECIFIC_TARGET (t));
       visit (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t));
     }
 
Index: lto-streamer.h
===================================================================
--- lto-streamer.h	(revision 217513)
+++ lto-streamer.h	(working copy)
@@ -836,7 +836,15 @@
 lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
 void select_what_to_stream (bool);
 
+/* In options-save.c.  */
+void cl_target_option_stream_out (struct output_block *, struct bitpack_d *,
+				  struct cl_target_option *);
 
+void cl_target_option_stream_in (struct data_in *,
+				 struct bitpack_d *,
+				 struct cl_target_option *);
+
+
 /* 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 217513)
+++ optc-save-gen.awk	(working copy)
@@ -39,6 +39,18 @@
 print ""
 print "#include " quote "flags.h" quote
 print "#include " quote "target.h" quote
+print "#include " quote "inchash.h" quote
+print "#include " quote "tree.h" quote
+print "#include " quote "tree-ssa-alias.h" quote
+print "#include " quote "is-a.h" quote
+print "#include " quote "predict.h" quote
+print "#include " quote "function.h" quote
+print "#include " quote "basic-block.h" quote
+print "#include " quote "gimple-expr.h" quote
+print "#include " quote "gimple.h" quote
+print "#include " quote "data-streamer.h" quote
+print "#include " quote "ipa-ref.h" quote
+print "#include " quote "cgraph.h" quote
 print ""
 
 if (n_extra_c_includes > 0) {
@@ -417,4 +429,126 @@
 
 print "}";
 
+print "";
+print "/* Compare two target options  */";
+print "bool";
+print "cl_target_option_eq (struct cl_target_option const *ptr1 ATTRIBUTE_UNUSED,";
+print "                     struct cl_target_option const *ptr2 ATTRIBUTE_UNUSED)";
+print "{";
+n_target_val = 0;
+n_target_str = 0;
+
+for (i = 0; i < n_target_save; i++) {
+	var = target_save_decl[i];
+	sub (" *=.*", "", var);
+	name = var;
+	type = var;
+	sub("^.*[ *]", "", name)
+	sub(" *" name "$", "", type)
+	if (target_save_decl[i] ~ "^const char \\*+[_" alnum "]+$")
+		var_target_str[n_target_str++] = name;
+	else {
+		var_target_val_type[n_target_val] = type;
+		var_target_val[n_target_val++] = name;
+	}
 }
+if (have_save) {
+	for (i = 0; i < n_opts; i++) {
+		if (flag_set_p("Save", flags[i])) {
+			name = var_name(flags[i])
+			if(name == "")
+				name = "target_flags";
+
+			if(name in var_list_seen)
+				continue;
+
+			var_list_seen[name]++;
+			otype = var_type_struct(flags[i])
+			if (otype ~ "^const char \\**$")
+				var_target_str[n_target_str++] = "x_" name;
+			else {
+				var_target_val_type[n_target_val] = otype;
+				var_target_val[n_target_val++] = "x_" name;
+			}
+		}
+	}
+} else {
+	var_target_val_type[n_target_val] = "int";
+	var_target_val[n_target_val++] = "x_target_flags";
+}
+
+for (i = 0; i < n_target_str; i++) {
+	name = var_target_str[i]
+	print "  if (ptr1->" name" != ptr2->" name;
+	print "      && (!ptr1->" name" || !ptr2->" name
+	print "          || strcmp (ptr1->" name", ptr2->" name ")))";
+	print "    return false;";
+}
+for (i = 0; i < n_target_val; i++) {
+	name = var_target_val[i]
+	print "  if (ptr1->" name" != ptr2->" name ")";
+	print "    return false;";
+}
+
+print "  return true;";
+
+print "}";
+
+print "";
+print "/* Hash target options  */";
+print "hashval_t";
+print "cl_target_option_hash (struct cl_target_option const *ptr ATTRIBUTE_UNUSED)";
+print "{";
+print "  inchash::hash hstate;";
+for (i = 0; i < n_target_str; i++) {
+	name = var_target_str[i]
+	print "  if (ptr->" name")";
+	print "    hstate.add (ptr->" name", strlen (ptr->" name"));";
+	print "  else";
+	print "    hstate.add_int (0);";
+}
+for (i = 0; i < n_target_val; i++) {
+	name = var_target_val[i]
+	print "  hstate.add_wide_int (ptr->" name");";
+}
+print "  return hstate.end ();";
+print "}";
+
+print "";
+print "/* Stream out target options  */";
+print "void";
+print "cl_target_option_stream_out (struct output_block *ob ATTRIBUTE_UNUSED,";
+print "                             struct bitpack_d *bp ATTRIBUTE_UNUSED,";
+print "                             struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
+print "{";
+for (i = 0; i < n_target_str; i++) {
+	name = var_target_str[i]
+	print "  bp_pack_string (ob, bp, ptr->" name", true);";
+}
+for (i = 0; i < n_target_val; i++) {
+	name = var_target_val[i]
+	print "  bp_pack_value (bp, ptr->" name", 64);";
+}
+print "}";
+
+print "";
+print "/* Stream in target options  */";
+print "void";
+print "cl_target_option_stream_in (struct data_in *data_in ATTRIBUTE_UNUSED,";
+print "                            struct bitpack_d *bp ATTRIBUTE_UNUSED,";
+print "                            struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
+print "{";
+for (i = 0; i < n_target_str; i++) {
+	name = var_target_str[i]
+	print "  ptr->" name" = bp_unpack_string (data_in, bp);";
+	print "  if (ptr->" name")";
+	print "    ptr->" name" = xstrdup (ptr->" name");";
+}
+for (i = 0; i < n_target_val; i++) {
+	name = var_target_val[i]
+	print "  ptr->" name" = (" var_target_val_type[i] ") bp_unpack_value (bp, 64);";
+}
+
+print "}";
+
+}
Index: opth-gen.awk
===================================================================
--- opth-gen.awk	(revision 217513)
+++ opth-gen.awk	(working copy)
@@ -293,6 +293,12 @@
 print "/* Print target option variables from a structure.  */";
 print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);";
 print "";
+print "/* Compare two target option variables from a structure.  */";
+print "extern bool cl_target_option_eq (const struct cl_target_option *, const struct cl_target_option *);";
+print "";
+print "/* Hash option variables from a structure.  */";
+print "extern hashval_t cl_target_option_hash (const struct cl_target_option *);";
+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 217513)
+++ tree-streamer-in.c	(working copy)
@@ -506,9 +506,6 @@
   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
     unpack_ts_translation_unit_decl_value_fields (data_in, bp, expr);
 
-  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
-    gcc_unreachable ();
-
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
     unpack_ts_optimization (bp, expr);
 
@@ -526,6 +523,9 @@
 	vec_safe_grow (CONSTRUCTOR_ELTS (expr), length);
     }
 
+  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
+    cl_target_option_stream_in (data_in, bp, TREE_TARGET_OPTION (expr));
+
   if (code == OMP_CLAUSE)
     unpack_ts_omp_clause_value_fields (data_in, bp, expr);
 }
Index: tree-streamer-out.c
===================================================================
--- tree-streamer-out.c	(revision 217513)
+++ tree-streamer-out.c	(working copy)
@@ -472,9 +472,6 @@
   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
     pack_ts_translation_unit_decl_value_fields (ob, bp, expr);
 
-  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
-    gcc_unreachable ();
-
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
     pack_ts_optimization (bp, expr);
 
@@ -484,6 +481,9 @@
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
     bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr));
 
+  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
+    cl_target_option_stream_out (ob, bp, TREE_TARGET_OPTION (expr));
+
   if (code == OMP_CLAUSE)
     pack_ts_omp_clause_value_fields (ob, bp, expr);
 }
Index: tree.c
===================================================================
--- tree.c	(revision 217513)
+++ tree.c	(working copy)
@@ -11486,10 +11486,7 @@
     }
 
   else if (TREE_CODE (t) == TARGET_OPTION_NODE)
-    {
-      p = (const char *)TREE_TARGET_OPTION (t);
-      len = sizeof (struct cl_target_option);
-    }
+    return cl_target_option_hash (TREE_TARGET_OPTION (t));
 
   else
     gcc_unreachable ();
@@ -11528,9 +11525,8 @@
 
   else if (TREE_CODE (xt) == TARGET_OPTION_NODE)
     {
-      xp = (const char *)TREE_TARGET_OPTION (xt);
-      yp = (const char *)TREE_TARGET_OPTION (yt);
-      len = sizeof (struct cl_target_option);
+      return cl_target_option_eq (TREE_TARGET_OPTION (xt),
+				  TREE_TARGET_OPTION (yt));
     }
 
   else

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2014-11-14  0:54     ` Jan Hubicka
@ 2014-11-14  8:54       ` Richard Biener
  2014-11-14 18:15       ` [BUILDROBOT] error: ‘cl_target_option_stream_in’ was not declared in this scope (was: LTO streaming of TARGET_OPTIMIZE_NODE) Jan-Benedict Glaw
  1 sibling, 0 replies; 19+ messages in thread
From: Richard Biener @ 2014-11-14  8:54 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches, Joseph S. Myers

On Fri, 14 Nov 2014, Jan Hubicka wrote:

> Hi,
> here is upated version with bitfields and also tested on PPC64-linux/aix.
> I hacked configury to use system awk instead of gawk, so the changes are hopefully safe.
> 
> OK?

Ok.

Thanks,
Richard.

> Honza
> 
> 	* 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.
> 
> 	* lto.c (compare_tree_sccs_1): Compare cl_target_option_eq.
> Index: lto/lto.c
> ===================================================================
> --- lto/lto.c	(revision 217513)
> +++ lto/lto.c	(working copy)
> @@ -1377,7 +1377,8 @@
>        return false;
>  
>    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> -    gcc_unreachable ();
> +    if (!cl_target_option_eq (TREE_TARGET_OPTION (t1), TREE_TARGET_OPTION (t2)))
> +      return false;
>  
>    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
>      if (memcmp (TREE_OPTIMIZATION (t1), TREE_OPTIMIZATION (t2),
> Index: lto-streamer-out.c
> ===================================================================
> --- lto-streamer-out.c	(revision 217513)
> +++ lto-streamer-out.c	(working copy)
> @@ -594,7 +594,7 @@
>      {
>        DFS_follow_tree_edge (DECL_VINDEX (expr));
>        DFS_follow_tree_edge (DECL_FUNCTION_PERSONALITY (expr));
> -      /* Do not DECL_FUNCTION_SPECIFIC_TARGET.  They will be regenerated.  */
> +      DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_TARGET (expr));
>        DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr));
>      }
>  
> @@ -945,7 +945,7 @@
>  			strlen (TRANSLATION_UNIT_LANGUAGE (t)));
>  
>    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> -    gcc_unreachable ();
> +    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));
> @@ -1028,7 +1028,7 @@
>      {
>        visit (DECL_VINDEX (t));
>        visit (DECL_FUNCTION_PERSONALITY (t));
> -      /* Do not follow DECL_FUNCTION_SPECIFIC_TARGET.  */
> +      visit (DECL_FUNCTION_SPECIFIC_TARGET (t));
>        visit (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t));
>      }
>  
> Index: lto-streamer.h
> ===================================================================
> --- lto-streamer.h	(revision 217513)
> +++ lto-streamer.h	(working copy)
> @@ -836,7 +836,15 @@
>  lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
>  void select_what_to_stream (bool);
>  
> +/* In options-save.c.  */
> +void cl_target_option_stream_out (struct output_block *, struct bitpack_d *,
> +				  struct cl_target_option *);
>  
> +void cl_target_option_stream_in (struct data_in *,
> +				 struct bitpack_d *,
> +				 struct cl_target_option *);
> +
> +
>  /* 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 217513)
> +++ optc-save-gen.awk	(working copy)
> @@ -39,6 +39,18 @@
>  print ""
>  print "#include " quote "flags.h" quote
>  print "#include " quote "target.h" quote
> +print "#include " quote "inchash.h" quote
> +print "#include " quote "tree.h" quote
> +print "#include " quote "tree-ssa-alias.h" quote
> +print "#include " quote "is-a.h" quote
> +print "#include " quote "predict.h" quote
> +print "#include " quote "function.h" quote
> +print "#include " quote "basic-block.h" quote
> +print "#include " quote "gimple-expr.h" quote
> +print "#include " quote "gimple.h" quote
> +print "#include " quote "data-streamer.h" quote
> +print "#include " quote "ipa-ref.h" quote
> +print "#include " quote "cgraph.h" quote
>  print ""
>  
>  if (n_extra_c_includes > 0) {
> @@ -417,4 +429,126 @@
>  
>  print "}";
>  
> +print "";
> +print "/* Compare two target options  */";
> +print "bool";
> +print "cl_target_option_eq (struct cl_target_option const *ptr1 ATTRIBUTE_UNUSED,";
> +print "                     struct cl_target_option const *ptr2 ATTRIBUTE_UNUSED)";
> +print "{";
> +n_target_val = 0;
> +n_target_str = 0;
> +
> +for (i = 0; i < n_target_save; i++) {
> +	var = target_save_decl[i];
> +	sub (" *=.*", "", var);
> +	name = var;
> +	type = var;
> +	sub("^.*[ *]", "", name)
> +	sub(" *" name "$", "", type)
> +	if (target_save_decl[i] ~ "^const char \\*+[_" alnum "]+$")
> +		var_target_str[n_target_str++] = name;
> +	else {
> +		var_target_val_type[n_target_val] = type;
> +		var_target_val[n_target_val++] = name;
> +	}
>  }
> +if (have_save) {
> +	for (i = 0; i < n_opts; i++) {
> +		if (flag_set_p("Save", flags[i])) {
> +			name = var_name(flags[i])
> +			if(name == "")
> +				name = "target_flags";
> +
> +			if(name in var_list_seen)
> +				continue;
> +
> +			var_list_seen[name]++;
> +			otype = var_type_struct(flags[i])
> +			if (otype ~ "^const char \\**$")
> +				var_target_str[n_target_str++] = "x_" name;
> +			else {
> +				var_target_val_type[n_target_val] = otype;
> +				var_target_val[n_target_val++] = "x_" name;
> +			}
> +		}
> +	}
> +} else {
> +	var_target_val_type[n_target_val] = "int";
> +	var_target_val[n_target_val++] = "x_target_flags";
> +}
> +
> +for (i = 0; i < n_target_str; i++) {
> +	name = var_target_str[i]
> +	print "  if (ptr1->" name" != ptr2->" name;
> +	print "      && (!ptr1->" name" || !ptr2->" name
> +	print "          || strcmp (ptr1->" name", ptr2->" name ")))";
> +	print "    return false;";
> +}
> +for (i = 0; i < n_target_val; i++) {
> +	name = var_target_val[i]
> +	print "  if (ptr1->" name" != ptr2->" name ")";
> +	print "    return false;";
> +}
> +
> +print "  return true;";
> +
> +print "}";
> +
> +print "";
> +print "/* Hash target options  */";
> +print "hashval_t";
> +print "cl_target_option_hash (struct cl_target_option const *ptr ATTRIBUTE_UNUSED)";
> +print "{";
> +print "  inchash::hash hstate;";
> +for (i = 0; i < n_target_str; i++) {
> +	name = var_target_str[i]
> +	print "  if (ptr->" name")";
> +	print "    hstate.add (ptr->" name", strlen (ptr->" name"));";
> +	print "  else";
> +	print "    hstate.add_int (0);";
> +}
> +for (i = 0; i < n_target_val; i++) {
> +	name = var_target_val[i]
> +	print "  hstate.add_wide_int (ptr->" name");";
> +}
> +print "  return hstate.end ();";
> +print "}";
> +
> +print "";
> +print "/* Stream out target options  */";
> +print "void";
> +print "cl_target_option_stream_out (struct output_block *ob ATTRIBUTE_UNUSED,";
> +print "                             struct bitpack_d *bp ATTRIBUTE_UNUSED,";
> +print "                             struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
> +print "{";
> +for (i = 0; i < n_target_str; i++) {
> +	name = var_target_str[i]
> +	print "  bp_pack_string (ob, bp, ptr->" name", true);";
> +}
> +for (i = 0; i < n_target_val; i++) {
> +	name = var_target_val[i]
> +	print "  bp_pack_value (bp, ptr->" name", 64);";
> +}
> +print "}";
> +
> +print "";
> +print "/* Stream in target options  */";
> +print "void";
> +print "cl_target_option_stream_in (struct data_in *data_in ATTRIBUTE_UNUSED,";
> +print "                            struct bitpack_d *bp ATTRIBUTE_UNUSED,";
> +print "                            struct cl_target_option *ptr ATTRIBUTE_UNUSED)";
> +print "{";
> +for (i = 0; i < n_target_str; i++) {
> +	name = var_target_str[i]
> +	print "  ptr->" name" = bp_unpack_string (data_in, bp);";
> +	print "  if (ptr->" name")";
> +	print "    ptr->" name" = xstrdup (ptr->" name");";
> +}
> +for (i = 0; i < n_target_val; i++) {
> +	name = var_target_val[i]
> +	print "  ptr->" name" = (" var_target_val_type[i] ") bp_unpack_value (bp, 64);";
> +}
> +
> +print "}";
> +
> +}
> Index: opth-gen.awk
> ===================================================================
> --- opth-gen.awk	(revision 217513)
> +++ opth-gen.awk	(working copy)
> @@ -293,6 +293,12 @@
>  print "/* Print target option variables from a structure.  */";
>  print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);";
>  print "";
> +print "/* Compare two target option variables from a structure.  */";
> +print "extern bool cl_target_option_eq (const struct cl_target_option *, const struct cl_target_option *);";
> +print "";
> +print "/* Hash option variables from a structure.  */";
> +print "extern hashval_t cl_target_option_hash (const struct cl_target_option *);";
> +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 217513)
> +++ tree-streamer-in.c	(working copy)
> @@ -506,9 +506,6 @@
>    if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
>      unpack_ts_translation_unit_decl_value_fields (data_in, bp, expr);
>  
> -  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> -    gcc_unreachable ();
> -
>    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
>      unpack_ts_optimization (bp, expr);
>  
> @@ -526,6 +523,9 @@
>  	vec_safe_grow (CONSTRUCTOR_ELTS (expr), length);
>      }
>  
> +  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> +    cl_target_option_stream_in (data_in, bp, TREE_TARGET_OPTION (expr));
> +
>    if (code == OMP_CLAUSE)
>      unpack_ts_omp_clause_value_fields (data_in, bp, expr);
>  }
> Index: tree-streamer-out.c
> ===================================================================
> --- tree-streamer-out.c	(revision 217513)
> +++ tree-streamer-out.c	(working copy)
> @@ -472,9 +472,6 @@
>    if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
>      pack_ts_translation_unit_decl_value_fields (ob, bp, expr);
>  
> -  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> -    gcc_unreachable ();
> -
>    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
>      pack_ts_optimization (bp, expr);
>  
> @@ -484,6 +481,9 @@
>    if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
>      bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr));
>  
> +  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> +    cl_target_option_stream_out (ob, bp, TREE_TARGET_OPTION (expr));
> +
>    if (code == OMP_CLAUSE)
>      pack_ts_omp_clause_value_fields (ob, bp, expr);
>  }
> Index: tree.c
> ===================================================================
> --- tree.c	(revision 217513)
> +++ tree.c	(working copy)
> @@ -11486,10 +11486,7 @@
>      }
>  
>    else if (TREE_CODE (t) == TARGET_OPTION_NODE)
> -    {
> -      p = (const char *)TREE_TARGET_OPTION (t);
> -      len = sizeof (struct cl_target_option);
> -    }
> +    return cl_target_option_hash (TREE_TARGET_OPTION (t));
>  
>    else
>      gcc_unreachable ();
> @@ -11528,9 +11525,8 @@
>  
>    else if (TREE_CODE (xt) == TARGET_OPTION_NODE)
>      {
> -      xp = (const char *)TREE_TARGET_OPTION (xt);
> -      yp = (const char *)TREE_TARGET_OPTION (yt);
> -      len = sizeof (struct cl_target_option);
> +      return cl_target_option_eq (TREE_TARGET_OPTION (xt),
> +				  TREE_TARGET_OPTION (yt));
>      }
>  
>    else
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendoerffer, HRB 21284
(AG Nuernberg)
Maxfeldstrasse 5, 90409 Nuernberg, Germany

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [BUILDROBOT] error: ‘cl_target_option_stream_in’ was not declared in this scope (was: LTO streaming of TARGET_OPTIMIZE_NODE)
  2014-11-14  0:54     ` Jan Hubicka
  2014-11-14  8:54       ` Richard Biener
@ 2014-11-14 18:15       ` Jan-Benedict Glaw
  2014-11-14 19:13         ` [BUILDROBOT] error: �??cl_target_option_stream_in�?? " Jan Hubicka
  1 sibling, 1 reply; 19+ messages in thread
From: Jan-Benedict Glaw @ 2014-11-14 18:15 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Biener, gcc-patches, Joseph S. Myers

[-- Attachment #1: Type: text/plain, Size: 2695 bytes --]

On Fri, 2014-11-14 01:37:14 +0100, Jan Hubicka <hubicka@ucw.cz> wrote:
> Hi,
> here is upated version with bitfields and also tested on PPC64-linux/aix.
> I hacked configury to use system awk instead of gawk, so the changes are hopefully safe.
> 
> OK?
> Honza
> 
> 	* 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.

Breaks build:

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 tree-streamer-in.o -MT tree-streamer-in.o -MMD -MP -MF ./.deps/tree-streamer-in.TPo /home/jbglaw/repos/gcc/gcc/tree-streamer-in.c
/home/jbglaw/repos/gcc/gcc/tree-streamer-in.c: In function ‘void unpack_value_fields(data_in*, bitpack_d*, tree)’:
/home/jbglaw/repos/gcc/gcc/tree-streamer-in.c:527:180: error: ‘cl_target_option_stream_in’ was not declared in this scope
make[1]: *** [tree-streamer-in.o] Error 1


See eg. these builds:

http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=376049
http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=376050
http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=376051

MfG, JBG

-- 
      Jan-Benedict Glaw      jbglaw@lug-owl.de              +49-172-7608481
Signature of:              What we do for ourselves dies with us. What we do for
the second  :         others and the world remains and is immortal. (Albert Pine)

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [BUILDROBOT] error: �??cl_target_option_stream_in�?? was not declared in this scope (was: LTO streaming of TARGET_OPTIMIZE_NODE)
  2014-11-14 18:15       ` [BUILDROBOT] error: ‘cl_target_option_stream_in’ was not declared in this scope (was: LTO streaming of TARGET_OPTIMIZE_NODE) Jan-Benedict Glaw
@ 2014-11-14 19:13         ` Jan Hubicka
  2014-11-15 17:07           ` Jan-Benedict Glaw
  0 siblings, 1 reply; 19+ messages in thread
From: Jan Hubicka @ 2014-11-14 19:13 UTC (permalink / raw)
  To: Jan-Benedict Glaw
  Cc: Jan Hubicka, Richard Biener, gcc-patches, Joseph S. Myers

> 
> Breaks build:
> 
> 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 tree-streamer-in.o -MT tree-streamer-in.o -MMD -MP -MF ./.deps/tree-streamer-in.TPo /home/jbglaw/repos/gcc/gcc/tree-streamer-in.c
> /home/jbglaw/repos/gcc/gcc/tree-streamer-in.c: In function ‘void unpack_value_fields(data_in*, bitpack_d*, tree)’:
> /home/jbglaw/repos/gcc/gcc/tree-streamer-in.c:527:180: error: ‘cl_target_option_stream_in’ was not declared in this scope
> make[1]: *** [tree-streamer-in.o] Error 1
> 
> 
> See eg. these builds:
> 
> http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=376049
> http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=376050
> http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=376051

I managed to do a partial commit (mistyping lto-streamer.h). It should be fixed by the followup commit
a minute later.  Does it works for you now?

Honza
> 
> MfG, JBG
> 
> -- 
>       Jan-Benedict Glaw      jbglaw@lug-owl.de              +49-172-7608481
> Signature of:              What we do for ourselves dies with us. What we do for
> the second  :         others and the world remains and is immortal. (Albert Pine)


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [BUILDROBOT] error: �??cl_target_option_stream_in�?? was not declared in this scope (was: LTO streaming of TARGET_OPTIMIZE_NODE)
  2014-11-14 19:13         ` [BUILDROBOT] error: �??cl_target_option_stream_in�?? " Jan Hubicka
@ 2014-11-15 17:07           ` Jan-Benedict Glaw
  0 siblings, 0 replies; 19+ messages in thread
From: Jan-Benedict Glaw @ 2014-11-15 17:07 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Biener, gcc-patches, Joseph S. Myers

[-- Attachment #1: Type: text/plain, Size: 1854 bytes --]

On Fri, 2014-11-14 19:53:33 +0100, Jan Hubicka <hubicka@ucw.cz> wrote:
> > Breaks build:
> > 
> > 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 tree-streamer-in.o -MT tree-streamer-in.o -MMD -MP -MF ./.deps/tree-streamer-in.TPo /home/jbglaw/repos/gcc/gcc/tree-streamer-in.c
> > /home/jbglaw/repos/gcc/gcc/tree-streamer-in.c: In function ‘void unpack_value_fields(data_in*, bitpack_d*, tree)’:
> > /home/jbglaw/repos/gcc/gcc/tree-streamer-in.c:527:180: error: ‘cl_target_option_stream_in’ was not declared in this scope
> > make[1]: *** [tree-streamer-in.o] Error 1
> > 
> > 
> > See eg. these builds:
> > 
> > http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=376049
> > http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=376050
> > http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=376051
> 
> I managed to do a partial commit (mistyping lto-streamer.h). It should be fixed by the followup commit
> a minute later.  Does it works for you now?

Looks good. Thanks!

MfG, JBG

-- 
      Jan-Benedict Glaw      jbglaw@lug-owl.de              +49-172-7608481
Signature of: They that give up essential liberty to obtain temporary safety,
the second  : deserve neither liberty nor safety.  (Ben Franklin)

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2014-11-13  5:10 LTO streaming of TARGET_OPTIMIZE_NODE Jan Hubicka
  2014-11-13 10:58 ` Richard Biener
@ 2014-11-20 13:09 ` Bernd Schmidt
  2014-11-20 13:38   ` Richard Biener
  2015-01-08 14:12   ` Jakub Jelinek
  1 sibling, 2 replies; 19+ messages in thread
From: Bernd Schmidt @ 2014-11-20 13:09 UTC (permalink / raw)
  To: Jan Hubicka, gcc-patches, rguenther, neil, joseph,
	Thomas Schwinge, Julian Brown, Cesar Philippidis

[-- Attachment #1: Type: text/plain, Size: 407 bytes --]

On 11/13/2014 05:06 AM, Jan Hubicka wrote:
> this patch adds infrastructure for proper streaming and merging of
> TREE_TARGET_OPTION.

This breaks the offloading path via LTO since it introduces an 
incompatibility in LTO format between host and offload machine.

A very quick patch to fix it is below - the OpenACC testcase I was using 
seems to be working again with this. Thoughts, suggestions?


Bernd


[-- Attachment #2: no-opts.diff --]
[-- Type: text/x-patch, Size: 3717 bytes --]

diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index be041e9..3c4b8c9 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -65,7 +65,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "streamer-hooks.h"
 #include "cfgloop.h"
 #include "builtins.h"
-
+#include "lto-section-names.h"
 
 static void lto_write_tree (struct output_block*, tree, bool);
 
@@ -944,7 +944,9 @@ hash_tree (struct streamer_tree_cache_d *cache, hash_map<tree, hashval_t> *map,
     hstate.add (TRANSLATION_UNIT_LANGUAGE (t),
 			strlen (TRANSLATION_UNIT_LANGUAGE (t)));
 
-  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
+  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)
+      /* We don't stream these when passing things to a different target.  */
+      && strcmp (section_name_prefix, LTO_SECTION_NAME_PREFIX) == 0)
     hstate.add_wide_int (cl_target_option_hash (TREE_TARGET_OPTION (t)));
 
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
index a2a2382..88d36d3 100644
--- a/gcc/tree-streamer-in.c
+++ b/gcc/tree-streamer-in.c
@@ -514,8 +514,10 @@ unpack_value_fields (struct data_in *data_in, struct bitpack_d *bp, tree expr)
 	vec_safe_grow (CONSTRUCTOR_ELTS (expr), length);
     }
 
+#ifndef ACCEL_COMPILER
   if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
     cl_target_option_stream_in (data_in, bp, TREE_TARGET_OPTION (expr));
+#endif
 
   if (code == OMP_CLAUSE)
     unpack_ts_omp_clause_value_fields (data_in, bp, expr);
@@ -779,7 +781,9 @@ lto_input_ts_function_decl_tree_pointers (struct lto_input_block *ib,
   DECL_VINDEX (expr) = stream_read_tree (ib, data_in);
   /* DECL_STRUCT_FUNCTION is loaded on demand by cgraph_get_body.  */
   DECL_FUNCTION_PERSONALITY (expr) = stream_read_tree (ib, data_in);
+#ifndef ACCEL_COMPILER
   DECL_FUNCTION_SPECIFIC_TARGET (expr) = stream_read_tree (ib, data_in);
+#endif
   DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = stream_read_tree (ib, data_in);
 
   /* If the file contains a function with an EH personality set,
diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c
index b959454..fca101e 100644
--- a/gcc/tree-streamer-out.c
+++ b/gcc/tree-streamer-out.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-streamer.h"
 #include "data-streamer.h"
 #include "streamer-hooks.h"
+#include "lto-section-names.h"
 
 /* Output the STRING constant to the string
    table in OB.  Then put the index onto the INDEX_STREAM.  */
@@ -463,7 +464,9 @@ streamer_pack_tree_bitfields (struct output_block *ob,
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
     bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr));
 
-  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
+  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)
+      /* Don't stream these when passing things to a different target.  */
+      && strcmp (section_name_prefix, LTO_SECTION_NAME_PREFIX) == 0)
     cl_target_option_stream_out (ob, bp, TREE_TARGET_OPTION (expr));
 
   if (code == OMP_CLAUSE)
@@ -678,7 +681,9 @@ write_ts_function_decl_tree_pointers (struct output_block *ob, tree expr,
   stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
   /* DECL_STRUCT_FUNCTION is handled by lto_output_function.  */
   stream_write_tree (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
-  stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
+  /* Don't stream these when passing things to a different target.  */
+  if (strcmp (section_name_prefix, LTO_SECTION_NAME_PREFIX) == 0)
+    stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
   stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), ref_p);
 }
 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2014-11-20 13:09 ` LTO streaming of TARGET_OPTIMIZE_NODE Bernd Schmidt
@ 2014-11-20 13:38   ` Richard Biener
  2014-11-20 14:24     ` Bernd Schmidt
  2015-01-08 14:12   ` Jakub Jelinek
  1 sibling, 1 reply; 19+ messages in thread
From: Richard Biener @ 2014-11-20 13:38 UTC (permalink / raw)
  To: Bernd Schmidt
  Cc: Jan Hubicka, gcc-patches, Joseph S. Myers, Thomas Schwinge,
	Julian Brown, Cesar Philippidis

On Thu, 20 Nov 2014, Bernd Schmidt wrote:

> On 11/13/2014 05:06 AM, Jan Hubicka wrote:
> > this patch adds infrastructure for proper streaming and merging of
> > TREE_TARGET_OPTION.
> 
> This breaks the offloading path via LTO since it introduces an incompatibility
> in LTO format between host and offload machine.
> 
> A very quick patch to fix it is below - the OpenACC testcase I was using seems
> to be working again with this. Thoughts, suggestions?

The offload target needs to have the same target options as the host?

Are the offload functions marked somehow?  That is, can we avoid
setting TREE_TARGET_OPTION on them?  Or rather we need to have a
default TREE_TARGET_OPTION node for the offload target which we'd
need to set - how would you otherwise transfer different offload
target options to the offload compile?  How do you transfer
offload target options to the offload compile at all?

I think this just shows conceptual issues with the LTO approach...

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2014-11-20 13:38   ` Richard Biener
@ 2014-11-20 14:24     ` Bernd Schmidt
  2014-11-20 21:51       ` Jan Hubicka
  0 siblings, 1 reply; 19+ messages in thread
From: Bernd Schmidt @ 2014-11-20 14:24 UTC (permalink / raw)
  To: Richard Biener
  Cc: Jan Hubicka, gcc-patches, Joseph S. Myers, Thomas Schwinge,
	Julian Brown, Cesar Philippidis

On 11/20/2014 02:20 PM, Richard Biener wrote:
> On Thu, 20 Nov 2014, Bernd Schmidt wrote:
>
>> On 11/13/2014 05:06 AM, Jan Hubicka wrote:
>>> this patch adds infrastructure for proper streaming and merging of
>>> TREE_TARGET_OPTION.
>>
>> This breaks the offloading path via LTO since it introduces an incompatibility
>> in LTO format between host and offload machine.
>>
>> A very quick patch to fix it is below - the OpenACC testcase I was using seems
>> to be working again with this. Thoughts, suggestions?
>
> The offload target needs to have the same target options as the host?

Not really meaningful I'd think.

> Are the offload functions marked somehow?  That is, can we avoid
> setting TREE_TARGET_OPTION on them?

Well, they are mostly generated automatically by omp-low.c, so 
TREE_TARGET_OPTION wouldn't normally be set anyway. So the field is 
unnecessary, we just can't write it out since the two compilers involved 
disagree on its layout.

> Or rather we need to have a
> default TREE_TARGET_OPTION node for the offload target which we'd
> need to set - how would you otherwise transfer different offload
> target options to the offload compile?  How do you transfer
> offload target options to the offload compile at all?

ABI options are transferred via the -foffload-abi mechanism. No other 
target options can be transferred.

> I think this just shows conceptual issues with the LTO approach...

I don't think running into a few problems demonstrates a conceptual 
problem when it works fine with some fairly small patches.


Bernd

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2014-11-20 14:24     ` Bernd Schmidt
@ 2014-11-20 21:51       ` Jan Hubicka
  0 siblings, 0 replies; 19+ messages in thread
From: Jan Hubicka @ 2014-11-20 21:51 UTC (permalink / raw)
  To: Bernd Schmidt
  Cc: Richard Biener, Jan Hubicka, gcc-patches, Joseph S. Myers,
	Thomas Schwinge, Julian Brown, Cesar Philippidis

> On 11/20/2014 02:20 PM, Richard Biener wrote:
> >On Thu, 20 Nov 2014, Bernd Schmidt wrote:
> >
> >>On 11/13/2014 05:06 AM, Jan Hubicka wrote:
> >>>this patch adds infrastructure for proper streaming and merging of
> >>>TREE_TARGET_OPTION.
> >>
> >>This breaks the offloading path via LTO since it introduces an incompatibility
> >>in LTO format between host and offload machine.
> >>
> >>A very quick patch to fix it is below - the OpenACC testcase I was using seems
> >>to be working again with this. Thoughts, suggestions?
> >
> >The offload target needs to have the same target options as the host?
> 
> Not really meaningful I'd think.
> 
> >Are the offload functions marked somehow?  That is, can we avoid
> >setting TREE_TARGET_OPTION on them?
> 
> Well, they are mostly generated automatically by omp-low.c, so
> TREE_TARGET_OPTION wouldn't normally be set anyway. So the field is
> unnecessary, we just can't write it out since the two compilers
> involved disagree on its layout.

I am currently populating TREE_TARGET_OPTION in free lang data that is probably
called after omp-low and incrementally I plan to set it even for newly constructed
functions (profiling, ctors etc.) that are built during IPA, so we do not really need
to rely on sane global state at link time.
This however has nothing to do with offloading.

Honza

> 
> >Or rather we need to have a
> >default TREE_TARGET_OPTION node for the offload target which we'd
> >need to set - how would you otherwise transfer different offload
> >target options to the offload compile?  How do you transfer
> >offload target options to the offload compile at all?
> 
> ABI options are transferred via the -foffload-abi mechanism. No
> other target options can be transferred.
> 
> >I think this just shows conceptual issues with the LTO approach...
> 
> I don't think running into a few problems demonstrates a conceptual
> problem when it works fine with some fairly small patches.
> 
> 
> Bernd

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2014-11-20 13:09 ` LTO streaming of TARGET_OPTIMIZE_NODE Bernd Schmidt
  2014-11-20 13:38   ` Richard Biener
@ 2015-01-08 14:12   ` Jakub Jelinek
  2015-01-09 11:13     ` Thomas Schwinge
  1 sibling, 1 reply; 19+ messages in thread
From: Jakub Jelinek @ 2015-01-08 14:12 UTC (permalink / raw)
  To: Bernd Schmidt, Richard Biener, Jan Hubicka
  Cc: gcc-patches, neil, joseph, Thomas Schwinge, Julian Brown,
	Cesar Philippidis

On Thu, Nov 20, 2014 at 01:27:08PM +0100, Bernd Schmidt wrote:
> On 11/13/2014 05:06 AM, Jan Hubicka wrote:
> >this patch adds infrastructure for proper streaming and merging of
> >TREE_TARGET_OPTION.
> 
> This breaks the offloading path via LTO since it introduces an
> incompatibility in LTO format between host and offload machine.
> 
> A very quick patch to fix it is below - the OpenACC testcase I was using
> seems to be working again with this. Thoughts, suggestions?

I actually think this patch makes a lot of sense.  Target option nodes
by definition are target specific, generally there is no mapping between
host and offloading target features.  So, the host target options
are not useful to the offloading target.  And, because the amount of bits
streamed is also target specific, say x86_64 will have different and
incompatible cl_target_option_stream_{out,in} from nvptx, and even
for Intel MIC offloading it doesn't make much sense, what CPU is certain
function targetting doesn't necessarily have any relation to the Intel MIC
that will offload it.

I agree the strcmp (section_name_prefix, LTO_SECTION_NAME_PREFIX) == 0
checks in the patch aren't very nice, that could be replaced by
some bool flag alongside of section_name_prefix that would be set
where section_name_prefix is set:
cgraphunit.c:	  section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
cgraphunit.c:	  section_name_prefix = LTO_SECTION_NAME_PREFIX;
lto-streamer.c:const char *section_name_prefix = LTO_SECTION_NAME_PREFIX;
lto/lto.c:    section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;

(call it say bool lto_stream_offload_p ?).

Also note that the patch fixes all the current regressions in Intel MIC
(emulated) offloading caused by the r218767

	Jakub

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2015-01-08 14:12   ` Jakub Jelinek
@ 2015-01-09 11:13     ` Thomas Schwinge
  2015-01-09 11:50       ` Jakub Jelinek
  0 siblings, 1 reply; 19+ messages in thread
From: Thomas Schwinge @ 2015-01-09 11:13 UTC (permalink / raw)
  To: Jakub Jelinek, Bernd Schmidt, Bernd Schmidt, Richard Biener, Jan Hubicka
  Cc: gcc-patches, neil, joseph, Julian Brown, Cesar Philippidis,
	iverbin, kirill.yukhin, andrey.turetskiy

[-- Attachment #1: Type: text/plain, Size: 1769 bytes --]

Hi!

On Thu, 8 Jan 2015 15:11:49 +0100, Jakub Jelinek <jakub@redhat.com> wrote:
> On Thu, Nov 20, 2014 at 01:27:08PM +0100, Bernd Schmidt wrote:
> > On 11/13/2014 05:06 AM, Jan Hubicka wrote:
> > >this patch adds infrastructure for proper streaming and merging of
> > >TREE_TARGET_OPTION.
> > 
> > This breaks the offloading path via LTO since it introduces an
> > incompatibility in LTO format between host and offload machine.
> > 
> > A very quick patch to fix it is below - the OpenACC testcase I was using
> > seems to be working again with this. Thoughts, suggestions?
> 
> I actually think

Thanks for picking up this issue!

> this patch makes a lot of sense.  Target option nodes
> by definition are target specific, generally there is no mapping between
> host and offloading target features.  So, the host target options
> are not useful to the offloading target.  And, because the amount of bits
> streamed is also target specific, say x86_64 will have different and
> incompatible cl_target_option_stream_{out,in} from nvptx, and even
> for Intel MIC offloading it doesn't make much sense, what CPU is certain
> function targetting doesn't necessarily have any relation to the Intel MIC
> that will offload it.

> Also note that the patch fixes all the current regressions in Intel MIC
> (emulated) offloading caused by the r218767

(Which has been filed as <https://gcc.gnu.org/PR64412>, by the way.)

I'm confirming that Bernd's patch resolves the intelmic offloading
regressions, but I still do see issues in all nvptx offloading, but
cannot tell yet what's going on.  (Reverting Honza's patch resolves
these; but maybe it's something that is solely an issue with the nvptx
offloading path.)


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2015-01-09 11:13     ` Thomas Schwinge
@ 2015-01-09 11:50       ` Jakub Jelinek
  2015-01-09 12:12         ` Richard Biener
                           ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Jakub Jelinek @ 2015-01-09 11:50 UTC (permalink / raw)
  To: Thomas Schwinge
  Cc: Bernd Schmidt, Bernd Schmidt, Richard Biener, Jan Hubicka,
	gcc-patches, neil, joseph, Julian Brown, Cesar Philippidis,
	iverbin, kirill.yukhin, andrey.turetskiy

On Fri, Jan 09, 2015 at 12:07:26PM +0100, Thomas Schwinge wrote:
> On Thu, 8 Jan 2015 15:11:49 +0100, Jakub Jelinek <jakub@redhat.com> wrote:
> > On Thu, Nov 20, 2014 at 01:27:08PM +0100, Bernd Schmidt wrote:
> > > On 11/13/2014 05:06 AM, Jan Hubicka wrote:
> > > >this patch adds infrastructure for proper streaming and merging of
> > > >TREE_TARGET_OPTION.
> > > 
> > > This breaks the offloading path via LTO since it introduces an
> > > incompatibility in LTO format between host and offload machine.
> > > 
> > > A very quick patch to fix it is below - the OpenACC testcase I was using
> > > seems to be working again with this. Thoughts, suggestions?
> > 
> > I actually think
> 
> Thanks for picking up this issue!

Richard said on IRC he doesn't like the string comparisons, so here is
untested modification of the patch.  If it looks good, I'll test it today:

2015-01-09  Bernd Schmidt  <bernds@codesourcery.com>
	    Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/64412
	* lto-streamer.h (lto_stream_offload_p): New declaration.
	* lto-streamer.c (lto_stream_offload_p): New variable.
	* cgraphunit.c (ipa_passes): Set lto_stream_offload_p
	at the same time as section_name_prefix.
	* lto-streamer-out.c (hash_tree): Don't hash TREE_TARGET_OPTION
	if lto_stream_offload_p.
	* tree-streamer-out.c (streamer_pack_tree_bitfields): Don't
	stream TREE_TARGET_OPTION if lto_stream_offload_p.
	(write_ts_function_decl_tree_pointers): Don't
	stream DECL_FUNCTION_SPECIFIC_TARGET if lto_stream_offload_p.
	* tree-streamer-in.c (unpack_value_fields): Don't stream
	TREE_TARGET_OPTION in if ACCEL_COMPILER.
	(lto_input_ts_function_decl_tree_pointers): Don't stream
	DECL_FUNCTION_SPECIFIC_TARGET in if ACCEL_COMPILER.
	* lto-opts.c (lto_write_options): Use lto_stream_offload_p
	instead of section_name_prefix string comparisons.
lto/
	* lto.c (read_cgraph_and_symbols): Set lto_stream_offload_p
	if ACCEL_COMPILER.

--- gcc/lto-streamer.h.jj	2015-01-05 13:07:13.000000000 +0100
+++ gcc/lto-streamer.h	2015-01-09 12:18:26.199842482 +0100
@@ -744,6 +744,10 @@ extern void lto_append_block (struct lto
 
 
 /* In lto-streamer.c.  */
+
+/* Set when streaming LTO for offloading compiler.  */
+extern bool lto_stream_offload_p;
+
 extern const char *lto_tag_name (enum LTO_tags);
 extern bitmap lto_bitmap_alloc (void);
 extern void lto_bitmap_free (bitmap);
--- gcc/lto-streamer.c.jj	2015-01-05 13:07:13.000000000 +0100
+++ gcc/lto-streamer.c	2015-01-09 12:16:04.909269917 +0100
@@ -61,6 +61,8 @@ static bitmap_obstack lto_obstack;
 static bool lto_obstack_initialized;
 
 const char *section_name_prefix = LTO_SECTION_NAME_PREFIX;
+/* Set when streaming LTO for offloading compiler.  */
+bool lto_stream_offload_p;
 
 /* Return a string representing LTO tag TAG.  */
 
--- gcc/cgraphunit.c.jj	2015-01-09 12:01:33.000000000 +0100
+++ gcc/cgraphunit.c	2015-01-09 12:22:27.742692667 +0100
@@ -2108,11 +2108,14 @@ ipa_passes (void)
       if (g->have_offload)
 	{
 	  section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
+	  lto_stream_offload_p = true;
 	  ipa_write_summaries (true);
+	  lto_stream_offload_p = false;
 	}
       if (flag_lto)
 	{
 	  section_name_prefix = LTO_SECTION_NAME_PREFIX;
+	  lto_stream_offload_p = false;
 	  ipa_write_summaries (false);
 	}
     }
--- gcc/lto-streamer-out.c.jj	2015-01-08 18:10:23.633598629 +0100
+++ gcc/lto-streamer-out.c	2015-01-09 12:14:41.017711211 +0100
@@ -944,7 +944,9 @@ hash_tree (struct streamer_tree_cache_d
     hstate.add (TRANSLATION_UNIT_LANGUAGE (t),
 			strlen (TRANSLATION_UNIT_LANGUAGE (t)));
 
-  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
+  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)
+      /* We don't stream these when passing things to a different target.  */
+      && !lto_stream_offload_p)
     hstate.add_wide_int (cl_target_option_hash (TREE_TARGET_OPTION (t)));
 
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
--- gcc/tree-streamer-out.c.jj	2015-01-08 18:10:23.631598663 +0100
+++ gcc/tree-streamer-out.c	2015-01-09 12:14:41.018711194 +0100
@@ -472,7 +472,9 @@ streamer_pack_tree_bitfields (struct out
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
     bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr));
 
-  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
+  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)
+      /* Don't stream these when passing things to a different target.  */
+      && !lto_stream_offload_p)
     cl_target_option_stream_out (ob, bp, TREE_TARGET_OPTION (expr));
 
   if (code == OMP_CLAUSE)
@@ -687,7 +689,9 @@ write_ts_function_decl_tree_pointers (st
   stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
   /* DECL_STRUCT_FUNCTION is handled by lto_output_function.  */
   stream_write_tree (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
-  stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
+  /* Don't stream these when passing things to a different target.  */
+  if (!lto_stream_offload_p)
+    stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
   stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), ref_p);
 }
 
--- gcc/tree-streamer-in.c.jj	2015-01-08 18:10:23.561599843 +0100
+++ gcc/tree-streamer-in.c	2015-01-09 12:14:41.017711211 +0100
@@ -520,8 +520,10 @@ unpack_value_fields (struct data_in *dat
 	vec_safe_grow (CONSTRUCTOR_ELTS (expr), length);
     }
 
+#ifndef ACCEL_COMPILER
   if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
     cl_target_option_stream_in (data_in, bp, TREE_TARGET_OPTION (expr));
+#endif
 
   if (code == OMP_CLAUSE)
     unpack_ts_omp_clause_value_fields (data_in, bp, expr);
@@ -785,7 +787,9 @@ lto_input_ts_function_decl_tree_pointers
   DECL_VINDEX (expr) = stream_read_tree (ib, data_in);
   /* DECL_STRUCT_FUNCTION is loaded on demand by cgraph_get_body.  */
   DECL_FUNCTION_PERSONALITY (expr) = stream_read_tree (ib, data_in);
+#ifndef ACCEL_COMPILER
   DECL_FUNCTION_SPECIFIC_TARGET (expr) = stream_read_tree (ib, data_in);
+#endif
   DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = stream_read_tree (ib, data_in);
 
   /* If the file contains a function with an EH personality set,
--- gcc/lto-opts.c.jj	2015-01-05 13:07:12.000000000 +0100
+++ gcc/lto-opts.c	2015-01-09 12:21:04.203127914 +0100
@@ -160,7 +160,7 @@ lto_write_options (void)
 			       "-fno-strict-overflow");
 
   /* Append options from target hook and store them to offload_lto section.  */
-  if (strcmp (section_name_prefix, OFFLOAD_SECTION_NAME_PREFIX) == 0)
+  if (lto_stream_offload_p)
     {
       char *offload_opts = targetm.offload_options ();
       char *offload_ptr = offload_opts;
@@ -201,7 +201,7 @@ lto_write_options (void)
 
       /* Do not store target-specific options in offload_lto section.  */
       if ((cl_options[option->opt_index].flags & CL_TARGET)
-	 && strcmp (section_name_prefix, OFFLOAD_SECTION_NAME_PREFIX) == 0)
+	  && lto_stream_offload_p)
        continue;
 
       /* Drop options created from the gcc driver that will be rejected
@@ -214,8 +214,7 @@ lto_write_options (void)
 	 We do not need those.  The only exception is -foffload option, if we
 	 write it in offload_lto section.  Also drop all diagnostic options.  */
       if ((cl_options[option->opt_index].flags & (CL_DRIVER|CL_WARNING))
-	  && (strcmp (section_name_prefix, OFFLOAD_SECTION_NAME_PREFIX) != 0
-	      || option->opt_index != OPT_foffload_))
+	  && (!lto_stream_offload_p || option->opt_index != OPT_foffload_))
 	continue;
 
       for (j = 0; j < option->canonical_option_num_elements; ++j)
--- gcc/lto/lto.c.jj	2015-01-05 13:07:19.000000000 +0100
+++ gcc/lto/lto.c	2015-01-09 12:21:50.479332868 +0100
@@ -2900,7 +2900,8 @@ read_cgraph_and_symbols (unsigned nfiles
   timevar_push (TV_IPA_LTO_DECL_IN);
 
 #ifdef ACCEL_COMPILER
-    section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
+  section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
+  lto_stream_offload_p = true;
 #endif
 
   real_file_decl_data

	Jakub

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2015-01-09 11:50       ` Jakub Jelinek
@ 2015-01-09 12:12         ` Richard Biener
  2015-01-11 17:38         ` Jan Hubicka
  2015-01-11 21:28         ` Ilya Verbin
  2 siblings, 0 replies; 19+ messages in thread
From: Richard Biener @ 2015-01-09 12:12 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: Thomas Schwinge, Bernd Schmidt, Bernd Schmidt, Jan Hubicka,
	gcc-patches, neil, joseph, Julian Brown, Cesar Philippidis,
	iverbin, kirill.yukhin, andrey.turetskiy

On Fri, 9 Jan 2015, Jakub Jelinek wrote:

> On Fri, Jan 09, 2015 at 12:07:26PM +0100, Thomas Schwinge wrote:
> > On Thu, 8 Jan 2015 15:11:49 +0100, Jakub Jelinek <jakub@redhat.com> wrote:
> > > On Thu, Nov 20, 2014 at 01:27:08PM +0100, Bernd Schmidt wrote:
> > > > On 11/13/2014 05:06 AM, Jan Hubicka wrote:
> > > > >this patch adds infrastructure for proper streaming and merging of
> > > > >TREE_TARGET_OPTION.
> > > > 
> > > > This breaks the offloading path via LTO since it introduces an
> > > > incompatibility in LTO format between host and offload machine.
> > > > 
> > > > A very quick patch to fix it is below - the OpenACC testcase I was using
> > > > seems to be working again with this. Thoughts, suggestions?
> > > 
> > > I actually think
> > 
> > Thanks for picking up this issue!
> 
> Richard said on IRC he doesn't like the string comparisons, so here is
> untested modification of the patch.  If it looks good, I'll test it today:

Looks good to me.

Richard.

> 2015-01-09  Bernd Schmidt  <bernds@codesourcery.com>
> 	    Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR middle-end/64412
> 	* lto-streamer.h (lto_stream_offload_p): New declaration.
> 	* lto-streamer.c (lto_stream_offload_p): New variable.
> 	* cgraphunit.c (ipa_passes): Set lto_stream_offload_p
> 	at the same time as section_name_prefix.
> 	* lto-streamer-out.c (hash_tree): Don't hash TREE_TARGET_OPTION
> 	if lto_stream_offload_p.
> 	* tree-streamer-out.c (streamer_pack_tree_bitfields): Don't
> 	stream TREE_TARGET_OPTION if lto_stream_offload_p.
> 	(write_ts_function_decl_tree_pointers): Don't
> 	stream DECL_FUNCTION_SPECIFIC_TARGET if lto_stream_offload_p.
> 	* tree-streamer-in.c (unpack_value_fields): Don't stream
> 	TREE_TARGET_OPTION in if ACCEL_COMPILER.
> 	(lto_input_ts_function_decl_tree_pointers): Don't stream
> 	DECL_FUNCTION_SPECIFIC_TARGET in if ACCEL_COMPILER.
> 	* lto-opts.c (lto_write_options): Use lto_stream_offload_p
> 	instead of section_name_prefix string comparisons.
> lto/
> 	* lto.c (read_cgraph_and_symbols): Set lto_stream_offload_p
> 	if ACCEL_COMPILER.
> 
> --- gcc/lto-streamer.h.jj	2015-01-05 13:07:13.000000000 +0100
> +++ gcc/lto-streamer.h	2015-01-09 12:18:26.199842482 +0100
> @@ -744,6 +744,10 @@ extern void lto_append_block (struct lto
>  
>  
>  /* In lto-streamer.c.  */
> +
> +/* Set when streaming LTO for offloading compiler.  */
> +extern bool lto_stream_offload_p;
> +
>  extern const char *lto_tag_name (enum LTO_tags);
>  extern bitmap lto_bitmap_alloc (void);
>  extern void lto_bitmap_free (bitmap);
> --- gcc/lto-streamer.c.jj	2015-01-05 13:07:13.000000000 +0100
> +++ gcc/lto-streamer.c	2015-01-09 12:16:04.909269917 +0100
> @@ -61,6 +61,8 @@ static bitmap_obstack lto_obstack;
>  static bool lto_obstack_initialized;
>  
>  const char *section_name_prefix = LTO_SECTION_NAME_PREFIX;
> +/* Set when streaming LTO for offloading compiler.  */
> +bool lto_stream_offload_p;
>  
>  /* Return a string representing LTO tag TAG.  */
>  
> --- gcc/cgraphunit.c.jj	2015-01-09 12:01:33.000000000 +0100
> +++ gcc/cgraphunit.c	2015-01-09 12:22:27.742692667 +0100
> @@ -2108,11 +2108,14 @@ ipa_passes (void)
>        if (g->have_offload)
>  	{
>  	  section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
> +	  lto_stream_offload_p = true;
>  	  ipa_write_summaries (true);
> +	  lto_stream_offload_p = false;
>  	}
>        if (flag_lto)
>  	{
>  	  section_name_prefix = LTO_SECTION_NAME_PREFIX;
> +	  lto_stream_offload_p = false;
>  	  ipa_write_summaries (false);
>  	}
>      }
> --- gcc/lto-streamer-out.c.jj	2015-01-08 18:10:23.633598629 +0100
> +++ gcc/lto-streamer-out.c	2015-01-09 12:14:41.017711211 +0100
> @@ -944,7 +944,9 @@ hash_tree (struct streamer_tree_cache_d
>      hstate.add (TRANSLATION_UNIT_LANGUAGE (t),
>  			strlen (TRANSLATION_UNIT_LANGUAGE (t)));
>  
> -  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> +  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)
> +      /* We don't stream these when passing things to a different target.  */
> +      && !lto_stream_offload_p)
>      hstate.add_wide_int (cl_target_option_hash (TREE_TARGET_OPTION (t)));
>  
>    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
> --- gcc/tree-streamer-out.c.jj	2015-01-08 18:10:23.631598663 +0100
> +++ gcc/tree-streamer-out.c	2015-01-09 12:14:41.018711194 +0100
> @@ -472,7 +472,9 @@ streamer_pack_tree_bitfields (struct out
>    if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
>      bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr));
>  
> -  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
> +  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)
> +      /* Don't stream these when passing things to a different target.  */
> +      && !lto_stream_offload_p)
>      cl_target_option_stream_out (ob, bp, TREE_TARGET_OPTION (expr));
>  
>    if (code == OMP_CLAUSE)
> @@ -687,7 +689,9 @@ write_ts_function_decl_tree_pointers (st
>    stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
>    /* DECL_STRUCT_FUNCTION is handled by lto_output_function.  */
>    stream_write_tree (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
> -  stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
> +  /* Don't stream these when passing things to a different target.  */
> +  if (!lto_stream_offload_p)
> +    stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
>    stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), ref_p);
>  }
>  
> --- gcc/tree-streamer-in.c.jj	2015-01-08 18:10:23.561599843 +0100
> +++ gcc/tree-streamer-in.c	2015-01-09 12:14:41.017711211 +0100
> @@ -520,8 +520,10 @@ unpack_value_fields (struct data_in *dat
>  	vec_safe_grow (CONSTRUCTOR_ELTS (expr), length);
>      }
>  
> +#ifndef ACCEL_COMPILER
>    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
>      cl_target_option_stream_in (data_in, bp, TREE_TARGET_OPTION (expr));
> +#endif
>  
>    if (code == OMP_CLAUSE)
>      unpack_ts_omp_clause_value_fields (data_in, bp, expr);
> @@ -785,7 +787,9 @@ lto_input_ts_function_decl_tree_pointers
>    DECL_VINDEX (expr) = stream_read_tree (ib, data_in);
>    /* DECL_STRUCT_FUNCTION is loaded on demand by cgraph_get_body.  */
>    DECL_FUNCTION_PERSONALITY (expr) = stream_read_tree (ib, data_in);
> +#ifndef ACCEL_COMPILER
>    DECL_FUNCTION_SPECIFIC_TARGET (expr) = stream_read_tree (ib, data_in);
> +#endif
>    DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = stream_read_tree (ib, data_in);
>  
>    /* If the file contains a function with an EH personality set,
> --- gcc/lto-opts.c.jj	2015-01-05 13:07:12.000000000 +0100
> +++ gcc/lto-opts.c	2015-01-09 12:21:04.203127914 +0100
> @@ -160,7 +160,7 @@ lto_write_options (void)
>  			       "-fno-strict-overflow");
>  
>    /* Append options from target hook and store them to offload_lto section.  */
> -  if (strcmp (section_name_prefix, OFFLOAD_SECTION_NAME_PREFIX) == 0)
> +  if (lto_stream_offload_p)
>      {
>        char *offload_opts = targetm.offload_options ();
>        char *offload_ptr = offload_opts;
> @@ -201,7 +201,7 @@ lto_write_options (void)
>  
>        /* Do not store target-specific options in offload_lto section.  */
>        if ((cl_options[option->opt_index].flags & CL_TARGET)
> -	 && strcmp (section_name_prefix, OFFLOAD_SECTION_NAME_PREFIX) == 0)
> +	  && lto_stream_offload_p)
>         continue;
>  
>        /* Drop options created from the gcc driver that will be rejected
> @@ -214,8 +214,7 @@ lto_write_options (void)
>  	 We do not need those.  The only exception is -foffload option, if we
>  	 write it in offload_lto section.  Also drop all diagnostic options.  */
>        if ((cl_options[option->opt_index].flags & (CL_DRIVER|CL_WARNING))
> -	  && (strcmp (section_name_prefix, OFFLOAD_SECTION_NAME_PREFIX) != 0
> -	      || option->opt_index != OPT_foffload_))
> +	  && (!lto_stream_offload_p || option->opt_index != OPT_foffload_))
>  	continue;
>  
>        for (j = 0; j < option->canonical_option_num_elements; ++j)
> --- gcc/lto/lto.c.jj	2015-01-05 13:07:19.000000000 +0100
> +++ gcc/lto/lto.c	2015-01-09 12:21:50.479332868 +0100
> @@ -2900,7 +2900,8 @@ read_cgraph_and_symbols (unsigned nfiles
>    timevar_push (TV_IPA_LTO_DECL_IN);
>  
>  #ifdef ACCEL_COMPILER
> -    section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
> +  section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
> +  lto_stream_offload_p = true;
>  #endif
>  
>    real_file_decl_data
> 
> 	Jakub
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild,
Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2015-01-09 11:50       ` Jakub Jelinek
  2015-01-09 12:12         ` Richard Biener
@ 2015-01-11 17:38         ` Jan Hubicka
  2015-01-11 21:28         ` Ilya Verbin
  2 siblings, 0 replies; 19+ messages in thread
From: Jan Hubicka @ 2015-01-11 17:38 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: Thomas Schwinge, Bernd Schmidt, Bernd Schmidt, Richard Biener,
	Jan Hubicka, gcc-patches, neil, joseph, Julian Brown,
	Cesar Philippidis, iverbin, kirill.yukhin, andrey.turetskiy

> On Fri, Jan 09, 2015 at 12:07:26PM +0100, Thomas Schwinge wrote:
> > On Thu, 8 Jan 2015 15:11:49 +0100, Jakub Jelinek <jakub@redhat.com> wrote:
> > > On Thu, Nov 20, 2014 at 01:27:08PM +0100, Bernd Schmidt wrote:
> > > > On 11/13/2014 05:06 AM, Jan Hubicka wrote:
> > > > >this patch adds infrastructure for proper streaming and merging of
> > > > >TREE_TARGET_OPTION.
> > > > 
> > > > This breaks the offloading path via LTO since it introduces an
> > > > incompatibility in LTO format between host and offload machine.
> > > > 
> > > > A very quick patch to fix it is below - the OpenACC testcase I was using
> > > > seems to be working again with this. Thoughts, suggestions?
> > > 
> > > I actually think
> > 
> > Thanks for picking up this issue!
> 
> Richard said on IRC he doesn't like the string comparisons, so here is
> untested modification of the patch.  If it looks good, I'll test it today:
> 
> 2015-01-09  Bernd Schmidt  <bernds@codesourcery.com>
> 	    Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR middle-end/64412
> 	* lto-streamer.h (lto_stream_offload_p): New declaration.
> 	* lto-streamer.c (lto_stream_offload_p): New variable.
> 	* cgraphunit.c (ipa_passes): Set lto_stream_offload_p
> 	at the same time as section_name_prefix.
> 	* lto-streamer-out.c (hash_tree): Don't hash TREE_TARGET_OPTION
> 	if lto_stream_offload_p.
> 	* tree-streamer-out.c (streamer_pack_tree_bitfields): Don't
> 	stream TREE_TARGET_OPTION if lto_stream_offload_p.
> 	(write_ts_function_decl_tree_pointers): Don't
> 	stream DECL_FUNCTION_SPECIFIC_TARGET if lto_stream_offload_p.
> 	* tree-streamer-in.c (unpack_value_fields): Don't stream
> 	TREE_TARGET_OPTION in if ACCEL_COMPILER.
> 	(lto_input_ts_function_decl_tree_pointers): Don't stream
> 	DECL_FUNCTION_SPECIFIC_TARGET in if ACCEL_COMPILER.
> 	* lto-opts.c (lto_write_options): Use lto_stream_offload_p
> 	instead of section_name_prefix string comparisons.
> lto/
> 	* lto.c (read_cgraph_and_symbols): Set lto_stream_offload_p
> 	if ACCEL_COMPILER.

This looks fine to me. Thanks for looking into this issue (that was mine,
but I was quite busy last month)

Honza

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2015-01-09 11:50       ` Jakub Jelinek
  2015-01-09 12:12         ` Richard Biener
  2015-01-11 17:38         ` Jan Hubicka
@ 2015-01-11 21:28         ` Ilya Verbin
  2015-01-12 20:08           ` Jan Hubicka
  2 siblings, 1 reply; 19+ messages in thread
From: Ilya Verbin @ 2015-01-11 21:28 UTC (permalink / raw)
  To: Jakub Jelinek, Richard Biener, Jan Hubicka; +Cc: Kirill Yukhin, gcc-patches

On 09 Jan 12:45, Jakub Jelinek wrote:
> --- gcc/cgraphunit.c.jj	2015-01-09 12:01:33.000000000 +0100
> +++ gcc/cgraphunit.c	2015-01-09 12:22:27.742692667 +0100
> @@ -2108,11 +2108,14 @@ ipa_passes (void)
>        if (g->have_offload)
>  	{
>  	  section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
> +	  lto_stream_offload_p = true;
>  	  ipa_write_summaries (true);
> +	  lto_stream_offload_p = false;
>  	}
>        if (flag_lto)
>  	{
>  	  section_name_prefix = LTO_SECTION_NAME_PREFIX;
> +	  lto_stream_offload_p = false;
>  	  ipa_write_summaries (false);
>  	}

Now when we have a global flag, there is no longer need to pass a flag to
ipa_write_summaries and to select_what_to_stream.

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


gcc/
	* cgraphunit.c (ipa_passes): Remove argument from ipa_write_summaries.
	* lto-cgraph.c (select_what_to_stream): Remove argument, use
	lto_stream_offload_p instead.
	* lto-streamer.h (select_what_to_stream): Remove argument.
	* passes.c (ipa_write_summaries): Likewise.
	* tree-pass.h (ipa_write_summaries): Likewise.
gcc/lto/
	* lto-partition.c (lto_promote_cross_file_statics): Remove argument
	from select_what_to_stream.


diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 149f447..1ef1b6c 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2115,14 +2115,14 @@ ipa_passes (void)
 	{
 	  section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
 	  lto_stream_offload_p = true;
-	  ipa_write_summaries (true);
+	  ipa_write_summaries ();
 	  lto_stream_offload_p = false;
 	}
       if (flag_lto)
 	{
 	  section_name_prefix = LTO_SECTION_NAME_PREFIX;
 	  lto_stream_offload_p = false;
-	  ipa_write_summaries (false);
+	  ipa_write_summaries ();
 	}
     }
 
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 6c6501a..91be530 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -842,11 +842,11 @@ create_references (lto_symtab_encoder_t encoder, symtab_node *node)
 /* Select what needs to be streamed out.  In regular lto mode stream everything.
    In offload lto mode stream only nodes marked as offloadable.  */
 void
-select_what_to_stream (bool offload_lto_mode)
+select_what_to_stream (void)
 {
   struct symtab_node *snode;
   FOR_EACH_SYMBOL (snode)
-    snode->need_lto_streaming = !offload_lto_mode || snode->offloadable;
+    snode->need_lto_streaming = !lto_stream_offload_p || snode->offloadable;
 }
 
 /* Find all symbols we want to stream into given partition and insert them
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 853630f..2d9f30c 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -837,7 +837,7 @@ bool referenced_from_this_partition_p (symtab_node *,
 bool reachable_from_this_partition_p (struct cgraph_node *,
 				      lto_symtab_encoder_t);
 lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
-void select_what_to_stream (bool);
+void select_what_to_stream (void);
 
 /* In options-save.c.  */
 void cl_target_option_stream_out (struct output_block *, struct bitpack_d *,
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 38809d2..c1179cb 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -973,7 +973,8 @@ lto_promote_cross_file_statics (void)
 
   gcc_assert (flag_wpa);
 
-  select_what_to_stream (false);
+  lto_stream_offload_p = false;
+  select_what_to_stream ();
 
   /* First compute boundaries.  */
   n_sets = ltrans_partitions.length ();
diff --git a/gcc/passes.c b/gcc/passes.c
index 52dc067..e78a325 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -2464,7 +2464,7 @@ ipa_write_summaries_1 (lto_symtab_encoder_t encoder)
 /* Write out summaries for all the nodes in the callgraph.  */
 
 void
-ipa_write_summaries (bool offload_lto_mode)
+ipa_write_summaries (void)
 {
   lto_symtab_encoder_t encoder;
   int i, order_pos;
@@ -2475,7 +2475,7 @@ ipa_write_summaries (bool offload_lto_mode)
   if ((!flag_generate_lto && !flag_generate_offload) || seen_error ())
     return;
 
-  select_what_to_stream (offload_lto_mode);
+  select_what_to_stream ();
 
   encoder = lto_symtab_encoder_new (false);
 
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 398ab83..9ff5bdc 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -603,7 +603,7 @@ extern void pass_fini_dump_file (opt_pass *);
 extern const char *get_current_pass_name (void);
 extern void print_current_pass (FILE *);
 extern void debug_pass (void);
-extern void ipa_write_summaries (bool);
+extern void ipa_write_summaries (void);
 extern void ipa_write_optimization_summaries (struct lto_symtab_encoder_d *);
 extern void ipa_read_summaries (void);
 extern void ipa_read_optimization_summaries (void);


  -- Ilya

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: LTO streaming of TARGET_OPTIMIZE_NODE
  2015-01-11 21:28         ` Ilya Verbin
@ 2015-01-12 20:08           ` Jan Hubicka
  0 siblings, 0 replies; 19+ messages in thread
From: Jan Hubicka @ 2015-01-12 20:08 UTC (permalink / raw)
  To: Ilya Verbin
  Cc: Jakub Jelinek, Richard Biener, Jan Hubicka, Kirill Yukhin, gcc-patches

> On 09 Jan 12:45, Jakub Jelinek wrote:
> > --- gcc/cgraphunit.c.jj	2015-01-09 12:01:33.000000000 +0100
> > +++ gcc/cgraphunit.c	2015-01-09 12:22:27.742692667 +0100
> > @@ -2108,11 +2108,14 @@ ipa_passes (void)
> >        if (g->have_offload)
> >  	{
> >  	  section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
> > +	  lto_stream_offload_p = true;
> >  	  ipa_write_summaries (true);
> > +	  lto_stream_offload_p = false;
> >  	}
> >        if (flag_lto)
> >  	{
> >  	  section_name_prefix = LTO_SECTION_NAME_PREFIX;
> > +	  lto_stream_offload_p = false;
> >  	  ipa_write_summaries (false);
> >  	}
> 
> Now when we have a global flag, there is no longer need to pass a flag to
> ipa_write_summaries and to select_what_to_stream.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, OK for trunk?
OK,
Honza
> 
> 
> gcc/
> 	* cgraphunit.c (ipa_passes): Remove argument from ipa_write_summaries.
> 	* lto-cgraph.c (select_what_to_stream): Remove argument, use
> 	lto_stream_offload_p instead.
> 	* lto-streamer.h (select_what_to_stream): Remove argument.
> 	* passes.c (ipa_write_summaries): Likewise.
> 	* tree-pass.h (ipa_write_summaries): Likewise.
> gcc/lto/
> 	* lto-partition.c (lto_promote_cross_file_statics): Remove argument
> 	from select_what_to_stream.
> 
> 
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index 149f447..1ef1b6c 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -2115,14 +2115,14 @@ ipa_passes (void)
>  	{
>  	  section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
>  	  lto_stream_offload_p = true;
> -	  ipa_write_summaries (true);
> +	  ipa_write_summaries ();
>  	  lto_stream_offload_p = false;
>  	}
>        if (flag_lto)
>  	{
>  	  section_name_prefix = LTO_SECTION_NAME_PREFIX;
>  	  lto_stream_offload_p = false;
> -	  ipa_write_summaries (false);
> +	  ipa_write_summaries ();
>  	}
>      }
>  
> diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
> index 6c6501a..91be530 100644
> --- a/gcc/lto-cgraph.c
> +++ b/gcc/lto-cgraph.c
> @@ -842,11 +842,11 @@ create_references (lto_symtab_encoder_t encoder, symtab_node *node)
>  /* Select what needs to be streamed out.  In regular lto mode stream everything.
>     In offload lto mode stream only nodes marked as offloadable.  */
>  void
> -select_what_to_stream (bool offload_lto_mode)
> +select_what_to_stream (void)
>  {
>    struct symtab_node *snode;
>    FOR_EACH_SYMBOL (snode)
> -    snode->need_lto_streaming = !offload_lto_mode || snode->offloadable;
> +    snode->need_lto_streaming = !lto_stream_offload_p || snode->offloadable;
>  }
>  
>  /* Find all symbols we want to stream into given partition and insert them
> diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
> index 853630f..2d9f30c 100644
> --- a/gcc/lto-streamer.h
> +++ b/gcc/lto-streamer.h
> @@ -837,7 +837,7 @@ bool referenced_from_this_partition_p (symtab_node *,
>  bool reachable_from_this_partition_p (struct cgraph_node *,
>  				      lto_symtab_encoder_t);
>  lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
> -void select_what_to_stream (bool);
> +void select_what_to_stream (void);
>  
>  /* In options-save.c.  */
>  void cl_target_option_stream_out (struct output_block *, struct bitpack_d *,
> diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
> index 38809d2..c1179cb 100644
> --- a/gcc/lto/lto-partition.c
> +++ b/gcc/lto/lto-partition.c
> @@ -973,7 +973,8 @@ lto_promote_cross_file_statics (void)
>  
>    gcc_assert (flag_wpa);
>  
> -  select_what_to_stream (false);
> +  lto_stream_offload_p = false;
> +  select_what_to_stream ();
>  
>    /* First compute boundaries.  */
>    n_sets = ltrans_partitions.length ();
> diff --git a/gcc/passes.c b/gcc/passes.c
> index 52dc067..e78a325 100644
> --- a/gcc/passes.c
> +++ b/gcc/passes.c
> @@ -2464,7 +2464,7 @@ ipa_write_summaries_1 (lto_symtab_encoder_t encoder)
>  /* Write out summaries for all the nodes in the callgraph.  */
>  
>  void
> -ipa_write_summaries (bool offload_lto_mode)
> +ipa_write_summaries (void)
>  {
>    lto_symtab_encoder_t encoder;
>    int i, order_pos;
> @@ -2475,7 +2475,7 @@ ipa_write_summaries (bool offload_lto_mode)
>    if ((!flag_generate_lto && !flag_generate_offload) || seen_error ())
>      return;
>  
> -  select_what_to_stream (offload_lto_mode);
> +  select_what_to_stream ();
>  
>    encoder = lto_symtab_encoder_new (false);
>  
> diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
> index 398ab83..9ff5bdc 100644
> --- a/gcc/tree-pass.h
> +++ b/gcc/tree-pass.h
> @@ -603,7 +603,7 @@ extern void pass_fini_dump_file (opt_pass *);
>  extern const char *get_current_pass_name (void);
>  extern void print_current_pass (FILE *);
>  extern void debug_pass (void);
> -extern void ipa_write_summaries (bool);
> +extern void ipa_write_summaries (void);
>  extern void ipa_write_optimization_summaries (struct lto_symtab_encoder_d *);
>  extern void ipa_read_summaries (void);
>  extern void ipa_read_optimization_summaries (void);
> 
> 
>   -- Ilya

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2015-01-12 20:02 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-13  5:10 LTO streaming of TARGET_OPTIMIZE_NODE Jan Hubicka
2014-11-13 10:58 ` Richard Biener
2014-11-13 15:32   ` Jan Hubicka
2014-11-14  0:54     ` Jan Hubicka
2014-11-14  8:54       ` Richard Biener
2014-11-14 18:15       ` [BUILDROBOT] error: ‘cl_target_option_stream_in’ was not declared in this scope (was: LTO streaming of TARGET_OPTIMIZE_NODE) Jan-Benedict Glaw
2014-11-14 19:13         ` [BUILDROBOT] error: �??cl_target_option_stream_in�?? " Jan Hubicka
2014-11-15 17:07           ` Jan-Benedict Glaw
2014-11-20 13:09 ` LTO streaming of TARGET_OPTIMIZE_NODE Bernd Schmidt
2014-11-20 13:38   ` Richard Biener
2014-11-20 14:24     ` Bernd Schmidt
2014-11-20 21:51       ` Jan Hubicka
2015-01-08 14:12   ` Jakub Jelinek
2015-01-09 11:13     ` Thomas Schwinge
2015-01-09 11:50       ` Jakub Jelinek
2015-01-09 12:12         ` Richard Biener
2015-01-11 17:38         ` Jan Hubicka
2015-01-11 21:28         ` Ilya Verbin
2015-01-12 20:08           ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).