Skip to content

Commit

Permalink
remove unnecessary Box when an argument is used before assigned (Juli…
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson authored Jun 12, 2020
1 parent abc7f75 commit 70fe622
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/ast.scm
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@
(symbol? (cadr e))))

(define (lam:args x) (cadr x))
(define (lam:vars x) (llist-vars (lam:args x)))
(define (lam:argnames x) (llist-vars (lam:args x)))
(define (lam:vinfo x) (caddr x))
(define (lam:body x) (cadddr x))
(define (lam:sp x) (cadddr (lam:vinfo x)))
Expand Down
18 changes: 12 additions & 6 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -2556,7 +2556,7 @@
(and (memq var (scope:locals scope)) 'local)
(and (memq var (scope:globals scope))
(if (and exclude-top-level-globals
(null? (lam:vars (scope:lam scope)))
(null? (lam:args (scope:lam scope)))
;; don't inherit global decls from the outermost scope block
;; in a top-level expression.
(or (not (scope:prev scope))
Expand Down Expand Up @@ -2636,13 +2636,13 @@
'(false)
'(true)))
((eq? (car e) 'lambda)
(let* ((args (lam:vars e))
(let* ((args (lam:argnames e))
(body (resolve-scopes- (lam:body e) (make-scope e args '() '() sp '() scope))))
`(lambda ,(cadr e) ,(caddr e) ,body)))
((eq? (car e) 'scope-block)
(let* ((blok (cadr e)) ;; body of scope-block expression
(lam (scope:lam scope))
(argnames (lam:vars lam))
(argnames (lam:argnames lam))
(toplevel? (and (null? argnames) (eq? e (lam:body lam))))
(current-locals (caddr lam)) ;; locals created so far in our lambda
(globals (find-global-decls blok))
Expand Down Expand Up @@ -2755,7 +2755,7 @@
,(resolve-scopes- (cadddr e) scope (method-expr-static-parameters e))))
(else
(if (and (eq? (car e) '=) (symbol? (cadr e))
scope (null? (lam:vars (scope:lam scope)))
scope (null? (lam:args (scope:lam scope)))
(warn-var?! (cadr e) scope)
(= *scopewarn-opt* 1))
(let* ((v (cadr e))
Expand All @@ -2782,7 +2782,7 @@

;; names of arguments and local vars
(define (lambda-all-vars e)
(append (lam:vars e) (caddr e)))
(append (lam:argnames e) (caddr e)))

;; compute set of variables referenced in a lambda but not bound by it
(define (free-vars- e tab)
Expand Down Expand Up @@ -3201,6 +3201,7 @@ f(x) = yt(x)
;; This does a basic-block-local dominance analysis to find variables that
;; are never used undef.
(let ((vi (car (lam:vinfo lam)))
(args (lam:argnames lam))
(unused (table)) ;; variables not (yet) used (read from) in the current block
(live (table)) ;; variables that have been set in the current block
(seen (table))) ;; all variables we've seen assignments to
Expand All @@ -3221,6 +3222,11 @@ f(x) = yt(x)
(restore (table)))
(define (mark-used var)
;; remove variable from the unused table
;; Note arguments are only "used" for purposes of this analysis when
;; they are captured, since they are never undefined.
(if (and (has? unused var) (not (memq var args)))
(del! unused var)))
(define (mark-captured var)
(if (has? unused var)
(del! unused var)))
(define (assign! var)
Expand Down Expand Up @@ -3272,7 +3278,7 @@ f(x) = yt(x)
(get-methods e (lam:body lam))
(list e))))
(for-each (lambda (ex)
(for-each mark-used
(for-each mark-captured
(map car (cadr (lam:vinfo (cadddr ex))))))
all-methods)
(assign! (cadr e))))
Expand Down
6 changes: 6 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5178,6 +5178,12 @@ end
@test let_Box5()() == 46
@test let_noBox()() == 21

function _assigns_and_captures_arg(a)
a = a
return ()->a
end
@test !any(contains_Box, code_lowered(_assigns_and_captures_arg,(Any,))[1].code)

module TestModuleAssignment
using Test
@eval $(GlobalRef(TestModuleAssignment, :x)) = 1
Expand Down

0 comments on commit 70fe622

Please sign in to comment.