Mercurial > hg > CbC > CbC_gcc
diff gcc/tree-ssa-ccp.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
line wrap: on
line diff
--- a/gcc/tree-ssa-ccp.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/tree-ssa-ccp.c Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ /* Conditional constant propagation pass for the GNU compiler. - Copyright (C) 2000-2018 Free Software Foundation, Inc. + Copyright (C) 2000-2020 Free Software Foundation, Inc. Adapted from original RTL SSA-CCP by Daniel Berlin <dberlin@dberlin.org> Adapted to GIMPLE trees by Diego Novillo <dnovillo@redhat.com> @@ -136,7 +136,6 @@ #include "tree-cfg.h" #include "tree-ssa-propagate.h" #include "dbgcnt.h" -#include "params.h" #include "builtins.h" #include "cfgloop.h" #include "stor-layout.h" @@ -147,6 +146,11 @@ #include "stringpool.h" #include "attribs.h" #include "tree-vector-builder.h" +#include "cgraph.h" +#include "alloc-pool.h" +#include "symbol-summary.h" +#include "ipa-utils.h" +#include "ipa-prop.h" /* Possible lattice values. */ typedef enum @@ -157,7 +161,8 @@ VARYING } ccp_lattice_t; -struct ccp_prop_value_t { +class ccp_prop_value_t { +public: /* Lattice value. */ ccp_lattice_t lattice_val; @@ -292,11 +297,26 @@ if (flag_tree_bit_ccp) { wide_int nonzero_bits = get_nonzero_bits (var); - if (nonzero_bits != -1) + tree value; + widest_int mask; + + if (SSA_NAME_VAR (var) + && TREE_CODE (SSA_NAME_VAR (var)) == PARM_DECL + && ipcp_get_parm_bits (SSA_NAME_VAR (var), &value, &mask)) + { + val.lattice_val = CONSTANT; + val.value = value; + val.mask = mask; + if (nonzero_bits != -1) + val.mask &= extend_mask (nonzero_bits, + TYPE_SIGN (TREE_TYPE (var))); + } + else if (nonzero_bits != -1) { val.lattice_val = CONSTANT; val.value = build_zero_cst (TREE_TYPE (var)); - val.mask = extend_mask (nonzero_bits, TYPE_SIGN (TREE_TYPE (var))); + val.mask = extend_mask (nonzero_bits, + TYPE_SIGN (TREE_TYPE (var))); } } } @@ -614,9 +634,17 @@ val.mask = -1; } if (for_bits_p - && val.lattice_val == CONSTANT - && TREE_CODE (val.value) == ADDR_EXPR) - val = get_value_from_alignment (val.value); + && val.lattice_val == CONSTANT) + { + if (TREE_CODE (val.value) == ADDR_EXPR) + val = get_value_from_alignment (val.value); + else if (TREE_CODE (val.value) != INTEGER_CST) + { + val.lattice_val = VARYING; + val.value = NULL_TREE; + val.mask = -1; + } + } /* Fall back to a copy value. */ if (!for_bits_p && val.lattice_val == VARYING @@ -1622,6 +1650,17 @@ TYPE_SIGN (TREE_TYPE (rhs2)), TYPE_PRECISION (TREE_TYPE (rhs2)), value_to_wide_int (r2val), r2val.mask); + /* (x * x) & 2 == 0. */ + if (code == MULT_EXPR && rhs1 == rhs2 && TYPE_PRECISION (type) > 1) + { + widest_int m = 2; + if (wi::sext (mask, TYPE_PRECISION (type)) != -1) + value = wi::bit_and_not (value, m); + else + value = 0; + mask = wi::bit_and_not (mask, m); + } + if (wi::sext (mask, TYPE_PRECISION (type)) != -1) { val.lattice_val = CONSTANT; @@ -1960,6 +1999,35 @@ break; } + case BUILT_IN_BSWAP16: + case BUILT_IN_BSWAP32: + case BUILT_IN_BSWAP64: + val = get_value_for_expr (gimple_call_arg (stmt, 0), true); + if (val.lattice_val == UNDEFINED) + break; + else if (val.lattice_val == CONSTANT + && val.value + && TREE_CODE (val.value) == INTEGER_CST) + { + tree type = TREE_TYPE (gimple_call_lhs (stmt)); + int prec = TYPE_PRECISION (type); + wide_int wval = wi::to_wide (val.value); + val.value + = wide_int_to_tree (type, + wide_int::from (wval, prec, + UNSIGNED).bswap ()); + val.mask + = widest_int::from (wide_int::from (val.mask, prec, + UNSIGNED).bswap (), + UNSIGNED); + if (wi::sext (val.mask, prec) != -1) + break; + } + val.lattice_val = VARYING; + val.value = NULL_TREE; + val.mask = -1; + break; + default:; } } @@ -2055,9 +2123,7 @@ FOR_EACH_IMM_USE_STMT (stmt, iter, saved_val) if (gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE)) { - clobber = build_constructor (TREE_TYPE (var), - NULL); - TREE_THIS_VOLATILE (clobber) = 1; + clobber = build_clobber (TREE_TYPE (var)); clobber_stmt = gimple_build_assign (var, clobber); i = gsi_for_stmt (stmt); @@ -2079,8 +2145,6 @@ else if (gimple_assign_ssa_name_copy_p (stmt)) insert_clobber_before_stack_restore (gimple_assign_lhs (stmt), var, visited); - else - gcc_assert (is_gimple_debug (stmt)); } /* Advance the iterator to the previous non-debug gimple statement in the same @@ -2105,9 +2169,9 @@ /* Find a BUILT_IN_STACK_SAVE dominating gsi_stmt (I), and insert a clobber of VAR before each matching BUILT_IN_STACK_RESTORE. - It is possible that BUILT_IN_STACK_SAVE cannot be find in a dominator when a - previous pass (such as DOM) duplicated it along multiple paths to a BB. In - that case the function gives up without inserting the clobbers. */ + It is possible that BUILT_IN_STACK_SAVE cannot be found in a dominator when + a previous pass (such as DOM) duplicated it along multiple paths to a BB. + In that case the function gives up without inserting the clobbers. */ static void insert_clobbers_for_var (gimple_stmt_iterator i, tree var) @@ -2159,7 +2223,7 @@ size = tree_to_uhwi (arg); /* Heuristic: don't fold large allocas. */ - threshold = (unsigned HOST_WIDE_INT)PARAM_VALUE (PARAM_LARGE_STACK_FRAME); + threshold = (unsigned HOST_WIDE_INT)param_large_stack_frame; /* In case the alloca is located at function entry, it has the same lifetime as a declared array, so we allow a larger size. */ block = gimple_block (stmt); @@ -2170,23 +2234,44 @@ if (size > threshold) return NULL_TREE; + /* We have to be able to move points-to info. We used to assert + that we can but IPA PTA might end up with two UIDs here + as it might need to handle more than one instance being + live at the same time. Instead of trying to detect this case + (using the first UID would be OK) just give up for now. */ + struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs); + unsigned uid = 0; + if (pi != NULL + && !pi->pt.anything + && !pt_solution_singleton_or_null_p (&pi->pt, &uid)) + return NULL_TREE; + /* Declare array. */ elem_type = build_nonstandard_integer_type (BITS_PER_UNIT, 1); n_elem = size * 8 / BITS_PER_UNIT; array_type = build_array_type_nelts (elem_type, n_elem); - var = create_tmp_var (array_type); + + if (tree ssa_name = SSA_NAME_IDENTIFIER (lhs)) + { + /* Give the temporary a name derived from the name of the VLA + declaration so it can be referenced in diagnostics. */ + const char *name = IDENTIFIER_POINTER (ssa_name); + var = create_tmp_var (array_type, name); + } + else + var = create_tmp_var (array_type); + + if (gimple *lhsdef = SSA_NAME_DEF_STMT (lhs)) + { + /* Set the temporary's location to that of the VLA declaration + so it can be pointed to in diagnostics. */ + location_t loc = gimple_location (lhsdef); + DECL_SOURCE_LOCATION (var) = loc; + } + SET_DECL_ALIGN (var, TREE_INT_CST_LOW (gimple_call_arg (stmt, 1))); - { - struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs); - if (pi != NULL && !pi->pt.anything) - { - bool singleton_p; - unsigned uid; - singleton_p = pt_solution_singleton_or_null_p (&pi->pt, &uid); - gcc_assert (singleton_p); - SET_DECL_PT_UID (var, uid); - } - } + if (uid != 0) + SET_DECL_PT_UID (var, uid); /* Fold alloca to the address of the array. */ return fold_convert (TREE_TYPE (lhs), build_fold_addr_expr (var)); @@ -2282,6 +2367,32 @@ } } + /* If there's no extra info from an assume_aligned call, + drop it so it doesn't act as otherwise useless dataflow + barrier. */ + if (gimple_call_builtin_p (stmt, BUILT_IN_ASSUME_ALIGNED)) + { + tree ptr = gimple_call_arg (stmt, 0); + ccp_prop_value_t ptrval = get_value_for_expr (ptr, true); + if (ptrval.lattice_val == CONSTANT + && TREE_CODE (ptrval.value) == INTEGER_CST + && ptrval.mask != 0) + { + ccp_prop_value_t val + = bit_value_assume_aligned (stmt, NULL_TREE, ptrval, false); + unsigned int ptralign = least_bit_hwi (ptrval.mask.to_uhwi ()); + unsigned int align = least_bit_hwi (val.mask.to_uhwi ()); + if (ptralign == align + && ((TREE_INT_CST_LOW (ptrval.value) & (align - 1)) + == (TREE_INT_CST_LOW (val.value) & (align - 1)))) + { + bool res = update_call_from_tree (gsi, ptr); + gcc_assert (res); + return true; + } + } + } + /* Propagate into the call arguments. Compared to replace_uses_in this can use the argument slot types for type verification instead of the current argument type. We also can safely @@ -2565,7 +2676,7 @@ || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee))) return NULL_TREE; - if (DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE) + if (fndecl_built_in_p (callee, BUILT_IN_STACK_RESTORE)) goto second_stack_restore; } @@ -2624,9 +2735,6 @@ bool va_list_simple_ptr; location_t loc = gimple_location (call); - if (gimple_code (call) != GIMPLE_CALL) - return NULL_TREE; - callee = gimple_call_fndecl (call); cfun_va_list = targetm.fn_abi_va_list (callee); @@ -2929,12 +3037,10 @@ bit, flag); gimple_call_set_lhs (g, new_lhs); gimple_set_location (g, gimple_location (call)); - gimple_set_vuse (g, gimple_vuse (call)); - gimple_set_vdef (g, gimple_vdef (call)); + gimple_move_vops (g, call); bool throws = stmt_can_throw_internal (cfun, call); gimple_call_set_nothrow (as_a <gcall *> (g), gimple_call_nothrow_p (as_a <gcall *> (call))); - SSA_NAME_DEF_STMT (gimple_vdef (call)) = g; gimple_stmt_iterator gsi = *gsip; gsi_insert_after (&gsi, g, GSI_NEW_STMT); edge e = NULL;