LCOV - code coverage report
Current view: top level - gcc - value-relation.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 91.0 % 67 61
Test Date: 2026-08-22 16:33:35 Functions: 66.7 % 15 10
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Header file for the value range relational processing.
       2              :    Copyright (C) 2020-2026 Free Software Foundation, Inc.
       3              :    Contributed by Andrew MacLeod <amacleod@redhat.com>
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              :  for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #ifndef GCC_VALUE_RELATION_H
      22              : #define GCC_VALUE_RELATION_H
      23              : 
      24              : 
      25              : // This file provides access to a relation oracle which can be used to
      26              : // maintain and query relations and equivalences between SSA_NAMES.
      27              : //
      28              : // The general range_query object provided in value-query.h provides
      29              : // access to an oracle, if one is available, via the oracle() method.
      30              : // There are also a couple of access routines provided, which even if there is
      31              : // no oracle, will return the default VREL_VARYING no relation.
      32              : //
      33              : // Typically, when a ranger object is active, there will be an oracle, and
      34              : // any information available can be directly queried.  Ranger also sets and
      35              : // utilizes the relation information to enhance it's range calculations, this
      36              : // is totally transparent to the client, and they are free to make queries.
      37              : //
      38              : // relation_kind is a new enum which represents the different relations,
      39              : // often with a direct mapping to tree codes. ie VREL_EQ is equivalent to
      40              : // EQ_EXPR.
      41              : //
      42              : // A query is made requesting the relation between SSA1 and SSA@ in a basic
      43              : // block, or on an edge, the possible return values are:
      44              : //
      45              : //  VREL_EQ, VREL_NE, VREL_LT, VREL_LE, VREL_GT, and VREL_GE mean the same.
      46              : //  VREL_VARYING : No relation between the 2 names.
      47              : //  VREL_UNDEFINED : Impossible relation (ie, A < B && A > B)
      48              : //
      49              : // The oracle maintains VREL_EQ relations with equivalency sets, so if a
      50              : // relation comes back VREL_EQ, it is also possible to query the set of
      51              : // equivalencies.  These are basically bitmaps over ssa_names.  An iterator is
      52              : // provided later for this activity.
      53              : //
      54              : // Relations are maintained via the dominance trees and are optimized assuming
      55              : // they are registered in dominance order.   When a new relation is added, it
      56              : // is intersected with whatever existing relation exists in the dominance tree
      57              : // and registered at the specified block.
      58              : 
      59              : 
      60              : // These codes are arranged such that VREL_VARYING is the first code, and all
      61              : // the rest are contiguous.
      62              : 
      63              : typedef enum relation_kind_t
      64              : {
      65              :   VREL_VARYING = 0,     // No known relation,  AKA varying.
      66              :   VREL_UNDEFINED,       // Impossible relation, ie (r1 < r2) && (r2 > r1)
      67              :   VREL_LT,              // r1 < r2
      68              :   VREL_LE,              // r1 <= r2
      69              :   VREL_GT,              // r1 > r2
      70              :   VREL_GE,              // r1 >= r2
      71              :   VREL_EQ,              // r1 == r2
      72              :   VREL_NE,              // r1 != r2
      73              :   VREL_PE8,             // 8 bit partial equivalency
      74              :   VREL_PE16,            // 16 bit partial equivalency
      75              :   VREL_PE32,            // 32 bit partial equivalency
      76              :   VREL_PE64,            // 64 bit partial equivalency
      77              :   VREL_LAST             // terminate, not a real relation.
      78              : } relation_kind;
      79              : 
      80              : // General relation kind transformations.
      81              : relation_kind relation_union (relation_kind r1, relation_kind r2);
      82              : relation_kind relation_intersect (relation_kind r1, relation_kind r2);
      83              : relation_kind relation_negate (relation_kind r);
      84              : relation_kind relation_swap (relation_kind r);
      85      5178829 : inline bool relation_lt_le_gt_ge_p (relation_kind r)
      86      5178829 :                       { return (r >= VREL_LT && r <= VREL_GE); }
      87    210870368 : inline bool relation_partial_equiv_p (relation_kind r)
      88    123692941 :                       { return (r >= VREL_PE8 && r <= VREL_PE64); }
      89    183625207 : inline bool relation_equiv_p (relation_kind r)
      90    183625219 :                       { return r == VREL_EQ || relation_partial_equiv_p (r); }
      91              : 
      92              : void print_relation (FILE *f, relation_kind rel);
      93              : 
      94              : // Adjust range as an equivalence.
      95              : void adjust_equivalence_range (vrange &range);
      96              : 
      97              : class relation_oracle
      98              : {
      99              : public:
     100     59134804 :   relation_oracle () { m_lhs_equiv_set_p = NULL; }
     101     59427830 :   virtual ~relation_oracle () { }
     102              : 
     103              :   // register a relation between 2 ssa names.
     104              :   bool record (gimple *, relation_kind, tree, tree);
     105              :   bool record (edge, relation_kind, tree, tree);
     106      1064567 :   virtual bool record (basic_block, relation_kind, tree, tree) { return false; }
     107              : 
     108              :   // Query if there is any relation between SSA1 and SSA2.
     109              :   relation_kind query (gimple *s, tree ssa1, tree ssa2);
     110              :   relation_kind query (edge e, tree ssa1, tree ssa2);
     111     14587788 :   virtual relation_kind query (basic_block, tree, tree) { return VREL_VARYING; }
     112              : 
     113              :   // Remove relations for an SSA_NAME
     114      7879420 :   virtual void clear (tree) { }
     115              : 
     116            0 :   virtual void dump (FILE *, basic_block) const { }
     117            0 :   virtual void dump (FILE *) const  { }
     118              :   void debug () const;
     119              : protected:
     120              :   friend class equiv_relation_iterator;
     121              :   friend class block_relation_iterator;
     122            0 :   virtual class relation_chain *next_relation (basic_block,
     123              :                                                relation_chain *,
     124              :                                                tree) const
     125            0 :     { return NULL; }
     126              :   // Return equivalency set for an SSA name in a basic block.
     127            1 :   virtual const_bitmap equiv_set (tree, basic_block) { return NULL; }
     128              :   // Return partial equivalency record for an SSA name.
     129            1 :   virtual const class pe_slice *partial_equiv_set (tree) { return NULL; }
     130              :   void valid_equivs (bitmap b, const_bitmap equivs, basic_block bb);
     131              :   // Query for a relation between two equivalency sets in a basic block.
     132            0 :   virtual relation_kind query (basic_block, const_bitmap, const_bitmap)
     133            0 :     { return VREL_VARYING; }
     134              :   friend class path_oracle;
     135              :   // Used to Avoid registering multiple eqiuvalences from the same statement.
     136              :   bitmap m_lhs_equiv_set_p;
     137              : };
     138              : 
     139              : // Instance with no storage used for default queries with no active oracle.
     140              : extern relation_oracle default_relation_oracle;
     141              : 
     142              : // This class represents an equivalency set, and contains a link to the next
     143              : // one in the list to be searched.
     144              : 
     145              : class equiv_chain
     146              : {
     147              : public:
     148              :   bitmap m_names;               // ssa-names in equiv set.
     149              :   basic_block m_bb;             // Block this belongs to
     150              :   equiv_chain *m_next;          // Next in block list.
     151              :   void dump (FILE *f) const;    // Show names in this list.
     152              :   equiv_chain *find (unsigned ssa);
     153              : };
     154              : 
     155              : class pe_slice
     156              : {
     157              : public:
     158              :   tree ssa_base;        // Slice of this name.
     159              :   relation_kind code;   // bits that are equivalent.
     160              :   bitmap members;       // Other members in the partial equivalency.
     161              : };
     162              : 
     163              : // The equivalency oracle maintains equivalencies using the dominator tree.
     164              : // Equivalencies apply to an entire basic block.  Equivalencies on edges
     165              : // can be represented only on edges whose destination is a single-pred block,
     166              : // and the equivalence is simply applied to that successor block.
     167              : 
     168              : class equiv_oracle : public relation_oracle
     169              : {
     170              : public:
     171              :   equiv_oracle ();
     172              :   ~equiv_oracle ();
     173              : 
     174              :   const_bitmap equiv_set (tree ssa, basic_block bb) final override;
     175              :   bool record (basic_block bb, relation_kind k, tree ssa1, tree ssa2) override;
     176              : 
     177              :   relation_kind partial_equiv (tree ssa1, tree ssa2, tree *base = NULL) const;
     178              :   relation_kind query (basic_block, tree, tree) override;
     179              :   relation_kind query (basic_block, const_bitmap, const_bitmap) override;
     180              : 
     181              :   virtual void clear (tree name);
     182              :   void dump (FILE *f, basic_block bb) const override;
     183              :   void dump (FILE *f) const override;
     184              : 
     185              : protected:
     186              :   bool add_partial_equiv (relation_kind, tree, tree);
     187              :   const pe_slice *partial_equiv_set (tree name) final override;
     188     86382160 :   inline bool has_equiv_p (unsigned v) { return bitmap_bit_p (m_equiv_set, v); }
     189              :   bitmap_obstack m_bitmaps;
     190              :   struct obstack m_chain_obstack;
     191              : private:
     192              :   bitmap m_equiv_set;   // Index by ssa-name. true if an equivalence exists.
     193              :   vec <equiv_chain *> m_equiv;    // Index by BB.  list of equivalences.
     194              :   class name_info
     195              :   {
     196              :   public:
     197              :     bitmap m_self_equiv;        // Self equivalency set.
     198              :     bitmap m_block_list;        // BB's name occurs in equivalencies.
     199              :   };
     200              :   vec <name_info> m_name_info;    // Index by ssa-name.
     201              :   vec <pe_slice> m_partial;  // Partial equivalencies.
     202              : 
     203              :   void limit_check (basic_block bb = NULL);
     204              :   equiv_chain *find_equiv_block (unsigned ssa, int bb) const;
     205              :   equiv_chain *find_equiv_dom (tree name, basic_block bb) const;
     206              : 
     207              :   bitmap register_equiv (basic_block bb, unsigned v, equiv_chain *equiv_1);
     208              :   bitmap register_equiv (basic_block bb, equiv_chain *equiv_1,
     209              :                          equiv_chain *equiv_2);
     210              : 
     211              :   void register_equiv_block (unsigned v, unsigned bbi);
     212              :   void register_equiv_block (const_bitmap equiv, basic_block bb);
     213              : 
     214              :   void register_initial_def (tree ssa);
     215              :   void add_equiv_to_block (basic_block bb, bitmap equiv);
     216              : };
     217              : 
     218              : // Summary block header for relations.
     219              : 
     220              : class relation_chain_head
     221              : {
     222              : public:
     223              :   bitmap m_names;               // ssa_names with relations in this block.
     224              :   class relation_chain *m_head; // List of relations in block.
     225              :   int m_num_relations;          // Number of relations in block.
     226              :   relation_kind find_relation (const_bitmap b1, const_bitmap b2) const;
     227              :   void clear (tree name);
     228              : };
     229              : 
     230              : // A relation oracle maintains a set of relations between ssa_names using the
     231              : // dominator tree structures.  Equivalencies are considered a subset of
     232              : // a general relation and maintained by an equivalence oracle by transparently
     233              : // passing any EQ_EXPR relations to it.
     234              : // Relations are handled at the basic block level.  All relations apply to
     235              : // an entire block, and are thus kept in a summary index by block.
     236              : // Similar to the equivalence oracle, edges are handled by applying the
     237              : // relation to the destination block of the edge, but ONLY if that block
     238              : // has a single successor.  For now.
     239              : 
     240              : class dom_oracle : public equiv_oracle
     241              : {
     242              : public:
     243              :   dom_oracle (bool do_trans_p = true);
     244              :   ~dom_oracle ();
     245              : 
     246              :   bool record (basic_block bb, relation_kind k, tree op1, tree op2)
     247              :     final override;
     248              : 
     249              :   relation_kind query (basic_block bb, tree ssa1, tree ssa2) final override;
     250              :   relation_kind query (basic_block bb, const_bitmap b1, const_bitmap b2)
     251              :     final override;
     252              : 
     253              :   virtual void clear (tree name);
     254              : 
     255              :   void dump (FILE *f, basic_block bb) const final override;
     256              :   void dump (FILE *f) const final override;
     257              : protected:
     258              :   virtual relation_chain *next_relation (basic_block, relation_chain *,
     259              :                                          tree) const override;
     260              :   bool m_do_trans_p;
     261              :   bitmap m_tmp, m_tmp2;
     262              :   bitmap m_relation_set;  // Index by ssa-name. True if a relation exists
     263              :   vec <relation_chain_head> m_relations;  // Index by BB, list of relations.
     264              :   vec <bitmap> m_block_list;      // Index by ssa-name.  Blocks with relations.
     265              :   relation_kind find_relation_block (unsigned bb, const_bitmap b1,
     266              :                                      const_bitmap b2) const;
     267              :   relation_kind find_relation_block (int bb, tree ssa1, tree ssa2,
     268              :                                      relation_chain **obj = NULL) const;
     269              :   relation_kind find_relation_dom (basic_block bb, tree ssa1, tree ssa2) const;
     270              :   relation_chain *create_relation_in_bb (basic_block bb, relation_kind k,
     271              :                                          tree op1, tree op2);
     272              :   relation_chain *search_and_merge_relation (basic_block bb, relation_kind k,
     273              :                                              tree op1, tree op2);
     274              :   void record_relation_block (unsigned v, unsigned bbi);
     275              :   void register_transitives (basic_block, const class value_relation &);
     276              :   relation_kind recomputed_relation (basic_block, edge, tree, tree) const;
     277              : };
     278              : 
     279              : // A path_oracle implements relations in a list.  The only sense of ordering
     280              : // is the latest registered relation is the first found during a search.
     281              : // It can be constructed with an optional "root" oracle which will be used
     282              : // to look up any relations not found in the list.
     283              : // This allows the client to walk paths starting at some block and register
     284              : // and query relations along that path, ignoring other edges.
     285              : //
     286              : // For registering a relation, a query if made of the root oracle if there is
     287              : // any known relationship at block BB, and it is combined with this new
     288              : // relation and entered in the list.
     289              : //
     290              : // Queries are resolved by looking first in the list, and only if nothing is
     291              : // found is the root oracle queried at block BB.
     292              : //
     293              : // reset_path is used to clear all locally registered paths to initial state.
     294              : 
     295              : class path_oracle : public relation_oracle
     296              : {
     297              : public:
     298              :   path_oracle (relation_oracle *oracle = NULL);
     299              :   ~path_oracle ();
     300              :   const_bitmap equiv_set (tree, basic_block) final override;
     301              :   bool record (basic_block, relation_kind, tree, tree) final override;
     302              :   void killing_def (tree);
     303              :   relation_kind query (basic_block, tree, tree) final override;
     304              :   relation_kind query (basic_block, const_bitmap, const_bitmap) final override;
     305              :   void reset_path (relation_oracle *oracle = NULL);
     306     56495554 :   void set_root_oracle (relation_oracle *oracle) { m_root = oracle; }
     307              : 
     308              :   virtual void clear (tree name);
     309              : 
     310              :   void dump (FILE *, basic_block) const final override;
     311              :   void dump (FILE *) const final override;
     312              : private:
     313              :   bool register_equiv (basic_block bb, tree ssa1, tree ssa2);
     314              :   equiv_chain m_equiv;
     315              :   relation_chain_head m_relations;
     316              :   relation_oracle *m_root;
     317              :   bitmap m_killed_defs;
     318              : 
     319              :   bitmap_obstack m_bitmaps;
     320              :   struct obstack m_chain_obstack;
     321              : };
     322              : 
     323              : // Used to assist with iterating over the equivalence list.
     324              : class equiv_relation_iterator {
     325              : public:
     326              :   equiv_relation_iterator (relation_oracle *oracle, basic_block bb, tree name,
     327              :                            bool full = true, bool partial = false);
     328              :   void next ();
     329              :   tree get_name (relation_kind *rel = NULL);
     330              : protected:
     331              :   relation_oracle *m_oracle;
     332              :   const_bitmap m_bm;
     333              :   const pe_slice *m_pe;
     334              :   bitmap_iterator m_bi;
     335              :   unsigned m_y;
     336              :   tree m_name;
     337              : };
     338              : 
     339              : #define FOR_EACH_EQUIVALENCE(oracle, bb, name, equiv_name)              \
     340              :   for (equiv_relation_iterator iter (oracle, bb, name, true, false);    \
     341              :        ((equiv_name) = iter.get_name ());                               \
     342              :        iter.next ())
     343              : 
     344              : #define FOR_EACH_PARTIAL_EQUIV(oracle, bb, name, equiv_name, equiv_rel) \
     345              :   for (equiv_relation_iterator iter (oracle, bb, name, false, true);    \
     346              :        ((equiv_name) = iter.get_name (&equiv_rel));                 \
     347              :        iter.next ())
     348              : 
     349              : #define FOR_EACH_PARTIAL_AND_FULL_EQUIV(oracle, bb, name, equiv_name,   \
     350              :                                                       equiv_rel)        \
     351              :   for (equiv_relation_iterator iter (oracle, bb, name, true, true);     \
     352              :        ((equiv_name) = iter.get_name (&equiv_rel));                 \
     353              :        iter.next ())
     354              : 
     355              : // -----------------------------------------------------------------------
     356              : 
     357              : // Range-ops deals with a LHS and 2 operands. A relation trio is a set of
     358              : // 3 potential relations packed into a single unsigned value.
     359              : //  1 - LHS relation OP1
     360              : //  2 - LHS relation OP2
     361              : //  3 - OP1 relation OP2
     362              : //  VREL_VARYING is a value of 0, and is the default for each position.
     363              : class relation_trio
     364              : {
     365              : public:
     366              :   relation_trio ();
     367              :   relation_trio (relation_kind lhs_op1, relation_kind lhs_op2,
     368              :                  relation_kind op1_op2);
     369              :   relation_kind lhs_op1 ();
     370              :   relation_kind lhs_op2 ();
     371              :   relation_kind op1_op2 ();
     372              :   relation_trio swap_op1_op2 ();
     373              : 
     374              :   static relation_trio lhs_op1 (relation_kind k);
     375              :   static relation_trio lhs_op2 (relation_kind k);
     376              :   static relation_trio op1_op2 (relation_kind k);
     377              : 
     378              : protected:
     379              :   unsigned m_val;
     380              : };
     381              : 
     382              : //  Default VREL_VARYING for all 3 relations.
     383              : #define TRIO_VARYING    relation_trio ()
     384              : 
     385              : #define TRIO_SHIFT      4
     386              : #define TRIO_MASK       0x000F
     387              : 
     388              : // These 3 classes are shortcuts for when a caller has a single relation to
     389              : // pass as a trio, it can simply construct the appropriate one.  The other
     390              : // unspecified relations will be VREL_VARYING.
     391              : 
     392    270224219 : inline relation_trio::relation_trio ()
     393              : {
     394    270224219 :   STATIC_ASSERT (VREL_LAST <= (1 << TRIO_SHIFT));
     395    270224219 :   m_val = 0;
     396              : }
     397              : 
     398    242057095 : inline relation_trio::relation_trio (relation_kind lhs_op1,
     399              :                                      relation_kind lhs_op2,
     400              :                                      relation_kind op1_op2)
     401              : {
     402    242057095 :   STATIC_ASSERT (VREL_LAST <= (1 << TRIO_SHIFT));
     403    242057095 :   unsigned i1 = (unsigned) lhs_op1;
     404    242057095 :   unsigned i2 = ((unsigned) lhs_op2) << TRIO_SHIFT;
     405    242057095 :   unsigned i3 = ((unsigned) op1_op2) << (TRIO_SHIFT * 2);
     406    241932440 :   m_val = i1 | i2 | i3;
     407              : }
     408              : 
     409              : inline relation_trio
     410       738958 : relation_trio::lhs_op1 (relation_kind k)
     411              : {
     412       738958 :   return relation_trio (k, VREL_VARYING, VREL_VARYING);
     413              : }
     414              : inline relation_trio
     415       608275 : relation_trio::lhs_op2 (relation_kind k)
     416              : {
     417       608275 :   return relation_trio (VREL_VARYING, k, VREL_VARYING);
     418              : }
     419              : inline relation_trio
     420    176260784 : relation_trio::op1_op2 (relation_kind k)
     421              : {
     422    176260784 :   return relation_trio (VREL_VARYING, VREL_VARYING, k);
     423              : }
     424              : 
     425              : inline relation_kind
     426     21177992 : relation_trio::lhs_op1 ()
     427              : {
     428     11779795 :   return (relation_kind) (m_val & TRIO_MASK);
     429              : }
     430              : 
     431              : inline relation_kind
     432      9663453 : relation_trio::lhs_op2 ()
     433              : {
     434      9804053 :   return (relation_kind) ((m_val >> TRIO_SHIFT) & TRIO_MASK);
     435              : }
     436              : 
     437              : inline relation_kind
     438    326107347 : relation_trio::op1_op2 ()
     439              : {
     440    316443895 :   return (relation_kind) ((m_val >> (TRIO_SHIFT * 2)) & TRIO_MASK);
     441              : }
     442              : 
     443              : inline relation_trio
     444      9663452 : relation_trio::swap_op1_op2 ()
     445              : {
     446      9663452 :   return relation_trio (lhs_op2 (), lhs_op1 (), relation_swap (op1_op2 ()));
     447              : }
     448              : 
     449              : // -----------------------------------------------------------------------
     450              : 
     451              : // The value-relation class is used to encapsulate the representation of an
     452              : // individual relation between 2 ssa-names, and to facilitate operating on
     453              : // the relation.
     454              : 
     455              : class value_relation
     456              : {
     457              : public:
     458              :   value_relation ();
     459              :   value_relation (relation_kind kind, tree n1, tree n2);
     460              :   void set_relation (relation_kind kind, tree n1, tree n2);
     461              : 
     462     30562687 :   inline relation_kind kind () const { return related; }
     463    142657310 :   inline tree op1 () const { return name1; }
     464    139697512 :   inline tree op2 () const { return name2; }
     465              : 
     466              :   relation_trio create_trio (tree lhs, tree op1, tree op2);
     467              :   bool union_ (value_relation &p);
     468              :   bool intersect (value_relation &p);
     469              :   void swap ();
     470              :   bool apply_transitive (const value_relation &rel);
     471              : 
     472              :   void dump (FILE *f) const;
     473              : private:
     474              :   relation_kind related;
     475              :   tree name1, name2;
     476              : };
     477              : 
     478              : // Set relation R between ssa_name N1 and N2.
     479              : 
     480              : inline void
     481     98042726 : value_relation::set_relation (relation_kind r, tree n1, tree n2)
     482              : {
     483     98042726 :   gcc_checking_assert (TREE_CODE (n1) == SSA_NAME
     484              :                        && TREE_CODE (n2) == SSA_NAME);
     485     98042726 :   related = r;
     486     98042726 :   name1 = n1;
     487     98042726 :   name2 = n2;
     488     98042726 : }
     489              : 
     490              : // Default constructor.
     491              : 
     492              : inline
     493    127651892 : value_relation::value_relation ()
     494              : {
     495    127651892 :   related = VREL_VARYING;
     496    127651892 :   name1 = NULL_TREE;
     497    127651892 :   name2 = NULL_TREE;
     498              : }
     499              : 
     500              : // Constructor for relation R between SSA version N1 and N2.
     501              : 
     502              : inline
     503     16374349 : value_relation::value_relation (relation_kind kind, tree n1, tree n2)
     504              : {
     505     16374349 :   set_relation (kind, n1, n2);
     506              : }
     507              : 
     508              : 
     509              : class block_relation_iterator {
     510              : public:
     511              :   block_relation_iterator (const relation_oracle *oracle, basic_block bb,
     512              :                            value_relation &, tree name = NULL);
     513              :   void get_next_relation (value_relation &vr);
     514              :   const relation_oracle *m_oracle;
     515              :   basic_block m_bb;
     516              :   relation_chain *m_ptr;
     517              :   bool m_done;
     518              :   tree m_name;
     519              : };
     520              : 
     521              : #define FOR_EACH_RELATION_BB(oracle, bb, vr)                    \
     522              :   for (block_relation_iterator iter (oracle, bb, vr);           \
     523              :        !iter.m_done;                                            \
     524              :        iter.get_next_relation (vr))
     525              : 
     526              : #define FOR_EACH_RELATION_NAME(oracle, bb, name, vr)            \
     527              :   for (block_relation_iterator iter (oracle, bb, vr, name);     \
     528              :        !iter.m_done;                                            \
     529              :        iter.get_next_relation (vr))
     530              : 
     531              : 
     532              : // Return the number of bits associated with partial equivalency T.
     533              : // Return 0 if this is not a supported partial equivalency relation.
     534              : 
     535              : inline int
     536     18024564 : pe_to_bits (relation_kind t)
     537              : {
     538     18024564 :   switch (t)
     539              :   {
     540              :     case VREL_PE8:
     541              :       return 8;
     542              :     case VREL_PE16:
     543              :       return 16;
     544              :     case VREL_PE32:
     545              :       return 32;
     546              :     case VREL_PE64:
     547              :       return 64;
     548              :     default:
     549              :       return 0;
     550              :   }
     551              : }
     552              : 
     553              : // Return the partial equivalency code associated with the number of BITS.
     554              : // return VREL_VARYING if there is no exact match.
     555              : 
     556              : inline relation_kind
     557     39039594 : bits_to_pe (int bits)
     558              : {
     559     39039594 :   switch (bits)
     560              :   {
     561              :     case 8:
     562              :       return VREL_PE8;
     563              :     case 16:
     564              :       return VREL_PE16;
     565              :     case 32:
     566              :       return VREL_PE32;
     567              :     case 64:
     568              :       return VREL_PE64;
     569              :     default:
     570              :       return VREL_VARYING;
     571              :   }
     572              : }
     573              : 
     574              : // Given partial equivalencies T1 and T2, return the smallest kind.
     575              : 
     576              : inline relation_kind
     577      9774057 : pe_min (relation_kind t1, relation_kind t2)
     578              : {
     579      9774057 :   gcc_checking_assert (relation_partial_equiv_p (t1));
     580      9774057 :   gcc_checking_assert (relation_partial_equiv_p (t2));
     581              :   // VREL_PE are declared small to large, so simple min will suffice.
     582      9774057 :   return MIN (t1, t2);
     583              : }
     584              : #endif  /* GCC_VALUE_RELATION_H */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.