extend reductions for expressions like (if (if X Y #f) Z K)

=> (if X (if Y Z K) K) where K is a constant,
to expressions where the inner `if` is (if X Y #t) or (if X #t/#f Y)
This commit is contained in:
Gustavo Massaccesi 2016-11-12 18:07:21 -03:00
parent c3595c56b4
commit 9ebfdb54e7
2 changed files with 42 additions and 14 deletions

View File

@ -2143,7 +2143,13 @@
(let ([test-if-if-reduction
(lambda (dup)
(test-comp `(lambda (x y z) (if (if x y #f) z ,dup))
`(lambda (x y z) (if x (if y z ,dup) ,dup))))])
`(lambda (x y z) (if x (if y z ,dup) ,dup)))
(test-comp `(lambda (x y z) (if (if x #f y) z ,dup))
`(lambda (x y z) (if x ,dup (if y z ,dup))))
(test-comp `(lambda (x y z) (if (if x y #t) ,dup z))
`(lambda (x y z) (if x (if y ,dup z) ,dup)))
(test-comp `(lambda (x y z) (if (if x #t y) ,dup z))
`(lambda (x y z) (if x ,dup (if y ,dup z)))))])
(test-if-if-reduction 1)
(test-if-if-reduction ''x)
(test-if-if-reduction "x")

View File

@ -5720,23 +5720,45 @@ static Scheme_Object *optimize_branch(Scheme_Object *o, Optimize_Info *info, int
return t;
}
/* Convert: (if (if M N #f) M2 K) => (if M (if N M2 K) K)
/* Convert: expressions like
(if (if M N #f) P K) => (if M (if N P K) K)
for simple constants K. This is useful to expose simple
tests to the JIT. */
if (SAME_TYPE(SCHEME_TYPE(t), scheme_branch_type)
&& scheme_ir_duplicate_ok(fb, 0)) {
if (SAME_TYPE(SCHEME_TYPE(t), scheme_branch_type)) {
Scheme_Branch_Rec *b2 = (Scheme_Branch_Rec *)t;
if (SCHEME_FALSEP(b2->fbranch)) {
Scheme_Object *fb3;
Scheme_Branch_Rec *b3;
b3 = MALLOC_ONE_TAGGED(Scheme_Branch_Rec);
b3->so.type = scheme_branch_type;
b3->test = b2->tbranch;
b3->tbranch = tb;
fb3 = optimize_clone(0, fb, info, empty_eq_hash_tree, 0);
b3->fbranch = fb3;
Scheme_Object *ntb, *nfb, *nt2 = NULL;
if (SCHEME_FALSEP(b2->fbranch)
&& scheme_ir_duplicate_ok(fb, 0)) {
/* (if (if M N #f) P K) => (if M (if N P K) K) */
ntb = (Scheme_Object *)b2;
nfb = optimize_clone(0, fb, info, empty_eq_hash_tree, 0);
nt2 = b2->tbranch;
} else if (SCHEME_FALSEP(b2->tbranch)
&& scheme_ir_duplicate_ok(fb, 0)) {
/* (if (if M #f N) P K) => (if M K (if N P K)) */
ntb = optimize_clone(0, fb, info, empty_eq_hash_tree, 0);
nfb = (Scheme_Object *)b2;
nt2 = b2->fbranch;
} else if (SAME_OBJ(b2->fbranch, scheme_true)
&& scheme_ir_duplicate_ok(tb, 0)) {
/* (if (if M N #t) K P) => (if M (if N K P) K) */
ntb = (Scheme_Object *)b2;
nfb = optimize_clone(0, tb, info, empty_eq_hash_tree, 0);
nt2 = b2->tbranch;
} else if (SAME_OBJ(b2->tbranch, scheme_true)
&& scheme_ir_duplicate_ok(tb, 0)) {
/* (if (if M #t N) K P) => (if M K (if N K P)) */
ntb = optimize_clone(0, tb, info, empty_eq_hash_tree, 0);
nfb = (Scheme_Object *)b2;
nt2 = b2->fbranch;
}
if (nt2) {
t = b2->test;
tb = (Scheme_Object *)b3;
b2->test = nt2;
b2->tbranch = tb;
b2->fbranch = fb;
tb = ntb;
fb = nfb;
}
}