xref: /dflybsd-src/contrib/gcc-8.0/gcc/ipa-predicate.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj /* IPA predicates.
2*38fd1498Szrj    Copyright (C) 2003-2018 Free Software Foundation, Inc.
3*38fd1498Szrj    Contributed by Jan Hubicka
4*38fd1498Szrj 
5*38fd1498Szrj This file is part of GCC.
6*38fd1498Szrj 
7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
8*38fd1498Szrj the terms of the GNU General Public License as published by the Free
9*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
10*38fd1498Szrj version.
11*38fd1498Szrj 
12*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15*38fd1498Szrj for more details.
16*38fd1498Szrj 
17*38fd1498Szrj You should have received a copy of the GNU General Public License
18*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
19*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
20*38fd1498Szrj 
21*38fd1498Szrj #include "config.h"
22*38fd1498Szrj #include "system.h"
23*38fd1498Szrj #include "coretypes.h"
24*38fd1498Szrj #include "backend.h"
25*38fd1498Szrj #include "tree.h"
26*38fd1498Szrj #include "cgraph.h"
27*38fd1498Szrj #include "tree-vrp.h"
28*38fd1498Szrj #include "symbol-summary.h"
29*38fd1498Szrj #include "alloc-pool.h"
30*38fd1498Szrj #include "ipa-prop.h"
31*38fd1498Szrj #include "ipa-fnsummary.h"
32*38fd1498Szrj #include "real.h"
33*38fd1498Szrj #include "fold-const.h"
34*38fd1498Szrj #include "tree-pretty-print.h"
35*38fd1498Szrj #include "gimple.h"
36*38fd1498Szrj #include "data-streamer.h"
37*38fd1498Szrj 
38*38fd1498Szrj 
39*38fd1498Szrj /* Add clause CLAUSE into the predicate P.
40*38fd1498Szrj    When CONDITIONS is NULL do not perform checking whether NEW_CLAUSE
41*38fd1498Szrj    is obviously true.  This is useful only when NEW_CLAUSE is known to be
42*38fd1498Szrj    sane.  */
43*38fd1498Szrj 
44*38fd1498Szrj void
add_clause(conditions conditions,clause_t new_clause)45*38fd1498Szrj predicate::add_clause (conditions conditions, clause_t new_clause)
46*38fd1498Szrj {
47*38fd1498Szrj   int i;
48*38fd1498Szrj   int i2;
49*38fd1498Szrj   int insert_here = -1;
50*38fd1498Szrj   int c1, c2;
51*38fd1498Szrj 
52*38fd1498Szrj   /* True clause.  */
53*38fd1498Szrj   if (!new_clause)
54*38fd1498Szrj     return;
55*38fd1498Szrj 
56*38fd1498Szrj   /* False clause makes the whole predicate false.  Kill the other variants.  */
57*38fd1498Szrj   if (new_clause == (1 << predicate::false_condition))
58*38fd1498Szrj     {
59*38fd1498Szrj       *this = false;
60*38fd1498Szrj       return;
61*38fd1498Szrj     }
62*38fd1498Szrj   if (*this == false)
63*38fd1498Szrj     return;
64*38fd1498Szrj 
65*38fd1498Szrj   /* No one should be silly enough to add false into nontrivial clauses.  */
66*38fd1498Szrj   gcc_checking_assert (!(new_clause & (1 << predicate::false_condition)));
67*38fd1498Szrj 
68*38fd1498Szrj   /* Look where to insert the new_clause.  At the same time prune out
69*38fd1498Szrj      new_clauses of P that are implied by the new new_clause and thus
70*38fd1498Szrj      redundant.  */
71*38fd1498Szrj   for (i = 0, i2 = 0; i <= max_clauses; i++)
72*38fd1498Szrj     {
73*38fd1498Szrj       m_clause[i2] = m_clause[i];
74*38fd1498Szrj 
75*38fd1498Szrj       if (!m_clause[i])
76*38fd1498Szrj 	break;
77*38fd1498Szrj 
78*38fd1498Szrj       /* If m_clause[i] implies new_clause, there is nothing to add.  */
79*38fd1498Szrj       if ((m_clause[i] & new_clause) == m_clause[i])
80*38fd1498Szrj 	{
81*38fd1498Szrj 	  /* We had nothing to add, none of clauses should've become
82*38fd1498Szrj 	     redundant.  */
83*38fd1498Szrj 	  gcc_checking_assert (i == i2);
84*38fd1498Szrj 	  return;
85*38fd1498Szrj 	}
86*38fd1498Szrj 
87*38fd1498Szrj       if (m_clause[i] < new_clause && insert_here < 0)
88*38fd1498Szrj 	insert_here = i2;
89*38fd1498Szrj 
90*38fd1498Szrj       /* If new_clause implies clause[i], then clause[i] becomes redundant.
91*38fd1498Szrj          Otherwise the clause[i] has to stay.  */
92*38fd1498Szrj       if ((m_clause[i] & new_clause) != new_clause)
93*38fd1498Szrj 	i2++;
94*38fd1498Szrj     }
95*38fd1498Szrj 
96*38fd1498Szrj   /* Look for clauses that are obviously true.  I.e.
97*38fd1498Szrj      op0 == 5 || op0 != 5.  */
98*38fd1498Szrj   if (conditions)
99*38fd1498Szrj     for (c1 = predicate::first_dynamic_condition;
100*38fd1498Szrj 	 c1 < num_conditions; c1++)
101*38fd1498Szrj       {
102*38fd1498Szrj 	condition *cc1;
103*38fd1498Szrj 	if (!(new_clause & (1 << c1)))
104*38fd1498Szrj 	  continue;
105*38fd1498Szrj 	cc1 = &(*conditions)[c1 - predicate::first_dynamic_condition];
106*38fd1498Szrj 	/* We have no way to represent !changed and !is_not_constant
107*38fd1498Szrj 	   and thus there is no point for looking for them.  */
108*38fd1498Szrj 	if (cc1->code == changed || cc1->code == is_not_constant)
109*38fd1498Szrj 	  continue;
110*38fd1498Szrj 	for (c2 = c1 + 1; c2 < num_conditions; c2++)
111*38fd1498Szrj 	  if (new_clause & (1 << c2))
112*38fd1498Szrj 	    {
113*38fd1498Szrj 	      condition *cc1 =
114*38fd1498Szrj 		&(*conditions)[c1 - predicate::first_dynamic_condition];
115*38fd1498Szrj 	      condition *cc2 =
116*38fd1498Szrj 		&(*conditions)[c2 - predicate::first_dynamic_condition];
117*38fd1498Szrj 	      if (cc1->operand_num == cc2->operand_num
118*38fd1498Szrj 		  && cc1->val == cc2->val
119*38fd1498Szrj 		  && cc2->code != is_not_constant
120*38fd1498Szrj 		  && cc2->code != predicate::changed
121*38fd1498Szrj 		  && cc1->code == invert_tree_comparison (cc2->code,
122*38fd1498Szrj 							  HONOR_NANS (cc1->val)))
123*38fd1498Szrj 		return;
124*38fd1498Szrj 	    }
125*38fd1498Szrj       }
126*38fd1498Szrj 
127*38fd1498Szrj 
128*38fd1498Szrj   /* We run out of variants.  Be conservative in positive direction.  */
129*38fd1498Szrj   if (i2 == max_clauses)
130*38fd1498Szrj     return;
131*38fd1498Szrj   /* Keep clauses in decreasing order. This makes equivalence testing easy.  */
132*38fd1498Szrj   m_clause[i2 + 1] = 0;
133*38fd1498Szrj   if (insert_here >= 0)
134*38fd1498Szrj     for (; i2 > insert_here; i2--)
135*38fd1498Szrj       m_clause[i2] = m_clause[i2 - 1];
136*38fd1498Szrj   else
137*38fd1498Szrj     insert_here = i2;
138*38fd1498Szrj   m_clause[insert_here] = new_clause;
139*38fd1498Szrj }
140*38fd1498Szrj 
141*38fd1498Szrj 
142*38fd1498Szrj /* Do THIS &= P.  */
143*38fd1498Szrj 
144*38fd1498Szrj predicate &
145*38fd1498Szrj predicate::operator &= (const predicate &p)
146*38fd1498Szrj {
147*38fd1498Szrj   /* Avoid busy work.  */
148*38fd1498Szrj   if (p == false || *this == true)
149*38fd1498Szrj     {
150*38fd1498Szrj       *this = p;
151*38fd1498Szrj       return *this;
152*38fd1498Szrj     }
153*38fd1498Szrj   if (*this == false || p == true || this == &p)
154*38fd1498Szrj     return *this;
155*38fd1498Szrj 
156*38fd1498Szrj   int i;
157*38fd1498Szrj 
158*38fd1498Szrj   /* See how far predicates match.  */
159*38fd1498Szrj   for (i = 0; m_clause[i] && m_clause[i] == p.m_clause[i]; i++)
160*38fd1498Szrj     {
161*38fd1498Szrj       gcc_checking_assert (i < max_clauses);
162*38fd1498Szrj     }
163*38fd1498Szrj 
164*38fd1498Szrj   /* Combine the predicates rest.  */
165*38fd1498Szrj   for (; p.m_clause[i]; i++)
166*38fd1498Szrj     {
167*38fd1498Szrj       gcc_checking_assert (i < max_clauses);
168*38fd1498Szrj       add_clause (NULL, p.m_clause[i]);
169*38fd1498Szrj     }
170*38fd1498Szrj   return *this;
171*38fd1498Szrj }
172*38fd1498Szrj 
173*38fd1498Szrj 
174*38fd1498Szrj 
175*38fd1498Szrj /* Return THIS | P2.  */
176*38fd1498Szrj 
177*38fd1498Szrj predicate
or_with(conditions conditions,const predicate & p)178*38fd1498Szrj predicate::or_with (conditions conditions,
179*38fd1498Szrj 	            const predicate &p) const
180*38fd1498Szrj {
181*38fd1498Szrj   /* Avoid busy work.  */
182*38fd1498Szrj   if (p == false || *this == true || *this == p)
183*38fd1498Szrj     return *this;
184*38fd1498Szrj   if (*this == false || p == true)
185*38fd1498Szrj     return p;
186*38fd1498Szrj 
187*38fd1498Szrj   /* OK, combine the predicates.  */
188*38fd1498Szrj   predicate out = true;
189*38fd1498Szrj 
190*38fd1498Szrj   for (int i = 0; m_clause[i]; i++)
191*38fd1498Szrj     for (int j = 0; p.m_clause[j]; j++)
192*38fd1498Szrj       {
193*38fd1498Szrj 	gcc_checking_assert (i < max_clauses && j < max_clauses);
194*38fd1498Szrj 	out.add_clause (conditions, m_clause[i] | p.m_clause[j]);
195*38fd1498Szrj       }
196*38fd1498Szrj   return out;
197*38fd1498Szrj }
198*38fd1498Szrj 
199*38fd1498Szrj 
200*38fd1498Szrj /* Having partial truth assignment in POSSIBLE_TRUTHS, return false
201*38fd1498Szrj    if predicate P is known to be false.  */
202*38fd1498Szrj 
203*38fd1498Szrj bool
evaluate(clause_t possible_truths)204*38fd1498Szrj predicate::evaluate (clause_t possible_truths) const
205*38fd1498Szrj {
206*38fd1498Szrj   int i;
207*38fd1498Szrj 
208*38fd1498Szrj   /* True remains true.  */
209*38fd1498Szrj   if (*this == true)
210*38fd1498Szrj     return true;
211*38fd1498Szrj 
212*38fd1498Szrj   gcc_assert (!(possible_truths & (1 << predicate::false_condition)));
213*38fd1498Szrj 
214*38fd1498Szrj   /* See if we can find clause we can disprove.  */
215*38fd1498Szrj   for (i = 0; m_clause[i]; i++)
216*38fd1498Szrj     {
217*38fd1498Szrj       gcc_checking_assert (i < max_clauses);
218*38fd1498Szrj       if (!(m_clause[i] & possible_truths))
219*38fd1498Szrj 	return false;
220*38fd1498Szrj     }
221*38fd1498Szrj   return true;
222*38fd1498Szrj }
223*38fd1498Szrj 
224*38fd1498Szrj /* Return the probability in range 0...REG_BR_PROB_BASE that the predicated
225*38fd1498Szrj    instruction will be recomputed per invocation of the inlined call.  */
226*38fd1498Szrj 
227*38fd1498Szrj int
probability(conditions conds,clause_t possible_truths,vec<inline_param_summary> inline_param_summary)228*38fd1498Szrj predicate::probability (conditions conds,
229*38fd1498Szrj 	                clause_t possible_truths,
230*38fd1498Szrj 	                vec<inline_param_summary> inline_param_summary) const
231*38fd1498Szrj {
232*38fd1498Szrj   int i;
233*38fd1498Szrj   int combined_prob = REG_BR_PROB_BASE;
234*38fd1498Szrj 
235*38fd1498Szrj   /* True remains true.  */
236*38fd1498Szrj   if (*this == true)
237*38fd1498Szrj     return REG_BR_PROB_BASE;
238*38fd1498Szrj 
239*38fd1498Szrj   if (*this == false)
240*38fd1498Szrj     return 0;
241*38fd1498Szrj 
242*38fd1498Szrj   gcc_assert (!(possible_truths & (1 << predicate::false_condition)));
243*38fd1498Szrj 
244*38fd1498Szrj   /* See if we can find clause we can disprove.  */
245*38fd1498Szrj   for (i = 0; m_clause[i]; i++)
246*38fd1498Szrj     {
247*38fd1498Szrj       gcc_checking_assert (i < max_clauses);
248*38fd1498Szrj       if (!(m_clause[i] & possible_truths))
249*38fd1498Szrj 	return 0;
250*38fd1498Szrj       else
251*38fd1498Szrj 	{
252*38fd1498Szrj 	  int this_prob = 0;
253*38fd1498Szrj 	  int i2;
254*38fd1498Szrj 	  if (!inline_param_summary.exists ())
255*38fd1498Szrj 	    return REG_BR_PROB_BASE;
256*38fd1498Szrj 	  for (i2 = 0; i2 < num_conditions; i2++)
257*38fd1498Szrj 	    if ((m_clause[i] & possible_truths) & (1 << i2))
258*38fd1498Szrj 	      {
259*38fd1498Szrj 		if (i2 >= predicate::first_dynamic_condition)
260*38fd1498Szrj 		  {
261*38fd1498Szrj 		    condition *c =
262*38fd1498Szrj 		      &(*conds)[i2 - predicate::first_dynamic_condition];
263*38fd1498Szrj 		    if (c->code == predicate::changed
264*38fd1498Szrj 			&& (c->operand_num <
265*38fd1498Szrj 			    (int) inline_param_summary.length ()))
266*38fd1498Szrj 		      {
267*38fd1498Szrj 			int iprob =
268*38fd1498Szrj 			  inline_param_summary[c->operand_num].change_prob;
269*38fd1498Szrj 			this_prob = MAX (this_prob, iprob);
270*38fd1498Szrj 		      }
271*38fd1498Szrj 		    else
272*38fd1498Szrj 		      this_prob = REG_BR_PROB_BASE;
273*38fd1498Szrj 		  }
274*38fd1498Szrj 		else
275*38fd1498Szrj 		  this_prob = REG_BR_PROB_BASE;
276*38fd1498Szrj 	      }
277*38fd1498Szrj 	  combined_prob = MIN (this_prob, combined_prob);
278*38fd1498Szrj 	  if (!combined_prob)
279*38fd1498Szrj 	    return 0;
280*38fd1498Szrj 	}
281*38fd1498Szrj     }
282*38fd1498Szrj   return combined_prob;
283*38fd1498Szrj }
284*38fd1498Szrj 
285*38fd1498Szrj 
286*38fd1498Szrj /* Dump conditional COND.  */
287*38fd1498Szrj 
288*38fd1498Szrj void
dump_condition(FILE * f,conditions conditions,int cond)289*38fd1498Szrj dump_condition (FILE *f, conditions conditions, int cond)
290*38fd1498Szrj {
291*38fd1498Szrj   condition *c;
292*38fd1498Szrj   if (cond == predicate::false_condition)
293*38fd1498Szrj     fprintf (f, "false");
294*38fd1498Szrj   else if (cond == predicate::not_inlined_condition)
295*38fd1498Szrj     fprintf (f, "not inlined");
296*38fd1498Szrj   else
297*38fd1498Szrj     {
298*38fd1498Szrj       c = &(*conditions)[cond - predicate::first_dynamic_condition];
299*38fd1498Szrj       fprintf (f, "op%i", c->operand_num);
300*38fd1498Szrj       if (c->agg_contents)
301*38fd1498Szrj 	fprintf (f, "[%soffset: " HOST_WIDE_INT_PRINT_DEC "]",
302*38fd1498Szrj 		 c->by_ref ? "ref " : "", c->offset);
303*38fd1498Szrj       if (c->code == predicate::is_not_constant)
304*38fd1498Szrj 	{
305*38fd1498Szrj 	  fprintf (f, " not constant");
306*38fd1498Szrj 	  return;
307*38fd1498Szrj 	}
308*38fd1498Szrj       if (c->code == predicate::changed)
309*38fd1498Szrj 	{
310*38fd1498Szrj 	  fprintf (f, " changed");
311*38fd1498Szrj 	  return;
312*38fd1498Szrj 	}
313*38fd1498Szrj       fprintf (f, " %s ", op_symbol_code (c->code));
314*38fd1498Szrj       print_generic_expr (f, c->val);
315*38fd1498Szrj     }
316*38fd1498Szrj }
317*38fd1498Szrj 
318*38fd1498Szrj 
319*38fd1498Szrj /* Dump clause CLAUSE.  */
320*38fd1498Szrj 
321*38fd1498Szrj static void
dump_clause(FILE * f,conditions conds,clause_t clause)322*38fd1498Szrj dump_clause (FILE *f, conditions conds, clause_t clause)
323*38fd1498Szrj {
324*38fd1498Szrj   int i;
325*38fd1498Szrj   bool found = false;
326*38fd1498Szrj   fprintf (f, "(");
327*38fd1498Szrj   if (!clause)
328*38fd1498Szrj     fprintf (f, "true");
329*38fd1498Szrj   for (i = 0; i < predicate::num_conditions; i++)
330*38fd1498Szrj     if (clause & (1 << i))
331*38fd1498Szrj       {
332*38fd1498Szrj 	if (found)
333*38fd1498Szrj 	  fprintf (f, " || ");
334*38fd1498Szrj 	found = true;
335*38fd1498Szrj 	dump_condition (f, conds, i);
336*38fd1498Szrj       }
337*38fd1498Szrj   fprintf (f, ")");
338*38fd1498Szrj }
339*38fd1498Szrj 
340*38fd1498Szrj 
341*38fd1498Szrj /* Dump THIS to F. CONDS a vector of conditions used when evauating
342*38fd1498Szrj    predicats. When NL is true new line is output at the end of dump.  */
343*38fd1498Szrj 
344*38fd1498Szrj void
dump(FILE * f,conditions conds,bool nl)345*38fd1498Szrj predicate::dump (FILE *f, conditions conds, bool nl) const
346*38fd1498Szrj {
347*38fd1498Szrj   int i;
348*38fd1498Szrj   if (*this == true)
349*38fd1498Szrj     dump_clause (f, conds, 0);
350*38fd1498Szrj   else
351*38fd1498Szrj     for (i = 0; m_clause[i]; i++)
352*38fd1498Szrj       {
353*38fd1498Szrj 	if (i)
354*38fd1498Szrj 	  fprintf (f, " && ");
355*38fd1498Szrj 	dump_clause (f, conds, m_clause[i]);
356*38fd1498Szrj       }
357*38fd1498Szrj   if (nl)
358*38fd1498Szrj     fprintf (f, "\n");
359*38fd1498Szrj }
360*38fd1498Szrj 
361*38fd1498Szrj 
362*38fd1498Szrj void
debug(conditions conds)363*38fd1498Szrj predicate::debug (conditions conds) const
364*38fd1498Szrj {
365*38fd1498Szrj   dump (stderr, conds);
366*38fd1498Szrj }
367*38fd1498Szrj 
368*38fd1498Szrj 
369*38fd1498Szrj /* Remap predicate THIS of former function to be predicate of duplicated function.
370*38fd1498Szrj    POSSIBLE_TRUTHS is clause of possible truths in the duplicated node,
371*38fd1498Szrj    INFO is inline summary of the duplicated node.  */
372*38fd1498Szrj 
373*38fd1498Szrj predicate
remap_after_duplication(clause_t possible_truths)374*38fd1498Szrj predicate::remap_after_duplication (clause_t possible_truths)
375*38fd1498Szrj {
376*38fd1498Szrj   int j;
377*38fd1498Szrj   predicate out = true;
378*38fd1498Szrj   for (j = 0; m_clause[j]; j++)
379*38fd1498Szrj     if (!(possible_truths & m_clause[j]))
380*38fd1498Szrj       return false;
381*38fd1498Szrj     else
382*38fd1498Szrj       out.add_clause (NULL, possible_truths & m_clause[j]);
383*38fd1498Szrj   return out;
384*38fd1498Szrj }
385*38fd1498Szrj 
386*38fd1498Szrj 
387*38fd1498Szrj /* Translate all conditions from callee representation into caller
388*38fd1498Szrj    representation and symbolically evaluate predicate THIS into new predicate.
389*38fd1498Szrj 
390*38fd1498Szrj    INFO is ipa_fn_summary of function we are adding predicate into, CALLEE_INFO
391*38fd1498Szrj    is summary of function predicate P is from. OPERAND_MAP is array giving
392*38fd1498Szrj    callee formal IDs the caller formal IDs. POSSSIBLE_TRUTHS is clausule of all
393*38fd1498Szrj    callee conditions that may be true in caller context.  TOPLEV_PREDICATE is
394*38fd1498Szrj    predicate under which callee is executed.  OFFSET_MAP is an array of of
395*38fd1498Szrj    offsets that need to be added to conditions, negative offset means that
396*38fd1498Szrj    conditions relying on values passed by reference have to be discarded
397*38fd1498Szrj    because they might not be preserved (and should be considered offset zero
398*38fd1498Szrj    for other purposes).  */
399*38fd1498Szrj 
400*38fd1498Szrj predicate
remap_after_inlining(struct ipa_fn_summary * info,struct ipa_fn_summary * callee_info,vec<int> operand_map,vec<int> offset_map,clause_t possible_truths,const predicate & toplev_predicate)401*38fd1498Szrj predicate::remap_after_inlining (struct ipa_fn_summary *info,
402*38fd1498Szrj 				 struct ipa_fn_summary *callee_info,
403*38fd1498Szrj 				 vec<int> operand_map,
404*38fd1498Szrj 				 vec<int> offset_map,
405*38fd1498Szrj 				 clause_t possible_truths,
406*38fd1498Szrj 				 const predicate &toplev_predicate)
407*38fd1498Szrj {
408*38fd1498Szrj   int i;
409*38fd1498Szrj   predicate out = true;
410*38fd1498Szrj 
411*38fd1498Szrj   /* True predicate is easy.  */
412*38fd1498Szrj   if (*this == true)
413*38fd1498Szrj     return toplev_predicate;
414*38fd1498Szrj   for (i = 0; m_clause[i]; i++)
415*38fd1498Szrj     {
416*38fd1498Szrj       clause_t clause = m_clause[i];
417*38fd1498Szrj       int cond;
418*38fd1498Szrj       predicate clause_predicate = false;
419*38fd1498Szrj 
420*38fd1498Szrj       gcc_assert (i < max_clauses);
421*38fd1498Szrj 
422*38fd1498Szrj       for (cond = 0; cond < num_conditions; cond++)
423*38fd1498Szrj 	/* Do we have condition we can't disprove?   */
424*38fd1498Szrj 	if (clause & possible_truths & (1 << cond))
425*38fd1498Szrj 	  {
426*38fd1498Szrj 	    predicate cond_predicate;
427*38fd1498Szrj 	    /* Work out if the condition can translate to predicate in the
428*38fd1498Szrj 	       inlined function.  */
429*38fd1498Szrj 	    if (cond >= predicate::first_dynamic_condition)
430*38fd1498Szrj 	      {
431*38fd1498Szrj 		struct condition *c;
432*38fd1498Szrj 
433*38fd1498Szrj 		c = &(*callee_info->conds)[cond
434*38fd1498Szrj 					   -
435*38fd1498Szrj 					   predicate::first_dynamic_condition];
436*38fd1498Szrj 		/* See if we can remap condition operand to caller's operand.
437*38fd1498Szrj 		   Otherwise give up.  */
438*38fd1498Szrj 		if (!operand_map.exists ()
439*38fd1498Szrj 		    || (int) operand_map.length () <= c->operand_num
440*38fd1498Szrj 		    || operand_map[c->operand_num] == -1
441*38fd1498Szrj 		    /* TODO: For non-aggregate conditions, adding an offset is
442*38fd1498Szrj 		       basically an arithmetic jump function processing which
443*38fd1498Szrj 		       we should support in future.  */
444*38fd1498Szrj 		    || ((!c->agg_contents || !c->by_ref)
445*38fd1498Szrj 			&& offset_map[c->operand_num] > 0)
446*38fd1498Szrj 		    || (c->agg_contents && c->by_ref
447*38fd1498Szrj 			&& offset_map[c->operand_num] < 0))
448*38fd1498Szrj 		  cond_predicate = true;
449*38fd1498Szrj 		else
450*38fd1498Szrj 		  {
451*38fd1498Szrj 		    struct agg_position_info ap;
452*38fd1498Szrj 		    HOST_WIDE_INT offset_delta = offset_map[c->operand_num];
453*38fd1498Szrj 		    if (offset_delta < 0)
454*38fd1498Szrj 		      {
455*38fd1498Szrj 			gcc_checking_assert (!c->agg_contents || !c->by_ref);
456*38fd1498Szrj 			offset_delta = 0;
457*38fd1498Szrj 		      }
458*38fd1498Szrj 		    gcc_assert (!c->agg_contents
459*38fd1498Szrj 				|| c->by_ref || offset_delta == 0);
460*38fd1498Szrj 		    ap.offset = c->offset + offset_delta;
461*38fd1498Szrj 		    ap.agg_contents = c->agg_contents;
462*38fd1498Szrj 		    ap.by_ref = c->by_ref;
463*38fd1498Szrj 		    cond_predicate = add_condition (info,
464*38fd1498Szrj 						    operand_map[c->operand_num],
465*38fd1498Szrj 						    c->size, &ap, c->code,
466*38fd1498Szrj 						    c->val);
467*38fd1498Szrj 		  }
468*38fd1498Szrj 	      }
469*38fd1498Szrj 	    /* Fixed conditions remains same, construct single
470*38fd1498Szrj 	       condition predicate.  */
471*38fd1498Szrj 	    else
472*38fd1498Szrj 	      cond_predicate = predicate::predicate_testing_cond (cond);
473*38fd1498Szrj 	    clause_predicate = clause_predicate.or_with (info->conds,
474*38fd1498Szrj 					                 cond_predicate);
475*38fd1498Szrj 	  }
476*38fd1498Szrj       out &= clause_predicate;
477*38fd1498Szrj     }
478*38fd1498Szrj   out &= toplev_predicate;
479*38fd1498Szrj   return out;
480*38fd1498Szrj }
481*38fd1498Szrj 
482*38fd1498Szrj 
483*38fd1498Szrj /* Read predicate from IB.  */
484*38fd1498Szrj 
485*38fd1498Szrj void
stream_in(struct lto_input_block * ib)486*38fd1498Szrj predicate::stream_in (struct lto_input_block *ib)
487*38fd1498Szrj {
488*38fd1498Szrj   clause_t clause;
489*38fd1498Szrj   int k = 0;
490*38fd1498Szrj 
491*38fd1498Szrj   do
492*38fd1498Szrj     {
493*38fd1498Szrj       gcc_assert (k <= max_clauses);
494*38fd1498Szrj       clause = m_clause[k++] = streamer_read_uhwi (ib);
495*38fd1498Szrj     }
496*38fd1498Szrj   while (clause);
497*38fd1498Szrj 
498*38fd1498Szrj   /* Zero-initialize the remaining clauses in OUT.  */
499*38fd1498Szrj   while (k <= max_clauses)
500*38fd1498Szrj     m_clause[k++] = 0;
501*38fd1498Szrj }
502*38fd1498Szrj 
503*38fd1498Szrj 
504*38fd1498Szrj /* Write predicate P to OB.  */
505*38fd1498Szrj 
506*38fd1498Szrj void
stream_out(struct output_block * ob)507*38fd1498Szrj predicate::stream_out (struct output_block *ob)
508*38fd1498Szrj {
509*38fd1498Szrj   int j;
510*38fd1498Szrj   for (j = 0; m_clause[j]; j++)
511*38fd1498Szrj     {
512*38fd1498Szrj       gcc_assert (j < max_clauses);
513*38fd1498Szrj       streamer_write_uhwi (ob, m_clause[j]);
514*38fd1498Szrj     }
515*38fd1498Szrj   streamer_write_uhwi (ob, 0);
516*38fd1498Szrj }
517*38fd1498Szrj 
518*38fd1498Szrj 
519*38fd1498Szrj /* Add condition to condition list SUMMARY. OPERAND_NUM, SIZE, CODE and VAL
520*38fd1498Szrj    correspond to fields of condition structure.  AGGPOS describes whether the
521*38fd1498Szrj    used operand is loaded from an aggregate and where in the aggregate it is.
522*38fd1498Szrj    It can be NULL, which means this not a load from an aggregate.  */
523*38fd1498Szrj 
524*38fd1498Szrj predicate
add_condition(struct ipa_fn_summary * summary,int operand_num,HOST_WIDE_INT size,struct agg_position_info * aggpos,enum tree_code code,tree val)525*38fd1498Szrj add_condition (struct ipa_fn_summary *summary, int operand_num,
526*38fd1498Szrj 	       HOST_WIDE_INT size, struct agg_position_info *aggpos,
527*38fd1498Szrj 	       enum tree_code code, tree val)
528*38fd1498Szrj {
529*38fd1498Szrj   int i;
530*38fd1498Szrj   struct condition *c;
531*38fd1498Szrj   struct condition new_cond;
532*38fd1498Szrj   HOST_WIDE_INT offset;
533*38fd1498Szrj   bool agg_contents, by_ref;
534*38fd1498Szrj 
535*38fd1498Szrj   if (aggpos)
536*38fd1498Szrj     {
537*38fd1498Szrj       offset = aggpos->offset;
538*38fd1498Szrj       agg_contents = aggpos->agg_contents;
539*38fd1498Szrj       by_ref = aggpos->by_ref;
540*38fd1498Szrj     }
541*38fd1498Szrj   else
542*38fd1498Szrj     {
543*38fd1498Szrj       offset = 0;
544*38fd1498Szrj       agg_contents = false;
545*38fd1498Szrj       by_ref = false;
546*38fd1498Szrj     }
547*38fd1498Szrj 
548*38fd1498Szrj   gcc_checking_assert (operand_num >= 0);
549*38fd1498Szrj   for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++)
550*38fd1498Szrj     {
551*38fd1498Szrj       if (c->operand_num == operand_num
552*38fd1498Szrj 	  && c->size == size
553*38fd1498Szrj 	  && c->code == code
554*38fd1498Szrj 	  && c->val == val
555*38fd1498Szrj 	  && c->agg_contents == agg_contents
556*38fd1498Szrj 	  && (!agg_contents || (c->offset == offset && c->by_ref == by_ref)))
557*38fd1498Szrj 	return predicate::predicate_testing_cond (i);
558*38fd1498Szrj     }
559*38fd1498Szrj   /* Too many conditions.  Give up and return constant true.  */
560*38fd1498Szrj   if (i == predicate::num_conditions - predicate::first_dynamic_condition)
561*38fd1498Szrj     return true;
562*38fd1498Szrj 
563*38fd1498Szrj   new_cond.operand_num = operand_num;
564*38fd1498Szrj   new_cond.code = code;
565*38fd1498Szrj   new_cond.val = val;
566*38fd1498Szrj   new_cond.agg_contents = agg_contents;
567*38fd1498Szrj   new_cond.by_ref = by_ref;
568*38fd1498Szrj   new_cond.offset = offset;
569*38fd1498Szrj   new_cond.size = size;
570*38fd1498Szrj   vec_safe_push (summary->conds, new_cond);
571*38fd1498Szrj 
572*38fd1498Szrj   return predicate::predicate_testing_cond (i);
573*38fd1498Szrj }
574