xref: /dflybsd-src/contrib/gcc-8.0/gcc/ipa-predicate.h (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 /* Representation of inline parameters that do depend on context function is
22*38fd1498Szrj    inlined into (i.e. known constant values of function parameters.
23*38fd1498Szrj 
24*38fd1498Szrj    Conditions that are interesting for function body are collected into CONDS
25*38fd1498Szrj    vector.  They are of simple for  function_param OP VAL, where VAL is
26*38fd1498Szrj    IPA invariant.  The conditions are then referred by predicates.  */
27*38fd1498Szrj 
28*38fd1498Szrj struct GTY(()) condition
29*38fd1498Szrj {
30*38fd1498Szrj   /* If agg_contents is set, this is the offset from which the used data was
31*38fd1498Szrj      loaded.  */
32*38fd1498Szrj   HOST_WIDE_INT offset;
33*38fd1498Szrj   /* Size of the access reading the data (or the PARM_DECL SSA_NAME).  */
34*38fd1498Szrj   HOST_WIDE_INT size;
35*38fd1498Szrj   tree val;
36*38fd1498Szrj   int operand_num;
37*38fd1498Szrj   ENUM_BITFIELD(tree_code) code : 16;
38*38fd1498Szrj   /* Set if the used data were loaded from an aggregate parameter or from
39*38fd1498Szrj      data received by reference.  */
40*38fd1498Szrj   unsigned agg_contents : 1;
41*38fd1498Szrj   /* If agg_contents is set, this differentiates between loads from data
42*38fd1498Szrj      passed by reference and by value.  */
43*38fd1498Szrj   unsigned by_ref : 1;
44*38fd1498Szrj };
45*38fd1498Szrj 
46*38fd1498Szrj /* Information kept about parameter of call site.  */
47*38fd1498Szrj struct inline_param_summary
48*38fd1498Szrj {
49*38fd1498Szrj   /* REG_BR_PROB_BASE based probability that parameter will change in between
50*38fd1498Szrj      two invocation of the calls.
51*38fd1498Szrj      I.e. loop invariant parameters
52*38fd1498Szrj      REG_BR_PROB_BASE/estimated_iterations and regular
53*38fd1498Szrj      parameters REG_BR_PROB_BASE.
54*38fd1498Szrj 
55*38fd1498Szrj      Value 0 is reserved for compile time invariants. */
56*38fd1498Szrj   int change_prob;
57*38fd1498Szrj };
58*38fd1498Szrj 
59*38fd1498Szrj typedef vec<condition, va_gc> *conditions;
60*38fd1498Szrj 
61*38fd1498Szrj /* Predicates are used to repesent function parameters (such as runtime)
62*38fd1498Szrj    which depend on a context function is called in.
63*38fd1498Szrj 
64*38fd1498Szrj    Predicates are logical formulas in conjunctive-disjunctive form consisting
65*38fd1498Szrj    of clauses which are bitmaps specifying a set of condition that must
66*38fd1498Szrj    be true for a clause to be satisfied. Physically they are represented as
67*38fd1498Szrj    array of clauses terminated by 0.
68*38fd1498Szrj 
69*38fd1498Szrj    In order to make predicate (possibly) true, all of its clauses must
70*38fd1498Szrj    be (possibly) true. To make clause (possibly) true, one of conditions
71*38fd1498Szrj    it mentions must be (possibly) true.
72*38fd1498Szrj 
73*38fd1498Szrj    There are fixed bounds on number of clauses and conditions and all the
74*38fd1498Szrj    manipulation functions are conservative in positive direction. I.e. we
75*38fd1498Szrj    may lose precision by thinking that predicate may be true even when it
76*38fd1498Szrj    is not.  */
77*38fd1498Szrj 
78*38fd1498Szrj typedef uint32_t clause_t;
79*38fd1498Szrj class predicate
80*38fd1498Szrj {
81*38fd1498Szrj public:
82*38fd1498Szrj   enum predicate_conditions
83*38fd1498Szrj     {
84*38fd1498Szrj       false_condition = 0,
85*38fd1498Szrj       not_inlined_condition = 1,
86*38fd1498Szrj       first_dynamic_condition = 2
87*38fd1498Szrj     };
88*38fd1498Szrj 
89*38fd1498Szrj   /* Maximal number of conditions predicate can reffer to.  This is limited
90*38fd1498Szrj      by using clause_t to be 32bit.  */
91*38fd1498Szrj   static const int num_conditions = 32;
92*38fd1498Szrj 
93*38fd1498Szrj   /* Special condition code we use to represent test that operand is compile
94*38fd1498Szrj      time constant.  */
95*38fd1498Szrj   static const tree_code is_not_constant = ERROR_MARK;
96*38fd1498Szrj 
97*38fd1498Szrj   /* Special condition code we use to represent test that operand is not changed
98*38fd1498Szrj      across invocation of the function.  When operand IS_NOT_CONSTANT it is
99*38fd1498Szrj      always CHANGED, however i.e. loop invariants can be NOT_CHANGED given
100*38fd1498Szrj      percentage of executions even when they are not compile time constants.  */
101*38fd1498Szrj   static const tree_code changed = IDENTIFIER_NODE;
102*38fd1498Szrj 
103*38fd1498Szrj 
104*38fd1498Szrj 
105*38fd1498Szrj   /* Initialize predicate either to true of false depending on P.  */
106*38fd1498Szrj   inline predicate (bool p = true)
107*38fd1498Szrj     {
108*38fd1498Szrj       if (p)
109*38fd1498Szrj         /* True predicate.  */
110*38fd1498Szrj         m_clause[0] = 0;
111*38fd1498Szrj       else
112*38fd1498Szrj         /* False predicate. */
113*38fd1498Szrj         set_to_cond (false_condition);
114*38fd1498Szrj     }
115*38fd1498Szrj 
116*38fd1498Szrj   /* Sanity check that we do not mix pointers to predicates with predicates.  */
predicate(predicate *)117*38fd1498Szrj   inline predicate (predicate *)
118*38fd1498Szrj     {
119*38fd1498Szrj       gcc_unreachable ();
120*38fd1498Szrj     }
121*38fd1498Szrj 
122*38fd1498Szrj   /* Return predicate testing condition I.  */
predicate_testing_cond(int i)123*38fd1498Szrj   static inline predicate predicate_testing_cond (int i)
124*38fd1498Szrj     {
125*38fd1498Szrj       class predicate p;
126*38fd1498Szrj       p.set_to_cond (i + first_dynamic_condition);
127*38fd1498Szrj       return p;
128*38fd1498Szrj     }
129*38fd1498Szrj 
130*38fd1498Szrj   /* Return predicate testing that function was not inlined.  */
not_inlined(void)131*38fd1498Szrj   static predicate not_inlined (void)
132*38fd1498Szrj     {
133*38fd1498Szrj       class predicate p;
134*38fd1498Szrj       p.set_to_cond (not_inlined_condition);
135*38fd1498Szrj       return p;
136*38fd1498Szrj     }
137*38fd1498Szrj 
138*38fd1498Szrj   /* Compute logical and of predicates.  */
139*38fd1498Szrj   predicate & operator &= (const predicate &);
140*38fd1498Szrj   inline predicate operator &(const predicate &p) const
141*38fd1498Szrj     {
142*38fd1498Szrj       predicate ret = *this;
143*38fd1498Szrj       ret &= p;
144*38fd1498Szrj       return ret;
145*38fd1498Szrj     }
146*38fd1498Szrj 
147*38fd1498Szrj   /* Compute logical or of predicates.  This is not operator because
148*38fd1498Szrj      extra parameter CONDITIONS is needed  */
149*38fd1498Szrj   predicate or_with (conditions, const predicate &) const;
150*38fd1498Szrj 
151*38fd1498Szrj   /* Return true if predicates are known to be equal.  */
152*38fd1498Szrj   inline bool operator==(const predicate &p2) const
153*38fd1498Szrj     {
154*38fd1498Szrj       int i;
155*38fd1498Szrj       for (i = 0; m_clause[i]; i++)
156*38fd1498Szrj 	{
157*38fd1498Szrj 	  gcc_checking_assert (i < max_clauses);
158*38fd1498Szrj 	  gcc_checking_assert (m_clause[i] > m_clause[i + 1]);
159*38fd1498Szrj 	  gcc_checking_assert (!p2.m_clause[i]
160*38fd1498Szrj 			       || p2.m_clause[i] > p2.m_clause[i + 1]);
161*38fd1498Szrj 	  if (m_clause[i] != p2.m_clause[i])
162*38fd1498Szrj 	    return false;
163*38fd1498Szrj 	}
164*38fd1498Szrj       return !p2.m_clause[i];
165*38fd1498Szrj     }
166*38fd1498Szrj 
167*38fd1498Szrj   /* Return true if predicates are known to be true or false depending
168*38fd1498Szrj      on COND.  */
169*38fd1498Szrj   inline bool operator==(const bool cond) const
170*38fd1498Szrj     {
171*38fd1498Szrj       if (cond)
172*38fd1498Szrj         return !m_clause[0];
173*38fd1498Szrj       if (m_clause[0] == (1 << false_condition))
174*38fd1498Szrj 	{
175*38fd1498Szrj 	  gcc_checking_assert (!m_clause[1]
176*38fd1498Szrj 			       && m_clause[0] == 1
177*38fd1498Szrj 				  << false_condition);
178*38fd1498Szrj 	  return true;
179*38fd1498Szrj 	}
180*38fd1498Szrj       return false;
181*38fd1498Szrj     }
182*38fd1498Szrj 
183*38fd1498Szrj   inline bool operator!=(const predicate &p2) const
184*38fd1498Szrj     {
185*38fd1498Szrj       return !(*this == p2);
186*38fd1498Szrj     }
187*38fd1498Szrj 
188*38fd1498Szrj   inline bool operator!=(const bool cond) const
189*38fd1498Szrj     {
190*38fd1498Szrj       return !(*this == cond);
191*38fd1498Szrj     }
192*38fd1498Szrj 
193*38fd1498Szrj   /* Evaluate if predicate is known to be false given the clause of possible
194*38fd1498Szrj      truths.  */
195*38fd1498Szrj   bool evaluate (clause_t) const;
196*38fd1498Szrj 
197*38fd1498Szrj   /* Estimate probability that predicate will be true in a given context.  */
198*38fd1498Szrj   int probability (conditions, clause_t, vec<inline_param_summary>) const;
199*38fd1498Szrj 
200*38fd1498Szrj   /* Dump predicate to F. Output newline if nl.  */
201*38fd1498Szrj   void dump (FILE *f, conditions, bool nl=true) const;
202*38fd1498Szrj   void DEBUG_FUNCTION debug (conditions) const;
203*38fd1498Szrj 
204*38fd1498Szrj   /* Return predicate equal to THIS after duplication.  */
205*38fd1498Szrj   predicate remap_after_duplication (clause_t);
206*38fd1498Szrj 
207*38fd1498Szrj   /* Return predicate equal to THIS after inlining.  */
208*38fd1498Szrj   predicate remap_after_inlining (struct ipa_fn_summary *,
209*38fd1498Szrj 			          struct ipa_fn_summary *,
210*38fd1498Szrj 			          vec<int>, vec<int>, clause_t, const predicate &);
211*38fd1498Szrj 
212*38fd1498Szrj   void stream_in (struct lto_input_block *);
213*38fd1498Szrj   void stream_out (struct output_block *);
214*38fd1498Szrj 
215*38fd1498Szrj private:
216*38fd1498Szrj   static const int max_clauses = 8;
217*38fd1498Szrj   clause_t m_clause[max_clauses + 1];
218*38fd1498Szrj 
219*38fd1498Szrj   /* Initialize predicate to one testing single condition number COND.  */
set_to_cond(int cond)220*38fd1498Szrj   inline void set_to_cond (int cond)
221*38fd1498Szrj     {
222*38fd1498Szrj       m_clause[0] = 1 << cond;
223*38fd1498Szrj       m_clause[1] = 0;
224*38fd1498Szrj     }
225*38fd1498Szrj 
226*38fd1498Szrj   void add_clause (conditions conditions, clause_t);
227*38fd1498Szrj };
228*38fd1498Szrj 
229*38fd1498Szrj void dump_condition (FILE *f, conditions conditions, int cond);
230*38fd1498Szrj predicate add_condition (struct ipa_fn_summary *summary, int operand_num,
231*38fd1498Szrj 			 HOST_WIDE_INT size, struct agg_position_info *aggpos,
232*38fd1498Szrj 			 enum tree_code code, tree val);
233