Created
October 12, 2018 11:04
-
-
Save Araq/6bb3b253c6ac6c0a27e61ae36d65f1d7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
proc isLastRead(n: PNode; c: var Con): bool = | |
# first we need to search for the instruction that belongs to 'n': | |
doAssert n.kind == nkSym | |
c.otherRead = nil | |
var instr = -1 | |
for i in 0..<c.g.len: | |
if c.g[i].n == n: | |
if instr < 0: instr = i | |
else: | |
# eh, we found two positions that belong to 'n'? | |
# better return 'false' then: | |
return false | |
if instr < 0: return false | |
# we go through all paths beginning from 'instr+1' and need to | |
# ensure that we don't find another 'use X' instruction. | |
if instr+1 >= c.g.len: return true | |
let s = n.sym | |
var pcs: seq[int] = @[instr+1] | |
var takenGotos: IntSet | |
while pcs.len > 0: | |
var pc = pcs.pop | |
while pc < c.g.len: | |
case c.g[pc].kind | |
of def: | |
if c.g[pc].sym == s: | |
# the path lead to a redefinition of 's' --> abandon it | |
break | |
inc pc | |
of use, useWithinCall: | |
if c.g[pc].sym == s: | |
c.otherRead = c.g[pc].n | |
return false | |
inc pc | |
of goto: | |
# we must leave endless loops eventually: | |
if not takenGotos.containsOrIncl(pc): | |
pc = pc + c.g[pc].dest | |
else: | |
inc pc | |
of fork: | |
# we follow the next instruction but push the dest onto our "work" stack: | |
if not takenGotos.containsOrIncl(pc): | |
pcs.add pc + c.g[pc].dest | |
inc pc | |
return true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment