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-02-28 14:20:25 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     14761165 : expr_eval_ops_equal_p (expr_eval_ops ops1, expr_eval_ops ops2)
      45              : {
      46     14761165 :   if (ops1)
      47              :     {
      48      1096835 :       if (!ops2 || ops1->length () != ops2->length ())
      49              :         return false;
      50              : 
      51      1475752 :       for (unsigned i = 0; i < ops1->length (); i++)
      52              :         {
      53      1039291 :           expr_eval_op &op1 = (*ops1)[i];
      54      1039291 :           expr_eval_op &op2 = (*ops2)[i];
      55              : 
      56      1039291 :           if (op1.code != op2.code
      57       900407 :               || op1.index != op2.index
      58       900407 :               || !vrp_operand_equal_p (op1.val[0], op2.val[0])
      59       653362 :               || !vrp_operand_equal_p (op1.val[1], op2.val[1])
      60      1692653 :               || !types_compatible_p (op1.type, op2.type))
      61       387116 :             return false;
      62              :         }
      63              :       return true;
      64              :     }
      65     13664330 :   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     50364895 : ipa_predicate::add_clause (conditions conditions, clause_t new_clause)
      75              : {
      76     50364895 :   int i;
      77     50364895 :   int i2;
      78     50364895 :   int insert_here = -1;
      79     50364895 :   int c1, c2;
      80              : 
      81              :   /* True clause.  */
      82     50364895 :   if (!new_clause)
      83              :     return;
      84              : 
      85              :   /* False clause makes the whole predicate false.  Kill the other variants.  */
      86     50364895 :   if (new_clause == (1 << ipa_predicate::false_condition))
      87              :     {
      88            0 :       *this = false;
      89            0 :       return;
      90              :     }
      91     50364895 :   if (*this == false)
      92              :     return;
      93              : 
      94              :   /* No one should be silly enough to add false into nontrivial clauses.  */
      95     50364895 :   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    134812748 :   for (i = 0, i2 = 0; i <= max_clauses; i++)
     101              :     {
     102    134812748 :       m_clause[i2] = m_clause[i];
     103              : 
     104    134812748 :       if (!m_clause[i])
     105              :         break;
     106              : 
     107              :       /* If m_clause[i] implies new_clause, there is nothing to add.  */
     108     96533638 :       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     12085785 :           gcc_checking_assert (i == i2);
     113              :           return;
     114              :         }
     115              : 
     116     84447853 :       if (m_clause[i] < new_clause && insert_here < 0)
     117     84447853 :         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     84447853 :       if ((m_clause[i] & new_clause) != new_clause)
     122     80968076 :         i2++;
     123              :     }
     124              : 
     125              :   /* Look for clauses that are obviously true.  I.e.
     126              :      op0 == 5 || op0 != 5.  */
     127     38279110 :   if (conditions)
     128    299581685 :     for (c1 = ipa_predicate::first_dynamic_condition;
     129    310802209 :          c1 < num_conditions; c1++)
     130              :       {
     131    300900833 :         condition *cc1;
     132    300900833 :         if (!(new_clause & (1 << c1)))
     133    270216583 :           continue;
     134     30684250 :         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     30684250 :         if (cc1->code == changed || cc1->code == is_not_constant || cc1->code == not_sra_candidate)
     138      6847042 :           continue;
     139    537170812 :         for (c2 = c1 + 1; c2 < num_conditions; c2++)
     140    514652752 :           if (new_clause & (1 << c2))
     141              :             {
     142     44651400 :               condition *cc2 =
     143     44651400 :                 &(*conditions)[c2 - ipa_predicate::first_dynamic_condition];
     144     44651400 :               if (cc1->operand_num == cc2->operand_num
     145     39563011 :                   && vrp_operand_equal_p (cc1->val, cc2->val)
     146      2848733 :                   && cc2->code != is_not_constant
     147      2848733 :                   && cc2->code != not_sra_candidate
     148      2848733 :                   && cc2->code != changed
     149      2848733 :                   && expr_eval_ops_equal_p (cc1->param_ops, cc2->param_ops)
     150      2118053 :                   && cc2->agg_contents == cc1->agg_contents
     151      1956157 :                   && cc2->by_ref == cc1->by_ref
     152      1954377 :                   && types_compatible_p (cc2->type, cc1->type)
     153     46535665 :                   && cc1->code == invert_tree_comparison (cc2->code,
     154      1884265 :                                                           HONOR_NANS (cc1->val)))
     155              :                 return;
     156              :             }
     157              :       }
     158              : 
     159              : 
     160              :   /* We run out of variants.  Be conservative in positive direction.  */
     161     36959962 :   if (i2 == max_clauses)
     162              :     return;
     163              :   /* Keep clauses in decreasing order. This makes equivalence testing easy.  */
     164     36694873 :   m_clause[i2 + 1] = 0;
     165     36694873 :   if (insert_here >= 0)
     166     44805881 :     for (; i2 > insert_here; i2--)
     167     26261263 :       m_clause[i2] = m_clause[i2 - 1];
     168              :   else
     169              :     insert_here = i2;
     170     36694873 :   m_clause[insert_here] = new_clause;
     171              : }
     172              : 
     173              : 
     174              : /* Do THIS &= P.  */
     175              : 
     176              : ipa_predicate &
     177    441182160 : ipa_predicate::operator &= (const ipa_predicate &p)
     178              : {
     179              :   /* Avoid busy work.  */
     180    441182160 :   if (p == false || *this == true)
     181              :     {
     182    342516829 :       *this = p;
     183    342516829 :       return *this;
     184              :     }
     185     98665331 :   if (*this == false || p == true || this == &p)
     186              :     return *this;
     187              : 
     188              :   int i;
     189              : 
     190              :   /* See how far ipa_predicates match.  */
     191     70359309 :   for (i = 0; m_clause[i] && m_clause[i] == p.m_clause[i]; i++)
     192              :     {
     193     27061603 :       gcc_checking_assert (i < max_clauses);
     194              :     }
     195              : 
     196              :   /* Combine the ipa_predicates rest.  */
     197     77082457 :   for (; p.m_clause[i]; i++)
     198              :     {
     199     33784751 :       gcc_checking_assert (i < max_clauses);
     200     33784751 :       add_clause (NULL, p.m_clause[i]);
     201              :     }
     202              :   return *this;
     203              : }
     204              : 
     205              : 
     206              : 
     207              : /* Return THIS | P2.  */
     208              : 
     209              : ipa_predicate
     210    121916583 : ipa_predicate::or_with (conditions conditions,
     211              :                         const ipa_predicate &p) const
     212              : {
     213              :   /* Avoid busy work.  */
     214    121916583 :   if (p == false || *this == true || *this == p)
     215     15542555 :     return *this;
     216    106374028 :   if (*this == false || p == true)
     217    101501844 :     return p;
     218              : 
     219              :   /* OK, combine the predicates.  */
     220      4872184 :   ipa_predicate out = true;
     221              : 
     222     12400039 :   for (int i = 0; m_clause[i]; i++)
     223     23858308 :     for (int j = 0; p.m_clause[j]; j++)
     224              :       {
     225     16330453 :         gcc_checking_assert (i < max_clauses && j < max_clauses);
     226     16330453 :         out.add_clause (conditions, m_clause[i] | p.m_clause[j]);
     227              :       }
     228      4872184 :   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    261617858 : ipa_predicate::evaluate (clause_t possible_truths) const
     237              : {
     238    261617858 :   int i;
     239              : 
     240              :   /* True remains true.  */
     241    261617858 :   if (*this == true)
     242              :     return true;
     243              : 
     244    203708612 :   gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));
     245              : 
     246              :   /* See if we can find clause we can disprove.  */
     247    471515831 :   for (i = 0; m_clause[i]; i++)
     248              :     {
     249    328846464 :       gcc_checking_assert (i < max_clauses);
     250    328846464 :       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     31395381 : ipa_predicate::probability (conditions conds,
     261              :                         clause_t possible_truths,
     262              :                         vec<inline_param_summary> inline_param_summary) const
     263              : {
     264     31395381 :   int i;
     265     31395381 :   int combined_prob = REG_BR_PROB_BASE;
     266              : 
     267              :   /* True remains true.  */
     268     31395381 :   if (*this == true)
     269              :     return REG_BR_PROB_BASE;
     270              : 
     271     21254744 :   if (*this == false)
     272              :     return 0;
     273              : 
     274     21254744 :   gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));
     275              : 
     276              :   /* See if we can find clause we can disprove.  */
     277     53515008 :   for (i = 0; m_clause[i]; i++)
     278              :     {
     279     36402952 :       gcc_checking_assert (i < max_clauses);
     280     36402952 :       if (!(m_clause[i] & possible_truths))
     281              :         return 0;
     282              :       else
     283              :         {
     284     36402952 :           int this_prob = 0;
     285     36402952 :           int i2;
     286     36402952 :           if (!inline_param_summary.exists ())
     287              :             return REG_BR_PROB_BASE;
     288   1201289166 :           for (i2 = 0; i2 < num_conditions; i2++)
     289   1164886464 :             if ((m_clause[i] & possible_truths) & (1 << i2))
     290              :               {
     291     45126559 :                 if (i2 >= ipa_predicate::first_dynamic_condition)
     292              :                   {
     293     45126559 :                     condition *c =
     294     45126559 :                       &(*conds)[i2 - ipa_predicate::first_dynamic_condition];
     295     45126559 :                     if (c->code == ipa_predicate::changed
     296     45126559 :                         && (c->operand_num <
     297     18135689 :                             (int) inline_param_summary.length ()))
     298              :                       {
     299     18135642 :                         int iprob =
     300     18135642 :                           inline_param_summary[c->operand_num].change_prob;
     301   1164886464 :                         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     36402702 :           combined_prob = MIN (this_prob, combined_prob);
     310     36402702 :           if (!combined_prob)
     311              :             return 0;
     312              :         }
     313              :     }
     314              :   return combined_prob;
     315              : }
     316              : 
     317              : 
     318              : /* Dump conditional COND.  */
     319              : 
     320              : void
     321        14569 : dump_condition (FILE *f, conditions conditions, int cond)
     322              : {
     323        14569 :   condition *c;
     324        14569 :   if (cond == ipa_predicate::false_condition)
     325         2551 :     fprintf (f, "false");
     326        12018 :   else if (cond == ipa_predicate::not_inlined_condition)
     327         3599 :     fprintf (f, "not inlined");
     328              :   else
     329              :     {
     330         8419 :       c = &(*conditions)[cond - ipa_predicate::first_dynamic_condition];
     331         8419 :       fprintf (f, "op%i", c->operand_num);
     332         8419 :       if (c->agg_contents)
     333         1622 :         fprintf (f, "[%soffset: " HOST_WIDE_INT_PRINT_DEC "]",
     334         1622 :                  c->by_ref ? "ref " : "", c->offset);
     335              : 
     336         9511 :       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         8419 :       if (c->code == ipa_predicate::is_not_constant)
     413              :         {
     414           18 :           fprintf (f, " not constant");
     415           18 :           return;
     416              :         }
     417         8401 :       if (c->code == ipa_predicate::changed)
     418              :         {
     419         1883 :           fprintf (f, " changed");
     420         1883 :           return;
     421              :         }
     422         6518 :       if (c->code == ipa_predicate::not_sra_candidate)
     423              :         {
     424         1744 :           fprintf (f, " not sra candidate");
     425         1744 :           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        15793 : dump_clause (FILE *f, conditions conds, clause_t clause)
     437              : {
     438        15793 :   int i;
     439        15793 :   bool found = false;
     440        15793 :   fprintf (f, "(");
     441        15793 :   if (!clause)
     442         3425 :     fprintf (f, "true");
     443       521169 :   for (i = 0; i < ipa_predicate::num_conditions; i++)
     444       505376 :     if (clause & (1 << i))
     445              :       {
     446        12800 :         if (found)
     447          432 :           fprintf (f, " || ");
     448        12800 :         found = true;
     449        12800 :         dump_condition (f, conds, i);
     450              :       }
     451        15793 :   fprintf (f, ")");
     452        15793 : }
     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        12533 : ipa_predicate::dump (FILE *f, conditions conds, bool nl) const
     460              : {
     461        12533 :   int i;
     462        12533 :   if (*this == true)
     463         3425 :     dump_clause (f, conds, 0);
     464              :   else
     465        21476 :     for (i = 0; m_clause[i]; i++)
     466              :       {
     467        12368 :         if (i)
     468         3260 :           fprintf (f, " && ");
     469        12368 :         dump_clause (f, conds, m_clause[i]);
     470              :       }
     471        12533 :   if (nl)
     472         4919 :     fprintf (f, "\n");
     473        12533 : }
     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       203694 : ipa_predicate::remap_after_duplication (clause_t possible_truths)
     489              : {
     490       203694 :   int j;
     491       203694 :   ipa_predicate out = true;
     492       453385 :   for (j = 0; m_clause[j]; j++)
     493       275631 :     if (!(possible_truths & m_clause[j]))
     494        25940 :       return false;
     495              :     else
     496       249691 :       out.add_clause (NULL, possible_truths & m_clause[j]);
     497       177754 :   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     36428619 : 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     36428619 :   int i;
     524     36428619 :   ipa_predicate out = true;
     525              : 
     526              :   /* True ipa_predicate is easy.  */
     527     36428619 :   if (*this == true)
     528      9269646 :     return toplev_predicate;
     529     70977134 :   for (i = 0; m_clause[i]; i++)
     530              :     {
     531     43818161 :       clause_t clause = m_clause[i];
     532     43818161 :       int cond;
     533     43818161 :       ipa_predicate clause_predicate = false;
     534              : 
     535     43818161 :       gcc_assert (i < max_clauses);
     536              : 
     537   1445999313 :       for (cond = 0; cond < num_conditions; cond++)
     538              :         /* Do we have condition we can't disprove?   */
     539   1402181152 :         if (clause & possible_truths & (1 << cond))
     540              :           {
     541     26268102 :             ipa_predicate cond_predicate;
     542              :             /* Work out if the condition can translate to predicate in the
     543              :                inlined function.  */
     544     26268102 :             if (cond >= ipa_predicate::first_dynamic_condition)
     545              :               {
     546     26268102 :                 struct condition *c;
     547              : 
     548     26268102 :                 int index = cond - ipa_predicate::first_dynamic_condition;
     549     26268102 :                 c = &(*callee_info->conds)[index];
     550              :                 /* See if we can remap condition operand to caller's operand.
     551              :                    Otherwise give up.  */
     552     26268102 :                 if (!operand_map.exists ()
     553     26268102 :                     || (int) operand_map.length () <= c->operand_num
     554     13019484 :                     || 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      4663214 :                     || ((!c->agg_contents || !c->by_ref)
     559      1964909 :                         && offset_map[c->operand_num] > 0)
     560     30818894 :                     || (c->agg_contents && c->by_ref
     561      2698305 :                         && offset_map[c->operand_num] < 0))
     562     23025148 :                   cond_predicate = true;
     563              :                 else
     564              :                   {
     565      3242954 :                     struct agg_position_info ap;
     566      3242954 :                     HOST_WIDE_INT offset_delta = offset_map[c->operand_num];
     567      3242954 :                     if (offset_delta < 0)
     568              :                       {
     569      1256522 :                         gcc_checking_assert (!c->agg_contents || !c->by_ref);
     570              :                         offset_delta = 0;
     571              :                       }
     572      3242954 :                     gcc_assert (!c->agg_contents
     573              :                                 || c->by_ref || offset_delta == 0);
     574      3242954 :                     ap.offset = c->offset + offset_delta;
     575      3242954 :                     ap.agg_contents = c->agg_contents;
     576      3242954 :                     ap.by_ref = c->by_ref;
     577      6485908 :                     cond_predicate = add_condition (info, params_summary,
     578      3242954 :                                                     operand_map[c->operand_num],
     579      3242954 :                                                     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     26268102 :             clause_predicate = clause_predicate.or_with (info->conds,
     588              :                                                          cond_predicate);
     589              :           }
     590     43818161 :       out &= clause_predicate;
     591              :     }
     592     27158973 :   out &= toplev_predicate;
     593     27158973 :   return out;
     594              : }
     595              : 
     596              : 
     597              : /* Read predicate from IB.  */
     598              : 
     599              : void
     600       828924 : ipa_predicate::stream_in (class lto_input_block *ib)
     601              : {
     602       828924 :   clause_t clause;
     603       828924 :   int k = 0;
     604              : 
     605      1190041 :   do
     606              :     {
     607      1190041 :       gcc_assert (k <= max_clauses);
     608      1190041 :       clause = m_clause[k++] = streamer_read_uhwi (ib);
     609              :     }
     610      1190041 :   while (clause);
     611              : 
     612              :   /* Zero-initialize the remaining clauses in OUT.  */
     613      7099199 :   while (k <= max_clauses)
     614      6270275 :     m_clause[k++] = 0;
     615       828924 : }
     616              : 
     617              : 
     618              : /* Write predicate P to OB.  */
     619              : 
     620              : void
     621       591558 : ipa_predicate::stream_out (struct output_block *ob)
     622              : {
     623       591558 :   int j;
     624      1034586 :   for (j = 0; m_clause[j]; j++)
     625              :     {
     626       443028 :       gcc_assert (j < max_clauses);
     627       443028 :       streamer_write_uhwi (ob, m_clause[j]);
     628              :     }
     629       591558 :   streamer_write_uhwi (ob, 0);
     630       591558 : }
     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     21652347 : 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     21652347 :   int i, j;
     647     21652347 :   struct condition *c;
     648     21652347 :   struct condition new_cond;
     649     21652347 :   HOST_WIDE_INT offset;
     650     21652347 :   bool agg_contents, by_ref;
     651     21652347 :   expr_eval_op *op;
     652              : 
     653     21652347 :   if (params_summary)
     654      8313311 :     ipa_set_param_used_by_ipa_predicates (params_summary, operand_num, true);
     655              : 
     656     21652347 :   if (aggpos)
     657              :     {
     658      9031269 :       offset = aggpos->offset;
     659      9031269 :       agg_contents = aggpos->agg_contents;
     660      9031269 :       by_ref = aggpos->by_ref;
     661              :     }
     662              :   else
     663              :     {
     664              :       offset = 0;
     665              :       agg_contents = false;
     666              :       by_ref = false;
     667              :     }
     668              : 
     669     21652347 :   gcc_checking_assert (operand_num >= 0);
     670    102268033 :   for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++)
     671              :     {
     672     90517914 :       if (c->operand_num == operand_num
     673     47595641 :           && c->code == code
     674     17781516 :           && types_compatible_p (c->type, type)
     675     15964751 :           && vrp_operand_equal_p (c->val, val)
     676     12350310 :           && c->agg_contents == agg_contents
     677     11912432 :           && expr_eval_ops_equal_p (c->param_ops, param_ops)
     678    102291737 :           && (!agg_contents || (c->offset == offset && c->by_ref == by_ref)))
     679      9902228 :         return ipa_predicate::predicate_testing_cond (i);
     680              :     }
     681              :   /* Too many conditions.  Give up and return constant true.  */
     682     11750119 :   if (i == ipa_predicate::num_conditions - ipa_predicate::first_dynamic_condition)
     683       266379 :     return true;
     684              : 
     685     11483740 :   new_cond.operand_num = operand_num;
     686     11483740 :   new_cond.code = code;
     687     11483740 :   new_cond.type = unshare_expr_without_location (type);
     688     11483740 :   new_cond.val = val ? unshare_expr_without_location (val) : val;
     689     11483740 :   new_cond.agg_contents = agg_contents;
     690     11483740 :   new_cond.by_ref = by_ref;
     691     11483740 :   new_cond.offset = offset;
     692     11483740 :   new_cond.param_ops = vec_safe_copy (param_ops);
     693              : 
     694     12012965 :   for (j = 0; vec_safe_iterate (new_cond.param_ops, j, &op); j++)
     695              :     {
     696       529225 :       if (op->val[0])
     697       274330 :         op->val[0] = unshare_expr_without_location (op->val[0]);
     698       529225 :       if (op->val[1])
     699           24 :         op->val[1] = unshare_expr_without_location (op->val[1]);
     700              :     }
     701              : 
     702     11483740 :   vec_safe_push (summary->conds, new_cond);
     703              : 
     704     11483740 :   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.