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.
This commit is contained in:
Andrew MacLeod 2021-09-15 14:43:51 -04:00
parent 896fec24c8
commit 3674d8e6fc
4 changed files with 207 additions and 179 deletions

View file

@ -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;

View file

@ -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

View file

@ -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.
if (k == EQ_EXPR)
register_equiv (e->dest, op1, op2);
else
register_relation (e->dest, k, op1, op2);
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.
// 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)
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)
equiv_oracle::register_relation (bb, k, op1, op2);
else
{
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.
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++)

View file

@ -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);
};