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

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #6)
> (In reply to Richard Biener from comment #3)
> > It also seems that DCE cannot remove the empty loop with the clobber, 
> > because
> > it's marked useful and thus its SSA requirements are marked useful (we
> > explicitely exclude the VDEF but _not_ the SSA uses on the LHS of
> > *ssa_2 = {} clobbers).  Even if we don't make that SSA use necessary we
> > still have made the clobber itself necessary and thus marked control
> > dependent
> > edges necessary.
> > 
> > Thus IMHO we shouldn't make clobbers necessary at all but only keep those
> > live that we can keep live (all uses still live).  That makes cddce1
> > kill bar_dtor_loop:
> > 
> > void bar_dtor_loop(Bar*, unsigned int) (struct Bar * p, unsigned int n)
> > {
> >   struct Bar * e;
> > 
> >   <bb 2>:
> >   return;
> > 
> > }
> > 
> > but of course it probably will DCE all indirect clobbers on an address
> > that is otherwise unused.  Jakub - do you think this will be a problem?
> > 
> > Index: gcc/tree-ssa-dce.c
> > ===================================================================
> > --- gcc/tree-ssa-dce.c  (revision 218479)
> > +++ gcc/tree-ssa-dce.c  (working copy)
> > @@ -292,8 +292,7 @@ mark_stmt_if_obviously_necessary (gimple
> >        break;
> >  
> >      case GIMPLE_ASSIGN:
> > -      if (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
> > -         && TREE_CLOBBER_P (gimple_assign_rhs1 (stmt)))
> > +      if (gimple_clobber_p (stmt))
> >         return;
> >        break;
> >  
> > @@ -813,8 +812,9 @@ propagate_necessity (bool aggressive)
> >                 }
> >             }
> >  
> > -         FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
> > -           mark_operand_necessary (use);
> > +         if (!gimple_clobber_p (stmt))
> > +           FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
> > +             mark_operand_necessary (use);
> >  
> >           use = gimple_vuse (stmt);
> >           if (!use)
> > @@ -1362,6 +1362,24 @@ eliminate_unnecessary_stmts (void)
> >           /* If GSI is not necessary then remove it.  */
> >           if (!gimple_plf (stmt, STMT_NECESSARY))
> >             {
> > +             /* Keep clobbers that we can keep live live.  */
> > +             if (gimple_clobber_p (stmt))
> > +               {
> > +                 ssa_op_iter iter;
> > +                 use_operand_p use_p;
> > +                 bool dead = false;
> > +                 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
> > +                   {
> > +                     gimple def = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p));
> > +                     if (!gimple_plf (def, STMT_NECESSARY))
> > +                       {
> > +                         dead = true;
> > +                         break;
> > +                       }
> > +                   }
> > +                 if (!dead)
> > +                   continue;
> > +               }
> >               if (!is_gimple_debug (stmt))
> >                 something_changed = true;
> >               remove_dead_stmt (&gsi, bb);
> 
> Or rather
> 
>               /* Keep clobbers that we can keep live live.  */
>               if (gimple_clobber_p (stmt))
>                 {
>                   ssa_op_iter iter;
>                   use_operand_p use_p;
>                   bool dead = true;
>                   FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
>                     {
>                       gimple def = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p));
>                       if (gimple_nop_p (def)
>                           || gimple_plf (def, STMT_NECESSARY))
>                         {
>                           dead = false;
>                           break;
>                         }
>                     }
> 
> so we keep the indirect clobbers in destructors (with use of parameter
> SSA default defs).

Or

          /* If GSI is not necessary then remove it.  */
          if (!gimple_plf (stmt, STMT_NECESSARY))
            {
+             /* Keep clobbers that we can keep live live.  */
+             if (gimple_clobber_p (stmt))
+               {
+                 ssa_op_iter iter;
+                 use_operand_p use_p;
+                 bool dead = false;
+                 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
+                   {
+                     gimple def = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p));
+                     if (!gimple_nop_p (def)
+                         && !gimple_plf (def, STMT_NECESSARY))
+                       {
+                         dead = true;
+                         break;
+                       }
+                   }
+                 if (!dead)
+                   continue;
+               }

to not remove all direct clobbers but still keep indirect clobbers
on default defs.

Reply via email to