On Thu, 6 Oct 2016, Richard Biener wrote:

> 
> The following guards against (some) remove-current-bit cases.  It
> would have ICEd for PR77855 instead of producing wrong code.
> 
> Bootstrap / regtest running on x86_64-unknown-linux-gnu.
> 
> Comments?

Found one additional issue.

Bootstrapped on x86_64-unknown-linux-gnu, regtest still in progress.

The test is quite conservative (not all "current" bit removed are
detected but only "current and last bit removed" is), still I believe
it's useful to more easily pin-point when it happens that a bitmap
iteration is prematurely terminated due to this.

Richard.

2016-10-06  Richard Biener  <rguent...@suse.de>

        * bitmap.c (bitmap_elem_to_freelist): Set indx to -1.
        * bitmap.h (bmp_iter_set): When advancing to the next element
        check that we didn't remove the current one.
        (bmp_iter_and): Likewise.
        (bmp_iter_and_compl): Likewise.
        * tree-ssa.c (release_defs_bitset): Do not remove worklist bit
        we currently iterate on but keep a one-level queue.

Index: gcc/bitmap.c
===================================================================
*** gcc/bitmap.c        (revision 240829)
--- gcc/bitmap.c        (working copy)
*************** bitmap_elem_to_freelist (bitmap head, bi
*** 66,71 ****
--- 66,72 ----
    bitmap_obstack *bit_obstack = head->obstack;
  
    elt->next = NULL;
+   elt->indx = -1;
    if (bit_obstack)
      {
        elt->prev = bit_obstack->elements;
Index: gcc/bitmap.h
===================================================================
*** gcc/bitmap.h        (revision 240829)
--- gcc/bitmap.h        (working copy)
*************** bmp_iter_set (bitmap_iterator *bi, unsig
*** 618,623 ****
--- 618,626 ----
          bi->word_no++;
        }
  
+       /* Make sure we didn't remove the element while iterating.  */
+       gcc_checking_assert (bi->elt1->indx != -1U);
+ 
        /* Advance to the next element.  */
        bi->elt1 = bi->elt1->next;
        if (!bi->elt1)
*************** bmp_iter_and (bitmap_iterator *bi, unsig
*** 664,669 ****
--- 667,675 ----
        /* Advance to the next identical element.  */
        do
        {
+         /* Make sure we didn't remove the element while iterating.  */
+         gcc_checking_assert (bi->elt1->indx != -1U);
+ 
          /* Advance elt1 while it is less than elt2.  We always want
             to advance one elt.  */
          do
*************** bmp_iter_and (bitmap_iterator *bi, unsig
*** 674,679 ****
--- 680,688 ----
            }
          while (bi->elt1->indx < bi->elt2->indx);
  
+         /* Make sure we didn't remove the element while iterating.  */
+         gcc_checking_assert (bi->elt2->indx != -1U);
+ 
          /* Advance elt2 to be no less than elt1.  This might not
             advance.  */
          while (bi->elt2->indx < bi->elt1->indx)
*************** bmp_iter_and_compl (bitmap_iterator *bi,
*** 726,736 ****
--- 735,751 ----
          bi->word_no++;
        }
  
+       /* Make sure we didn't remove the element while iterating.  */
+       gcc_checking_assert (bi->elt1->indx != -1U);
+ 
        /* Advance to the next element of elt1.  */
        bi->elt1 = bi->elt1->next;
        if (!bi->elt1)
        return false;
  
+       /* Make sure we didn't remove the element while iterating.  */
+       gcc_checking_assert (! bi->elt2 || bi->elt2->indx != -1U);
+ 
        /* Advance elt2 until it is no less than elt1.  */
        while (bi->elt2 && bi->elt2->indx < bi->elt1->indx)
        bi->elt2 = bi->elt2->next;
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c      (revision 240829)
--- gcc/tree-ssa.c      (working copy)
*************** release_defs_bitset (bitmap toremove)
*** 551,608 ****
       most likely run in slightly superlinear time, rather than the
       pathological quadratic worst case.  */
    while (!bitmap_empty_p (toremove))
!     EXECUTE_IF_SET_IN_BITMAP (toremove, 0, j, bi)
!       {
!       bool remove_now = true;
!       tree var = ssa_name (j);
!       gimple *stmt;
!       imm_use_iterator uit;
! 
!       FOR_EACH_IMM_USE_STMT (stmt, uit, var)
!         {
!           ssa_op_iter dit;
!           def_operand_p def_p;
! 
!           /* We can't propagate PHI nodes into debug stmts.  */
!           if (gimple_code (stmt) == GIMPLE_PHI
!               || is_gimple_debug (stmt))
!             continue;
! 
!           /* If we find another definition to remove that uses
!              the one we're looking at, defer the removal of this
!              one, so that it can be propagated into debug stmts
!              after the other is.  */
!           FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, dit, SSA_OP_DEF)
!             {
!               tree odef = DEF_FROM_PTR (def_p);
! 
!               if (bitmap_bit_p (toremove, SSA_NAME_VERSION (odef)))
!                 {
!                   remove_now = false;
!                   break;
!                 }
!             }
! 
!           if (!remove_now)
!             BREAK_FROM_IMM_USE_STMT (uit);
!         }
! 
!       if (remove_now)
!         {
!           gimple *def = SSA_NAME_DEF_STMT (var);
!           gimple_stmt_iterator gsi = gsi_for_stmt (def);
! 
!           if (gimple_code (def) == GIMPLE_PHI)
!             remove_phi_node (&gsi, true);
!           else
!             {
!               gsi_remove (&gsi, true);
!               release_defs (def);
!             }
! 
!           bitmap_clear_bit (toremove, j);
!         }
!       }
  }
  
  /* Verify virtual SSA form.  */
--- 551,620 ----
       most likely run in slightly superlinear time, rather than the
       pathological quadratic worst case.  */
    while (!bitmap_empty_p (toremove))
!     {
!       unsigned to_remove_bit = -1U;
!       EXECUTE_IF_SET_IN_BITMAP (toremove, 0, j, bi)
!       {
!         if (to_remove_bit != -1U)
!           {
!             bitmap_clear_bit (toremove, to_remove_bit);
!             to_remove_bit = -1U;
!           }
! 
!         bool remove_now = true;
!         tree var = ssa_name (j);
!         gimple *stmt;
!         imm_use_iterator uit;
! 
!         FOR_EACH_IMM_USE_STMT (stmt, uit, var)
!           {
!             ssa_op_iter dit;
!             def_operand_p def_p;
! 
!             /* We can't propagate PHI nodes into debug stmts.  */
!             if (gimple_code (stmt) == GIMPLE_PHI
!                 || is_gimple_debug (stmt))
!               continue;
! 
!             /* If we find another definition to remove that uses
!                the one we're looking at, defer the removal of this
!                one, so that it can be propagated into debug stmts
!                after the other is.  */
!             FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, dit, SSA_OP_DEF)
!               {
!                 tree odef = DEF_FROM_PTR (def_p);
! 
!                 if (bitmap_bit_p (toremove, SSA_NAME_VERSION (odef)))
!                   {
!                     remove_now = false;
!                     break;
!                   }
!               }
! 
!             if (!remove_now)
!               BREAK_FROM_IMM_USE_STMT (uit);
!           }
! 
!         if (remove_now)
!           {
!             gimple *def = SSA_NAME_DEF_STMT (var);
!             gimple_stmt_iterator gsi = gsi_for_stmt (def);
! 
!             if (gimple_code (def) == GIMPLE_PHI)
!               remove_phi_node (&gsi, true);
!             else
!               {
!                 gsi_remove (&gsi, true);
!                 release_defs (def);
!               }
! 
!             to_remove_bit = j;
!           }
!       }
!       if (to_remove_bit != -1U)
!       bitmap_clear_bit (toremove, to_remove_bit);
!     }
! 
  }
  
  /* Verify virtual SSA form.  */

Reply via email to