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-03-28 14:25:54 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     14720871 : expr_eval_ops_equal_p (expr_eval_ops ops1, expr_eval_ops ops2)
      45              : {
      46     14720871 :   if (ops1)
      47              :     {
      48      1100400 :       if (!ops2 || ops1->length () != ops2->length ())
      49              :         return false;
      50              : 
      51      1482318 :       for (unsigned i = 0; i < ops1->length (); i++)
      52              :         {
      53      1042777 :           expr_eval_op &op1 = (*ops1)[i];
      54      1042777 :           expr_eval_op &op2 = (*ops2)[i];
      55              : 
      56      1042777 :           if (op1.code != op2.code
      57       903927 :               || op1.index != op2.index
      58       903927 :               || !vrp_operand_equal_p (op1.val[0], op2.val[0])
      59       656475 :               || !vrp_operand_equal_p (op1.val[1], op2.val[1])
      60      1699252 :               || !types_compatible_p (op1.type, op2.type))
      61       387489 :             return false;
      62              :         }
      63              :       return true;
      64              :     }
      65     13620471 :   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     50262698 : ipa_predicate::add_clause (conditions conditions, clause_t new_clause)
      75              : {
      76     50262698 :   int i;
      77     50262698 :   int i2;
      78     50262698 :   int insert_here = -1;
      79     50262698 :   int c1, c2;
      80              : 
      81              :   /* True clause.  */
      82     50262698 :   if (!new_clause)
      83              :     return;
      84              : 
      85              :   /* False clause makes the whole predicate false.  Kill the other variants.  */
      86     50262698 :   if (new_clause == (1 << ipa_predicate::false_condition))
      87              :     {
      88            0 :       *this = false;
      89            0 :       return;
      90              :     }
      91     50262698 :   if (*this == false)
      92              :     return;
      93              : 
      94              :   /* No one should be silly enough to add false into nontrivial clauses.  */
      95     50262698 :   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    135043683 :   for (i = 0, i2 = 0; i <= max_clauses; i++)
     101              :     {
     102    135043683 :       m_clause[i2] = m_clause[i];
     103              : 
     104    135043683 :       if (!m_clause[i])
     105              :         break;
     106              : 
     107              :       /* If m_clause[i] implies new_clause, there is nothing to add.  */
     108     96909528 :       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     12128543 :           gcc_checking_assert (i == i2);
     113              :           return;
     114              :         }
     115              : 
     116     84780985 :       if (m_clause[i] < new_clause && insert_here < 0)
     117     84780985 :         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     84780985 :       if ((m_clause[i] & new_clause) != new_clause)
     122     81256046 :         i2++;
     123              :     }
     124              : 
     125              :   /* Look for clauses that are obviously true.  I.e.
     126              :      op0 == 5 || op0 != 5.  */
     127     38134155 :   if (conditions)
     128    302166261 :     for (c1 = ipa_predicate::first_dynamic_condition;
     129    313472419 :          c1 < num_conditions; c1++)
     130              :       {
     131    303485454 :         condition *cc1;
     132    303485454 :         if (!(new_clause & (1 << c1)))
     133    272414249 :           continue;
     134     31071205 :         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     31071205 :         if (cc1->code == changed || cc1->code == is_not_constant || cc1->code == not_sra_candidate)
     138      6819934 :           continue;
     139    546428687 :         for (c2 = c1 + 1; c2 < num_conditions; c2++)
     140    523496609 :           if (new_clause & (1 << c2))
     141              :             {
     142     45419332 :               condition *cc2 =
     143     45419332 :                 &(*conditions)[c2 - ipa_predicate::first_dynamic_condition];
     144     45419332 :               if (cc1->operand_num == cc2->operand_num
     145     40313687 :                   && vrp_operand_equal_p (cc1->val, cc2->val)
     146      2860934 :                   && cc2->code != is_not_constant
     147      2860934 :                   && cc2->code != not_sra_candidate
     148      2860934 :                   && cc2->code != changed
     149      2860934 :                   && expr_eval_ops_equal_p (cc1->param_ops, cc2->param_ops)
     150      2116536 :                   && cc2->agg_contents == cc1->agg_contents
     151      1954780 :                   && cc2->by_ref == cc1->by_ref
     152      1953000 :                   && types_compatible_p (cc2->type, cc1->type)
     153     47302992 :                   && cc1->code == invert_tree_comparison (cc2->code,
     154      1883660 :                                                           HONOR_NANS (cc1->val)))
     155              :                 return;
     156              :             }
     157              :       }
     158              : 
     159              : 
     160              :   /* We run out of variants.  Be conservative in positive direction.  */
     161     36814962 :   if (i2 == max_clauses)
     162              :     return;
     163              :   /* Keep clauses in decreasing order. This makes equivalence testing easy.  */
     164     36547963 :   m_clause[i2 + 1] = 0;
     165     36547963 :   if (insert_here >= 0)
     166     44532175 :     for (; i2 > insert_here; i2--)
     167     26120654 :       m_clause[i2] = m_clause[i2 - 1];
     168              :   else
     169              :     insert_here = i2;
     170     36547963 :   m_clause[insert_here] = new_clause;
     171              : }
     172              : 
     173              : 
     174              : /* Do THIS &= P.  */
     175              : 
     176              : ipa_predicate &
     177    442073879 : ipa_predicate::operator &= (const ipa_predicate &p)
     178              : {
     179              :   /* Avoid busy work.  */
     180    442073879 :   if (p == false || *this == true)
     181              :     {
     182    343688672 :       *this = p;
     183    343688672 :       return *this;
     184              :     }
     185     98385207 :   if (*this == false || p == true || this == &p)
     186              :     return *this;
     187              : 
     188              :   int i;
     189              : 
     190              :   /* See how far ipa_predicates match.  */
     191     70167728 :   for (i = 0; m_clause[i] && m_clause[i] == p.m_clause[i]; i++)
     192              :     {
     193     27111302 :       gcc_checking_assert (i < max_clauses);
     194              :     }
     195              : 
     196              :   /* Combine the ipa_predicates rest.  */
     197     76527212 :   for (; p.m_clause[i]; i++)
     198              :     {
     199     33470786 :       gcc_checking_assert (i < max_clauses);
     200     33470786 :       add_clause (NULL, p.m_clause[i]);
     201              :     }
     202              :   return *this;
     203              : }
     204              : 
     205              : 
     206              : 
     207              : /* Return THIS | P2.  */
     208              : 
     209              : ipa_predicate
     210    121961439 : ipa_predicate::or_with (conditions conditions,
     211              :                         const ipa_predicate &p) const
     212              : {
     213              :   /* Avoid busy work.  */
     214    121961439 :   if (p == false || *this == true || *this == p)
     215     15606797 :     return *this;
     216    106354642 :   if (*this == false || p == true)
     217    101493640 :     return p;
     218              : 
     219              :   /* OK, combine the predicates.  */
     220      4861002 :   ipa_predicate out = true;
     221              : 
     222     12414844 :   for (int i = 0; m_clause[i]; i++)
     223     24096333 :     for (int j = 0; p.m_clause[j]; j++)
     224              :       {
     225     16542491 :         gcc_checking_assert (i < max_clauses && j < max_clauses);
     226     16542491 :         out.add_clause (conditions, m_clause[i] | p.m_clause[j]);
     227              :       }
     228      4861002 :   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    259073379 : ipa_predicate::evaluate (clause_t possible_truths) const
     237              : {
     238    259073379 :   int i;
     239              : 
     240              :   /* True remains true.  */
     241    259073379 :   if (*this == true)
     242              :     return true;
     243              : 
     244    201640495 :   gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));
     245              : 
     246              :   /* See if we can find clause we can disprove.  */
     247    467637012 :   for (i = 0; m_clause[i]; i++)
     248              :     {
     249    326319902 :       gcc_checking_assert (i < max_clauses);
     250    326319902 :       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     31162629 : ipa_predicate::probability (conditions conds,
     261              :                         clause_t possible_truths,
     262              :                         vec<inline_param_summary> inline_param_summary) const
     263              : {
     264     31162629 :   int i;
     265     31162629 :   int combined_prob = REG_BR_PROB_BASE;
     266              : 
     267              :   /* True remains true.  */
     268     31162629 :   if (*this == true)
     269              :     return REG_BR_PROB_BASE;
     270              : 
     271     21127232 :   if (*this == false)
     272              :     return 0;
     273              : 
     274     21127232 :   gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));
     275              : 
     276              :   /* See if we can find clause we can disprove.  */
     277     53454883 :   for (i = 0; m_clause[i]; i++)
     278              :     {
     279     36339802 :       gcc_checking_assert (i < max_clauses);
     280     36339802 :       if (!(m_clause[i] & possible_truths))
     281              :         return 0;
     282              :       else
     283              :         {
     284     36339802 :           int this_prob = 0;
     285     36339802 :           int i2;
     286     36339802 :           if (!inline_param_summary.exists ())
     287              :             return REG_BR_PROB_BASE;
     288   1199205216 :           for (i2 = 0; i2 < num_conditions; i2++)
     289   1162865664 :             if ((m_clause[i] & possible_truths) & (1 << i2))
     290              :               {
     291     45201863 :                 if (i2 >= ipa_predicate::first_dynamic_condition)
     292              :                   {
     293     45201863 :                     condition *c =
     294     45201863 :                       &(*conds)[i2 - ipa_predicate::first_dynamic_condition];
     295     45201863 :                     if (c->code == ipa_predicate::changed
     296     45201863 :                         && (c->operand_num <
     297     18018993 :                             (int) inline_param_summary.length ()))
     298              :                       {
     299     18018946 :                         int iprob =
     300     18018946 :                           inline_param_summary[c->operand_num].change_prob;
     301   1162865664 :                         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     36339552 :           combined_prob = MIN (this_prob, combined_prob);
     310     36339552 :           if (!combined_prob)
     311              :             return 0;
     312              :         }
     313              :     }
     314              :   return combined_prob;
     315              : }
     316              : 
     317              : 
     318              : /* Dump conditional COND.  */
     319              : 
     320              : void
     321        14559 : dump_condition (FILE *f, conditions conditions, int cond)
     322              : {
     323        14559 :   condition *c;
     324        14559 :   if (cond == ipa_predicate::false_condition)
     325         2551 :     fprintf (f, "false");
     326        12008 :   else if (cond == ipa_predicate::not_inlined_condition)
     327         3597 :     fprintf (f, "not inlined");
     328              :   else
     329              :     {
     330         8411 :       c = &(*conditions)[cond - ipa_predicate::first_dynamic_condition];
     331         8411 :       fprintf (f, "op%i", c->operand_num);
     332         8411 :       if (c->agg_contents)
     333         1622 :         fprintf (f, "[%soffset: " HOST_WIDE_INT_PRINT_DEC "]",
     334         1622 :                  c->by_ref ? "ref " : "", c->offset);
     335              : 
     336         9503 :       for (unsigned i = 0; i < vec_safe_length (c->param_ops); i++)
     337              :         {
     338         1092 :           expr_eval_op &op = (*(c->param_ops))[i];
     339         1092 :           const char *op_name = op_symbol_code (op.code);
     340              : 
     341         1092 :           if (op_name == op_symbol_code (ERROR_MARK))
     342          302 :             op_name = get_tree_code_name (op.code);
     343              : 
     344         1092 :           fprintf (f, ",(");
     345              : 
     346         1092 :           if (!op.val[0])
     347              :             {
     348          302 :               switch (op.code)
     349              :                 {
     350          302 :                 case FLOAT_EXPR:
     351          302 :                 case FIX_TRUNC_EXPR:
     352          302 :                 case FIXED_CONVERT_EXPR:
     353          302 :                 case VIEW_CONVERT_EXPR:
     354          302 :                 CASE_CONVERT:
     355          302 :                   if (op.code == VIEW_CONVERT_EXPR)
     356            0 :                     fprintf (f, "VCE");
     357          302 :                   fprintf (f, "(");
     358          302 :                   print_generic_expr (f, op.type);
     359          302 :                   fprintf (f, ")" );
     360          302 :                   break;
     361              : 
     362            0 :                 default:
     363            0 :                   fprintf (f, "%s", op_name);
     364              :                 }
     365          302 :               fprintf (f, " #");
     366              :             }
     367          790 :           else if (!op.val[1])
     368              :             {
     369          790 :               if (op.index)
     370              :                 {
     371           61 :                   print_generic_expr (f, op.val[0]);
     372           61 :                   fprintf (f, " %s #", op_name);
     373              :                 }
     374              :               else
     375              :                 {
     376          729 :                   fprintf (f, "# %s ", op_name);
     377          729 :                   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         1092 :           fprintf (f, ")");
     410              :         }
     411              : 
     412         8411 :       if (c->code == ipa_predicate::is_not_constant)
     413              :         {
     414           18 :           fprintf (f, " not constant");
     415           18 :           return;
     416              :         }
     417         8393 :       if (c->code == ipa_predicate::changed)
     418              :         {
     419         1879 :           fprintf (f, " changed");
     420         1879 :           return;
     421              :         }
     422         6514 :       if (c->code == ipa_predicate::not_sra_candidate)
     423              :         {
     424         1740 :           fprintf (f, " not sra candidate");
     425         1740 :           return;
     426              :         }
     427         4774 :       fprintf (f, " %s ", op_symbol_code (c->code));
     428         4774 :       print_generic_expr (f, c->val);
     429              :     }
     430              : }
     431              : 
     432              : 
     433              : /* Dump clause CLAUSE.  */
     434              : 
     435              : static void
     436        15785 : dump_clause (FILE *f, conditions conds, clause_t clause)
     437              : {
     438        15785 :   int i;
     439        15785 :   bool found = false;
     440        15785 :   fprintf (f, "(");
     441        15785 :   if (!clause)
     442         3425 :     fprintf (f, "true");
     443       520905 :   for (i = 0; i < ipa_predicate::num_conditions; i++)
     444       505120 :     if (clause & (1 << i))
     445              :       {
     446        12790 :         if (found)
     447          430 :           fprintf (f, " || ");
     448        12790 :         found = true;
     449        12790 :         dump_condition (f, conds, i);
     450              :       }
     451        15785 :   fprintf (f, ")");
     452        15785 : }
     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        12527 : ipa_predicate::dump (FILE *f, conditions conds, bool nl) const
     460              : {
     461        12527 :   int i;
     462        12527 :   if (*this == true)
     463         3425 :     dump_clause (f, conds, 0);
     464              :   else
     465        21462 :     for (i = 0; m_clause[i]; i++)
     466              :       {
     467        12360 :         if (i)
     468         3258 :           fprintf (f, " && ");
     469        12360 :         dump_clause (f, conds, m_clause[i]);
     470              :       }
     471        12527 :   if (nl)
     472         4919 :     fprintf (f, "\n");
     473        12527 : }
     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       203640 : ipa_predicate::remap_after_duplication (clause_t possible_truths)
     489              : {
     490       203640 :   int j;
     491       203640 :   ipa_predicate out = true;
     492       453061 :   for (j = 0; m_clause[j]; j++)
     493       275373 :     if (!(possible_truths & m_clause[j]))
     494        25952 :       return false;
     495              :     else
     496       249421 :       out.add_clause (NULL, possible_truths & m_clause[j]);
     497       177688 :   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     36378952 : 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     36378952 :   int i;
     524     36378952 :   ipa_predicate out = true;
     525              : 
     526              :   /* True ipa_predicate is easy.  */
     527     36378952 :   if (*this == true)
     528      9246127 :     return toplev_predicate;
     529     70952753 :   for (i = 0; m_clause[i]; i++)
     530              :     {
     531     43819928 :       clause_t clause = m_clause[i];
     532     43819928 :       int cond;
     533     43819928 :       ipa_predicate clause_predicate = false;
     534              : 
     535     43819928 :       gcc_assert (i < max_clauses);
     536              : 
     537   1446057624 :       for (cond = 0; cond < num_conditions; cond++)
     538              :         /* Do we have condition we can't disprove?   */
     539   1402237696 :         if (clause & possible_truths & (1 << cond))
     540              :           {
     541     26301888 :             ipa_predicate cond_predicate;
     542              :             /* Work out if the condition can translate to predicate in the
     543              :                inlined function.  */
     544     26301888 :             if (cond >= ipa_predicate::first_dynamic_condition)
     545              :               {
     546     26301888 :                 struct condition *c;
     547              : 
     548     26301888 :                 int index = cond - ipa_predicate::first_dynamic_condition;
     549     26301888 :                 c = &(*callee_info->conds)[index];
     550              :                 /* See if we can remap condition operand to caller's operand.
     551              :                    Otherwise give up.  */
     552     26301888 :                 if (!operand_map.exists ()
     553     26301888 :                     || (int) operand_map.length () <= c->operand_num
     554     12941549 :                     || 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      4654865 :                     || ((!c->agg_contents || !c->by_ref)
     559      1964761 :                         && offset_map[c->operand_num] > 0)
     560     30844592 :                     || (c->agg_contents && c->by_ref
     561      2690104 :                         && offset_map[c->operand_num] < 0))
     562     23070930 :                   cond_predicate = true;
     563              :                 else
     564              :                   {
     565      3230958 :                     struct agg_position_info ap;
     566      3230958 :                     HOST_WIDE_INT offset_delta = offset_map[c->operand_num];
     567      3230958 :                     if (offset_delta < 0)
     568              :                       {
     569      1258313 :                         gcc_checking_assert (!c->agg_contents || !c->by_ref);
     570              :                         offset_delta = 0;
     571              :                       }
     572      3230958 :                     gcc_assert (!c->agg_contents
     573              :                                 || c->by_ref || offset_delta == 0);
     574      3230958 :                     ap.offset = c->offset + offset_delta;
     575      3230958 :                     ap.agg_contents = c->agg_contents;
     576      3230958 :                     ap.by_ref = c->by_ref;
     577      6461916 :                     cond_predicate = add_condition (info, params_summary,
     578      3230958 :                                                     operand_map[c->operand_num],
     579      3230958 :                                                     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     26301888 :             clause_predicate = clause_predicate.or_with (info->conds,
     588              :                                                          cond_predicate);
     589              :           }
     590     43819928 :       out &= clause_predicate;
     591              :     }
     592     27132825 :   out &= toplev_predicate;
     593     27132825 :   return out;
     594              : }
     595              : 
     596              : 
     597              : /* Read predicate from IB.  */
     598              : 
     599              : void
     600       830378 : ipa_predicate::stream_in (class lto_input_block *ib)
     601              : {
     602       830378 :   clause_t clause;
     603       830378 :   int k = 0;
     604              : 
     605      1192543 :   do
     606              :     {
     607      1192543 :       gcc_assert (k <= max_clauses);
     608      1192543 :       clause = m_clause[k++] = streamer_read_uhwi (ib);
     609              :     }
     610      1192543 :   while (clause);
     611              : 
     612              :   /* Zero-initialize the remaining clauses in OUT.  */
     613      7111237 :   while (k <= max_clauses)
     614      6280859 :     m_clause[k++] = 0;
     615       830378 : }
     616              : 
     617              : 
     618              : /* Write predicate P to OB.  */
     619              : 
     620              : void
     621       592588 : ipa_predicate::stream_out (struct output_block *ob)
     622              : {
     623       592588 :   int j;
     624      1036618 :   for (j = 0; m_clause[j]; j++)
     625              :     {
     626       444030 :       gcc_assert (j < max_clauses);
     627       444030 :       streamer_write_uhwi (ob, m_clause[j]);
     628              :     }
     629       592588 :   streamer_write_uhwi (ob, 0);
     630       592588 : }
     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     21557636 : 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     21557636 :   int i, j;
     647     21557636 :   struct condition *c;
     648     21557636 :   struct condition new_cond;
     649     21557636 :   HOST_WIDE_INT offset;
     650     21557636 :   bool agg_contents, by_ref;
     651     21557636 :   expr_eval_op *op;
     652              : 
     653     21557636 :   if (params_summary)
     654      8282560 :     ipa_set_param_used_by_ipa_predicates (params_summary, operand_num, true);
     655              : 
     656     21557636 :   if (aggpos)
     657              :     {
     658      8978890 :       offset = aggpos->offset;
     659      8978890 :       agg_contents = aggpos->agg_contents;
     660      8978890 :       by_ref = aggpos->by_ref;
     661              :     }
     662              :   else
     663              :     {
     664              :       offset = 0;
     665              :       agg_contents = false;
     666              :       by_ref = false;
     667              :     }
     668              : 
     669     21557636 :   gcc_checking_assert (operand_num >= 0);
     670    101985779 :   for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++)
     671              :     {
     672     90304765 :       if (c->operand_num == operand_num
     673     47320464 :           && c->code == code
     674     17680361 :           && types_compatible_p (c->type, type)
     675     15888775 :           && vrp_operand_equal_p (c->val, val)
     676     12283897 :           && c->agg_contents == agg_contents
     677     11859937 :           && expr_eval_ops_equal_p (c->param_ops, param_ops)
     678    102025606 :           && (!agg_contents || (c->offset == offset && c->by_ref == by_ref)))
     679      9876622 :         return ipa_predicate::predicate_testing_cond (i);
     680              :     }
     681              :   /* Too many conditions.  Give up and return constant true.  */
     682     11681014 :   if (i == ipa_predicate::num_conditions - ipa_predicate::first_dynamic_condition)
     683       266781 :     return true;
     684              : 
     685     11414233 :   new_cond.operand_num = operand_num;
     686     11414233 :   new_cond.code = code;
     687     11414233 :   new_cond.type = unshare_expr_without_location (type);
     688     11414233 :   new_cond.val = val ? unshare_expr_without_location (val) : val;
     689     11414233 :   new_cond.agg_contents = agg_contents;
     690     11414233 :   new_cond.by_ref = by_ref;
     691     11414233 :   new_cond.offset = offset;
     692     11414233 :   new_cond.param_ops = vec_safe_copy (param_ops);
     693              : 
     694     11944883 :   for (j = 0; vec_safe_iterate (new_cond.param_ops, j, &op); j++)
     695              :     {
     696       530650 :       if (op->val[0])
     697       275245 :         op->val[0] = unshare_expr_without_location (op->val[0]);
     698       530650 :       if (op->val[1])
     699           24 :         op->val[1] = unshare_expr_without_location (op->val[1]);
     700              :     }
     701              : 
     702     11414233 :   vec_safe_push (summary->conds, new_cond);
     703              : 
     704     11414233 :   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.