https://gcc.gnu.org/g:8d0ec97fc6629f2d2bac00e1926a9aea9ef81a0c
commit r16-249-g8d0ec97fc6629f2d2bac00e1926a9aea9ef81a0c Author: Andrew MacLeod <amacl...@redhat.com> Date: Mon Feb 10 16:14:17 2025 -0500 Add a Relation iterator to the relation oracle. This patch adds a relation iterator to query the oracle to list either all the relations on exit to a block, or just ones involving a specified SSA_NAME. The oracle then uses this iterator internally as well. * value-relation.cc (value_relation::swap): New. (value_relation::negate): Remove. (dom_oracle::next_relation): New. (block_relation_iterator::block_relation_iterator): New. (block_relation_iterator::get_next_relation): New. (dom_oracle::dump): Use iterator. * value-relation.h (relation_oracle::next_relation): New. (dom_oracle::next_relation): New prototype. (class block_relation_iterator): New. (FOR_EACH_RELATION_BB): New. (FOR_EACH_RELATION_NAME): New. Diff: --- gcc/value-relation.cc | 90 +++++++++++++++++++++++++++++++++++++++++++++++---- gcc/value-relation.h | 35 ++++++++++++++++++-- 2 files changed, 117 insertions(+), 8 deletions(-) diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc index 08449b72d9a9..c7ced445ad76 100644 --- a/gcc/value-relation.cc +++ b/gcc/value-relation.cc @@ -780,15 +780,20 @@ equiv_oracle::dump (FILE *f) const // -------------------------------------------------------------------------- -// 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) @@ -951,6 +956,79 @@ public: 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. @@ -1441,11 +1519,11 @@ dom_oracle::dump (FILE *f, basic_block bb) const 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"); } } diff --git a/gcc/value-relation.h b/gcc/value-relation.h index 23cfb41c6357..1081877ccca7 100644 --- a/gcc/value-relation.h +++ b/gcc/value-relation.h @@ -114,6 +114,11 @@ public: 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. @@ -228,7 +233,9 @@ public: 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 @@ -431,7 +438,7 @@ public: 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; @@ -470,6 +477,30 @@ value_relation::value_relation (relation_kind kind, tree n1, tree n2) 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.