------- Comment #4 from jakub at gcc dot gnu dot org  2009-03-05 15:02 -------
This is harder than I thought.
My first attempt:
--- integrate.c.xx2009-02-20 15:36:24.000000000 +0100
+++ integrate.c2009-03-05 15:46:23.000000000 +0100
@@ -173,7 +173,10 @@ set_block_abstract_flags (tree stmt, int
   for (local_decl = BLOCK_VARS (stmt);
        local_decl != NULL_TREE;
        local_decl = TREE_CHAIN (local_decl))
-    set_decl_abstract_flags (local_decl, setting);
+    /* Don't mark local static variables, those are shared between all
+       inline/cloned copies.  */
+    if (TREE_CODE (local_decl) != VAR_DECL || !TREE_STATIC (local_decl))
+      set_decl_abstract_flags (local_decl, setting);

   for (subblock = BLOCK_SUBBLOCKS (stmt);
        subblock != NULL_TREE;

works well for this testcase, the abstract DIE has DW_AT_location attribute for
the local variable and DIEs for the ctor clones don't have any DIEs for this
variable.  But it creates worse output for C:
extern void f (int *);
static inline __attribute__((always_inline)) void foo (void)
{
  static int staticvar1[4];
  f (staticvar1);
}

void bar (void)
{
  foo ();
}

void baz (void)
{
  foo ();
  foo ();
}

Before the patch the abstract fn DIE contains a DIE for the static variable
without DW_AT_location and the spots that inline this fn has DIE for the static
variable with DW_AT_abstract_origin and DW_AT_location (the same in all cases).
After the patch the abstract fn DIE's static variable DIE contains
DW_AT_location, the spots that inline this have DIE for the static variable
without DW_AT_abstract_origin and again with DW_AT_location.  I'd say either
the abstract origin DIE shouldn't contain DW_AT_location, but then all spots
that use it should contain DW_AT_abstract_origin and DW_AT_location, or the
abstract origin DIE should contain DW_AT_location and the clones shouldn't
contain the DIE at all.  So, I've tried a different patch:

--- tree-cfg.c.jj2        2009-03-05 09:44:31.000000000 +0100
+++ tree-cfg.c        2009-03-05 14:57:46.000000000 +0100
@@ -1799,11 +1799,11 @@ remove_useless_stmts_bind (gimple_stmt_i
       tree var = NULL_TREE;
       /* Even if there are no gimple_bind_vars, there might be other
          decls in BLOCK_VARS rendering the GIMPLE_BIND not useless.  */
-      if (block)
+      if (block && !BLOCK_NUM_NONLOCALIZED_VARS (block))
         for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var))
           if (TREE_CODE (var) == IMPORTED_DECL)
             break;
-      if (var)
+      if (var || (block && BLOCK_NUM_NONLOCALIZED_VARS (block)))
         gsi_next (gsi);
       else
         {

which prevents removing GIMPLE_BINDs that contain BLOCK_NONLOCALIZED_VARS in
its gimple_bind_block (tree-ssa-live.c BLOCK removal does the same thing).
Unfortunately this doesn't solve the original bug, because the abstract
FUNCTION_DECL in the C++ ctor clone case is marked DECL_ABSTRACT already by the
C++ FE, so when dwarf2out_abstract_function is called on it, was_abstract is
true and so everything is set to DECL_ABSTRACT, but not reset afterwards.
This means the VAR_DECL in clone's BLOCK_NONLOCALIZED_VARS has DECL_ABSTRACT
set and thus won't have DW_AT_location emitted.


-- 

jakub at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hubicka at gcc dot gnu dot
                   |                            |org
         AssignedTo|jakub at gcc dot gnu dot org|unassigned at gcc dot gnu
                   |                            |dot org
             Status|ASSIGNED                    |NEW


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39372

Reply via email to