// --------------------------------------------------------------------------
-// Negate the current relation.
+
+// Adjust the relation by Swapping the operands and relation.
void
-value_relation::negate ()
+value_relation::swap ()
{
- related = relation_negate (related);
+ related = relation_swap (related);
+ tree tmp = name1;
+ name1 = name2;
+ name2 = tmp;
}
// Perform an intersection between 2 relations. *this &&= p.
+// Return false if the relations cannot be intersected.
bool
value_relation::intersect (value_relation &p)
relation_chain *m_next;
};
+// Given relation record PTR in block BB, return the next relation in the
+// list. If PTR is NULL, retreive the first relation in BB.
+// If NAME is sprecified, return only relations which include NAME.
+// Return NULL when there are no relations left.
+
+relation_chain *
+dom_oracle::next_relation (basic_block bb, relation_chain *ptr,
+ tree name) const
+{
+ relation_chain *p;
+ // No value_relation pointer is used to intialize the iterator.
+ if (!ptr)
+ {
+ int bbi = bb->index;
+ if (bbi >= (int)m_relations.length())
+ return NULL;
+ else
+ p = m_relations[bbi].m_head;
+ }
+ else
+ p = ptr->m_next;
+
+ if (name)
+ for ( ; p; p = p->m_next)
+ if (p->op1 () == name || p->op2 () == name)
+ break;
+ return p;
+}
+
+// Instatiate a block relation iterator to iterate over the relations
+// on exit from block BB in ORACLE. Limit this to relations involving NAME
+// if specified. Return the first such relation in VR if there is one.
+
+block_relation_iterator::block_relation_iterator (const relation_oracle *oracle,
+ basic_block bb,
+ value_relation &vr,
+ tree name)
+{
+ m_oracle = oracle;
+ m_bb = bb;
+ m_name = name;
+ m_ptr = oracle->next_relation (bb, NULL, m_name);
+ if (m_ptr)
+ {
+ m_done = false;
+ vr = *m_ptr;
+ }
+ else
+ m_done = true;
+}
+
+// Retreive the next relation from the iterator and return it in VR.
+
+void
+block_relation_iterator::get_next_relation (value_relation &vr)
+{
+ m_ptr = m_oracle->next_relation (m_bb, m_ptr, m_name);
+ if (m_ptr)
+ {
+ vr = *m_ptr;
+ if (m_name)
+ {
+ if (vr.op1 () != m_name)
+ {
+ gcc_checking_assert (vr.op2 () == m_name);
+ vr.swap ();
+ }
+ }
+ }
+ else
+ m_done = true;
+}
+
// ------------------------------------------------------------------------
// Find the relation between any ssa_name in B1 and any name in B2 in LIST.
if (!m_relations[bb->index].m_names)
return;
- relation_chain *ptr = m_relations[bb->index].m_head;
- for (; ptr; ptr = ptr->m_next)
+ value_relation vr;
+ FOR_EACH_RELATION_BB (this, bb, vr)
{
fprintf (f, "Relational : ");
- ptr->dump (f);
+ vr.dump (f);
fprintf (f, "\n");
}
}
void debug () const;
protected:
friend class equiv_relation_iterator;
+ friend class block_relation_iterator;
+ virtual class relation_chain *next_relation (basic_block,
+ relation_chain *,
+ tree) const
+ { return NULL; }
// Return equivalency set for an SSA name in a basic block.
virtual const_bitmap equiv_set (tree, basic_block) { return NULL; }
// Return partial equivalency record for an SSA name.
void dump (FILE *f, basic_block bb) const final override;
void dump (FILE *f) const final override;
-private:
+protected:
+ virtual relation_chain *next_relation (basic_block, relation_chain *,
+ tree) const;
bool m_do_trans_p;
bitmap m_tmp, m_tmp2;
bitmap m_relation_set; // Index by ssa-name. True if a relation exists
relation_trio create_trio (tree lhs, tree op1, tree op2);
bool union_ (value_relation &p);
bool intersect (value_relation &p);
- void negate ();
+ void swap ();
bool apply_transitive (const value_relation &rel);
void dump (FILE *f) const;
set_relation (kind, n1, n2);
}
+
+class block_relation_iterator {
+public:
+ block_relation_iterator (const relation_oracle *oracle, basic_block bb,
+ value_relation &, tree name = NULL);
+ void get_next_relation (value_relation &vr);
+ const relation_oracle *m_oracle;
+ basic_block m_bb;
+ relation_chain *m_ptr;
+ bool m_done;
+ tree m_name;
+};
+
+#define FOR_EACH_RELATION_BB(oracle, bb, vr) \
+ for (block_relation_iterator iter (oracle, bb, vr); \
+ !iter.m_done; \
+ iter.get_next_relation (vr))
+
+#define FOR_EACH_RELATION_NAME(oracle, bb, name, vr) \
+ for (block_relation_iterator iter (oracle, bb, vr, name); \
+ !iter.m_done; \
+ iter.get_next_relation (vr))
+
+
// Return the number of bits associated with partial equivalency T.
// Return 0 if this is not a supported partial equivalency relation.