From 2a8f32231ba684bc0c069f7f5bec83bce0b7b877 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 14 Jan 2016 15:12:53 -0800 Subject: [PATCH] re PR rtl-optimization/69014 (gcc.c-torture/execute/991023-1.c FAILs with -Os -fmodulo-sched -fno-tree-vrp) PR rtl-opt/69014 * loop-doloop.c (record_reg_sets): New. (doloop_optimize): Reject the transform if the sequence clobbers registers live at the end of the loop block. (doloop_optimize_loops): Enable df_live if needed. From-SVN: r232395 --- gcc/ChangeLog | 8 ++++++++ gcc/loop-doloop.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f5ba8f02..790662511 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-01-14 Richard Henderson + + PR rtl-opt/69014 + * loop-doloop.c (record_reg_sets): New. + (doloop_optimize): Reject the transform if the sequence + clobbers registers live at the end of the loop block. + (doloop_optimize_loops): Enable df_live if needed. + 2016-01-14 Michael Meissner * config/rs6000/rs6000-builtin.def: Revert 2016-01-13 change. diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c index 157de49..940c966 100644 --- a/gcc/loop-doloop.c +++ b/gcc/loop-doloop.c @@ -34,6 +34,8 @@ along with GCC; see the file COPYING3. If not see #include "params.h" #include "dumpfile.h" #include "loop-unroll.h" +#include "regs.h" +#include "df.h" /* This module is used to modify loops with a determinable number of iterations to use special low-overhead looping instructions. @@ -573,6 +575,27 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, } } +/* Called through note_stores. */ + +static void +record_reg_sets (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) +{ + bitmap mod = (bitmap)data; + if (REG_P (x)) + { + unsigned int regno = REGNO (x); + if (HARD_REGISTER_P (x)) + { + unsigned int end_regno = end_hard_regno (GET_MODE (x), regno); + do + bitmap_set_bit (mod, regno); + while (++regno < end_regno); + } + else + bitmap_set_bit (mod, regno); + } +} + /* Process loop described by LOOP validating that the loop is suitable for conversion to use a low overhead looping instruction, replacing the jump insn where suitable. Returns true if the loop was successfully @@ -706,6 +729,26 @@ doloop_optimize (struct loop *loop) return false; } + /* Ensure that the new sequence doesn't clobber a register that + is live at the end of the block. */ + { + bitmap modified = BITMAP_ALLOC (NULL); + + for (rtx_insn *i = doloop_seq; i != NULL; i = NEXT_INSN (i)) + note_stores (PATTERN (i), record_reg_sets, modified); + + basic_block loop_end = desc->out_edge->src; + bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified); + BITMAP_FREE (modified); + + if (fail) + { + if (dump_file) + fprintf (dump_file, "Doloop: doloop pattern clobbers live out\n"); + return false; + } + } + doloop_modify (loop, desc, doloop_seq, condition, count); return true; } @@ -717,11 +760,20 @@ doloop_optimize_loops (void) { struct loop *loop; + if (optimize == 1) + { + df_live_add_problem (); + df_live_set_all_dirty (); + } + FOR_EACH_LOOP (loop, 0) { doloop_optimize (loop); } + if (optimize == 1) + df_remove_problem (df_live); + iv_analysis_done (); checking_verify_loop_structure (); -- 2.7.4