Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aaron/lesson3 tasks #2

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
3941a3d
add the cfg and dce code
atucker Feb 3, 2022
a4bb3c4
gold the outputs of tdce+ for turnt, and then tweak the test to be us…
atucker Feb 3, 2022
d705d4e
write an implementation of lvn that works reasonably well
atucker Feb 8, 2022
16a3600
I now see the wisdom in leaving dead code id operations in code -- in…
atucker Feb 8, 2022
f7d98ca
realize that I need to do constant substitutions and not just id subs…
atucker Feb 8, 2022
622ae43
move the id lookup from the insertion to the value making, which seem…
atucker Feb 8, 2022
3c7ae8a
try to handle nonlocality by invalidating the var_to_idx cache. Basic…
atucker Feb 9, 2022
4342669
move the id unrolling into the idx_to_* mappings. This seems to work …
atucker Feb 9, 2022
20243d6
fix a bug where I wasn't keeping granular enough details for the argu…
atucker Feb 9, 2022
1c2743c
switch to Adrian's variable names that I'm seeing in the test outputs
atucker Feb 9, 2022
778fcda
refactor to make the variable lookup table an object rather than a bu…
atucker Feb 9, 2022
4baa1c5
this should have been two commits basically, but the point here is to…
atucker Feb 9, 2022
669b8b2
move the destination renaming logic out of the table
atucker Feb 9, 2022
890fc69
fix a bug where once we decide to replace something with an id, we ho…
atucker Feb 9, 2022
7dbaeda
get lines under 80 characters
atucker Feb 9, 2022
e20f634
fix a typo in the refactor
atucker Feb 9, 2022
4cd6635
change to a rename structure that I like more
atucker Feb 9, 2022
0c3a581
with the new unpacking flow it seems that we don't need to unroll id …
atucker Feb 9, 2022
7eb331e
improve the representation of constants to include the type, because …
atucker Feb 9, 2022
528544b
remove functions from the variable mapping interface to keep things c…
atucker Feb 9, 2022
f690a21
clean up the constant replacement logic more -- once we know somethin…
atucker Feb 9, 2022
9441b2e
go clean up the issue that I caused by removing hte bit where I aggre…
atucker Feb 9, 2022
73e7d11
rearrange functions a bit
atucker Feb 9, 2022
32bf4a8
realize that all of the constant instructions are already correct + g…
atucker Feb 9, 2022
6758677
assert that if our value was a constant then we've already set up the…
atucker Feb 9, 2022
c50fd5f
refactor to make it clearer that a bunch of our optimizations are jus…
atucker Feb 9, 2022
2873eb9
actually look through the docs to make sure I caught all the commutat…
atucker Feb 9, 2022
a1e373a
fix a bug in how I was handling variable names that I introduced in t…
atucker Feb 9, 2022
a655712
keep track of types in the constant value entires
atucker Feb 9, 2022
f2aa016
do a basic implementation of replacing values with constants when pos…
atucker Feb 9, 2022
fb35aa0
implement a bunch of special cases so that even if the operation uses…
atucker Feb 9, 2022
3964662
this is a badly organized commit which slightly refactors our computa…
atucker Feb 9, 2022
e1fcdb5
small tweaks
atucker Feb 9, 2022
10aae8c
fix bug in compute_expression
atucker Feb 10, 2022
4877959
better printing
atucker Feb 10, 2022
d97e0c9
actually build test coverage. This basically just takes the example t…
atucker Feb 11, 2022
029c1f9
fix a dce bug that came up in testing
atucker Feb 11, 2022
3851dc4
fix a bug in renaming variables that are going to be replaced in lvn
atucker Feb 11, 2022
db1adb4
get rid of something in the main logic that didn't seem necessary
atucker Feb 11, 2022
88c504f
gold the lvn outputs so that we can show all the test results at once
atucker Feb 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions compiler/cfg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import json
import sys

TERMINATORS = {'jmp', 'br', 'ret'}


def make_blocks(body):
cur_block = []
for instr in body:
if 'op' in instr:
cur_block.append(instr)
if instr['op'] in TERMINATORS:
if cur_block: yield cur_block
cur_block = []
elif 'label' in instr:
if cur_block: yield cur_block
cur_block = [instr]
else:
assert False, f"{instr} has neither an op nor label"
if cur_block: yield cur_block


def name_blocks(blocks):
named_blocks = []
for block in blocks:
name = f"b{len(named_blocks)}"
print(block)
if 'label' in block[0]:
name = block[0]['label']
named_blocks.append((name, block))
return named_blocks


def make_cfg():
prog = json.load(sys.stdin)
cfg = {}
for func in prog['functions']:
named_blocks = name_blocks(make_blocks(func['instrs']))
for i, (name, block) in enumerate(named_blocks):
if 'op' in block[-1] and block[-1]['op'] in {'jmp', 'br'}:
cfg[name] = block[-1]['labels']
elif 'op' in block[-1] and block[-1]['op'] == 'ret':
cfg[name] = []
else:
if i + 1 < len(named_blocks):
cfg[name] = [named_blocks[i+1][0]]
else:
cfg[name] = []
print(cfg)


if __name__ == "__main__":
make_cfg()
58 changes: 58 additions & 0 deletions compiler/dce.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import json
import sys
from cfg import make_blocks


def eliminate_unused_vars(instructions):
used_variables = set()
for instr in instructions:
if 'args' in instr:
for var in instr['args']:
used_variables.add(var)

for i, instr in enumerate(instructions):
if 'dest' in instr and instr['dest'] not in used_variables:
print(f"Deleting {instr}", file=sys.stderr)
instructions.remove(instr)

return instructions


def eliminate_redundant_assigns_in_basic_block(block):
assigned_but_unused = {}
for i, instr in enumerate(block):
if 'args' in instr:
for arg in instr['args']:
if arg in assigned_but_unused:
del assigned_but_unused[arg]
if 'dest' in instr:
if instr['dest'] in assigned_but_unused:
del block[assigned_but_unused[instr['dest']]]
assigned_but_unused[instr['dest']] = i


def do_dce():
prog = json.load(sys.stdin)
for func in prog['functions']:
# Eliminate everything which just doesn't get used
old_len = 0
while len(func['instrs']) != old_len:
old_len = len(func['instrs'])
func['instrs'] = eliminate_unused_vars(func['instrs'])

# Eliminate everything which gets reassigned before use
blocks = make_blocks(func['instrs'])
instructions = []
for block in blocks:
old_len = 0
while len(block) != old_len:
old_len = len(block)
eliminate_redundant_assigns_in_basic_block(block)
instructions.extend(block)
func['instrs'] = instructions

print(json.dumps(prog))


if __name__ == '__main__':
do_dce()
Loading