diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-03-02 07:07:08 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-03-02 07:07:08 -0800 |
commit | 82c19e330fef2a9ef4055923fdbb9cd6764043b3 (patch) | |
tree | 1b4dc8e1fbc1da0ab684579d6fdf3fbc60358940 | |
parent | 3ccb0bd9c12fdd0da89262b8d96f00df9c950c2a (diff) | |
download | txr-82c19e330fef2a9ef4055923fdbb9cd6764043b3.tar.gz txr-82c19e330fef2a9ef4055923fdbb9cd6764043b3.tar.bz2 txr-82c19e330fef2a9ef4055923fdbb9cd6764043b3.zip |
compiler: join blocks after dead code elimination.
After eliminating dead code and useless forward jumps, there
can be blocks which unconditionally proceed to subsequent
blocks, which have no other predecessor. These blocks can be
merged together. This currently does nothing to alter the
generated code. The advantage will be obvious in a subsequent
commit.
* share/txr/stdlib/optimize.tl (struct basic-block): New slot,
rlinks: reverse links.
(basic-blocks join-block): New method.
(basic-blocks link-graph): Populate rlinks slots.
(basic-blocks join-blocks): New method.
(basic-blocks elim-dead-code): Reset rlinks also before
re-calculating the graph connectivity with link-graph.
Call join-blocks to merge together consecutive blocks.
-rw-r--r-- | share/txr/stdlib/optimize.tl | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/share/txr/stdlib/optimize.tl b/share/txr/stdlib/optimize.tl index 4ef549b6..e4a6e225 100644 --- a/share/txr/stdlib/optimize.tl +++ b/share/txr/stdlib/optimize.tl @@ -35,6 +35,7 @@ label next links + rlinks insns) (defstruct (basic-blocks insns lt-dregs) nil @@ -84,7 +85,16 @@ (:method next-block (bb bl) (let ((ltail (memq bl bb.list))) (iflet ((next (cdr ltail))) - (car next)))))) + (car next)))) + + (:method join-block (bb bl nxbl) + (when (eql (car nxbl.insns) nxbl.label) + (pop nxbl.insns)) + (set bl.insns (append bl.insns nxbl.insns)) + (set bl.next nxbl.next) + (set bl.links nxbl.links) + (set bb.list (remq nxbl bb.list)) + (del [bb.hash nxbl.label])))) (defmacro rewrite-case (sym list . cases) ^(rewrite (lambda (,sym) @@ -124,7 +134,9 @@ ((@(or abscsr ret jend) . @nil) (set bl.next nil))) (if (and bl.next link-next) - (pushnew bl.next bl.links))))) + (pushnew bl.next bl.links)) + (each ((nxbl bl.links)) + (pushnew bl nxbl.rlinks))))) (defmeth basic-blocks local-liveness (bb bl) (labels ((regnum (reg) @@ -395,9 +407,25 @@ (when (eql nxbl.?label jlabel) (set bl.insns (butlast bl.insns))))))) +(defmeth basic-blocks join-blocks (bb) + (labels ((join (list) + (tree-case list + ((bl nxbl . rest) + (cond + ((and (eq bl.next nxbl) + (eq (car bl.links) nxbl) + (null (cdr bl.links)) + (null (cdr nxbl.rlinks))) + bb.(join-block bl nxbl) + (join (cons bl rest))) + (t (cons bl (join (cdr list)))))) + (else else)))) + (set bb.list (join bb.list)))) + (defmeth basic-blocks elim-dead-code (bb) (each ((bl bb.list)) - (set bl.links nil)) + (set bl.links nil) + (set bl.rlinks nil)) bb.(link-graph) (let* ((visited (hash :eq-based)) (reachable (build @@ -413,7 +441,8 @@ (visit bb.root))))) (set bb.list [keep-if visited bb.list]) (each ((bl bb.list)) - bb.(elim-next-jump bl)))) + bb.(elim-next-jump bl))) + bb.(join-blocks)) (defun rewrite (fun list) (build |