-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
internal: separate TLoc
from TSym
and TType
#790
Changes from 7 commits
1e167eb
bfe73f9
c4e7b46
397e5af
473b194
8af6d34
58d906d
356ee71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1590,19 +1590,13 @@ type | |
data*: seq[PSym] | ||
|
||
# -------------- backend information ------------------------------- | ||
TLocKind* = enum | ||
locNone, ## no location | ||
locTemp, ## temporary location | ||
locLocalVar, ## location is a local variable | ||
locGlobalVar, ## location is a global variable | ||
locParam, ## location is a parameter | ||
locField, ## location is a record field | ||
locExpr, ## "location" is really an expression | ||
locProc, ## location is a proc (an address of a procedure) | ||
locData, ## location is a constant | ||
locCall, ## location is a call expression | ||
locOther ## location is something other | ||
TLocFlag* = enum | ||
# XXX: `TLocFlag` conflates two things: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah, even more reason to hold off on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, I'm going to split the enum up immediately after this PR. |
||
# - flags regarding the external interface (e.g., `lfHeader`; set by | ||
# sem, used by sem and the code generators) | ||
# - location-related flags (e.g., ``lfIndirect``, ``lfSingleUse``, | ||
# etc.; only relevant to the C code generator) | ||
# Split the enum up. | ||
lfIndirect, ## backend introduced a pointer | ||
lfFullExternalName, ## only used when 'conf.cmd == cmdNimfix': Indicates | ||
## that the symbol has been imported via 'importc: "fullname"' and | ||
|
@@ -1617,19 +1611,8 @@ type | |
## ptr array due to C array limitations. | ||
## See #1181, #6422, #11171 | ||
lfPrepareForMutation ## string location is about to be mutated (V2) | ||
TStorageLoc* = enum | ||
OnUnknown, ## location is unknown (stack, heap or static) | ||
OnStatic, ## in a static section | ||
OnStack, ## location is on hardware stack | ||
OnHeap ## location is on heap or global | ||
## (reference counting needed) | ||
|
||
TLocFlags* = set[TLocFlag] | ||
TLoc* = object | ||
k*: TLocKind ## kind of location | ||
storage*: TStorageLoc | ||
flags*: TLocFlags ## location's flags | ||
lode*: PNode ## Node where the location came from; can be faked | ||
r*: Rope ## rope value of location (code generators) | ||
|
||
# ---------------- end of backend information ------------------------------ | ||
|
||
|
@@ -1713,7 +1696,12 @@ type | |
## to the module's fileIdx | ||
## for variables a slot index for the evaluator | ||
offset*: int ## offset of record field | ||
loc*: TLoc | ||
extname*: string ## the external name of the type, or empty if a | ||
## generated name is to be used | ||
locFlags*: TLocFlags ## additional flags that are relevant to code | ||
## generation | ||
locId*: uint32 ## associates the symbol with a loc in the C code | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If two symbols can't be associated with the same location, could we piggy back off of (I'm guessing this will result in a 'no' once I've read further in the PR) It would mean we'd have to store something for each symbol (more memory), but that might balance out as we're storing an extra 4 bytes with the current change. The lack of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. revisiting this comment, I'm pretty sure this wouldn't be a good approach at present, better to defer it as the necessary data and consequent layout are likely to change dramatically. |
||
## generator. 0 means unset. | ||
annex*: PLib ## additional fields (seldom used, so we use a | ||
## reference to another object to save space) | ||
constraint*: PNode ## additional constraints like 'lit|result'; also | ||
|
@@ -1759,7 +1747,6 @@ type | |
align*: int16 ## the type's alignment requirements | ||
paddingAtEnd*: int16 ## | ||
lockLevel*: TLockLevel ## lock level as required for deadlock checking | ||
loc*: TLoc | ||
typeInst*: PType ## for generic instantiations the tyGenericInst that led to this | ||
## type; for tyError the previous type if avaiable | ||
uniqueId*: ItemId ## due to a design mistake, we need to keep the real ID here as it | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,7 +37,8 @@ import | |
], | ||
compiler/ast/[ | ||
ast, | ||
lineinfos | ||
lineinfos, | ||
ndi | ||
], | ||
compiler/backend/[ | ||
backends, | ||
|
@@ -93,6 +94,14 @@ type | |
|
||
func hash(x: PSym): int = hash(x.id) | ||
|
||
proc writeMangledLocals(p: BProc) = | ||
## Writes the mangled names of `p`'s locals to the module's NDI file. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is a nice secondary benefit developing over time, as the mangling becomes more and more consistent it's going to make |
||
for it in p.locals.items: | ||
# writing out mangled names for compiler-inserted variables (temporaries) | ||
# is not necessary (lode is guaranteed to be a symbol) | ||
if it.lode.sym.kind != skTemp: | ||
writeMangledName(p.module.ndi, it.lode.sym, it.r, p.config) | ||
|
||
func registerInline(g: var InliningData, prc: PSym): uint32 = | ||
## If not already registered, registers the inline procedure `prc` with | ||
## `g`. This only sets up an ``InlineProc`` stub -- the entry is | ||
|
@@ -151,7 +160,7 @@ proc processEvent(g: BModuleList, inl: var InliningData, discovery: var Discover | |
# XXX: dynlib procedure handling is going to move into the unified backend | ||
# processing pipeline (i.e., the ``process`` iterator) in the future | ||
for _, s in peek(discovery.procedures): | ||
if lfDynamicLib in s.loc.flags: | ||
if lfDynamicLib in s.locFlags: | ||
let m = g.modules[s.itemId.module.int] | ||
fillProcLoc(m, newSymNode(s)) | ||
symInDynamicLib(m, s) | ||
|
@@ -237,7 +246,13 @@ proc processEvent(g: BModuleList, inl: var InliningData, discovery: var Discover | |
bmod.declaredThings.incl(evt.sym.id) | ||
let | ||
body = generateAST(g.graph, bmod.idgen, evt.sym, evt.body) | ||
r = genProc(bmod, evt.sym, body) | ||
p = startProc(bmod, evt.sym, body) | ||
|
||
# we can't generate with ``genProc`` because we still need to output | ||
# the mangled names | ||
genStmts(p, body) | ||
writeMangledLocals(p) | ||
let r = finishProc(p, evt.sym) | ||
|
||
if inlineId.isSome: | ||
# remember the generated body: | ||
|
@@ -365,8 +380,8 @@ proc generateCode*(graph: ModuleGraph, g: BModuleList, mlist: sink ModuleList) = | |
|
||
# the init and data-init procedures use special names in the | ||
# generated code: | ||
m.init.loc.r = getInitName(bmod) | ||
m.dataInit.loc.r = getDatInitName(bmod) | ||
m.init.extname = getInitName(bmod) | ||
m.dataInit.extname = getDatInitName(bmod) | ||
|
||
# mark the init procedure so that the code generator can detect and | ||
# special-case it: | ||
|
@@ -389,12 +404,35 @@ proc generateCode*(graph: ModuleGraph, g: BModuleList, mlist: sink ModuleList) = | |
|
||
# finish the partial procedures: | ||
for s, p in partial.pairs: | ||
writeMangledLocals(p) | ||
p.module.s[cfsProcs].add(finishProc(p, s)) | ||
|
||
# ------------------------- | ||
# all alive entities must have been discovered when reaching here; it is | ||
# not allowed to raise new ones beyond this point | ||
|
||
block: | ||
# write the mangled names of the various entities to the NDI files | ||
for it in g.procs.items: | ||
let | ||
s = it.loc.lode.sym | ||
m = g.modules[moduleId(s)] | ||
writeMangledName(m.ndi, s, it.loc.r, g.config) | ||
# parameters: | ||
for p in it.params.items: | ||
if p.k != locNone: # not all parameters have locs | ||
writeMangledName(m.ndi, s, p.r, g.config) | ||
|
||
template write(loc: TLoc) = | ||
let s = loc.lode.sym | ||
writeMangledName(g.modules[moduleId(s)].ndi, s, loc.r, g.config) | ||
|
||
for it in g.globals.items: | ||
write(it) | ||
|
||
for it in g.consts.items: | ||
write(it) | ||
|
||
# now emit a duplicate of each inline procedure into the C files where the | ||
# procedure is used. Due to how ``cgen`` currently works, this means | ||
# generating C code for the procedure again | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
too big a change to name it
extFlags
?a soft suggestion as a fair bit of this is under heavy transition.