From 14d0a7debc41c1d74b638328ba8aaef5470f9173 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 13 Mar 2014 01:13:02 -0400 Subject: [PATCH] compile simple loop conditions twice for a more efficient branch structure I didn't think this would matter, but it actually makes a big difference to LLVM. fixes #5469 with this, I believe no changes to Range1 are needed for performance. --- src/julia-syntax.scm | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 4691dc6811a50..fca5717b4ba73 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -2914,13 +2914,28 @@ So far only the second case can actually occur. (set-car! (cdr end-jump) (make&mark-label))))) ((block) (for-each (lambda (x) (compile x break-labels vi)) (cdr e))) - ((_while) (let ((topl (make&mark-label)) - (endl (make-label))) - (compile (cadr e) break-labels vi) - (emit `(gotoifnot ,(goto-form (caddr e)) ,endl)) - (compile (cadddr e) break-labels vi) - (emit `(goto ,topl)) - (mark-label endl))) + ((_while) + (let ((test-blk (cadr e)) + (endl (make-label))) + (if (or (atom? test-blk) (equal? test-blk '(block))) + ;; if condition is simple, compile it twice in order + ;; to generate a single branch per iteration. + (let ((topl (make-label))) + (compile test-blk break-labels vi) + (emit `(gotoifnot ,(goto-form (caddr e)) ,endl)) + (mark-label topl) + (compile (cadddr e) break-labels vi) + (compile test-blk break-labels vi) + (emit `(gotoifnot (call (top !) ,(goto-form (caddr e))) ,topl)) + (mark-label endl)) + + (let ((topl (make&mark-label))) + (compile test-blk break-labels vi) + (emit `(gotoifnot ,(goto-form (caddr e)) ,endl)) + (compile (cadddr e) break-labels vi) + (emit `(goto ,topl)) + (mark-label endl))))) + ((break-block) (let ((endl (make-label))) (compile (caddr e) (cons (list (cadr e) endl handler-level)