* bitmap.h (bitmap_equal_p): Return bool.
(bitmap_intersect_p, bitmap_intersect_compl_p): Declare.
* bitmap.c (bitmap_equal_p): Return bool. Compare directly.
(bitmap_intersect_p, bitmap_intersect_compl_p): New.
* flow.c (calculate_global_regs_live): Use bitmap_intersect_p and
bitmap_intersect_compl_p.
* ifcvt (dead_or_predicable): Likewise.
From-SVN: r89981
+2004-11-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * bitmap.h (bitmap_equal_p): Return bool.
+ (bitmap_intersect_p, bitmap_intersect_compl_p): Declare.
+ * bitmap.c (bitmap_equal_p): Return bool. Compare directly.
+ (bitmap_intersect_p, bitmap_intersect_compl_p): New.
+ * flow.c (calculate_global_regs_live): Use bitmap_intersect_p and
+ bitmap_intersect_compl_p.
+ * ifcvt (dead_or_predicable): Likewise.
+
2004-11-02 Nathan Sidwell <nathan@codesourcery.com>
PR rtl-optimization/17104
return changed;
}
-/* Return true if two bitmaps are identical. */
+/* Return true if two bitmaps are identical.
+ We do not bother with a check for pointer equality, as that never
+ occurs in practice. */
-int
+bool
bitmap_equal_p (bitmap a, bitmap b)
{
- bitmap_head c;
- int ret;
+ bitmap_element *a_elt;
+ bitmap_element *b_elt;
+ unsigned ix;
+
+ for (a_elt = a->first, b_elt = b->first;
+ a_elt && b_elt;
+ a_elt = a_elt->next, b_elt = b_elt->next)
+ {
+ if (a_elt->indx != b_elt->indx)
+ return false;
+ for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ if (a_elt->bits[ix] != b_elt->bits[ix])
+ return false;
+ }
+ return !a_elt && !b_elt;
+}
+
+/* Return true if A AND B is not empty. */
+
+bool
+bitmap_intersect_p (bitmap a, bitmap b)
+{
+ bitmap_element *a_elt;
+ bitmap_element *b_elt;
+ unsigned ix;
+
+ for (a_elt = a->first, b_elt = b->first;
+ a_elt && b_elt;)
+ {
+ if (a_elt->indx < b_elt->indx)
+ a_elt = a_elt->next;
+ else if (b_elt->indx < a_elt->indx)
+ b_elt = b_elt->next;
+ else
+ {
+ for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ if (a_elt->bits[ix] & b_elt->bits[ix])
+ return true;
+ a_elt = a_elt->next;
+ b_elt = b_elt->next;
+ }
+ }
+ return false;
+}
- memset (&c, 0, sizeof (c));
- ret = ! bitmap_xor (&c, a, b);
- bitmap_clear (&c);
+/* Return true if A AND NOT B is not empty. */
- return ret;
+bool
+bitmap_intersect_compl_p (bitmap a, bitmap b)
+{
+ bitmap_element *a_elt;
+ bitmap_element *b_elt;
+ unsigned ix;
+ for (a_elt = a->first, b_elt = b->first;
+ a_elt && b_elt;)
+ {
+ if (a_elt->indx < b_elt->indx)
+ return true;
+ else if (b_elt->indx < a_elt->indx)
+ b_elt = b_elt->next;
+ else
+ {
+ for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ if (a_elt->bits[ix] & ~b_elt->bits[ix])
+ return true;
+ a_elt = a_elt->next;
+ b_elt = b_elt->next;
+ }
+ }
+ return a_elt != NULL;
}
+
\f
/* Or into bitmap TO bitmap FROM1 and'ed with the complement of
bitmap FROM2. */
extern void bitmap_copy (bitmap, bitmap);
/* True if two bitmaps are identical. */
-extern int bitmap_equal_p (bitmap, bitmap);
+extern bool bitmap_equal_p (bitmap, bitmap);
+/* True if the bitmaps intersect (their AND is non-empty). */
+extern bool bitmap_intersect_p (bitmap, bitmap);
+
+/* True if the complement of the second intersects the first (their
+ AND_COMPL is non-empty). */
+extern bool bitmap_intersect_compl_p (bitmap, bitmap);
+
+/* True if MAP is an empty bitmap. */
#define bitmap_empty_p(MAP) (!(MAP)->first)
/* Perform an operation on two bitmaps, yielding a third. */
rescan the block. This wouldn't be necessary if we had
precalculated local_live, however with PROP_SCAN_DEAD_CODE
local_live is really dependent on live_at_end. */
- CLEAR_REG_SET (tmp);
- rescan = bitmap_and_compl (tmp, bb->global_live_at_end,
- new_live_at_end);
-
- if (! rescan)
- {
- /* If any of the registers in the new live_at_end set are
- conditionally set in this basic block, we must rescan.
- This is because conditional lifetimes at the end of the
- block do not just take the live_at_end set into account,
- but also the liveness at the start of each successor
- block. We can miss changes in those sets if we only
- compare the new live_at_end against the previous one. */
- CLEAR_REG_SET (tmp);
- rescan = bitmap_and (tmp, new_live_at_end,
- bb->cond_local_set);
- }
-
- if (! rescan)
+ rescan = bitmap_intersect_compl_p (bb->global_live_at_end,
+ new_live_at_end);
+
+ if (!rescan)
+ /* If any of the registers in the new live_at_end set are
+ conditionally set in this basic block, we must rescan.
+ This is because conditional lifetimes at the end of the
+ block do not just take the live_at_end set into
+ account, but also the liveness at the start of each
+ successor block. We can miss changes in those sets if
+ we only compare the new live_at_end against the
+ previous one. */
+ rescan = bitmap_intersect_p (new_live_at_end,
+ bb->cond_local_set);
+
+ if (!rescan)
{
/* Find the set of changed bits. Take this opportunity
to notice that this set is empty and early out. */
- CLEAR_REG_SET (tmp);
- changed = bitmap_xor (tmp, bb->global_live_at_end,
- new_live_at_end);
- if (! changed)
+ bitmap_xor (tmp, bb->global_live_at_end, new_live_at_end);
+ if (bitmap_empty_p (tmp))
continue;
-
+
/* If any of the changed bits overlap with local_set,
- we'll have to rescan the block. Detect overlap by
- the AND with ~local_set turning off bits. */
- rescan = bitmap_and_compl_into (tmp, bb->local_set);
+ we'll have to rescan the block. */
+ rescan = bitmap_intersect_p (tmp, bb->local_set);
}
}
TEST_SET & merge_bb->global_live_at_start
are empty. */
- bitmap_ior (tmp, test_set, test_live);
- bitmap_and_into (tmp, merge_set);
- if (!bitmap_empty_p (tmp))
- fail = 1;
-
- bitmap_and (tmp, test_set, merge_bb->global_live_at_start);
- if (!bitmap_empty_p (tmp))
+ if (bitmap_intersect_p (test_set, merge_set)
+ || bitmap_intersect_p (test_live, merge_set)
+ || bitmap_intersect_p (test_set, merge_bb->global_live_at_start))
fail = 1;
FREE_REG_SET (tmp);