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