summaryrefslogtreecommitdiff
path: root/gcc/cfgloop.c
diff options
context:
space:
mode:
authortejohnson <tejohnson@138bc75d-0d04-0410-961f-82ee72b054a4>2013-01-03 00:56:35 +0000
committertejohnson <tejohnson@138bc75d-0d04-0410-961f-82ee72b054a4>2013-01-03 00:56:35 +0000
commitf55775aa1b300f48fa760f179c0fdb56ef975586 (patch)
tree30f5b42d2bf373055b9ccc82406aaf7132d801d2 /gcc/cfgloop.c
parent13367f529bf33ff8939d3bd89e6a80d703bfed1d (diff)
downloadgcc-f55775aa1b300f48fa760f179c0fdb56ef975586.tar.gz
2013-01-02 Teresa Johnson <tejohnson@google.com>
* dumpfile.c (dump_loc): Print filename with location. * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Use new location_t parameter to emit complete unroll message with new dump framework. (canonicalize_loop_induction_variables): Compute loops location and pass to try_unroll_loop_completely. * loop-unroll.c (report_unroll_peel): New function. (peel_loops_completely): Use new dump format with location for main dumpfile message, and invoke report_unroll_peel on success. (decide_unrolling_and_peeling): Ditto. (decide_peel_once_rolling): Remove old dumpfile message subsumed by report_unroll_peel. (decide_peel_completely): Ditto. (decide_unroll_constant_iterations): Ditto. (decide_unroll_runtime_iterations): Ditto. (decide_peel_simple): Ditto. (decide_unroll_stupid): Ditto. * cfgloop.c (get_loop_location): New function. * cfgloop.h (get_loop_location): Declare. testsuite/ * gcc.dg/tree-ssa/loop-1.c: Update expected dump message. * gcc.dg/tree-ssa/loop-23.c: Ditto. * gcc.dg/tree-ssa/cunroll-1.c: Ditto. * gcc.dg/tree-ssa/cunroll-2.c: Ditto. * gcc.dg/tree-ssa/cunroll-3.c: Ditto. * gcc.dg/tree-ssa/cunroll-4.c: Ditto. * gcc.dg/tree-ssa/cunroll-5.c: Ditto. * gcc.dg/unroll_1.c: Ditto. * gcc.dg/unroll_2.c: Ditto. * gcc.dg/unroll_3.c: Ditto. * gcc.dg/unroll_4.c: Ditto. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194829 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgloop.c')
-rw-r--r--gcc/cfgloop.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index b45493a16bb..c15e64945f4 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -1666,3 +1666,55 @@ loop_exits_from_bb_p (struct loop *loop, basic_block bb)
return false;
}
+
+/* Return location corresponding to the loop control condition if possible. */
+
+location_t
+get_loop_location (struct loop *loop)
+{
+ rtx insn = NULL;
+ struct niter_desc *desc = NULL;
+ edge exit;
+
+ /* For a for or while loop, we would like to return the location
+ of the for or while statement, if possible. To do this, look
+ for the branch guarding the loop back-edge. */
+
+ /* If this is a simple loop with an in_edge, then the loop control
+ branch is typically at the end of its source. */
+ desc = get_simple_loop_desc (loop);
+ if (desc->in_edge)
+ {
+ FOR_BB_INSNS_REVERSE (desc->in_edge->src, insn)
+ {
+ if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+ return INSN_LOCATION (insn);
+ }
+ }
+ /* If loop has a single exit, then the loop control branch
+ must be at the end of its source. */
+ if ((exit = single_exit (loop)))
+ {
+ FOR_BB_INSNS_REVERSE (exit->src, insn)
+ {
+ if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+ return INSN_LOCATION (insn);
+ }
+ }
+ /* Next check the latch, to see if it is non-empty. */
+ FOR_BB_INSNS_REVERSE (loop->latch, insn)
+ {
+ if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+ return INSN_LOCATION (insn);
+ }
+ /* Finally, if none of the above identifies the loop control branch,
+ return the first location in the loop header. */
+ FOR_BB_INSNS (loop->header, insn)
+ {
+ if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+ return INSN_LOCATION (insn);
+ }
+ /* If all else fails, simply return the current function location. */
+ return DECL_SOURCE_LOCATION (current_function_decl);
+}
+