| Index: gcc/gcc/tree-call-cdce.c
|
| diff --git a/gcc/gcc/tree-call-cdce.c b/gcc/gcc/tree-call-cdce.c
|
| index 301fe253b9af78707b75d013f345b8299792f7a1..9a27adc94e3a62f11ff5bf3ca5b3a93bb8461551 100644
|
| --- a/gcc/gcc/tree-call-cdce.c
|
| +++ b/gcc/gcc/tree-call-cdce.c
|
| @@ -4,17 +4,17 @@
|
| Contributed by Xinliang David Li <davidxl@google.com>
|
|
|
| This file is part of GCC.
|
| -
|
| +
|
| GCC is free software; you can redistribute it and/or modify it
|
| under the terms of the GNU General Public License as published by the
|
| Free Software Foundation; either version 3, or (at your option) any
|
| later version.
|
| -
|
| +
|
| GCC is distributed in the hope that it will be useful, but WITHOUT
|
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
| for more details.
|
| -
|
| +
|
| You should have received a copy of the GNU General Public License
|
| along with GCC; see the file COPYING3. If not see
|
| <http://www.gnu.org/licenses/>. */
|
| @@ -49,7 +49,7 @@ along with GCC; see the file COPYING3. If not see
|
| not used, the compiler can still not eliminate the call without
|
| powerful interprocedural analysis to prove that the errno is not
|
| checked. However, if the conditions under which the error occurs
|
| - are known, the compiler can conditionally dead code eliminate the
|
| + are known, the compiler can conditionally dead code eliminate the
|
| calls by shrink-wrapping the semi-dead calls into the error condition:
|
|
|
| built_in_call (args)
|
| @@ -65,7 +65,7 @@ along with GCC; see the file COPYING3. If not see
|
| With this change, call to log (x) is effectively eliminated, as
|
| in majority of the cases, log won't be called with x out of
|
| range. The branch is totally predictable, so the branch cost
|
| - is low.
|
| + is low.
|
|
|
| Note that library functions are not supposed to clear errno to zero without
|
| error. See IEEE Std 1003.1, section 2.3 Error Numbers, and section 7.5:3 of
|
| @@ -81,12 +81,12 @@ along with GCC; see the file COPYING3. If not see
|
| inlining). */
|
|
|
|
|
| -/* A structure for representing input domain of
|
| +/* A structure for representing input domain of
|
| a function argument in integer. If the lower
|
| - bound is -inf, has_lb is set to false. If the
|
| - upper bound is +inf, has_ub is false.
|
| - is_lb_inclusive and is_ub_inclusive are flags
|
| - to indicate if lb and ub value are inclusive
|
| + bound is -inf, has_lb is set to false. If the
|
| + upper bound is +inf, has_ub is false.
|
| + is_lb_inclusive and is_ub_inclusive are flags
|
| + to indicate if lb and ub value are inclusive
|
| respectively. */
|
|
|
| typedef struct input_domain
|
| @@ -100,11 +100,11 @@ typedef struct input_domain
|
| } inp_domain;
|
|
|
| /* A helper function to construct and return an input
|
| - domain object. LB is the lower bound, HAS_LB is
|
| + domain object. LB is the lower bound, HAS_LB is
|
| a boolean flag indicating if the lower bound exists,
|
| and LB_INCLUSIVE is a boolean flag indicating if the
|
| lower bound is inclusive or not. UB, HAS_UB, and
|
| - UB_INCLUSIVE have the same meaning, but for upper
|
| + UB_INCLUSIVE have the same meaning, but for upper
|
| bound of the domain. */
|
|
|
| static inp_domain
|
| @@ -121,13 +121,13 @@ get_domain (int lb, bool has_lb, bool lb_inclusive,
|
| return domain;
|
| }
|
|
|
| -/* A helper function to check the target format for the
|
| +/* A helper function to check the target format for the
|
| argument type. In this implementation, only IEEE formats
|
| - are supported. ARG is the call argument to be checked.
|
| + are supported. ARG is the call argument to be checked.
|
| Returns true if the format is supported. To support other
|
| target formats, function get_no_error_domain needs to be
|
| - enhanced to have range bounds properly computed. Since
|
| - the check is cheap (very small number of candidates
|
| + enhanced to have range bounds properly computed. Since
|
| + the check is cheap (very small number of candidates
|
| to be checked), the result is not cached for each float type. */
|
|
|
| static bool
|
| @@ -136,7 +136,7 @@ check_target_format (tree arg)
|
| tree type;
|
| enum machine_mode mode;
|
| const struct real_format *rfmt;
|
| -
|
| +
|
| type = TREE_TYPE (arg);
|
| mode = TYPE_MODE (type);
|
| rfmt = REAL_MODE_FORMAT (mode);
|
| @@ -147,16 +147,16 @@ check_target_format (tree arg)
|
| && (rfmt == &ieee_double_format || rfmt == &mips_double_format
|
| || rfmt == &motorola_double_format))
|
| /* For long double, we can not really check XFmode
|
| - which is only defined on intel platforms.
|
| - Candidate pre-selection using builtin function
|
| - code guarantees that we are checking formats
|
| + which is only defined on intel platforms.
|
| + Candidate pre-selection using builtin function
|
| + code guarantees that we are checking formats
|
| for long double modes: double, quad, and extended. */
|
| - || (mode != SFmode && mode != DFmode
|
| + || (mode != SFmode && mode != DFmode
|
| && (rfmt == &ieee_quad_format
|
| || rfmt == &mips_quad_format
|
| || rfmt == &ieee_extended_motorola_format
|
| - || rfmt == &ieee_extended_intel_96_format
|
| - || rfmt == &ieee_extended_intel_128_format
|
| + || rfmt == &ieee_extended_intel_96_format
|
| + || rfmt == &ieee_extended_intel_128_format
|
| || rfmt == &ieee_extended_intel_96_round_53_format)))
|
| return true;
|
|
|
| @@ -167,7 +167,7 @@ check_target_format (tree arg)
|
| /* A helper function to help select calls to pow that are suitable for
|
| conditional DCE transformation. It looks for pow calls that can be
|
| guided with simple conditions. Such calls either have constant base
|
| - values or base values converted from integers. Returns true if
|
| + values or base values converted from integers. Returns true if
|
| the pow call POW_CALL is a candidate. */
|
|
|
| /* The maximum integer bit size for base argument of a pow call
|
| @@ -218,7 +218,7 @@ check_pow (gimple pow_call)
|
| int bit_sz;
|
|
|
| /* Only handles cases where base value is converted
|
| - from integer values. */
|
| + from integer values. */
|
| base_def = SSA_NAME_DEF_STMT (base);
|
| if (gimple_code (base_def) != GIMPLE_ASSIGN)
|
| return false;
|
| @@ -277,7 +277,7 @@ is_call_dce_candidate (gimple call)
|
|
|
| fn = gimple_call_fndecl (call);
|
| if (!fn
|
| - || !DECL_BUILT_IN (fn)
|
| + || !DECL_BUILT_IN (fn)
|
| || (DECL_BUILT_IN_CLASS (fn) != BUILT_IN_NORMAL))
|
| return false;
|
|
|
| @@ -324,11 +324,11 @@ is_call_dce_candidate (gimple call)
|
| TEMP_NAME1/TEMP_NAME2 are names of the temporaries,
|
| CONDS is a vector holding the produced GIMPLE statements,
|
| and NCONDS points to the variable holding the number
|
| - of logical comparisons. CONDS is either empty or
|
| + of logical comparisons. CONDS is either empty or
|
| a list ended with a null tree. */
|
|
|
| static void
|
| -gen_one_condition (tree arg, int lbub,
|
| +gen_one_condition (tree arg, int lbub,
|
| enum tree_code tcode,
|
| const char *temp_name1,
|
| const char *temp_name2,
|
| @@ -367,14 +367,14 @@ gen_one_condition (tree arg, int lbub,
|
| out of input domain check. ARG is the call argument
|
| to be runtime checked, DOMAIN holds the valid domain
|
| for the given function, CONDS points to the vector
|
| - holding the result GIMPLE statements. *NCONDS is
|
| - the number of logical comparisons. This function
|
| + holding the result GIMPLE statements. *NCONDS is
|
| + the number of logical comparisons. This function
|
| produces no more than two logical comparisons, one
|
| for lower bound check, one for upper bound check. */
|
|
|
| static void
|
| gen_conditions_for_domain (tree arg, inp_domain domain,
|
| - VEC (gimple, heap) *conds,
|
| + VEC (gimple, heap) *conds,
|
| unsigned *nconds)
|
| {
|
| if (domain.has_lb)
|
| @@ -401,7 +401,7 @@ gen_conditions_for_domain (tree arg, inp_domain domain,
|
|
|
| /* A helper function to generate condition
|
| code for the y argument in call pow (some_const, y).
|
| - See candidate selection in check_pow. Since the
|
| + See candidate selection in check_pow. Since the
|
| candidates' base values have a limited range,
|
| the guarded code generated for y are simple:
|
| if (y > max_y)
|
| @@ -420,8 +420,8 @@ gen_conditions_for_pow_cst_base (tree base, tree expn,
|
| VEC (gimple, heap) *conds,
|
| unsigned *nconds)
|
| {
|
| - inp_domain exp_domain;
|
| - /* Validate the range of the base constant to make
|
| + inp_domain exp_domain;
|
| + /* Validate the range of the base constant to make
|
| sure it is consistent with check_pow. */
|
| REAL_VALUE_TYPE mv;
|
| REAL_VALUE_TYPE bcv = TREE_REAL_CST (base);
|
| @@ -444,11 +444,11 @@ gen_conditions_for_pow_cst_base (tree base, tree expn,
|
| the max exp value is computed based on the size
|
| of the integer type (i.e. max possible base value).
|
| The resulting input domain for exp argument is thus
|
| - conservative (smaller than the max value allowed by
|
| - the runtime value of the base). BASE is the integer
|
| - base value, EXPN is the expression for the exponent
|
| - argument, *CONDS is the vector to hold resulting
|
| - statements, and *NCONDS is the number of logical
|
| + conservative (smaller than the max value allowed by
|
| + the runtime value of the base). BASE is the integer
|
| + base value, EXPN is the expression for the exponent
|
| + argument, *CONDS is the vector to hold resulting
|
| + statements, and *NCONDS is the number of logical
|
| conditions. */
|
|
|
| static void
|
| @@ -457,7 +457,7 @@ gen_conditions_for_pow_int_base (tree base, tree expn,
|
| unsigned *nconds)
|
| {
|
| gimple base_def;
|
| - tree base_nm, base_val0;
|
| + tree base_val0;
|
| tree base_var, int_type;
|
| tree temp, tempn;
|
| tree cst0;
|
| @@ -466,12 +466,11 @@ gen_conditions_for_pow_int_base (tree base, tree expn,
|
| inp_domain exp_domain;
|
|
|
| base_def = SSA_NAME_DEF_STMT (base);
|
| - base_nm = gimple_assign_lhs (base_def);
|
| base_val0 = gimple_assign_rhs1 (base_def);
|
| base_var = SSA_NAME_VAR (base_val0);
|
| int_type = TREE_TYPE (base_var);
|
| bit_sz = TYPE_PRECISION (int_type);
|
| - gcc_assert (bit_sz > 0
|
| + gcc_assert (bit_sz > 0
|
| && bit_sz <= MAX_BASE_INT_BIT_SIZE);
|
|
|
| /* Determine the max exp argument value according to
|
| @@ -483,10 +482,10 @@ gen_conditions_for_pow_int_base (tree base, tree expn,
|
| else if (bit_sz == 16)
|
| max_exp = 64;
|
| else
|
| - {
|
| - gcc_assert (bit_sz == MAX_BASE_INT_BIT_SIZE);
|
| - max_exp = 32;
|
| - }
|
| + {
|
| + gcc_assert (bit_sz == MAX_BASE_INT_BIT_SIZE);
|
| + max_exp = 32;
|
| + }
|
|
|
| /* For pow ((double)x, y), generate the following conditions:
|
| cond 1:
|
| @@ -544,11 +543,11 @@ gen_conditions_for_pow_int_base (tree base, tree expn,
|
| and *NCONDS is the number of logical conditions. */
|
|
|
| static void
|
| -gen_conditions_for_pow (gimple pow_call, VEC (gimple, heap) *conds,
|
| +gen_conditions_for_pow (gimple pow_call, VEC (gimple, heap) *conds,
|
| unsigned *nconds)
|
| {
|
| tree base, expn;
|
| - enum tree_code bc, ec;
|
| + enum tree_code bc;
|
|
|
| #ifdef ENABLE_CHECKING
|
| gcc_assert (check_pow (pow_call));
|
| @@ -560,12 +559,11 @@ gen_conditions_for_pow (gimple pow_call, VEC (gimple, heap) *conds,
|
| expn = gimple_call_arg (pow_call, 1);
|
|
|
| bc = TREE_CODE (base);
|
| - ec = TREE_CODE (expn);
|
|
|
| if (bc == REAL_CST)
|
| - gen_conditions_for_pow_cst_base (base, expn, conds, nconds);
|
| + gen_conditions_for_pow_cst_base (base, expn, conds, nconds);
|
| else if (bc == SSA_NAME)
|
| - gen_conditions_for_pow_int_base (base, expn, conds, nconds);
|
| + gen_conditions_for_pow_int_base (base, expn, conds, nconds);
|
| else
|
| gcc_unreachable ();
|
| }
|
| @@ -576,15 +574,15 @@ gen_conditions_for_pow (gimple pow_call, VEC (gimple, heap) *conds,
|
| resulting region can be conservative (smaller) than the actual
|
| one and rounded to integers. Some of the bounds are documented
|
| in the standard, while other limit constants are computed
|
| - assuming IEEE floating point format (for SF and DF modes).
|
| - Since IEEE only sets minimum requirements for long double format,
|
| - different long double formats exist under different implementations
|
| - (e.g, 64 bit double precision (DF), 80 bit double-extended
|
| - precision (XF), and 128 bit quad precision (QF) ). For simplicity,
|
| - in this implementation, the computed bounds for long double assume
|
| - 64 bit format (DF), and are therefore conservative. Another
|
| + assuming IEEE floating point format (for SF and DF modes).
|
| + Since IEEE only sets minimum requirements for long double format,
|
| + different long double formats exist under different implementations
|
| + (e.g, 64 bit double precision (DF), 80 bit double-extended
|
| + precision (XF), and 128 bit quad precision (QF) ). For simplicity,
|
| + in this implementation, the computed bounds for long double assume
|
| + 64 bit format (DF), and are therefore conservative. Another
|
| assumption is that single precision float type is always SF mode,
|
| - and double type is DF mode. This function is quite
|
| + and double type is DF mode. This function is quite
|
| implementation specific, so it may not be suitable to be part of
|
| builtins.c. This needs to be revisited later to see if it can
|
| be leveraged in x87 assembly expansion. */
|
| @@ -668,22 +666,22 @@ get_no_error_domain (enum built_in_function fnc)
|
| return get_domain (0, true, true,
|
| 0, false, false);
|
| default:
|
| - gcc_unreachable ();
|
| + gcc_unreachable ();
|
| }
|
|
|
| - gcc_unreachable ();
|
| + gcc_unreachable ();
|
| }
|
|
|
| /* The function to generate shrink wrap conditions for a partially
|
| dead builtin call whose return value is not used anywhere,
|
| but has to be kept live due to potential error condition.
|
| - BI_CALL is the builtin call, CONDS is the vector of statements
|
| - for condition code, NCODES is the pointer to the number of
|
| + BI_CALL is the builtin call, CONDS is the vector of statements
|
| + for condition code, NCODES is the pointer to the number of
|
| logical conditions. Statements belonging to different logical
|
| condition are separated by NULL tree in the vector. */
|
|
|
| static void
|
| -gen_shrink_wrap_conditions (gimple bi_call, VEC (gimple, heap) *conds,
|
| +gen_shrink_wrap_conditions (gimple bi_call, VEC (gimple, heap) *conds,
|
| unsigned int *nconds)
|
| {
|
| gimple call;
|
| @@ -718,12 +716,12 @@ gen_shrink_wrap_conditions (gimple bi_call, VEC (gimple, heap) *conds,
|
| /* Probability of the branch (to the call) is taken. */
|
| #define ERR_PROB 0.01
|
|
|
| -/* The function to shrink wrap a partially dead builtin call
|
| - whose return value is not used anywhere, but has to be kept
|
| +/* The function to shrink wrap a partially dead builtin call
|
| + whose return value is not used anywhere, but has to be kept
|
| live due to potential error condition. Returns true if the
|
| transformation actually happens. */
|
|
|
| -static bool
|
| +static bool
|
| shrink_wrap_one_built_in_call (gimple bi_call)
|
| {
|
| gimple_stmt_iterator bi_call_bsi;
|
| @@ -743,7 +741,7 @@ shrink_wrap_one_built_in_call (gimple bi_call)
|
|
|
| /* This can happen if the condition generator decides
|
| it is not beneficial to do the transformation. Just
|
| - return false and do not do any transformation for
|
| + return false and do not do any transformation for
|
| the call. */
|
| if (nconds == 0)
|
| return false;
|
| @@ -779,7 +777,7 @@ shrink_wrap_one_built_in_call (gimple bi_call)
|
| gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
|
|
|
| /* Now the label. */
|
| - bi_call_label_decl = create_artificial_label ();
|
| + bi_call_label_decl = create_artificial_label (gimple_location (bi_call));
|
| bi_call_label = gimple_build_label (bi_call_label_decl);
|
| gsi_insert_before (&bi_call_bsi, bi_call_label, GSI_SAME_STMT);
|
|
|
| @@ -788,7 +786,7 @@ shrink_wrap_one_built_in_call (gimple bi_call)
|
| bi_call_in_edge0->flags |= EDGE_TRUE_VALUE;
|
| guard_bb0 = bi_call_bb;
|
| bi_call_bb = bi_call_in_edge0->dest;
|
| - join_tgt_in_edge_fall_thru = make_edge (guard_bb0, join_tgt_bb,
|
| + join_tgt_in_edge_fall_thru = make_edge (guard_bb0, join_tgt_bb,
|
| EDGE_FALSE_VALUE);
|
|
|
| bi_call_in_edge0->probability = REG_BR_PROB_BASE * ERR_PROB;
|
| @@ -851,7 +849,7 @@ shrink_wrap_conditional_dead_built_in_calls (VEC (gimple, heap) *calls)
|
| unsigned i = 0;
|
|
|
| unsigned n = VEC_length (gimple, calls);
|
| - if (n == 0)
|
| + if (n == 0)
|
| return false;
|
|
|
| for (; i < n ; i++)
|
| @@ -906,7 +904,10 @@ tree_call_cdce (void)
|
| {
|
| free_dominance_info (CDI_DOMINATORS);
|
| free_dominance_info (CDI_POST_DOMINATORS);
|
| - return (TODO_update_ssa | TODO_cleanup_cfg | TODO_ggc_collect
|
| + /* As we introduced new control-flow we need to insert PHI-nodes
|
| + for the call-clobbers of the remaining call. */
|
| + mark_sym_for_renaming (gimple_vop (cfun));
|
| + return (TODO_update_ssa | TODO_cleanup_cfg | TODO_ggc_collect
|
| | TODO_remove_unused_locals);
|
| }
|
| else
|
| @@ -919,7 +920,7 @@ gate_call_cdce (void)
|
| /* The limit constants used in the implementation
|
| assume IEEE floating point format. Other formats
|
| can be supported in the future if needed. */
|
| - return flag_tree_builtin_call_dce != 0 && optimize_function_for_speed_p (cfun);
|
| + return flag_tree_builtin_call_dce != 0 && optimize_function_for_speed_p (cfun);
|
| }
|
|
|
| struct gimple_opt_pass pass_call_cdce =
|
|
|