LCOV - code coverage report
Current view: top level - gcc - ipa-predicate.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 90.7 % 322 292
Test Date: 2026-05-30 15:37:04 Functions: 93.3 % 15 14
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* IPA predicates.
       2              :    Copyright (C) 2003-2026 Free Software Foundation, Inc.
       3              :    Contributed by Jan Hubicka
       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              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "backend.h"
      25              : #include "tree.h"
      26              : #include "cgraph.h"
      27              : #include "tree-vrp.h"
      28              : #include "alloc-pool.h"
      29              : #include "symbol-summary.h"
      30              : #include "sreal.h"
      31              : #include "ipa-cp.h"
      32              : #include "ipa-prop.h"
      33              : #include "ipa-fnsummary.h"
      34              : #include "real.h"
      35              : #include "fold-const.h"
      36              : #include "tree-pretty-print.h"
      37              : #include "gimple.h"
      38              : #include "gimplify.h"
      39              : #include "data-streamer.h"
      40              : 
      41              : 
      42              : /* Check whether two set of operations have same effects.  */
      43              : static bool
      44     14585278 : expr_eval_ops_equal_p (expr_eval_ops ops1, expr_eval_ops ops2)
      45              : {
      46     14585278 :   if (ops1)
      47              :     {
      48      1020580 :       if (!ops2 || ops1->length () != ops2->length ())
      49              :         return false;
      50              : 
      51      1477301 :       for (unsigned i = 0; i < ops1->length (); i++)
      52              :         {
      53      1042447 :           expr_eval_op &op1 = (*ops1)[i];
      54      1042447 :           expr_eval_op &op2 = (*ops2)[i];
      55              : 
      56      1042447 :           if (op1.code != op2.code
      57       914498 :               || op1.index != op2.index
      58       914498 :               || !vrp_operand_equal_p (op1.val[0], op2.val[0])
      59       677160 :               || !vrp_operand_equal_p (op1.val[1], op2.val[1])
      60      1719607 :               || !types_compatible_p (op1.type, op2.type))
      61       367302 :             return false;
      62              :         }
      63              :       return true;
      64              :     }
      65     13564698 :   return !ops2;
      66              : }
      67              : 
      68              : /* Add clause CLAUSE into the predicate P.
      69              :    When CONDITIONS is NULL do not perform checking whether NEW_CLAUSE
      70              :    is obviously true.  This is useful only when NEW_CLAUSE is known to be
      71              :    sane.  */
      72              : 
      73              : void
      74     48572940 : ipa_predicate::add_clause (conditions conditions, clause_t new_clause)
      75              : {
      76     48572940 :   int i;
      77     48572940 :   int i2;
      78     48572940 :   int insert_here = -1;
      79     48572940 :   int c1, c2;
      80              : 
      81              :   /* True clause.  */
      82     48572940 :   if (!new_clause)
      83              :     return;
      84              : 
      85              :   /* False clause makes the whole predicate false.  Kill the other variants.  */
      86     48572940 :   if (new_clause == (1 << ipa_predicate::false_condition))
      87              :     {
      88            0 :       *this = false;
      89            0 :       return;
      90              :     }
      91     48572940 :   if (*this == false)
      92              :     return;
      93              : 
      94              :   /* No one should be silly enough to add false into nontrivial clauses.  */
      95     48572940 :   gcc_checking_assert (!(new_clause & (1 << ipa_predicate::false_condition)));
      96              : 
      97              :   /* Look where to insert the new_clause.  At the same time prune out
      98              :      new_clauses of P that are implied by the new new_clause and thus
      99              :      redundant.  */
     100    128869874 :   for (i = 0, i2 = 0; i <= max_clauses; i++)
     101              :     {
     102    128869874 :       m_clause[i2] = m_clause[i];
     103              : 
     104    128869874 :       if (!m_clause[i])
     105              :         break;
     106              : 
     107              :       /* If m_clause[i] implies new_clause, there is nothing to add.  */
     108     91606369 :       if ((m_clause[i] & new_clause) == m_clause[i])
     109              :         {
     110              :           /* We had nothing to add, none of clauses should've become
     111              :              redundant.  */
     112     11309435 :           gcc_checking_assert (i == i2);
     113              :           return;
     114              :         }
     115              : 
     116     80296934 :       if (m_clause[i] < new_clause && insert_here < 0)
     117     80296934 :         insert_here = i2;
     118              : 
     119              :       /* If new_clause implies clause[i], then clause[i] becomes redundant.
     120              :          Otherwise the clause[i] has to stay.  */
     121     80296934 :       if ((m_clause[i] & new_clause) != new_clause)
     122     77076846 :         i2++;
     123              :     }
     124              : 
     125              :   /* Look for clauses that are obviously true.  I.e.
     126              :      op0 == 5 || op0 != 5.  */
     127     37263505 :   if (conditions)
     128    281022880 :     for (c1 = ipa_predicate::first_dynamic_condition;
     129    291606533 :          c1 < num_conditions; c1++)
     130              :       {
     131    282321822 :         condition *cc1;
     132    282321822 :         if (!(new_clause & (1 << c1)))
     133    253982709 :           continue;
     134     28339113 :         cc1 = &(*conditions)[c1 - ipa_predicate::first_dynamic_condition];
     135              :         /* We have no way to represent !changed and !is_not_constant
     136              :            and thus there is no point for looking for them.  */
     137     28339113 :         if (cc1->code == changed || cc1->code == is_not_constant || cc1->code == not_sra_candidate)
     138      6865850 :           continue;
     139    483126404 :         for (c2 = c1 + 1; c2 < num_conditions; c2++)
     140    462952083 :           if (new_clause & (1 << c2))
     141              :             {
     142     38865800 :               condition *cc2 =
     143     38865800 :                 &(*conditions)[c2 - ipa_predicate::first_dynamic_condition];
     144     38865800 :               if (cc1->operand_num == cc2->operand_num
     145     33923384 :                   && vrp_operand_equal_p (cc1->val, cc2->val)
     146      2692305 :                   && cc2->code != is_not_constant
     147      2692305 :                   && cc2->code != not_sra_candidate
     148      2692305 :                   && cc2->code != changed
     149      2692305 :                   && expr_eval_ops_equal_p (cc1->param_ops, cc2->param_ops)
     150      2092900 :                   && cc2->agg_contents == cc1->agg_contents
     151      1931284 :                   && cc2->by_ref == cc1->by_ref
     152      1929504 :                   && types_compatible_p (cc2->type, cc1->type)
     153     40730206 :                   && cc1->code == invert_tree_comparison (cc2->code,
     154      1864406 :                                                           HONOR_NANS (cc1->val)))
     155              :                 return;
     156              :             }
     157              :       }
     158              : 
     159              : 
     160              :   /* We run out of variants.  Be conservative in positive direction.  */
     161     35964563 :   if (i2 == max_clauses)
     162              :     return;
     163              :   /* Keep clauses in decreasing order. This makes equivalence testing easy.  */
     164     35701969 :   m_clause[i2 + 1] = 0;
     165     35701969 :   if (insert_here >= 0)
     166     44076482 :     for (; i2 > insert_here; i2--)
     167     25784408 :       m_clause[i2] = m_clause[i2 - 1];
     168              :   else
     169              :     insert_here = i2;
     170     35701969 :   m_clause[insert_here] = new_clause;
     171              : }
     172              : 
     173              : 
     174              : /* Do THIS &= P.  */
     175              : 
     176              : ipa_predicate &
     177    444436839 : ipa_predicate::operator &= (const ipa_predicate &p)
     178              : {
     179              :   /* Avoid busy work.  */
     180    444436839 :   if (p == false || *this == true)
     181              :     {
     182    345900580 :       *this = p;
     183    345900580 :       return *this;
     184              :     }
     185     98536259 :   if (*this == false || p == true || this == &p)
     186              :     return *this;
     187              : 
     188              :   int i;
     189              : 
     190              :   /* See how far ipa_predicates match.  */
     191     69891996 :   for (i = 0; m_clause[i] && m_clause[i] == p.m_clause[i]; i++)
     192              :     {
     193     26857832 :       gcc_checking_assert (i < max_clauses);
     194              :     }
     195              : 
     196              :   /* Combine the ipa_predicates rest.  */
     197     76293116 :   for (; p.m_clause[i]; i++)
     198              :     {
     199     33258952 :       gcc_checking_assert (i < max_clauses);
     200     33258952 :       add_clause (NULL, p.m_clause[i]);
     201              :     }
     202              :   return *this;
     203              : }
     204              : 
     205              : 
     206              : 
     207              : /* Return THIS | P2.  */
     208              : 
     209              : ipa_predicate
     210    123185419 : ipa_predicate::or_with (conditions conditions,
     211              :                         const ipa_predicate &p) const
     212              : {
     213              :   /* Avoid busy work.  */
     214    123185419 :   if (p == false || *this == true || *this == p)
     215     15980658 :     return *this;
     216    107204761 :   if (*this == false || p == true)
     217    102446485 :     return p;
     218              : 
     219              :   /* OK, combine the predicates.  */
     220      4758276 :   ipa_predicate out = true;
     221              : 
     222     11942228 :   for (int i = 0; m_clause[i]; i++)
     223     22282973 :     for (int j = 0; p.m_clause[j]; j++)
     224              :       {
     225     15099021 :         gcc_checking_assert (i < max_clauses && j < max_clauses);
     226     15099021 :         out.add_clause (conditions, m_clause[i] | p.m_clause[j]);
     227              :       }
     228      4758276 :   return out;
     229              : }
     230              : 
     231              : 
     232              : /* Having partial truth assignment in POSSIBLE_TRUTHS, return false
     233              :    if predicate P is known to be false.  */
     234              : 
     235              : bool
     236    266021151 : ipa_predicate::evaluate (clause_t possible_truths) const
     237              : {
     238    266021151 :   int i;
     239              : 
     240              :   /* True remains true.  */
     241    266021151 :   if (*this == true)
     242              :     return true;
     243              : 
     244    206804756 :   gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));
     245              : 
     246              :   /* See if we can find clause we can disprove.  */
     247    476515949 :   for (i = 0; m_clause[i]; i++)
     248              :     {
     249    331328405 :       gcc_checking_assert (i < max_clauses);
     250    331328405 :       if (!(m_clause[i] & possible_truths))
     251              :         return false;
     252              :     }
     253              :   return true;
     254              : }
     255              : 
     256              : /* Return the probability in range 0...REG_BR_PROB_BASE that the predicated
     257              :    instruction will be recomputed per invocation of the inlined call.  */
     258              : 
     259              : int
     260     32559789 : ipa_predicate::probability (conditions conds,
     261              :                         clause_t possible_truths,
     262              :                         vec<inline_param_summary> inline_param_summary) const
     263              : {
     264     32559789 :   int i;
     265     32559789 :   int combined_prob = REG_BR_PROB_BASE;
     266              : 
     267              :   /* True remains true.  */
     268     32559789 :   if (*this == true)
     269              :     return REG_BR_PROB_BASE;
     270              : 
     271     22081667 :   if (*this == false)
     272              :     return 0;
     273              : 
     274     22081667 :   gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));
     275              : 
     276              :   /* See if we can find clause we can disprove.  */
     277     55165583 :   for (i = 0; m_clause[i]; i++)
     278              :     {
     279     37541591 :       gcc_checking_assert (i < max_clauses);
     280     37541591 :       if (!(m_clause[i] & possible_truths))
     281              :         return 0;
     282              :       else
     283              :         {
     284     37541591 :           int this_prob = 0;
     285     37541591 :           int i2;
     286     37541591 :           if (!inline_param_summary.exists ())
     287              :             return REG_BR_PROB_BASE;
     288   1238864055 :           for (i2 = 0; i2 < num_conditions; i2++)
     289   1201322720 :             if ((m_clause[i] & possible_truths) & (1 << i2))
     290              :               {
     291     46275804 :                 if (i2 >= ipa_predicate::first_dynamic_condition)
     292              :                   {
     293     46275804 :                     condition *c =
     294     46275804 :                       &(*conds)[i2 - ipa_predicate::first_dynamic_condition];
     295     46275804 :                     if (c->code == ipa_predicate::changed
     296     46275804 :                         && (c->operand_num <
     297     18924775 :                             (int) inline_param_summary.length ()))
     298              :                       {
     299     18924738 :                         int iprob =
     300     18924738 :                           inline_param_summary[c->operand_num].change_prob;
     301   1201322720 :                         this_prob = MAX (this_prob, iprob);
     302              :                       }
     303              :                     else
     304              :                       this_prob = REG_BR_PROB_BASE;
     305              :                   }
     306              :                 else
     307              :                   this_prob = REG_BR_PROB_BASE;
     308              :               }
     309     37541335 :           combined_prob = MIN (this_prob, combined_prob);
     310     37541335 :           if (!combined_prob)
     311              :             return 0;
     312              :         }
     313              :     }
     314              :   return combined_prob;
     315              : }
     316              : 
     317              : 
     318              : /* Dump conditional COND.  */
     319              : 
     320              : void
     321        14518 : dump_condition (FILE *f, conditions conditions, int cond)
     322              : {
     323        14518 :   condition *c;
     324        14518 :   if (cond == ipa_predicate::false_condition)
     325         2551 :     fprintf (f, "false");
     326        11967 :   else if (cond == ipa_predicate::not_inlined_condition)
     327         3576 :     fprintf (f, "not inlined");
     328              :   else
     329              :     {
     330         8391 :       c = &(*conditions)[cond - ipa_predicate::first_dynamic_condition];
     331         8391 :       fprintf (f, "op%i", c->operand_num);
     332         8391 :       if (c->agg_contents)
     333         1597 :         fprintf (f, "[%soffset: " HOST_WIDE_INT_PRINT_DEC "]",
     334         1597 :                  c->by_ref ? "ref " : "", c->offset);
     335              : 
     336         9513 :       for (unsigned i = 0; i < vec_safe_length (c->param_ops); i++)
     337              :         {
     338         1122 :           expr_eval_op &op = (*(c->param_ops))[i];
     339         1122 :           const char *op_name = op_symbol_code (op.code);
     340              : 
     341         1122 :           if (op_name == op_symbol_code (ERROR_MARK))
     342          300 :             op_name = get_tree_code_name (op.code);
     343              : 
     344         1122 :           fprintf (f, ",(");
     345              : 
     346         1122 :           if (!op.val[0])
     347              :             {
     348          300 :               switch (op.code)
     349              :                 {
     350          300 :                 case FLOAT_EXPR:
     351          300 :                 case FIX_TRUNC_EXPR:
     352          300 :                 case FIXED_CONVERT_EXPR:
     353          300 :                 case VIEW_CONVERT_EXPR:
     354          300 :                 CASE_CONVERT:
     355          300 :                   if (op.code == VIEW_CONVERT_EXPR)
     356            0 :                     fprintf (f, "VCE");
     357          300 :                   fprintf (f, "(");
     358          300 :                   print_generic_expr (f, op.type);
     359          300 :                   fprintf (f, ")" );
     360          300 :                   break;
     361              : 
     362            0 :                 default:
     363            0 :                   fprintf (f, "%s", op_name);
     364              :                 }
     365          300 :               fprintf (f, " #");
     366              :             }
     367          822 :           else if (!op.val[1])
     368              :             {
     369          822 :               if (op.index)
     370              :                 {
     371           62 :                   print_generic_expr (f, op.val[0]);
     372           62 :                   fprintf (f, " %s #", op_name);
     373              :                 }
     374              :               else
     375              :                 {
     376          760 :                   fprintf (f, "# %s ", op_name);
     377          760 :                   print_generic_expr (f, op.val[0]);
     378              :                 }
     379              :             }
     380              :           else
     381              :             {
     382            0 :               fprintf (f, "%s ", op_name);
     383            0 :               switch (op.index)
     384              :                 {
     385            0 :                 case 0:
     386            0 :                   fprintf (f, "#, ");
     387            0 :                   print_generic_expr (f, op.val[0]);
     388            0 :                   fprintf (f, ", ");
     389            0 :                   print_generic_expr (f, op.val[1]);
     390            0 :                   break;
     391              : 
     392            0 :                 case 1:
     393            0 :                   print_generic_expr (f, op.val[0]);
     394            0 :                   fprintf (f, ", #, ");
     395            0 :                   print_generic_expr (f, op.val[1]);
     396            0 :                   break;
     397              : 
     398            0 :                 case 2:
     399            0 :                   print_generic_expr (f, op.val[0]);
     400            0 :                   fprintf (f, ", ");
     401            0 :                   print_generic_expr (f, op.val[1]);
     402            0 :                   fprintf (f, ", #");
     403            0 :                   break;
     404              : 
     405            0 :                 default:
     406            0 :                   fprintf (f, "*, *, *");
     407              :                 }
     408              :             }
     409         1122 :           fprintf (f, ")");
     410              :         }
     411              : 
     412         8391 :       if (c->code == ipa_predicate::is_not_constant)
     413              :         {
     414           18 :           fprintf (f, " not constant");
     415           18 :           return;
     416              :         }
     417         8373 :       if (c->code == ipa_predicate::changed)
     418              :         {
     419         1854 :           fprintf (f, " changed");
     420         1854 :           return;
     421              :         }
     422         6519 :       if (c->code == ipa_predicate::not_sra_candidate)
     423              :         {
     424         1700 :           fprintf (f, " not sra candidate");
     425         1700 :           return;
     426              :         }
     427         4819 :       fprintf (f, " %s ", op_symbol_code (c->code));
     428         4819 :       print_generic_expr (f, c->val);
     429              :     }
     430              : }
     431              : 
     432              : 
     433              : /* Dump clause CLAUSE.  */
     434              : 
     435              : static void
     436        15665 : dump_clause (FILE *f, conditions conds, clause_t clause)
     437              : {
     438        15665 :   int i;
     439        15665 :   bool found = false;
     440        15665 :   fprintf (f, "(");
     441        15665 :   if (!clause)
     442         3383 :     fprintf (f, "true");
     443       516945 :   for (i = 0; i < ipa_predicate::num_conditions; i++)
     444       501280 :     if (clause & (1 << i))
     445              :       {
     446        12712 :         if (found)
     447          430 :           fprintf (f, " || ");
     448        12712 :         found = true;
     449        12712 :         dump_condition (f, conds, i);
     450              :       }
     451        15665 :   fprintf (f, ")");
     452        15665 : }
     453              : 
     454              : 
     455              : /* Dump THIS to F.  CONDS a vector of conditions used when evaluating
     456              :    ipa_predicates.  When NL is true new line is output at the end of dump.  */
     457              : 
     458              : void
     459        12438 : ipa_predicate::dump (FILE *f, conditions conds, bool nl) const
     460              : {
     461        12438 :   int i;
     462        12438 :   if (*this == true)
     463         3383 :     dump_clause (f, conds, 0);
     464              :   else
     465        21337 :     for (i = 0; m_clause[i]; i++)
     466              :       {
     467        12282 :         if (i)
     468         3227 :           fprintf (f, " && ");
     469        12282 :         dump_clause (f, conds, m_clause[i]);
     470              :       }
     471        12438 :   if (nl)
     472         4911 :     fprintf (f, "\n");
     473        12438 : }
     474              : 
     475              : 
     476              : void
     477            0 : ipa_predicate::debug (conditions conds) const
     478              : {
     479            0 :   dump (stderr, conds);
     480            0 : }
     481              : 
     482              : 
     483              : /* Remap predicate THIS of former function to be predicate of duplicated function.
     484              :    POSSIBLE_TRUTHS is clause of possible truths in the duplicated node,
     485              :    INFO is inline summary of the duplicated node.  */
     486              : 
     487              : ipa_predicate
     488       182950 : ipa_predicate::remap_after_duplication (clause_t possible_truths)
     489              : {
     490       182950 :   int j;
     491       182950 :   ipa_predicate out = true;
     492       397917 :   for (j = 0; m_clause[j]; j++)
     493       236934 :     if (!(possible_truths & m_clause[j]))
     494        21967 :       return false;
     495              :     else
     496       214967 :       out.add_clause (NULL, possible_truths & m_clause[j]);
     497       160983 :   return out;
     498              : }
     499              : 
     500              : 
     501              : /* Translate all conditions from callee representation into caller
     502              :    representation and symbolically evaluate predicate THIS into new predicate.
     503              : 
     504              :    INFO is ipa_fn_summary of function we are adding predicate into, CALLEE_INFO
     505              :    is summary of function predicate P is from. OPERAND_MAP is array giving
     506              :    callee formal IDs the caller formal IDs. POSSSIBLE_TRUTHS is clause of all
     507              :    callee conditions that may be true in caller context.  TOPLEV_PREDICATE is
     508              :    predicate under which callee is executed.  OFFSET_MAP is an array of
     509              :    offsets that need to be added to conditions, negative offset means that
     510              :    conditions relying on values passed by reference have to be discarded
     511              :    because they might not be preserved (and should be considered offset zero
     512              :    for other purposes).  */
     513              : 
     514              : ipa_predicate
     515     36989155 : ipa_predicate::remap_after_inlining (class ipa_fn_summary *info,
     516              :                                  class ipa_node_params *params_summary,
     517              :                                  class ipa_fn_summary *callee_info,
     518              :                                  const vec<int> &operand_map,
     519              :                                  const vec<HOST_WIDE_INT> &offset_map,
     520              :                                  clause_t possible_truths,
     521              :                                  const ipa_predicate &toplev_predicate)
     522              : {
     523     36989155 :   int i;
     524     36989155 :   ipa_predicate out = true;
     525              : 
     526              :   /* True ipa_predicate is easy.  */
     527     36989155 :   if (*this == true)
     528      9405289 :     return toplev_predicate;
     529     72118949 :   for (i = 0; m_clause[i]; i++)
     530              :     {
     531     44535083 :       clause_t clause = m_clause[i];
     532     44535083 :       int cond;
     533     44535083 :       ipa_predicate clause_predicate = false;
     534              : 
     535     44535083 :       gcc_assert (i < max_clauses);
     536              : 
     537   1469657739 :       for (cond = 0; cond < num_conditions; cond++)
     538              :         /* Do we have condition we can't disprove?   */
     539   1425122656 :         if (clause & possible_truths & (1 << cond))
     540              :           {
     541     27218243 :             ipa_predicate cond_predicate;
     542              :             /* Work out if the condition can translate to predicate in the
     543              :                inlined function.  */
     544     27218243 :             if (cond >= ipa_predicate::first_dynamic_condition)
     545              :               {
     546     27218243 :                 struct condition *c;
     547              : 
     548     27218243 :                 int index = cond - ipa_predicate::first_dynamic_condition;
     549     27218243 :                 c = &(*callee_info->conds)[index];
     550              :                 /* See if we can remap condition operand to caller's operand.
     551              :                    Otherwise give up.  */
     552     27218243 :                 if (!operand_map.exists ()
     553     27218243 :                     || (int) operand_map.length () <= c->operand_num
     554     13699771 :                     || operand_map[c->operand_num] == -1
     555              :                     /* TODO: For non-aggregate conditions, adding an offset is
     556              :                        basically an arithmetic jump function processing which
     557              :                        we should support in future.  */
     558      5001354 :                     || ((!c->agg_contents || !c->by_ref)
     559      1959523 :                         && offset_map[c->operand_num] > 0)
     560     32102054 :                     || (c->agg_contents && c->by_ref
     561      3041831 :                         && offset_map[c->operand_num] < 0))
     562     23946284 :                   cond_predicate = true;
     563              :                 else
     564              :                   {
     565      3271959 :                     struct agg_position_info ap;
     566      3271959 :                     HOST_WIDE_INT offset_delta = offset_map[c->operand_num];
     567      3271959 :                     if (offset_delta < 0)
     568              :                       {
     569      1276765 :                         gcc_checking_assert (!c->agg_contents || !c->by_ref);
     570              :                         offset_delta = 0;
     571              :                       }
     572      3271959 :                     gcc_assert (!c->agg_contents
     573              :                                 || c->by_ref || offset_delta == 0);
     574      3271959 :                     ap.offset = c->offset + offset_delta;
     575      3271959 :                     ap.agg_contents = c->agg_contents;
     576      3271959 :                     ap.by_ref = c->by_ref;
     577      6543918 :                     cond_predicate = add_condition (info, params_summary,
     578      3271959 :                                                     operand_map[c->operand_num],
     579      3271959 :                                                     c->type, &ap, c->code,
     580              :                                                     c->val, c->param_ops);
     581              :                   }
     582              :               }
     583              :             /* Fixed conditions remains same, construct single
     584              :                condition predicate.  */
     585              :             else
     586            0 :               cond_predicate = ipa_predicate::predicate_testing_cond (cond);
     587     27218243 :             clause_predicate = clause_predicate.or_with (info->conds,
     588              :                                                          cond_predicate);
     589              :           }
     590     44535083 :       out &= clause_predicate;
     591              :     }
     592     27583866 :   out &= toplev_predicate;
     593     27583866 :   return out;
     594              : }
     595              : 
     596              : 
     597              : /* Read predicate from IB.  */
     598              : 
     599              : void
     600       830973 : ipa_predicate::stream_in (class lto_input_block *ib)
     601              : {
     602       830973 :   clause_t clause;
     603       830973 :   int k = 0;
     604              : 
     605      1192831 :   do
     606              :     {
     607      1192831 :       gcc_assert (k <= max_clauses);
     608      1192831 :       clause = m_clause[k++] = streamer_read_uhwi (ib);
     609              :     }
     610      1192831 :   while (clause);
     611              : 
     612              :   /* Zero-initialize the remaining clauses in OUT.  */
     613      7116899 :   while (k <= max_clauses)
     614      6285926 :     m_clause[k++] = 0;
     615       830973 : }
     616              : 
     617              : 
     618              : /* Write predicate P to OB.  */
     619              : 
     620              : void
     621       594329 : ipa_predicate::stream_out (struct output_block *ob)
     622              : {
     623       594329 :   int j;
     624      1039057 :   for (j = 0; m_clause[j]; j++)
     625              :     {
     626       444728 :       gcc_assert (j < max_clauses);
     627       444728 :       streamer_write_uhwi (ob, m_clause[j]);
     628              :     }
     629       594329 :   streamer_write_uhwi (ob, 0);
     630       594329 : }
     631              : 
     632              : 
     633              : /* Add condition to condition list SUMMARY.  OPERAND_NUM, TYPE, CODE, VAL and
     634              :    PARAM_OPS correspond to fields of condition structure.  AGGPOS describes
     635              :    whether the used operand is loaded from an aggregate and where in the
     636              :    aggregate it is.  It can be NULL, which means this not a load from an
     637              :    aggregate.  */
     638              : 
     639              : ipa_predicate
     640     21686896 : add_condition (class ipa_fn_summary *summary,
     641              :                class ipa_node_params *params_summary,
     642              :                int operand_num,
     643              :                tree type, struct agg_position_info *aggpos,
     644              :                enum tree_code code, tree val, expr_eval_ops param_ops)
     645              : {
     646     21686896 :   int i, j;
     647     21686896 :   struct condition *c;
     648     21686896 :   struct condition new_cond;
     649     21686896 :   HOST_WIDE_INT offset;
     650     21686896 :   bool agg_contents, by_ref;
     651     21686896 :   expr_eval_op *op;
     652              : 
     653     21686896 :   if (params_summary)
     654      8331627 :     ipa_set_param_used_by_ipa_predicates (params_summary, operand_num, true);
     655              : 
     656     21686896 :   if (aggpos)
     657              :     {
     658      9027690 :       offset = aggpos->offset;
     659      9027690 :       agg_contents = aggpos->agg_contents;
     660      9027690 :       by_ref = aggpos->by_ref;
     661              :     }
     662              :   else
     663              :     {
     664              :       offset = 0;
     665              :       agg_contents = false;
     666              :       by_ref = false;
     667              :     }
     668              : 
     669     21686896 :   gcc_checking_assert (operand_num >= 0);
     670    100367391 :   for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++)
     671              :     {
     672     88574305 :       if (c->operand_num == operand_num
     673     47459059 :           && c->code == code
     674     17618139 :           && types_compatible_p (c->type, type)
     675     15837236 :           && vrp_operand_equal_p (c->val, val)
     676     12323519 :           && c->agg_contents == agg_contents
     677     11892973 :           && expr_eval_ops_equal_p (c->param_ops, param_ops)
     678    100331266 :           && (!agg_contents || (c->offset == offset && c->by_ref == by_ref)))
     679      9893810 :         return ipa_predicate::predicate_testing_cond (i);
     680              :     }
     681              :   /* Too many conditions.  Give up and return constant true.  */
     682     11793086 :   if (i == ipa_predicate::num_conditions - ipa_predicate::first_dynamic_condition)
     683       267467 :     return true;
     684              : 
     685     11525619 :   new_cond.operand_num = operand_num;
     686     11525619 :   new_cond.code = code;
     687     11525619 :   new_cond.type = unshare_expr_without_location (type);
     688     11525619 :   new_cond.val = val ? unshare_expr_without_location (val) : val;
     689     11525619 :   new_cond.agg_contents = agg_contents;
     690     11525619 :   new_cond.by_ref = by_ref;
     691     11525619 :   new_cond.offset = offset;
     692     11525619 :   new_cond.param_ops = vec_safe_copy (param_ops);
     693              : 
     694     12188721 :   for (j = 0; vec_safe_iterate (new_cond.param_ops, j, &op); j++)
     695              :     {
     696       663102 :       if (op->val[0])
     697       331603 :         op->val[0] = unshare_expr_without_location (op->val[0]);
     698       663102 :       if (op->val[1])
     699           24 :         op->val[1] = unshare_expr_without_location (op->val[1]);
     700              :     }
     701              : 
     702     11525619 :   vec_safe_push (summary->conds, new_cond);
     703              : 
     704     11525619 :   return ipa_predicate::predicate_testing_cond (i);
     705              : }
        

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.