thavlak.nim: more idiomatic code
This commit is contained in:
parent
d45a736cc8
commit
135774d92b
1 changed files with 45 additions and 45 deletions
|
|
@ -18,38 +18,38 @@ when not declared(withScratchRegion):
|
||||||
template withScratchRegion(body: untyped) = body
|
template withScratchRegion(body: untyped) = body
|
||||||
|
|
||||||
type
|
type
|
||||||
BasicBlock = object
|
BasicBlock = ref object
|
||||||
inEdges: seq[ref BasicBlock]
|
inEdges: seq[BasicBlock]
|
||||||
outEdges: seq[ref BasicBlock]
|
outEdges: seq[BasicBlock]
|
||||||
name: int
|
name: int
|
||||||
|
|
||||||
proc newBasicBlock(name: int): ref BasicBlock =
|
proc newBasicBlock(name: int): BasicBlock =
|
||||||
result = (ref BasicBlock)(
|
result = BasicBlock(
|
||||||
inEdges: newSeq[ref BasicBlock](),
|
inEdges: newSeq[BasicBlock](),
|
||||||
outEdges: newSeq[ref BasicBlock](),
|
outEdges: newSeq[BasicBlock](),
|
||||||
name: name
|
name: name
|
||||||
)
|
)
|
||||||
|
|
||||||
proc hash(x: ref BasicBlock): int {.inline.} =
|
proc hash(x: BasicBlock): int {.inline.} =
|
||||||
result = x.name
|
result = x.name
|
||||||
|
|
||||||
type
|
type
|
||||||
BasicBlockEdge = object
|
BasicBlockEdge = object
|
||||||
fr: ref BasicBlock
|
fr: BasicBlock
|
||||||
to: ref BasicBlock
|
to: BasicBlock
|
||||||
|
|
||||||
Cfg = object
|
Cfg = object
|
||||||
basicBlockMap: Table[int, ref BasicBlock]
|
basicBlockMap: Table[int, BasicBlock]
|
||||||
edgeList: seq[BasicBlockEdge]
|
edgeList: seq[BasicBlockEdge]
|
||||||
startNode: ref BasicBlock
|
startNode: BasicBlock
|
||||||
|
|
||||||
proc newCfg(): Cfg =
|
proc newCfg(): Cfg =
|
||||||
result = Cfg(
|
result = Cfg(
|
||||||
basicBlockMap: initTable[int, ref BasicBlock](),
|
basicBlockMap: initTable[int, BasicBlock](),
|
||||||
edgeList: newSeq[BasicBlockEdge](),
|
edgeList: newSeq[BasicBlockEdge](),
|
||||||
startNode: nil)
|
startNode: nil)
|
||||||
|
|
||||||
proc createNode(self: var Cfg, name: int): ref BasicBlock =
|
proc createNode(self: var Cfg, name: int): BasicBlock =
|
||||||
result = self.basicBlockMap.getOrDefault(name)
|
result = self.basicBlockMap.getOrDefault(name)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
result = newBasicBlock(name)
|
result = newBasicBlock(name)
|
||||||
|
|
@ -68,23 +68,23 @@ proc newBasicBlockEdge(cfg: var Cfg, fromName, toName: int) =
|
||||||
cfg.edgeList.add(result)
|
cfg.edgeList.add(result)
|
||||||
|
|
||||||
type
|
type
|
||||||
SimpleLoop = object
|
SimpleLoop = ref object
|
||||||
basicBlocks: seq[ref BasicBlock] # TODO: set here
|
basicBlocks: seq[BasicBlock] # TODO: set here
|
||||||
children: seq[ref SimpleLoop] # TODO: set here
|
children: seq[SimpleLoop] # TODO: set here
|
||||||
parent: ref SimpleLoop
|
parent: SimpleLoop
|
||||||
header: ref BasicBlock
|
header: BasicBlock
|
||||||
isRoot, isReducible: bool
|
isRoot, isReducible: bool
|
||||||
counter, nestingLevel, depthLevel: int
|
counter, nestingLevel, depthLevel: int
|
||||||
|
|
||||||
proc setParent(self: ref SimpleLoop, parent: ref SimpleLoop) =
|
proc setParent(self: SimpleLoop, parent: SimpleLoop) =
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.parent.children.add self
|
self.parent.children.add self
|
||||||
|
|
||||||
proc setHeader(self: ref SimpleLoop, bb: ref BasicBlock) =
|
proc setHeader(self: SimpleLoop, bb: BasicBlock) =
|
||||||
self.basicBlocks.add(bb)
|
self.basicBlocks.add(bb)
|
||||||
self.header = bb
|
self.header = bb
|
||||||
|
|
||||||
proc setNestingLevel(self: ref SimpleLoop, level: int) =
|
proc setNestingLevel(self: SimpleLoop, level: int) =
|
||||||
self.nestingLevel = level
|
self.nestingLevel = level
|
||||||
if level == 0: self.isRoot = true
|
if level == 0: self.isRoot = true
|
||||||
|
|
||||||
|
|
@ -92,40 +92,40 @@ var loopCounter: int = 0
|
||||||
|
|
||||||
type
|
type
|
||||||
Lsg = object
|
Lsg = object
|
||||||
loops: seq[ref SimpleLoop]
|
loops: seq[SimpleLoop]
|
||||||
root: ref SimpleLoop
|
root: SimpleLoop
|
||||||
|
|
||||||
proc createNewLoop(self: var Lsg): ref SimpleLoop =
|
proc createNewLoop(self: var Lsg): SimpleLoop =
|
||||||
result = (ref SimpleLoop)(
|
result = SimpleLoop(
|
||||||
basicBlocks: newSeq[ref BasicBlock](),
|
basicBlocks: newSeq[BasicBlock](),
|
||||||
children: newSeq[ref SimpleLoop](),
|
children: newSeq[SimpleLoop](),
|
||||||
isReducible: true)
|
isReducible: true)
|
||||||
loopCounter += 1
|
loopCounter += 1
|
||||||
result.counter = loopCounter
|
result.counter = loopCounter
|
||||||
|
|
||||||
proc addLoop(self: var Lsg, l: ref SimpleLoop) =
|
proc addLoop(self: var Lsg, l: SimpleLoop) =
|
||||||
self.loops.add l
|
self.loops.add l
|
||||||
|
|
||||||
proc newLsg(): Lsg =
|
proc newLsg(): Lsg =
|
||||||
result = Lsg(loops: newSeq[ref SimpleLoop](),
|
result = Lsg(loops: newSeq[SimpleLoop](),
|
||||||
root: result.createNewLoop())
|
root: result.createNewLoop())
|
||||||
result.root.setNestingLevel(0)
|
result.root.setNestingLevel(0)
|
||||||
result.addLoop(result.root)
|
result.addLoop(result.root)
|
||||||
|
|
||||||
type
|
type
|
||||||
UnionFindNode = object
|
UnionFindNode = ref object
|
||||||
parent {.cursor.}: ref UnionFindNode
|
parent {.cursor.}: UnionFindNode
|
||||||
bb: ref BasicBlock
|
bb: BasicBlock
|
||||||
l: ref SimpleLoop
|
l: SimpleLoop
|
||||||
dfsNumber: int
|
dfsNumber: int
|
||||||
|
|
||||||
proc initNode(self: ref UnionFindNode, bb: ref BasicBlock, dfsNumber: int) =
|
proc initNode(self: UnionFindNode, bb: BasicBlock, dfsNumber: int) =
|
||||||
self.parent = self
|
self.parent = self
|
||||||
self.bb = bb
|
self.bb = bb
|
||||||
self.dfsNumber = dfsNumber
|
self.dfsNumber = dfsNumber
|
||||||
|
|
||||||
proc findSet(self: ref UnionFindNode): ref UnionFindNode =
|
proc findSet(self: UnionFindNode): UnionFindNode =
|
||||||
var nodeList = newSeq[ref UnionFindNode]()
|
var nodeList = newSeq[UnionFindNode]()
|
||||||
var it {.cursor.} = self
|
var it {.cursor.} = self
|
||||||
|
|
||||||
while it != it.parent:
|
while it != it.parent:
|
||||||
|
|
@ -136,7 +136,7 @@ proc findSet(self: ref UnionFindNode): ref UnionFindNode =
|
||||||
for iter in nodeList: iter.parent = it.parent
|
for iter in nodeList: iter.parent = it.parent
|
||||||
result = it
|
result = it
|
||||||
|
|
||||||
proc union(self: ref UnionFindNode, unionFindNode: ref UnionFindNode) =
|
proc union(self: UnionFindNode, unionFindNode: UnionFindNode) =
|
||||||
self.parent = unionFindNode
|
self.parent = unionFindNode
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -164,8 +164,8 @@ proc newHavlakLoopFinder(cfg: Cfg, lsg: sink Lsg): HavlakLoopFinder =
|
||||||
proc isAncestor(w, v: int, last: seq[int]): bool =
|
proc isAncestor(w, v: int, last: seq[int]): bool =
|
||||||
w <= v and v <= last[w]
|
w <= v and v <= last[w]
|
||||||
|
|
||||||
proc dfs(currentNode: ref BasicBlock, nodes: var seq[ref UnionFindNode],
|
proc dfs(currentNode: BasicBlock, nodes: var seq[UnionFindNode],
|
||||||
number: var Table[ref BasicBlock, int],
|
number: var Table[BasicBlock, int],
|
||||||
last: var seq[int], current: int) =
|
last: var seq[int], current: int) =
|
||||||
var stack = @[(currentNode, current)]
|
var stack = @[(currentNode, current)]
|
||||||
while stack.len > 0:
|
while stack.len > 0:
|
||||||
|
|
@ -186,16 +186,16 @@ proc findLoops(self: var HavlakLoopFinder): int =
|
||||||
|
|
||||||
var nonBackPreds = newSeq[HashSet[int]]()
|
var nonBackPreds = newSeq[HashSet[int]]()
|
||||||
var backPreds = newSeq[seq[int]]()
|
var backPreds = newSeq[seq[int]]()
|
||||||
var number = initTable[ref BasicBlock, int]()
|
var number = initTable[BasicBlock, int]()
|
||||||
var header = newSeq[int](size)
|
var header = newSeq[int](size)
|
||||||
var types = newSeq[int](size)
|
var types = newSeq[int](size)
|
||||||
var last = newSeq[int](size)
|
var last = newSeq[int](size)
|
||||||
var nodes = newSeq[ref UnionFindNode]()
|
var nodes = newSeq[UnionFindNode]()
|
||||||
|
|
||||||
for i in 1..size:
|
for i in 1..size:
|
||||||
nonBackPreds.add initHashSet[int](1)
|
nonBackPreds.add initHashSet[int](1)
|
||||||
backPreds.add newSeq[int]()
|
backPreds.add newSeq[int]()
|
||||||
nodes.add((ref UnionFindNode)())
|
nodes.add(UnionFindNode())
|
||||||
|
|
||||||
# Step a:
|
# Step a:
|
||||||
# - initialize all nodes as unvisited.
|
# - initialize all nodes as unvisited.
|
||||||
|
|
@ -248,7 +248,7 @@ proc findLoops(self: var HavlakLoopFinder): int =
|
||||||
|
|
||||||
for w in countdown(size - 1, 0):
|
for w in countdown(size - 1, 0):
|
||||||
# this is 'P' in Havlak's paper
|
# this is 'P' in Havlak's paper
|
||||||
var nodePool = newSeq[ref UnionFindNode]()
|
var nodePool = newSeq[UnionFindNode]()
|
||||||
|
|
||||||
var nodeW = nodes[w].bb
|
var nodeW = nodes[w].bb
|
||||||
if nodeW != nil: # dead BB
|
if nodeW != nil: # dead BB
|
||||||
|
|
@ -261,7 +261,7 @@ proc findLoops(self: var HavlakLoopFinder): int =
|
||||||
|
|
||||||
# Copy nodePool to workList.
|
# Copy nodePool to workList.
|
||||||
#
|
#
|
||||||
var workList = newSeq[ref UnionFindNode]()
|
var workList = newSeq[UnionFindNode]()
|
||||||
for x in nodePool: workList.add x
|
for x in nodePool: workList.add x
|
||||||
|
|
||||||
if nodePool.len != 0: types[w] = BB_REDUCIBLE
|
if nodePool.len != 0: types[w] = BB_REDUCIBLE
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue