summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-04-18 06:18:02 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-04-18 06:18:02 -0700
commit93cbd81f0fb5242bb93062848826bf5b6b5e9d46 (patch)
tree06949b66eba3b6e0667b6ba652e96292b1f677c2 /share
parentbfc81fe0cb680d95ae8fc91ec94562d2df6e12e4 (diff)
downloadtxr-93cbd81f0fb5242bb93062848826bf5b6b5e9d46.tar.gz
txr-93cbd81f0fb5242bb93062848826bf5b6b5e9d46.tar.bz2
txr-93cbd81f0fb5242bb93062848826bf5b6b5e9d46.zip
compiler: de-duplicate switch.
* share/txr/stdlib/compiler.tl (compiler comp-switch): Identify duplicate cases and don't generate code for these; patch their table entries to point to one case. The case macros generate such code when the keys are integers, and multiple integer keys are associated with the same case: (caseq x ((1 2 3 4 5) ...) ((6 7) ...)).
Diffstat (limited to 'share')
-rw-r--r--share/txr/stdlib/compiler.tl29
1 files changed, 18 insertions, 11 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index 8b705835..5d68e0f5 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -480,21 +480,28 @@
(clabels (mapcar (ret (gensym "l")) cases))
(treg me.(maybe-alloc-treg oreg))
(ifrag me.(compile treg env idx-form))
+ (seen (unless shared (hash :eql-based)))
last-cfrag
(cfrags (collect-each ((cs cases)
(lb clabels)
(i (range 1)))
- (let ((cfrag me.(comp-progn oreg env cs)))
- (when (eq i ncases)
- (set last-cfrag cfrag))
- (new (frag oreg
- ^(,lb
- ,*cfrag.code
- ,*(unless shared
- ^(,*(maybe-mov oreg cfrag.oreg)
- ,*(unless (= i ncases)
- ^((jmp ,lend))))))
- cfrag.fvars cfrag.ffuns))))))
+ (iflet ((seen-lb (and seen [seen cs])))
+ (progn
+ (set [clabels (pred i)] seen-lb)
+ (new (frag oreg nil)))
+ (let ((cfrag me.(comp-progn oreg env cs)))
+ (when (eq i ncases)
+ (set last-cfrag cfrag))
+ (unless shared
+ (set [seen cs] lb))
+ (new (frag oreg
+ ^(,lb
+ ,*cfrag.code
+ ,*(unless shared
+ ^(,*(maybe-mov oreg cfrag.oreg)
+ ,*(unless (= i ncases)
+ ^((jmp ,lend))))))
+ cfrag.fvars cfrag.ffuns)))))))
me.(maybe-free-treg treg oreg)
(new (frag oreg
^(,*ifrag.code