On Tue, 8 Aug 2017, Bin.Cheng wrote: > 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]?
Not sure - we already do this to some extent in pass_laddress, but only for the non-constant offset case. Note for the testcase we have &MEM[ptr + 8] and &ptr->foo.bar. Richard. > 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" } } */ > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)