diff options
Diffstat (limited to 'src/interp')
-rw-r--r-- | src/interp/c-util.boot | 6 | ||||
-rw-r--r-- | src/interp/g-opt.boot | 29 | ||||
-rw-r--r-- | src/interp/g-util.boot | 9 |
3 files changed, 39 insertions, 5 deletions
diff --git a/src/interp/c-util.boot b/src/interp/c-util.boot index ab80ac63..17d630b4 100644 --- a/src/interp/c-util.boot +++ b/src/interp/c-util.boot @@ -1620,8 +1620,10 @@ transformToBackendCode x == -- Make it explicitly a sequence of statements if it is not a one liner. body := body is [stmt] and - (atom stmt or stmt.op = "SEQ" or not CONTAINED("EXIT",stmt)) => - body + (atom stmt + or stmt.op in '(SEQ LET LET_*) + or not CONTAINED("EXIT",stmt)) => + body [simplifySEQ ["SEQ",:body]] $FluidVars := removeDuplicates nreverse $FluidVars $LocalVars := S_-(S_-(removeDuplicates nreverse $LocalVars,$FluidVars), diff --git a/src/interp/g-opt.boot b/src/interp/g-opt.boot index e47f7be0..f8e28b42 100644 --- a/src/interp/g-opt.boot +++ b/src/interp/g-opt.boot @@ -79,6 +79,33 @@ changeVariableDefinitionToStore(form,vars) == x is ['%LET,v,:.] and not (v in vars) => vars := [v,:vars] +++ Return true if `x' contains control transfer to a point outside itself. +jumpToToplevel? x == + isAtomicForm x => false + op := x.op + op = 'SEQ => CONTAINED('THROW,x.args) + op in '(EXIT THROW %leave) => true + or/[jumpToToplevel? x' for x' in x] + +++ Return true if `form' is just one assignment expression. +singleAssignment? form == + form is ['%LET,.,rhs] and not CONTAINED('%LET,rhs) + +++ Turns `form' into a `%bind'-expression if it starts with a +++ a sequence of first-time variable definitions. +groupVariableDefinitions form == + isAtomicForm form => form + form isnt ['SEQ,:stmts,['EXIT,val]] => form + defs := nil + for x in stmts while singleAssignment? x repeat + defs := [x.args,:defs] + defs = nil or jumpToToplevel? defs => form + stmts := drop(#defs,stmts) + expr := + stmts = nil => val + ['SEQ,:stmts,['EXIT,val]] + ['%bind,nreverse defs,expr] + optimizeFunctionDef(def) == if $reportOptimization then sayBrightlyI bright '"Original LISP code:" @@ -109,7 +136,7 @@ optimizeFunctionDef(def) == replaceThrowByReturn(first x,g) replaceThrowByReturn(rest x,g) changeVariableDefinitionToStore(body',args) - [name,[slamOrLam,args,body']] + [name,[slamOrLam,args,groupVariableDefinitions body']] optimize x == (opt x; x) where diff --git a/src/interp/g-util.boot b/src/interp/g-util.boot index ed134390..bf4a02ee 100644 --- a/src/interp/g-util.boot +++ b/src/interp/g-util.boot @@ -227,11 +227,16 @@ expandEq ["%eq",:args] == ["EQ",:expandToVMForm args] -- Local variable bindings -expandBind ["%bind",inits,body] == +expandBind ['%bind,inits,body] == body := expandToVMForm body inits := [[first x,expandToVMForm second x] for x in inits] + n := #inits + n = 0 => body -- FIXME: we should consider turning LET* into LET or direct inlining. - ["LET*",inits,body] + op := + n = 1 => 'LET + 'LET_* + [op,inits,body] -- Memory load/store |