explicit ID generation for easier IC (#15559)

* refactoring: idents don't need inheritance
* refactoring: adding an IdGenerator (part 1)
* refactoring: adding an IdGenerator (part 2)
* refactoring: adding an IdGenerator (part 3)
* refactoring: adding an IdGenerator (part 4)
* refactoring: adding an IdGenerator (part 5)
* refactoring: adding an IdGenerator (part 5)
* IdGenerator must be a ref type; hello world works again
* make bootstrapping work again
* progress: add back the 'exactReplica' ideas
* added back the missing exactReplica hacks
* make tcompilerapi work again
* make important packages green
* attempt to fix the build for 32 bit machines (probably need a better solution here)
This commit is contained in:
Andreas Rumpf 2020-10-25 08:50:47 +01:00 • committed by GitHub
commit 226595515c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 853 additions and 903 deletions

View file

@ -24,7 +24,7 @@ import
lowerings, liftlocals,
modulegraphs, lineinfos
proc transformBody*(g: ModuleGraph, prc: PSym, cache: bool): PNode
proc transformBody*(g: ModuleGraph; idgen: IdGenerator, prc: PSym, cache: bool): PNode
import closureiters, lambdalifting
@ -40,7 +40,7 @@ type
# if we encounter the 2nd yield statement
next: PTransCon # for stacking
TTransfContext = object of TPassContext
TTransfContext = object
module: PSym
transCon: PTransCon # top of a TransCon stack
inlining: int # > 0 if we are in inlining context (copy vars)
@ -48,6 +48,7 @@ type
contSyms, breakSyms: seq[PSym] # to transform 'continue' and 'break'
deferDetected, tooEarly: bool
graph: ModuleGraph
idgen: IdGenerator
PTransf = ref TTransfContext
proc newTransNode(a: PNode): PNode {.inline.} =
@ -86,12 +87,12 @@ proc getCurrOwner(c: PTransf): PSym =
else: result = c.module
proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PNode =
let r = newSym(skTemp, getIdent(c.graph.cache, genPrefix), getCurrOwner(c), info)
let r = newSym(skTemp, getIdent(c.graph.cache, genPrefix), nextId(c.idgen), getCurrOwner(c), info)
r.typ = typ #skipTypes(typ, {tyGenericInst, tyAlias, tySink})
incl(r.flags, sfFromGeneric)
let owner = getCurrOwner(c)
if owner.isIterator and not c.tooEarly:
result = freshVarForClosureIter(c.graph, r, owner)
result = freshVarForClosureIter(c.graph, r, c.idgen, owner)
else:
result = newSymNode(r)
@ -111,13 +112,13 @@ proc transformSymAux(c: PTransf, n: PNode): PNode =
let s = n.sym
if s.typ != nil and s.typ.callConv == ccClosure:
if s.kind in routineKinds:
discard transformBody(c.graph, s, true)
discard transformBody(c.graph, c.idgen, s, true)
if s.kind == skIterator:
if c.tooEarly: return n
else: return liftIterSym(c.graph, n, getCurrOwner(c))
else: return liftIterSym(c.graph, n, c.idgen, 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(c.graph, s, nil, n.info)
return makeClosure(c.graph, c.idgen, 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:
@ -160,9 +161,9 @@ proc transformSym(c: PTransf, n: PNode): PNode =
proc freshVar(c: PTransf; v: PSym): PNode =
let owner = getCurrOwner(c)
if owner.isIterator and not c.tooEarly:
result = freshVarForClosureIter(c.graph, v, owner)
result = freshVarForClosureIter(c.graph, v, c.idgen, owner)
else:
var newVar = copySym(v)
var newVar = copySym(v, nextId(c.idgen))
incl(newVar.flags, sfFromGeneric)
newVar.owner = owner
result = newSymNode(newVar)
@ -232,7 +233,7 @@ proc hasContinue(n: PNode): bool =
if hasContinue(n[i]): return true
proc newLabel(c: PTransf, n: PNode): PSym =
result = newSym(skLabel, nil, getCurrOwner(c), n.info)
result = newSym(skLabel, nil, nextId(c.idgen), getCurrOwner(c), n.info)
result.name = getIdent(c.graph.cache, genPrefix)
proc transformBlock(c: PTransf, n: PNode): PNode =
@ -423,7 +424,7 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
result.typ = n.typ
elif n.typ.skipTypes(abstractInst).kind in {tyVar}:
result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind)
result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind, c.idgen)
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
var m = n[0][1]
if m.kind == a or m.kind == b:
@ -433,7 +434,7 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
result.typ = n.typ
elif n.typ.skipTypes(abstractInst).kind in {tyVar}:
result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind)
result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind, c.idgen)
else:
if n[0].kind == a or n[0].kind == b:
# addr ( deref ( x )) --> x
@ -495,7 +496,7 @@ proc transformConv(c: PTransf, n: PNode): PNode =
of tyOpenArray, tyVarargs:
result = transform(c, n[1])
#result = transformSons(c, n)
result.typ = takeType(n.typ, n[1].typ)
result.typ = takeType(n.typ, n[1].typ, c.idgen)
#echo n.info, " came here and produced ", typeToString(result.typ),
# " from ", typeToString(n.typ), " and ", typeToString(n[1].typ)
of tyCString:
@ -629,7 +630,7 @@ proc transformFor(c: PTransf, n: PNode): PNode =
result[1] = n
result[1][^1] = transformLoopBody(c, n[^1])
result[1][^2] = transform(c, n[^2])
result[1] = lambdalifting.liftForLoop(c.graph, result[1], getCurrOwner(c))
result[1] = lambdalifting.liftForLoop(c.graph, result[1], c.idgen, getCurrOwner(c))
discard c.breakSyms.pop
return result
@ -698,7 +699,7 @@ proc transformFor(c: PTransf, n: PNode): PNode =
stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg))
idNodeTablePut(newC.mapping, formal, temp)
let body = transformBody(c.graph, iter, true)
let body = transformBody(c.graph, c.idgen, iter, true)
pushInfoContext(c.graph.config, n.info)
inc(c.inlining)
stmtList.add(transform(c, body))
@ -830,7 +831,7 @@ proc transformExceptBranch(c: PTransf, n: PNode): PNode =
let convNode = newTransNode(nkHiddenSubConv, n[1].info, 2)
convNode[0] = newNodeI(nkEmpty, n.info)
convNode[1] = excCall
convNode.typ = excTypeNode.typ.toRef()
convNode.typ = excTypeNode.typ.toRef(c.idgen)
# -> let exc = ...
let identDefs = newTransNode(nkIdentDefs, n[1].info, 3)
identDefs[0] = n[0][2]
@ -850,10 +851,10 @@ proc transformExceptBranch(c: PTransf, n: PNode): PNode =
else:
result = transformSons(c, n)
proc commonOptimizations*(g: ModuleGraph; c: PSym, n: PNode): PNode =
proc commonOptimizations*(g: ModuleGraph; idgen: IdGenerator; c: PSym, n: PNode): PNode =
result = n
for i in 0..<n.safeLen:
result[i] = commonOptimizations(g, c, n[i])
result[i] = commonOptimizations(g, idgen, c, n[i])
var op = getMergeOp(n)
if (op != nil) and (op.magic != mNone) and (n.len >= 3):
result = newNodeIT(nkCall, n.info, n.typ)
@ -873,7 +874,7 @@ proc commonOptimizations*(g: ModuleGraph; c: PSym, n: PNode): PNode =
result.add(a)
if result.len == 2: result = result[1]
else:
var cnst = getConstExpr(c, n, g)
var cnst = getConstExpr(c, n, idgen, g)
# we inline constants if they are not complex constants:
if cnst != nil and not dontInlineConstant(n, cnst):
result = cnst
@ -1012,7 +1013,7 @@ proc transform(c: PTransf, n: PNode): PNode =
n.typ != nil and
n.typ.kind == tyPointer
if not exprIsPointerCast:
var cnst = getConstExpr(c.module, result, c.graph)
var cnst = getConstExpr(c.module, result, c.idgen, c.graph)
# we inline constants if they are not complex constants:
if cnst != nil and not dontInlineConstant(n, cnst):
result = cnst # do not miss an optimization
@ -1027,12 +1028,13 @@ proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode =
popTransCon(c)
incl(result.flags, nfTransf)
proc openTransf(g: ModuleGraph; module: PSym, filename: string): PTransf =
proc openTransf(g: ModuleGraph; module: PSym, filename: string; idgen: IdGenerator): PTransf =
new(result)
result.contSyms = @[]
result.breakSyms = @[]
result.module = module
result.graph = g
result.idgen = idgen
proc flattenStmts(n: PNode) =
var goOn = true
@ -1075,7 +1077,7 @@ template liftDefer(c, root) =
if c.deferDetected:
liftDeferAux(root)
proc transformBody*(g: ModuleGraph, prc: PSym, cache: bool): PNode =
proc transformBody*(g: ModuleGraph; idgen: IdGenerator; prc: PSym; cache: bool): PNode =
assert prc.kind in routineKinds
if prc.transformedBody != nil:
@ -1084,14 +1086,14 @@ proc transformBody*(g: ModuleGraph, prc: PSym, cache: bool): PNode =
result = prc.ast[bodyPos]
else:
prc.transformedBody = newNode(nkEmpty) # protects from recursion
var c = openTransf(g, prc.getModule, "")
result = liftLambdas(g, prc, prc.ast[bodyPos], c.tooEarly)
var c = openTransf(g, prc.getModule, "", idgen)
result = liftLambdas(g, prc, prc.ast[bodyPos], c.tooEarly, c.idgen)
result = processTransf(c, result, prc)
liftDefer(c, result)
result = liftLocalsIfRequested(prc, result, g.cache, g.config)
result = liftLocalsIfRequested(prc, result, g.cache, g.config, c.idgen)
if prc.isIterator:
result = g.transformClosureIterator(prc, result)
result = g.transformClosureIterator(c.idgen, prc, result)
incl(result.flags, nfTransf)
@ -1105,21 +1107,21 @@ proc transformBody*(g: ModuleGraph, prc: PSym, cache: bool): PNode =
#if prc.name.s == "main":
# echo "transformed into ", renderTree(result, {renderIds})
proc transformStmt*(g: ModuleGraph; module: PSym, n: PNode): PNode =
proc transformStmt*(g: ModuleGraph; idgen: IdGenerator; module: PSym, n: PNode): PNode =
if nfTransf in n.flags:
result = n
else:
var c = openTransf(g, module, "")
var c = openTransf(g, module, "", idgen)
result = processTransf(c, n, module)
liftDefer(c, result)
#result = liftLambdasForTopLevel(module, result)
incl(result.flags, nfTransf)
proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode =
proc transformExpr*(g: ModuleGraph; idgen: IdGenerator; module: PSym, n: PNode): PNode =
if nfTransf in n.flags:
result = n
else:
var c = openTransf(g, module, "")
var c = openTransf(g, module, "", idgen)
result = processTransf(c, n, module)
liftDefer(c, result)
# expressions are not to be injected with destructor calls as that