summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/macrocacheimpl.nim84
-rw-r--r--compiler/modulegraphs.nim8
-rw-r--r--compiler/rodimpl.nim41
-rw-r--r--compiler/vm.nim64
-rw-r--r--compiler/vmdef.nim8
-rw-r--r--compiler/vmgen.nim12
6 files changed, 147 insertions, 70 deletions
diff --git a/compiler/macrocacheimpl.nim b/compiler/macrocacheimpl.nim
index 5c27f9265..d23040763 100644
--- a/compiler/macrocacheimpl.nim
+++ b/compiler/macrocacheimpl.nim
@@ -11,39 +11,69 @@
 
 import lineinfos, ast, modulegraphs, vmdef, magicsys
 
-proc genCall3(g: ModuleGraph; m: TMagic; s: string; a, b, c: PNode): PNode =
-  newTree(nkStaticStmt, newTree(nkCall, createMagic(g, s, m).newSymNode, a, b, c))
+proc recordInc*(c: PCtx; info: TLineInfo; key: string; by: BiggestInt) =
+  var recorded = newNodeI(nkCommentStmt, info)
+  recorded.add newStrNode("inc", info)
+  recorded.add newStrNode(key, info)
+  recorded.add newIntNode(nkIntLit, by)
+  c.graph.recordStmt(c.graph, c.module, recorded)
 
-proc genCall2(g: ModuleGraph; m: TMagic; s: string; a, b: PNode): PNode =
-  newTree(nkStaticStmt, newTree(nkCall, createMagic(g, s, m).newSymNode, a, b))
+proc recordPut*(c: PCtx; info: TLineInfo; key: string; k: string; val: PNode) =
+  var recorded = newNodeI(nkCommentStmt, info)
+  recorded.add newStrNode("put", info)
+  recorded.add newStrNode(key, info)
+  recorded.add newStrNode(k, info)
+  recorded.add copyTree(val)
+  c.graph.recordStmt(c.graph, c.module, recorded)
 
-template nodeFrom(s: string): PNode =
-  var res = newStrNode(s, info)
-  res.typ = getSysType(g, info, tyString)
-  res
+proc recordAdd*(c: PCtx; info: TLineInfo; key: string; val: PNode) =
+  var recorded = newNodeI(nkCommentStmt, info)
+  recorded.add newStrNode("add", info)
+  recorded.add newStrNode(key, info)
+  recorded.add copyTree(val)
+  c.graph.recordStmt(c.graph, c.module, recorded)
 
-template nodeFrom(i: BiggestInt): PNode =
-  var res = newIntNode(i, info)
-  res.typ = getSysType(g, info, tyInt)
-  res
+proc recordIncl*(c: PCtx; info: TLineInfo; key: string; val: PNode) =
+  var recorded = newNodeI(nkCommentStmt, info)
+  recorded.add newStrNode("incl", info)
+  recorded.add newStrNode(key, info)
+  recorded.add copyTree(val)
+  c.graph.recordStmt(c.graph, c.module, recorded)
 
-template nodeFrom(n: PNode): PNode = copyTree(n)
+when false:
+  proc genCall3(g: ModuleGraph; m: TMagic; s: string; a, b, c: PNode): PNode =
+    newTree(nkStaticStmt, newTree(nkCall, createMagic(g, s, m).newSymNode, a, b, c))
 
-template record(call) =
-  g.recordStmt(g, c.module, call)
+  proc genCall2(g: ModuleGraph; m: TMagic; s: string; a, b: PNode): PNode =
+    newTree(nkStaticStmt, newTree(nkCall, createMagic(g, s, m).newSymNode, a, b))
 
-proc recordInc*(c: PCtx; info: TLineInfo; key: string; by: BiggestInt) =
-  let g = c.graph
-  record genCall2(mNccInc, "inc", nodeFrom key, nodeFrom by)
+  template nodeFrom(s: string): PNode =
+    var res = newStrNode(s, info)
+    res.typ = getSysType(g, info, tyString)
+    res
 
-proc recordPut*(c: PCtx; info: TLineInfo; key: string; k: string; val: PNode) =
-  let g = c.graph
-  record genCall3(mNctPut, "[]=", nodeFrom key, nodeFrom k, nodeFrom val)
+  template nodeFrom(i: BiggestInt): PNode =
+    var res = newIntNode(i, info)
+    res.typ = getSysType(g, info, tyInt)
+    res
 
-proc recordAdd*(c: PCtx; info: TLineInfo; key: string; val: PNode) =
-  let g = c.graph
-  record genCall2(mNcsAdd, "add", nodeFrom key, nodeFrom val)
+  template nodeFrom(n: PNode): PNode = copyTree(n)
 
-proc recordIncl*(c: PCtx; info: TLineInfo; key: string; val: PNode) =
-  let g = c.graph
-  record genCall2(mNcsIncl, "incl", nodeFrom key, nodeFrom val)
+  template record(call) =
+    g.recordStmt(g, c.module, call)
+
+  proc recordInc*(c: PCtx; info: TLineInfo; key: string; by: BiggestInt) =
+    let g = c.graph
+    record genCall2(mNccInc, "inc", nodeFrom key, nodeFrom by)
+
+  proc recordPut*(c: PCtx; info: TLineInfo; key: string; k: string; val: PNode) =
+    let g = c.graph
+    record genCall3(mNctPut, "[]=", nodeFrom key, nodeFrom k, nodeFrom val)
+
+  proc recordAdd*(c: PCtx; info: TLineInfo; key: string; val: PNode) =
+    let g = c.graph
+    record genCall2(mNcsAdd, "add", nodeFrom key, nodeFrom val)
+
+  proc recordIncl*(c: PCtx; info: TLineInfo; key: string; val: PNode) =
+    let g = c.graph
+    record genCall2(mNcsIncl, "incl", nodeFrom key, nodeFrom val)
diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim
index f214309a5..334cd1ae6 100644
--- a/compiler/modulegraphs.nim
+++ b/compiler/modulegraphs.nim
@@ -26,7 +26,7 @@
 ##
 
 import ast, intsets, tables, options, lineinfos, hashes, idents,
-  incremental
+  incremental, btrees
 
 type
   ModuleGraph* = ref object
@@ -59,6 +59,9 @@ type
     importModuleCallback*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex): PSym {.nimcall.}
     includeFileCallback*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex): PNode {.nimcall.}
     recordStmt*: proc (graph: ModuleGraph; m: PSym; n: PNode) {.nimcall.}
+    cacheSeqs*: Table[string, PNode] # state that is shared to suppor the 'macrocache' API
+    cacheCounters*: Table[string, BiggestInt]
+    cacheTables*: Table[string, BTree[string, PNode]]
 
 proc hash*(x: FileIndex): Hash {.borrow.}
 
@@ -90,6 +93,9 @@ proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
   init(result.incr)
   result.recordStmt = proc (graph: ModuleGraph; m: PSym; n: PNode) {.nimcall.} =
     discard
+  result.cacheSeqs = initTable[string, PNode]()
+  result.cacheCounters = initTable[string, BiggestInt]()
+  result.cacheTables = initTable[string, BTree[string, PNode]]()
 
 proc resetAllModules*(g: ModuleGraph) =
   initStrTable(packageSyms)
diff --git a/compiler/rodimpl.nim b/compiler/rodimpl.nim
index e2160aa84..fffec0004 100644
--- a/compiler/rodimpl.nim
+++ b/compiler/rodimpl.nim
@@ -10,7 +10,8 @@
 ## This module implements the new compilation cache.
 
 import strutils, os, intsets, tables, ropes, db_sqlite, msgs, options, types,
-  renderer, rodutils, idents, astalgo, btrees, magicsys, cgmeth, extccomp, vm
+  renderer, rodutils, idents, astalgo, btrees, magicsys, cgmeth, extccomp,
+  btrees, trees
 
 ## Todo:
 ## - Make conditional symbols and the configuration part of a module's
@@ -757,9 +758,10 @@ proc loadModuleSymTab(g; module: PSym) =
     g.systemModule = module
 
 proc replay(g: ModuleGraph; module: PSym; n: PNode) =
+  # XXX check if we need to replay nkStaticStmt here.
   case n.kind
-  of nkStaticStmt:
-    evalStaticStmt(module, g, n[0], module)
+  #of nkStaticStmt:
+    #evalStaticStmt(module, g, n[0], module)
     #of nkVarSection, nkLetSection:
     #  nkVarSections are already covered by the vmgen which produces nkStaticStmt
   of nkMethodDef:
@@ -786,6 +788,39 @@ proc replay(g: ModuleGraph; module: PSym; n: PNode) =
         extccomp.addExternalFileToCompile(g.config, cf)
       of "link":
         extccomp.addExternalFileToLink(g.config, n[1].strVal)
+      of "inc":
+        let destKey = n[1].strVal
+        let by = n[2].intVal
+        let v = getOrDefault(g.cacheCounters, destKey)
+        g.cacheCounters[destKey] = v+by
+      of "put":
+        let destKey = n[1].strVal
+        let key = n[2].strVal
+        let val = n[3]
+        if not contains(g.cacheTables, destKey):
+          g.cacheTables[destKey] = initBTree[string, PNode]()
+        if not contains(g.cacheTables[destKey], key):
+          g.cacheTables[destKey].add(key, val)
+        else:
+          internalError(g.config, n.info, "key already exists: " & key)
+      of "incl":
+        let destKey = n[1].strVal
+        let val = n[2]
+        if not contains(g.cacheSeqs, destKey):
+          g.cacheSeqs[destKey] = newTree(nkStmtList, val)
+        else:
+          block search:
+            for existing in g.cacheSeqs[destKey]:
+              if exprStructuralEquivalent(existing, val, strictSymEquality=true):
+                break search
+            g.cacheSeqs[destKey].add val
+      of "add":
+        let destKey = n[1].strVal
+        let val = n[2]
+        if not contains(g.cacheSeqs, destKey):
+          g.cacheSeqs[destKey] = newTree(nkStmtList, val)
+        else:
+          g.cacheSeqs[destKey].add val
       else:
         internalAssert g.config, false
   of nkImportStmt:
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 019aa08e8..3e33e8256 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1576,86 +1576,98 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcNccValue:
       decodeB(rkInt)
       let destKey = regs[rb].node.strVal
-      regs[ra].intVal = getOrDefault(c.cacheCounters, destKey)
+      regs[ra].intVal = getOrDefault(c.graph.cacheCounters, destKey)
     of opcNccInc:
-      let rb = instr.regB
+      let g = c.graph
       let destKey = regs[ra].node.strVal
-      let by = regs[rb].intVal
-      let v = getOrDefault(c.cacheCounters, destKey)
-      c.cacheCounters[destKey] = v+by
+      let by = regs[instr.regB].intVal
+      let v = getOrDefault(g.cacheCounters, destKey)
+      g.cacheCounters[destKey] = v+by
       recordInc(c, c.debug[pc], destKey, by)
     of opcNcsAdd:
+      let g = c.graph
       let destKey = regs[ra].node.strVal
       let val = regs[instr.regB].node
-      if not contains(c.cacheSeqs, destKey):
-        c.cacheSeqs[destKey] = newTree(nkStmtList, val)
+      if not contains(g.cacheSeqs, destKey):
+        g.cacheSeqs[destKey] = newTree(nkStmtList, val)
         # newNodeI(nkStmtList, c.debug[pc])
       else:
-        c.cacheSeqs[destKey].add val
+        g.cacheSeqs[destKey].add val
       recordAdd(c, c.debug[pc], destKey, val)
     of opcNcsIncl:
+      let g = c.graph
       let destKey = regs[ra].node.strVal
       let val = regs[instr.regB].node
-      if not contains(c.cacheSeqs, destKey):
-        c.cacheSeqs[destKey] = newTree(nkStmtList, val)
+      if not contains(g.cacheSeqs, destKey):
+        g.cacheSeqs[destKey] = newTree(nkStmtList, val)
       else:
         block search:
-          for existing in c.cacheSeqs[destKey]:
+          for existing in g.cacheSeqs[destKey]:
             if exprStructuralEquivalent(existing, val, strictSymEquality=true):
               break search
-          c.cacheSeqs[destKey].add val
+          g.cacheSeqs[destKey].add val
       recordIncl(c, c.debug[pc], destKey, val)
     of opcNcsLen:
+      let g = c.graph
       decodeB(rkInt)
       let destKey = regs[rb].node.strVal
       regs[ra].intVal =
-        if contains(c.cacheSeqs, destKey): c.cacheSeqs[destKey].len else: 0
+        if contains(g.cacheSeqs, destKey): g.cacheSeqs[destKey].len else: 0
     of opcNcsAt:
+      let g = c.graph
       decodeBC(rkNode)
       let idx = regs[rc].intVal
       let destKey = regs[rb].node.strVal
-      if contains(c.cacheSeqs, destKey) and idx <% c.cacheSeqs[destKey].len:
-        regs[ra].node = c.cacheSeqs[destKey][idx.int]
+      if contains(g.cacheSeqs, destKey) and idx <% g.cacheSeqs[destKey].len:
+        regs[ra].node = g.cacheSeqs[destKey][idx.int]
       else:
         stackTrace(c, tos, pc, errIndexOutOfBounds)
     of opcNctPut:
+      let g = c.graph
       let destKey = regs[ra].node.strVal
       let key = regs[instr.regB].node.strVal
       let val = regs[instr.regC].node
-      if not contains(c.cacheTables, destKey):
-        c.cacheTables[destKey] = initBTree[string, PNode]()
-      if not contains(c.cacheTables[destKey], key):
-        c.cacheTables[destKey].add(key, val)
+      if not contains(g.cacheTables, destKey):
+        g.cacheTables[destKey] = initBTree[string, PNode]()
+      if not contains(g.cacheTables[destKey], key):
+        g.cacheTables[destKey].add(key, val)
         recordPut(c, c.debug[pc], destKey, key, val)
       else:
         stackTrace(c, tos, pc, "key already exists: " & key)
     of opcNctLen:
+      let g = c.graph
       decodeB(rkInt)
       let destKey = regs[rb].node.strVal
       regs[ra].intVal =
-        if contains(c.cacheTables, destKey): c.cacheTables[destKey].len else: 0
+        if contains(g.cacheTables, destKey): g.cacheTables[destKey].len else: 0
     of opcNctGet:
+      let g = c.graph
       decodeBC(rkNode)
       let destKey = regs[rb].node.strVal
       let key = regs[rc].node.strVal
-      if contains(c.cacheTables, destKey):
-        if contains(c.cacheTables[destKey], key):
-          regs[ra].node = getOrDefault(c.cacheTables[destKey], key)
+      if contains(g.cacheTables, destKey):
+        if contains(g.cacheTables[destKey], key):
+          regs[ra].node = getOrDefault(g.cacheTables[destKey], key)
         else:
           stackTrace(c, tos, pc, "key does not exist: " & key)
       else:
         stackTrace(c, tos, pc, "key does not exist: " & destKey)
     of opcNctHasNext:
+      let g = c.graph
       decodeBC(rkInt)
       let destKey = regs[rb].node.strVal
       regs[ra].intVal =
-        btrees.hasNext(c.cacheTables[destKey], regs[rc].intVal.int) else: 0
+        if g.cacheTables.contains(destKey):
+          ord(btrees.hasNext(g.cacheTables[destKey], regs[rc].intVal.int))
+        else:
+          0
     of opcNctNext:
+      let g = c.graph
       decodeBC(rkNode)
       let destKey = regs[rb].node.strVal
       let index = regs[rc].intVal
-      if contains(c.cacheTables, destKey):
-        let (k, v, nextIndex) = btrees.next(c.cacheTables[destKey], index.int)
+      if contains(g.cacheTables, destKey):
+        let (k, v, nextIndex) = btrees.next(g.cacheTables[destKey], index.int)
         regs[ra].node = newTree(nkTupleConstr, newStrNode(k, c.debug[pc]), v,
                                 newIntNode(nkIntLit, nextIndex))
       else:
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index 1ef984466..cec61ade5 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -213,9 +213,6 @@ type
     config*: ConfigRef
     graph*: ModuleGraph
     oldErrorCount*: int
-    cacheSeqs*: Table[string, PNode]
-    cacheCounters*: Table[string, BiggestInt]
-    cacheTables*: Table[string, BTree[string, PNode]]
 
   TPosition* = distinct int
 
@@ -226,10 +223,7 @@ proc newCtx*(module: PSym; cache: IdentCache; g: ModuleGraph): PCtx =
     globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[],
     prc: PProc(blocks: @[]), module: module, loopIterations: MaxLoopIterations,
     comesFromHeuristic: unknownLineInfo(), callbacks: @[], errorFlag: "",
-    cache: cache, config: g.config, graph: g,
-    cacheSeqs: initTable[string, PNode]()
-    cacheCounters: initTable[string, BiggestInt]()
-    cacheTables: initTable[string, BTree[string, PNode]]())
+    cache: cache, config: g.config, graph: g)
 
 proc refresh*(c: PCtx, module: PSym) =
   c.module = module
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 9444e41d8..4c58ea789 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -804,12 +804,12 @@ proc genIntCast(c: PCtx; n: PNode; dest: var TDest) =
   else:
     globalError(c.config, n.info, "VM is only allowed to 'cast' between integers of same size")
 
-proc genVoidABC(c: PCtx, n: PNode, dest: TRegister, opcode: TOpcode)
+proc genVoidABC(c: PCtx, n: PNode, dest: TRegister, opcode: TOpcode) =
   unused(c, n, dest)
   var
-    tmp1 = c.genx(n.sons[1])
-    tmp2 = c.genx(n.sons[2])
-    tmp3 = c.genx(n.sons[3])
+    tmp1 = c.genx(n[1])
+    tmp2 = c.genx(n[2])
+    tmp3 = c.genx(n[3])
   c.gABC(n, opcode, tmp1, tmp2, tmp3)
   c.freeTemp(tmp1)
   c.freeTemp(tmp2)
@@ -1087,8 +1087,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
 
   of mNccValue: genUnaryABC(c, n, dest, opcNccValue)
   of mNccInc: genBinaryABC(c, n, dest, opcNccInc)
-  of mNcsAdd: genBinaryABC(c, n, dest, opcNcsAdd
-  of mNcsIncl: genBinaryABC(c, n, dest, opcNcsIncl
+  of mNcsAdd: genBinaryABC(c, n, dest, opcNcsAdd)
+  of mNcsIncl: genBinaryABC(c, n, dest, opcNcsIncl)
   of mNcsLen: genUnaryABC(c, n, dest, opcNcsLen)
   of mNcsAt: genBinaryABC(c, n, dest, opcNcsAt)
   of mNctPut: genVoidABC(c, n, dest, opcNctPut)