From: Richard Biener Date: Fri, 2 Aug 2019 08:40:34 +0000 (+0000) Subject: backport: [multiple changes] X-Git-Tag: releases/gcc-9.2.0~78 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d72c9e1bc15949b5309562263c3b50adaac5fc8;p=thirdparty%2Fgcc.git backport: [multiple changes] 2019-08-02 Richard Biener Backport from mainline 2019-07-31 Richard Biener PR tree-optimization/91178 * tree-ssa-sccvn.c (vn_reference_maybe_forwprop_address): Use tail-recursion. * gcc.dg/torture/pr91178-2.c: New testcase. 2019-07-17 Richard Biener PR tree-optimization/91178 * tree-ssa.c (release_defs_bitset): Iterate from higher to lower SSA names to avoid quadratic behavior in the common case. * tree-data-ref.c (split_constant_offset): Add limit argument and pass it down. Initialize it from PARAM_SSA_NAME_DEF_CHAIN_LIMIT. (split_constant_offset_1): Add limit argument and use it to limit SSA def walking. Optimize the common plus/minus case. * gcc.dg/torture/pr91178.c: New testcase. 2019-07-12 Martin Sebor * doc/invoke.texi (ssa-name-def-chain-limit): Document new --param. * params.def (PARAM_SSA_NAME_DEF_CHAIN_LIMIT): Add new --param. * tree-vrp.c (vrp_prop::check_mem_ref): Use PARAM_SSA_NAME_DEF_CHAIN_LIMIT. * gcc.dg/Warray-bounds-43.c: New test. From-SVN: r274000 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9934b26f7aa6..57c1025f6e34 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2019-08-02 Richard Biener + + Backport from mainline + 2019-07-31 Richard Biener + + PR tree-optimization/91178 + * tree-ssa-sccvn.c (vn_reference_maybe_forwprop_address): + Use tail-recursion. + + 2019-07-17 Richard Biener + + PR tree-optimization/91178 + * tree-ssa.c (release_defs_bitset): Iterate from higher to + lower SSA names to avoid quadratic behavior in the common case. + * tree-data-ref.c (split_constant_offset): Add limit argument + and pass it down. Initialize it from PARAM_SSA_NAME_DEF_CHAIN_LIMIT. + (split_constant_offset_1): Add limit argument and use it to + limit SSA def walking. Optimize the common plus/minus case. + + 2019-07-12 Martin Sebor + + * doc/invoke.texi (ssa-name-def-chain-limit): Document new --param. + * params.def (PARAM_SSA_NAME_DEF_CHAIN_LIMIT): Add new --param. + * tree-vrp.c (vrp_prop::check_mem_ref): Use + PARAM_SSA_NAME_DEF_CHAIN_LIMIT. + 2019-08-01 Jakub Jelinek Backported from mainline diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 29585cf15aac..6ef36ce02aaa 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -12157,6 +12157,13 @@ before the loop versioning pass considers it too big to copy, discounting any instructions in inner loops that directly benefit from versioning. +@item ssa-name-def-chain-limit +The maximum number of SSA_NAME assignments to follow in determining +a property of a variable such as its value. This limits the number +of iterations or recursive calls GCC performs when optimizing certain +statements or when determining their validity prior to issuing +diagnostics. + @end table @end table diff --git a/gcc/params.def b/gcc/params.def index 3c9c5fc0f13d..813dc55d94c6 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -1414,6 +1414,12 @@ DEFPARAM(PARAM_LOOP_VERSIONING_MAX_OUTER_INSNS, " loops.", 100, 0, 0) +DEFPARAM(PARAM_SSA_NAME_DEF_CHAIN_LIMIT, + "ssa-name-def-chain-limit", + "The maximum number of SSA_NAME assignments to follow in determining " + "a value.", + 512, 0, 0) + /* Local variables: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b7d14cd03dec..337b50e194c0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,20 @@ +2019-08-02 Richard Biener + + Backport from mainline + 2019-07-31 Richard Biener + + PR tree-optimization/91178 + * gcc.dg/torture/pr91178-2.c: New testcase. + + 2019-07-17 Richard Biener + + PR tree-optimization/91178 + * gcc.dg/torture/pr91178.c: New testcase. + + 2019-07-12 Martin Sebor + + * gcc.dg/Warray-bounds-43.c: New test. + 2019-08-01 Jakub Jelinek Backported from mainline diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-43.c b/gcc/testsuite/gcc.dg/Warray-bounds-43.c new file mode 100644 index 000000000000..8892921157d2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-43.c @@ -0,0 +1,133 @@ +/* Test to verify that --param ssa_name_def_chain_limit can be used to + limit the maximum number of SSA_NAME assignments the warning follows. + { dg-do compile } + { dg-options "-O2 -Wall --param ssa-name-def-chain-limit=4" } */ + +#define NOIPA __attribute__ ((noipa)) + +const char a0[] = ""; +const char a1[] = "1"; +const char a2[] = "12"; +const char a3[] = "123"; +const char a4[] = "1234"; +const char a5[] = "12345"; +const char a6[] = "123456"; +const char a7[] = "1234567"; +const char a8[] = "12345678"; +const char a9[] = "123456789"; + +void f (const char*, ...); + +int i0, i1, i2, i3, i4, i5, i6, i7, i8; + +NOIPA int g2 (int i) +{ + if (i < 1) i = 1; + + const char *p0 = a9; + const char *p1 = p0 + i; + const char *p2 = p1 + i; + + f (p0, p1, p2); + + return p2[8]; // { dg-warning "\\\[-Warray-bounds]" } +} + +NOIPA int g3 (int i) +{ + if (i < 1) i = 1; + + const char *p0 = a9; + const char *p1 = p0 + i; + const char *p2 = p1 + i; + const char *p3 = p2 + i; + + f (p0, p1, p2, p3); + + return p3[7]; // { dg-warning "\\\[-Warray-bounds]" } +} + +NOIPA int g4 (int i) +{ + if (i < 1) i = 1; + + const char *p0 = a9; + const char *p1 = p0 + i; + const char *p2 = p1 + i; + const char *p3 = p2 + i; + const char *p4 = p3 + i; + + f (p0, p1, p2, p3, p4); + + return p4[6]; // { dg-warning "\\\[-Warray-bounds]" } +} + +NOIPA int g5 (int i) +{ + if (i < 1) i = 1; + + const char *p0 = a9; + const char *p1 = p0 + i; + const char *p2 = p1 + i; + const char *p3 = p2 + i; + const char *p4 = p3 + i; + const char *p5 = p4 + i; + + f (p0, p1, p2, p3, p4, p5); + + return p5[5]; +} + +NOIPA int g6 (int i) +{ + if (i < 1) i = 1; + + const char *p0 = a9; + const char *p1 = p0 + i; + const char *p2 = p1 + i; + const char *p3 = p2 + i; + const char *p4 = p3 + i; + const char *p5 = p4 + i; + const char *p6 = p5 + i; + + f (p0, p1, p2, p3, p4, p5, p6); + + return p6[4]; +} + +NOIPA int g7 (int i) +{ + if (i < 1) i = 1; + + const char *p0 = a9; + const char *p1 = p0 + i; + const char *p2 = p1 + i; + const char *p3 = p2 + i; + const char *p4 = p3 + i; + const char *p5 = p4 + i; + const char *p6 = p5 + i; + const char *p7 = p6 + i; + + f (p0, p1, p2, p3, p4, p5, p6, p7); + + return p7[3]; +} + +NOIPA int g8 (int i) +{ + if (i < 1) i = 1; + + const char *p0 = a9; + const char *p1 = p0 + i; + const char *p2 = p1 + i; + const char *p3 = p2 + i; + const char *p4 = p3 + i; + const char *p5 = p4 + i; + const char *p6 = p5 + i; + const char *p7 = p6 + i; + const char *p8 = p7 + i; + + f (p0, p1, p2, p3, p4, p5, p6, p7, p8); + + return p8[2]; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr91178-2.c b/gcc/testsuite/gcc.dg/torture/pr91178-2.c new file mode 100644 index 000000000000..0ebb4700b2af --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr91178-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ + +int a[100][70304]; +int b[100]; +void c() +{ + for (int d = 2; d < 4; d++) + for (int e = 2; e <= 50; e++) + for (int f = 32; f <= 38; f++) + b[d + f] -= a[e][5]; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr91178.c b/gcc/testsuite/gcc.dg/torture/pr91178.c new file mode 100644 index 000000000000..b7a2dbe9e7f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr91178.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ + +int a; +extern int f[10][91125]; +int b[50]; +void c() +{ + for (int d = 6; d <= a; d++) + for (int e = 16; e <= 24; e++) + b[e] -= f[d][d]; +} diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index ad0a00720d1d..d00c1bd31e64 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -584,7 +584,8 @@ debug_ddrs (vec ddrs) static void split_constant_offset (tree exp, tree *var, tree *off, - hash_map > &cache); + hash_map > &cache, + unsigned *limit); /* Helper function for split_constant_offset. Expresses OP0 CODE OP1 (the type of the result is TYPE) as VAR + OFF, where OFF is a nonzero @@ -595,7 +596,8 @@ split_constant_offset (tree exp, tree *var, tree *off, static bool split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1, tree *var, tree *off, - hash_map > &cache) + hash_map > &cache, + unsigned *limit) { tree var0, var1; tree off0, off1; @@ -616,8 +618,15 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1, /* FALLTHROUGH */ case PLUS_EXPR: case MINUS_EXPR: - split_constant_offset (op0, &var0, &off0, cache); - split_constant_offset (op1, &var1, &off1, cache); + if (TREE_CODE (op1) == INTEGER_CST) + { + split_constant_offset (op0, &var0, &off0, cache, limit); + *var = var0; + *off = size_binop (ocode, off0, fold_convert (ssizetype, op1)); + return true; + } + split_constant_offset (op0, &var0, &off0, cache, limit); + split_constant_offset (op1, &var1, &off1, cache, limit); *var = fold_build2 (code, type, var0, var1); *off = size_binop (ocode, off0, off1); return true; @@ -626,7 +635,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1, if (TREE_CODE (op1) != INTEGER_CST) return false; - split_constant_offset (op0, &var0, &off0, cache); + split_constant_offset (op0, &var0, &off0, cache, limit); *var = fold_build2 (MULT_EXPR, type, var0, op1); *off = size_binop (MULT_EXPR, off0, fold_convert (ssizetype, op1)); return true; @@ -650,7 +659,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1, if (poffset) { - split_constant_offset (poffset, &poffset, &off1, cache); + split_constant_offset (poffset, &poffset, &off1, cache, limit); off0 = size_binop (PLUS_EXPR, off0, off1); if (POINTER_TYPE_P (TREE_TYPE (base))) base = fold_build_pointer_plus (base, poffset); @@ -720,11 +729,15 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1, e = std::make_pair (op0, ssize_int (0)); } + if (*limit == 0) + return false; + --*limit; + var0 = gimple_assign_rhs1 (def_stmt); var1 = gimple_assign_rhs2 (def_stmt); bool res = split_constant_offset_1 (type, var0, subcode, var1, - var, off, cache); + var, off, cache, limit); if (res && use_cache) *cache.get (op0) = std::make_pair (*var, *off); return res; @@ -747,7 +760,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1, /* Split the unconverted operand and try to prove that wrapping isn't a problem. */ tree tmp_var, tmp_off; - split_constant_offset (op0, &tmp_var, &tmp_off, cache); + split_constant_offset (op0, &tmp_var, &tmp_off, cache, limit); /* See whether we have an SSA_NAME whose range is known to be [A, B]. */ @@ -782,7 +795,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1, *off = wide_int_to_tree (ssizetype, diff); } else - split_constant_offset (op0, &var0, off, cache); + split_constant_offset (op0, &var0, off, cache, limit); *var = fold_convert (type, var0); return true; } @@ -799,7 +812,8 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1, static void split_constant_offset (tree exp, tree *var, tree *off, - hash_map > &cache) + hash_map > &cache, + unsigned *limit) { tree type = TREE_TYPE (exp), op0, op1, e, o; enum tree_code code; @@ -813,7 +827,7 @@ split_constant_offset (tree exp, tree *var, tree *off, code = TREE_CODE (exp); extract_ops_from_tree (exp, &code, &op0, &op1); - if (split_constant_offset_1 (type, op0, code, op1, &e, &o, cache)) + if (split_constant_offset_1 (type, op0, code, op1, &e, &o, cache, limit)) { *var = e; *off = o; @@ -823,10 +837,11 @@ split_constant_offset (tree exp, tree *var, tree *off, void split_constant_offset (tree exp, tree *var, tree *off) { + unsigned limit = PARAM_VALUE (PARAM_SSA_NAME_DEF_CHAIN_LIMIT); static hash_map > *cache; if (!cache) cache = new hash_map > (37); - split_constant_offset (exp, var, off, *cache); + split_constant_offset (exp, var, off, *cache, &limit); cache->empty (); } diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 8bc2a9da6c82..9529d1669c96 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1267,113 +1267,123 @@ static bool vn_reference_maybe_forwprop_address (vec *ops, unsigned int *i_p) { - unsigned int i = *i_p; - vn_reference_op_t op = &(*ops)[i]; - vn_reference_op_t mem_op = &(*ops)[i - 1]; - gimple *def_stmt; - enum tree_code code; - poly_offset_int off; - - def_stmt = SSA_NAME_DEF_STMT (op->op0); - if (!is_gimple_assign (def_stmt)) - return false; - - code = gimple_assign_rhs_code (def_stmt); - if (code != ADDR_EXPR - && code != POINTER_PLUS_EXPR) - return false; - - off = poly_offset_int::from (wi::to_poly_wide (mem_op->op0), SIGNED); + bool changed = false; + vn_reference_op_t op; - /* The only thing we have to do is from &OBJ.foo.bar add the offset - from .foo.bar to the preceding MEM_REF offset and replace the - address with &OBJ. */ - if (code == ADDR_EXPR) + do { - tree addr, addr_base; - poly_int64 addr_offset; - - addr = gimple_assign_rhs1 (def_stmt); - addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0), - &addr_offset); - /* If that didn't work because the address isn't invariant propagate - the reference tree from the address operation in case the current - dereference isn't offsetted. */ - if (!addr_base - && *i_p == ops->length () - 1 - && known_eq (off, 0) - /* This makes us disable this transform for PRE where the - reference ops might be also used for code insertion which - is invalid. */ - && default_vn_walk_kind == VN_WALKREWRITE) + unsigned int i = *i_p; + op = &(*ops)[i]; + vn_reference_op_t mem_op = &(*ops)[i - 1]; + gimple *def_stmt; + enum tree_code code; + poly_offset_int off; + + def_stmt = SSA_NAME_DEF_STMT (op->op0); + if (!is_gimple_assign (def_stmt)) + return changed; + + code = gimple_assign_rhs_code (def_stmt); + if (code != ADDR_EXPR + && code != POINTER_PLUS_EXPR) + return changed; + + off = poly_offset_int::from (wi::to_poly_wide (mem_op->op0), SIGNED); + + /* The only thing we have to do is from &OBJ.foo.bar add the offset + from .foo.bar to the preceding MEM_REF offset and replace the + address with &OBJ. */ + if (code == ADDR_EXPR) { - auto_vec tem; - copy_reference_ops_from_ref (TREE_OPERAND (addr, 0), &tem); - /* Make sure to preserve TBAA info. The only objects not - wrapped in MEM_REFs that can have their address taken are - STRING_CSTs. */ - if (tem.length () >= 2 - && tem[tem.length () - 2].opcode == MEM_REF) + tree addr, addr_base; + poly_int64 addr_offset; + + addr = gimple_assign_rhs1 (def_stmt); + addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0), + &addr_offset); + /* If that didn't work because the address isn't invariant propagate + the reference tree from the address operation in case the current + dereference isn't offsetted. */ + if (!addr_base + && *i_p == ops->length () - 1 + && known_eq (off, 0) + /* This makes us disable this transform for PRE where the + reference ops might be also used for code insertion which + is invalid. */ + && default_vn_walk_kind == VN_WALKREWRITE) { - vn_reference_op_t new_mem_op = &tem[tem.length () - 2]; - new_mem_op->op0 - = wide_int_to_tree (TREE_TYPE (mem_op->op0), - wi::to_poly_wide (new_mem_op->op0)); + auto_vec tem; + copy_reference_ops_from_ref (TREE_OPERAND (addr, 0), &tem); + /* Make sure to preserve TBAA info. The only objects not + wrapped in MEM_REFs that can have their address taken are + STRING_CSTs. */ + if (tem.length () >= 2 + && tem[tem.length () - 2].opcode == MEM_REF) + { + vn_reference_op_t new_mem_op = &tem[tem.length () - 2]; + new_mem_op->op0 + = wide_int_to_tree (TREE_TYPE (mem_op->op0), + wi::to_poly_wide (new_mem_op->op0)); + } + else + gcc_assert (tem.last ().opcode == STRING_CST); + ops->pop (); + ops->pop (); + ops->safe_splice (tem); + --*i_p; + return true; } - else - gcc_assert (tem.last ().opcode == STRING_CST); - ops->pop (); - ops->pop (); - ops->safe_splice (tem); - --*i_p; - return true; + if (!addr_base + || TREE_CODE (addr_base) != MEM_REF + || (TREE_CODE (TREE_OPERAND (addr_base, 0)) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (addr_base, + 0)))) + return changed; + + off += addr_offset; + off += mem_ref_offset (addr_base); + op->op0 = TREE_OPERAND (addr_base, 0); + } + else + { + tree ptr, ptroff; + ptr = gimple_assign_rhs1 (def_stmt); + ptroff = gimple_assign_rhs2 (def_stmt); + if (TREE_CODE (ptr) != SSA_NAME + || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr) + /* Make sure to not endlessly recurse. + See gcc.dg/tree-ssa/20040408-1.c for an example. Can easily + happen when we value-number a PHI to its backedge value. */ + || SSA_VAL (ptr) == op->op0 + || !poly_int_tree_p (ptroff)) + return changed; + + off += wi::to_poly_offset (ptroff); + op->op0 = ptr; } - if (!addr_base - || TREE_CODE (addr_base) != MEM_REF - || (TREE_CODE (TREE_OPERAND (addr_base, 0)) == SSA_NAME - && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (addr_base, 0)))) - return false; - - off += addr_offset; - off += mem_ref_offset (addr_base); - op->op0 = TREE_OPERAND (addr_base, 0); - } - else - { - tree ptr, ptroff; - ptr = gimple_assign_rhs1 (def_stmt); - ptroff = gimple_assign_rhs2 (def_stmt); - if (TREE_CODE (ptr) != SSA_NAME - || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr) - /* Make sure to not endlessly recurse. - See gcc.dg/tree-ssa/20040408-1.c for an example. Can easily - happen when we value-number a PHI to its backedge value. */ - || SSA_VAL (ptr) == op->op0 - || !poly_int_tree_p (ptroff)) - return false; - off += wi::to_poly_offset (ptroff); - op->op0 = ptr; + mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off); + if (tree_fits_shwi_p (mem_op->op0)) + mem_op->off = tree_to_shwi (mem_op->op0); + else + mem_op->off = -1; + /* ??? Can end up with endless recursion here!? + gcc.c-torture/execute/strcmp-1.c */ + if (TREE_CODE (op->op0) == SSA_NAME) + op->op0 = SSA_VAL (op->op0); + if (TREE_CODE (op->op0) != SSA_NAME) + op->opcode = TREE_CODE (op->op0); + + changed = true; } + /* Tail-recurse. */ + while (TREE_CODE (op->op0) == SSA_NAME); - mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off); - if (tree_fits_shwi_p (mem_op->op0)) - mem_op->off = tree_to_shwi (mem_op->op0); - else - mem_op->off = -1; - /* ??? Can end up with endless recursion here!? - gcc.c-torture/execute/strcmp-1.c */ - if (TREE_CODE (op->op0) == SSA_NAME) - op->op0 = SSA_VAL (op->op0); - if (TREE_CODE (op->op0) != SSA_NAME) - op->opcode = TREE_CODE (op->op0); - - /* And recurse. */ - if (TREE_CODE (op->op0) == SSA_NAME) - vn_reference_maybe_forwprop_address (ops, i_p); - else if (TREE_CODE (op->op0) == ADDR_EXPR) + /* Fold a remaining *&. */ + if (TREE_CODE (op->op0) == ADDR_EXPR) vn_reference_fold_indirect (ops, i_p); - return true; + + return changed; } /* Optimize the reference REF to a constant if possible or return diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index cf366982eef6..bdb6d6b0a706 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -554,20 +554,25 @@ release_defs_bitset (bitmap toremove) /* Performing a topological sort is probably overkill, this will most likely run in slightly superlinear time, rather than the - pathological quadratic worst case. */ + pathological quadratic worst case. + But iterate from max SSA name version to min one because + that mimics allocation order during code generation behavior best. + Use an array for this which we compact on-the-fly with a NULL + marker moving towards the end of the vector. */ + auto_vec names; + names.reserve (bitmap_count_bits (toremove) + 1); + names.quick_push (NULL_TREE); + EXECUTE_IF_SET_IN_BITMAP (toremove, 0, j, bi) + names.quick_push (ssa_name (j)); + + bitmap_tree_view (toremove); while (!bitmap_empty_p (toremove)) { - unsigned to_remove_bit = -1U; - EXECUTE_IF_SET_IN_BITMAP (toremove, 0, j, bi) + j = names.length () - 1; + for (unsigned i = names.length () - 1; names[i];) { - if (to_remove_bit != -1U) - { - bitmap_clear_bit (toremove, to_remove_bit); - to_remove_bit = -1U; - } - bool remove_now = true; - tree var = ssa_name (j); + tree var = names[i]; gimple *stmt; imm_use_iterator uit; @@ -612,14 +617,15 @@ release_defs_bitset (bitmap toremove) gsi_remove (&gsi, true); release_defs (def); } - - to_remove_bit = j; + bitmap_clear_bit (toremove, SSA_NAME_VERSION (var)); } + else + --i; + if (--j != i) + names[i] = names[j]; } - if (to_remove_bit != -1U) - bitmap_clear_bit (toremove, to_remove_bit); } - + bitmap_list_view (toremove); } /* Verify virtual SSA form. */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 0a172719e5df..795d7184a65f 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4549,7 +4549,8 @@ vrp_prop::check_mem_ref (location_t location, tree ref, The loop computes the range of the final offset for expressions such as (A + i0 + ... + iN)[CSTOFF] where i0 through iN are SSA_NAMEs in some range. */ - while (TREE_CODE (arg) == SSA_NAME) + const unsigned limit = PARAM_VALUE (PARAM_SSA_NAME_DEF_CHAIN_LIMIT); + for (unsigned n = 0; TREE_CODE (arg) == SSA_NAME && n < limit; ++n) { gimple *def = SSA_NAME_DEF_STMT (arg); if (!is_gimple_assign (def))