From f9adcdecb2035ff8eb1b55428a1392b7d90503cc Mon Sep 17 00:00:00 2001 From: Paul Koning Date: Thu, 12 Jul 2018 15:02:57 -0400 Subject: [PATCH] rtl.texi (REG_NONNEG): Remove decrement and branch until zero reference, add doloop_end instead. * doc/rtl.texi (REG_NONNEG): Remove decrement and branch until zero reference, add doloop_end instead. * doc/md.texi (decrement_and_branch_until_zero): Remove. (Looping patterns): Remove decrement_and_branch_until_zero. Add detail for doloop_end. From-SVN: r262603 --- gcc/ChangeLog | 8 +++ gcc/doc/md.texi | 140 +++++++++++++++++++++-------------------------- gcc/doc/rtl.texi | 8 +-- 3 files changed, 74 insertions(+), 82 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7e24d18175a..3bc1f902ccb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-07-12 Paul Koning + + * doc/rtl.texi (REG_NONNEG): Remove decrement and branch until + zero reference, add doloop_end instead. + * doc/md.texi (decrement_and_branch_until_zero): Remove. + (Looping patterns): Remove decrement_and_branch_until_zero. Add + detail for doloop_end. + 2018-07-12 Martin Sebor PR c/86453 diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index b4f4a9a9622..734bc765387 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -6698,17 +6698,6 @@ second operand, but you should incorporate it in the RTL pattern so that the jump optimizer will not delete the table as unreachable code. -@cindex @code{decrement_and_branch_until_zero} instruction pattern -@item @samp{decrement_and_branch_until_zero} -Conditional branch instruction that decrements a register and -jumps if the register is nonzero. Operand 0 is the register to -decrement and test; operand 1 is the label to jump to if the -register is nonzero. @xref{Looping Patterns}. - -This optional instruction pattern is only used by the combiner, -typically for loops reversed by the loop optimizer when strength -reduction is enabled. - @cindex @code{doloop_end} instruction pattern @item @samp{doloop_end} Conditional branch instruction that decrements a register and @@ -7532,66 +7521,11 @@ iterations. This avoids the need for fetching and executing a @samp{dbra}-like instruction and avoids pipeline stalls associated with the jump. -GCC has three special named patterns to support low overhead looping. -They are @samp{decrement_and_branch_until_zero}, @samp{doloop_begin}, -and @samp{doloop_end}. The first pattern, -@samp{decrement_and_branch_until_zero}, is not emitted during RTL -generation but may be emitted during the instruction combination phase. -This requires the assistance of the loop optimizer, using information -collected during strength reduction, to reverse a loop to count down to -zero. Some targets also require the loop optimizer to add a -@code{REG_NONNEG} note to indicate that the iteration count is always -positive. This is needed if the target performs a signed loop -termination test. For example, the 68000 uses a pattern similar to the -following for its @code{dbra} instruction: - -@smallexample -@group -(define_insn "decrement_and_branch_until_zero" - [(set (pc) - (if_then_else - (ge (plus:SI (match_operand:SI 0 "general_operand" "+d*am") - (const_int -1)) - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (const_int -1)))] - "find_reg_note (insn, REG_NONNEG, 0)" - "@dots{}") -@end group -@end smallexample - -Note that since the insn is both a jump insn and has an output, it must -deal with its own reloads, hence the `m' constraints. Also note that -since this insn is generated by the instruction combination phase -combining two sequential insns together into an implicit parallel insn, -the iteration counter needs to be biased by the same amount as the -decrement operation, in this case @minus{}1. Note that the following similar -pattern will not be matched by the combiner. - -@smallexample -@group -(define_insn "decrement_and_branch_until_zero" - [(set (pc) - (if_then_else - (ge (match_operand:SI 0 "general_operand" "+d*am") - (const_int 1)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (const_int -1)))] - "find_reg_note (insn, REG_NONNEG, 0)" - "@dots{}") -@end group -@end smallexample - -The other two special looping patterns, @samp{doloop_begin} and -@samp{doloop_end}, are emitted by the loop optimizer for certain -well-behaved loops with a finite number of loop iterations using -information collected during strength reduction. +GCC has two special named patterns to support low overhead looping. +They are @samp{doloop_begin} and @samp{doloop_end}. These are emitted +by the loop optimizer for certain well-behaved loops with a finite +number of loop iterations using information collected during strength +reduction. The @samp{doloop_end} pattern describes the actual looping instruction (or the implicit looping operation) and the @samp{doloop_begin} pattern @@ -7611,14 +7545,64 @@ desired special iteration counter register was not allocated, this machine dependent reorg pass could emit a traditional compare and jump instruction pair. -The essential difference between the -@samp{decrement_and_branch_until_zero} and the @samp{doloop_end} -patterns is that the loop optimizer allocates an additional pseudo -register for the latter as an iteration counter. This pseudo register -cannot be used within the loop (i.e., general induction variables cannot -be derived from it), however, in many cases the loop induction variable -may become redundant and removed by the flow pass. +For the @samp{doloop_end} pattern, the loop optimizer allocates an +additional pseudo register as an iteration counter. This pseudo +register cannot be used within the loop (i.e., general induction +variables cannot be derived from it), however, in many cases the loop +induction variable may become redundant and removed by the flow pass. + +The @samp{doloop_end} pattern must have a specific structure to be +handled correctly by GCC. The example below is taken (slightly +simplified) from the PDP-11 target: + +@smallexample +@group +(define_insn "doloop_end" + [(set (pc) + (if_then_else + (ne (match_operand:HI 0 "nonimmediate_operand" "+r,!m") + (const_int 1)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:HI (match_dup 0) + (const_int -1)))] + "" + + @{ + if (which_alternative == 0) + return "sob %0,%l1"; + + /* emulate sob */ + output_asm_insn ("dec %0", operands); + return "bne %l1"; + @}) +@end group +@end smallexample + +The first part of the pattern describes the branch condition. GCC +supports three cases for the way the target machine handles the loop +counter: +@itemize @bullet +@item Loop terminates when the loop register decrements to zero. This +is represented by a @code{ne} comparison of the register (its old value) +with constant 1 (as in the example above). +@item Loop terminates when the loop register decrements to @minus{}1. +This is represented by a @code{ne} comparison of the register with +constant zero. +@item Loop terminates when the loop register decrements to a negative +value. This is represented by a @code{ge} comparison of the register +with constant zero. For this case, GCC will attach a @code{REG_NONNEG} +note to the @code{doloop_end} insn if it can determine that the register +will be non-negative. +@end itemize +Since the @code{doloop_end} insn is a jump insn that also has an output, +the reload pass does not handle the output operand. Therefore, the +constraint must allow for that operand to be in memory rather than a +register. In the example shown above, that is handled by using a loop +instruction sequence that can handle memory operands when the memory +alternative appears. @end ifset @ifset INTERNALS diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index b5410f9689d..a37d9ac5389 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -4151,11 +4151,11 @@ This means it appears in a @code{post_inc}, @code{pre_inc}, @findex REG_NONNEG @item REG_NONNEG The register @var{op} is known to have a nonnegative value when this -insn is reached. This is used so that decrement and branch until zero -instructions, such as the m68k dbra, can be matched. +insn is reached. This is used by special looping instructions +that terminate when the register goes negative. -The @code{REG_NONNEG} note is added to insns only if the machine -description has a @samp{decrement_and_branch_until_zero} pattern. +The @code{REG_NONNEG} note is added only to @samp{doloop_end} +insns, if its pattern uses a @code{ge} condition. @findex REG_LABEL_OPERAND @item REG_LABEL_OPERAND -- 2.30.2