transf and vmgen compile again
This commit is contained in:
parent
1310279691
commit
fedc136985
9 changed files with 234 additions and 223 deletions
|
|
@ -21,7 +21,8 @@
|
|||
import
|
||||
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os,
|
||||
idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread,
|
||||
lambdalifting, sempass2, lowerings, lookups, destroyer, liftlocals
|
||||
lambdalifting, sempass2, lowerings, lookups, destroyer, liftlocals,
|
||||
modulegraphs
|
||||
|
||||
type
|
||||
PTransNode* = distinct PNode
|
||||
|
|
@ -44,6 +45,7 @@ type
|
|||
nestedProcs: int # > 0 if we are in a nested proc
|
||||
contSyms, breakSyms: seq[PSym] # to transform 'continue' and 'break'
|
||||
deferDetected, tooEarly, needsDestroyPass: bool
|
||||
graph: ModuleGraph
|
||||
PTransf = ref TTransfContext
|
||||
|
||||
proc newTransNode(a: PNode): PTransNode {.inline.} =
|
||||
|
|
@ -84,7 +86,7 @@ proc pushTransCon(c: PTransf, t: PTransCon) =
|
|||
c.transCon = t
|
||||
|
||||
proc popTransCon(c: PTransf) =
|
||||
if (c.transCon == nil): internalError("popTransCon")
|
||||
if (c.transCon == nil): internalError(c.graph.config, "popTransCon")
|
||||
c.transCon = c.transCon.next
|
||||
|
||||
proc getCurrOwner(c: PTransf): PSym =
|
||||
|
|
@ -97,7 +99,7 @@ proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PNode =
|
|||
incl(r.flags, sfFromGeneric)
|
||||
let owner = getCurrOwner(c)
|
||||
if owner.isIterator and not c.tooEarly:
|
||||
result = freshVarForClosureIter(r, owner)
|
||||
result = freshVarForClosureIter(c.graph, r, owner)
|
||||
else:
|
||||
result = newSymNode(r)
|
||||
|
||||
|
|
@ -118,10 +120,10 @@ proc transformSymAux(c: PTransf, n: PNode): PNode =
|
|||
if s.typ != nil and s.typ.callConv == ccClosure:
|
||||
if s.kind == skIterator:
|
||||
if c.tooEarly: return n
|
||||
else: return liftIterSym(n, getCurrOwner(c))
|
||||
else: return liftIterSym(c.graph, n, getCurrOwner(c))
|
||||
elif s.kind in {skProc, skFunc, skConverter, skMethod} and not c.tooEarly:
|
||||
# top level .closure procs are still somewhat supported for 'Nake':
|
||||
return makeClosure(s, nil, n.info)
|
||||
return makeClosure(c.graph, s, nil, n.info)
|
||||
#elif n.sym.kind in {skVar, skLet} and n.sym.typ.callConv == ccClosure:
|
||||
# echo n.info, " come heer for ", c.tooEarly
|
||||
# if not c.tooEarly:
|
||||
|
|
@ -130,7 +132,7 @@ proc transformSymAux(c: PTransf, n: PNode): PNode =
|
|||
if sfBorrow in s.flags and s.kind in routineKinds:
|
||||
# simply exchange the symbol:
|
||||
b = s.getBody
|
||||
if b.kind != nkSym: internalError(n.info, "wrong AST for borrowed symbol")
|
||||
if b.kind != nkSym: internalError(c.graph.config, n.info, "wrong AST for borrowed symbol")
|
||||
b = newSymNode(b.sym, n.info)
|
||||
else:
|
||||
b = n
|
||||
|
|
@ -151,7 +153,7 @@ proc transformSym(c: PTransf, n: PNode): PTransNode =
|
|||
proc freshVar(c: PTransf; v: PSym): PNode =
|
||||
let owner = getCurrOwner(c)
|
||||
if owner.isIterator and not c.tooEarly:
|
||||
result = freshVarForClosureIter(v, owner)
|
||||
result = freshVarForClosureIter(c.graph, v, owner)
|
||||
else:
|
||||
var newVar = copySym(v)
|
||||
incl(newVar.flags, sfFromGeneric)
|
||||
|
|
@ -166,11 +168,11 @@ proc transformVarSection(c: PTransf, v: PNode): PTransNode =
|
|||
result[i] = PTransNode(it)
|
||||
elif it.kind == nkIdentDefs:
|
||||
if it.sons[0].kind == nkSym:
|
||||
internalAssert(it.len == 3)
|
||||
internalAssert(c.graph.config, it.len == 3)
|
||||
let x = freshVar(c, it.sons[0].sym)
|
||||
idNodeTablePut(c.transCon.mapping, it.sons[0].sym, x)
|
||||
var defs = newTransNode(nkIdentDefs, it.info, 3)
|
||||
if importantComments():
|
||||
if importantComments(c.graph.config):
|
||||
# keep documentation information:
|
||||
PNode(defs).comment = it.comment
|
||||
defs[0] = x.PTransNode
|
||||
|
|
@ -184,7 +186,7 @@ proc transformVarSection(c: PTransf, v: PNode): PTransNode =
|
|||
result[i] = transform(c, it)
|
||||
else:
|
||||
if it.kind != nkVarTuple:
|
||||
internalError(it.info, "transformVarSection: not nkVarTuple")
|
||||
internalError(c.graph.config, it.info, "transformVarSection: not nkVarTuple")
|
||||
var L = sonsLen(it)
|
||||
var defs = newTransNode(it.kind, it.info, L)
|
||||
for j in countup(0, L-3):
|
||||
|
|
@ -203,9 +205,9 @@ proc transformConstSection(c: PTransf, v: PNode): PTransNode =
|
|||
if it.kind == nkCommentStmt:
|
||||
result[i] = PTransNode(it)
|
||||
else:
|
||||
if it.kind != nkConstDef: internalError(it.info, "transformConstSection")
|
||||
if it.kind != nkConstDef: internalError(c.graph.config, it.info, "transformConstSection")
|
||||
if it.sons[0].kind != nkSym:
|
||||
internalError(it.info, "transformConstSection")
|
||||
internalError(c.graph.config, it.info, "transformConstSection")
|
||||
|
||||
result[i] = PTransNode(it)
|
||||
|
||||
|
|
@ -301,7 +303,7 @@ proc unpackTuple(c: PTransf, n: PNode, father: PTransNode) =
|
|||
# XXX: BUG: what if `n` is an expression with side-effects?
|
||||
for i in countup(0, sonsLen(c.transCon.forStmt) - 3):
|
||||
add(father, newAsgnStmt(c, c.transCon.forStmt.sons[i],
|
||||
transform(c, newTupleAccess(n, i))))
|
||||
transform(c, newTupleAccess(c.graph, n, i))))
|
||||
|
||||
proc introduceNewLocalVars(c: PTransf, n: PNode): PTransNode =
|
||||
case n.kind
|
||||
|
|
@ -382,7 +384,7 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
|
|||
if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
|
||||
PNode(result).typ = n.typ
|
||||
|
||||
proc generateThunk(prc: PNode, dest: PType): PNode =
|
||||
proc generateThunk(c: PTransf; prc: PNode, dest: PType): PNode =
|
||||
## Converts 'prc' into '(thunk, nil)' so that it's compatible with
|
||||
## a closure.
|
||||
|
||||
|
|
@ -394,9 +396,9 @@ proc generateThunk(prc: PNode, dest: PType): PNode =
|
|||
conv.add(emptyNode)
|
||||
conv.add(prc)
|
||||
if prc.kind == nkClosure:
|
||||
internalError(prc.info, "closure to closure created")
|
||||
internalError(c.graph.config, prc.info, "closure to closure created")
|
||||
result.add(conv)
|
||||
result.add(newNodeIT(nkNilLit, prc.info, getSysType(tyNil)))
|
||||
result.add(newNodeIT(nkNilLit, prc.info, getSysType(c.graph, prc.info, tyNil)))
|
||||
|
||||
proc transformConv(c: PTransf, n: PNode): PTransNode =
|
||||
# numeric types need range checks:
|
||||
|
|
@ -481,7 +483,7 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
|
|||
of tyProc:
|
||||
result = transformSons(c, n)
|
||||
if dest.callConv == ccClosure and source.callConv == ccDefault:
|
||||
result = generateThunk(result[1].PNode, dest).PTransNode
|
||||
result = generateThunk(c, result[1].PNode, dest).PTransNode
|
||||
else:
|
||||
result = transformSons(c, n)
|
||||
|
||||
|
|
@ -513,7 +515,7 @@ proc findWrongOwners(c: PTransf, n: PNode) =
|
|||
if n.kind == nkVarSection:
|
||||
let x = n.sons[0].sons[0]
|
||||
if x.kind == nkSym and x.sym.owner != getCurrOwner(c):
|
||||
internalError(x.info, "bah " & x.sym.name.s & " " &
|
||||
internalError(c.graph.config, x.info, "bah " & x.sym.name.s & " " &
|
||||
x.sym.owner.name.s & " " & getCurrOwner(c).name.s)
|
||||
else:
|
||||
for i in 0 ..< safeLen(n): findWrongOwners(c, n.sons[i])
|
||||
|
|
@ -521,7 +523,7 @@ proc findWrongOwners(c: PTransf, n: PNode) =
|
|||
proc transformFor(c: PTransf, n: PNode): PTransNode =
|
||||
# generate access statements for the parameters (unless they are constant)
|
||||
# put mapping from formal parameters to actual parameters
|
||||
if n.kind != nkForStmt: internalError(n.info, "transformFor")
|
||||
if n.kind != nkForStmt: internalError(c.graph.config, n.info, "transformFor")
|
||||
|
||||
var length = sonsLen(n)
|
||||
var call = n.sons[length - 2]
|
||||
|
|
@ -539,7 +541,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
|||
n.sons[length-1] = transformLoopBody(c, n.sons[length-1]).PNode
|
||||
if not c.tooEarly:
|
||||
n.sons[length-2] = transform(c, n.sons[length-2]).PNode
|
||||
result[1] = lambdalifting.liftForLoop(n, getCurrOwner(c)).PTransNode
|
||||
result[1] = lambdalifting.liftForLoop(c.graph, n, getCurrOwner(c)).PTransNode
|
||||
else:
|
||||
result[1] = newNode(nkEmpty).PTransNode
|
||||
discard c.breakSyms.pop
|
||||
|
|
@ -689,7 +691,7 @@ proc transformCall(c: PTransf, n: PNode): PTransNode =
|
|||
while (j < sonsLen(n)):
|
||||
let b = transform(c, n.sons[j]).PNode
|
||||
if not isConstExpr(b): break
|
||||
a = evalOp(op.magic, n, a, b, nil)
|
||||
a = evalOp(op.magic, n, a, b, nil, c.graph)
|
||||
inc(j)
|
||||
add(result, a.PTransNode)
|
||||
if len(result) == 2: result = result[1]
|
||||
|
|
@ -708,7 +710,7 @@ proc transformCall(c: PTransf, n: PNode): PTransNode =
|
|||
let t = lastSon(s.sons[0].sym.ast)
|
||||
if t.kind != nkSym or sfDispatcher notin t.sym.flags:
|
||||
methodDef(s.sons[0].sym, false)
|
||||
result = methodCall(s).PTransNode
|
||||
result = methodCall(s, c.graph.config).PTransNode
|
||||
else:
|
||||
result = s.PTransNode
|
||||
|
||||
|
|
@ -719,7 +721,7 @@ proc transformExceptBranch(c: PTransf, n: PNode): PTransNode =
|
|||
let actions = newTransNode(nkStmtListExpr, n[1], 2)
|
||||
# Generating `let exc = (excType)(getCurrentException())`
|
||||
# -> getCurrentException()
|
||||
let excCall = PTransNode(callCodegenProc("getCurrentException", ast.emptyNode))
|
||||
let excCall = PTransNode(callCodegenProc(c.graph, "getCurrentException", ast.emptyNode))
|
||||
# -> (excType)
|
||||
let convNode = newTransNode(nkHiddenSubConv, n[1].info, 2)
|
||||
convNode[0] = PTransNode(ast.emptyNode)
|
||||
|
|
@ -748,10 +750,10 @@ proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} =
|
|||
result = orig.kind == nkSym and cnst.kind in {nkCurly, nkPar, nkTupleConstr, nkBracket} and
|
||||
cnst.len != 0
|
||||
|
||||
proc commonOptimizations*(c: PSym, n: PNode): PNode =
|
||||
proc commonOptimizations*(g: ModuleGraph; c: PSym, n: PNode): PNode =
|
||||
result = n
|
||||
for i in 0 ..< n.safeLen:
|
||||
result.sons[i] = commonOptimizations(c, n.sons[i])
|
||||
result.sons[i] = commonOptimizations(g, c, n.sons[i])
|
||||
var op = getMergeOp(n)
|
||||
if (op != nil) and (op.magic != mNone) and (sonsLen(n) >= 3):
|
||||
result = newNodeIT(nkCall, n.info, n.typ)
|
||||
|
|
@ -766,12 +768,12 @@ proc commonOptimizations*(c: PSym, n: PNode): PNode =
|
|||
while j < sonsLen(args):
|
||||
let b = args.sons[j]
|
||||
if not isConstExpr(b): break
|
||||
a = evalOp(op.magic, result, a, b, nil)
|
||||
a = evalOp(op.magic, result, a, b, nil, g)
|
||||
inc(j)
|
||||
add(result, a)
|
||||
if len(result) == 2: result = result[1]
|
||||
else:
|
||||
var cnst = getConstExpr(c, n)
|
||||
var cnst = getConstExpr(c, n, g)
|
||||
# we inline constants if they are not complex constants:
|
||||
if cnst != nil and not dontInlineConstant(n, cnst):
|
||||
result = cnst
|
||||
|
|
@ -888,7 +890,7 @@ proc transform(c: PTransf, n: PNode): PTransNode =
|
|||
let L = n.len-1
|
||||
result[L] = transform(c, n.sons[L])
|
||||
# XXX comment handling really sucks:
|
||||
if importantComments():
|
||||
if importantComments(c.graph.config):
|
||||
PNode(result).comment = n.comment
|
||||
of nkClosure:
|
||||
# it can happen that for-loop-inlining produced a fresh
|
||||
|
|
@ -905,7 +907,7 @@ proc transform(c: PTransf, n: PNode): PTransNode =
|
|||
when false:
|
||||
if oldDeferAnchor != nil: c.deferAnchor = oldDeferAnchor
|
||||
|
||||
var cnst = getConstExpr(c.module, PNode(result))
|
||||
var cnst = getConstExpr(c.module, PNode(result), c.graph)
|
||||
# we inline constants if they are not complex constants:
|
||||
if cnst != nil and not dontInlineConstant(n, cnst):
|
||||
result = PTransNode(cnst) # do not miss an optimization
|
||||
|
|
@ -920,11 +922,12 @@ proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode =
|
|||
popTransCon(c)
|
||||
incl(result.flags, nfTransf)
|
||||
|
||||
proc openTransf(module: PSym, filename: string): PTransf =
|
||||
proc openTransf(g: ModuleGraph; module: PSym, filename: string): PTransf =
|
||||
new(result)
|
||||
result.contSyms = @[]
|
||||
result.breakSyms = @[]
|
||||
result.module = module
|
||||
result.graph = g
|
||||
|
||||
proc flattenStmts(n: PNode) =
|
||||
var goOn = true
|
||||
|
|
@ -967,46 +970,46 @@ template liftDefer(c, root) =
|
|||
if c.deferDetected:
|
||||
liftDeferAux(root)
|
||||
|
||||
proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode =
|
||||
proc transformBody*(g: ModuleGraph; module: PSym, n: PNode, prc: PSym): PNode =
|
||||
if nfTransf in n.flags or prc.kind in {skTemplate}:
|
||||
result = n
|
||||
else:
|
||||
var c = openTransf(module, "")
|
||||
result = liftLambdas(prc, n, c.tooEarly)
|
||||
var c = openTransf(g, module, "")
|
||||
result = liftLambdas(g, prc, n, c.tooEarly)
|
||||
#result = n
|
||||
result = processTransf(c, result, prc)
|
||||
liftDefer(c, result)
|
||||
#result = liftLambdas(prc, result)
|
||||
when useEffectSystem: trackProc(prc, result)
|
||||
result = liftLocalsIfRequested(prc, result)
|
||||
when useEffectSystem: trackProc(g, prc, result)
|
||||
result = liftLocalsIfRequested(prc, result, g.config)
|
||||
if c.needsDestroyPass: #and newDestructors:
|
||||
result = injectDestructorCalls(prc, result)
|
||||
result = injectDestructorCalls(g, prc, result)
|
||||
incl(result.flags, nfTransf)
|
||||
#if prc.name.s == "testbody":
|
||||
# echo renderTree(result)
|
||||
|
||||
proc transformStmt*(module: PSym, n: PNode): PNode =
|
||||
proc transformStmt*(g: ModuleGraph; module: PSym, n: PNode): PNode =
|
||||
if nfTransf in n.flags:
|
||||
result = n
|
||||
else:
|
||||
var c = openTransf(module, "")
|
||||
var c = openTransf(g, module, "")
|
||||
result = processTransf(c, n, module)
|
||||
liftDefer(c, result)
|
||||
#result = liftLambdasForTopLevel(module, result)
|
||||
when useEffectSystem: trackTopLevelStmt(module, result)
|
||||
when useEffectSystem: trackTopLevelStmt(g, module, result)
|
||||
#if n.info ?? "temp.nim":
|
||||
# echo renderTree(result, {renderIds})
|
||||
if c.needsDestroyPass:
|
||||
result = injectDestructorCalls(module, result)
|
||||
result = injectDestructorCalls(g, module, result)
|
||||
incl(result.flags, nfTransf)
|
||||
|
||||
proc transformExpr*(module: PSym, n: PNode): PNode =
|
||||
proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode =
|
||||
if nfTransf in n.flags:
|
||||
result = n
|
||||
else:
|
||||
var c = openTransf(module, "")
|
||||
var c = openTransf(g, module, "")
|
||||
result = processTransf(c, n, module)
|
||||
liftDefer(c, result)
|
||||
if c.needsDestroyPass:
|
||||
result = injectDestructorCalls(module, result)
|
||||
result = injectDestructorCalls(g, module, result)
|
||||
incl(result.flags, nfTransf)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue