diff mbox

Handle undefined extern vars in output_in_order

Message ID alpine.LNX.2.20.1606091554200.19352@monopod.intra.ispras.ru
State New
Headers show

Commit Message

Alexander Monakov June 9, 2016, 1:13 p.m. UTC
Hi,

This patch teaches cgraphunit.c:output_in_order to output undefined external
variables via assemble_undefined_decl.  At the moment that is only done for
-ftoplevel-reorder in varpool.c:symbol_table::output_variables.  This patch
makes both behave the same way.  I've also made handling of variables in both
functions look similar to each other.

I'll admit it's rather unclear to me what the '!DECL_EXTERNAL (pv->decl)'
condition is guarding in output_in_order (removed in my patch).  AIUI, it
should be always true for defined variables (or, conversely, if it's false
for a defined variable, why are we skipping it?).

I have plans to reimplement handling of "omp declare target link" in a more
clean manner.  Now it looks quite out of place there.

Bootstrapped and regtested on x86_64, OK for trunk?

Alexander

	* cgraphunit.c (cgraph_order_sort_kind): New entry ORDER_VAR_UNDEF.
	(output_in_order): Loop over undefined variables too.  Output them
	via assemble_undefined_decl.  Skip "omp declare target link" variables
	earlier.
	* varpool.c (symbol_table::output_variables): Handle undefined
	variables together with defined ones.

Comments

Alexander Monakov June 16, 2016, 1:59 p.m. UTC | #1
On Thu, 9 Jun 2016, Alexander Monakov wrote:

> Hi,
> 
> This patch teaches cgraphunit.c:output_in_order to output undefined external
> variables via assemble_undefined_decl.  At the moment that is only done for
> -ftoplevel-reorder in varpool.c:symbol_table::output_variables.  This patch
> makes both behave the same way.  I've also made handling of variables in both
> functions look similar to each other.

Ping.

Thanks.
Alexander
Jan Hubicka June 16, 2016, 2:25 p.m. UTC | #2
> On Thu, 9 Jun 2016, Alexander Monakov wrote:
> 
> > Hi,
> > 
> > This patch teaches cgraphunit.c:output_in_order to output undefined external
> > variables via assemble_undefined_decl.  At the moment that is only done for
> > -ftoplevel-reorder in varpool.c:symbol_table::output_variables.  This patch
> > makes both behave the same way.  I've also made handling of variables in both
> > functions look similar to each other.
> 
> Ping.
+  FOR_EACH_VARIABLE (pv)
+    {
+      if (no_reorder && !pv->no_reorder)
+	continue;
+      if (DECL_HARD_REGISTER (pv->decl))
+	continue;
+      if (DECL_HAS_VALUE_EXPR_P (pv->decl))
+	{
+	  gcc_checking_assert (lookup_attribute ("omp declare target link",
+						 DECL_ATTRIBUTES (pv->decl)));
+#ifdef ACCEL_COMPILER
+	  continue;
+#endif
+	}
+      i = pv->order;
+      gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
+      nodes[i].kind = pv->definition ? ORDER_VAR : ORDER_VAR_UNDEF;
+      nodes[i].u.v = pv;

order for undefined variables is not computed, so it will be 0. Doesn't think overwrite existing
entries of nodes array?

Honza
> 
> Thanks.
> Alexander
Alexander Monakov June 16, 2016, 2:37 p.m. UTC | #3
On Thu, 16 Jun 2016, Jan Hubicka wrote:
> > On Thu, 9 Jun 2016, Alexander Monakov wrote:
> +  FOR_EACH_VARIABLE (pv)
[snip]
> +      i = pv->order;
> +      gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
> +      nodes[i].kind = pv->definition ? ORDER_VAR : ORDER_VAR_UNDEF;
> +      nodes[i].u.v = pv;
> 
> order for undefined variables is not computed, so it will be 0. Doesn't
> think overwrite existing entries of nodes array?

Hm, I've tried the following testcase:

extern int a, b;
int f()
{
  return a+b;
}

and in the above loop I see pv->order == 2 on the first iteration,
pv->order == 1 on the second. Under what circumstances wouldn't
order be computed?

Thanks.
Alexander
Jan Hubicka June 16, 2016, 3:24 p.m. UTC | #4
> On Thu, 16 Jun 2016, Jan Hubicka wrote:
> > > On Thu, 9 Jun 2016, Alexander Monakov wrote:
> > +  FOR_EACH_VARIABLE (pv)
> [snip]
> > +      i = pv->order;
> > +      gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
> > +      nodes[i].kind = pv->definition ? ORDER_VAR : ORDER_VAR_UNDEF;
> > +      nodes[i].u.v = pv;
> > 
> > order for undefined variables is not computed, so it will be 0. Doesn't
> > think overwrite existing entries of nodes array?
> 
> Hm, I've tried the following testcase:
> 
> extern int a, b;
> int f()
> {
>   return a+b;
> }
> 
> and in the above loop I see pv->order == 2 on the first iteration,
> pv->order == 1 on the second. Under what circumstances wouldn't
> order be computed?

I see, order is created at a time variable is added to symbol table (not at time when definition is given).
So we should have order everywhere.
Patch is OK

Honza
> 
> Thanks.
> Alexander
Alexander Monakov June 16, 2016, 3:36 p.m. UTC | #5
On Thu, 16 Jun 2016, Jan Hubicka wrote:
> I see, order is created at a time variable is added to symbol table (not at
> time when definition is given).  So we should have order everywhere.
> Patch is OK

Thanks!  If you don't mind a quick followup question: now that both
FOR_EACH_VARIABLE loops in two functions have the same structure, is
it alright to add a comment of the form

  /* There is a similar loop in output_in_order.  Please keep them in sync.  */

to symbol_table::output_variables, and vice versa?

Alexander
Jan Hubicka June 16, 2016, 3:42 p.m. UTC | #6
> On Thu, 16 Jun 2016, Jan Hubicka wrote:
> > I see, order is created at a time variable is added to symbol table (not at
> > time when definition is given).  So we should have order everywhere.
> > Patch is OK
> 
> Thanks!  If you don't mind a quick followup question: now that both
> FOR_EACH_VARIABLE loops in two functions have the same structure, is
> it alright to add a comment of the form
> 
>   /* There is a similar loop in output_in_order.  Please keep them in sync.  */
> 
> to symbol_table::output_variables, and vice versa?

Yes, that is fine.

Honza
diff mbox

Patch

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 4bfcad7..5a04902 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2141,6 +2141,7 @@  enum cgraph_order_sort_kind
   ORDER_UNDEFINED = 0,
   ORDER_FUNCTION,
   ORDER_VAR,
+  ORDER_VAR_UNDEF,
   ORDER_ASM
 };
 
@@ -2187,16 +2188,25 @@  output_in_order (bool no_reorder)
 	}
     }
 
-  FOR_EACH_DEFINED_VARIABLE (pv)
-    if (!DECL_EXTERNAL (pv->decl))
-      {
-	if (no_reorder && !pv->no_reorder)
-	    continue;
-	i = pv->order;
-	gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
-	nodes[i].kind = ORDER_VAR;
-	nodes[i].u.v = pv;
-      }
+  FOR_EACH_VARIABLE (pv)
+    {
+      if (no_reorder && !pv->no_reorder)
+	continue;
+      if (DECL_HARD_REGISTER (pv->decl))
+	continue;
+      if (DECL_HAS_VALUE_EXPR_P (pv->decl))
+	{
+	  gcc_checking_assert (lookup_attribute ("omp declare target link",
+						 DECL_ATTRIBUTES (pv->decl)));
+#ifdef ACCEL_COMPILER
+	  continue;
+#endif
+	}
+      i = pv->order;
+      gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
+      nodes[i].kind = pv->definition ? ORDER_VAR : ORDER_VAR_UNDEF;
+      nodes[i].u.v = pv;
+    }
 
   for (pa = symtab->first_asm_symbol (); pa; pa = pa->next)
     {
@@ -2222,16 +2232,13 @@  output_in_order (bool no_reorder)
 	  break;
 
 	case ORDER_VAR:
-#ifdef ACCEL_COMPILER
-	  /* Do not assemble "omp declare target link" vars.  */
-	  if (DECL_HAS_VALUE_EXPR_P (nodes[i].u.v->decl)
-	      && lookup_attribute ("omp declare target link",
-				   DECL_ATTRIBUTES (nodes[i].u.v->decl)))
-	    break;
-#endif
 	  nodes[i].u.v->assemble_decl ();
 	  break;
 
+	case ORDER_VAR_UNDEF:
+	  assemble_undefined_decl (nodes[i].u.v->decl);
+	  break;
+
 	case ORDER_ASM:
 	  assemble_asm (nodes[i].u.a->asm_str);
 	  break;
diff --git a/gcc/varpool.c b/gcc/varpool.c
index ab615fa..b513026 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -733,11 +733,6 @@  symbol_table::output_variables (void)
 
   timevar_push (TV_VAROUT);
 
-  FOR_EACH_VARIABLE (node)
-    if (!node->definition
-	&& !DECL_HAS_VALUE_EXPR_P (node->decl)
- 	&& !DECL_HARD_REGISTER (node->decl))
-      assemble_undefined_decl (node->decl);
   FOR_EACH_DEFINED_VARIABLE (node)
     {
       /* Handled in output_in_order.  */
@@ -747,20 +742,24 @@  symbol_table::output_variables (void)
       node->finalize_named_section_flags ();
     }
 
-  FOR_EACH_DEFINED_VARIABLE (node)
+  FOR_EACH_VARIABLE (node)
     {
-      /* Handled in output_in_order.  */
       if (node->no_reorder)
 	continue;
+      if (DECL_HARD_REGISTER (node->decl))
+	continue;
+      if (DECL_HAS_VALUE_EXPR_P (node->decl))
+	{
+	  gcc_checking_assert (lookup_attribute ("omp declare target link",
+						 DECL_ATTRIBUTES (node->decl)));
 #ifdef ACCEL_COMPILER
-      /* Do not assemble "omp declare target link" vars.  */
-      if (DECL_HAS_VALUE_EXPR_P (node->decl)
-	  && lookup_attribute ("omp declare target link",
-			       DECL_ATTRIBUTES (node->decl)))
-	continue;
+	  continue;
 #endif
-      if (node->assemble_decl ())
-        changed = true;
+	}
+      if (node->definition)
+	changed |= node->assemble_decl ();
+      else
+	assemble_undefined_decl (node->decl);
     }
   timevar_pop (TV_VAROUT);
   return changed;