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: 2024-12-21 13:15:12 Functions: 93.3 % 15 14
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* IPA predicates.
       2                 :             :    Copyright (C) 2003-2024 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                 :    12418405 : expr_eval_ops_equal_p (expr_eval_ops ops1, expr_eval_ops ops2)
      45                 :             : {
      46                 :    12418405 :   if (ops1)
      47                 :             :     {
      48                 :      960627 :       if (!ops2 || ops1->length () != ops2->length ())
      49                 :             :         return false;
      50                 :             : 
      51                 :     1361965 :       for (unsigned i = 0; i < ops1->length (); i++)
      52                 :             :         {
      53                 :      937651 :           expr_eval_op &op1 = (*ops1)[i];
      54                 :      937651 :           expr_eval_op &op2 = (*ops2)[i];
      55                 :             : 
      56                 :      937651 :           if (op1.code != op2.code
      57                 :      839286 :               || op1.index != op2.index
      58                 :      839286 :               || !vrp_operand_equal_p (op1.val[0], op2.val[0])
      59                 :      604867 :               || !vrp_operand_equal_p (op1.val[1], op2.val[1])
      60                 :     1542518 :               || !types_compatible_p (op1.type, op2.type))
      61                 :      333935 :             return false;
      62                 :             :         }
      63                 :             :       return true;
      64                 :             :     }
      65                 :    11457778 :   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                 :    45763258 : ipa_predicate::add_clause (conditions conditions, clause_t new_clause)
      75                 :             : {
      76                 :    45763258 :   int i;
      77                 :    45763258 :   int i2;
      78                 :    45763258 :   int insert_here = -1;
      79                 :    45763258 :   int c1, c2;
      80                 :             : 
      81                 :             :   /* True clause.  */
      82                 :    45763258 :   if (!new_clause)
      83                 :             :     return;
      84                 :             : 
      85                 :             :   /* False clause makes the whole predicate false.  Kill the other variants.  */
      86                 :    45763258 :   if (new_clause == (1 << ipa_predicate::false_condition))
      87                 :             :     {
      88                 :           0 :       *this = false;
      89                 :           0 :       return;
      90                 :             :     }
      91                 :    45763258 :   if (*this == false)
      92                 :             :     return;
      93                 :             : 
      94                 :             :   /* No one should be silly enough to add false into nontrivial clauses.  */
      95                 :    45763258 :   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                 :   124799952 :   for (i = 0, i2 = 0; i <= max_clauses; i++)
     101                 :             :     {
     102                 :   124799952 :       m_clause[i2] = m_clause[i];
     103                 :             : 
     104                 :   124799952 :       if (!m_clause[i])
     105                 :             :         break;
     106                 :             : 
     107                 :             :       /* If m_clause[i] implies new_clause, there is nothing to add.  */
     108                 :    90759281 :       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                 :    11722587 :           gcc_checking_assert (i == i2);
     113                 :             :           return;
     114                 :             :         }
     115                 :             : 
     116                 :    79036694 :       if (m_clause[i] < new_clause && insert_here < 0)
     117                 :    79036694 :         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                 :    79036694 :       if ((m_clause[i] & new_clause) != new_clause)
     122                 :    76131231 :         i2++;
     123                 :             :     }
     124                 :             : 
     125                 :             :   /* Look for clauses that are obviously true.  I.e.
     126                 :             :      op0 == 5 || op0 != 5.  */
     127                 :    34040671 :   if (conditions)
     128                 :   265849085 :     for (c1 = ipa_predicate::first_dynamic_condition;
     129                 :   275907974 :          c1 < num_conditions; c1++)
     130                 :             :       {
     131                 :   267136893 :         condition *cc1;
     132                 :   267136893 :         if (!(new_clause & (1 << c1)))
     133                 :   238928661 :           continue;
     134                 :    28208232 :         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                 :    28208232 :         if (cc1->code == changed || cc1->code == is_not_constant || cc1->code == not_sra_candidate)
     138                 :     6396374 :           continue;
     139                 :   482089103 :         for (c2 = c1 + 1; c2 < num_conditions; c2++)
     140                 :   461565053 :           if (new_clause & (1 << c2))
     141                 :             :             {
     142                 :    41404455 :               condition *cc2 =
     143                 :    41404455 :                 &(*conditions)[c2 - ipa_predicate::first_dynamic_condition];
     144                 :    41404455 :               if (cc1->operand_num == cc2->operand_num
     145                 :    35424925 :                   && vrp_operand_equal_p (cc1->val, cc2->val)
     146                 :     2578760 :                   && cc2->code != is_not_constant
     147                 :     2578760 :                   && cc2->code != not_sra_candidate
     148                 :     2578760 :                   && cc2->code != changed
     149                 :     2578760 :                   && expr_eval_ops_equal_p (cc1->param_ops, cc2->param_ops)
     150                 :     1997576 :                   && cc2->agg_contents == cc1->agg_contents
     151                 :     1837698 :                   && cc2->by_ref == cc1->by_ref
     152                 :     1835598 :                   && types_compatible_p (cc2->type, cc1->type)
     153                 :    43152158 :                   && cc1->code == invert_tree_comparison (cc2->code,
     154                 :     1747703 :                                                           HONOR_NANS (cc1->val)))
     155                 :             :                 return;
     156                 :             :             }
     157                 :             :       }
     158                 :             : 
     159                 :             : 
     160                 :             :   /* We run out of variants.  Be conservative in positive direction.  */
     161                 :    32752863 :   if (i2 == max_clauses)
     162                 :             :     return;
     163                 :             :   /* Keep clauses in decreasing order. This makes equivalence testing easy.  */
     164                 :    32361191 :   m_clause[i2 + 1] = 0;
     165                 :    32361191 :   if (insert_here >= 0)
     166                 :    39663856 :     for (; i2 > insert_here; i2--)
     167                 :    23207615 :       m_clause[i2] = m_clause[i2 - 1];
     168                 :             :   else
     169                 :             :     insert_here = i2;
     170                 :    32361191 :   m_clause[insert_here] = new_clause;
     171                 :             : }
     172                 :             : 
     173                 :             : 
     174                 :             : /* Do THIS &= P.  */
     175                 :             : 
     176                 :             : ipa_predicate &
     177                 :   408020951 : ipa_predicate::operator &= (const ipa_predicate &p)
     178                 :             : {
     179                 :             :   /* Avoid busy work.  */
     180                 :   408020951 :   if (p == false || *this == true)
     181                 :             :     {
     182                 :   318515147 :       *this = p;
     183                 :   318515147 :       return *this;
     184                 :             :     }
     185                 :    89505804 :   if (*this == false || p == true || this == &p)
     186                 :             :     return *this;
     187                 :             : 
     188                 :             :   int i;
     189                 :             : 
     190                 :             :   /* See how far ipa_predicates match.  */
     191                 :    64535366 :   for (i = 0; m_clause[i] && m_clause[i] == p.m_clause[i]; i++)
     192                 :             :     {
     193                 :    25364655 :       gcc_checking_assert (i < max_clauses);
     194                 :             :     }
     195                 :             : 
     196                 :             :   /* Combine the ipa_predicates rest.  */
     197                 :    68701384 :   for (; p.m_clause[i]; i++)
     198                 :             :     {
     199                 :    29530673 :       gcc_checking_assert (i < max_clauses);
     200                 :    29530673 :       add_clause (NULL, p.m_clause[i]);
     201                 :             :     }
     202                 :             :   return *this;
     203                 :             : }
     204                 :             : 
     205                 :             : 
     206                 :             : 
     207                 :             : /* Return THIS | P2.  */
     208                 :             : 
     209                 :             : ipa_predicate
     210                 :   110120199 : ipa_predicate::or_with (conditions conditions,
     211                 :             :                         const ipa_predicate &p) const
     212                 :             : {
     213                 :             :   /* Avoid busy work.  */
     214                 :   110120199 :   if (p == false || *this == true || *this == p)
     215                 :    13890915 :     return *this;
     216                 :    96229284 :   if (*this == false || p == true)
     217                 :    92032364 :     return p;
     218                 :             : 
     219                 :             :   /* OK, combine the predicates.  */
     220                 :     4196920 :   ipa_predicate out = true;
     221                 :             : 
     222                 :    10884047 :   for (int i = 0; m_clause[i]; i++)
     223                 :    22729008 :     for (int j = 0; p.m_clause[j]; j++)
     224                 :             :       {
     225                 :    16041881 :         gcc_checking_assert (i < max_clauses && j < max_clauses);
     226                 :    16041881 :         out.add_clause (conditions, m_clause[i] | p.m_clause[j]);
     227                 :             :       }
     228                 :     4196920 :   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                 :   217356530 : ipa_predicate::evaluate (clause_t possible_truths) const
     237                 :             : {
     238                 :   217356530 :   int i;
     239                 :             : 
     240                 :             :   /* True remains true.  */
     241                 :   217356530 :   if (*this == true)
     242                 :             :     return true;
     243                 :             : 
     244                 :   165760891 :   gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));
     245                 :             : 
     246                 :             :   /* See if we can find clause we can disprove.  */
     247                 :   374337621 :   for (i = 0; m_clause[i]; i++)
     248                 :             :     {
     249                 :   259272104 :       gcc_checking_assert (i < max_clauses);
     250                 :   259272104 :       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                 :    25057466 : ipa_predicate::probability (conditions conds,
     261                 :             :                         clause_t possible_truths,
     262                 :             :                         vec<inline_param_summary> inline_param_summary) const
     263                 :             : {
     264                 :    25057466 :   int i;
     265                 :    25057466 :   int combined_prob = REG_BR_PROB_BASE;
     266                 :             : 
     267                 :             :   /* True remains true.  */
     268                 :    25057466 :   if (*this == true)
     269                 :             :     return REG_BR_PROB_BASE;
     270                 :             : 
     271                 :    16451206 :   if (*this == false)
     272                 :             :     return 0;
     273                 :             : 
     274                 :    16451206 :   gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));
     275                 :             : 
     276                 :             :   /* See if we can find clause we can disprove.  */
     277                 :    39754164 :   for (i = 0; m_clause[i]; i++)
     278                 :             :     {
     279                 :    26359459 :       gcc_checking_assert (i < max_clauses);
     280                 :    26359459 :       if (!(m_clause[i] & possible_truths))
     281                 :             :         return 0;
     282                 :             :       else
     283                 :             :         {
     284                 :    26359459 :           int this_prob = 0;
     285                 :    26359459 :           int i2;
     286                 :    26359459 :           if (!inline_param_summary.exists ())
     287                 :             :             return REG_BR_PROB_BASE;
     288                 :   869853798 :           for (i2 = 0; i2 < num_conditions; i2++)
     289                 :   843494592 :             if ((m_clause[i] & possible_truths) & (1 << i2))
     290                 :             :               {
     291                 :    31075747 :                 if (i2 >= ipa_predicate::first_dynamic_condition)
     292                 :             :                   {
     293                 :    31075747 :                     condition *c =
     294                 :    31075747 :                       &(*conds)[i2 - ipa_predicate::first_dynamic_condition];
     295                 :    31075747 :                     if (c->code == ipa_predicate::changed
     296                 :    31075747 :                         && (c->operand_num <
     297                 :    13513963 :                             (int) inline_param_summary.length ()))
     298                 :             :                       {
     299                 :    13513960 :                         int iprob =
     300                 :    13513960 :                           inline_param_summary[c->operand_num].change_prob;
     301                 :    13513960 :                         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                 :    26359206 :           combined_prob = MIN (this_prob, combined_prob);
     310                 :    26359206 :           if (!combined_prob)
     311                 :             :             return 0;
     312                 :             :         }
     313                 :             :     }
     314                 :             :   return combined_prob;
     315                 :             : }
     316                 :             : 
     317                 :             : 
     318                 :             : /* Dump conditional COND.  */
     319                 :             : 
     320                 :             : void
     321                 :       14098 : dump_condition (FILE *f, conditions conditions, int cond)
     322                 :             : {
     323                 :       14098 :   condition *c;
     324                 :       14098 :   if (cond == ipa_predicate::false_condition)
     325                 :        2551 :     fprintf (f, "false");
     326                 :       11547 :   else if (cond == ipa_predicate::not_inlined_condition)
     327                 :        3287 :     fprintf (f, "not inlined");
     328                 :             :   else
     329                 :             :     {
     330                 :        8260 :       c = &(*conditions)[cond - ipa_predicate::first_dynamic_condition];
     331                 :        8260 :       fprintf (f, "op%i", c->operand_num);
     332                 :        8260 :       if (c->agg_contents)
     333                 :        1535 :         fprintf (f, "[%soffset: " HOST_WIDE_INT_PRINT_DEC "]",
     334                 :        1535 :                  c->by_ref ? "ref " : "", c->offset);
     335                 :             : 
     336                 :        9284 :       for (unsigned i = 0; i < vec_safe_length (c->param_ops); i++)
     337                 :             :         {
     338                 :        1024 :           expr_eval_op &op = (*(c->param_ops))[i];
     339                 :        1024 :           const char *op_name = op_symbol_code (op.code);
     340                 :             : 
     341                 :        1024 :           if (op_name == op_symbol_code (ERROR_MARK))
     342                 :         288 :             op_name = get_tree_code_name (op.code);
     343                 :             : 
     344                 :        1024 :           fprintf (f, ",(");
     345                 :             : 
     346                 :        1024 :           if (!op.val[0])
     347                 :             :             {
     348                 :         288 :               switch (op.code)
     349                 :             :                 {
     350                 :         288 :                 case FLOAT_EXPR:
     351                 :         288 :                 case FIX_TRUNC_EXPR:
     352                 :         288 :                 case FIXED_CONVERT_EXPR:
     353                 :         288 :                 case VIEW_CONVERT_EXPR:
     354                 :         288 :                 CASE_CONVERT:
     355                 :         288 :                   if (op.code == VIEW_CONVERT_EXPR)
     356                 :           0 :                     fprintf (f, "VCE");
     357                 :         288 :                   fprintf (f, "(");
     358                 :         288 :                   print_generic_expr (f, op.type);
     359                 :         288 :                   fprintf (f, ")" );
     360                 :         288 :                   break;
     361                 :             : 
     362                 :           0 :                 default:
     363                 :           0 :                   fprintf (f, "%s", op_name);
     364                 :             :                 }
     365                 :         288 :               fprintf (f, " #");
     366                 :             :             }
     367                 :         736 :           else if (!op.val[1])
     368                 :             :             {
     369                 :         736 :               if (op.index)
     370                 :             :                 {
     371                 :          48 :                   print_generic_expr (f, op.val[0]);
     372                 :          48 :                   fprintf (f, " %s #", op_name);
     373                 :             :                 }
     374                 :             :               else
     375                 :             :                 {
     376                 :         688 :                   fprintf (f, "# %s ", op_name);
     377                 :         688 :                   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                 :        1024 :           fprintf (f, ")");
     410                 :             :         }
     411                 :             : 
     412                 :        8260 :       if (c->code == ipa_predicate::is_not_constant)
     413                 :             :         {
     414                 :          18 :           fprintf (f, " not constant");
     415                 :          18 :           return;
     416                 :             :         }
     417                 :        8242 :       if (c->code == ipa_predicate::changed)
     418                 :             :         {
     419                 :        1780 :           fprintf (f, " changed");
     420                 :        1780 :           return;
     421                 :             :         }
     422                 :        6462 :       if (c->code == ipa_predicate::not_sra_candidate)
     423                 :             :         {
     424                 :        1704 :           fprintf (f, " not sra candidate");
     425                 :        1704 :           return;
     426                 :             :         }
     427                 :        4758 :       fprintf (f, " %s ", op_symbol_code (c->code));
     428                 :        4758 :       print_generic_expr (f, c->val);
     429                 :             :     }
     430                 :             : }
     431                 :             : 
     432                 :             : 
     433                 :             : /* Dump clause CLAUSE.  */
     434                 :             : 
     435                 :             : static void
     436                 :       15718 : dump_clause (FILE *f, conditions conds, clause_t clause)
     437                 :             : {
     438                 :       15718 :   int i;
     439                 :       15718 :   bool found = false;
     440                 :       15718 :   fprintf (f, "(");
     441                 :       15718 :   if (!clause)
     442                 :        3441 :     fprintf (f, "true");
     443                 :      518694 :   for (i = 0; i < ipa_predicate::num_conditions; i++)
     444                 :      502976 :     if (clause & (1 << i))
     445                 :             :       {
     446                 :       12709 :         if (found)
     447                 :         432 :           fprintf (f, " || ");
     448                 :       12709 :         found = true;
     449                 :       12709 :         dump_condition (f, conds, i);
     450                 :             :       }
     451                 :       15718 :   fprintf (f, ")");
     452                 :       15718 : }
     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                 :       12489 : ipa_predicate::dump (FILE *f, conditions conds, bool nl) const
     460                 :             : {
     461                 :       12489 :   int i;
     462                 :       12489 :   if (*this == true)
     463                 :        3441 :     dump_clause (f, conds, 0);
     464                 :             :   else
     465                 :       21325 :     for (i = 0; m_clause[i]; i++)
     466                 :             :       {
     467                 :       12277 :         if (i)
     468                 :        3229 :           fprintf (f, " && ");
     469                 :       12277 :         dump_clause (f, conds, m_clause[i]);
     470                 :             :       }
     471                 :       12489 :   if (nl)
     472                 :        4908 :     fprintf (f, "\n");
     473                 :       12489 : }
     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                 :      147044 : ipa_predicate::remap_after_duplication (clause_t possible_truths)
     489                 :             : {
     490                 :      147044 :   int j;
     491                 :      147044 :   ipa_predicate out = true;
     492                 :      337748 :   for (j = 0; m_clause[j]; j++)
     493                 :      204739 :     if (!(possible_truths & m_clause[j]))
     494                 :       14035 :       return false;
     495                 :             :     else
     496                 :      190704 :       out.add_clause (NULL, possible_truths & m_clause[j]);
     497                 :      133009 :   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                 :    30785243 : 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                 :    30785243 :   int i;
     524                 :    30785243 :   ipa_predicate out = true;
     525                 :             : 
     526                 :             :   /* True ipa_predicate is easy.  */
     527                 :    30785243 :   if (*this == true)
     528                 :     8052526 :     return toplev_predicate;
     529                 :    58485836 :   for (i = 0; m_clause[i]; i++)
     530                 :             :     {
     531                 :    35753119 :       clause_t clause = m_clause[i];
     532                 :    35753119 :       int cond;
     533                 :    35753119 :       ipa_predicate clause_predicate = false;
     534                 :             : 
     535                 :    35753119 :       gcc_assert (i < max_clauses);
     536                 :             : 
     537                 :  1179852927 :       for (cond = 0; cond < num_conditions; cond++)
     538                 :             :         /* Do we have condition we can't disprove?   */
     539                 :  1144099808 :         if (clause & possible_truths & (1 << cond))
     540                 :             :           {
     541                 :    20144397 :             ipa_predicate cond_predicate;
     542                 :             :             /* Work out if the condition can translate to predicate in the
     543                 :             :                inlined function.  */
     544                 :    20144397 :             if (cond >= ipa_predicate::first_dynamic_condition)
     545                 :             :               {
     546                 :    20144397 :                 struct condition *c;
     547                 :             : 
     548                 :    20144397 :                 int index = cond - ipa_predicate::first_dynamic_condition;
     549                 :    20144397 :                 c = &(*callee_info->conds)[index];
     550                 :             :                 /* See if we can remap condition operand to caller's operand.
     551                 :             :                    Otherwise give up.  */
     552                 :    20144397 :                 if (!operand_map.exists ()
     553                 :    20144397 :                     || (int) operand_map.length () <= c->operand_num
     554                 :     8941605 :                     || 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                 :     2816124 :                     || ((!c->agg_contents || !c->by_ref)
     559                 :     1551213 :                         && offset_map[c->operand_num] > 0)
     560                 :    22886695 :                     || (c->agg_contents && c->by_ref
     561                 :     1264911 :                         && offset_map[c->operand_num] < 0))
     562                 :    18086889 :                   cond_predicate = true;
     563                 :             :                 else
     564                 :             :                   {
     565                 :     2057508 :                     struct agg_position_info ap;
     566                 :     2057508 :                     HOST_WIDE_INT offset_delta = offset_map[c->operand_num];
     567                 :     2057508 :                     if (offset_delta < 0)
     568                 :             :                       {
     569                 :     1018594 :                         gcc_checking_assert (!c->agg_contents || !c->by_ref);
     570                 :             :                         offset_delta = 0;
     571                 :             :                       }
     572                 :     2057508 :                     gcc_assert (!c->agg_contents
     573                 :             :                                 || c->by_ref || offset_delta == 0);
     574                 :     2057508 :                     ap.offset = c->offset + offset_delta;
     575                 :     2057508 :                     ap.agg_contents = c->agg_contents;
     576                 :     2057508 :                     ap.by_ref = c->by_ref;
     577                 :     4115016 :                     cond_predicate = add_condition (info, params_summary,
     578                 :     2057508 :                                                     operand_map[c->operand_num],
     579                 :     2057508 :                                                     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                 :    20144397 :             clause_predicate = clause_predicate.or_with (info->conds,
     588                 :             :                                                          cond_predicate);
     589                 :             :           }
     590                 :    35753119 :       out &= clause_predicate;
     591                 :             :     }
     592                 :    22732717 :   out &= toplev_predicate;
     593                 :    22732717 :   return out;
     594                 :             : }
     595                 :             : 
     596                 :             : 
     597                 :             : /* Read predicate from IB.  */
     598                 :             : 
     599                 :             : void
     600                 :      810444 : ipa_predicate::stream_in (class lto_input_block *ib)
     601                 :             : {
     602                 :      810444 :   clause_t clause;
     603                 :      810444 :   int k = 0;
     604                 :             : 
     605                 :     1137321 :   do
     606                 :             :     {
     607                 :     1137321 :       gcc_assert (k <= max_clauses);
     608                 :     1137321 :       clause = m_clause[k++] = streamer_read_uhwi (ib);
     609                 :             :     }
     610                 :     1137321 :   while (clause);
     611                 :             : 
     612                 :             :   /* Zero-initialize the remaining clauses in OUT.  */
     613                 :     6967119 :   while (k <= max_clauses)
     614                 :     6156675 :     m_clause[k++] = 0;
     615                 :      810444 : }
     616                 :             : 
     617                 :             : 
     618                 :             : /* Write predicate P to OB.  */
     619                 :             : 
     620                 :             : void
     621                 :      572974 : ipa_predicate::stream_out (struct output_block *ob)
     622                 :             : {
     623                 :      572974 :   int j;
     624                 :      976591 :   for (j = 0; m_clause[j]; j++)
     625                 :             :     {
     626                 :      403617 :       gcc_assert (j < max_clauses);
     627                 :      403617 :       streamer_write_uhwi (ob, m_clause[j]);
     628                 :             :     }
     629                 :      572974 :   streamer_write_uhwi (ob, 0);
     630                 :      572974 : }
     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                 :    18979363 : 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                 :    18979363 :   int i, j;
     647                 :    18979363 :   struct condition *c;
     648                 :    18979363 :   struct condition new_cond;
     649                 :    18979363 :   HOST_WIDE_INT offset;
     650                 :    18979363 :   bool agg_contents, by_ref;
     651                 :    18979363 :   expr_eval_op *op;
     652                 :             : 
     653                 :    18979363 :   if (params_summary)
     654                 :     6693037 :     ipa_set_param_used_by_ipa_predicates (params_summary, operand_num, true);
     655                 :             : 
     656                 :    18979363 :   if (aggpos)
     657                 :             :     {
     658                 :     7277404 :       offset = aggpos->offset;
     659                 :     7277404 :       agg_contents = aggpos->agg_contents;
     660                 :     7277404 :       by_ref = aggpos->by_ref;
     661                 :             :     }
     662                 :             :   else
     663                 :             :     {
     664                 :             :       offset = 0;
     665                 :             :       agg_contents = false;
     666                 :             :       by_ref = false;
     667                 :             :     }
     668                 :             : 
     669                 :    18979363 :   gcc_checking_assert (operand_num >= 0);
     670                 :    85615337 :   for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++)
     671                 :             :     {
     672                 :    74816444 :       if (c->operand_num == operand_num
     673                 :    37458676 :           && c->code == code
     674                 :    14676464 :           && types_compatible_p (c->type, type)
     675                 :    13030131 :           && vrp_operand_equal_p (c->val, val)
     676                 :    10193605 :           && c->agg_contents == agg_contents
     677                 :     9839645 :           && expr_eval_ops_equal_p (c->param_ops, param_ops)
     678                 :    84535728 :           && (!agg_contents || (c->offset == offset && c->by_ref == by_ref)))
     679                 :     8180470 :         return ipa_predicate::predicate_testing_cond (i);
     680                 :             :     }
     681                 :             :   /* Too many conditions.  Give up and return constant true.  */
     682                 :    10798893 :   if (i == ipa_predicate::num_conditions - ipa_predicate::first_dynamic_condition)
     683                 :      272044 :     return true;
     684                 :             : 
     685                 :    10526849 :   new_cond.operand_num = operand_num;
     686                 :    10526849 :   new_cond.code = code;
     687                 :    10526849 :   new_cond.type = unshare_expr_without_location (type);
     688                 :    10526849 :   new_cond.val = val ? unshare_expr_without_location (val) : val;
     689                 :    10526849 :   new_cond.agg_contents = agg_contents;
     690                 :    10526849 :   new_cond.by_ref = by_ref;
     691                 :    10526849 :   new_cond.offset = offset;
     692                 :    10526849 :   new_cond.param_ops = vec_safe_copy (param_ops);
     693                 :             : 
     694                 :    11056310 :   for (j = 0; vec_safe_iterate (new_cond.param_ops, j, &op); j++)
     695                 :             :     {
     696                 :      529461 :       if (op->val[0])
     697                 :      284549 :         op->val[0] = unshare_expr_without_location (op->val[0]);
     698                 :      529461 :       if (op->val[1])
     699                 :          24 :         op->val[1] = unshare_expr_without_location (op->val[1]);
     700                 :             :     }
     701                 :             : 
     702                 :    10526849 :   vec_safe_push (summary->conds, new_cond);
     703                 :             : 
     704                 :    10526849 :   return ipa_predicate::predicate_testing_cond (i);
     705                 :             : }
        

Generated by: LCOV version 2.1-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.