DFA works for simple examples
This commit is contained in:
parent
6b321d0650
commit
c2d91771bc
1 changed files with 17 additions and 9 deletions
|
|
@ -344,20 +344,20 @@ proc dfa(code: seq[Instr]) =
|
|||
case code[i].kind
|
||||
of use, useWithinCall: u[i].incl(code[i].sym.id)
|
||||
of def: d[i].incl(code[i].sym.id)
|
||||
of fork:
|
||||
of fork, goto:
|
||||
let d = i+code[i].dest
|
||||
backrefs.add(d, i)
|
||||
of goto: discard
|
||||
|
||||
var w = @[0]
|
||||
var maxIters = 50
|
||||
var someChange = true
|
||||
while w.len > 0 and maxIters > 0 and someChange:
|
||||
var takenGotos = initIntSet()
|
||||
while w.len > 0 and maxIters > 0: # and someChange:
|
||||
dec maxIters
|
||||
var pc = w.pop() # w[^1]
|
||||
var prevPc = -1
|
||||
# this simulates a single linear control flow execution:
|
||||
while pc < code.len and someChange:
|
||||
while pc < code.len:
|
||||
# according to the paper, it is better to shrink the working set here
|
||||
# in this inner loop:
|
||||
#let widx = w.find(pc)
|
||||
|
|
@ -386,17 +386,21 @@ proc dfa(code: seq[Instr]) =
|
|||
if def notin d[prevPc]:
|
||||
excl(intersect, def)
|
||||
someChange = true
|
||||
when defined(debugDfa):
|
||||
echo "Excluding ", pc, " prev ", prevPc
|
||||
assign d[pc], intersect
|
||||
|
||||
# our interpretation ![I!]:
|
||||
prevPc = pc
|
||||
when defined(debugDfa):
|
||||
echo "looking at ", pc
|
||||
case code[pc].kind
|
||||
of goto:
|
||||
# we must leave endless loops eventually:
|
||||
#if someChange:
|
||||
pc = pc + code[pc].dest
|
||||
#else:
|
||||
# inc pc
|
||||
if not takenGotos.containsOrIncl(pc) or someChange:
|
||||
pc = pc + code[pc].dest
|
||||
else:
|
||||
inc pc
|
||||
of fork:
|
||||
# we follow the next instruction but push the dest onto our "work" stack:
|
||||
#if someChange:
|
||||
|
|
@ -405,6 +409,10 @@ proc dfa(code: seq[Instr]) =
|
|||
of use, useWithinCall, def:
|
||||
inc pc
|
||||
|
||||
when defined(useDfa) and defined(debugDfa):
|
||||
for i in 0..<code.len:
|
||||
echo "PC ", i, ": defs: ", d[i], "; uses ", u[i]
|
||||
|
||||
# now check the condition we're interested in:
|
||||
for i in 0..<code.len:
|
||||
case code[i].kind
|
||||
|
|
@ -508,7 +516,7 @@ proc dfaUnused(code: seq[Instr]) =
|
|||
proc dataflowAnalysis*(s: PSym; body: PNode) =
|
||||
var c = Con(code: @[], blocks: @[])
|
||||
gen(c, body)
|
||||
#echoCfg(c.code)
|
||||
when defined(useDfa) and defined(debugDfa): echoCfg(c.code)
|
||||
dfa(c.code)
|
||||
|
||||
proc constructCfg*(s: PSym; body: PNode): ControlFlowGraph =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue