Mercurial > hg > CbC > CbC_gcc
diff gcc/tree-ssa-forwprop.c @ 132:d34655255c78
update gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 10:21:07 +0900 |
parents | 84e7813d76e9 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/tree-ssa-forwprop.c Thu Oct 25 08:08:40 2018 +0900 +++ b/gcc/tree-ssa-forwprop.c Thu Oct 25 10:21:07 2018 +0900 @@ -1,5 +1,5 @@ /* Forward propagation of expressions for single use variables. - Copyright (C) 2004-2017 Free Software Foundation, Inc. + Copyright (C) 2004-2018 Free Software Foundation, Inc. This file is part of GCC. @@ -46,6 +46,8 @@ #include "tree-cfgcleanup.h" #include "cfganal.h" #include "optabs-tree.h" +#include "tree-vector-builder.h" +#include "vec-perm-indices.h" /* This pass propagates the RHS of assignment statements into use sites of the LHS of the assignment. It's basically a specialized @@ -758,12 +760,12 @@ && TREE_OPERAND (lhs, 0) == name) { tree def_rhs_base; - HOST_WIDE_INT def_rhs_offset; + poly_int64 def_rhs_offset; /* If the address is invariant we can always fold it. */ if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0), &def_rhs_offset))) { - offset_int off = mem_ref_offset (lhs); + poly_offset_int off = mem_ref_offset (lhs); tree new_ptr; off += def_rhs_offset; if (TREE_CODE (def_rhs_base) == MEM_REF) @@ -850,11 +852,11 @@ && TREE_OPERAND (rhs, 0) == name) { tree def_rhs_base; - HOST_WIDE_INT def_rhs_offset; + poly_int64 def_rhs_offset; if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0), &def_rhs_offset))) { - offset_int off = mem_ref_offset (rhs); + poly_offset_int off = mem_ref_offset (rhs); tree new_ptr; off += def_rhs_offset; if (TREE_CODE (def_rhs_base) == MEM_REF) @@ -1069,7 +1071,7 @@ for (i = 0; i < gimple_switch_num_labels (stmt); i++) { tree elt = gimple_switch_label (stmt, i); - basic_block target = label_to_block (CASE_LABEL (elt)); + basic_block target = label_to_block (cfun, CASE_LABEL (elt)); bitmap_set_bit (target_blocks, target->index); } for (ei = ei_start (gimple_bb (stmt)->succs); (e = ei_safe_edge (ei)); ) @@ -1169,12 +1171,12 @@ if (TREE_CODE (p) == ADDR_EXPR) { tree q = TREE_OPERAND (p, 0); - HOST_WIDE_INT offset; + poly_int64 offset; tree base = get_addr_base_and_unit_offset (q, &offset); if (base) { q = base; - if (offset) + if (maybe_ne (offset, 0)) off = size_binop (PLUS_EXPR, off, size_int (offset)); } if (TREE_CODE (q) == MEM_REF @@ -1276,7 +1278,7 @@ constant length. */ callee1 = gimple_call_fndecl (stmt1); if (callee1 == NULL_TREE - || DECL_BUILT_IN_CLASS (callee1) != BUILT_IN_NORMAL + || !fndecl_built_in_p (callee1, BUILT_IN_NORMAL) || gimple_call_num_args (stmt1) != 3) break; if (DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMCPY @@ -1288,7 +1290,7 @@ lhs1 = gimple_call_lhs (stmt1); if (!tree_fits_uhwi_p (len1)) break; - str1 = string_constant (src1, &off1); + str1 = string_constant (src1, &off1, NULL, NULL); if (str1 == NULL_TREE) break; if (!tree_fits_uhwi_p (off1) @@ -1780,7 +1782,7 @@ gimple *def_stmt; tree op, op0, op1, op2; tree elem_type; - unsigned idx, n, size; + unsigned idx, size; enum tree_code code; op = gimple_assign_rhs1 (stmt); @@ -1815,19 +1817,18 @@ return false; size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type)); - n = TREE_INT_CST_LOW (op1) / size; - if (n != 1) + if (maybe_ne (bit_field_size (op), size)) return false; - idx = TREE_INT_CST_LOW (op2) / size; - if (code == VEC_PERM_EXPR) + if (code == VEC_PERM_EXPR + && constant_multiple_p (bit_field_offset (op), size, &idx)) { tree p, m, tem; - unsigned nelts; + unsigned HOST_WIDE_INT nelts; m = gimple_assign_rhs3 (def_stmt); - if (TREE_CODE (m) != VECTOR_CST) + if (TREE_CODE (m) != VECTOR_CST + || !VECTOR_CST_NELTS (m).is_constant (&nelts)) return false; - nelts = VECTOR_CST_NELTS (m); idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx)); idx %= 2 * nelts; if (idx < nelts) @@ -1857,16 +1858,18 @@ is_combined_permutation_identity (tree mask1, tree mask2) { tree mask; - unsigned int nelts, i, j; + unsigned HOST_WIDE_INT nelts, i, j; bool maybe_identity1 = true; bool maybe_identity2 = true; gcc_checking_assert (TREE_CODE (mask1) == VECTOR_CST && TREE_CODE (mask2) == VECTOR_CST); mask = fold_ternary (VEC_PERM_EXPR, TREE_TYPE (mask1), mask1, mask1, mask2); - gcc_assert (TREE_CODE (mask) == VECTOR_CST); + if (mask == NULL_TREE || TREE_CODE (mask) != VECTOR_CST) + return 0; - nelts = VECTOR_CST_NELTS (mask); + if (!VECTOR_CST_NELTS (mask).is_constant (&nelts)) + return 0; for (i = 0; i < nelts; i++) { tree val = VECTOR_CST_ELT (mask, i); @@ -2001,8 +2004,9 @@ { gimple *stmt = gsi_stmt (*gsi); gimple *def_stmt; - tree op, op2, orig, type, elem_type; - unsigned elem_size, nelts, i; + tree op, op2, orig[2], type, elem_type; + unsigned elem_size, i; + unsigned HOST_WIDE_INT nelts; enum tree_code code, conv_code; constructor_elt *elt; bool maybe_ident; @@ -2013,12 +2017,14 @@ type = TREE_TYPE (op); gcc_checking_assert (TREE_CODE (type) == VECTOR_TYPE); - nelts = TYPE_VECTOR_SUBPARTS (type); + if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts)) + return false; elem_type = TREE_TYPE (type); elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type)); - auto_vec_perm_indices sel (nelts); - orig = NULL; + vec_perm_builder sel (nelts, nelts, 1); + orig[0] = NULL; + orig[1] = NULL; conv_code = ERROR_MARK; maybe_ident = true; FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt) @@ -2040,8 +2046,8 @@ op1 = gimple_assign_rhs1 (def_stmt); if (conv_code == ERROR_MARK) { - if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (elt->value))) - != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op1)))) + if (maybe_ne (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (elt->value))), + GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op1))))) return false; conv_code = code; } @@ -2058,24 +2064,35 @@ return false; op1 = gimple_assign_rhs1 (def_stmt); ref = TREE_OPERAND (op1, 0); - if (orig) - { - if (ref != orig) - return false; - } - else + unsigned int j; + for (j = 0; j < 2; ++j) { - if (TREE_CODE (ref) != SSA_NAME) - return false; - if (! VECTOR_TYPE_P (TREE_TYPE (ref)) - || ! useless_type_conversion_p (TREE_TYPE (op1), - TREE_TYPE (TREE_TYPE (ref)))) - return false; - orig = ref; + if (!orig[j]) + { + if (TREE_CODE (ref) != SSA_NAME) + return false; + if (! VECTOR_TYPE_P (TREE_TYPE (ref)) + || ! useless_type_conversion_p (TREE_TYPE (op1), + TREE_TYPE (TREE_TYPE (ref)))) + return false; + if (j && !useless_type_conversion_p (TREE_TYPE (orig[0]), + TREE_TYPE (ref))) + return false; + orig[j] = ref; + break; + } + else if (ref == orig[j]) + break; } - if (TREE_INT_CST_LOW (TREE_OPERAND (op1, 1)) != elem_size) + if (j == 2) return false; - unsigned int elt = TREE_INT_CST_LOW (TREE_OPERAND (op1, 2)) / elem_size; + + unsigned int elt; + if (maybe_ne (bit_field_size (op1), elem_size) + || !constant_multiple_p (bit_field_offset (op1), elem_size, &elt)) + return false; + if (j) + elt += nelts; if (elt != i) maybe_ident = false; sel.quick_push (elt); @@ -2083,14 +2100,15 @@ if (i < nelts) return false; - if (! VECTOR_TYPE_P (TREE_TYPE (orig)) - || (TYPE_VECTOR_SUBPARTS (type) - != TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig)))) + if (! VECTOR_TYPE_P (TREE_TYPE (orig[0])) + || maybe_ne (TYPE_VECTOR_SUBPARTS (type), + TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig[0])))) return false; tree tem; if (conv_code != ERROR_MARK - && (! supportable_convert_operation (conv_code, type, TREE_TYPE (orig), + && (! supportable_convert_operation (conv_code, type, + TREE_TYPE (orig[0]), &tem, &conv_code) || conv_code == CALL_EXPR)) return false; @@ -2098,38 +2116,39 @@ if (maybe_ident) { if (conv_code == ERROR_MARK) - gimple_assign_set_rhs_from_tree (gsi, orig); + gimple_assign_set_rhs_from_tree (gsi, orig[0]); else - gimple_assign_set_rhs_with_ops (gsi, conv_code, orig, + gimple_assign_set_rhs_with_ops (gsi, conv_code, orig[0], NULL_TREE, NULL_TREE); } else { tree mask_type; - if (!can_vec_perm_p (TYPE_MODE (type), false, &sel)) + vec_perm_indices indices (sel, orig[1] ? 2 : 1, nelts); + if (!can_vec_perm_const_p (TYPE_MODE (type), indices)) return false; mask_type = build_vector_type (build_nonstandard_integer_type (elem_size, 1), nelts); if (GET_MODE_CLASS (TYPE_MODE (mask_type)) != MODE_VECTOR_INT - || GET_MODE_SIZE (TYPE_MODE (mask_type)) - != GET_MODE_SIZE (TYPE_MODE (type))) + || maybe_ne (GET_MODE_SIZE (TYPE_MODE (mask_type)), + GET_MODE_SIZE (TYPE_MODE (type)))) return false; - auto_vec<tree, 32> mask_elts (nelts); - for (i = 0; i < nelts; i++) - mask_elts.quick_push (build_int_cst (TREE_TYPE (mask_type), sel[i])); - op2 = build_vector (mask_type, mask_elts); + op2 = vec_perm_indices_to_tree (mask_type, indices); + if (!orig[1]) + orig[1] = orig[0]; if (conv_code == ERROR_MARK) - gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig, orig, op2); + gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig[0], + orig[1], op2); else { gimple *perm - = gimple_build_assign (make_ssa_name (TREE_TYPE (orig)), - VEC_PERM_EXPR, orig, orig, op2); - orig = gimple_assign_lhs (perm); + = gimple_build_assign (make_ssa_name (TREE_TYPE (orig[0])), + VEC_PERM_EXPR, orig[0], orig[1], op2); + orig[0] = gimple_assign_lhs (perm); gsi_insert_before (gsi, perm, GSI_SAME_STMT); - gimple_assign_set_rhs_with_ops (gsi, conv_code, orig, + gimple_assign_set_rhs_with_ops (gsi, conv_code, orig[0], NULL_TREE, NULL_TREE); } } @@ -2324,7 +2343,7 @@ && !gimple_has_volatile_ops (stmt) && (TREE_CODE (gimple_assign_rhs1 (stmt)) != TARGET_MEM_REF) - && !stmt_can_throw_internal (stmt)) + && !stmt_can_throw_internal (cfun, stmt)) { /* Rewrite loads used only in real/imagpart extractions to component-wise loads. */ @@ -2519,7 +2538,7 @@ { tree callee = gimple_call_fndecl (stmt); if (callee != NULL_TREE - && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL) + && fndecl_built_in_p (callee, BUILT_IN_NORMAL)) changed = simplify_builtin_call (&gsi, callee); break; }