IC: next steps (#16729)
* IC: dead code elimination pass * preparations for a different codegen strategy * added documentation to the newly written code * IC: backend code * IC: backend adjustments * optimized the compiler a bit * IC: yet another massive refactoring * fixes regressions * cleanups
This commit is contained in:
parent
eae3bdf8fe
commit
8241e55023
32 changed files with 729 additions and 323 deletions
|
|
@ -10,7 +10,7 @@
|
|||
# This module does the instantiation of generic types.
|
||||
|
||||
import ast, astalgo, msgs, types, magicsys, semdata, renderer, options,
|
||||
lineinfos
|
||||
lineinfos, modulegraphs
|
||||
|
||||
const tfInstClearedFlags = {tfHasMeta, tfUnresolved}
|
||||
|
||||
|
|
@ -30,15 +30,12 @@ proc checkConstructedType*(conf: ConfigRef; info: TLineInfo, typ: PType) =
|
|||
if t[0].kind != tyObject or tfFinal in t[0].flags:
|
||||
localError(info, errInheritanceOnlyWithNonFinalObjects)
|
||||
|
||||
proc searchInstTypes*(key: PType): PType =
|
||||
proc searchInstTypes*(g: ModuleGraph; key: PType): PType =
|
||||
let genericTyp = key[0]
|
||||
if not (genericTyp.kind == tyGenericBody and
|
||||
key[0] == genericTyp and genericTyp.sym != nil): return
|
||||
|
||||
when not defined(nimNoNilSeqs):
|
||||
if genericTyp.sym.typeInstCache == nil: return
|
||||
|
||||
for inst in genericTyp.sym.typeInstCache:
|
||||
for inst in typeInstCacheItems(g, genericTyp.sym):
|
||||
if inst.id == key.id: return inst
|
||||
if inst.len < key.len:
|
||||
# XXX: This happens for prematurely cached
|
||||
|
|
@ -57,14 +54,12 @@ proc searchInstTypes*(key: PType): PType =
|
|||
|
||||
return inst
|
||||
|
||||
proc cacheTypeInst*(inst: PType) =
|
||||
# XXX: add to module's generics
|
||||
# update the refcount
|
||||
proc cacheTypeInst(g: ModuleGraph; moduleId: int; inst: PType) =
|
||||
let gt = inst[0]
|
||||
let t = if gt.kind == tyGenericBody: gt.lastSon else: gt
|
||||
if t.kind in {tyStatic, tyError, tyGenericParam} + tyTypeClasses:
|
||||
return
|
||||
gt.sym.typeInstCache.add(inst)
|
||||
addToGenericCache(g, moduleId, gt.sym, inst)
|
||||
|
||||
type
|
||||
LayeredIdTable* = ref object
|
||||
|
|
@ -306,6 +301,7 @@ proc instCopyType*(cl: var TReplTypeVars, t: PType): PType =
|
|||
result = t.exactReplica
|
||||
else:
|
||||
result = copyType(t, nextTypeId(cl.c.idgen), t.owner)
|
||||
copyTypeProps(cl.c.graph, cl.c.idgen.module, result, t)
|
||||
#cl.typeMap.topLayer.idTablePut(result, t)
|
||||
|
||||
if cl.allowMetaTypes: return
|
||||
|
|
@ -332,7 +328,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
|||
if cl.allowMetaTypes:
|
||||
result = PType(idTableGet(cl.localCache, t))
|
||||
else:
|
||||
result = searchInstTypes(t)
|
||||
result = searchInstTypes(cl.c.graph, t)
|
||||
|
||||
if result != nil and sameFlags(result, t):
|
||||
when defined(reportCacheHits):
|
||||
|
|
@ -351,7 +347,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
|||
|
||||
if header != t:
|
||||
# search again after first pass:
|
||||
result = searchInstTypes(header)
|
||||
result = searchInstTypes(cl.c.graph, header)
|
||||
if result != nil and sameFlags(result, t):
|
||||
when defined(reportCacheHits):
|
||||
echo "Generic instantiation cached ", typeToString(result), " for ",
|
||||
|
|
@ -368,7 +364,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
|||
# we need to add the candidate here, before it's fully instantiated for
|
||||
# recursive instantions:
|
||||
if not cl.allowMetaTypes:
|
||||
cacheTypeInst(result)
|
||||
cacheTypeInst(cl.c.graph, cl.c.module.position, result)
|
||||
else:
|
||||
idTablePut(cl.localCache, t, result)
|
||||
|
||||
|
|
@ -408,13 +404,13 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
|||
if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
|
||||
rawAddSon(result, newbody)
|
||||
checkPartialConstructedType(cl.c.config, cl.info, newbody)
|
||||
let dc = newbody.attachedOps[attachedDeepCopy]
|
||||
if not cl.allowMetaTypes:
|
||||
if dc != nil and sfFromGeneric notin newbody.attachedOps[attachedDeepCopy].flags:
|
||||
let dc = cl.c.graph.getAttachedOp(newbody, attachedDeepCopy)
|
||||
if dc != nil and sfFromGeneric notin dc.flags:
|
||||
# 'deepCopy' needs to be instantiated for
|
||||
# generics *when the type is constructed*:
|
||||
newbody.attachedOps[attachedDeepCopy] = cl.c.instTypeBoundOp(cl.c, dc, result, cl.info,
|
||||
attachedDeepCopy, 1)
|
||||
cl.c.graph.setAttachedOp(cl.c.module.position, newbody, attachedDeepCopy,
|
||||
cl.c.instTypeBoundOp(cl.c, dc, result, cl.info, attachedDeepCopy, 1))
|
||||
if newbody.typeInst == nil:
|
||||
# doAssert newbody.typeInst == nil
|
||||
newbody.typeInst = result
|
||||
|
|
@ -436,8 +432,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
|||
if tfFromGeneric notin mm.flags:
|
||||
# bug #5479, prevent endless recursions here:
|
||||
incl mm.flags, tfFromGeneric
|
||||
let methods = mm.methods
|
||||
for col, meth in items(methods):
|
||||
for col, meth in methodsForGeneric(cl.c.graph, mm):
|
||||
# we instantiate the known methods belonging to that type, this causes
|
||||
# them to be registered and that's enough, so we 'discard' the result.
|
||||
discard cl.c.instTypeBoundOp(cl.c, meth, result, cl.info,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue