This code change intends to improve scev for array element and reduce the common sub-expressions in loop, which may be introduced by multiple reference of expression like &a[i]. With this optimization the register pressure can be reduced in loops.
The problem is originally from a real benchmark, and the test case only tries to detect the GIMPLE level changes. Bootstraped on x86-32. OK for trunk? ChangeLog: 2012-01-05 Jiangning Liu <jiangning....@arm.com> * tree-scalar-evolution (interpret_rhs_expr): generate chrec for array reference. ChangeLog for testsuite: 2012-01-05 Jiangning Liu <jiangning....@arm.com> * gcc.dg/scev-1.c: New. diff --git a/gcc/testsuite/gcc.dg/scev-1.c b/gcc/testsuite/gcc.dg/scev-1.c new file mode 100644 index 0000000..28d5c93 --- /dev/null +++ b/gcc/testsuite/gcc.dg/scev-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int *a_p; +int a[1000]; + +f(int k) +{ + int i; + + for (i=k; i<1000; i+=k) { + a_p = &a[i]; + *a_p = 100; + } +} + +/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index 2077c8d..de89fc4 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -1712,6 +1712,42 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, switch (code) { case ADDR_EXPR: + if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == ARRAY_REF) + { + tree array_ref; + tree var_decl, base, offset; + tree low_bound; + tree unit_size; + tree index; + + array_ref = TREE_OPERAND (rhs1, 0); + var_decl = TREE_OPERAND (array_ref, 0); + index = TREE_OPERAND (array_ref, 1); + + low_bound = array_ref_low_bound (array_ref); + unit_size = array_ref_element_size (array_ref); + + /* We assume all arrays have sizes that are a multiple of a byte. + First subtract the lower bound, if any, in the type of the + index, then convert to sizetype and multiply by the size of + the array element. */ + if (! integer_zerop (low_bound)) + index = fold_build2 (MINUS_EXPR, TREE_TYPE (index), + index, low_bound); + + offset = size_binop (MULT_EXPR, + fold_convert (sizetype, index), + unit_size); + + base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), var_decl); + chrec1 = analyze_scalar_evolution (loop, base); + chrec2 = analyze_scalar_evolution (loop, offset); + chrec1 = chrec_convert (type, chrec1, at_stmt); + chrec2 = chrec_convert (TREE_TYPE (offset), chrec2, at_stmt); + res = chrec_fold_plus (type, chrec1, chrec2); + break; + } + /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR. */ if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF) { Thanks, -Jiangning
scev.patch
Description: Binary data