From f8b3ba8253b2b94e5f0b060bc256f651ba73dd48 Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Thu, 30 Jun 2016 00:37:20 -0300 Subject: [PATCH] optimizer: reduce ignored `if`s The optimizer tries to reduce the `if` assuming that the result will be used. In case it later detects that the result will be ignored, it can try to apply some additional reductions to the branches and to the whole expression. --- .../tests/racket/optimize.rktl | 20 +++++++++++++++++++ racket/src/racket/src/optimize.c | 19 ++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 8d938e8cf2..f39f5982b6 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -1956,6 +1956,26 @@ (test-comp '(lambda (x) (not (if (null? x) #t x))) '(lambda (x) (not x))) +;reduce ignored `if`s +(test-comp '(lambda (x) (void (if x 1 2))) + '(lambda (x) (void))) +(test-comp '(lambda (f) (void (if (f) 1 2))) + '(lambda (f) (void (values (f))))) +(test-comp '(lambda () (void (if (eq? (random 2) 0) 1 2))) + '(lambda () (void (random 2)))) +(test-comp '(lambda (x) (void (if (eq? (random 2) 0) (box x) (list x)))) + '(lambda (x) (void (random 2)))) +(test-comp '(lambda (x) (void (if x (random) 1))) + '(lambda (x) (void (if x (random) 2)))) +(test-comp '(lambda (x) (void (if x 1 (random)))) + '(lambda (x) (void (if x 2 (random))))) +(test-comp '(lambda (x) (void (if x (random) 1))) + '(lambda (x) (void)) + #f) +(test-comp '(lambda (x) (void (if x 1 (random)))) + '(lambda (x) (void)) + #f) + (test-comp '(lambda (x) (let ([n (list 1)]) (list n n (not (if x #t n))))) '(lambda (x) (let ([n (list 1)]) diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index 72591770d2..5635fdc548 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -808,6 +808,25 @@ static Scheme_Object *optimize_ignored(Scheme_Object *e, Optimize_Info *info, return make_discarding_app_sequence(app, -1, NULL, info); } break; + case scheme_branch_type: + { + Scheme_Branch_Rec *b = (Scheme_Branch_Rec *)e; + Scheme_Object *tb, *fb; + + tb = optimize_ignored(b->tbranch, info, expected_vals, 1, fuel - 1); + fb = optimize_ignored(b->fbranch, info, expected_vals, 1, fuel - 1); + + if (tb || fb) { + b->tbranch = tb ? tb : scheme_false; + b->fbranch = fb ? fb : scheme_false; + return (Scheme_Object*)b; + } else { + Scheme_Object *val; + val = ensure_single_value(b->test); + return optimize_ignored(val, info, 1, maybe_omittable, 5); + } + } + break; } }