Skip to content

Commit

Permalink
Merge b6b7d7e into 70a342b
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardt committed Oct 18, 2018
2 parents 70a342b + b6b7d7e commit 42771cd
Show file tree
Hide file tree
Showing 11 changed files with 645 additions and 262 deletions.
9 changes: 5 additions & 4 deletions silica/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

import magma as m
from magma import Bit, zext, concat, Array, Bits, UInt
from magma.bit_vector import BitVector
from bit_vector import BitVector
import bit_vector
import operator


Expand All @@ -16,12 +17,12 @@ def __repr__(self):

class Memory(list):
def __getitem__(self, key):
if isinstance(key, m.bit_vector.BitVector):
if isinstance(key, bit_vector.BitVector):
key = key.as_int()
return super().__getitem__(key)

def __setitem__(self, key, value):
if isinstance(key, m.bit_vector.BitVector):
if isinstance(key, bit_vector.BitVector):
key = key.as_int()
return super().__setitem__(key, value)

Expand All @@ -42,7 +43,7 @@ def zext(value, n):
return BitVector(value, num_bits=n + value.num_bits)

def add(a, b, cout=False):
assert isinstance(a, m.bit_vector.BitVector) and isinstance(b, m.bit_vector.BitVector)
assert isinstance(a, bit_vector.BitVector) and isinstance(b, bit_vector.BitVector)
assert len(a) == len(b)
if cout:
width = len(a)
Expand Down
366 changes: 192 additions & 174 deletions silica/cfg/control_flow_graph.py

Large diffs are not rendered by default.

49 changes: 29 additions & 20 deletions silica/cfg/liveness.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import ast
from .types import Yield, HeadBlock, Branch
import silica.ast_utils as ast_utils
import copy


class Analyzer(ast.NodeVisitor):
def __init__(self):
self.gen = set()
self.kill = set()
self.in_assign = False
# self.return_values = set()

def visit_Call(self, node):
Expand All @@ -19,16 +22,18 @@ def visit_Call(self, node):
def visit_Assign(self, node):
# Need to visit loads before store
self.visit(node.value)
self.in_assign = True
self.visit(node.targets[0])
self.in_assign = False

def visit_Name(self, node):
if isinstance(node.ctx, ast.Load):
if isinstance(node.ctx, ast.Store) or self.in_assign:
self.kill.add(node.id)
else:
if node.id not in self.kill:
self.gen.add(node.id)
else:
self.kill.add(node.id)
if node.id in self.gen:
self.gen.remove(node.id)
# if node.id in self.gen:
# self.gen.remove(node.id)

# def visit_Return(self, node):
# if isinstance(node, ast.Tuple):
Expand All @@ -42,7 +47,7 @@ def analyze(node):
analyzer = Analyzer()
if isinstance(node, Yield):
analyzer.visit(node.value)
analyzer.gen = set(value for value in node.output_map.values())
# analyzer.gen = set(value for value in node.output_map.values())
# if not node.terminal: # We only use assigments
# analyzer.gen = set()
# else:
Expand All @@ -59,26 +64,30 @@ def analyze(node):
analyzer.visit(statement)
return analyzer.gen, analyzer.kill

def do_analysis(block, seen=set()):
if block in seen:
return block.live_ins
seen.add(block)
def do_analysis(block, cfg):
block.gen, block.kill = analyze(block)
if not isinstance(block, Yield):
if isinstance(block, Branch):
true_live_ins = do_analysis(block.true_edge, seen)
false_live_ins = do_analysis(block.false_edge, seen)
block.live_outs = true_live_ins | false_live_ins
for path in cfg.paths:
if block in path and block.true_edge in path:
block.live_outs |= do_analysis(block.true_edge, cfg)
if block in path and block.false_edge in path:
block.live_outs |= do_analysis(block.false_edge, cfg)
else:
block.live_outs = do_analysis(block.outgoing_edge[0], seen)
block.live_outs |= do_analysis(block.outgoing_edge[0], cfg)
still_live = block.live_outs - block.kill
block.live_ins = block.gen | still_live
return block.live_ins

def liveness_analysis(cfg):
for block in cfg.blocks:
if isinstance(block, (HeadBlock, Yield)):
block.live_outs = do_analysis(block.outgoing_edge[0])
block.gen, block.kill = analyze(block)
still_live = block.live_outs - block.kill
block.live_ins = still_live
last_live_outs = None
curr_live_outs = [copy.copy(block.live_outs) for block in cfg.blocks]
while last_live_outs != curr_live_outs:
for block in cfg.blocks:
if isinstance(block, (HeadBlock, Yield)):
block.live_outs = do_analysis(block.outgoing_edge[0], cfg)
block.gen, block.kill = analyze(block)
still_live = block.live_outs - block.kill
block.live_ins = block.gen | still_live
last_live_outs = curr_live_outs
curr_live_outs = [copy.copy(block.live_outs) for block in cfg.blocks]
Loading

0 comments on commit 42771cd

Please sign in to comment.