On Tue, Aug 8, 2017 at 1:20 PM, Richard Biener <rguent...@suse.de> wrote: > > The following improves niter analysis for range-based for loops > by handling ADDR_EXPR in expand_simple_operations. > > Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. > > Richard. > > 2017-08-08 Richard Biener <rguent...@suse.de> > > PR middle-end/81719 > * tree-ssa-loop-niter.c: Include tree-dfa.h. > (expand_simple_operations): Also look through ADDR_EXPRs with > MEM_REF bases treating them as POINTER_PLUS_EXPR. > > * g++.dg/tree-ssa/pr81719.C: New testcase. > > Index: gcc/tree-ssa-loop-niter.c > =================================================================== > *** gcc/tree-ssa-loop-niter.c (revision 250813) > --- gcc/tree-ssa-loop-niter.c (working copy) > *************** along with GCC; see the file COPYING3. > *** 42,47 **** > --- 42,48 ---- > #include "tree-chrec.h" > #include "tree-scalar-evolution.h" > #include "params.h" > + #include "tree-dfa.h" > > > /* The maximum number of dominator BBs we search for conditions > *************** expand_simple_operations (tree expr, tre > *** 1980,1985 **** > --- 1981,2001 ---- > > if (code == SSA_NAME) > return expand_simple_operations (e, stop); > + else if (code == ADDR_EXPR) > + { > + HOST_WIDE_INT offset; > + tree base = get_addr_base_and_unit_offset (TREE_OPERAND (e, 0), > + &offset); > + if (base > + && TREE_CODE (base) == MEM_REF) > + { > + ee = expand_simple_operations (TREE_OPERAND (base, 0), stop); > + return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (expr), ee, > + wide_int_to_tree (sizetype, > + mem_ref_offset (base) > + + offset)); > + } > + } > > return expr; > } There are various places we need to look into ADDR_EXPR (MEM_REF), is it possible/beneficial to generally simplify &MEM_REF[base + offset]?
Thanks, bin > Index: gcc/testsuite/g++.dg/tree-ssa/pr81719.C > =================================================================== > *** gcc/testsuite/g++.dg/tree-ssa/pr81719.C (nonexistent) > --- gcc/testsuite/g++.dg/tree-ssa/pr81719.C (working copy) > *************** > *** 0 **** > --- 1,24 ---- > + /* { dg-do compile { target c++11 } } */ > + /* { dg-options "-O3 -fdump-tree-optimized" } */ > + > + typedef int Items[2]; > + > + struct ItemArray > + { > + Items items; > + int sum_x2() const; > + }; > + > + int ItemArray::sum_x2() const > + { > + int total = 0; > + for (int item : items) > + { > + total += item; > + } > + return total; > + } > + > + /* We should be able to compute the number of iterations to two, unroll > + the loop and end up with a single basic-block in sum_x2. */ > + /* { dg-final { scan-tree-dump-times "bb" 1 "optimized" } } */