Cleanup dead-code.rkt

original commit: 1f022efb352f9e0d72af00d6672140ac7068a361
This commit is contained in:
Eric Dobson 2013-08-30 08:57:47 -07:00
parent 75f8759f36
commit b281083d13
2 changed files with 48 additions and 61 deletions

View File

@ -1,7 +1,7 @@
#lang racket/base
(require syntax/parse syntax/stx
(for-template racket/base racket/flonum racket/fixnum)
(require syntax/parse racket/promise syntax/stx unstable/sequence
(for-template racket/base)
"../utils/utils.rkt"
(types type-table)
(utils tc-utils)
@ -9,65 +9,53 @@
(provide dead-code-opt-expr)
(define-syntax-class predicate
#:literals (flvector? fxvector? exact-integer? fixnum? flonum? vector? string? bytes?)
[pattern (~and x:id (~or flvector? fxvector? exact-integer? fixnum? flonum? vector? string? bytes?))])
;; The type based 'dead code elimination' done by this file just makes the dead code obvious.
;; The actual elimination step is left to the compiler.
(define (pure? stx)
(syntax-parse stx
#:literals (#%plain-app)
[(#%plain-app f:predicate x:id)
#:when (eq? 'lexical (identifier-binding #'x))
(add-disappeared-use #'f)
(add-disappeared-use #'x)
#true]
[else #false]))
(define (optimize/drop-pure stx)
(cond [(pure? stx)
(log-optimization "useless pure code"
"Unreachable pure code elimination."
stx)
(syntax/loc stx (void))]
[else ((optimize) stx)]))
;; if the conditional has a known truth value, we can reveal this
;; we have to keep the test, in case it has side effects
(define-syntax-class tautology
#:attributes (opt)
(pattern e:opt-expr
#:when (tautology? #'e)
#:attr opt (delay #'(begin e.opt #t))))
(define-syntax-class contradiction
#:attributes (opt)
(pattern e:opt-expr
#:when (contradiction? #'e)
#:attr opt (delay #'(begin e.opt #f))))
(define-syntax-class dead-code-opt-expr
#:commit
;; if one of the brances of an if is unreachable, we can eliminate it
;; we have to keep the test, in case it has side effects
(pattern ((~and kw (~literal if)) tst:expr thn:expr els:expr)
#:when (tautology? #'tst)
#:with opt
(begin (log-optimization "dead else branch"
"Unreachable else branch elimination."
#'els)
(quasisyntax/loc/origin
this-syntax #'kw
(#%expression (begin #,(optimize/drop-pure #'tst)
#,((optimize) #'thn))))))
(pattern ((~and kw (~literal if)) tst:expr thn:expr els:expr)
#:when (contradiction? #'tst)
#:with opt
(begin (log-optimization "dead then branch"
"Unreachable then branch elimination."
#'thn)
(quasisyntax/loc/origin
this-syntax #'kw
(#%expression (begin #,(optimize/drop-pure #'tst)
#,((optimize) #'els))))))
(pattern ((~and kw (~literal case-lambda)) (formals . bodies) ...)
#:when (for/or ((formals (syntax->list #'(formals ...))))
(dead-case-lambda-branch? formals))
#:with opt
(quasisyntax/loc/origin
this-syntax #'kw
(case-lambda
#,@(for/list ((formals (syntax->list #'(formals ...)))
(bodies (syntax->list #'(bodies ...)))
#:unless (and (dead-case-lambda-branch? formals)
(log-optimization
"dead case-lambda branch"
"Unreachable case-lambda branch elimination."
formals)))
(cons formals (stx-map (optimize) bodies)))))))
#:literal-sets (kernel-literals)
(pattern ((~and kw if) tst:tautology thn:opt-expr els:expr)
#:do [(log-optimization "dead else branch" "Unreachable else branch elimination." #'els)]
#:with opt (syntax/loc/origin this-syntax #'kw (if tst.opt thn.opt els)))
(pattern ((~and kw if) tst:contradiction thn:expr els:opt-expr)
#:do [(log-optimization "dead then branch" "Unreachable then branch elimination." #'thn)]
#:with opt (syntax/loc/origin this-syntax #'kw (if tst.opt thn els.opt)))
(pattern ((~and kw case-lambda) (formals . bodies) ...)
#:when (for/or ((formals (in-syntax #'(formals ...))))
(dead-case-lambda-branch? formals))
#:with opt
(quasisyntax/loc/origin
this-syntax #'kw
(begin0
(case-lambda
#,@(for/list ((formals (in-syntax #'(formals ...)))
(bodies (in-syntax #'(bodies ...)))
#:unless (dead-case-lambda-branch? formals))
(cons formals (stx-map (optimize) bodies))))
;; We need to keep the syntax objects around in the generated code with the correct bindings
;; so that CheckSyntax displays the arrows correctly
#,@(for/list ((formals (in-syntax #'(formals ...)))
(bodies (in-syntax #'(bodies ...)))
#:when (dead-case-lambda-branch? formals))
(log-optimization
"dead case-lambda branch"
"Unreachable case-lambda branch elimination."
formals)
#`(λ #,formals . #,bodies))))))

View File

@ -1,7 +1,6 @@
#;#;
#<<END
TR opt: drop-pure-pred.rkt 16:6 (exact-integer? x) -- useless pure code
TR opt: drop-pure-pred.rkt 18:6 (list 2) -- dead else branch
TR opt: drop-pure-pred.rkt 17:6 (list 2) -- dead else branch
END
#<<END
'(1)