NIR: temporary ID generation bugfix (#22830)

This commit is contained in:
Andreas Rumpf
2023-10-16 15:47:13 +02:00
committed by GitHub
parent a9bc6779e1
commit 3c48af7ebe
5 changed files with 61 additions and 44 deletions

View File

@@ -25,12 +25,12 @@ type
man*: LineInfoManager
lit*: Literals
types*: TypesCon
slotGenerator: ref int
module*: PSym
graph*: ModuleGraph
nativeIntId, nativeUIntId: TypeId
idgen: IdGenerator
pendingProcs: Table[ItemId, PSym] # procs we still need to generate code for
processedProcs: HashSet[ItemId]
pendingProcs: seq[PSym] # procs we still need to generate code for
ProcCon* = object
config*: ConfigRef
@@ -42,16 +42,14 @@ type
code*: Tree
blocks: seq[(PSym, LabelId)]
sm: SlotManager
locGen: int
idgen: IdGenerator
m: ModuleCon
prc: PSym
options: TOptions
proc initModuleCon*(graph: ModuleGraph; config: ConfigRef; idgen: IdGenerator; module: PSym): ModuleCon =
let lit = Literals() # must be shared
var g = new(int)
g[] = idgen.symId + 1
result = ModuleCon(graph: graph, types: initTypesCon(config, lit), slotGenerator: g,
result = ModuleCon(graph: graph, types: initTypesCon(config, lit),
idgen: idgen, module: module, lit: lit)
case config.target.intSize
of 2:
@@ -65,8 +63,8 @@ proc initModuleCon*(graph: ModuleGraph; config: ConfigRef; idgen: IdGenerator; m
result.nativeUIntId = UInt16Id
proc initProcCon*(m: ModuleCon; prc: PSym; config: ConfigRef): ProcCon =
ProcCon(m: m, sm: initSlotManager({}, m.slotGenerator), prc: prc, config: config,
lit: m.lit,
ProcCon(m: m, sm: initSlotManager({}), prc: prc, config: config,
lit: m.lit, idgen: m.idgen,
options: if prc != nil: prc.options
else: config.options)
@@ -117,12 +115,12 @@ proc freeTemp(c: var ProcCon; tmp: Value) =
proc getTemp(c: var ProcCon; n: PNode): Value =
let info = toLineInfo(c, n.info)
let t = typeToIr(c.m.types, n.typ)
let tmp = allocTemp(c.sm, t)
let tmp = allocTemp(c.sm, t, c.idgen.symId)
c.code.addSummon info, tmp, t
result = localToValue(info, tmp)
proc getTemp(c: var ProcCon; t: TypeId; info: PackedLineInfo): Value =
let tmp = allocTemp(c.sm, t)
let tmp = allocTemp(c.sm, t, c.idgen.symId)
c.code.addSummon info, tmp, t
result = localToValue(info, tmp)
@@ -322,7 +320,6 @@ proc addUseCodegenProc(c: var ProcCon; dest: var Tree; name: string; info: Packe
template buildCond(useNegation: bool; cond: typed; body: untyped) =
let lab = newLabel(c.labelGen)
#let info = toLineInfo(c, n.info)
buildTyped c.code, info, Select, Bool8Id:
c.code.copyTree cond
build c.code, info, SelectPair:
@@ -998,7 +995,7 @@ proc genEqSet(c: var ProcCon; n: PNode; d: var Value) =
freeTemp c, a
proc beginCountLoop(c: var ProcCon; info: PackedLineInfo; first, last: int): (SymId, LabelId, LabelId) =
let tmp = allocTemp(c.sm, c.m.nativeIntId)
let tmp = allocTemp(c.sm, c.m.nativeIntId, c.idgen.symId)
c.code.addSummon info, tmp, c.m.nativeIntId
buildTyped c.code, info, Asgn, c.m.nativeIntId:
c.code.addSymUse info, tmp
@@ -1016,7 +1013,7 @@ proc beginCountLoop(c: var ProcCon; info: PackedLineInfo; first, last: int): (Sy
c.code.gotoLabel info, Goto, result[2]
proc beginCountLoop(c: var ProcCon; info: PackedLineInfo; first, last: Value): (SymId, LabelId, LabelId) =
let tmp = allocTemp(c.sm, c.m.nativeIntId)
let tmp = allocTemp(c.sm, c.m.nativeIntId, c.idgen.symId)
c.code.addSummon info, tmp, c.m.nativeIntId
buildTyped c.code, info, Asgn, c.m.nativeIntId:
c.code.addSymUse info, tmp
@@ -1400,7 +1397,7 @@ proc genStrConcat(c: var ProcCon; n: PNode; d: var Value) =
args.add genx(c, it)
# generate length computation:
var tmpLen = allocTemp(c.sm, c.m.nativeIntId)
var tmpLen = allocTemp(c.sm, c.m.nativeIntId, c.idgen.symId)
buildTyped c.code, info, Asgn, c.m.nativeIntId:
c.code.addSymUse info, tmpLen
c.code.addIntVal c.lit.numbers, info, c.m.nativeIntId, precomputedLen
@@ -2108,8 +2105,8 @@ proc genSym(c: var ProcCon; n: PNode; d: var Value; flags: GenFlags = {}) =
if ast.originatingModule(s) == c.m.module:
# anon and generic procs have no AST so we need to remember not to forget
# to emit these:
if not c.m.pendingProcs.hasKey(s.itemId):
c.m.pendingProcs[s.itemId] = s
if not c.m.processedProcs.containsOrIncl(s.itemId):
c.m.pendingProcs.add s
genRdVar(c, n, d, flags)
of skEnumField:
let info = toLineInfo(c, n.info)
@@ -2270,10 +2267,9 @@ proc addCallConv(c: var ProcCon; info: PackedLineInfo; callConv: TCallingConvent
of ccThisCall: ann ThisCall
of ccNoConvention: ann NoCall
proc genProc(cOuter: var ProcCon; n: PNode) =
if n.len == 0 or n[namePos].kind != nkSym: return
let prc = n[namePos].sym
if isGenericRoutineStrict(prc) or isCompileTimeProc(prc): return
proc genProc(cOuter: var ProcCon; prc: PSym) =
if cOuter.m.processedProcs.containsOrIncl(prc.itemId):
return
var c = initProcCon(cOuter.m, prc, cOuter.m.graph.config)
@@ -2312,6 +2308,12 @@ proc genProc(cOuter: var ProcCon; n: PNode) =
copyTree cOuter.code, c.code
proc genProc(cOuter: var ProcCon; n: PNode) =
if n.len == 0 or n[namePos].kind != nkSym: return
let prc = n[namePos].sym
if isGenericRoutineStrict(prc) or isCompileTimeProc(prc): return
genProc cOuter, prc
proc gen(c: var ProcCon; n: PNode; d: var Value; flags: GenFlags = {}) =
when defined(nimCompilerStacktraceHints):
setFrameMsg c.config$n.info & " " & $n.kind & " " & $flags
@@ -2405,19 +2407,30 @@ proc gen(c: var ProcCon; n: PNode; d: var Value; flags: GenFlags = {}) =
genConv(c, n, n[1], d, flags, Cast)
of nkComesFrom:
discard "XXX to implement for better stack traces"
#of nkState: genState(c, n)
#of nkGotoState: genGotoState(c, n)
#of nkBreakState: genBreakState(c, n, d)
else:
localError(c.config, n.info, "cannot generate IR code for " & $n)
proc genPendingProcs(c: var ProcCon) =
while c.m.pendingProcs.len > 0:
let procs = move(c.m.pendingProcs)
for v in procs:
genProc(c, v)
proc genStmt*(c: var ProcCon; n: PNode): int =
result = c.code.len
var d = default(Value)
c.gen(n, d)
unused c, n, d
genPendingProcs c
proc genExpr*(c: var ProcCon; n: PNode, requiresValue = true): int =
result = c.code.len
var d = default(Value)
c.gen(n, d)
genPendingProcs c
if isEmpty d:
if requiresValue:
globalError(c.config, n.info, "VM problem: d register is not set")

View File

@@ -41,6 +41,8 @@ proc view(filename: string) =
var res = ""
allTreesToString code, lit.strings, lit.numbers, res
res.add "\n# TYPES\n"
nirtypes.toString res, types
echo res
import std / os

View File

@@ -368,8 +368,9 @@ proc toString*(t: Tree; pos: NodePos; strings: BiTable[string]; integers: BiTabl
of PragmaId:
r.add $cast[PragmaKey](t[pos].operand)
of Typed:
r.add "Typed "
r.add "T<"
r.add $t[pos].operand
r.add ">"
of NilVal:
r.add "NilVal"
of Label:
@@ -377,7 +378,7 @@ proc toString*(t: Tree; pos: NodePos; strings: BiTable[string]; integers: BiTabl
r.add $t[pos].operand
of Goto, CheckedGoto, LoopLabel, GotoLoop:
r.add $t[pos].kind
r.add ' '
r.add " L"
r.add $t[pos].operand
else:
r.add $t[pos].kind
@@ -391,7 +392,6 @@ proc toString*(t: Tree; pos: NodePos; strings: BiTable[string]; integers: BiTabl
proc allTreesToString*(t: Tree; strings: BiTable[string]; integers: BiTable[int64];
r: var string) =
var i = 0
while i < t.len:
toString t, NodePos(i), strings, integers, r

View File

@@ -24,25 +24,25 @@ type
dead: Table[TypeId, seq[SymId]]
flags: set[SlotManagerFlag]
inScope: seq[SymId]
locGen: ref int
proc initSlotManager*(flags: set[SlotManagerFlag]; generator: ref int): SlotManager {.inline.} =
SlotManager(flags: flags, locGen: generator)
proc initSlotManager*(flags: set[SlotManagerFlag]): SlotManager {.inline.} =
SlotManager(flags: flags)
proc allocRaw(m: var SlotManager; t: TypeId; f: SlotManagerFlag; k: SlotKind): SymId {.inline.} =
proc allocRaw(m: var SlotManager; t: TypeId; f: SlotManagerFlag; k: SlotKind;
symIdgen: var int32): SymId {.inline.} =
if f in m.flags and m.dead.hasKey(t) and m.dead[t].len > 0:
result = m.dead[t].pop()
else:
result = SymId(m.locGen[])
inc m.locGen[]
inc symIdgen
result = SymId(symIdgen)
m.inScope.add result
m.live[result] = (k, t)
proc allocTemp*(m: var SlotManager; t: TypeId): SymId {.inline.} =
result = allocRaw(m, t, ReuseTemps, Temp)
proc allocTemp*(m: var SlotManager; t: TypeId; symIdgen: var int32): SymId {.inline.} =
result = allocRaw(m, t, ReuseTemps, Temp, symIdgen)
proc allocVar*(m: var SlotManager; t: TypeId): SymId {.inline.} =
result = allocRaw(m, t, ReuseVars, Perm)
proc allocVar*(m: var SlotManager; t: TypeId; symIdgen: var int32): SymId {.inline.} =
result = allocRaw(m, t, ReuseVars, Perm, symIdgen)
proc freeLoc*(m: var SlotManager; s: SymId) =
let t = m.live.getOrDefault(s)
@@ -74,32 +74,31 @@ proc closeScope*(m: var SlotManager) =
dec i
when isMainModule:
var m = initSlotManager({ReuseTemps}, new(int))
var symIdgen: int32
var m = initSlotManager({ReuseTemps})
var g = initTypeGraph(Literals())
let a = g.openType ArrayTy
g.addBuiltinType Int8Id
g.addArrayLen 5'u64
let finalArrayType = sealType(g, a)
g.addArrayLen 5
let finalArrayType = finishType(g, a)
let obj = g.openType ObjectDecl
g.addName "MyType"
g.addField "p", finalArrayType
let objB = sealType(g, obj)
g.addField "p", finalArrayType, 0
let objB = finishType(g, obj)
let x = m.allocTemp(objB)
let x = m.allocTemp(objB, symIdgen)
assert x.int == 0
let y = m.allocTemp(objB)
let y = m.allocTemp(objB, symIdgen)
assert y.int == 1
let z = m.allocTemp(Int8Id)
let z = m.allocTemp(Int8Id, symIdgen)
assert z.int == 2
m.freeLoc y
let y2 = m.allocTemp(objB)
let y2 = m.allocTemp(objB, symIdgen)
assert y2.int == 1

View File

@@ -392,6 +392,9 @@ proc toString*(dest: var string; g: TypeGraph; i: TypeId) =
proc toString*(dest: var string; g: TypeGraph) =
var i = 0
while i < g.len:
dest.add "T<"
dest.addInt i
dest.add "> "
toString(dest, g, TypeId i)
dest.add '\n'
nextChild g, i