1*e4b17023SJohn Marino /* Conditional Dead Call Elimination pass for the GNU compiler.
2*e4b17023SJohn Marino Copyright (C) 2008, 2009, 2010
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino Contributed by Xinliang David Li <davidxl@google.com>
5*e4b17023SJohn Marino
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it
9*e4b17023SJohn Marino under the terms of the GNU General Public License as published by the
10*e4b17023SJohn Marino Free Software Foundation; either version 3, or (at your option) any
11*e4b17023SJohn Marino later version.
12*e4b17023SJohn Marino
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT
14*e4b17023SJohn Marino ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16*e4b17023SJohn Marino for more details.
17*e4b17023SJohn Marino
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21*e4b17023SJohn Marino
22*e4b17023SJohn Marino #include "config.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino #include "coretypes.h"
25*e4b17023SJohn Marino #include "tm.h"
26*e4b17023SJohn Marino #include "basic-block.h"
27*e4b17023SJohn Marino #include "tree.h"
28*e4b17023SJohn Marino #include "gimple-pretty-print.h"
29*e4b17023SJohn Marino #include "tree-flow.h"
30*e4b17023SJohn Marino #include "gimple.h"
31*e4b17023SJohn Marino #include "tree-dump.h"
32*e4b17023SJohn Marino #include "tree-pass.h"
33*e4b17023SJohn Marino #include "timevar.h"
34*e4b17023SJohn Marino #include "flags.h"
35*e4b17023SJohn Marino
36*e4b17023SJohn Marino
37*e4b17023SJohn Marino /* Conditional dead call elimination
38*e4b17023SJohn Marino
39*e4b17023SJohn Marino Some builtin functions can set errno on error conditions, but they
40*e4b17023SJohn Marino are otherwise pure. If the result of a call to such a function is
41*e4b17023SJohn Marino not used, the compiler can still not eliminate the call without
42*e4b17023SJohn Marino powerful interprocedural analysis to prove that the errno is not
43*e4b17023SJohn Marino checked. However, if the conditions under which the error occurs
44*e4b17023SJohn Marino are known, the compiler can conditionally dead code eliminate the
45*e4b17023SJohn Marino calls by shrink-wrapping the semi-dead calls into the error condition:
46*e4b17023SJohn Marino
47*e4b17023SJohn Marino built_in_call (args)
48*e4b17023SJohn Marino ==>
49*e4b17023SJohn Marino if (error_cond (args))
50*e4b17023SJohn Marino built_in_call (args)
51*e4b17023SJohn Marino
52*e4b17023SJohn Marino An actual simple example is :
53*e4b17023SJohn Marino log (x); // Mostly dead call
54*e4b17023SJohn Marino ==>
55*e4b17023SJohn Marino if (x < 0)
56*e4b17023SJohn Marino log (x);
57*e4b17023SJohn Marino With this change, call to log (x) is effectively eliminated, as
58*e4b17023SJohn Marino in majority of the cases, log won't be called with x out of
59*e4b17023SJohn Marino range. The branch is totally predictable, so the branch cost
60*e4b17023SJohn Marino is low.
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino Note that library functions are not supposed to clear errno to zero without
63*e4b17023SJohn Marino error. See IEEE Std 1003.1, section 2.3 Error Numbers, and section 7.5:3 of
64*e4b17023SJohn Marino ISO/IEC 9899 (C99).
65*e4b17023SJohn Marino
66*e4b17023SJohn Marino The condition wrapping the builtin call is conservatively set to avoid too
67*e4b17023SJohn Marino aggressive (wrong) shrink wrapping. The optimization is called conditional
68*e4b17023SJohn Marino dead call elimination because the call is eliminated under the condition
69*e4b17023SJohn Marino that the input arguments would not lead to domain or range error (for
70*e4b17023SJohn Marino instance when x <= 0 for a log (x) call), however the chances that the error
71*e4b17023SJohn Marino condition is hit is very low (those builtin calls which are conditionally
72*e4b17023SJohn Marino dead are usually part of the C++ abstraction penalty exposed after
73*e4b17023SJohn Marino inlining). */
74*e4b17023SJohn Marino
75*e4b17023SJohn Marino
76*e4b17023SJohn Marino /* A structure for representing input domain of
77*e4b17023SJohn Marino a function argument in integer. If the lower
78*e4b17023SJohn Marino bound is -inf, has_lb is set to false. If the
79*e4b17023SJohn Marino upper bound is +inf, has_ub is false.
80*e4b17023SJohn Marino is_lb_inclusive and is_ub_inclusive are flags
81*e4b17023SJohn Marino to indicate if lb and ub value are inclusive
82*e4b17023SJohn Marino respectively. */
83*e4b17023SJohn Marino
84*e4b17023SJohn Marino typedef struct input_domain
85*e4b17023SJohn Marino {
86*e4b17023SJohn Marino int lb;
87*e4b17023SJohn Marino int ub;
88*e4b17023SJohn Marino bool has_lb;
89*e4b17023SJohn Marino bool has_ub;
90*e4b17023SJohn Marino bool is_lb_inclusive;
91*e4b17023SJohn Marino bool is_ub_inclusive;
92*e4b17023SJohn Marino } inp_domain;
93*e4b17023SJohn Marino
94*e4b17023SJohn Marino /* A helper function to construct and return an input
95*e4b17023SJohn Marino domain object. LB is the lower bound, HAS_LB is
96*e4b17023SJohn Marino a boolean flag indicating if the lower bound exists,
97*e4b17023SJohn Marino and LB_INCLUSIVE is a boolean flag indicating if the
98*e4b17023SJohn Marino lower bound is inclusive or not. UB, HAS_UB, and
99*e4b17023SJohn Marino UB_INCLUSIVE have the same meaning, but for upper
100*e4b17023SJohn Marino bound of the domain. */
101*e4b17023SJohn Marino
102*e4b17023SJohn Marino static inp_domain
get_domain(int lb,bool has_lb,bool lb_inclusive,int ub,bool has_ub,bool ub_inclusive)103*e4b17023SJohn Marino get_domain (int lb, bool has_lb, bool lb_inclusive,
104*e4b17023SJohn Marino int ub, bool has_ub, bool ub_inclusive)
105*e4b17023SJohn Marino {
106*e4b17023SJohn Marino inp_domain domain;
107*e4b17023SJohn Marino domain.lb = lb;
108*e4b17023SJohn Marino domain.has_lb = has_lb;
109*e4b17023SJohn Marino domain.is_lb_inclusive = lb_inclusive;
110*e4b17023SJohn Marino domain.ub = ub;
111*e4b17023SJohn Marino domain.has_ub = has_ub;
112*e4b17023SJohn Marino domain.is_ub_inclusive = ub_inclusive;
113*e4b17023SJohn Marino return domain;
114*e4b17023SJohn Marino }
115*e4b17023SJohn Marino
116*e4b17023SJohn Marino /* A helper function to check the target format for the
117*e4b17023SJohn Marino argument type. In this implementation, only IEEE formats
118*e4b17023SJohn Marino are supported. ARG is the call argument to be checked.
119*e4b17023SJohn Marino Returns true if the format is supported. To support other
120*e4b17023SJohn Marino target formats, function get_no_error_domain needs to be
121*e4b17023SJohn Marino enhanced to have range bounds properly computed. Since
122*e4b17023SJohn Marino the check is cheap (very small number of candidates
123*e4b17023SJohn Marino to be checked), the result is not cached for each float type. */
124*e4b17023SJohn Marino
125*e4b17023SJohn Marino static bool
check_target_format(tree arg)126*e4b17023SJohn Marino check_target_format (tree arg)
127*e4b17023SJohn Marino {
128*e4b17023SJohn Marino tree type;
129*e4b17023SJohn Marino enum machine_mode mode;
130*e4b17023SJohn Marino const struct real_format *rfmt;
131*e4b17023SJohn Marino
132*e4b17023SJohn Marino type = TREE_TYPE (arg);
133*e4b17023SJohn Marino mode = TYPE_MODE (type);
134*e4b17023SJohn Marino rfmt = REAL_MODE_FORMAT (mode);
135*e4b17023SJohn Marino if ((mode == SFmode
136*e4b17023SJohn Marino && (rfmt == &ieee_single_format || rfmt == &mips_single_format
137*e4b17023SJohn Marino || rfmt == &motorola_single_format))
138*e4b17023SJohn Marino || (mode == DFmode
139*e4b17023SJohn Marino && (rfmt == &ieee_double_format || rfmt == &mips_double_format
140*e4b17023SJohn Marino || rfmt == &motorola_double_format))
141*e4b17023SJohn Marino /* For long double, we can not really check XFmode
142*e4b17023SJohn Marino which is only defined on intel platforms.
143*e4b17023SJohn Marino Candidate pre-selection using builtin function
144*e4b17023SJohn Marino code guarantees that we are checking formats
145*e4b17023SJohn Marino for long double modes: double, quad, and extended. */
146*e4b17023SJohn Marino || (mode != SFmode && mode != DFmode
147*e4b17023SJohn Marino && (rfmt == &ieee_quad_format
148*e4b17023SJohn Marino || rfmt == &mips_quad_format
149*e4b17023SJohn Marino || rfmt == &ieee_extended_motorola_format
150*e4b17023SJohn Marino || rfmt == &ieee_extended_intel_96_format
151*e4b17023SJohn Marino || rfmt == &ieee_extended_intel_128_format
152*e4b17023SJohn Marino || rfmt == &ieee_extended_intel_96_round_53_format)))
153*e4b17023SJohn Marino return true;
154*e4b17023SJohn Marino
155*e4b17023SJohn Marino return false;
156*e4b17023SJohn Marino }
157*e4b17023SJohn Marino
158*e4b17023SJohn Marino
159*e4b17023SJohn Marino /* A helper function to help select calls to pow that are suitable for
160*e4b17023SJohn Marino conditional DCE transformation. It looks for pow calls that can be
161*e4b17023SJohn Marino guided with simple conditions. Such calls either have constant base
162*e4b17023SJohn Marino values or base values converted from integers. Returns true if
163*e4b17023SJohn Marino the pow call POW_CALL is a candidate. */
164*e4b17023SJohn Marino
165*e4b17023SJohn Marino /* The maximum integer bit size for base argument of a pow call
166*e4b17023SJohn Marino that is suitable for shrink-wrapping transformation. */
167*e4b17023SJohn Marino #define MAX_BASE_INT_BIT_SIZE 32
168*e4b17023SJohn Marino
169*e4b17023SJohn Marino static bool
check_pow(gimple pow_call)170*e4b17023SJohn Marino check_pow (gimple pow_call)
171*e4b17023SJohn Marino {
172*e4b17023SJohn Marino tree base, expn;
173*e4b17023SJohn Marino enum tree_code bc, ec;
174*e4b17023SJohn Marino
175*e4b17023SJohn Marino if (gimple_call_num_args (pow_call) != 2)
176*e4b17023SJohn Marino return false;
177*e4b17023SJohn Marino
178*e4b17023SJohn Marino base = gimple_call_arg (pow_call, 0);
179*e4b17023SJohn Marino expn = gimple_call_arg (pow_call, 1);
180*e4b17023SJohn Marino
181*e4b17023SJohn Marino if (!check_target_format (expn))
182*e4b17023SJohn Marino return false;
183*e4b17023SJohn Marino
184*e4b17023SJohn Marino bc = TREE_CODE (base);
185*e4b17023SJohn Marino ec = TREE_CODE (expn);
186*e4b17023SJohn Marino
187*e4b17023SJohn Marino /* Folding candidates are not interesting.
188*e4b17023SJohn Marino Can actually assert that it is already folded. */
189*e4b17023SJohn Marino if (ec == REAL_CST && bc == REAL_CST)
190*e4b17023SJohn Marino return false;
191*e4b17023SJohn Marino
192*e4b17023SJohn Marino if (bc == REAL_CST)
193*e4b17023SJohn Marino {
194*e4b17023SJohn Marino /* Only handle a fixed range of constant. */
195*e4b17023SJohn Marino REAL_VALUE_TYPE mv;
196*e4b17023SJohn Marino REAL_VALUE_TYPE bcv = TREE_REAL_CST (base);
197*e4b17023SJohn Marino if (REAL_VALUES_EQUAL (bcv, dconst1))
198*e4b17023SJohn Marino return false;
199*e4b17023SJohn Marino if (REAL_VALUES_LESS (bcv, dconst1))
200*e4b17023SJohn Marino return false;
201*e4b17023SJohn Marino real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), 256, 0, 1);
202*e4b17023SJohn Marino if (REAL_VALUES_LESS (mv, bcv))
203*e4b17023SJohn Marino return false;
204*e4b17023SJohn Marino return true;
205*e4b17023SJohn Marino }
206*e4b17023SJohn Marino else if (bc == SSA_NAME)
207*e4b17023SJohn Marino {
208*e4b17023SJohn Marino tree base_val0, base_var, type;
209*e4b17023SJohn Marino gimple base_def;
210*e4b17023SJohn Marino int bit_sz;
211*e4b17023SJohn Marino
212*e4b17023SJohn Marino /* Only handles cases where base value is converted
213*e4b17023SJohn Marino from integer values. */
214*e4b17023SJohn Marino base_def = SSA_NAME_DEF_STMT (base);
215*e4b17023SJohn Marino if (gimple_code (base_def) != GIMPLE_ASSIGN)
216*e4b17023SJohn Marino return false;
217*e4b17023SJohn Marino
218*e4b17023SJohn Marino if (gimple_assign_rhs_code (base_def) != FLOAT_EXPR)
219*e4b17023SJohn Marino return false;
220*e4b17023SJohn Marino base_val0 = gimple_assign_rhs1 (base_def);
221*e4b17023SJohn Marino
222*e4b17023SJohn Marino base_var = SSA_NAME_VAR (base_val0);
223*e4b17023SJohn Marino if (!DECL_P (base_var))
224*e4b17023SJohn Marino return false;
225*e4b17023SJohn Marino
226*e4b17023SJohn Marino type = TREE_TYPE (base_var);
227*e4b17023SJohn Marino if (TREE_CODE (type) != INTEGER_TYPE)
228*e4b17023SJohn Marino return false;
229*e4b17023SJohn Marino bit_sz = TYPE_PRECISION (type);
230*e4b17023SJohn Marino /* If the type of the base is too wide,
231*e4b17023SJohn Marino the resulting shrink wrapping condition
232*e4b17023SJohn Marino will be too conservative. */
233*e4b17023SJohn Marino if (bit_sz > MAX_BASE_INT_BIT_SIZE)
234*e4b17023SJohn Marino return false;
235*e4b17023SJohn Marino
236*e4b17023SJohn Marino return true;
237*e4b17023SJohn Marino }
238*e4b17023SJohn Marino else
239*e4b17023SJohn Marino return false;
240*e4b17023SJohn Marino }
241*e4b17023SJohn Marino
242*e4b17023SJohn Marino /* A helper function to help select candidate function calls that are
243*e4b17023SJohn Marino suitable for conditional DCE. Candidate functions must have single
244*e4b17023SJohn Marino valid input domain in this implementation except for pow (see check_pow).
245*e4b17023SJohn Marino Returns true if the function call is a candidate. */
246*e4b17023SJohn Marino
247*e4b17023SJohn Marino static bool
check_builtin_call(gimple bcall)248*e4b17023SJohn Marino check_builtin_call (gimple bcall)
249*e4b17023SJohn Marino {
250*e4b17023SJohn Marino tree arg;
251*e4b17023SJohn Marino
252*e4b17023SJohn Marino arg = gimple_call_arg (bcall, 0);
253*e4b17023SJohn Marino return check_target_format (arg);
254*e4b17023SJohn Marino }
255*e4b17023SJohn Marino
256*e4b17023SJohn Marino /* A helper function to determine if a builtin function call is a
257*e4b17023SJohn Marino candidate for conditional DCE. Returns true if the builtin call
258*e4b17023SJohn Marino is a candidate. */
259*e4b17023SJohn Marino
260*e4b17023SJohn Marino static bool
is_call_dce_candidate(gimple call)261*e4b17023SJohn Marino is_call_dce_candidate (gimple call)
262*e4b17023SJohn Marino {
263*e4b17023SJohn Marino tree fn;
264*e4b17023SJohn Marino enum built_in_function fnc;
265*e4b17023SJohn Marino
266*e4b17023SJohn Marino /* Only potentially dead calls are considered. */
267*e4b17023SJohn Marino if (gimple_call_lhs (call))
268*e4b17023SJohn Marino return false;
269*e4b17023SJohn Marino
270*e4b17023SJohn Marino fn = gimple_call_fndecl (call);
271*e4b17023SJohn Marino if (!fn
272*e4b17023SJohn Marino || !DECL_BUILT_IN (fn)
273*e4b17023SJohn Marino || (DECL_BUILT_IN_CLASS (fn) != BUILT_IN_NORMAL))
274*e4b17023SJohn Marino return false;
275*e4b17023SJohn Marino
276*e4b17023SJohn Marino fnc = DECL_FUNCTION_CODE (fn);
277*e4b17023SJohn Marino switch (fnc)
278*e4b17023SJohn Marino {
279*e4b17023SJohn Marino /* Trig functions. */
280*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_ACOS):
281*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_ASIN):
282*e4b17023SJohn Marino /* Hyperbolic functions. */
283*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_ACOSH):
284*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_ATANH):
285*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_COSH):
286*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_SINH):
287*e4b17023SJohn Marino /* Log functions. */
288*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_LOG):
289*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_LOG2):
290*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_LOG10):
291*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_LOG1P):
292*e4b17023SJohn Marino /* Exp functions. */
293*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_EXP):
294*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_EXP2):
295*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_EXP10):
296*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_EXPM1):
297*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_POW10):
298*e4b17023SJohn Marino /* Sqrt. */
299*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_SQRT):
300*e4b17023SJohn Marino return check_builtin_call (call);
301*e4b17023SJohn Marino /* Special one: two argument pow. */
302*e4b17023SJohn Marino case BUILT_IN_POW:
303*e4b17023SJohn Marino return check_pow (call);
304*e4b17023SJohn Marino default:
305*e4b17023SJohn Marino break;
306*e4b17023SJohn Marino }
307*e4b17023SJohn Marino
308*e4b17023SJohn Marino return false;
309*e4b17023SJohn Marino }
310*e4b17023SJohn Marino
311*e4b17023SJohn Marino
312*e4b17023SJohn Marino /* A helper function to generate gimple statements for
313*e4b17023SJohn Marino one bound comparison. ARG is the call argument to
314*e4b17023SJohn Marino be compared with the bound, LBUB is the bound value
315*e4b17023SJohn Marino in integer, TCODE is the tree_code of the comparison,
316*e4b17023SJohn Marino TEMP_NAME1/TEMP_NAME2 are names of the temporaries,
317*e4b17023SJohn Marino CONDS is a vector holding the produced GIMPLE statements,
318*e4b17023SJohn Marino and NCONDS points to the variable holding the number
319*e4b17023SJohn Marino of logical comparisons. CONDS is either empty or
320*e4b17023SJohn Marino a list ended with a null tree. */
321*e4b17023SJohn Marino
322*e4b17023SJohn Marino static void
gen_one_condition(tree arg,int lbub,enum tree_code tcode,const char * temp_name1,const char * temp_name2,VEC (gimple,heap)* conds,unsigned * nconds)323*e4b17023SJohn Marino gen_one_condition (tree arg, int lbub,
324*e4b17023SJohn Marino enum tree_code tcode,
325*e4b17023SJohn Marino const char *temp_name1,
326*e4b17023SJohn Marino const char *temp_name2,
327*e4b17023SJohn Marino VEC (gimple, heap) *conds,
328*e4b17023SJohn Marino unsigned *nconds)
329*e4b17023SJohn Marino {
330*e4b17023SJohn Marino tree lbub_real_cst, lbub_cst, float_type;
331*e4b17023SJohn Marino tree temp, tempn, tempc, tempcn;
332*e4b17023SJohn Marino gimple stmt1, stmt2, stmt3;
333*e4b17023SJohn Marino
334*e4b17023SJohn Marino float_type = TREE_TYPE (arg);
335*e4b17023SJohn Marino lbub_cst = build_int_cst (integer_type_node, lbub);
336*e4b17023SJohn Marino lbub_real_cst = build_real_from_int_cst (float_type, lbub_cst);
337*e4b17023SJohn Marino
338*e4b17023SJohn Marino temp = create_tmp_var (float_type, temp_name1);
339*e4b17023SJohn Marino stmt1 = gimple_build_assign (temp, arg);
340*e4b17023SJohn Marino tempn = make_ssa_name (temp, stmt1);
341*e4b17023SJohn Marino gimple_assign_set_lhs (stmt1, tempn);
342*e4b17023SJohn Marino
343*e4b17023SJohn Marino tempc = create_tmp_var (boolean_type_node, temp_name2);
344*e4b17023SJohn Marino stmt2 = gimple_build_assign (tempc,
345*e4b17023SJohn Marino fold_build2 (tcode,
346*e4b17023SJohn Marino boolean_type_node,
347*e4b17023SJohn Marino tempn, lbub_real_cst));
348*e4b17023SJohn Marino tempcn = make_ssa_name (tempc, stmt2);
349*e4b17023SJohn Marino gimple_assign_set_lhs (stmt2, tempcn);
350*e4b17023SJohn Marino
351*e4b17023SJohn Marino stmt3 = gimple_build_cond_from_tree (tempcn, NULL_TREE, NULL_TREE);
352*e4b17023SJohn Marino VEC_quick_push (gimple, conds, stmt1);
353*e4b17023SJohn Marino VEC_quick_push (gimple, conds, stmt2);
354*e4b17023SJohn Marino VEC_quick_push (gimple, conds, stmt3);
355*e4b17023SJohn Marino (*nconds)++;
356*e4b17023SJohn Marino }
357*e4b17023SJohn Marino
358*e4b17023SJohn Marino /* A helper function to generate GIMPLE statements for
359*e4b17023SJohn Marino out of input domain check. ARG is the call argument
360*e4b17023SJohn Marino to be runtime checked, DOMAIN holds the valid domain
361*e4b17023SJohn Marino for the given function, CONDS points to the vector
362*e4b17023SJohn Marino holding the result GIMPLE statements. *NCONDS is
363*e4b17023SJohn Marino the number of logical comparisons. This function
364*e4b17023SJohn Marino produces no more than two logical comparisons, one
365*e4b17023SJohn Marino for lower bound check, one for upper bound check. */
366*e4b17023SJohn Marino
367*e4b17023SJohn Marino static void
gen_conditions_for_domain(tree arg,inp_domain domain,VEC (gimple,heap)* conds,unsigned * nconds)368*e4b17023SJohn Marino gen_conditions_for_domain (tree arg, inp_domain domain,
369*e4b17023SJohn Marino VEC (gimple, heap) *conds,
370*e4b17023SJohn Marino unsigned *nconds)
371*e4b17023SJohn Marino {
372*e4b17023SJohn Marino if (domain.has_lb)
373*e4b17023SJohn Marino gen_one_condition (arg, domain.lb,
374*e4b17023SJohn Marino (domain.is_lb_inclusive
375*e4b17023SJohn Marino ? LT_EXPR : LE_EXPR),
376*e4b17023SJohn Marino "DCE_COND_LB", "DCE_COND_LB_TEST",
377*e4b17023SJohn Marino conds, nconds);
378*e4b17023SJohn Marino
379*e4b17023SJohn Marino if (domain.has_ub)
380*e4b17023SJohn Marino {
381*e4b17023SJohn Marino /* Now push a separator. */
382*e4b17023SJohn Marino if (domain.has_lb)
383*e4b17023SJohn Marino VEC_quick_push (gimple, conds, NULL);
384*e4b17023SJohn Marino
385*e4b17023SJohn Marino gen_one_condition (arg, domain.ub,
386*e4b17023SJohn Marino (domain.is_ub_inclusive
387*e4b17023SJohn Marino ? GT_EXPR : GE_EXPR),
388*e4b17023SJohn Marino "DCE_COND_UB", "DCE_COND_UB_TEST",
389*e4b17023SJohn Marino conds, nconds);
390*e4b17023SJohn Marino }
391*e4b17023SJohn Marino }
392*e4b17023SJohn Marino
393*e4b17023SJohn Marino
394*e4b17023SJohn Marino /* A helper function to generate condition
395*e4b17023SJohn Marino code for the y argument in call pow (some_const, y).
396*e4b17023SJohn Marino See candidate selection in check_pow. Since the
397*e4b17023SJohn Marino candidates' base values have a limited range,
398*e4b17023SJohn Marino the guarded code generated for y are simple:
399*e4b17023SJohn Marino if (y > max_y)
400*e4b17023SJohn Marino pow (const, y);
401*e4b17023SJohn Marino Note max_y can be computed separately for each
402*e4b17023SJohn Marino const base, but in this implementation, we
403*e4b17023SJohn Marino choose to compute it using the max base
404*e4b17023SJohn Marino in the allowed range for the purpose of
405*e4b17023SJohn Marino simplicity. BASE is the constant base value,
406*e4b17023SJohn Marino EXPN is the expression for the exponent argument,
407*e4b17023SJohn Marino *CONDS is the vector to hold resulting statements,
408*e4b17023SJohn Marino and *NCONDS is the number of logical conditions. */
409*e4b17023SJohn Marino
410*e4b17023SJohn Marino static void
gen_conditions_for_pow_cst_base(tree base,tree expn,VEC (gimple,heap)* conds,unsigned * nconds)411*e4b17023SJohn Marino gen_conditions_for_pow_cst_base (tree base, tree expn,
412*e4b17023SJohn Marino VEC (gimple, heap) *conds,
413*e4b17023SJohn Marino unsigned *nconds)
414*e4b17023SJohn Marino {
415*e4b17023SJohn Marino inp_domain exp_domain;
416*e4b17023SJohn Marino /* Validate the range of the base constant to make
417*e4b17023SJohn Marino sure it is consistent with check_pow. */
418*e4b17023SJohn Marino REAL_VALUE_TYPE mv;
419*e4b17023SJohn Marino REAL_VALUE_TYPE bcv = TREE_REAL_CST (base);
420*e4b17023SJohn Marino gcc_assert (!REAL_VALUES_EQUAL (bcv, dconst1)
421*e4b17023SJohn Marino && !REAL_VALUES_LESS (bcv, dconst1));
422*e4b17023SJohn Marino real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), 256, 0, 1);
423*e4b17023SJohn Marino gcc_assert (!REAL_VALUES_LESS (mv, bcv));
424*e4b17023SJohn Marino
425*e4b17023SJohn Marino exp_domain = get_domain (0, false, false,
426*e4b17023SJohn Marino 127, true, false);
427*e4b17023SJohn Marino
428*e4b17023SJohn Marino gen_conditions_for_domain (expn, exp_domain,
429*e4b17023SJohn Marino conds, nconds);
430*e4b17023SJohn Marino }
431*e4b17023SJohn Marino
432*e4b17023SJohn Marino /* Generate error condition code for pow calls with
433*e4b17023SJohn Marino non constant base values. The candidates selected
434*e4b17023SJohn Marino have their base argument value converted from
435*e4b17023SJohn Marino integer (see check_pow) value (1, 2, 4 bytes), and
436*e4b17023SJohn Marino the max exp value is computed based on the size
437*e4b17023SJohn Marino of the integer type (i.e. max possible base value).
438*e4b17023SJohn Marino The resulting input domain for exp argument is thus
439*e4b17023SJohn Marino conservative (smaller than the max value allowed by
440*e4b17023SJohn Marino the runtime value of the base). BASE is the integer
441*e4b17023SJohn Marino base value, EXPN is the expression for the exponent
442*e4b17023SJohn Marino argument, *CONDS is the vector to hold resulting
443*e4b17023SJohn Marino statements, and *NCONDS is the number of logical
444*e4b17023SJohn Marino conditions. */
445*e4b17023SJohn Marino
446*e4b17023SJohn Marino static void
gen_conditions_for_pow_int_base(tree base,tree expn,VEC (gimple,heap)* conds,unsigned * nconds)447*e4b17023SJohn Marino gen_conditions_for_pow_int_base (tree base, tree expn,
448*e4b17023SJohn Marino VEC (gimple, heap) *conds,
449*e4b17023SJohn Marino unsigned *nconds)
450*e4b17023SJohn Marino {
451*e4b17023SJohn Marino gimple base_def;
452*e4b17023SJohn Marino tree base_val0;
453*e4b17023SJohn Marino tree base_var, int_type;
454*e4b17023SJohn Marino tree temp, tempn;
455*e4b17023SJohn Marino tree cst0;
456*e4b17023SJohn Marino gimple stmt1, stmt2;
457*e4b17023SJohn Marino int bit_sz, max_exp;
458*e4b17023SJohn Marino inp_domain exp_domain;
459*e4b17023SJohn Marino
460*e4b17023SJohn Marino base_def = SSA_NAME_DEF_STMT (base);
461*e4b17023SJohn Marino base_val0 = gimple_assign_rhs1 (base_def);
462*e4b17023SJohn Marino base_var = SSA_NAME_VAR (base_val0);
463*e4b17023SJohn Marino int_type = TREE_TYPE (base_var);
464*e4b17023SJohn Marino bit_sz = TYPE_PRECISION (int_type);
465*e4b17023SJohn Marino gcc_assert (bit_sz > 0
466*e4b17023SJohn Marino && bit_sz <= MAX_BASE_INT_BIT_SIZE);
467*e4b17023SJohn Marino
468*e4b17023SJohn Marino /* Determine the max exp argument value according to
469*e4b17023SJohn Marino the size of the base integer. The max exp value
470*e4b17023SJohn Marino is conservatively estimated assuming IEEE754 double
471*e4b17023SJohn Marino precision format. */
472*e4b17023SJohn Marino if (bit_sz == 8)
473*e4b17023SJohn Marino max_exp = 128;
474*e4b17023SJohn Marino else if (bit_sz == 16)
475*e4b17023SJohn Marino max_exp = 64;
476*e4b17023SJohn Marino else
477*e4b17023SJohn Marino {
478*e4b17023SJohn Marino gcc_assert (bit_sz == MAX_BASE_INT_BIT_SIZE);
479*e4b17023SJohn Marino max_exp = 32;
480*e4b17023SJohn Marino }
481*e4b17023SJohn Marino
482*e4b17023SJohn Marino /* For pow ((double)x, y), generate the following conditions:
483*e4b17023SJohn Marino cond 1:
484*e4b17023SJohn Marino temp1 = x;
485*e4b17023SJohn Marino if (temp1 <= 0)
486*e4b17023SJohn Marino
487*e4b17023SJohn Marino cond 2:
488*e4b17023SJohn Marino temp2 = y;
489*e4b17023SJohn Marino if (temp2 > max_exp_real_cst) */
490*e4b17023SJohn Marino
491*e4b17023SJohn Marino /* Generate condition in reverse order -- first
492*e4b17023SJohn Marino the condition for the exp argument. */
493*e4b17023SJohn Marino
494*e4b17023SJohn Marino exp_domain = get_domain (0, false, false,
495*e4b17023SJohn Marino max_exp, true, true);
496*e4b17023SJohn Marino
497*e4b17023SJohn Marino gen_conditions_for_domain (expn, exp_domain,
498*e4b17023SJohn Marino conds, nconds);
499*e4b17023SJohn Marino
500*e4b17023SJohn Marino /* Now generate condition for the base argument.
501*e4b17023SJohn Marino Note it does not use the helper function
502*e4b17023SJohn Marino gen_conditions_for_domain because the base
503*e4b17023SJohn Marino type is integer. */
504*e4b17023SJohn Marino
505*e4b17023SJohn Marino /* Push a separator. */
506*e4b17023SJohn Marino VEC_quick_push (gimple, conds, NULL);
507*e4b17023SJohn Marino
508*e4b17023SJohn Marino temp = create_tmp_var (int_type, "DCE_COND1");
509*e4b17023SJohn Marino cst0 = build_int_cst (int_type, 0);
510*e4b17023SJohn Marino stmt1 = gimple_build_assign (temp, base_val0);
511*e4b17023SJohn Marino tempn = make_ssa_name (temp, stmt1);
512*e4b17023SJohn Marino gimple_assign_set_lhs (stmt1, tempn);
513*e4b17023SJohn Marino stmt2 = gimple_build_cond (LE_EXPR, tempn, cst0, NULL_TREE, NULL_TREE);
514*e4b17023SJohn Marino
515*e4b17023SJohn Marino VEC_quick_push (gimple, conds, stmt1);
516*e4b17023SJohn Marino VEC_quick_push (gimple, conds, stmt2);
517*e4b17023SJohn Marino (*nconds)++;
518*e4b17023SJohn Marino }
519*e4b17023SJohn Marino
520*e4b17023SJohn Marino /* Method to generate conditional statements for guarding conditionally
521*e4b17023SJohn Marino dead calls to pow. One or more statements can be generated for
522*e4b17023SJohn Marino each logical condition. Statement groups of different conditions
523*e4b17023SJohn Marino are separated by a NULL tree and they are stored in the VEC
524*e4b17023SJohn Marino conds. The number of logical conditions are stored in *nconds.
525*e4b17023SJohn Marino
526*e4b17023SJohn Marino See C99 standard, 7.12.7.4:2, for description of pow (x, y).
527*e4b17023SJohn Marino The precise condition for domain errors are complex. In this
528*e4b17023SJohn Marino implementation, a simplified (but conservative) valid domain
529*e4b17023SJohn Marino for x and y are used: x is positive to avoid dom errors, while
530*e4b17023SJohn Marino y is smaller than a upper bound (depending on x) to avoid range
531*e4b17023SJohn Marino errors. Runtime code is generated to check x (if not constant)
532*e4b17023SJohn Marino and y against the valid domain. If it is out, jump to the call,
533*e4b17023SJohn Marino otherwise the call is bypassed. POW_CALL is the call statement,
534*e4b17023SJohn Marino *CONDS is a vector holding the resulting condition statements,
535*e4b17023SJohn Marino and *NCONDS is the number of logical conditions. */
536*e4b17023SJohn Marino
537*e4b17023SJohn Marino static void
gen_conditions_for_pow(gimple pow_call,VEC (gimple,heap)* conds,unsigned * nconds)538*e4b17023SJohn Marino gen_conditions_for_pow (gimple pow_call, VEC (gimple, heap) *conds,
539*e4b17023SJohn Marino unsigned *nconds)
540*e4b17023SJohn Marino {
541*e4b17023SJohn Marino tree base, expn;
542*e4b17023SJohn Marino enum tree_code bc;
543*e4b17023SJohn Marino
544*e4b17023SJohn Marino gcc_checking_assert (check_pow (pow_call));
545*e4b17023SJohn Marino
546*e4b17023SJohn Marino *nconds = 0;
547*e4b17023SJohn Marino
548*e4b17023SJohn Marino base = gimple_call_arg (pow_call, 0);
549*e4b17023SJohn Marino expn = gimple_call_arg (pow_call, 1);
550*e4b17023SJohn Marino
551*e4b17023SJohn Marino bc = TREE_CODE (base);
552*e4b17023SJohn Marino
553*e4b17023SJohn Marino if (bc == REAL_CST)
554*e4b17023SJohn Marino gen_conditions_for_pow_cst_base (base, expn, conds, nconds);
555*e4b17023SJohn Marino else if (bc == SSA_NAME)
556*e4b17023SJohn Marino gen_conditions_for_pow_int_base (base, expn, conds, nconds);
557*e4b17023SJohn Marino else
558*e4b17023SJohn Marino gcc_unreachable ();
559*e4b17023SJohn Marino }
560*e4b17023SJohn Marino
561*e4b17023SJohn Marino /* A helper routine to help computing the valid input domain
562*e4b17023SJohn Marino for a builtin function. See C99 7.12.7 for details. In this
563*e4b17023SJohn Marino implementation, we only handle single region domain. The
564*e4b17023SJohn Marino resulting region can be conservative (smaller) than the actual
565*e4b17023SJohn Marino one and rounded to integers. Some of the bounds are documented
566*e4b17023SJohn Marino in the standard, while other limit constants are computed
567*e4b17023SJohn Marino assuming IEEE floating point format (for SF and DF modes).
568*e4b17023SJohn Marino Since IEEE only sets minimum requirements for long double format,
569*e4b17023SJohn Marino different long double formats exist under different implementations
570*e4b17023SJohn Marino (e.g, 64 bit double precision (DF), 80 bit double-extended
571*e4b17023SJohn Marino precision (XF), and 128 bit quad precision (QF) ). For simplicity,
572*e4b17023SJohn Marino in this implementation, the computed bounds for long double assume
573*e4b17023SJohn Marino 64 bit format (DF), and are therefore conservative. Another
574*e4b17023SJohn Marino assumption is that single precision float type is always SF mode,
575*e4b17023SJohn Marino and double type is DF mode. This function is quite
576*e4b17023SJohn Marino implementation specific, so it may not be suitable to be part of
577*e4b17023SJohn Marino builtins.c. This needs to be revisited later to see if it can
578*e4b17023SJohn Marino be leveraged in x87 assembly expansion. */
579*e4b17023SJohn Marino
580*e4b17023SJohn Marino static inp_domain
get_no_error_domain(enum built_in_function fnc)581*e4b17023SJohn Marino get_no_error_domain (enum built_in_function fnc)
582*e4b17023SJohn Marino {
583*e4b17023SJohn Marino switch (fnc)
584*e4b17023SJohn Marino {
585*e4b17023SJohn Marino /* Trig functions: return [-1, +1] */
586*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_ACOS):
587*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_ASIN):
588*e4b17023SJohn Marino return get_domain (-1, true, true,
589*e4b17023SJohn Marino 1, true, true);
590*e4b17023SJohn Marino /* Hyperbolic functions. */
591*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_ACOSH):
592*e4b17023SJohn Marino /* acosh: [1, +inf) */
593*e4b17023SJohn Marino return get_domain (1, true, true,
594*e4b17023SJohn Marino 1, false, false);
595*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_ATANH):
596*e4b17023SJohn Marino /* atanh: (-1, +1) */
597*e4b17023SJohn Marino return get_domain (-1, true, false,
598*e4b17023SJohn Marino 1, true, false);
599*e4b17023SJohn Marino case BUILT_IN_COSHF:
600*e4b17023SJohn Marino case BUILT_IN_SINHF:
601*e4b17023SJohn Marino /* coshf: (-89, +89) */
602*e4b17023SJohn Marino return get_domain (-89, true, false,
603*e4b17023SJohn Marino 89, true, false);
604*e4b17023SJohn Marino case BUILT_IN_COSH:
605*e4b17023SJohn Marino case BUILT_IN_SINH:
606*e4b17023SJohn Marino case BUILT_IN_COSHL:
607*e4b17023SJohn Marino case BUILT_IN_SINHL:
608*e4b17023SJohn Marino /* cosh: (-710, +710) */
609*e4b17023SJohn Marino return get_domain (-710, true, false,
610*e4b17023SJohn Marino 710, true, false);
611*e4b17023SJohn Marino /* Log functions: (0, +inf) */
612*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_LOG):
613*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_LOG2):
614*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_LOG10):
615*e4b17023SJohn Marino return get_domain (0, true, false,
616*e4b17023SJohn Marino 0, false, false);
617*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_LOG1P):
618*e4b17023SJohn Marino return get_domain (-1, true, false,
619*e4b17023SJohn Marino 0, false, false);
620*e4b17023SJohn Marino /* Exp functions. */
621*e4b17023SJohn Marino case BUILT_IN_EXPF:
622*e4b17023SJohn Marino case BUILT_IN_EXPM1F:
623*e4b17023SJohn Marino /* expf: (-inf, 88) */
624*e4b17023SJohn Marino return get_domain (-1, false, false,
625*e4b17023SJohn Marino 88, true, false);
626*e4b17023SJohn Marino case BUILT_IN_EXP:
627*e4b17023SJohn Marino case BUILT_IN_EXPM1:
628*e4b17023SJohn Marino case BUILT_IN_EXPL:
629*e4b17023SJohn Marino case BUILT_IN_EXPM1L:
630*e4b17023SJohn Marino /* exp: (-inf, 709) */
631*e4b17023SJohn Marino return get_domain (-1, false, false,
632*e4b17023SJohn Marino 709, true, false);
633*e4b17023SJohn Marino case BUILT_IN_EXP2F:
634*e4b17023SJohn Marino /* exp2f: (-inf, 128) */
635*e4b17023SJohn Marino return get_domain (-1, false, false,
636*e4b17023SJohn Marino 128, true, false);
637*e4b17023SJohn Marino case BUILT_IN_EXP2:
638*e4b17023SJohn Marino case BUILT_IN_EXP2L:
639*e4b17023SJohn Marino /* exp2: (-inf, 1024) */
640*e4b17023SJohn Marino return get_domain (-1, false, false,
641*e4b17023SJohn Marino 1024, true, false);
642*e4b17023SJohn Marino case BUILT_IN_EXP10F:
643*e4b17023SJohn Marino case BUILT_IN_POW10F:
644*e4b17023SJohn Marino /* exp10f: (-inf, 38) */
645*e4b17023SJohn Marino return get_domain (-1, false, false,
646*e4b17023SJohn Marino 38, true, false);
647*e4b17023SJohn Marino case BUILT_IN_EXP10:
648*e4b17023SJohn Marino case BUILT_IN_POW10:
649*e4b17023SJohn Marino case BUILT_IN_EXP10L:
650*e4b17023SJohn Marino case BUILT_IN_POW10L:
651*e4b17023SJohn Marino /* exp10: (-inf, 308) */
652*e4b17023SJohn Marino return get_domain (-1, false, false,
653*e4b17023SJohn Marino 308, true, false);
654*e4b17023SJohn Marino /* sqrt: [0, +inf) */
655*e4b17023SJohn Marino CASE_FLT_FN (BUILT_IN_SQRT):
656*e4b17023SJohn Marino return get_domain (0, true, true,
657*e4b17023SJohn Marino 0, false, false);
658*e4b17023SJohn Marino default:
659*e4b17023SJohn Marino gcc_unreachable ();
660*e4b17023SJohn Marino }
661*e4b17023SJohn Marino
662*e4b17023SJohn Marino gcc_unreachable ();
663*e4b17023SJohn Marino }
664*e4b17023SJohn Marino
665*e4b17023SJohn Marino /* The function to generate shrink wrap conditions for a partially
666*e4b17023SJohn Marino dead builtin call whose return value is not used anywhere,
667*e4b17023SJohn Marino but has to be kept live due to potential error condition.
668*e4b17023SJohn Marino BI_CALL is the builtin call, CONDS is the vector of statements
669*e4b17023SJohn Marino for condition code, NCODES is the pointer to the number of
670*e4b17023SJohn Marino logical conditions. Statements belonging to different logical
671*e4b17023SJohn Marino condition are separated by NULL tree in the vector. */
672*e4b17023SJohn Marino
673*e4b17023SJohn Marino static void
gen_shrink_wrap_conditions(gimple bi_call,VEC (gimple,heap)* conds,unsigned int * nconds)674*e4b17023SJohn Marino gen_shrink_wrap_conditions (gimple bi_call, VEC (gimple, heap) *conds,
675*e4b17023SJohn Marino unsigned int *nconds)
676*e4b17023SJohn Marino {
677*e4b17023SJohn Marino gimple call;
678*e4b17023SJohn Marino tree fn;
679*e4b17023SJohn Marino enum built_in_function fnc;
680*e4b17023SJohn Marino
681*e4b17023SJohn Marino gcc_assert (nconds && conds);
682*e4b17023SJohn Marino gcc_assert (VEC_length (gimple, conds) == 0);
683*e4b17023SJohn Marino gcc_assert (is_gimple_call (bi_call));
684*e4b17023SJohn Marino
685*e4b17023SJohn Marino call = bi_call;
686*e4b17023SJohn Marino fn = gimple_call_fndecl (call);
687*e4b17023SJohn Marino gcc_assert (fn && DECL_BUILT_IN (fn));
688*e4b17023SJohn Marino fnc = DECL_FUNCTION_CODE (fn);
689*e4b17023SJohn Marino *nconds = 0;
690*e4b17023SJohn Marino
691*e4b17023SJohn Marino if (fnc == BUILT_IN_POW)
692*e4b17023SJohn Marino gen_conditions_for_pow (call, conds, nconds);
693*e4b17023SJohn Marino else
694*e4b17023SJohn Marino {
695*e4b17023SJohn Marino tree arg;
696*e4b17023SJohn Marino inp_domain domain = get_no_error_domain (fnc);
697*e4b17023SJohn Marino *nconds = 0;
698*e4b17023SJohn Marino arg = gimple_call_arg (bi_call, 0);
699*e4b17023SJohn Marino gen_conditions_for_domain (arg, domain, conds, nconds);
700*e4b17023SJohn Marino }
701*e4b17023SJohn Marino
702*e4b17023SJohn Marino return;
703*e4b17023SJohn Marino }
704*e4b17023SJohn Marino
705*e4b17023SJohn Marino
706*e4b17023SJohn Marino /* Probability of the branch (to the call) is taken. */
707*e4b17023SJohn Marino #define ERR_PROB 0.01
708*e4b17023SJohn Marino
709*e4b17023SJohn Marino /* The function to shrink wrap a partially dead builtin call
710*e4b17023SJohn Marino whose return value is not used anywhere, but has to be kept
711*e4b17023SJohn Marino live due to potential error condition. Returns true if the
712*e4b17023SJohn Marino transformation actually happens. */
713*e4b17023SJohn Marino
714*e4b17023SJohn Marino static bool
shrink_wrap_one_built_in_call(gimple bi_call)715*e4b17023SJohn Marino shrink_wrap_one_built_in_call (gimple bi_call)
716*e4b17023SJohn Marino {
717*e4b17023SJohn Marino gimple_stmt_iterator bi_call_bsi;
718*e4b17023SJohn Marino basic_block bi_call_bb, join_tgt_bb, guard_bb, guard_bb0;
719*e4b17023SJohn Marino edge join_tgt_in_edge_from_call, join_tgt_in_edge_fall_thru;
720*e4b17023SJohn Marino edge bi_call_in_edge0, guard_bb_in_edge;
721*e4b17023SJohn Marino VEC (gimple, heap) *conds;
722*e4b17023SJohn Marino unsigned tn_cond_stmts, nconds;
723*e4b17023SJohn Marino unsigned ci;
724*e4b17023SJohn Marino gimple cond_expr = NULL;
725*e4b17023SJohn Marino gimple cond_expr_start;
726*e4b17023SJohn Marino tree bi_call_label_decl;
727*e4b17023SJohn Marino gimple bi_call_label;
728*e4b17023SJohn Marino
729*e4b17023SJohn Marino conds = VEC_alloc (gimple, heap, 12);
730*e4b17023SJohn Marino gen_shrink_wrap_conditions (bi_call, conds, &nconds);
731*e4b17023SJohn Marino
732*e4b17023SJohn Marino /* This can happen if the condition generator decides
733*e4b17023SJohn Marino it is not beneficial to do the transformation. Just
734*e4b17023SJohn Marino return false and do not do any transformation for
735*e4b17023SJohn Marino the call. */
736*e4b17023SJohn Marino if (nconds == 0)
737*e4b17023SJohn Marino return false;
738*e4b17023SJohn Marino
739*e4b17023SJohn Marino bi_call_bb = gimple_bb (bi_call);
740*e4b17023SJohn Marino
741*e4b17023SJohn Marino /* Now find the join target bb -- split
742*e4b17023SJohn Marino bi_call_bb if needed. */
743*e4b17023SJohn Marino bi_call_bsi = gsi_for_stmt (bi_call);
744*e4b17023SJohn Marino
745*e4b17023SJohn Marino join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call);
746*e4b17023SJohn Marino bi_call_bsi = gsi_for_stmt (bi_call);
747*e4b17023SJohn Marino
748*e4b17023SJohn Marino join_tgt_bb = join_tgt_in_edge_from_call->dest;
749*e4b17023SJohn Marino
750*e4b17023SJohn Marino /* Now it is time to insert the first conditional expression
751*e4b17023SJohn Marino into bi_call_bb and split this bb so that bi_call is
752*e4b17023SJohn Marino shrink-wrapped. */
753*e4b17023SJohn Marino tn_cond_stmts = VEC_length (gimple, conds);
754*e4b17023SJohn Marino cond_expr = NULL;
755*e4b17023SJohn Marino cond_expr_start = VEC_index (gimple, conds, 0);
756*e4b17023SJohn Marino for (ci = 0; ci < tn_cond_stmts; ci++)
757*e4b17023SJohn Marino {
758*e4b17023SJohn Marino gimple c = VEC_index (gimple, conds, ci);
759*e4b17023SJohn Marino gcc_assert (c || ci != 0);
760*e4b17023SJohn Marino if (!c)
761*e4b17023SJohn Marino break;
762*e4b17023SJohn Marino gsi_insert_before (&bi_call_bsi, c, GSI_SAME_STMT);
763*e4b17023SJohn Marino cond_expr = c;
764*e4b17023SJohn Marino }
765*e4b17023SJohn Marino nconds--;
766*e4b17023SJohn Marino ci++;
767*e4b17023SJohn Marino gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
768*e4b17023SJohn Marino
769*e4b17023SJohn Marino /* Now the label. */
770*e4b17023SJohn Marino bi_call_label_decl = create_artificial_label (gimple_location (bi_call));
771*e4b17023SJohn Marino bi_call_label = gimple_build_label (bi_call_label_decl);
772*e4b17023SJohn Marino gsi_insert_before (&bi_call_bsi, bi_call_label, GSI_SAME_STMT);
773*e4b17023SJohn Marino
774*e4b17023SJohn Marino bi_call_in_edge0 = split_block (bi_call_bb, cond_expr);
775*e4b17023SJohn Marino bi_call_in_edge0->flags &= ~EDGE_FALLTHRU;
776*e4b17023SJohn Marino bi_call_in_edge0->flags |= EDGE_TRUE_VALUE;
777*e4b17023SJohn Marino guard_bb0 = bi_call_bb;
778*e4b17023SJohn Marino bi_call_bb = bi_call_in_edge0->dest;
779*e4b17023SJohn Marino join_tgt_in_edge_fall_thru = make_edge (guard_bb0, join_tgt_bb,
780*e4b17023SJohn Marino EDGE_FALSE_VALUE);
781*e4b17023SJohn Marino
782*e4b17023SJohn Marino bi_call_in_edge0->probability = REG_BR_PROB_BASE * ERR_PROB;
783*e4b17023SJohn Marino join_tgt_in_edge_fall_thru->probability =
784*e4b17023SJohn Marino REG_BR_PROB_BASE - bi_call_in_edge0->probability;
785*e4b17023SJohn Marino
786*e4b17023SJohn Marino /* Code generation for the rest of the conditions */
787*e4b17023SJohn Marino guard_bb = guard_bb0;
788*e4b17023SJohn Marino while (nconds > 0)
789*e4b17023SJohn Marino {
790*e4b17023SJohn Marino unsigned ci0;
791*e4b17023SJohn Marino edge bi_call_in_edge;
792*e4b17023SJohn Marino gimple_stmt_iterator guard_bsi = gsi_for_stmt (cond_expr_start);
793*e4b17023SJohn Marino ci0 = ci;
794*e4b17023SJohn Marino cond_expr_start = VEC_index (gimple, conds, ci0);
795*e4b17023SJohn Marino for (; ci < tn_cond_stmts; ci++)
796*e4b17023SJohn Marino {
797*e4b17023SJohn Marino gimple c = VEC_index (gimple, conds, ci);
798*e4b17023SJohn Marino gcc_assert (c || ci != ci0);
799*e4b17023SJohn Marino if (!c)
800*e4b17023SJohn Marino break;
801*e4b17023SJohn Marino gsi_insert_before (&guard_bsi, c, GSI_SAME_STMT);
802*e4b17023SJohn Marino cond_expr = c;
803*e4b17023SJohn Marino }
804*e4b17023SJohn Marino nconds--;
805*e4b17023SJohn Marino ci++;
806*e4b17023SJohn Marino gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
807*e4b17023SJohn Marino guard_bb_in_edge = split_block (guard_bb, cond_expr);
808*e4b17023SJohn Marino guard_bb_in_edge->flags &= ~EDGE_FALLTHRU;
809*e4b17023SJohn Marino guard_bb_in_edge->flags |= EDGE_FALSE_VALUE;
810*e4b17023SJohn Marino
811*e4b17023SJohn Marino bi_call_in_edge = make_edge (guard_bb, bi_call_bb, EDGE_TRUE_VALUE);
812*e4b17023SJohn Marino
813*e4b17023SJohn Marino bi_call_in_edge->probability = REG_BR_PROB_BASE * ERR_PROB;
814*e4b17023SJohn Marino guard_bb_in_edge->probability =
815*e4b17023SJohn Marino REG_BR_PROB_BASE - bi_call_in_edge->probability;
816*e4b17023SJohn Marino }
817*e4b17023SJohn Marino
818*e4b17023SJohn Marino VEC_free (gimple, heap, conds);
819*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
820*e4b17023SJohn Marino {
821*e4b17023SJohn Marino location_t loc;
822*e4b17023SJohn Marino loc = gimple_location (bi_call);
823*e4b17023SJohn Marino fprintf (dump_file,
824*e4b17023SJohn Marino "%s:%d: note: function call is shrink-wrapped"
825*e4b17023SJohn Marino " into error conditions.\n",
826*e4b17023SJohn Marino LOCATION_FILE (loc), LOCATION_LINE (loc));
827*e4b17023SJohn Marino }
828*e4b17023SJohn Marino
829*e4b17023SJohn Marino return true;
830*e4b17023SJohn Marino }
831*e4b17023SJohn Marino
832*e4b17023SJohn Marino /* The top level function for conditional dead code shrink
833*e4b17023SJohn Marino wrapping transformation. */
834*e4b17023SJohn Marino
835*e4b17023SJohn Marino static bool
shrink_wrap_conditional_dead_built_in_calls(VEC (gimple,heap)* calls)836*e4b17023SJohn Marino shrink_wrap_conditional_dead_built_in_calls (VEC (gimple, heap) *calls)
837*e4b17023SJohn Marino {
838*e4b17023SJohn Marino bool changed = false;
839*e4b17023SJohn Marino unsigned i = 0;
840*e4b17023SJohn Marino
841*e4b17023SJohn Marino unsigned n = VEC_length (gimple, calls);
842*e4b17023SJohn Marino if (n == 0)
843*e4b17023SJohn Marino return false;
844*e4b17023SJohn Marino
845*e4b17023SJohn Marino for (; i < n ; i++)
846*e4b17023SJohn Marino {
847*e4b17023SJohn Marino gimple bi_call = VEC_index (gimple, calls, i);
848*e4b17023SJohn Marino changed |= shrink_wrap_one_built_in_call (bi_call);
849*e4b17023SJohn Marino }
850*e4b17023SJohn Marino
851*e4b17023SJohn Marino return changed;
852*e4b17023SJohn Marino }
853*e4b17023SJohn Marino
854*e4b17023SJohn Marino /* Pass entry points. */
855*e4b17023SJohn Marino
856*e4b17023SJohn Marino static unsigned int
tree_call_cdce(void)857*e4b17023SJohn Marino tree_call_cdce (void)
858*e4b17023SJohn Marino {
859*e4b17023SJohn Marino basic_block bb;
860*e4b17023SJohn Marino gimple_stmt_iterator i;
861*e4b17023SJohn Marino bool something_changed = false;
862*e4b17023SJohn Marino VEC (gimple, heap) *cond_dead_built_in_calls = NULL;
863*e4b17023SJohn Marino FOR_EACH_BB (bb)
864*e4b17023SJohn Marino {
865*e4b17023SJohn Marino /* Collect dead call candidates. */
866*e4b17023SJohn Marino for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
867*e4b17023SJohn Marino {
868*e4b17023SJohn Marino gimple stmt = gsi_stmt (i);
869*e4b17023SJohn Marino if (is_gimple_call (stmt)
870*e4b17023SJohn Marino && is_call_dce_candidate (stmt))
871*e4b17023SJohn Marino {
872*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
873*e4b17023SJohn Marino {
874*e4b17023SJohn Marino fprintf (dump_file, "Found conditional dead call: ");
875*e4b17023SJohn Marino print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
876*e4b17023SJohn Marino fprintf (dump_file, "\n");
877*e4b17023SJohn Marino }
878*e4b17023SJohn Marino if (cond_dead_built_in_calls == NULL)
879*e4b17023SJohn Marino cond_dead_built_in_calls = VEC_alloc (gimple, heap, 64);
880*e4b17023SJohn Marino VEC_safe_push (gimple, heap, cond_dead_built_in_calls, stmt);
881*e4b17023SJohn Marino }
882*e4b17023SJohn Marino }
883*e4b17023SJohn Marino }
884*e4b17023SJohn Marino
885*e4b17023SJohn Marino if (cond_dead_built_in_calls == NULL)
886*e4b17023SJohn Marino return 0;
887*e4b17023SJohn Marino
888*e4b17023SJohn Marino something_changed
889*e4b17023SJohn Marino = shrink_wrap_conditional_dead_built_in_calls (cond_dead_built_in_calls);
890*e4b17023SJohn Marino
891*e4b17023SJohn Marino VEC_free (gimple, heap, cond_dead_built_in_calls);
892*e4b17023SJohn Marino
893*e4b17023SJohn Marino if (something_changed)
894*e4b17023SJohn Marino {
895*e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS);
896*e4b17023SJohn Marino free_dominance_info (CDI_POST_DOMINATORS);
897*e4b17023SJohn Marino /* As we introduced new control-flow we need to insert PHI-nodes
898*e4b17023SJohn Marino for the call-clobbers of the remaining call. */
899*e4b17023SJohn Marino mark_sym_for_renaming (gimple_vop (cfun));
900*e4b17023SJohn Marino return (TODO_update_ssa | TODO_cleanup_cfg | TODO_ggc_collect
901*e4b17023SJohn Marino | TODO_remove_unused_locals);
902*e4b17023SJohn Marino }
903*e4b17023SJohn Marino else
904*e4b17023SJohn Marino return 0;
905*e4b17023SJohn Marino }
906*e4b17023SJohn Marino
907*e4b17023SJohn Marino static bool
gate_call_cdce(void)908*e4b17023SJohn Marino gate_call_cdce (void)
909*e4b17023SJohn Marino {
910*e4b17023SJohn Marino /* The limit constants used in the implementation
911*e4b17023SJohn Marino assume IEEE floating point format. Other formats
912*e4b17023SJohn Marino can be supported in the future if needed. */
913*e4b17023SJohn Marino return flag_tree_builtin_call_dce != 0 && optimize_function_for_speed_p (cfun);
914*e4b17023SJohn Marino }
915*e4b17023SJohn Marino
916*e4b17023SJohn Marino struct gimple_opt_pass pass_call_cdce =
917*e4b17023SJohn Marino {
918*e4b17023SJohn Marino {
919*e4b17023SJohn Marino GIMPLE_PASS,
920*e4b17023SJohn Marino "cdce", /* name */
921*e4b17023SJohn Marino gate_call_cdce, /* gate */
922*e4b17023SJohn Marino tree_call_cdce, /* execute */
923*e4b17023SJohn Marino NULL, /* sub */
924*e4b17023SJohn Marino NULL, /* next */
925*e4b17023SJohn Marino 0, /* static_pass_number */
926*e4b17023SJohn Marino TV_TREE_CALL_CDCE, /* tv_id */
927*e4b17023SJohn Marino PROP_cfg | PROP_ssa, /* properties_required */
928*e4b17023SJohn Marino 0, /* properties_provided */
929*e4b17023SJohn Marino 0, /* properties_destroyed */
930*e4b17023SJohn Marino 0, /* todo_flags_start */
931*e4b17023SJohn Marino TODO_verify_ssa /* todo_flags_finish */
932*e4b17023SJohn Marino }
933*e4b17023SJohn Marino };
934