From 5ad1acc60ce6d25e6491c60afc1605d6cd76fc5a Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Mon, 28 May 2018 18:18:43 +0200 Subject: remove the last global variables in the C code generator --- compiler/ccgthreadvars.nim | 27 +++++++-------------------- compiler/cgendata.nim | 13 ++++++++++++- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/compiler/ccgthreadvars.nim b/compiler/ccgthreadvars.nim index da5c624b7..3e8a87041 100644 --- a/compiler/ccgthreadvars.nim +++ b/compiler/ccgthreadvars.nim @@ -23,27 +23,14 @@ proc accessThreadLocalVar(p: BProc, s: PSym) = add(p.procSec(cpsInit), ropecg(p.module, "\tNimTV_ = (NimThreadVars*) #GetThreadLocalVars();$n")) -var - nimtv: Rope # Nim thread vars; the struct body - nimtvDeps: seq[PType] = @[] # type deps: every module needs whole struct - nimtvDeclared = initIntSet() # so that every var/field exists only once - # in the struct - -# 'nimtv' is incredibly hard to modularize! Best effort is to store all thread -# vars in a ROD section and with their type deps and load them -# unconditionally... - -# nimtvDeps is VERY hard to cache because it's not a list of IDs nor can it be -# made to be one. - proc declareThreadVar(m: BModule, s: PSym, isExtern: bool) = if emulatedThreadVars(m.config): # we gather all thread locals var into a struct; we need to allocate # storage for that somehow, can't use the thread local storage # allocator for it :-( - if not containsOrIncl(nimtvDeclared, s.id): - nimtvDeps.add(s.loc.t) - addf(nimtv, "$1 $2;$n", [getTypeDesc(m, s.loc.t), s.loc.r]) + if not containsOrIncl(m.g.nimtvDeclared, s.id): + m.g.nimtvDeps.add(s.loc.t) + addf(m.g.nimtv, "$1 $2;$n", [getTypeDesc(m, s.loc.t), s.loc.r]) else: if isExtern: add(m.s[cfsVars], "extern ") if optThreads in m.config.globalOptions: add(m.s[cfsVars], "NIM_THREADVAR ") @@ -51,12 +38,12 @@ proc declareThreadVar(m: BModule, s: PSym, isExtern: bool) = addf(m.s[cfsVars], " $1;$n", [s.loc.r]) proc generateThreadLocalStorage(m: BModule) = - if nimtv != nil and (usesThreadVars in m.flags or sfMainModule in m.module.flags): - for t in items(nimtvDeps): discard getTypeDesc(m, t) - addf(m.s[cfsSeqTypes], "typedef struct {$1} NimThreadVars;$n", [nimtv]) + if m.g.nimtv != nil and (usesThreadVars in m.flags or sfMainModule in m.module.flags): + for t in items(m.g.nimtvDeps): discard getTypeDesc(m, t) + addf(m.s[cfsSeqTypes], "typedef struct {$1} NimThreadVars;$n", [m.g.nimtv]) proc generateThreadVarsSize(m: BModule) = - if nimtv != nil: + if m.g.nimtv != nil: let externc = if m.config.cmd == cmdCompileToCpp or sfCompileToCpp in m.module.flags: "extern \"C\" " else: "" diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index daad1b1ce..aba317e7c 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -119,6 +119,17 @@ type graph*: ModuleGraph strVersion*, seqVersion*: int # version of the string/seq implementation to use + nimtv*: Rope # Nim thread vars; the struct body + nimtvDeps*: seq[PType] # type deps: every module needs whole struct + nimtvDeclared*: IntSet # so that every var/field exists only once + # in the struct + # 'nimtv' is incredibly hard to modularize! Best + # effort is to store all thread vars in a ROD + # section and with their type deps and load them + # unconditionally... + # nimtvDeps is VERY hard to cache because it's + # not a list of IDs nor can it be made to be one. + TCGen = object of TPassContext # represents a C source file s*: TCFileSections # sections of the C file flags*: set[Codegenflag] @@ -177,7 +188,7 @@ proc newProc*(prc: PSym, module: BModule): BProc = proc newModuleList*(g: ModuleGraph): BModuleList = BModuleList(modules: @[], typeInfoMarker: initTable[SigHash, Rope](), config: g.config, - graph: g) + graph: g, nimtvDeps: @[], nimtvDeclared: initIntSet()) iterator cgenModules*(g: BModuleList): BModule = for i in 0..high(g.modules): -- cgit 1.4.1-2-gfad0 ef='#n39'>39 40 41 42 43 44 45 46 47 48 49 50 51 52 53