https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77692

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ok, so tree_add_const_value_attribute_for_decl gives up because the decl is not
readonly.  But via add_location_or_const_value_attribute rtl_for_decl_location
would get us

(const_vector:V4SF [
        (const_double:SF 2.5e+8 [0x0.ee6b28p+28])
        (const_double:SF 0.0 [0x0.0p+0])
        (const_double:SF 0.0 [0x0.0p+0])
        (const_double:SF 0.0 [0x0.0p+0])
    ])

which looks inconsistent.  That simply does

  /* A variable with no DECL_RTL but a DECL_INITIAL is a compile-time constant,
     and will have been substituted directly into all expressions that use it.
     C does not have such a concept, but C++ and other languages do.  */
  if (!rtl && TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
    rtl = rtl_for_decl_init (DECL_INITIAL (decl), TREE_TYPE (decl));

which may be true if called late enough.

We're invoking dwarf2out_late_global_decl for removed globals only at a very
specific point so it doesn't get called for

typedef float FloatVect __attribute__((__vector_size__(16)));
static FloatVect Foo = { 250000000.0, 0.0, 0.0, 0.0 };

int main()
{
  Foo = (FloatVect) { 1., 1., 1., 1. };
}

where we also remove Foo (as write-only).  For this case it would be definitely
bogus to add a DW_AT_const_value attribute.  We do call it for

typedef float FloatVect __attribute__((__vector_size__(16)));
static FloatVect Foo = { 250000000.0, 0.0, 0.0, 0.0 };

static void bar ()
{
  Foo = (FloatVect) { 1., 1., 1., 1. };
}

int main()
{
}

which means this case did get a DW_AT_const_value attached to Foo.

Note that on the original testcase IPA would have found Foo to be readonly,
likewise on the last.

I believe rtl_for_decl_location is bogus doing

  /* A variable with no DECL_RTL but a DECL_INITIAL is a compile-time constant,
     and will have been substituted directly into all expressions that use it.
     C does not have such a concept, but C++ and other languages do.  */
  if (!rtl && TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
    rtl = rtl_for_decl_init (DECL_INITIAL (decl), TREE_TYPE (decl));

when it is called early before decl got a chance to even create RTL.

So -- is it worth trying to handle this special case where we know a variable
is readonly by means of nothing referencing it?  Then the following fixes it:

Index: gcc/cgraphunit.c
===================================================================
--- gcc/cgraphunit.c    (revision 240388)
+++ gcc/cgraphunit.c    (working copy)
@@ -1194,8 +1194,15 @@ analyze_functions (bool first_time)
             at looking at optimized away DECLs, since
             late_global_decl will subsequently be called from the
             contents of the now pruned symbol table.  */
-         if (!decl_function_context (node->decl))
-           (*debug_hooks->late_global_decl) (node->decl);
+         if (TREE_CODE (node->decl) == VAR_DECL
+             && !decl_function_context (node->decl))
+           {
+             /* We are reclaiming totally unreachable code and variables
+                so they effectively appear as readonly.  Show that to
+                the debug machinery.  */
+             TREE_READONLY (node->decl) = 1;
+             (*debug_hooks->late_global_decl) (node->decl);
+           }

          node->remove ();
          continue;

Reply via email to