rtl.texi (REG_NONNEG): Remove decrement and branch until zero reference, add doloop_e...
authorPaul Koning <ni1d@arrl.net>
Thu, 12 Jul 2018 19:02:57 +0000 (15:02 -0400)
committerPaul Koning <pkoning@gcc.gnu.org>
Thu, 12 Jul 2018 19:02:57 +0000 (15:02 -0400)
* 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
gcc/doc/md.texi
gcc/doc/rtl.texi

index 7e24d18175ac7e47bfa6defe3b032c57a3501160..3bc1f902ccb655372447fe98283616d2f4bbfc9e 100644 (file)
@@ -1,3 +1,11 @@
+2018-07-12  Paul Koning  <ni1d@arrl.net>
+
+       * 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  <msebor@redhat.com>
 
        PR c/86453
index b4f4a9a96229a7b367a85e3e707c94651b9cb6bc..734bc7653872b1e6d1ebf5d59139bca347ef503c 100644 (file)
@@ -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
index b5410f9689d7e966903d16ec869ad9b3c6378c28..a37d9ac538991c507985bda4f825023534321b76 100644 (file)
@@ -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