explicit ID generation for easier IC (#15559)

* refactoring: idents don't need inheritance
* refactoring: adding an IdGenerator (part 1)
* refactoring: adding an IdGenerator (part 2)
* refactoring: adding an IdGenerator (part 3)
* refactoring: adding an IdGenerator (part 4)
* refactoring: adding an IdGenerator (part 5)
* refactoring: adding an IdGenerator (part 5)
* IdGenerator must be a ref type; hello world works again
* make bootstrapping work again
* progress: add back the 'exactReplica' ideas
* added back the missing exactReplica hacks
* make tcompilerapi work again
* make important packages green
* attempt to fix the build for 32 bit machines (probably need a better solution here)
This commit is contained in:
Andreas Rumpf 2020-10-25 08:50:47 +01:00 • committed by GitHub
commit 226595515c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 853 additions and 903 deletions

View file

@ -10,7 +10,7 @@
# abstract syntax tree + symbol table
import
lineinfos, hashes, options, ropes, idents, idgen, int128
lineinfos, hashes, options, ropes, idents, int128
from strutils import toLowerAscii
export int128
@ -717,6 +717,14 @@ const
mInSet, mRepr}
type
ItemId* = object
module*: int32
item*: int32
TIdObj* = object of RootObj
itemId*: ItemId
PIdObj* = ref TIdObj
PNode* = ref TNode
TNodeSeq* = seq[PNode]
PType* = ref TType
@ -926,7 +934,7 @@ type
loc*: TLoc
typeInst*: PType # for generic instantiations the tyGenericInst that led to this
# type.
uniqueId*: int # due to a design mistake, we need to keep the real ID here as it
uniqueId*: ItemId # due to a design mistake, we need to keep the real ID here as it
# required by the --incremental:on mode.
TPair* = object
@ -1060,6 +1068,35 @@ proc getnimblePkg*(a: PSym): PSym =
else:
assert false, $result.kind
const
moduleShift = when defined(cpu32): 20 else: 24
template id*(a: PIdObj): int =
let x = a
(x.itemId.module.int shl moduleShift) + x.itemId.item.int
type
IdGenerator* = ref ItemId # unfortunately, we really need the 'shared mutable' aspect here.
const
PackageModuleId* = -3'i32
proc idGeneratorFromModule*(m: PSym): IdGenerator =
assert m.kind == skModule
result = IdGenerator(module: m.itemId.module, item: m.itemId.item)
proc nextId*(x: IdGenerator): ItemId {.inline.} =
inc x.item
result = x[]
when false:
proc storeBack*(dest: var IdGenerator; src: IdGenerator) {.inline.} =
assert dest.ItemId.module == src.ItemId.module
if dest.ItemId.item > src.ItemId.item:
echo dest.ItemId.item, " ", src.ItemId.item, " ", src.ItemId.module
assert dest.ItemId.item <= src.ItemId.item
dest = src
proc getnimblePkgId*(a: PSym): int =
let b = a.getnimblePkg
result = if b == nil: -1 else: b.id
@ -1164,13 +1201,11 @@ proc newTreeIT*(kind: TNodeKind; info: TLineInfo; typ: PType; children: varargs[
template previouslyInferred*(t: PType): PType =
if t.sons.len > 1: t.lastSon else: nil
proc newSym*(symKind: TSymKind, name: PIdent, owner: PSym,
proc newSym*(symKind: TSymKind, name: PIdent, id: ItemId, owner: PSym,
info: TLineInfo; options: TOptions = {}): PSym =
# generates a symbol and initializes the hash field too
result = PSym(name: name, kind: symKind, flags: {}, info: info, id: getID(),
result = PSym(name: name, kind: symKind, flags: {}, info: info, itemId: id,
options: options, owner: owner, offset: defaultOffset)
when debugIds:
registerId(result)
proc astdef*(s: PSym): PNode =
# get only the definition (initializer) portion of the ast
@ -1344,13 +1379,11 @@ proc `$`*(s: PSym): string =
else:
result = "<nil>"
proc newType*(kind: TTypeKind, owner: PSym): PType =
let id = getID()
proc newType*(kind: TTypeKind, id: ItemId; owner: PSym): PType =
result = PType(kind: kind, owner: owner, size: defaultSize,
align: defaultAlignment, id: id, uniqueId: id,
lockLevel: UnspecifiedLockLevel)
when debugIds:
registerId(result)
align: defaultAlignment, itemId: id,
lockLevel: UnspecifiedLockLevel,
uniqueId: id)
when false:
if result.id == 76426:
echo "KNID ", kind
@ -1392,22 +1425,18 @@ proc assignType*(dest, src: PType) =
newSons(dest, src.len)
for i in 0..<src.len: dest[i] = src[i]
proc copyType*(t: PType, owner: PSym, keepId: bool): PType =
result = newType(t.kind, owner)
proc copyType*(t: PType, id: ItemId, owner: PSym): PType =
result = newType(t.kind, id, owner)
assignType(result, t)
if keepId:
result.id = t.id
else:
when debugIds: registerId(result)
result.sym = t.sym # backend-info should not be copied
proc exactReplica*(t: PType): PType = copyType(t, t.owner, true)
proc exactReplica*(t: PType): PType =
result = copyType(t, t.itemId, t.owner)
proc copySym*(s: PSym): PSym =
result = newSym(s.kind, s.name, s.owner, s.info, s.options)
proc copySym*(s: PSym; id: ItemId): PSym =
result = newSym(s.kind, s.name, id, s.owner, s.info, s.options)
#result.ast = nil # BUGFIX; was: s.ast which made problems
result.typ = s.typ
when debugIds: registerId(result)
result.flags = s.flags
result.magic = s.magic
if s.kind == skModule:
@ -1421,12 +1450,12 @@ proc copySym*(s: PSym): PSym =
result.bitsize = s.bitsize
result.alignment = s.alignment
proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo;
proc createModuleAlias*(s: PSym, id: ItemId, newIdent: PIdent, info: TLineInfo;
options: TOptions): PSym =
result = newSym(s.kind, newIdent, s.owner, info, options)
result = newSym(s.kind, newIdent, id, s.owner, info, options)
# keep ID!
result.ast = s.ast
result.id = s.id
#result.id = s.id # XXX figure out what to do with the ID.
result.flags = s.flags
system.shallowCopy(result.tab, s.tab)
result.options = s.options
@ -1576,7 +1605,7 @@ proc transitionNoneToSym*(n: PNode) =
template transitionSymKindCommon*(k: TSymKind) =
let obj {.inject.} = s[]
s[] = TSym(kind: k, id: obj.id, magic: obj.magic, typ: obj.typ, name: obj.name,
s[] = TSym(kind: k, itemId: obj.itemId, magic: obj.magic, typ: obj.typ, name: obj.name,
info: obj.info, owner: obj.owner, flags: obj.flags, ast: obj.ast,
options: obj.options, position: obj.position, offset: obj.offset,
loc: obj.loc, annex: obj.annex, constraint: obj.constraint)
@ -1797,19 +1826,19 @@ proc skipStmtList*(n: PNode): PNode =
else:
result = n
proc toVar*(typ: PType; kind: TTypeKind): PType =
proc toVar*(typ: PType; kind: TTypeKind; idgen: IdGenerator): PType =
## If ``typ`` is not a tyVar then it is converted into a `var <typ>` and
## returned. Otherwise ``typ`` is simply returned as-is.
result = typ
if typ.kind != kind:
result = newType(kind, typ.owner)
result = newType(kind, nextId(idgen), typ.owner)
rawAddSon(result, typ)
proc toRef*(typ: PType): PType =
proc toRef*(typ: PType; idgen: IdGenerator): PType =
## If ``typ`` is a tyObject then it is converted into a `ref <typ>` and
## returned. Otherwise ``typ`` is simply returned as-is.
if typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject:
result = newType(tyRef, typ.owner)
result = newType(tyRef, nextId(idgen), typ.owner)
rawAddSon(result, typ)
proc toObject*(typ: PType): PType =
@ -1888,8 +1917,8 @@ proc isSinkParam*(s: PSym): bool {.inline.} =
proc isSinkType*(t: PType): bool {.inline.} =
t.kind == tySink or tfHasOwned in t.flags
proc newProcType*(info: TLineInfo; owner: PSym): PType =
result = newType(tyProc, owner)
proc newProcType*(info: TLineInfo; id: ItemId; owner: PSym): PType =
result = newType(tyProc, id, owner)
result.n = newNodeI(nkFormalParams, info)
rawAddSon(result, nil) # return type
# result.n[0] used to be `nkType`, but now it's `nkEffectList` because