aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ChangeLog10
-rw-r--r--src/interp/compiler.boot15
-rw-r--r--src/interp/g-opt.boot5
3 files changed, 22 insertions, 8 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 4e86d93b..fcc54354 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,15 @@
2012-02-26 Gabriel Dos Reis <gdr@cs.tamu.edu>
+ * interp/compiler.boot (emitLocalCallInsn): Mark external
+ operators as such, and local functions as such.
+ (freeVarUsage): Do not count external and local functions.
+ (extractCode): Tidy. Handle closure literals.
+ * interp/g-opt.boot (optCall): Optimize external calls where
+ possible.
+ %external is a side-effect free operator.
+
+2012-02-26 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
* interp/g-util.boot (usedSymbol?): Remove.
(bindingForm?): New.
(usesVariable?): Likewise.
diff --git a/src/interp/compiler.boot b/src/interp/compiler.boot
index 1087b07e..f3420579 100644
--- a/src/interp/compiler.boot
+++ b/src/interp/compiler.boot
@@ -211,8 +211,9 @@ emitLocalCallInsn: (%Symbol,%List %Code,%Env) -> %Code
emitLocalCallInsn(op,args,e) ==
op' := -- Find out the linkage name for `op'.
get(op,"%Link",e) or encodeLocalFunctionName op
- get(op,"%Lang",e) => [op',:args] -- non-Spad calling convention
- [op',:args,"$"]
+ get(op,"%Lang",e) => -- non-Spad calling convention
+ ['%call,['%external,op'],:args]
+ ['%call,['%closure,['%function,op'],'$],:args]
applyMapping([op,:argl],m,e,ml) ==
#argl ~= #ml-1 => nil
@@ -235,8 +236,8 @@ applyMapping([op,:argl],m,e,ml) ==
T() == [.,.,e]:= comp(x,m',e) or return "failed"
if argl' is "failed" then return nil
form:=
- symbol? op and not symbolMember?(op,$formalArgList) and null (u := get(op,"value",e)) =>
- emitLocalCallInsn(op,argl',e)
+ symbol? op and not symbolMember?(op,$formalArgList)
+ and (u := get(op,"value",e)) = nil => emitLocalCallInsn(op,argl',e)
-- Compiler synthetized operators are inline.
u ~= nil and u.expr is ["XLAM",:.] => ['%call,u.expr,:argl']
['%call,['%apply,op],:argl']
@@ -263,8 +264,9 @@ freeVarUsage([.,vars,body],env) ==
free
getmode(u,e) = nil => free
[[u,:1],:free]
+ atomic? u => free
op := u.op
- op in '(QUOTE GO function) => free
+ op in '(GO %external %function function) => free
op in '(LAMBDA %lambda) =>
bound := setUnion(u.absParms,bound)
for v in CDDR u repeat
@@ -358,8 +360,9 @@ compWithMappingMode(x,m is ["Mapping",m',:sl],oldE) ==
[finishLambdaExpression(fun,e),m,oldE]
extractCode(u,vars) ==
- u is ['%call,['%apply,a],: =vars] => a
u is ['%call,[q,:etc],: =vars] and q in '(ELT CONST) => ['%tref,:etc]
+ u is ['%call,['%apply,a],: =vars] => a
+ u is ['%call,['%closure,:.],: =vars] => first u.args
['%closure,['%function,['%lambda,[:vars,'$],u]],'$]
compExpression(x,m,e) ==
diff --git a/src/interp/g-opt.boot b/src/interp/g-opt.boot
index 51bc8cef..d771739b 100644
--- a/src/interp/g-opt.boot
+++ b/src/interp/g-opt.boot
@@ -547,9 +547,10 @@ optCall (x is ['%call,:u]) ==
x.first := op
x.rest := [:a,env]
x
- fn is ['%function,op] =>
+ fn is ['%external,op] =>
x.first := op
x.rest := a
+ opt := op has OPTIMIZE => resetTo(x,apply(opt,x,nil))
x
fn is ['ELT,:.] => emitIndirectCall(fn,a,x)
fn is ['CONST,R,n] => ['spadConstant,R,n]
@@ -656,7 +657,7 @@ $VMsideEffectFreeOperators ==
%bitvecnot %bitvecand %bitvecnand %bivecor %bitvecnor %bitvecxor
%bitveccopy %bitvecconc %bitveclength %bitvecref %bitveceq %bitveclt
%before? %equal %sptreq %ident? %property %tref
- %void %retract %pullback %lambda %closure)
+ %void %retract %pullback %lambda %closure %external)
++ List of simple VM operators
$simpleVMoperators ==