mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-06 11:54:11 +00:00
NIR: temporary ID generation bugfix (#22830)
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user