Make the registered passes local to the ModuleGraph (#9259)

Closes #9068
This commit is contained in:
LemonBoy 2018-10-09 19:24:03 +02:00 • committed by Andreas Rumpf
commit b97a7dbf3d
12 changed files with 60 additions and 64 deletions

View file

@ -18,7 +18,7 @@ import
import strutils except `%` # collides with ropes.`%` import strutils except `%` # collides with ropes.`%`
from modulegraphs import ModuleGraph from modulegraphs import ModuleGraph, PPassContext
from lineinfos import from lineinfos import
warnGcMem, errXMustBeCompileTime, hintDependency, errGenerated, errCannotOpenFile warnGcMem, errXMustBeCompileTime, hintDependency, errGenerated, errCannotOpenFile
import dynlib import dynlib

View file

@ -13,7 +13,7 @@ import
ast, astalgo, ropes, passes, options, intsets, platform, sighashes, ast, astalgo, ropes, passes, options, intsets, platform, sighashes,
tables, ndi, lineinfos, pathutils tables, ndi, lineinfos, pathutils
from modulegraphs import ModuleGraph from modulegraphs import ModuleGraph, PPassContext
type type
TLabel* = Rope # for the C generator a label is just a rope TLabel* = Rope # for the C generator a label is just a rope
@ -132,7 +132,7 @@ type
# nimtvDeps is VERY hard to cache because it's # nimtvDeps is VERY hard to cache because it's
# not a list of IDs nor can it be made to be one. # not a list of IDs nor can it be made to be one.
TCGen = object of TPassContext # represents a C source file TCGen = object of PPassContext # represents a C source file
s*: TCFileSections # sections of the C file s*: TCFileSections # sections of the C file
flags*: set[Codegenflag] flags*: set[Codegenflag]
module*: PSym module*: PSym

View file

@ -13,10 +13,10 @@ import
os, options, ast, astalgo, msgs, ropes, idents, passes, modulepaths, os, options, ast, astalgo, msgs, ropes, idents, passes, modulepaths,
pathutils pathutils
from modulegraphs import ModuleGraph from modulegraphs import ModuleGraph, PPassContext
type type
TGen = object of TPassContext TGen = object of PPassContext
module: PSym module: PSym
config: ConfigRef config: ConfigRef
graph: ModuleGraph graph: ModuleGraph

View file

@ -14,10 +14,10 @@ import
os, options, ast, astalgo, msgs, ropes, idents, passes, docgen, lineinfos, os, options, ast, astalgo, msgs, ropes, idents, passes, docgen, lineinfos,
pathutils pathutils
from modulegraphs import ModuleGraph from modulegraphs import ModuleGraph, PPassContext
type type
TGen = object of TPassContext TGen = object of PPassContext
doc: PDoc doc: PDoc
module: PSym module: PSym
PGen = ref TGen PGen = ref TGen

View file

@ -34,10 +34,10 @@ import
times, ropes, math, passes, ccgutils, wordrecg, renderer, times, ropes, math, passes, ccgutils, wordrecg, renderer,
intsets, cgmeth, lowerings, sighashes, lineinfos, rodutils, pathutils intsets, cgmeth, lowerings, sighashes, lineinfos, rodutils, pathutils
from modulegraphs import ModuleGraph from modulegraphs import ModuleGraph, PPassContext
type type
TJSGen = object of TPassContext TJSGen = object of PPassContext
module: PSym module: PSym
graph: ModuleGraph graph: ModuleGraph
config: ConfigRef config: ConfigRef

View file

@ -62,6 +62,19 @@ type
cacheSeqs*: Table[string, PNode] # state that is shared to suppor the 'macrocache' API cacheSeqs*: Table[string, PNode] # state that is shared to suppor the 'macrocache' API
cacheCounters*: Table[string, BiggestInt] cacheCounters*: Table[string, BiggestInt]
cacheTables*: Table[string, BTree[string, PNode]] cacheTables*: Table[string, BTree[string, PNode]]
passes*: seq[TPass]
TPassContext* = object of RootObj # the pass's context
PPassContext* = ref TPassContext
TPassOpen* = proc (graph: ModuleGraph; module: PSym): PPassContext {.nimcall.}
TPassClose* = proc (graph: ModuleGraph; p: PPassContext, n: PNode): PNode {.nimcall.}
TPassProcess* = proc (p: PPassContext, topLevelStmt: PNode): PNode {.nimcall.}
TPass* = tuple[open: TPassOpen,
process: TPassProcess,
close: TPassClose,
isFrontend: bool]
proc hash*(x: FileIndex): Hash {.borrow.} proc hash*(x: FileIndex): Hash {.borrow.}

View file

@ -12,10 +12,10 @@
import import
strutils, ast, astalgo, passes, idents, msgs, options, idgen, lineinfos strutils, ast, astalgo, passes, idents, msgs, options, idgen, lineinfos
from modulegraphs import ModuleGraph from modulegraphs import ModuleGraph, PPassContext
type type
VerboseRef = ref object of TPassContext VerboseRef = ref object of PPassContext
config: ConfigRef config: ConfigRef
proc verboseOpen(graph: ModuleGraph; s: PSym): PPassContext = proc verboseOpen(graph: ModuleGraph; s: PSym): PPassContext =

View file

@ -16,21 +16,8 @@ import
nimsets, syntaxes, times, idgen, modulegraphs, reorder, rod, nimsets, syntaxes, times, idgen, modulegraphs, reorder, rod,
lineinfos, pathutils lineinfos, pathutils
type type
TPassContext* = object of RootObj # the pass's context
PPassContext* = ref TPassContext
TPassOpen* = proc (graph: ModuleGraph; module: PSym): PPassContext {.nimcall.}
TPassClose* = proc (graph: ModuleGraph; p: PPassContext, n: PNode): PNode {.nimcall.}
TPassProcess* = proc (p: PPassContext, topLevelStmt: PNode): PNode {.nimcall.}
TPass* = tuple[open: TPassOpen, process: TPassProcess, close: TPassClose,
isFrontend: bool]
TPassData* = tuple[input: PNode, closeOutput: PNode] TPassData* = tuple[input: PNode, closeOutput: PNode]
TPasses* = openArray[TPass]
# a pass is a tuple of procedure vars ``TPass.close`` may produce additional # a pass is a tuple of procedure vars ``TPass.close`` may produce additional
# nodes. These are passed to the other close procedures. # nodes. These are passed to the other close procedures.
@ -57,16 +44,12 @@ const
type type
TPassContextArray = array[0..maxPasses - 1, PPassContext] TPassContextArray = array[0..maxPasses - 1, PPassContext]
var
gPasses: array[0..maxPasses - 1, TPass]
gPassesLen*: int
proc clearPasses*(g: ModuleGraph) = proc clearPasses*(g: ModuleGraph) =
gPassesLen = 0 g.passes.setLen(0)
proc registerPass*(g: ModuleGraph; p: TPass) = proc registerPass*(g: ModuleGraph; p: TPass) =
gPasses[gPassesLen] = p internalAssert g.config, g.passes.len < maxPasses
inc(gPassesLen) g.passes.add(p)
proc carryPass*(g: ModuleGraph; p: TPass, module: PSym; proc carryPass*(g: ModuleGraph; p: TPass, module: PSym;
m: TPassData): TPassData = m: TPassData): TPassData =
@ -76,7 +59,7 @@ proc carryPass*(g: ModuleGraph; p: TPass, module: PSym;
else: m.closeOutput else: m.closeOutput
proc carryPasses*(g: ModuleGraph; nodes: PNode, module: PSym; proc carryPasses*(g: ModuleGraph; nodes: PNode, module: PSym;
passes: TPasses) = passes: openArray[TPass]) =
var passdata: TPassData var passdata: TPassData
passdata.input = nodes passdata.input = nodes
for pass in passes: for pass in passes:
@ -84,23 +67,23 @@ proc carryPasses*(g: ModuleGraph; nodes: PNode, module: PSym;
proc openPasses(g: ModuleGraph; a: var TPassContextArray; proc openPasses(g: ModuleGraph; a: var TPassContextArray;
module: PSym) = module: PSym) =
for i in countup(0, gPassesLen - 1): for i in countup(0, g.passes.len - 1):
if not isNil(gPasses[i].open): if not isNil(g.passes[i].open):
a[i] = gPasses[i].open(g, module) a[i] = g.passes[i].open(g, module)
else: a[i] = nil else: a[i] = nil
proc closePasses(graph: ModuleGraph; a: var TPassContextArray) = proc closePasses(graph: ModuleGraph; a: var TPassContextArray) =
var m: PNode = nil var m: PNode = nil
for i in countup(0, gPassesLen - 1): for i in countup(0, graph.passes.len - 1):
if not isNil(gPasses[i].close): m = gPasses[i].close(graph, a[i], m) if not isNil(graph.passes[i].close): m = graph.passes[i].close(graph, a[i], m)
a[i] = nil # free the memory here a[i] = nil # free the memory here
proc processTopLevelStmt(n: PNode, a: var TPassContextArray): bool = proc processTopLevelStmt(graph: ModuleGraph, n: PNode, a: var TPassContextArray): bool =
# this implements the code transformation pipeline # this implements the code transformation pipeline
var m = n var m = n
for i in countup(0, gPassesLen - 1): for i in countup(0, graph.passes.len - 1):
if not isNil(gPasses[i].process): if not isNil(graph.passes[i].process):
m = gPasses[i].process(a[i], m) m = graph.passes[i].process(a[i], m)
if isNil(m): return false if isNil(m): return false
result = true result = true
@ -111,19 +94,19 @@ proc resolveMod(conf: ConfigRef; module, relativeTo: string): FileIndex =
else: else:
result = fileInfoIdx(conf, fullPath) result = fileInfoIdx(conf, fullPath)
proc processImplicits(conf: ConfigRef; implicits: seq[string], nodeKind: TNodeKind, proc processImplicits(graph: ModuleGraph; implicits: seq[string], nodeKind: TNodeKind,
a: var TPassContextArray; m: PSym) = a: var TPassContextArray; m: PSym) =
# XXX fixme this should actually be relative to the config file! # XXX fixme this should actually be relative to the config file!
let gCmdLineInfo = newLineInfo(FileIndex(0), 1, 1) let gCmdLineInfo = newLineInfo(FileIndex(0), 1, 1)
let relativeTo = toFullPath(conf, m.info) let relativeTo = toFullPath(graph.config, m.info)
for module in items(implicits): for module in items(implicits):
# implicit imports should not lead to a module importing itself # implicit imports should not lead to a module importing itself
if m.position != resolveMod(conf, module, relativeTo).int32: if m.position != resolveMod(graph.config, module, relativeTo).int32:
var importStmt = newNodeI(nodeKind, gCmdLineInfo) var importStmt = newNodeI(nodeKind, gCmdLineInfo)
var str = newStrNode(nkStrLit, module) var str = newStrNode(nkStrLit, module)
str.info = gCmdLineInfo str.info = gCmdLineInfo
importStmt.addSon str importStmt.addSon str
if not processTopLevelStmt(importStmt, a): break if not processTopLevelStmt(graph, importStmt, a): break
const const
imperativeCode = {low(TNodeKind)..high(TNodeKind)} - {nkTemplateDef, nkProcDef, nkMethodDef, imperativeCode = {low(TNodeKind)..high(TNodeKind)} - {nkTemplateDef, nkProcDef, nkMethodDef,
@ -139,25 +122,25 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {
fileIdx = module.fileIdx fileIdx = module.fileIdx
if module.id < 0: if module.id < 0:
# new module caching mechanism: # new module caching mechanism:
for i in 0..<gPassesLen: for i in 0 ..< graph.passes.len:
if not isNil(gPasses[i].open) and not gPasses[i].isFrontend: if not isNil(graph.passes[i].open) and not graph.passes[i].isFrontend:
a[i] = gPasses[i].open(graph, module) a[i] = graph.passes[i].open(graph, module)
else: else:
a[i] = nil a[i] = nil
if not graph.stopCompile(): if not graph.stopCompile():
let n = loadNode(graph, module) let n = loadNode(graph, module)
var m = n var m = n
for i in 0..<gPassesLen: for i in 0 ..< graph.passes.len:
if not isNil(gPasses[i].process) and not gPasses[i].isFrontend: if not isNil(graph.passes[i].process) and not graph.passes[i].isFrontend:
m = gPasses[i].process(a[i], m) m = graph.passes[i].process(a[i], m)
if isNil(m): if isNil(m):
break break
var m: PNode = nil var m: PNode = nil
for i in 0..<gPassesLen: for i in 0 ..< graph.passes.len:
if not isNil(gPasses[i].close) and not gPasses[i].isFrontend: if not isNil(graph.passes[i].close) and not graph.passes[i].isFrontend:
m = gPasses[i].close(graph, a[i], m) m = graph.passes[i].close(graph, a[i], m)
a[i] = nil a[i] = nil
else: else:
openPasses(graph, a, module) openPasses(graph, a, module)
@ -177,8 +160,8 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {
# modules to include between compilation runs? we'd need to track that # modules to include between compilation runs? we'd need to track that
# in ROD files. I think we should enable this feature only # in ROD files. I think we should enable this feature only
# for the interactive mode. # for the interactive mode.
processImplicits graph.config, graph.config.implicitImports, nkImportStmt, a, module processImplicits graph, graph.config.implicitImports, nkImportStmt, a, module
processImplicits graph.config, graph.config.implicitIncludes, nkIncludeStmt, a, module processImplicits graph, graph.config.implicitIncludes, nkIncludeStmt, a, module
while true: while true:
if graph.stopCompile(): break if graph.stopCompile(): break
@ -194,7 +177,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {
sl.add n sl.add n
if sfReorder in module.flags: if sfReorder in module.flags:
sl = reorder(graph, sl, module) sl = reorder(graph, sl, module)
discard processTopLevelStmt(sl, a) discard processTopLevelStmt(graph, sl, a)
break break
elif n.kind in imperativeCode: elif n.kind in imperativeCode:
# read everything until the next proc declaration etc. # read everything until the next proc declaration etc.
@ -208,13 +191,13 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {
break break
sl.add n sl.add n
#echo "-----\n", sl #echo "-----\n", sl
if not processTopLevelStmt(sl, a): break if not processTopLevelStmt(graph, sl, a): break
if rest != nil: if rest != nil:
#echo "-----\n", rest #echo "-----\n", rest
if not processTopLevelStmt(rest, a): break if not processTopLevelStmt(graph, rest, a): break
else: else:
#echo "----- single\n", n #echo "----- single\n", n
if not processTopLevelStmt(n, a): break if not processTopLevelStmt(graph, n, a): break
closeParsers(p) closeParsers(p)
if s.kind != llsStdIn: break if s.kind != llsStdIn: break
closePasses(graph, a) closePasses(graph, a)

View file

@ -18,7 +18,7 @@ import
evaltempl, patterns, parampatterns, sempass2, linter, semmacrosanity, evaltempl, patterns, parampatterns, sempass2, linter, semmacrosanity,
semparallel, lowerings, pluginsupport, plugins/active, rod, lineinfos semparallel, lowerings, pluginsupport, plugins/active, rod, lineinfos
from modulegraphs import ModuleGraph from modulegraphs import ModuleGraph, PPassContext
when defined(nimfix): when defined(nimfix):
import nimfix/prettybase import nimfix/prettybase

View file

@ -38,7 +38,7 @@ type
# if we encounter the 2nd yield statement # if we encounter the 2nd yield statement
next: PTransCon # for stacking next: PTransCon # for stacking
TTransfContext = object of passes.TPassContext TTransfContext = object of TPassContext
module: PSym module: PSym
transCon: PTransCon # top of a TransCon stack transCon: PTransCon # top of a TransCon stack
inlining: int # > 0 if we are in inlining context (copy vars) inlining: int # > 0 if we are in inlining context (copy vars)

View file

@ -24,7 +24,7 @@ import
from semfold import leValueConv, ordinalValToString from semfold import leValueConv, ordinalValToString
from evaltempl import evalTemplate from evaltempl import evalTemplate
from modulegraphs import ModuleGraph from modulegraphs import ModuleGraph, PPassContext
when hasFFI: when hasFFI:
import evalffi import evalffi

View file

@ -191,7 +191,7 @@ type
VmCallback* = proc (args: VmArgs) {.closure.} VmCallback* = proc (args: VmArgs) {.closure.}
PCtx* = ref TCtx PCtx* = ref TCtx
TCtx* = object of passes.TPassContext # code gen context TCtx* = object of TPassContext # code gen context
code*: seq[TInstr] code*: seq[TInstr]
debug*: seq[TLineInfo] # line info for every instruction; kept separate debug*: seq[TLineInfo] # line info for every instruction; kept separate
# to not slow down interpretation # to not slow down interpretation