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