From 99f6be4b59c7a6f7076102291e61cca12f813de8 Mon Sep 17 00:00:00 2001 From: rguenth Date: Wed, 6 Nov 2013 15:00:16 +0000 Subject: [PATCH] 2013-11-06 Richard Biener PR tree-optimization/58653 * tree-predcom.c (ref_at_iteration): Rewrite to generate a MEM_REF. (prepare_initializers_chain): Adjust. * gcc.dg/tree-ssa/predcom-6.c: New testcase. * gcc.dg/tree-ssa/predcom-7.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204458 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++ gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/gcc.dg/tree-ssa/predcom-6.c | 13 ++++ gcc/testsuite/gcc.dg/tree-ssa/predcom-7.c | 18 +++++ gcc/tree-predcom.c | 111 +++++++----------------------- 5 files changed, 67 insertions(+), 88 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/predcom-6.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/predcom-7.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7465c4ae372..9d45b0ca4fd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-11-06 Richard Biener + + PR tree-optimization/58653 + * tree-predcom.c (ref_at_iteration): Rewrite to generate + a MEM_REF. + (prepare_initializers_chain): Adjust. + 2013-11-06 Andrew MacLeod * gimple.h (block_in_transaction): Move to basic-block.h and rename. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8cad9e1637f..9d19eb10231 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-11-06 Richard Biener + + PR tree-optimization/58653 + * gcc.dg/tree-ssa/predcom-6.c: New testcase. + * gcc.dg/tree-ssa/predcom-7.c: Likewise. + 2013-11-05 Balaji V. Iyer * c-c++-common/cilk-plus/CK/fib.c: Reduced the iteration from diff --git a/gcc/testsuite/gcc.dg/tree-ssa/predcom-6.c b/gcc/testsuite/gcc.dg/tree-ssa/predcom-6.c new file mode 100644 index 00000000000..96d9bf93ef7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/predcom-6.c @@ -0,0 +1,13 @@ +/* { dg-do run } */ + +int a, c, e[5][2]; +unsigned int d; + +int +main () +{ + for (d = 0; d < 2; d++) + if (a ? 0 : e[c + 3][d] & e[c + 4][d]) + break; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/predcom-7.c b/gcc/testsuite/gcc.dg/tree-ssa/predcom-7.c new file mode 100644 index 00000000000..e7ae87ccc7a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/predcom-7.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-tree-pcom-details" } */ + +int b, f, d[5][2]; +unsigned int c; + +int +main () +{ + for (c = 0; c < 2; c++) + if (d[b + 3][c] & d[b + 4][c]) + if (f) + break; + return 0; +} + +/* { dg-final { scan-tree-dump "Executing predictive commoning" "pcom" } } */ +/* { dg-final { cleanup-tree-dump "pcom" } } */ diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 1005e783d0b..3358f8b9331 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -1334,90 +1334,29 @@ replace_ref_with (gimple stmt, tree new_tree, bool set, bool in_lhs) gsi_insert_after (&bsi, new_stmt, GSI_NEW_STMT); } -/* Returns the reference to the address of REF in the ITER-th iteration of - LOOP, or NULL if we fail to determine it (ITER may be negative). We - try to preserve the original shape of the reference (not rewrite it - as an indirect ref to the address), to make tree_could_trap_p in - prepare_initializers_chain return false more often. */ - -static tree -ref_at_iteration (struct loop *loop, tree ref, int iter) -{ - tree idx, *idx_p, type, val, op0 = NULL_TREE, ret; - affine_iv iv; - bool ok; - - if (handled_component_p (ref)) - { - op0 = ref_at_iteration (loop, TREE_OPERAND (ref, 0), iter); - if (!op0) - return NULL_TREE; - } - else if (!INDIRECT_REF_P (ref) - && TREE_CODE (ref) != MEM_REF) - return unshare_expr (ref); - - if (TREE_CODE (ref) == MEM_REF) - { - ret = unshare_expr (ref); - idx = TREE_OPERAND (ref, 0); - idx_p = &TREE_OPERAND (ret, 0); - } - else if (TREE_CODE (ref) == COMPONENT_REF) - { - /* Check that the offset is loop invariant. */ - if (TREE_OPERAND (ref, 2) - && !expr_invariant_in_loop_p (loop, TREE_OPERAND (ref, 2))) - return NULL_TREE; - - return build3 (COMPONENT_REF, TREE_TYPE (ref), op0, - unshare_expr (TREE_OPERAND (ref, 1)), - unshare_expr (TREE_OPERAND (ref, 2))); - } - else if (TREE_CODE (ref) == ARRAY_REF) - { - /* Check that the lower bound and the step are loop invariant. */ - if (TREE_OPERAND (ref, 2) - && !expr_invariant_in_loop_p (loop, TREE_OPERAND (ref, 2))) - return NULL_TREE; - if (TREE_OPERAND (ref, 3) - && !expr_invariant_in_loop_p (loop, TREE_OPERAND (ref, 3))) - return NULL_TREE; - - ret = build4 (ARRAY_REF, TREE_TYPE (ref), op0, NULL_TREE, - unshare_expr (TREE_OPERAND (ref, 2)), - unshare_expr (TREE_OPERAND (ref, 3))); - idx = TREE_OPERAND (ref, 1); - idx_p = &TREE_OPERAND (ret, 1); - } - else - return NULL_TREE; - - ok = simple_iv (loop, loop, idx, &iv, true); - if (!ok) - return NULL_TREE; - iv.base = expand_simple_operations (iv.base); - if (integer_zerop (iv.step)) - *idx_p = unshare_expr (iv.base); +/* Returns a memory reference to DR in the ITER-th iteration of + the loop it was analyzed in. Append init stmts to STMTS. */ + +static tree +ref_at_iteration (data_reference_p dr, int iter, gimple_seq *stmts) +{ + tree off = DR_OFFSET (dr); + tree coff = DR_INIT (dr); + if (iter == 0) + ; + else if (TREE_CODE (DR_STEP (dr)) == INTEGER_CST) + coff = size_binop (PLUS_EXPR, coff, + size_binop (MULT_EXPR, DR_STEP (dr), ssize_int (iter))); else - { - type = TREE_TYPE (iv.base); - if (POINTER_TYPE_P (type)) - { - val = fold_build2 (MULT_EXPR, sizetype, iv.step, - size_int (iter)); - val = fold_build_pointer_plus (iv.base, val); - } - else - { - val = fold_build2 (MULT_EXPR, type, iv.step, - build_int_cst_type (type, iter)); - val = fold_build2 (PLUS_EXPR, type, iv.base, val); - } - *idx_p = unshare_expr (val); - } - - return ret; + off = size_binop (PLUS_EXPR, off, + size_binop (MULT_EXPR, DR_STEP (dr), ssize_int (iter))); + tree addr = fold_build_pointer_plus (DR_BASE_ADDRESS (dr), off); + addr = force_gimple_operand_1 (addr, stmts, is_gimple_mem_ref_addr, + NULL_TREE); + return fold_build2 (MEM_REF, TREE_TYPE (DR_REF (dr)), + addr, + fold_convert (reference_alias_ptr_type (DR_REF (dr)), + coff)); } /* Get the initialization expression for the INDEX-th temporary variable @@ -2376,14 +2315,10 @@ prepare_initializers_chain (struct loop *loop, chain_p chain) if (chain->inits[i] != NULL_TREE) continue; - init = ref_at_iteration (loop, DR_REF (dr), (int) i - n); - if (!init) - return false; - + init = ref_at_iteration (dr, (int) i - n, &stmts); if (!chain->all_always_accessed && tree_could_trap_p (init)) return false; - init = force_gimple_operand (init, &stmts, false, NULL_TREE); if (stmts) gsi_insert_seq_on_edge_immediate (entry, stmts); -- 2.11.4.GIT