Cleanup DFA (#13173)

This commit is contained in:
Clyybber 2020-01-16 20:15:50 +01:00 • committed by GitHub
commit e3acb2d12c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 36 deletions

View file

@ -37,13 +37,10 @@ type
InstrKind* = enum InstrKind* = enum
goto, fork, join, def, use goto, fork, join, def, use
Instr* = object Instr* = object
n*: PNode n*: PNode # contains the def/use location.
case kind*: InstrKind case kind*: InstrKind
of def, use: sym*: PSym # 'sym' can also be 'nil' and
# then 'n' contains the def/use location.
# This is used so that we can track object
# and tuple field accesses precisely.
of goto, fork, join: dest*: int of goto, fork, join: dest*: int
else: discard
ControlFlowGraph* = seq[Instr] ControlFlowGraph* = seq[Instr]
@ -595,7 +592,7 @@ proc genUse(c: var Con; orig: PNode) =
n = n[1] n = n[1]
else: break else: break
if n.kind == nkSym and n.sym.kind in InterestingSyms: if n.kind == nkSym and n.sym.kind in InterestingSyms:
c.code.add Instr(n: orig, kind: use, sym: if orig != n: nil else: n.sym) c.code.add Instr(n: orig, kind: use)
proc aliases*(obj, field: PNode): bool = proc aliases*(obj, field: PNode): bool =
var n = field var n = field
@ -605,41 +602,24 @@ proc aliases*(obj, field: PNode): bool =
while true: while true:
if sameTrees(obj, n): return true if sameTrees(obj, n): return true
case n.kind case n.kind
of nkDotExpr, nkCheckedFieldExpr, nkHiddenSubConv, nkHiddenStdConv, of PathKinds0, PathKinds1:
nkObjDownConv, nkObjUpConv, nkHiddenAddr, nkAddr, nkBracketExpr,
nkHiddenDeref, nkDerefExpr:
n = n[0] n = n[0]
else: else:
break break
return false
proc useInstrTargets*(ins: Instr; loc: PNode): bool = proc useInstrTargets*(ins: Instr; loc: PNode): bool =
assert ins.kind == use assert ins.kind == use
if ins.sym != nil and loc.kind == nkSym: sameTrees(ins.n, loc) or
result = ins.sym == loc.sym ins.n.aliases(loc) or loc.aliases(ins.n) # We can come here if loc is 'x.f' and ins.n is 'x' or the other way round.
else:
result = ins.n == loc or sameTrees(ins.n, loc)
if not result:
# We can come here if loc is 'x.f' and ins.n is 'x' or the other way round.
# def x.f; question: does it affect the full 'x'? No.
# def x; question: does it affect the 'x.f'? Yes.
# use x.f; question: does it affect the full 'x'? No. # use x.f; question: does it affect the full 'x'? No.
# use x; question does it affect 'x.f'? Yes. # use x; question does it affect 'x.f'? Yes.
result = aliases(ins.n, loc) or aliases(loc, ins.n)
proc defInstrTargets*(ins: Instr; loc: PNode): bool = proc defInstrTargets*(ins: Instr; loc: PNode): bool =
assert ins.kind == def assert ins.kind == def
if ins.sym != nil and loc.kind == nkSym: sameTrees(ins.n, loc) or
result = ins.sym == loc.sym ins.n.aliases(loc) # We can come here if loc is 'x.f' and ins.n is 'x' or the other way round.
else:
result = ins.n == loc or sameTrees(ins.n, loc)
if not result:
# We can come here if loc is 'x.f' and ins.n is 'x' or the other way round.
# def x.f; question: does it affect the full 'x'? No. # def x.f; question: does it affect the full 'x'? No.
# def x; question: does it affect the 'x.f'? Yes. # def x; question: does it affect the 'x.f'? Yes.
# use x.f; question: does it affect the full 'x'? No.
# use x; question does it affect 'x.f'? Yes.
result = aliases(ins.n, loc)
proc isAnalysableFieldAccess*(orig: PNode; owner: PSym): bool = proc isAnalysableFieldAccess*(orig: PNode; owner: PSym): bool =
var n = orig var n = orig
@ -695,9 +675,9 @@ proc genDef(c: var Con; n: PNode) =
break break
if n.kind == nkSym and n.sym.kind in InterestingSyms: if n.kind == nkSym and n.sym.kind in InterestingSyms:
c.code.add Instr(n: n, kind: def, sym: n.sym) c.code.add Instr(n: n, kind: def)
elif isAnalysableFieldAccess(n, c.owner): elif isAnalysableFieldAccess(n, c.owner):
c.code.add Instr(n: n, kind: def, sym: nil) c.code.add Instr(n: n, kind: def)
proc genCall(c: var Con; n: PNode) = proc genCall(c: var Con; n: PNode) =
gen(c, n[0]) gen(c, n[0])

View file

@ -168,13 +168,13 @@ proc initialized(code: ControlFlowGraph; pc: int,
if comesFrom == target: return pc if comesFrom == target: return pc
inc pc inc pc
of use: of use:
let v = code[pc].sym let v = code[pc].n.sym
if v.kind != skParam and v.id notin init: if v.kind != skParam and v.id notin init:
# attempt to read an uninit'ed variable # attempt to read an uninit'ed variable
uninit.incl v.id uninit.incl v.id
inc pc inc pc
of def: of def:
let v = code[pc].sym let v = code[pc].n.sym
init.incl v.id init.incl v.id
inc pc inc pc
return pc return pc