summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/nir/ast2ir.nim53
-rw-r--r--compiler/nir/nirc.nim2
-rw-r--r--compiler/nir/nirinsts.nim6
-rw-r--r--compiler/nir/nirslots.nim41
-rw-r--r--compiler/nir/nirtypes.nim3
5 files changed, 61 insertions, 44 deletions
diff --git a/compiler/nir/ast2ir.nim b/compiler/nir/ast2ir.nim
index fd3a4df09..0920f5d8a 100644
--- a/compiler/nir/ast2ir.nim
+++ b/compiler/nir/ast2ir.nim
@@ -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")
diff --git a/compiler/nir/nirc.nim b/compiler/nir/nirc.nim
index da8d7d778..3d8c8e6ff 100644
--- a/compiler/nir/nirc.nim
+++ b/compiler/nir/nirc.nim
@@ -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
diff --git a/compiler/nir/nirinsts.nim b/compiler/nir/nirinsts.nim
index 741733d48..d95cd061d 100644
--- a/compiler/nir/nirinsts.nim
+++ b/compiler/nir/nirinsts.nim
@@ -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
diff --git a/compiler/nir/nirslots.nim b/compiler/nir/nirslots.nim
index d983fdea2..a01e7a633 100644
--- a/compiler/nir/nirslots.nim
+++ b/compiler/nir/nirslots.nim
@@ -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
-
-
diff --git a/compiler/nir/nirtypes.nim b/compiler/nir/nirtypes.nim
index 288f3063d..e07f1395d 100644
--- a/compiler/nir/nirtypes.nim
+++ b/compiler/nir/nirtypes.nim
@@ -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