From: rth Date: Thu, 14 Jan 2016 23:12:53 +0000 (+0000) Subject: PR rtl-opt/69014 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a3fb1e280d77bd4d7a047646e43a66947c4f0fda;p=thirdparty%2Fgcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232395 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f5ba8f02fc86..790662511d1b 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 157de494ac0a..940c966dc5a8 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 ();