X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fcontrol.lisp;h=3c4a3ff56fee7972fb6203e356a011edf58990c4;hb=12b1dae1a1ed90c6ffe4d958f1281c1c04a8e89b;hp=6d3b5f545bf72a7c1783c8c9a97cad333c347476;hpb=c2431e2d0d0222a3cf20cfdfa48201bdcc65cd76;p=sbcl.git diff --git a/src/compiler/control.lisp b/src/compiler/control.lisp index 6d3b5f5..3c4a3ff 100644 --- a/src/compiler/control.lisp +++ b/src/compiler/control.lisp @@ -47,6 +47,22 @@ ;;; suppress rotation of loop heads which are the start of a function ;;; (i.e. tail calls), as the debugger wants functions to start at the ;;; start. +;;; +;;; The rotation also is not done if the back edge identified in the +;;; first step originates from a block that has more than one successor. +;;; This matches loops that have their terminating condition tested at +;;; the end, for which the original block order already minimizes the +;;; number of branches: the back edge starts at a conditional branch at +;;; the loop's tail and no other branches are needed. We used not to +;;; test for this situation, rotating these loops, too, resulting in +;;; machine code that looked like this +;;; jump to L1 +;;; L0: body of loop +;;; conditionally branch to L2 if the loop should terminate +;;; L1: jump to L0 +;;; L2: +;;; which is ugly, and larger and often slower than what is generated +;;; when not rotating these loops. (defun find-rotated-loop-head (block) (declare (type cblock block)) (let* ((num (block-number block)) @@ -59,7 +75,8 @@ (cond ((and pred (not (physenv-nlx-info env)) - (not (eq (lambda-block (block-home-lambda block)) block))) + (not (eq (lambda-block (block-home-lambda block)) block)) + (null (cdr (block-succ pred)))) (let ((current pred) (current-num (block-number pred))) (block DONE