generalizing the optimization
This commit is contained in:
parent
074be88089
commit
ad71a72121
432
compile.rkt
432
compile.rkt
|
@ -264,23 +264,23 @@
|
||||||
(let: ([t-branch : LabelLinkage (make-LabelLinkage (make-label 'trueBranch))]
|
(let: ([t-branch : LabelLinkage (make-LabelLinkage (make-label 'trueBranch))]
|
||||||
[f-branch : LabelLinkage (make-LabelLinkage (make-label 'falseBranch))]
|
[f-branch : LabelLinkage (make-LabelLinkage (make-label 'falseBranch))]
|
||||||
[after-if : LabelLinkage (make-LabelLinkage (make-label 'afterIf))])
|
[after-if : LabelLinkage (make-LabelLinkage (make-label 'afterIf))])
|
||||||
(let ([consequent-linkage
|
(let ([consequent-linkage
|
||||||
(if (eq? linkage next-linkage)
|
(if (eq? linkage next-linkage)
|
||||||
after-if
|
after-if
|
||||||
linkage)])
|
linkage)])
|
||||||
(let ([p-code (compile (Branch-predicate exp) cenv 'val next-linkage)]
|
(let ([p-code (compile (Branch-predicate exp) cenv 'val next-linkage)]
|
||||||
[c-code (compile (Branch-consequent exp) cenv target consequent-linkage)]
|
[c-code (compile (Branch-consequent exp) cenv target consequent-linkage)]
|
||||||
[a-code (compile (Branch-alternative exp) cenv target linkage)])
|
[a-code (compile (Branch-alternative exp) cenv target linkage)])
|
||||||
(append-instruction-sequences p-code
|
(append-instruction-sequences p-code
|
||||||
(append-instruction-sequences
|
(append-instruction-sequences
|
||||||
(make-instruction-sequence
|
(make-instruction-sequence
|
||||||
`(,(make-TestAndBranchStatement 'false?
|
`(,(make-TestAndBranchStatement 'false?
|
||||||
'val
|
'val
|
||||||
(LabelLinkage-label f-branch))))
|
(LabelLinkage-label f-branch))))
|
||||||
(append-instruction-sequences
|
(append-instruction-sequences
|
||||||
(append-instruction-sequences (LabelLinkage-label t-branch) c-code)
|
(append-instruction-sequences (LabelLinkage-label t-branch) c-code)
|
||||||
(append-instruction-sequences (LabelLinkage-label f-branch) a-code))
|
(append-instruction-sequences (LabelLinkage-label f-branch) a-code))
|
||||||
(LabelLinkage-label after-if)))))))
|
(LabelLinkage-label after-if)))))))
|
||||||
|
|
||||||
|
|
||||||
(: compile-sequence ((Listof Expression) CompileTimeEnvironment Target Linkage -> InstructionSequence))
|
(: compile-sequence ((Listof Expression) CompileTimeEnvironment Target Linkage -> InstructionSequence))
|
||||||
|
@ -363,7 +363,7 @@
|
||||||
(append (build-list n (lambda: ([i : Natural])
|
(append (build-list n (lambda: ([i : Natural])
|
||||||
'?))
|
'?))
|
||||||
cenv))
|
cenv))
|
||||||
|
|
||||||
(: compile-application (App CompileTimeEnvironment Target Linkage -> InstructionSequence))
|
(: compile-application (App CompileTimeEnvironment Target Linkage -> InstructionSequence))
|
||||||
;; Compiles procedure application
|
;; Compiles procedure application
|
||||||
;; Special cases: if we know something about the operator, the compiler will special case.
|
;; Special cases: if we know something about the operator, the compiler will special case.
|
||||||
|
@ -376,7 +376,7 @@
|
||||||
(extend-compile-time-environment/scratch-space
|
(extend-compile-time-environment/scratch-space
|
||||||
cenv
|
cenv
|
||||||
(length (App-operands exp)))])
|
(length (App-operands exp)))])
|
||||||
|
|
||||||
(define (default)
|
(define (default)
|
||||||
(compile-general-application exp cenv target linkage))
|
(compile-general-application exp cenv target linkage))
|
||||||
|
|
||||||
|
@ -446,114 +446,161 @@
|
||||||
(KernelPrimitiveName App CompileTimeEnvironment Target Linkage -> InstructionSequence))
|
(KernelPrimitiveName App CompileTimeEnvironment Target Linkage -> InstructionSequence))
|
||||||
;; This is a special case of application, where the operator is statically
|
;; This is a special case of application, where the operator is statically
|
||||||
;; known to be in the set of hardcoded primitives.
|
;; known to be in the set of hardcoded primitives.
|
||||||
|
;;
|
||||||
|
;; There's a special case optimization we can perform: we can avoid touching
|
||||||
|
;; the stack for constant arguments; rather than allocate (length (App-operands exp))
|
||||||
|
;; stack slots, we can do less than that.
|
||||||
|
;;
|
||||||
|
;; We have to be sensitive to mutation.
|
||||||
(define (compile-kernel-primitive-application kernel-op exp cenv target linkage)
|
(define (compile-kernel-primitive-application kernel-op exp cenv target linkage)
|
||||||
(let*-values ([(n)
|
(cond
|
||||||
(length (App-operands exp))]
|
;; If all the arguments are primitive enough (all constants, localrefs, or toplevelrefs),
|
||||||
|
;; then application requires no stack space at all, and application is especially simple.
|
||||||
[(expected-operand-types)
|
[(andmap (lambda (op)
|
||||||
(kernel-primitive-expected-operand-types kernel-op n)]
|
;; TODO: as long as the operand contains no applications?
|
||||||
|
(or (Constant? op)
|
||||||
[(constant-operands rest-operands)
|
(ToplevelRef? op)
|
||||||
(split-operands-by-constant-or-stack-references (App-operands exp))]
|
(LocalRef? op)))
|
||||||
|
(App-operands exp))
|
||||||
;; here, we rewrite the stack references so they assume no scratch space
|
(let* ([n (length (App-operands exp))]
|
||||||
;; used by the constant operands.
|
|
||||||
[(extended-cenv constant-operands rest-operands)
|
[operand-knowledge
|
||||||
(values (extend-compile-time-environment/scratch-space
|
(map (lambda: ([arg : Expression])
|
||||||
cenv
|
(extract-static-knowledge
|
||||||
(length rest-operands))
|
arg
|
||||||
|
(extend-compile-time-environment/scratch-space
|
||||||
(map (lambda: ([constant-operand : Expression])
|
cenv n)))
|
||||||
(ensure-simple-expression
|
(App-operands exp))]
|
||||||
(adjust-expression-depth constant-operand
|
|
||||||
(length constant-operands)
|
[typechecks?
|
||||||
n)))
|
(map (lambda: ([dom : OperandDomain]
|
||||||
constant-operands)
|
[known : CompileTimeEnvironmentEntry])
|
||||||
|
(not (redundant-check? dom known)))
|
||||||
(map (lambda: ([rest-operand : Expression])
|
(kernel-primitive-expected-operand-types kernel-op n)
|
||||||
(adjust-expression-depth rest-operand
|
operand-knowledge)]
|
||||||
(length constant-operands)
|
|
||||||
n))
|
[expected-operand-types
|
||||||
rest-operands))]
|
(kernel-primitive-expected-operand-types kernel-op n)]
|
||||||
|
[operand-poss
|
||||||
[(operand-knowledge)
|
(simple-operands->opargs (map (lambda: ([op : Expression])
|
||||||
(append (map (lambda: ([arg : Expression])
|
(adjust-expression-depth op n n))
|
||||||
(extract-static-knowledge arg extended-cenv))
|
(App-operands exp)))])
|
||||||
constant-operands)
|
(end-with-linkage
|
||||||
(map (lambda: ([arg : Expression])
|
linkage cenv
|
||||||
(extract-static-knowledge arg extended-cenv))
|
(make-instruction-sequence
|
||||||
rest-operands))]
|
`(,(make-AssignPrimOpStatement
|
||||||
|
target
|
||||||
[(typechecks?)
|
(make-CallKernelPrimitiveProcedure
|
||||||
(map (lambda: ([dom : OperandDomain]
|
kernel-op
|
||||||
[known : CompileTimeEnvironmentEntry])
|
operand-poss
|
||||||
(not (redundant-check? dom known)))
|
expected-operand-types
|
||||||
(kernel-primitive-expected-operand-types kernel-op n)
|
typechecks?))))))]
|
||||||
operand-knowledge)]
|
|
||||||
|
|
||||||
[(stack-pushing-code)
|
|
||||||
(if (empty? rest-operands)
|
|
||||||
empty-instruction-sequence
|
|
||||||
(make-instruction-sequence `(,(make-PushEnvironment
|
|
||||||
(length rest-operands)
|
|
||||||
#f))))]
|
|
||||||
[(stack-popping-code)
|
|
||||||
(if (empty? rest-operands)
|
|
||||||
empty-instruction-sequence
|
|
||||||
(make-instruction-sequence `(,(make-PopEnvironment
|
|
||||||
(length rest-operands)
|
|
||||||
0))))]
|
|
||||||
|
|
||||||
[(constant-operand-poss)
|
|
||||||
(constant-operands->opargs constant-operands)]
|
|
||||||
|
|
||||||
[(rest-operand-poss)
|
|
||||||
(build-list (length rest-operands)
|
|
||||||
(lambda: ([i : Natural])
|
|
||||||
(make-EnvLexicalReference i #f)))]
|
|
||||||
[(rest-operand-code)
|
|
||||||
(apply append-instruction-sequences
|
|
||||||
(map (lambda: ([operand : Expression]
|
|
||||||
[target : Target])
|
|
||||||
(compile operand extended-cenv target next-linkage))
|
|
||||||
rest-operands
|
|
||||||
rest-operand-poss))])
|
|
||||||
;; There's a special case optimization we can perform: we can avoid touching
|
|
||||||
;; the stack for constant arguments; rather than allocate (length (App-operands exp))
|
|
||||||
;; stack slots, we can do less than that.
|
|
||||||
|
|
||||||
(end-with-linkage
|
|
||||||
linkage cenv
|
|
||||||
(append-instruction-sequences
|
|
||||||
stack-pushing-code
|
|
||||||
rest-operand-code
|
|
||||||
(make-instruction-sequence
|
|
||||||
`(,(make-AssignPrimOpStatement
|
|
||||||
target
|
|
||||||
(make-CallKernelPrimitiveProcedure
|
|
||||||
kernel-op
|
|
||||||
(append constant-operand-poss rest-operand-poss)
|
|
||||||
expected-operand-types
|
|
||||||
typechecks?))))
|
|
||||||
stack-popping-code))))
|
|
||||||
|
|
||||||
|
|
||||||
|
[else
|
||||||
|
;; Otherwise, we can split the operands into two categories: constants, and the rest.
|
||||||
|
(let*-values ([(n)
|
||||||
|
(length (App-operands exp))]
|
||||||
|
|
||||||
|
[(expected-operand-types)
|
||||||
|
(kernel-primitive-expected-operand-types kernel-op n)]
|
||||||
|
|
||||||
|
[(constant-operands rest-operands)
|
||||||
|
(split-operands-by-constant-or-stack-references
|
||||||
|
(App-operands exp))]
|
||||||
|
|
||||||
|
;; here, we rewrite the stack references so they assume no scratch space
|
||||||
|
;; used by the constant operands.
|
||||||
|
[(extended-cenv constant-operands rest-operands)
|
||||||
|
(values (extend-compile-time-environment/scratch-space
|
||||||
|
cenv
|
||||||
|
(length rest-operands))
|
||||||
|
|
||||||
|
(map (lambda: ([constant-operand : Expression])
|
||||||
|
(ensure-simple-expression
|
||||||
|
(adjust-expression-depth constant-operand
|
||||||
|
(length constant-operands)
|
||||||
|
n)))
|
||||||
|
constant-operands)
|
||||||
|
|
||||||
|
(map (lambda: ([rest-operand : Expression])
|
||||||
|
(adjust-expression-depth rest-operand
|
||||||
|
(length constant-operands)
|
||||||
|
n))
|
||||||
|
rest-operands))]
|
||||||
|
|
||||||
|
[(operand-knowledge)
|
||||||
|
(append (map (lambda: ([arg : Expression])
|
||||||
|
(extract-static-knowledge arg extended-cenv))
|
||||||
|
constant-operands)
|
||||||
|
(map (lambda: ([arg : Expression])
|
||||||
|
(extract-static-knowledge arg extended-cenv))
|
||||||
|
rest-operands))]
|
||||||
|
|
||||||
|
[(typechecks?)
|
||||||
|
(map (lambda: ([dom : OperandDomain]
|
||||||
|
[known : CompileTimeEnvironmentEntry])
|
||||||
|
(not (redundant-check? dom known)))
|
||||||
|
(kernel-primitive-expected-operand-types kernel-op n)
|
||||||
|
operand-knowledge)]
|
||||||
|
|
||||||
|
[(stack-pushing-code)
|
||||||
|
(if (empty? rest-operands)
|
||||||
|
empty-instruction-sequence
|
||||||
|
(make-instruction-sequence `(,(make-PushEnvironment
|
||||||
|
(length rest-operands)
|
||||||
|
#f))))]
|
||||||
|
[(stack-popping-code)
|
||||||
|
(if (empty? rest-operands)
|
||||||
|
empty-instruction-sequence
|
||||||
|
(make-instruction-sequence `(,(make-PopEnvironment
|
||||||
|
(length rest-operands)
|
||||||
|
0))))]
|
||||||
|
|
||||||
|
[(constant-operand-poss)
|
||||||
|
(simple-operands->opargs constant-operands)]
|
||||||
|
|
||||||
|
[(rest-operand-poss)
|
||||||
|
(build-list (length rest-operands)
|
||||||
|
(lambda: ([i : Natural])
|
||||||
|
(make-EnvLexicalReference i #f)))]
|
||||||
|
[(rest-operand-code)
|
||||||
|
(apply append-instruction-sequences
|
||||||
|
(map (lambda: ([operand : Expression]
|
||||||
|
[target : Target])
|
||||||
|
(compile operand extended-cenv target next-linkage))
|
||||||
|
rest-operands
|
||||||
|
rest-operand-poss))])
|
||||||
|
|
||||||
|
(end-with-linkage
|
||||||
|
linkage cenv
|
||||||
|
(append-instruction-sequences
|
||||||
|
stack-pushing-code
|
||||||
|
rest-operand-code
|
||||||
|
(make-instruction-sequence
|
||||||
|
`(,(make-AssignPrimOpStatement
|
||||||
|
(adjust-target-depth target (length rest-operands))
|
||||||
|
(make-CallKernelPrimitiveProcedure
|
||||||
|
kernel-op
|
||||||
|
(append constant-operand-poss rest-operand-poss)
|
||||||
|
expected-operand-types
|
||||||
|
typechecks?))))
|
||||||
|
stack-popping-code)))]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(: ensure-simple-expression (Expression -> (U Constant ToplevelRef LocalRef)))
|
(: ensure-simple-expression (Expression -> (U Constant ToplevelRef LocalRef)))
|
||||||
(define (ensure-simple-expression e)
|
(define (ensure-simple-expression e)
|
||||||
(if (or (Constant? e)
|
(if (or (Constant? e)
|
||||||
(LocalRef? e)
|
(LocalRef? e)
|
||||||
(ToplevelRef? e))
|
(ToplevelRef? e))
|
||||||
e
|
e
|
||||||
(error 'ensure-simple-expression)))
|
(error 'ensure-simple-expression)))
|
||||||
|
|
||||||
|
|
||||||
(: constant-operands->opargs ((Listof (U Constant LocalRef ToplevelRef))
|
(: simple-operands->opargs ((Listof Expression) -> (Listof OpArg)))
|
||||||
->
|
|
||||||
(Listof OpArg)))
|
|
||||||
;; Produces a list of OpArgs if all the operands are particularly simple, and false therwise.
|
;; Produces a list of OpArgs if all the operands are particularly simple, and false therwise.
|
||||||
(define (constant-operands->opargs rands)
|
(define (simple-operands->opargs rands)
|
||||||
(map (lambda: ([e : Expression])
|
(map (lambda: ([e : Expression])
|
||||||
(cond
|
(cond
|
||||||
[(Constant? e)
|
[(Constant? e)
|
||||||
|
@ -564,8 +611,8 @@
|
||||||
[(ToplevelRef? e)
|
[(ToplevelRef? e)
|
||||||
(make-EnvPrefixReference (ToplevelRef-depth e)
|
(make-EnvPrefixReference (ToplevelRef-depth e)
|
||||||
(ToplevelRef-pos e))]
|
(ToplevelRef-pos e))]
|
||||||
[else
|
[else
|
||||||
(error 'all-operands-are-constant "Impossible")]))
|
(error 'all-operands-are-constant "Impossible")]))
|
||||||
rands))
|
rands))
|
||||||
|
|
||||||
|
|
||||||
|
@ -594,8 +641,9 @@
|
||||||
|
|
||||||
|
|
||||||
(: split-operands-by-constant-or-stack-references
|
(: split-operands-by-constant-or-stack-references
|
||||||
((Listof Expression) -> (values (Listof (U Constant LocalRef ToplevelRef))
|
((Listof Expression) ->
|
||||||
(Listof Expression))))
|
(values (Listof (U Constant LocalRef ToplevelRef))
|
||||||
|
(Listof Expression))))
|
||||||
;; Splits off the list of operations into two: a prefix of constant
|
;; Splits off the list of operations into two: a prefix of constant
|
||||||
;; or simple expressions, and the remainder.
|
;; or simple expressions, and the remainder.
|
||||||
(define (split-operands-by-constant-or-stack-references rands)
|
(define (split-operands-by-constant-or-stack-references rands)
|
||||||
|
@ -607,8 +655,12 @@
|
||||||
(values (reverse constants) empty)]
|
(values (reverse constants) empty)]
|
||||||
[else (let ([e (first rands)])
|
[else (let ([e (first rands)])
|
||||||
(if (or (Constant? e)
|
(if (or (Constant? e)
|
||||||
(LocalRef? e)
|
(and (LocalRef? e) (not (LocalRef-unbox? e)))
|
||||||
(ToplevelRef? e))
|
#;(and (ToplevelRef? e)
|
||||||
|
(let ([prefix (ensure-prefix
|
||||||
|
(list-ref cenv (ToplevelRef-depth e)))])
|
||||||
|
(ModuleVariable?
|
||||||
|
(list-ref prefix (ToplevelRef-pos e))))))
|
||||||
(loop (rest rands) (cons e constants))
|
(loop (rest rands) (cons e constants))
|
||||||
(values (reverse constants) rands)))])))
|
(values (reverse constants) rands)))])))
|
||||||
|
|
||||||
|
@ -631,23 +683,23 @@
|
||||||
(extend-compile-time-environment/scratch-space
|
(extend-compile-time-environment/scratch-space
|
||||||
cenv
|
cenv
|
||||||
(length (App-operands exp)))]
|
(length (App-operands exp)))]
|
||||||
[proc-code (compile (App-operator exp)
|
[proc-code (compile (App-operator exp)
|
||||||
extended-cenv
|
extended-cenv
|
||||||
(if (empty? (App-operands exp))
|
(if (empty? (App-operands exp))
|
||||||
'proc
|
'proc
|
||||||
(make-EnvLexicalReference
|
(make-EnvLexicalReference
|
||||||
(ensure-natural (sub1 (length (App-operands exp))))
|
(ensure-natural (sub1 (length (App-operands exp))))
|
||||||
#f))
|
#f))
|
||||||
next-linkage)]
|
next-linkage)]
|
||||||
[operand-codes (map (lambda: ([operand : Expression]
|
[operand-codes (map (lambda: ([operand : Expression]
|
||||||
[target : Target])
|
[target : Target])
|
||||||
(compile operand extended-cenv target next-linkage))
|
(compile operand extended-cenv target next-linkage))
|
||||||
(App-operands exp)
|
(App-operands exp)
|
||||||
(build-list (length (App-operands exp))
|
(build-list (length (App-operands exp))
|
||||||
(lambda: ([i : Natural])
|
(lambda: ([i : Natural])
|
||||||
(if (< i (sub1 (length (App-operands exp))))
|
(if (< i (sub1 (length (App-operands exp))))
|
||||||
(make-EnvLexicalReference i #f)
|
(make-EnvLexicalReference i #f)
|
||||||
'val))))])
|
'val))))])
|
||||||
(append-instruction-sequences
|
(append-instruction-sequences
|
||||||
(if (not (empty? (App-operands exp)))
|
(if (not (empty? (App-operands exp)))
|
||||||
(make-instruction-sequence `(,(make-PushEnvironment (length (App-operands exp)) #f)))
|
(make-instruction-sequence `(,(make-PushEnvironment (length (App-operands exp)) #f)))
|
||||||
|
@ -701,38 +753,38 @@
|
||||||
(let: ([primitive-branch : LabelLinkage (make-LabelLinkage (make-label 'primitiveBranch))]
|
(let: ([primitive-branch : LabelLinkage (make-LabelLinkage (make-label 'primitiveBranch))]
|
||||||
[compiled-branch : LabelLinkage (make-LabelLinkage (make-label 'compiledBranch))]
|
[compiled-branch : LabelLinkage (make-LabelLinkage (make-label 'compiledBranch))]
|
||||||
[after-call : LabelLinkage (make-LabelLinkage (make-label 'afterCall))])
|
[after-call : LabelLinkage (make-LabelLinkage (make-label 'afterCall))])
|
||||||
(let: ([compiled-linkage : Linkage (if (eq? linkage next-linkage) after-call linkage)])
|
(let: ([compiled-linkage : Linkage (if (eq? linkage next-linkage) after-call linkage)])
|
||||||
(append-instruction-sequences
|
(append-instruction-sequences
|
||||||
(make-instruction-sequence
|
(make-instruction-sequence
|
||||||
`(,(make-TestAndBranchStatement 'primitive-procedure?
|
`(,(make-TestAndBranchStatement 'primitive-procedure?
|
||||||
'proc
|
'proc
|
||||||
(LabelLinkage-label primitive-branch))))
|
(LabelLinkage-label primitive-branch))))
|
||||||
|
|
||||||
(LabelLinkage-label compiled-branch)
|
(LabelLinkage-label compiled-branch)
|
||||||
(make-instruction-sequence
|
(make-instruction-sequence
|
||||||
`(,(make-PerformStatement (make-CheckClosureArity! n))))
|
`(,(make-PerformStatement (make-CheckClosureArity! n))))
|
||||||
(end-with-compiled-application-linkage
|
(end-with-compiled-application-linkage
|
||||||
compiled-linkage
|
compiled-linkage
|
||||||
extended-cenv
|
extended-cenv
|
||||||
(compile-proc-appl extended-cenv (make-Reg 'val) n target compiled-linkage))
|
(compile-proc-appl extended-cenv (make-Reg 'val) n target compiled-linkage))
|
||||||
|
|
||||||
(LabelLinkage-label primitive-branch)
|
(LabelLinkage-label primitive-branch)
|
||||||
(end-with-linkage
|
(end-with-linkage
|
||||||
linkage
|
linkage
|
||||||
cenv
|
cenv
|
||||||
(append-instruction-sequences
|
(append-instruction-sequences
|
||||||
(make-instruction-sequence
|
(make-instruction-sequence
|
||||||
`(,(make-AssignPrimOpStatement
|
`(,(make-AssignPrimOpStatement
|
||||||
;; Optimization: we put the result directly in the registers, or in
|
;; Optimization: we put the result directly in the registers, or in
|
||||||
;; the appropriate spot on the stack. This takes into account the popenviroment
|
;; the appropriate spot on the stack. This takes into account the popenviroment
|
||||||
;; that happens right afterwards.
|
;; that happens right afterwards.
|
||||||
(adjust-target-depth target n)
|
(adjust-target-depth target n)
|
||||||
(make-ApplyPrimitiveProcedure n))))
|
(make-ApplyPrimitiveProcedure n))))
|
||||||
(if (not (= n 0))
|
(if (not (= n 0))
|
||||||
(make-instruction-sequence
|
(make-instruction-sequence
|
||||||
`(,(make-PopEnvironment n 0)))
|
`(,(make-PopEnvironment n 0)))
|
||||||
empty-instruction-sequence)))
|
empty-instruction-sequence)))
|
||||||
(LabelLinkage-label after-call)))))
|
(LabelLinkage-label after-call)))))
|
||||||
|
|
||||||
|
|
||||||
(: compile-procedure-call/statically-known-lam
|
(: compile-procedure-call/statically-known-lam
|
||||||
|
@ -740,16 +792,16 @@
|
||||||
(define (compile-procedure-call/statically-known-lam static-knowledge extended-cenv n target linkage)
|
(define (compile-procedure-call/statically-known-lam static-knowledge extended-cenv n target linkage)
|
||||||
(let*: ([after-call : LabelLinkage (make-LabelLinkage (make-label 'afterCall))]
|
(let*: ([after-call : LabelLinkage (make-LabelLinkage (make-label 'afterCall))]
|
||||||
[compiled-linkage : Linkage (if (eq? linkage next-linkage) after-call linkage)])
|
[compiled-linkage : Linkage (if (eq? linkage next-linkage) after-call linkage)])
|
||||||
(append-instruction-sequences
|
(append-instruction-sequences
|
||||||
(end-with-compiled-application-linkage
|
(end-with-compiled-application-linkage
|
||||||
compiled-linkage
|
compiled-linkage
|
||||||
extended-cenv
|
extended-cenv
|
||||||
(compile-proc-appl extended-cenv
|
(compile-proc-appl extended-cenv
|
||||||
(make-Label (StaticallyKnownLam-entry-point static-knowledge))
|
(make-Label (StaticallyKnownLam-entry-point static-knowledge))
|
||||||
n
|
n
|
||||||
target
|
target
|
||||||
compiled-linkage))
|
compiled-linkage))
|
||||||
(LabelLinkage-label after-call))))
|
(LabelLinkage-label after-call))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -782,7 +834,7 @@
|
||||||
;; only when the target is the val register.
|
;; only when the target is the val register.
|
||||||
(error 'compile "return linkage, target not val: ~s" target)])]
|
(error 'compile "return linkage, target not val: ~s" target)])]
|
||||||
|
|
||||||
|
|
||||||
[(NextLinkage? linkage)
|
[(NextLinkage? linkage)
|
||||||
(cond [(eq? target 'val)
|
(cond [(eq? target 'val)
|
||||||
;; This case happens for a function call that isn't in
|
;; This case happens for a function call that isn't in
|
||||||
|
@ -813,7 +865,7 @@
|
||||||
`(,(make-PushControlFrame (LabelLinkage-label linkage))
|
`(,(make-PushControlFrame (LabelLinkage-label linkage))
|
||||||
,(make-AssignPrimOpStatement 'val (make-GetCompiledProcedureEntry))
|
,(make-AssignPrimOpStatement 'val (make-GetCompiledProcedureEntry))
|
||||||
,(make-GotoStatement entry-point)))]
|
,(make-GotoStatement entry-point)))]
|
||||||
|
|
||||||
[else
|
[else
|
||||||
;; This case happens for evaluating arguments, since the
|
;; This case happens for evaluating arguments, since the
|
||||||
;; arguments are being installed into the scratch space.
|
;; arguments are being installed into the scratch space.
|
||||||
|
@ -1112,7 +1164,7 @@
|
||||||
exp
|
exp
|
||||||
(make-LocalRef (ensure-natural (- (LocalRef-depth exp) n))
|
(make-LocalRef (ensure-natural (- (LocalRef-depth exp) n))
|
||||||
(LocalRef-unbox? exp)))]
|
(LocalRef-unbox? exp)))]
|
||||||
|
|
||||||
[(ToplevelSet? exp)
|
[(ToplevelSet? exp)
|
||||||
(if (< (ToplevelSet-depth exp) skip)
|
(if (< (ToplevelSet-depth exp) skip)
|
||||||
(make-ToplevelSet (ToplevelSet-depth exp)
|
(make-ToplevelSet (ToplevelSet-depth exp)
|
||||||
|
@ -1123,12 +1175,12 @@
|
||||||
(ToplevelSet-pos exp)
|
(ToplevelSet-pos exp)
|
||||||
(ToplevelSet-name exp)
|
(ToplevelSet-name exp)
|
||||||
(adjust-expression-depth (ToplevelSet-value exp) n skip)))]
|
(adjust-expression-depth (ToplevelSet-value exp) n skip)))]
|
||||||
|
|
||||||
[(Branch? exp)
|
[(Branch? exp)
|
||||||
(make-Branch (adjust-expression-depth (Branch-predicate exp) n skip)
|
(make-Branch (adjust-expression-depth (Branch-predicate exp) n skip)
|
||||||
(adjust-expression-depth (Branch-consequent exp) n skip)
|
(adjust-expression-depth (Branch-consequent exp) n skip)
|
||||||
(adjust-expression-depth (Branch-alternative exp) n skip))]
|
(adjust-expression-depth (Branch-alternative exp) n skip))]
|
||||||
|
|
||||||
[(Lam? exp)
|
[(Lam? exp)
|
||||||
(make-Lam (Lam-name exp)
|
(make-Lam (Lam-name exp)
|
||||||
(Lam-num-parameters exp)
|
(Lam-num-parameters exp)
|
||||||
|
@ -1144,7 +1196,7 @@
|
||||||
(make-Seq (map (lambda: ([action : Expression])
|
(make-Seq (map (lambda: ([action : Expression])
|
||||||
(adjust-expression-depth action n skip))
|
(adjust-expression-depth action n skip))
|
||||||
(Seq-actions exp)))]
|
(Seq-actions exp)))]
|
||||||
|
|
||||||
[(App? exp)
|
[(App? exp)
|
||||||
(make-App (adjust-expression-depth (App-operator exp) n
|
(make-App (adjust-expression-depth (App-operator exp) n
|
||||||
(+ skip (length (App-operands exp))))
|
(+ skip (length (App-operands exp))))
|
||||||
|
@ -1156,14 +1208,14 @@
|
||||||
[(Let1? exp)
|
[(Let1? exp)
|
||||||
(make-Let1 (adjust-expression-depth (Let1-rhs exp) n (add1 skip))
|
(make-Let1 (adjust-expression-depth (Let1-rhs exp) n (add1 skip))
|
||||||
(adjust-expression-depth (Let1-body exp) n (add1 skip)))]
|
(adjust-expression-depth (Let1-body exp) n (add1 skip)))]
|
||||||
|
|
||||||
[(LetVoid? exp)
|
[(LetVoid? exp)
|
||||||
(make-LetVoid (LetVoid-count exp)
|
(make-LetVoid (LetVoid-count exp)
|
||||||
(adjust-expression-depth (LetVoid-body exp)
|
(adjust-expression-depth (LetVoid-body exp)
|
||||||
n
|
n
|
||||||
(+ skip (LetVoid-count exp)))
|
(+ skip (LetVoid-count exp)))
|
||||||
(LetVoid-boxes? exp))]
|
(LetVoid-boxes? exp))]
|
||||||
|
|
||||||
[(LetRec? exp)
|
[(LetRec? exp)
|
||||||
(make-LetRec (let: loop : (Listof Lam) ([procs : (Listof Lam) (LetRec-procs exp)])
|
(make-LetRec (let: loop : (Listof Lam) ([procs : (Listof Lam) (LetRec-procs exp)])
|
||||||
(cond
|
(cond
|
||||||
|
@ -1190,7 +1242,7 @@
|
||||||
n
|
n
|
||||||
skip)
|
skip)
|
||||||
(InstallValue-box? exp)))]
|
(InstallValue-box? exp)))]
|
||||||
|
|
||||||
[(BoxEnv? exp)
|
[(BoxEnv? exp)
|
||||||
(if (< (BoxEnv-depth exp) skip)
|
(if (< (BoxEnv-depth exp) skip)
|
||||||
(make-BoxEnv (BoxEnv-depth exp)
|
(make-BoxEnv (BoxEnv-depth exp)
|
||||||
|
@ -1198,4 +1250,4 @@
|
||||||
(make-BoxEnv (ensure-natural (- (BoxEnv-depth exp) n))
|
(make-BoxEnv (ensure-natural (- (BoxEnv-depth exp) n))
|
||||||
(adjust-expression-depth (BoxEnv-body exp) n skip)))]))
|
(adjust-expression-depth (BoxEnv-body exp) n skip)))]))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user