2009-06-27 Paolo Bonzini <bonzini@gnu.org>
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 27 Jun 2009 14:46:56 +0000 (14:46 +0000)
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 27 Jun 2009 14:46:56 +0000 (14:46 +0000)
* bitmap.h (bitmap_ior_and_into): New.
* bitmap.c (bitmap_ior_and_into): New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149009 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/bitmap.c
gcc/bitmap.h

index 5517f37..f7fdd4f 100644 (file)
@@ -1,5 +1,10 @@
 2009-06-27  Paolo Bonzini  <bonzini@gnu.org>
 
+       * bitmap.h (bitmap_ior_and_into): New.
+       * bitmap.c (bitmap_ior_and_into): New.
+
+2009-06-27  Paolo Bonzini  <bonzini@gnu.org>
+
         * domwalk.h (struct dom_walk_data): Remove all callbacks except
         before_dom_children_before_stmts and after_dom_children_after_stmts.
         Rename the two remaining callbacks to just before_dom_children and 
index 61a40ee..deca5e5 100644 (file)
@@ -1942,6 +1942,84 @@ bitmap_ior_and_compl_into (bitmap a, const_bitmap from1, const_bitmap from2)
   return changed;
 }
 
+/* A |= (B & C).  Return true if A changes.  */
+
+bool
+bitmap_ior_and_into (bitmap a, const_bitmap b, const_bitmap c)
+{
+  bitmap_element *a_elt = a->first;
+  const bitmap_element *b_elt = b->first;
+  const bitmap_element *c_elt = c->first;
+  bitmap_element and_elt;
+  bitmap_element *a_prev = NULL;
+  bitmap_element **a_prev_pnext = &a->first;
+  bool changed = false;
+  unsigned ix;
+
+  if (b == c)
+    return bitmap_ior_into (a, b);
+  if (bitmap_empty_p (b) || bitmap_empty_p (c))
+    return false;
+
+  and_elt.indx = -1;
+  while (b_elt && c_elt)
+    {
+      BITMAP_WORD overall;
+
+      /* Find a common item of B and C.  */
+      while (b_elt->indx != c_elt->indx)
+       {
+          if (b_elt->indx < c_elt->indx)
+           {
+             b_elt = b_elt->next;
+             if (!b_elt)
+               goto done;
+           }
+          else
+           {
+             c_elt = c_elt->next;
+             if (!c_elt)
+               goto done;
+           }
+       }
+
+      overall = 0;
+      and_elt.indx = b_elt->indx;
+      for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+       {
+         and_elt.bits[ix] = b_elt->bits[ix] & c_elt->bits[ix];
+         overall |= and_elt.bits[ix];
+       }
+
+      b_elt = b_elt->next;
+      c_elt = c_elt->next;
+      if (!overall)
+       continue;
+
+      /* Now find a place to insert AND_ELT.  */
+      do
+       {
+         ix = a_elt ? a_elt->indx : and_elt.indx;
+          if (ix == and_elt.indx)
+           changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt, &and_elt, changed);
+          else if (ix > and_elt.indx)
+           changed = bitmap_elt_copy (a, NULL, a_prev, &and_elt, changed);
+
+          a_prev = *a_prev_pnext;
+          a_prev_pnext = &a_prev->next;
+          a_elt = *a_prev_pnext;
+
+          /* If A lagged behind B/C, we advanced it so loop once more.  */
+       }
+      while (ix < and_elt.indx);
+    }
+
+ done:
+  gcc_assert (!a->current == !a->first);
+  if (a->current)
+    a->indx = a->current->indx;
+  return changed;
+}
 \f
 /* Debugging function to print out the contents of a bitmap.  */
 
index 54267c2..bbc0e20 100644 (file)
@@ -129,6 +129,8 @@ extern bool bitmap_ior_into (bitmap, const_bitmap);
 extern void bitmap_xor (bitmap, const_bitmap, const_bitmap);
 extern void bitmap_xor_into (bitmap, const_bitmap);
 
+/* DST = A | (B & C).  Return true if DST changes.  */
+extern bool bitmap_ior_and_into (bitmap DST, const_bitmap B, const_bitmap C);
 /* DST = A | (B & ~C).  Return true if DST changes.  */
 extern bool bitmap_ior_and_compl (bitmap DST, const_bitmap A, const_bitmap B, const_bitmap C);
 /* A |= (B & ~C).  Return true if A changes.  */