From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10279 invoked by alias); 31 Oct 2012 12:18:55 -0000 Received: (qmail 10130 invoked by uid 22791); 31 Oct 2012 12:18:39 -0000 X-SWARE-Spam-Status: No, hits=-6.5 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,TW_TM X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 31 Oct 2012 12:18:26 +0000 Received: from relay1.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 032FBA4453; Wed, 31 Oct 2012 13:18:25 +0100 (CET) Date: Wed, 31 Oct 2012 12:22:00 -0000 From: Richard Biener To: Jan Hubicka Cc: gcc-patches@gcc.gnu.org Subject: Re: Non-dominating loop bounds in tree-ssa-loop-niter 3/4 In-Reply-To: <20121031120359.GA13132@kam.mff.cuni.cz> Message-ID: References: <20121031103949.GD19020@kam.mff.cuni.cz> <20121031120359.GA13132@kam.mff.cuni.cz> User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2012-10/txt/msg02905.txt.bz2 On Wed, 31 Oct 2012, Jan Hubicka wrote: > > > Index: tree-ssa-loop-niter.c > > > =================================================================== > > > --- tree-ssa-loop-niter.c (revision 192989) > > > @@ -3505,15 +3737,11 @@ scev_probably_wraps_p (tree base, tree s > > > return true; > > > } > > > > > > -/* Frees the information on upper bounds on numbers of iterations of LOOP. */ > > > - > > > > Needs a comment. > > Yep, > also the reason I export it is because I use in other patch. > (I think we should not hook the bounds into the loop structure and keep them dead, > so i want the max_iter*friends to free them unless they are asked to preserve and > explicitely free in the two users of them). > > > +static bool > > > +remove_exits_and_undefined_stmts (struct loop *loop, unsigned int npeeled) > > > +{ > > > + struct nb_iter_bound *elt; > > > + bool changed = false; > > > + > > > + for (elt = loop->bounds; elt; elt = elt->next) > > > + { > > > + /* If statement is known to be undefined after peeling, turn it > > > + into unreachable (or trap when debugging experience is supposed > > > + to be good). */ > > > + if (!elt->is_exit > > > + && elt->bound.ule (double_int::from_uhwi (npeeled))) > > > + { > > > + gimple_stmt_iterator gsi = gsi_for_stmt (elt->stmt); > > > + gimple stmt = gimple_build_call > > > + (builtin_decl_implicit (optimize_debug > > > + ? BUILT_IN_TRAP : BUILT_IN_UNREACHABLE), > > > > I'm not sure we should do different things for -Og here. In fact there > > is no unrolling done for -Og at all, so just use unreachable. > > OK, I was thinking about BUILT_IN_TRAP for -O1 too, but I am not sure either. > i guess we will gather some experience on how much are users confused. > > Why we do ont inline at -Og? unroll you mean. Because unrolling mutates the CFG too much. Well - it was just a starting point, populating -Og with as little as possible and 100% profitable transforms (in both debug and speed metric). In late opts we only do (early opt queue is shared): NEXT_PASS (pass_all_optimizations_g); { struct opt_pass **p = &pass_all_optimizations_g.pass.sub; NEXT_PASS (pass_remove_cgraph_callee_edges); NEXT_PASS (pass_strip_predict_hints); /* Lower remaining pieces of GIMPLE. */ NEXT_PASS (pass_lower_complex); NEXT_PASS (pass_lower_vector_ssa); /* Perform simple scalar cleanup which is constant/copy propagation. */ NEXT_PASS (pass_ccp); NEXT_PASS (pass_object_sizes); /* Copy propagation also copy-propagates constants, this is necessary to forward object-size results properly. */ NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_rename_ssa_copies); NEXT_PASS (pass_dce); /* Fold remaining builtins. */ NEXT_PASS (pass_fold_builtins); /* ??? We do want some kind of loop invariant motion, but we possibly need to adjust LIM to be more friendly towards preserving accurate debug information here. */ NEXT_PASS (pass_late_warn_uninitialized); NEXT_PASS (pass_uncprop); NEXT_PASS (pass_local_pure_const); } > > > + /* If we know the exit will be taken after peeling, update. */ > > > + else if (elt->is_exit > > > + && elt->bound.ule (double_int::from_uhwi (npeeled))) > > > + { > > > + basic_block bb = gimple_bb (elt->stmt); > > > + edge exit_edge = EDGE_SUCC (bb, 0); > > > + > > > + if (dump_file && (dump_flags & TDF_DETAILS)) > > > + { > > > + fprintf (dump_file, "Forced exit to be taken: "); > > > + print_gimple_stmt (dump_file, elt->stmt, 0, 0); > > > + } > > > + if (!loop_exit_edge_p (loop, exit_edge)) > > > + exit_edge = EDGE_SUCC (bb, 1); > > > + if (exit_edge->flags & EDGE_TRUE_VALUE) > > > > I think we can have abnormal/eh exit edges. So I'm not sure you > > can, without checking, assume the block ends in a GIMPLE_COND. > > We can't - those are only edges that are found by the IV analysis and they > always test IV with some bound. (it is all done by number_of_iterations_exit) > > > > See above. Otherwise the overall idea sounds fine. > > Similarly here, simple exits are always conditionals. I see. Then the patch is ok (with the comment added). Thanks, Richard.