From 3674d8e6fc6305507ed50b501f049f25f868458a Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Wed, 15 Sep 2021 14:43:51 -0400
Subject: [PATCH 1/2] Virtualize relation oracle and various cleanups.
Standardize equiv_oracle API onto the new relation_oracle virtual base, and
then have dom_oracle inherit from that.
equiv_set always returns an equivalency set now, never NULL.
EQ_EXPR requires symmetry now. Each SSA name must be in the other equiv set.
Shuffle some routines around, simplify.
* gimple-range-cache.cc (ranger_cache::ranger_cache): Create a DOM
based oracle.
* gimple-range-fold.cc (fur_depend::register_relation): Use
register_stmt/edge routines.
* value-relation.cc (equiv_chain::find): Relocate from equiv_oracle.
(equiv_oracle::equiv_oracle): Create self equivalence cache.
(equiv_oracle::~equiv_oracle): Release same.
(equiv_oracle::equiv_set): Return entry from self equiv cache if there
are no equivalences.
(equiv_oracle::find_equiv_block): Move list find to equiv_chain.
(equiv_oracle::register_relation): Rename from register_equiv.
(relation_chain_head::find_relation): Relocate from dom_oracle.
(relation_oracle::register_stmt): New.
(relation_oracle::register_edge): New.
(dom_oracle::*): Rename from relation_oracle.
(dom_oracle::register_relation): Adjust to call equiv_oracle.
(dom_oracle::set_one_relation): Split from register_relation.
(dom_oracle::register_transitives): Consolidate 2 methods.
(dom_oracle::find_relation_block): Move core to relation_chain.
(dom_oracle::query_relation): Rename from find_relation_dom and adjust.
* value-relation.h (class relation_oracle): New pure virtual base.
(class equiv_oracle): Inherit from relation_oracle and adjust.
(class dom_oracle): Rename from old relation_oracle and adjust.
---
gcc/gimple-range-cache.cc | 2 +-
gcc/gimple-range-fold.cc | 4 +-
gcc/value-relation.cc | 316 +++++++++++++++++++-------------------
gcc/value-relation.h | 62 +++++---
4 files changed, 206 insertions(+), 178 deletions(-)
@@ -760,7 +760,7 @@ ranger_cache::ranger_cache ()
m_temporal = new temporal_cache;
// If DOM info is available, spawn an oracle as well.
if (dom_info_available_p (CDI_DOMINATORS))
- m_oracle = new relation_oracle ();
+ m_oracle = new dom_oracle ();
else
m_oracle = NULL;
@@ -195,7 +195,7 @@ void
fur_depend::register_relation (gimple *s, relation_kind k, tree op1, tree op2)
{
if (m_oracle)
- m_oracle->register_relation (s, k, op1, op2);
+ m_oracle->register_stmt (s, k, op1, op2);
}
// Register a relation on an edge if there is an oracle.
@@ -204,7 +204,7 @@ void
fur_depend::register_relation (edge e, relation_kind k, tree op1, tree op2)
{
if (m_oracle)
- m_oracle->register_relation (e, k, op1, op2);
+ m_oracle->register_edge (e, k, op1, op2);
}
// This version of fur_source will pick a range up from a list of ranges
@@ -199,7 +199,7 @@ relation_transitive (relation_kind r1, relation_kind r2)
// This allows for much faster traversal of the DOM chain, as a search for
// SSA_NAME simply requires walking the DOM chain until a block is found
// which has the bit for SSA_NAME set. Then scan for the equivalency set in
-// that block. No previous blcoks need be searched.
+// that block. No previous lists need be searched.
class equiv_chain
{
@@ -208,8 +208,26 @@ public:
basic_block m_bb; // Block this belongs to
equiv_chain *m_next; // Next in block list.
void dump (FILE *f) const; // Show names in this list.
+ equiv_chain *find (unsigned ssa);
};
+// If SSA has an equivalence in this list, find and return it.
+// Otherwise return NULL.
+
+equiv_chain *
+equiv_chain::find (unsigned ssa)
+{
+ equiv_chain *ptr = NULL;
+ // If there are equiv sets and SSA is in one in this list, find it.
+ // Otherwise return NULL.
+ if (bitmap_bit_p (m_names, ssa))
+ {
+ for (ptr = m_next; ptr; ptr = ptr->m_next)
+ if (bitmap_bit_p (ptr->m_names, ssa))
+ break;
+ }
+ return ptr;
+}
// Dump the names in this equivalence set.
@@ -244,12 +262,15 @@ equiv_oracle::equiv_oracle ()
m_equiv.safe_grow_cleared (last_basic_block_for_fn (cfun) + 1);
m_equiv_set = BITMAP_ALLOC (&m_bitmaps);
obstack_init (&m_chain_obstack);
+ m_self_equiv.create (0);
+ m_self_equiv.safe_grow_cleared (num_ssa_names + 1);
}
// Destruct an equivalency oracle.
equiv_oracle::~equiv_oracle ()
{
+ m_self_equiv.release ();
obstack_free (&m_chain_obstack, NULL);
m_equiv.release ();
bitmap_obstack_release (&m_bitmaps);
@@ -259,16 +280,48 @@ equiv_oracle::~equiv_oracle ()
// This is the external API.
const_bitmap
-equiv_oracle::equiv_set (tree ssa, basic_block bb) const
+equiv_oracle::equiv_set (tree ssa, basic_block bb)
{
// Search the dominator tree for an equivalency.
equiv_chain *equiv = find_equiv_dom (ssa, bb);
if (equiv)
return equiv->m_names;
- return NULL;
+ // Otherwise return a cached equiv set containing just this SSA.
+ unsigned v = SSA_NAME_VERSION (ssa);
+ if (v >= m_self_equiv.length ())
+ m_self_equiv.safe_grow_cleared (num_ssa_names + 1);
+
+ if (!m_self_equiv[v])
+ {
+ m_self_equiv[v] = BITMAP_ALLOC (&m_bitmaps);
+ bitmap_set_bit (m_self_equiv[v], v);
+ }
+ return m_self_equiv[v];
}
+// Query if thre is a relation (equivalence) between 2 SSA_NAMEs.
+
+relation_kind
+equiv_oracle::query_relation (basic_block bb, tree ssa1, tree ssa2)
+{
+ // If the 2 ssa names share the same equiv set, they are equal.
+ if (equiv_set (ssa1, bb) == equiv_set (ssa2, bb))
+ return EQ_EXPR;
+ return VREL_NONE;
+}
+
+// Query if thre is a relation (equivalence) between 2 SSA_NAMEs.
+
+relation_kind
+equiv_oracle::query_relation (basic_block bb ATTRIBUTE_UNUSED, const_bitmap e1,
+ const_bitmap e2)
+{
+ // If the 2 ssa names share the same equiv set, they are equal.
+ if (bitmap_equal_p (e1, e2))
+ return EQ_EXPR;
+ return VREL_NONE;
+}
// If SSA has an equivalence in block BB, find and return it.
// Otherwise return NULL.
@@ -276,19 +329,10 @@ equiv_oracle::equiv_set (tree ssa, basic_block bb) const
equiv_chain *
equiv_oracle::find_equiv_block (unsigned ssa, int bb) const
{
- equiv_chain *ptr = NULL;
- if (bb >= (int)m_equiv.length ())
+ if (bb >= (int)m_equiv.length () || !m_equiv[bb])
return NULL;
- // If there are equiv sets and SSA is in one in this block, find it.
- // Otherwise return NULL.
- if (m_equiv[bb] && bitmap_bit_p (m_equiv[bb]->m_names, ssa))
- {
- for (ptr = m_equiv[bb]->m_next; ptr; ptr = ptr->m_next)
- if (bitmap_bit_p (ptr->m_names, ssa))
- break;
- }
- return ptr;
+ return m_equiv[bb]->find (ssa);
}
// Starting at block BB, walk the dominator chain looking for the nearest
@@ -385,8 +429,13 @@ equiv_oracle::register_equiv (basic_block bb, equiv_chain *equiv_1,
// containing all the ssa_names in this basic block.
void
-equiv_oracle::register_equiv (basic_block bb, tree ssa1, tree ssa2)
+equiv_oracle::register_relation (basic_block bb, relation_kind k, tree ssa1,
+ tree ssa2)
{
+ // Only handle equality relations.
+ if (k != EQ_EXPR)
+ return;
+
unsigned v1 = SSA_NAME_VERSION (ssa1);
unsigned v2 = SSA_NAME_VERSION (ssa2);
equiv_chain *equiv_1 = find_equiv_dom (ssa1, bb);
@@ -681,9 +730,37 @@ public:
// ------------------------------------------------------------------------
+// Find the relation between any ssa_name in B1 and any name in B2 in LIST.
+// This will allow equivalencies to be applied to any SSA_NAME in a relation.
+
+relation_kind
+relation_chain_head::find_relation (const_bitmap b1, const_bitmap b2) const
+{
+ if (!m_names)
+ return VREL_NONE;
+
+ // If both b1 and b2 aren't referenced in thie block, cant be a relation
+ if (!bitmap_intersect_p (m_names, b1) || !bitmap_intersect_p (m_names, b2))
+ return VREL_NONE;
+
+ // Search for the fiorst relation that contains BOTH an element from B1
+ // and B2, and return that relation.
+ for (relation_chain *ptr = m_head; ptr ; ptr = ptr->m_next)
+ {
+ unsigned op1 = SSA_NAME_VERSION (ptr->op1 ());
+ unsigned op2 = SSA_NAME_VERSION (ptr->op2 ());
+ if (bitmap_bit_p (b1, op1) && bitmap_bit_p (b2, op2))
+ return ptr->kind ();
+ if (bitmap_bit_p (b1, op2) && bitmap_bit_p (b2, op1))
+ return relation_swap (ptr->kind ());
+ }
+
+ return VREL_NONE;
+}
+
// Instantiate a relation oracle.
-relation_oracle::relation_oracle ()
+dom_oracle::dom_oracle ()
{
m_relations.create (0);
m_relations.safe_grow_cleared (last_basic_block_for_fn (cfun) + 1);
@@ -694,7 +771,7 @@ relation_oracle::relation_oracle ()
// Destruct a relation oracle.
-relation_oracle::~relation_oracle ()
+dom_oracle::~dom_oracle ()
{
m_relations.release ();
}
@@ -702,8 +779,8 @@ relation_oracle::~relation_oracle ()
// Register relation K between ssa_name OP1 and OP2 on STMT.
void
-relation_oracle::register_relation (gimple *stmt, relation_kind k, tree op1,
- tree op2)
+relation_oracle::register_stmt (gimple *stmt, relation_kind k, tree op1,
+ tree op2)
{
gcc_checking_assert (TREE_CODE (op1) == SSA_NAME);
gcc_checking_assert (TREE_CODE (op2) == SSA_NAME);
@@ -722,19 +799,13 @@ relation_oracle::register_relation (gimple *stmt, relation_kind k, tree op1,
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
- // This relation applies to the entire block, use STMT's block.
- // Equivalencies are handled by the equivalence oracle.
- if (k == EQ_EXPR)
- register_equiv (gimple_bb (stmt), op1, op2);
- else
- register_relation (gimple_bb (stmt), k, op1, op2);
+ register_relation (gimple_bb (stmt), k, op1, op2);
}
// Register relation K between ssa_name OP1 and OP2 on edge E.
void
-relation_oracle::register_relation (edge e, relation_kind k, tree op1,
- tree op2)
+relation_oracle::register_edge (edge e, relation_kind k, tree op1, tree op2)
{
gcc_checking_assert (TREE_CODE (op1) == SSA_NAME);
gcc_checking_assert (TREE_CODE (op2) == SSA_NAME);
@@ -752,24 +823,35 @@ relation_oracle::register_relation (edge e, relation_kind k, tree op1,
fprintf (dump_file, " on (%d->%d)\n", e->src->index, e->dest->index);
}
- // Equivalencies are handled by the equivalence oracle.
+ register_relation (e->dest, k, op1, op2);
+}
+
+// Register relation K between OP! and OP2 in block BB.
+// This creates the record and searches for existing records in the dominator
+// tree to merge with.
+
+void
+dom_oracle::register_relation (basic_block bb, relation_kind k, tree op1,
+ tree op2)
+{ // Equivalencies are handled by the equivalence oracle.
if (k == EQ_EXPR)
- register_equiv (e->dest, op1, op2);
+ equiv_oracle::register_relation (bb, k, op1, op2);
else
- register_relation (e->dest, k, op1, op2);
+ {
+ relation_chain *ptr = set_one_relation (bb, k, op1, op2);
+ register_transitives (bb, *ptr);
+ }
}
// Register relation K between OP! and OP2 in block BB.
// This creates the record and searches for existing records in the dominator
// tree to merge with.
-// TRANSITIVE_P is true if this is being registered as a transitive operation,
-// and should not try to register further transitives.
-void
-relation_oracle::register_relation (basic_block bb, relation_kind k, tree op1,
- tree op2, bool transitive_p)
+relation_chain *
+dom_oracle::set_one_relation (basic_block bb, relation_kind k, tree op1,
+ tree op2)
{
- gcc_checking_assert (k != VREL_NONE);
+ gcc_checking_assert (k != VREL_NONE && k != EQ_EXPR);
value_relation vr(k, op1, op2);
int bbi = bb->index;
@@ -824,11 +906,9 @@ relation_oracle::register_relation (basic_block bb, relation_kind k, tree op1,
sizeof (relation_chain));
ptr->set_relation (k, op1, op2);
ptr->m_next = m_relations[bbi].m_head;
- m_relations[bbi].m_head = ptr;;
+ m_relations[bbi].m_head = ptr;
}
-
- if (!transitive_p)
- register_transitives (bb, *ptr);
+ return ptr;
}
// Starting at ROOT_BB search the DOM tree looking for relations which
@@ -837,12 +917,25 @@ relation_oracle::register_relation (basic_block bb, relation_kind k, tree op1,
// considered.
void
-relation_oracle::register_transitives (basic_block root_bb,
- const value_relation &relation,
- const_bitmap equiv1,
- const_bitmap equiv2)
+dom_oracle::register_transitives (basic_block root_bb,
+ const value_relation &relation)
{
basic_block bb;
+ // Only apply transitives to certain kinds of operations.
+ switch (relation.kind ())
+ {
+ case LE_EXPR:
+ case LT_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ break;
+ default:
+ return;
+ }
+
+ const_bitmap equiv1 = equiv_set (relation.op1 (), root_bb);
+ const_bitmap equiv2 = equiv_set (relation.op2 (), root_bb);
+
for (bb = root_bb; bb; bb = get_immediate_dominator (CDI_DOMINATORS, bb))
{
int bbi = bb->index;
@@ -897,8 +990,7 @@ relation_oracle::register_transitives (basic_block root_bb,
value_relation nr (relation.kind (), r1, r2);
if (nr.apply_transitive (*ptr))
{
- register_relation (root_bb, nr.kind (), nr.op1 (), nr.op2 (),
- true);
+ set_one_relation (root_bb, nr.kind (), nr.op1 (), nr.op2 ());
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Registering transitive relation ");
@@ -911,98 +1003,30 @@ relation_oracle::register_transitives (basic_block root_bb,
}
}
-// Find adn register any transitive relations implied by RELATION occuring
-// in block BB.
-
-void
-relation_oracle::register_transitives (basic_block bb,
- const value_relation &relation)
-{
- // Only apply transitives to certain kinds of operations.
- switch (relation.kind ())
- {
- case LE_EXPR:
- case LT_EXPR:
- case GT_EXPR:
- case GE_EXPR:
- break;
- default:
- return;
- }
-
- // Set up the bitmaps for op1 and op2, and if there are no equivalencies,
- // set just op1 or op2 in their own bitmap.
- const_bitmap equiv1 = equiv_set (relation.op1 (), bb);
- const_bitmap equiv2 = equiv_set (relation.op2 (), bb);
- if (equiv1)
- {
- if (equiv2)
- register_transitives (bb, relation, equiv1, equiv2);
- else
- {
- bitmap_clear (m_tmp);
- bitmap_set_bit (m_tmp, SSA_NAME_VERSION (relation.op2 ()));
- register_transitives (bb, relation, equiv1, m_tmp);
- }
- }
- else if (equiv2)
- {
- bitmap_clear (m_tmp);
- bitmap_set_bit (m_tmp, SSA_NAME_VERSION (relation.op1 ()));
- register_transitives (bb, relation, m_tmp, equiv2);
- }
- else
- {
- bitmap_clear (m_tmp);
- bitmap_clear (m_tmp2);
- bitmap_set_bit (m_tmp, SSA_NAME_VERSION (relation.op1 ()));
- bitmap_set_bit (m_tmp2, SSA_NAME_VERSION (relation.op2 ()));
- register_transitives (bb, relation, m_tmp, m_tmp2);
- }
-}
-
// Find the relation between any ssa_name in B1 and any name in B2 in block BB.
// This will allow equivalencies to be applied to any SSA_NAME in a relation.
relation_kind
-relation_oracle::find_relation_block (unsigned bb, const_bitmap b1,
- const_bitmap b2)
+dom_oracle::find_relation_block (unsigned bb, const_bitmap b1,
+ const_bitmap b2) const
{
- const_bitmap bm;
if (bb >= m_relations.length())
return VREL_NONE;
- bm = m_relations[bb].m_names;
- if (!bm)
- return VREL_NONE;
-
- // If both b1 and b2 aren't referenced in thie block, cant be a relation
- if (!bitmap_intersect_p (bm, b1) || !bitmap_intersect_p (bm, b2))
- return VREL_NONE;
-
- // Search for the fiorst relation that contains BOTH an element from B1
- // and B2, and return that relation.
- for (relation_chain *ptr = m_relations[bb].m_head; ptr ; ptr = ptr->m_next)
- {
- unsigned op1 = SSA_NAME_VERSION (ptr->op1 ());
- unsigned op2 = SSA_NAME_VERSION (ptr->op2 ());
- if (bitmap_bit_p (b1, op1) && bitmap_bit_p (b2, op2))
- return ptr->kind ();
- if (bitmap_bit_p (b1, op2) && bitmap_bit_p (b2, op1))
- return relation_swap (ptr->kind ());
- }
-
- return VREL_NONE;
+ return m_relations[bb].find_relation (b1, b2);
}
-// Search the DOM tree for a relation between an element of B1 and B2, starting
-// with block BB.
+// Search the DOM tree for a relation between an element of equivalency set B1
+// and B2, starting with block BB.
relation_kind
-relation_oracle::find_relation_dom (basic_block bb, const_bitmap b1,
- const_bitmap b2)
+dom_oracle::query_relation (basic_block bb, const_bitmap b1,
+ const_bitmap b2)
{
relation_kind r;
+ if (bitmap_equal_p (b1, b2))
+ return EQ_EXPR;
+
// If either name does not occur in a relation anywhere, there isnt one.
if (!bitmap_intersect_p (m_relation_set, b1)
|| !bitmap_intersect_p (m_relation_set, b2))
@@ -1023,8 +1047,8 @@ relation_oracle::find_relation_dom (basic_block bb, const_bitmap b1,
// is found, return a pointer to the chain object in OBJ.
relation_kind
-relation_oracle::find_relation_block (int bb, unsigned v1, unsigned v2,
- relation_chain **obj)
+dom_oracle::find_relation_block (int bb, unsigned v1, unsigned v2,
+ relation_chain **obj) const
{
if (bb >= (int)m_relations.length())
return VREL_NONE;
@@ -1063,7 +1087,7 @@ relation_oracle::find_relation_block (int bb, unsigned v1, unsigned v2,
// starting with block BB
relation_kind
-relation_oracle::find_relation_dom (basic_block bb, unsigned v1, unsigned v2)
+dom_oracle::find_relation_dom (basic_block bb, unsigned v1, unsigned v2) const
{
relation_kind r;
// IF either name does not occur in a relation anywhere, there isnt one.
@@ -1084,7 +1108,7 @@ relation_oracle::find_relation_dom (basic_block bb, unsigned v1, unsigned v2)
// dominator of BB
relation_kind
-relation_oracle::query_relation (basic_block bb, tree ssa1, tree ssa2)
+dom_oracle::query_relation (basic_block bb, tree ssa1, tree ssa2)
{
relation_kind kind;
unsigned v1 = SSA_NAME_VERSION (ssa1);
@@ -1092,9 +1116,10 @@ relation_oracle::query_relation (basic_block bb, tree ssa1, tree ssa2)
if (v1 == v2)
return EQ_EXPR;
- // Check for equivalence first.
+ // Check for equivalence first. They must be in each equivalency set.
const_bitmap equiv1 = equiv_set (ssa1, bb);
- if (equiv1 && bitmap_bit_p (equiv1, v2))
+ const_bitmap equiv2 = equiv_set (ssa2, bb);
+ if (bitmap_bit_p (equiv1, v2) && bitmap_bit_p (equiv2, v1))
return EQ_EXPR;
// Initially look for a direct relationship and just return that.
@@ -1102,38 +1127,15 @@ relation_oracle::query_relation (basic_block bb, tree ssa1, tree ssa2)
if (kind != VREL_NONE)
return kind;
- // If v2 isn't in v1s equiv set, then v1 shouldn't be in v2's set either.
- // It is possible for out-of-order dominator processing to have an out of
- // sync set of equivalences.. Down the road, when we do full updates,
- // change this to an assert to ensure everything is in sync.
- const_bitmap equiv2 = equiv_set (ssa2, bb);
- if (equiv2 && bitmap_bit_p (equiv2, v1))
- return EQ_EXPR;
-
- // If not equal, see if there is a relationship between equivalences.
- if (!equiv1 && !equiv2)
- kind = VREL_NONE;
- else if (!equiv1)
- {
- bitmap_clear (m_tmp);
- bitmap_set_bit (m_tmp, v1);
- kind = find_relation_dom (bb, m_tmp, equiv2);
- }
- else if (!equiv2)
- {
- bitmap_clear (m_tmp);
- bitmap_set_bit (m_tmp, v2);
- kind = find_relation_dom (bb, equiv1, m_tmp);
- }
- else
- kind = find_relation_dom (bb, equiv1, equiv2);
+ // Query using the equiovalence sets.
+ kind = query_relation (bb, equiv1, equiv2);
return kind;
}
// Dump all the relations in block BB to file F.
void
-relation_oracle::dump (FILE *f, basic_block bb) const
+dom_oracle::dump (FILE *f, basic_block bb) const
{
equiv_oracle::dump (f,bb);
@@ -1154,7 +1156,7 @@ relation_oracle::dump (FILE *f, basic_block bb) const
// Dump all the relations known to file F.
void
-relation_oracle::dump (FILE *f) const
+dom_oracle::dump (FILE *f) const
{
fprintf (f, "Relation dump\n");
for (unsigned i = 0; i < m_relations.length (); i++)
@@ -73,6 +73,31 @@ relation_kind relation_negate (relation_kind r);
relation_kind relation_swap (relation_kind r);
void print_relation (FILE *f, relation_kind rel);
+
+class relation_oracle
+{
+public:
+ virtual ~relation_oracle () { }
+ // register a relation between 2 ssa names at a stmt.
+ void register_stmt (gimple *, relation_kind, tree, tree);
+ // register a relation between 2 ssa names on an edge.
+ void register_edge (edge, relation_kind, tree, tree);
+
+ // Return equivalency set for an SSA name in a basic block.
+ virtual const_bitmap equiv_set (tree, basic_block) = 0;
+ // register a relation between 2 ssa names in a basic block.
+ virtual void register_relation (basic_block, relation_kind, tree, tree) = 0;
+ // Query for a relation between two ssa names in a basic block.
+ virtual relation_kind query_relation (basic_block, tree, tree) = 0;
+ // Query for a relation between two equivalency stes in a basic block.
+ virtual relation_kind query_relation (basic_block, const_bitmap,
+ const_bitmap) = 0;
+
+ virtual void dump (FILE *, basic_block) const = 0;
+ virtual void dump (FILE *) const = 0;
+ void debug () const;
+};
+
// Declared internally in value-relation.cc
class equiv_chain;
@@ -81,15 +106,18 @@ class equiv_chain;
// can be represented only on edges whose destination is a single-pred block,
// and the equivalence is simply applied to that succesor block.
-class equiv_oracle
+class equiv_oracle : public relation_oracle
{
public:
equiv_oracle ();
~equiv_oracle ();
- const_bitmap equiv_set (tree ssa, basic_block bb) const;
- void register_equiv (basic_block bb, tree ssa1, tree ssa2);
+ const_bitmap equiv_set (tree ssa, basic_block bb);
+ void register_relation (basic_block bb, relation_kind k, tree ssa1,
+ tree ssa2);
+ relation_kind query_relation (basic_block, tree, tree);
+ relation_kind query_relation (basic_block, const_bitmap, const_bitmap);
void dump (FILE *f, basic_block bb) const;
void dump (FILE *f) const;
@@ -99,6 +127,7 @@ protected:
private:
bitmap m_equiv_set; // Index by ssa-name. true if an equivalence exists.
vec <equiv_chain *> m_equiv; // Index by BB. list of equivalences.
+ vec <bitmap> m_self_equiv; // Index by ssa-name, self equivalency set.
void limit_check (basic_block bb = NULL);
equiv_chain *find_equiv_block (unsigned ssa, int bb) const;
@@ -117,6 +146,7 @@ class relation_chain_head
public:
bitmap m_names; // ssa_names with relations in this block.
class relation_chain *m_head; // List of relations in block.
+ relation_kind find_relation (const_bitmap b1, const_bitmap b2) const;
};
// A relation oracle maintains a set of relations between ssa_names using the
@@ -129,36 +159,32 @@ public:
// relation to the destination block of the edge, but ONLY if that block
// has a single successor. For now.
-class relation_oracle : public equiv_oracle
+class dom_oracle : public equiv_oracle
{
public:
- relation_oracle ();
- ~relation_oracle ();
+ dom_oracle ();
+ ~dom_oracle ();
- void register_relation (gimple *stmt, relation_kind k, tree op1, tree op2);
- void register_relation (edge e, relation_kind k, tree op1, tree op2);
+ void register_relation (basic_block bb, relation_kind k, tree op1, tree op2);
relation_kind query_relation (basic_block bb, tree ssa1, tree ssa2);
+ relation_kind query_relation (basic_block bb, const_bitmap b1,
+ const_bitmap b2);
void dump (FILE *f, basic_block bb) const;
void dump (FILE *f) const;
- void debug () const;
private:
bitmap m_tmp, m_tmp2;
bitmap m_relation_set; // Index by ssa-name. True if a relation exists
vec <relation_chain_head> m_relations; // Index by BB, list of relations.
relation_kind find_relation_block (unsigned bb, const_bitmap b1,
- const_bitmap b2);
- relation_kind find_relation_dom (basic_block bb, const_bitmap b1,
- const_bitmap b2);
+ const_bitmap b2) const;
relation_kind find_relation_block (int bb, unsigned v1, unsigned v2,
- relation_chain **obj = NULL);
- relation_kind find_relation_dom (basic_block bb, unsigned v1, unsigned v2);
- void register_relation (basic_block bb, relation_kind k, tree op1, tree op2,
- bool transitive_p = false);
+ relation_chain **obj = NULL) const;
+ relation_kind find_relation_dom (basic_block bb, unsigned v1, unsigned v2) const;
+ relation_chain *set_one_relation (basic_block bb, relation_kind k, tree op1,
+ tree op2);
void register_transitives (basic_block, const class value_relation &);
- void register_transitives (basic_block, const value_relation &, const_bitmap,
- const_bitmap);
};
--
2.17.2