summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--stdlib/compiler.tl69
1 files changed, 49 insertions, 20 deletions
diff --git a/stdlib/compiler.tl b/stdlib/compiler.tl
index f3c27153..7ad727e0 100644
--- a/stdlib/compiler.tl
+++ b/stdlib/compiler.tl
@@ -56,6 +56,8 @@
(defstruct blockinfo nil
sym
+ label
+ oreg
used
sys:env)
@@ -103,13 +105,10 @@
(((up me.up)) up.(lookup-lisp1 sym mark-used))
(t nil)))
- (:method lookup-block (me sym : mark-used)
+ (:method lookup-block (me sym)
(condlet
- (((cell (assoc sym me.bb)))
- (let ((bi (cdr cell)))
- (if mark-used (set bi.used t))
- bi))
- (((up me.up)) up.(lookup-block sym mark-used))
+ (((cell (assoc sym me.bb))) (cdr cell))
+ (((up me.up)) up.(lookup-block sym))
(t nil)))
(:method get-loc (me)
@@ -166,8 +165,8 @@
(let ((lev (ssucc (cadr reg))))
(< me.lev lev))))
- (:method extend-block (me sym)
- (let* ((bn (new blockinfo sym sym env me)))
+ (:method extend-block (me sym label oreg)
+ (let* ((bn (new blockinfo sym sym label label oreg oreg env me)))
(set me.bb (acons sym bn me.bb))))
(:method unused-check (me form nuance)
@@ -231,6 +230,7 @@
closure-spies
access-spies
tjmp-occurs
+ bjmp-occurs
(:method snapshot (me)
(let ((snap (copy me)))
@@ -835,14 +835,16 @@
(let* ((star (and name (eq op 'block*)))
(nenv (unless star
(new env up env lev env.lev co me)))
+ (lskip (gensym "l"))
(binfo (unless star
- (cdar nenv.(extend-block name))))
+ (cdar nenv.(extend-block name lskip oreg))))
(treg (if star me.(maybe-alloc-treg oreg)))
(nfrag (if star (ntp me.(compile treg env name))))
(nreg (if star nfrag.oreg me.(get-dreg name)))
- (*esc-blocks* (cons name *esc-blocks*))
- (bfrag me.(comp-progn oreg (or nenv env) body))
- (lskip (gensym "l")))
+ (*esc-blocks* (if star
+ *esc-blocks*
+ (cons name *esc-blocks*)))
+ (bfrag me.(comp-progn oreg (or nenv env) body)))
(when treg
me.(maybe-free-treg treg oreg))
(if (and (>= *opt-level* 2)
@@ -852,7 +854,11 @@
[all bfrag.ffuns [orf system-symbol-p (op eq name)]]
[all bfrag.ffuns system-symbol-p])
[none bfrag.ffuns (op member @1 %block-using-funs%)])
- bfrag
+ (set bfrag.code (append bfrag.code
+ ^(,*(maybe-mov oreg bfrag.oreg)
+ ,lskip))
+ bfrag.oreg oreg
+ bfrag bfrag)
(new (frag oreg
^(,*(if nfrag nfrag.code)
(block ,oreg ,nreg ,lskip)
@@ -871,11 +877,19 @@
nil
me.(get-dreg name)))
(opcode (if (eq op 'return-from) 'ret 'abscsr))
- (vfrag me.(compile oreg env value)))
- env.(lookup-block name t)
+ (vfrag me.(compile oreg env value))
+ (binfo env.(lookup-block name)))
(new (frag oreg
- ^(,*vfrag.code
- (,opcode ,nreg ,vfrag.oreg))
+ (cond
+ ((member name *esc-blocks*)
+ (set me.bjmp-occurs t)
+ ^(,*vfrag.code
+ ,*(maybe-mov binfo.oreg vfrag.oreg)
+ (bjmp ,binfo.label)))
+ (t (if binfo
+ (set binfo.used t))
+ ^(,*vfrag.code
+ (,opcode ,nreg ,vfrag.oreg))))
vfrag.fvars
vfrag.ffuns)))))
@@ -1873,7 +1887,7 @@
@1))]
insns)))
-(defun convert-tjmps (insns)
+(defun convert-t-b-jmps (insns)
(build
(while-true-match-case insns
(((tjmp @top) . @rest)
@@ -1891,11 +1905,26 @@
((zerop bal) (add (pop rest)))
(t (dec bal) (pop rest))))
(@nil (pop rest)))))
+ (((bjmp @bskip) . @rest)
+ (let ((bal 0))
+ (while-true-match-case rest
+ ((@bskip . @nil)
+ (add ^(jmp ,bskip))
+ (pop insns)
+ (return))
+ (((@(or frame dframe block handle catch uwprot) . @nil) . @nil)
+ (inc bal)
+ (pop rest))
+ (((end . @nil) . @nil)
+ (cond
+ ((zerop bal) (add (pop rest)))
+ (t (dec bal) (pop rest))))
+ (@nil (pop rest)))))
(@nil (add (pop insns))))))
(defmeth compiler optimize (me insns)
- (when me.tjmp-occurs
- (set insns (convert-tjmps insns)))
+ (when (or me.tjmp-occurs me.bjmp-occurs)
+ (set insns (convert-t-b-jmps insns)))
(let ((olev *opt-level*))
(if (>= olev 4)
(let* ((lt-dregs (mapcar .oreg me.lt-frags))