diff --git a/compiler/cfg.py b/compiler/cfg.py new file mode 100644 index 000000000..f31d8e037 --- /dev/null +++ b/compiler/cfg.py @@ -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() diff --git a/compiler/dce.py b/compiler/dce.py new file mode 100644 index 000000000..c3fcfdf5d --- /dev/null +++ b/compiler/dce.py @@ -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() \ No newline at end of file diff --git a/compiler/lvn.py b/compiler/lvn.py new file mode 100644 index 000000000..3775e5fa7 --- /dev/null +++ b/compiler/lvn.py @@ -0,0 +1,289 @@ +import json +import sys +from collections import defaultdict +from functools import reduce + +DEBUG = False +COMMUTATIVE = {'add', 'mul', 'or', 'and', 'eq'} +CAST_VALUE = { + 'int': int, + 'bool': bool +} +EXPRESSIONS = { + 'add': lambda a, b: a + b, + 'mul': lambda a, b: a * b, + 'sub': lambda a, b: a - b, + 'div': lambda a, b: a / b, + 'eq': lambda a, b: a == b, + 'lt': lambda a, b: a < b, + 'gt': lambda a, b: a > b, + 'le': lambda a, b: a <= b, + 'ge': lambda a, b: a >= b, + 'not': lambda a: not a, + 'and': lambda a, b: a and b, + 'or': lambda a, b: a or b +} + + +class Simplification: + def __init__(self, trigger, val, result): + assert trigger in {'either', '2'} + self.trigger = trigger + self.val = val + self.result = result + + def simplify(self, arg1, arg2): + if self.trigger == 'either': + if self.val == arg1: + return self.render_result(arg2) + if self.val == arg2: + return self.render_result(arg1) + # return None if this simplification doesn't do anything + return None + + def render_result(self, other): + res = other if self.result == 'identity' else self.result + return res + + +SIMPLIFICATIONS = { + 'add': [Simplification('either', 0, 'identity')], + 'mul': [Simplification('either', 1, 'identity')], + 'sub': [Simplification('2', 0, 'identity')], + 'div': [Simplification('2', 1, 'identity')], + 'and': [Simplification('either', True, 'identity'), + Simplification('either', False, False)], + 'or': [Simplification('either', False, 'identity'), + Simplification('either', True, True)] +} + + +def compute_expression(value, const_vals, do_special_cases=False): + op = value[0] + val = None + + if op in SIMPLIFICATIONS and do_special_cases: + for simplification in SIMPLIFICATIONS[op]: + ans = simplification.simplify(*const_vals) + if ans is not None: + if isinstance(ans, tuple): + assert ans[0] == 'variable' + return ('id', value[1], ans[1]) + else: + return ('const', value[1], ans) + + is_consts = [not isinstance(val, tuple) for val in const_vals] + if reduce(lambda a, b: a and b, is_consts, True): + try: + val = EXPRESSIONS[value[0]](*const_vals) + return ('const', value[1], val) + except Exception: + return value + else: + return value + + +def debug_msg(*args): + if DEBUG: + print(*args, file=sys.stderr) + + +class VarMapping: + def __init__(self, compute_constant_ops=True, do_special_cases=True): + self.var_to_idx = dict() + self.value_to_idx = dict() + self.table = [] # idx is #, then contains tuples of (value, home) + self.compute_constant_ops = compute_constant_ops + self.do_special_cases = do_special_cases + + def insert_var(self, var, value): + # If it's not already in the table, add it + if value not in self.value_to_idx: + idx = len(self.table) + self.table.append((value, var)) + # This is only set on insert, so it is correct + self.value_to_idx[value] = idx + + # always map the variable to the index + # this means we remap on reassignment, which is correct + self.var_to_idx[var] = self.value_to_idx[value] + + def _idx_to_home_var(self, idx): + return self.table[idx][1] + + def _idx_to_value(self, idx): + return self.table[idx][0] + + def unroll_ids(self, value): + if value[0] == 'id': + assert len(value) == 3 + return self.unroll_ids(self._idx_to_value(value[2])) + return value + + def add_unseen_variables(self, args): + for arg in args: + if arg not in self.var_to_idx: + self.insert_var(arg, ('arg', arg)) + + def _replace_indices_through_idx(self, indices): + ans = [] + for idx in indices: + value = self._idx_to_value(idx) + value = self.unroll_ids(value) + ans.append(self.value_to_idx[value]) + return ans + + def _const_value_from_index(self, idx): + value = self._idx_to_value(idx) + if value[0] == 'const': + return CAST_VALUE[value[1]](value[2]) + else: + # This needs to be an enum or something if we ever handle tuples + return ('variable', idx) + + def make_value(self, instr): + op = instr['op'] + type = instr['type'] if 'type' in instr else None + if 'args' in instr: + self.add_unseen_variables(instr['args']) + indices = [self.var_to_idx[arg] for arg in instr['args']] + + indices = self._replace_indices_through_idx(indices) + if op in COMMUTATIVE: + indices = sorted(indices) + + value = op, type, *indices + if op not in {'const', 'id'} and self.compute_constant_ops: + vals = [self._const_value_from_index(idx) for idx in value[2:]] + value = compute_expression( + value, vals, do_special_cases=self.do_special_cases + ) + return value + elif 'value' in instr: + return (op, instr['type'], instr['value']) + else: + assert False, f"idk how to make value for {instr}" + + def indices_to_vars(self, indices): + return [self._idx_to_home_var(idx) for idx in indices] + + def value_to_home_var(self, value): + return self._idx_to_home_var(self.value_to_idx[value]) + + def rename(self, old_name, new_name): + idx = self.var_to_idx[old_name] + # If we're renaming a variable which is being used as a home variable + # we need to go update that to its new name + if self._idx_to_home_var(idx) == old_name: + self.table[idx] = (self.table[idx][0], new_name) + + +def count_variables(func): + ans = defaultdict(lambda : 0) + for instr in func['instrs']: + if 'dest' in instr: + ans[instr['dest']] += 1 + return ans + + +def const_instr(dest, value): + assert value[0] == 'const' + assert len(value) == 3 + return {'dest': dest, 'op': 'const', 'value': value[2], 'type': value[1]} + + +def id_instr(dest, type, home_var): + return {'dest': dest, 'op': 'id', 'args': [home_var], 'type': type} + + +def name_dest(var_counts, lvn_count, dest): + var_counts[dest] -= 1 + if var_counts[dest] > 0: + dest = f'lvn.{dest}.{lvn_count}' + assert dest not in var_counts, f"Alas, {dest} is used" + return dest + + +def do_lvn(): + prog = json.load(sys.stdin) + renamed_var_count = 0 + + for func in prog['functions']: + var_table = VarMapping() + if 'args' in func: + var_table.add_unseen_variables([ + arg['name'] for arg in func['args'] + ]) + + var_counts = count_variables(func) + new_instrs = [] + for instr in func['instrs']: + for key in instr.keys(): + assert key in {'op', 'dest', 'args', 'type', 'funcs', 'value', + 'label', 'labels'}, \ + f"Unrecognized instruction key {key}" + + if 'op' in instr and instr['op'] not in {'jmp', 'br'}: + old_instr = instr + old_value = var_table.make_value(instr) + value = var_table.unroll_ids(old_value) + debug_msg(f"Unrolled id lookups for {old_value} -> {value}") + # If we simplified the value into a constant, put it in the + # table so that the simplification step can find it + if old_value[0] == 'const' and instr['op'] != 'const': + var_table.insert_var(instr['dest'], value) + + if 'dest' in instr: + dest = instr['dest'] + + # If the value is already there, replace with id or constant + if value in var_table.value_to_idx: + home_var = var_table.value_to_home_var(value) + if value[0] == 'const': + instr = const_instr(dest, value) + else: + instr = id_instr(dest, instr['type'], home_var) + value = var_table.make_value(instr) + + # If the var gets used again, rename it + new_dest = name_dest(var_counts, renamed_var_count, dest) + if new_dest != dest: + var_table.insert_var(dest, value) + var_table.rename(dest, new_dest) + instr['dest'] = dest = new_dest + renamed_var_count += 1 + + # Put the value in the destination + var_table.insert_var(dest, value) + + debug_msg(f"{old_instr} -> {instr} -> {value}") + + if 'args' in instr: + # Replace arg indices with their home variables + debug_msg(f"Table: {var_table.table}") + instr['args'] = var_table.indices_to_vars(value[2:]) + + if value[0] == 'const': + debug_msg(f"Constant {instr} should describe {value}") + assert instr['op'] == 'const' + assert instr['type'] == value[1] + assert instr['value'] == value[2] + + new_instrs.append(instr) + debug_msg("") + + else: + # If it's a label instruction, then we might have jumped and + # so we need to drop the cache + if 'label' in instr: + var_table = VarMapping() + + # if its not an op, then just put it back unchanged + new_instrs.append(instr) + + func['instrs'] = new_instrs + print(json.dumps(prog)) + + +if __name__ == '__main__': + do_lvn() \ No newline at end of file diff --git a/compiler/test/dce-gold/combo.bril b/compiler/test/dce-gold/combo.bril new file mode 100644 index 000000000..5dbd6e8b2 --- /dev/null +++ b/compiler/test/dce-gold/combo.bril @@ -0,0 +1,8 @@ +@main { + a: int = const 1; + b: int = const 2; + c: int = add a b; + b: int = const 3; + d: int = add a b; + print d; +} diff --git a/compiler/test/dce-gold/combo.out b/compiler/test/dce-gold/combo.out new file mode 100644 index 000000000..b8626c4cf --- /dev/null +++ b/compiler/test/dce-gold/combo.out @@ -0,0 +1 @@ +4 diff --git a/compiler/test/dce-gold/combo.prof b/compiler/test/dce-gold/combo.prof new file mode 100644 index 000000000..d887198fd --- /dev/null +++ b/compiler/test/dce-gold/combo.prof @@ -0,0 +1 @@ +total_dyn_inst: 6 diff --git a/compiler/test/dce-gold/diamond.bril b/compiler/test/dce-gold/diamond.bril new file mode 100644 index 000000000..0bd0cf156 --- /dev/null +++ b/compiler/test/dce-gold/diamond.bril @@ -0,0 +1,13 @@ +@main { + a: int = const 47; + cond: bool = const true; + br cond .left .right; +.left: + a: int = const 1; + jmp .end; +.right: + a: int = const 2; + jmp .end; +.end: + print a; +} diff --git a/compiler/test/dce-gold/diamond.out b/compiler/test/dce-gold/diamond.out new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/compiler/test/dce-gold/diamond.out @@ -0,0 +1 @@ +1 diff --git a/compiler/test/dce-gold/diamond.prof b/compiler/test/dce-gold/diamond.prof new file mode 100644 index 000000000..d887198fd --- /dev/null +++ b/compiler/test/dce-gold/diamond.prof @@ -0,0 +1 @@ +total_dyn_inst: 6 diff --git a/compiler/test/dce-gold/double-pass.bril b/compiler/test/dce-gold/double-pass.bril new file mode 100644 index 000000000..fb6096a8e --- /dev/null +++ b/compiler/test/dce-gold/double-pass.bril @@ -0,0 +1,8 @@ +@main { + a: int = const 4; + b: int = const 2; + c: int = const 1; + d: int = add a b; + e: int = add c d; + print d; +} diff --git a/compiler/test/dce-gold/double-pass.out b/compiler/test/dce-gold/double-pass.out new file mode 100644 index 000000000..1e8b31496 --- /dev/null +++ b/compiler/test/dce-gold/double-pass.out @@ -0,0 +1 @@ +6 diff --git a/compiler/test/dce-gold/double-pass.prof b/compiler/test/dce-gold/double-pass.prof new file mode 100644 index 000000000..d887198fd --- /dev/null +++ b/compiler/test/dce-gold/double-pass.prof @@ -0,0 +1 @@ +total_dyn_inst: 6 diff --git a/compiler/test/dce-gold/double.bril b/compiler/test/dce-gold/double.bril new file mode 100644 index 000000000..fb6096a8e --- /dev/null +++ b/compiler/test/dce-gold/double.bril @@ -0,0 +1,8 @@ +@main { + a: int = const 4; + b: int = const 2; + c: int = const 1; + d: int = add a b; + e: int = add c d; + print d; +} diff --git a/compiler/test/dce-gold/double.out b/compiler/test/dce-gold/double.out new file mode 100644 index 000000000..1e8b31496 --- /dev/null +++ b/compiler/test/dce-gold/double.out @@ -0,0 +1 @@ +6 diff --git a/compiler/test/dce-gold/double.prof b/compiler/test/dce-gold/double.prof new file mode 100644 index 000000000..d887198fd --- /dev/null +++ b/compiler/test/dce-gold/double.prof @@ -0,0 +1 @@ +total_dyn_inst: 6 diff --git a/compiler/test/dce-gold/reassign-dkp.bril b/compiler/test/dce-gold/reassign-dkp.bril new file mode 100644 index 000000000..b3dabfe62 --- /dev/null +++ b/compiler/test/dce-gold/reassign-dkp.bril @@ -0,0 +1,5 @@ +@main { + a: int = const 100; + a: int = const 42; + print a; +} diff --git a/compiler/test/dce-gold/reassign-dkp.out b/compiler/test/dce-gold/reassign-dkp.out new file mode 100644 index 000000000..d81cc0710 --- /dev/null +++ b/compiler/test/dce-gold/reassign-dkp.out @@ -0,0 +1 @@ +42 diff --git a/compiler/test/dce-gold/reassign-dkp.prof b/compiler/test/dce-gold/reassign-dkp.prof new file mode 100644 index 000000000..ab6154dae --- /dev/null +++ b/compiler/test/dce-gold/reassign-dkp.prof @@ -0,0 +1 @@ +total_dyn_inst: 3 diff --git a/compiler/test/dce-gold/reassign.bril b/compiler/test/dce-gold/reassign.bril new file mode 100644 index 000000000..b3dabfe62 --- /dev/null +++ b/compiler/test/dce-gold/reassign.bril @@ -0,0 +1,5 @@ +@main { + a: int = const 100; + a: int = const 42; + print a; +} diff --git a/compiler/test/dce-gold/reassign.out b/compiler/test/dce-gold/reassign.out new file mode 100644 index 000000000..d81cc0710 --- /dev/null +++ b/compiler/test/dce-gold/reassign.out @@ -0,0 +1 @@ +42 diff --git a/compiler/test/dce-gold/reassign.prof b/compiler/test/dce-gold/reassign.prof new file mode 100644 index 000000000..ab6154dae --- /dev/null +++ b/compiler/test/dce-gold/reassign.prof @@ -0,0 +1 @@ +total_dyn_inst: 3 diff --git a/compiler/test/dce-gold/simple.bril b/compiler/test/dce-gold/simple.bril new file mode 100644 index 000000000..dd83901ed --- /dev/null +++ b/compiler/test/dce-gold/simple.bril @@ -0,0 +1,7 @@ +@main { + a: int = const 4; + b: int = const 2; + c: int = const 1; + d: int = add a b; + print d; +} diff --git a/compiler/test/dce-gold/simple.out b/compiler/test/dce-gold/simple.out new file mode 100644 index 000000000..1e8b31496 --- /dev/null +++ b/compiler/test/dce-gold/simple.out @@ -0,0 +1 @@ +6 diff --git a/compiler/test/dce-gold/simple.prof b/compiler/test/dce-gold/simple.prof new file mode 100644 index 000000000..a87eec418 --- /dev/null +++ b/compiler/test/dce-gold/simple.prof @@ -0,0 +1 @@ +total_dyn_inst: 5 diff --git a/compiler/test/dce-gold/skipped.bril b/compiler/test/dce-gold/skipped.bril new file mode 100644 index 000000000..af45e5492 --- /dev/null +++ b/compiler/test/dce-gold/skipped.bril @@ -0,0 +1,8 @@ +@main { + a: int = const 4; + b: int = const 2; + jmp .end; + print b; +.end: + print a; +} diff --git a/compiler/test/dce-gold/skipped.out b/compiler/test/dce-gold/skipped.out new file mode 100644 index 000000000..b8626c4cf --- /dev/null +++ b/compiler/test/dce-gold/skipped.out @@ -0,0 +1 @@ +4 diff --git a/compiler/test/dce-gold/skipped.prof b/compiler/test/dce-gold/skipped.prof new file mode 100644 index 000000000..7e3da9650 --- /dev/null +++ b/compiler/test/dce-gold/skipped.prof @@ -0,0 +1 @@ +total_dyn_inst: 4 diff --git a/compiler/test/dce-gold/turnt.toml b/compiler/test/dce-gold/turnt.toml new file mode 100644 index 000000000..cd6485f33 --- /dev/null +++ b/compiler/test/dce-gold/turnt.toml @@ -0,0 +1 @@ +command = " bril2json < {filename} | python3 ../../dce.py | brili {args} " diff --git a/compiler/test/dce/combo.bril b/compiler/test/dce/combo.bril new file mode 100644 index 000000000..96ee99646 --- /dev/null +++ b/compiler/test/dce/combo.bril @@ -0,0 +1,9 @@ +# ARGS: tdce+ +@main { + a: int = const 1; + b: int = const 2; + c: int = add a b; + b: int = const 3; + d: int = add a b; + print d; +} diff --git a/compiler/test/dce/combo.out b/compiler/test/dce/combo.out new file mode 100644 index 000000000..30229ec09 --- /dev/null +++ b/compiler/test/dce/combo.out @@ -0,0 +1,6 @@ +@main { + a: int = const 1; + b: int = const 3; + d: int = add a b; + print d; +} diff --git a/compiler/test/dce/diamond.bril b/compiler/test/dce/diamond.bril new file mode 100644 index 000000000..0bd0cf156 --- /dev/null +++ b/compiler/test/dce/diamond.bril @@ -0,0 +1,13 @@ +@main { + a: int = const 47; + cond: bool = const true; + br cond .left .right; +.left: + a: int = const 1; + jmp .end; +.right: + a: int = const 2; + jmp .end; +.end: + print a; +} diff --git a/compiler/test/dce/diamond.out b/compiler/test/dce/diamond.out new file mode 100644 index 000000000..0bd0cf156 --- /dev/null +++ b/compiler/test/dce/diamond.out @@ -0,0 +1,13 @@ +@main { + a: int = const 47; + cond: bool = const true; + br cond .left .right; +.left: + a: int = const 1; + jmp .end; +.right: + a: int = const 2; + jmp .end; +.end: + print a; +} diff --git a/compiler/test/dce/double-pass.bril b/compiler/test/dce/double-pass.bril new file mode 100644 index 000000000..d12cf60ae --- /dev/null +++ b/compiler/test/dce/double-pass.bril @@ -0,0 +1,9 @@ +# ARGS: tdcep +@main { + a: int = const 4; + b: int = const 2; + c: int = const 1; + d: int = add a b; + e: int = add c d; + print d; +} diff --git a/compiler/test/dce/double-pass.out b/compiler/test/dce/double-pass.out new file mode 100644 index 000000000..ae7ac4d82 --- /dev/null +++ b/compiler/test/dce/double-pass.out @@ -0,0 +1,6 @@ +@main { + a: int = const 4; + b: int = const 2; + d: int = add a b; + print d; +} diff --git a/compiler/test/dce/double.bril b/compiler/test/dce/double.bril new file mode 100644 index 000000000..fb6096a8e --- /dev/null +++ b/compiler/test/dce/double.bril @@ -0,0 +1,8 @@ +@main { + a: int = const 4; + b: int = const 2; + c: int = const 1; + d: int = add a b; + e: int = add c d; + print d; +} diff --git a/compiler/test/dce/double.out b/compiler/test/dce/double.out new file mode 100644 index 000000000..ae7ac4d82 --- /dev/null +++ b/compiler/test/dce/double.out @@ -0,0 +1,6 @@ +@main { + a: int = const 4; + b: int = const 2; + d: int = add a b; + print d; +} diff --git a/compiler/test/dce/reassign-dkp.bril b/compiler/test/dce/reassign-dkp.bril new file mode 100644 index 000000000..9f7aa4e7f --- /dev/null +++ b/compiler/test/dce/reassign-dkp.bril @@ -0,0 +1,6 @@ +# ARGS: dkp +@main { + a: int = const 100; + a: int = const 42; + print a; +} diff --git a/compiler/test/dce/reassign-dkp.out b/compiler/test/dce/reassign-dkp.out new file mode 100644 index 000000000..728d98420 --- /dev/null +++ b/compiler/test/dce/reassign-dkp.out @@ -0,0 +1,4 @@ +@main { + a: int = const 42; + print a; +} diff --git a/compiler/test/dce/reassign.bril b/compiler/test/dce/reassign.bril new file mode 100644 index 000000000..b3dabfe62 --- /dev/null +++ b/compiler/test/dce/reassign.bril @@ -0,0 +1,5 @@ +@main { + a: int = const 100; + a: int = const 42; + print a; +} diff --git a/compiler/test/dce/reassign.out b/compiler/test/dce/reassign.out new file mode 100644 index 000000000..728d98420 --- /dev/null +++ b/compiler/test/dce/reassign.out @@ -0,0 +1,4 @@ +@main { + a: int = const 42; + print a; +} diff --git a/compiler/test/dce/simple.bril b/compiler/test/dce/simple.bril new file mode 100644 index 000000000..dd83901ed --- /dev/null +++ b/compiler/test/dce/simple.bril @@ -0,0 +1,7 @@ +@main { + a: int = const 4; + b: int = const 2; + c: int = const 1; + d: int = add a b; + print d; +} diff --git a/compiler/test/dce/simple.out b/compiler/test/dce/simple.out new file mode 100644 index 000000000..ae7ac4d82 --- /dev/null +++ b/compiler/test/dce/simple.out @@ -0,0 +1,6 @@ +@main { + a: int = const 4; + b: int = const 2; + d: int = add a b; + print d; +} diff --git a/compiler/test/dce/skipped.bril b/compiler/test/dce/skipped.bril new file mode 100644 index 000000000..af45e5492 --- /dev/null +++ b/compiler/test/dce/skipped.bril @@ -0,0 +1,8 @@ +@main { + a: int = const 4; + b: int = const 2; + jmp .end; + print b; +.end: + print a; +} diff --git a/compiler/test/dce/skipped.out b/compiler/test/dce/skipped.out new file mode 100644 index 000000000..af45e5492 --- /dev/null +++ b/compiler/test/dce/skipped.out @@ -0,0 +1,8 @@ +@main { + a: int = const 4; + b: int = const 2; + jmp .end; + print b; +.end: + print a; +} diff --git a/compiler/test/dce/turnt.toml b/compiler/test/dce/turnt.toml new file mode 100644 index 000000000..93a0d01cf --- /dev/null +++ b/compiler/test/dce/turnt.toml @@ -0,0 +1 @@ +command = "bril2json < {filename} | python3 ../../dce.py {args} | bril2txt" diff --git a/compiler/test/lvn-gold/clobber-fold.bril b/compiler/test/lvn-gold/clobber-fold.bril new file mode 100644 index 000000000..f0ef57fdd --- /dev/null +++ b/compiler/test/lvn-gold/clobber-fold.bril @@ -0,0 +1,20 @@ +# +@main { + a: int = const 4; + b: int = const 2; + + # (a + b) * (a + b) + sum1: int = add a b; + sum2: int = add a b; + prod1: int = mul sum1 sum2; + + # Clobber both sums. + sum1: int = const 0; + sum2: int = const 0; + + # Use the sums again. + sum3: int = add a b; + prod2: int = mul sum3 sum3; + + print prod2; +} diff --git a/compiler/test/lvn-gold/clobber-fold.out b/compiler/test/lvn-gold/clobber-fold.out new file mode 100644 index 000000000..7facc8993 --- /dev/null +++ b/compiler/test/lvn-gold/clobber-fold.out @@ -0,0 +1 @@ +36 diff --git a/compiler/test/lvn-gold/clobber-fold.prof b/compiler/test/lvn-gold/clobber-fold.prof new file mode 100644 index 000000000..d059c5412 --- /dev/null +++ b/compiler/test/lvn-gold/clobber-fold.prof @@ -0,0 +1 @@ +total_dyn_inst: 10 diff --git a/compiler/test/lvn-gold/clobber.bril b/compiler/test/lvn-gold/clobber.bril new file mode 100644 index 000000000..f0ef57fdd --- /dev/null +++ b/compiler/test/lvn-gold/clobber.bril @@ -0,0 +1,20 @@ +# +@main { + a: int = const 4; + b: int = const 2; + + # (a + b) * (a + b) + sum1: int = add a b; + sum2: int = add a b; + prod1: int = mul sum1 sum2; + + # Clobber both sums. + sum1: int = const 0; + sum2: int = const 0; + + # Use the sums again. + sum3: int = add a b; + prod2: int = mul sum3 sum3; + + print prod2; +} diff --git a/compiler/test/lvn-gold/clobber.out b/compiler/test/lvn-gold/clobber.out new file mode 100644 index 000000000..7facc8993 --- /dev/null +++ b/compiler/test/lvn-gold/clobber.out @@ -0,0 +1 @@ +36 diff --git a/compiler/test/lvn-gold/clobber.prof b/compiler/test/lvn-gold/clobber.prof new file mode 100644 index 000000000..d059c5412 --- /dev/null +++ b/compiler/test/lvn-gold/clobber.prof @@ -0,0 +1 @@ +total_dyn_inst: 10 diff --git a/compiler/test/lvn-gold/commute.bril b/compiler/test/lvn-gold/commute.bril new file mode 100644 index 000000000..220b922e2 --- /dev/null +++ b/compiler/test/lvn-gold/commute.bril @@ -0,0 +1,9 @@ +# (a + b) * (b + a) +@main { + a: int = const 4; + b: int = const 2; + sum1: int = add a b; + sum2: int = add b a; + prod: int = mul sum1 sum2; + print prod; +} diff --git a/compiler/test/lvn-gold/commute.out b/compiler/test/lvn-gold/commute.out new file mode 100644 index 000000000..7facc8993 --- /dev/null +++ b/compiler/test/lvn-gold/commute.out @@ -0,0 +1 @@ +36 diff --git a/compiler/test/lvn-gold/commute.prof b/compiler/test/lvn-gold/commute.prof new file mode 100644 index 000000000..d887198fd --- /dev/null +++ b/compiler/test/lvn-gold/commute.prof @@ -0,0 +1 @@ +total_dyn_inst: 6 diff --git a/compiler/test/lvn-gold/divide-by-zero.out b/compiler/test/lvn-gold/divide-by-zero.out new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/test/lvn-gold/divide-by-zero.prof b/compiler/test/lvn-gold/divide-by-zero.prof new file mode 100644 index 000000000..dcf1fe438 --- /dev/null +++ b/compiler/test/lvn-gold/divide-by-zero.prof @@ -0,0 +1,14 @@ +/Users/aaron/projects/grad_school/cs6120/bril/bril-ts/build/brili.js:789 +process.on('unhandledRejection', e => { throw e; }); + ^ + +RangeError: Division by zero + at evalInstr (/Users/aaron/projects/grad_school/cs6120/bril/bril-ts/build/brili.js:402:51) + at evalFunc (/Users/aaron/projects/grad_school/cs6120/bril/bril-ts/build/brili.js:635:26) + at evalProg (/Users/aaron/projects/grad_school/cs6120/bril/bril-ts/build/brili.js:763:5) + at /Users/aaron/projects/grad_school/cs6120/bril/bril-ts/build/brili.js:775:13 + at Generator.next () + at fulfilled (/Users/aaron/projects/grad_school/cs6120/bril/bril-ts/build/brili.js:6:58) + at processTicksAndRejections (node:internal/process/task_queues:96:5) + +Node.js v17.4.0 diff --git a/compiler/test/lvn-gold/fold-comparisons.out b/compiler/test/lvn-gold/fold-comparisons.out new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/test/lvn-gold/fold-comparisons.prof b/compiler/test/lvn-gold/fold-comparisons.prof new file mode 100644 index 000000000..1c1aa660e --- /dev/null +++ b/compiler/test/lvn-gold/fold-comparisons.prof @@ -0,0 +1 @@ +error: mismatched main argument arity: expected 2; got 0 diff --git a/compiler/test/lvn-gold/idchain-nonlocal.bril b/compiler/test/lvn-gold/idchain-nonlocal.bril new file mode 100644 index 000000000..0b1d81648 --- /dev/null +++ b/compiler/test/lvn-gold/idchain-nonlocal.bril @@ -0,0 +1,9 @@ +@main { + x: int = const 4; + jmp .label; +.label: + copy1: int = id x; + copy2: int = id copy1; + copy3: int = id copy2; + print copy3; +} diff --git a/compiler/test/lvn-gold/idchain-nonlocal.out b/compiler/test/lvn-gold/idchain-nonlocal.out new file mode 100644 index 000000000..b8626c4cf --- /dev/null +++ b/compiler/test/lvn-gold/idchain-nonlocal.out @@ -0,0 +1 @@ +4 diff --git a/compiler/test/lvn-gold/idchain-nonlocal.prof b/compiler/test/lvn-gold/idchain-nonlocal.prof new file mode 100644 index 000000000..d887198fd --- /dev/null +++ b/compiler/test/lvn-gold/idchain-nonlocal.prof @@ -0,0 +1 @@ +total_dyn_inst: 6 diff --git a/compiler/test/lvn-gold/idchain-prop.bril b/compiler/test/lvn-gold/idchain-prop.bril new file mode 100644 index 000000000..83f377c38 --- /dev/null +++ b/compiler/test/lvn-gold/idchain-prop.bril @@ -0,0 +1,7 @@ +@main { + x: int = const 4; + copy1: int = id x; + copy2: int = id copy1; + copy3: int = id copy2; + print copy3; +} diff --git a/compiler/test/lvn-gold/idchain-prop.out b/compiler/test/lvn-gold/idchain-prop.out new file mode 100644 index 000000000..b8626c4cf --- /dev/null +++ b/compiler/test/lvn-gold/idchain-prop.out @@ -0,0 +1 @@ +4 diff --git a/compiler/test/lvn-gold/idchain-prop.prof b/compiler/test/lvn-gold/idchain-prop.prof new file mode 100644 index 000000000..a87eec418 --- /dev/null +++ b/compiler/test/lvn-gold/idchain-prop.prof @@ -0,0 +1 @@ +total_dyn_inst: 5 diff --git a/compiler/test/lvn-gold/idchain.bril b/compiler/test/lvn-gold/idchain.bril new file mode 100644 index 000000000..83f377c38 --- /dev/null +++ b/compiler/test/lvn-gold/idchain.bril @@ -0,0 +1,7 @@ +@main { + x: int = const 4; + copy1: int = id x; + copy2: int = id copy1; + copy3: int = id copy2; + print copy3; +} diff --git a/compiler/test/lvn-gold/idchain.out b/compiler/test/lvn-gold/idchain.out new file mode 100644 index 000000000..b8626c4cf --- /dev/null +++ b/compiler/test/lvn-gold/idchain.out @@ -0,0 +1 @@ +4 diff --git a/compiler/test/lvn-gold/idchain.prof b/compiler/test/lvn-gold/idchain.prof new file mode 100644 index 000000000..a87eec418 --- /dev/null +++ b/compiler/test/lvn-gold/idchain.prof @@ -0,0 +1 @@ +total_dyn_inst: 5 diff --git a/compiler/test/lvn-gold/logical-operators.bril b/compiler/test/lvn-gold/logical-operators.bril new file mode 100644 index 000000000..da26fff98 --- /dev/null +++ b/compiler/test/lvn-gold/logical-operators.bril @@ -0,0 +1,26 @@ +# ARGS: true false + +@main(arg1: bool, arg2: bool) { + t: int = const true; + f: int = const false; + + constant_fold1: bool = and f t; + constant_fold2: bool = and t f; + constant_fold3: bool = or t f; + constant_fold4: bool = or f t; + constant_fold5: bool = not t; + constant_fold6: bool = not f; + + should_fold1: bool = and f arg1; + should_fold2: bool = and arg1 f; + should_fold3: bool = or t arg1; + should_fold4: bool = or arg1 t; + + no_fold1: bool = and t arg1; + no_fold2: bool = and arg1 t; + no_fold3: bool = or f arg1; + no_fold4: bool = or arg1 f; + no_fold5: bool = and arg1 arg2; + no_fold6: bool = or arg1 arg2; + no_fold7: bool = not arg1; +} diff --git a/compiler/test/lvn-gold/logical-operators.out b/compiler/test/lvn-gold/logical-operators.out new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/test/lvn-gold/logical-operators.prof b/compiler/test/lvn-gold/logical-operators.prof new file mode 100644 index 000000000..1c1aa660e --- /dev/null +++ b/compiler/test/lvn-gold/logical-operators.prof @@ -0,0 +1 @@ +error: mismatched main argument arity: expected 2; got 0 diff --git a/compiler/test/lvn-gold/nonlocal.bril b/compiler/test/lvn-gold/nonlocal.bril new file mode 100644 index 000000000..1fb0a56dd --- /dev/null +++ b/compiler/test/lvn-gold/nonlocal.bril @@ -0,0 +1,10 @@ +@main { + a: int = const 4; + b: int = const 2; + sum1: int = add a b; + sum2: int = add a b; + jmp .label; +.label: + prod: int = mul sum1 sum2; + print prod; +} diff --git a/compiler/test/lvn-gold/nonlocal.out b/compiler/test/lvn-gold/nonlocal.out new file mode 100644 index 000000000..7facc8993 --- /dev/null +++ b/compiler/test/lvn-gold/nonlocal.out @@ -0,0 +1 @@ +36 diff --git a/compiler/test/lvn-gold/nonlocal.prof b/compiler/test/lvn-gold/nonlocal.prof new file mode 100644 index 000000000..d55fa2169 --- /dev/null +++ b/compiler/test/lvn-gold/nonlocal.prof @@ -0,0 +1 @@ +total_dyn_inst: 7 diff --git a/compiler/test/lvn-gold/reassign.bril b/compiler/test/lvn-gold/reassign.bril new file mode 100644 index 000000000..b3dabfe62 --- /dev/null +++ b/compiler/test/lvn-gold/reassign.bril @@ -0,0 +1,5 @@ +@main { + a: int = const 100; + a: int = const 42; + print a; +} diff --git a/compiler/test/lvn-gold/reassign.out b/compiler/test/lvn-gold/reassign.out new file mode 100644 index 000000000..d81cc0710 --- /dev/null +++ b/compiler/test/lvn-gold/reassign.out @@ -0,0 +1 @@ +42 diff --git a/compiler/test/lvn-gold/reassign.prof b/compiler/test/lvn-gold/reassign.prof new file mode 100644 index 000000000..ab6154dae --- /dev/null +++ b/compiler/test/lvn-gold/reassign.prof @@ -0,0 +1 @@ +total_dyn_inst: 3 diff --git a/compiler/test/lvn-gold/redundant-dce.bril b/compiler/test/lvn-gold/redundant-dce.bril new file mode 100644 index 000000000..a15aaddd0 --- /dev/null +++ b/compiler/test/lvn-gold/redundant-dce.bril @@ -0,0 +1,9 @@ + +@main { + a: int = const 4; + b: int = const 2; + sum1: int = add a b; + sum2: int = add a b; + prod: int = mul sum1 sum2; + print prod; +} diff --git a/compiler/test/lvn-gold/redundant-dce.out b/compiler/test/lvn-gold/redundant-dce.out new file mode 100644 index 000000000..7facc8993 --- /dev/null +++ b/compiler/test/lvn-gold/redundant-dce.out @@ -0,0 +1 @@ +36 diff --git a/compiler/test/lvn-gold/redundant-dce.prof b/compiler/test/lvn-gold/redundant-dce.prof new file mode 100644 index 000000000..d887198fd --- /dev/null +++ b/compiler/test/lvn-gold/redundant-dce.prof @@ -0,0 +1 @@ +total_dyn_inst: 6 diff --git a/compiler/test/lvn-gold/redundant.bril b/compiler/test/lvn-gold/redundant.bril new file mode 100644 index 000000000..56ea25261 --- /dev/null +++ b/compiler/test/lvn-gold/redundant.bril @@ -0,0 +1,9 @@ +# (a + b) * (a + b) +@main { + a: int = const 4; + b: int = const 2; + sum1: int = add a b; + sum2: int = add a b; + prod: int = mul sum1 sum2; + print prod; +} diff --git a/compiler/test/lvn-gold/redundant.out b/compiler/test/lvn-gold/redundant.out new file mode 100644 index 000000000..7facc8993 --- /dev/null +++ b/compiler/test/lvn-gold/redundant.out @@ -0,0 +1 @@ +36 diff --git a/compiler/test/lvn-gold/redundant.prof b/compiler/test/lvn-gold/redundant.prof new file mode 100644 index 000000000..d887198fd --- /dev/null +++ b/compiler/test/lvn-gold/redundant.prof @@ -0,0 +1 @@ +total_dyn_inst: 6 diff --git a/compiler/test/lvn-gold/rename-fold.bril b/compiler/test/lvn-gold/rename-fold.bril new file mode 100644 index 000000000..f01c52f42 --- /dev/null +++ b/compiler/test/lvn-gold/rename-fold.bril @@ -0,0 +1,9 @@ +@main { + v1: int = const 4; + v2: int = const 0; + mul1: int = mul v1 v2; + add1: int = add v1 v2; + v2: int = const 3; + print mul1; + print add1; +} diff --git a/compiler/test/lvn-gold/rename-fold.out b/compiler/test/lvn-gold/rename-fold.out new file mode 100644 index 000000000..4f1d7cd30 --- /dev/null +++ b/compiler/test/lvn-gold/rename-fold.out @@ -0,0 +1,2 @@ +0 +4 diff --git a/compiler/test/lvn-gold/rename-fold.prof b/compiler/test/lvn-gold/rename-fold.prof new file mode 100644 index 000000000..d55fa2169 --- /dev/null +++ b/compiler/test/lvn-gold/rename-fold.prof @@ -0,0 +1 @@ +total_dyn_inst: 7 diff --git a/compiler/test/lvn-gold/turnt.toml b/compiler/test/lvn-gold/turnt.toml new file mode 100644 index 000000000..9a183f2cc --- /dev/null +++ b/compiler/test/lvn-gold/turnt.toml @@ -0,0 +1 @@ +command = " bril2json < {filename} | python3 ../../lvn.py | python3 ../../dce.py | brili {args} " diff --git a/compiler/test/lvn/clobber-fold.bril b/compiler/test/lvn/clobber-fold.bril new file mode 100644 index 000000000..075d9d8b5 --- /dev/null +++ b/compiler/test/lvn/clobber-fold.bril @@ -0,0 +1,21 @@ +# CMD: bril2json < {filename} | python3 ../../lvn.py | python3 ../../dce.py | bril2txt + +@main { + a: int = const 4; + b: int = const 2; + + # (a + b) * (a + b) + sum1: int = add a b; + sum2: int = add a b; + prod1: int = mul sum1 sum2; + + # Clobber both sums. + sum1: int = const 0; + sum2: int = const 0; + + # Use the sums again. + sum3: int = add a b; + prod2: int = mul sum3 sum3; + + print prod2; +} diff --git a/compiler/test/lvn/clobber-fold.out b/compiler/test/lvn/clobber-fold.out new file mode 100644 index 000000000..0975e125e --- /dev/null +++ b/compiler/test/lvn/clobber-fold.out @@ -0,0 +1,4 @@ +@main { + prod1: int = const 36; + print prod1; +} diff --git a/compiler/test/lvn/clobber.bril b/compiler/test/lvn/clobber.bril new file mode 100644 index 000000000..075d9d8b5 --- /dev/null +++ b/compiler/test/lvn/clobber.bril @@ -0,0 +1,21 @@ +# CMD: bril2json < {filename} | python3 ../../lvn.py | python3 ../../dce.py | bril2txt + +@main { + a: int = const 4; + b: int = const 2; + + # (a + b) * (a + b) + sum1: int = add a b; + sum2: int = add a b; + prod1: int = mul sum1 sum2; + + # Clobber both sums. + sum1: int = const 0; + sum2: int = const 0; + + # Use the sums again. + sum3: int = add a b; + prod2: int = mul sum3 sum3; + + print prod2; +} diff --git a/compiler/test/lvn/clobber.out b/compiler/test/lvn/clobber.out new file mode 100644 index 000000000..0975e125e --- /dev/null +++ b/compiler/test/lvn/clobber.out @@ -0,0 +1,4 @@ +@main { + prod1: int = const 36; + print prod1; +} diff --git a/compiler/test/lvn/commute.bril b/compiler/test/lvn/commute.bril new file mode 100644 index 000000000..e80844ad0 --- /dev/null +++ b/compiler/test/lvn/commute.bril @@ -0,0 +1,10 @@ +# ARGS: -c +# (a + b) * (b + a) +@main { + a: int = const 4; + b: int = const 2; + sum1: int = add a b; + sum2: int = add b a; + prod: int = mul sum1 sum2; + print prod; +} diff --git a/compiler/test/lvn/commute.out b/compiler/test/lvn/commute.out new file mode 100644 index 000000000..9ac6eb244 --- /dev/null +++ b/compiler/test/lvn/commute.out @@ -0,0 +1,8 @@ +@main { + a: int = const 4; + b: int = const 2; + sum1: int = const 6; + sum2: int = const 6; + prod: int = const 36; + print prod; +} diff --git a/compiler/test/lvn/divide-by-zero.bril b/compiler/test/lvn/divide-by-zero.bril new file mode 100644 index 000000000..f99ecec78 --- /dev/null +++ b/compiler/test/lvn/divide-by-zero.bril @@ -0,0 +1,7 @@ +@main { +.entry: + zero : int = const 0; + one : int = const 1; + baddiv : int = div one zero; + print baddiv; +} diff --git a/compiler/test/lvn/divide-by-zero.out b/compiler/test/lvn/divide-by-zero.out new file mode 100644 index 000000000..cc83ef97c --- /dev/null +++ b/compiler/test/lvn/divide-by-zero.out @@ -0,0 +1,7 @@ +@main { +.entry: + zero: int = const 0; + one: int = const 1; + baddiv: int = div one zero; + print baddiv; +} diff --git a/compiler/test/lvn/fold-comparisons.bril b/compiler/test/lvn/fold-comparisons.bril new file mode 100644 index 000000000..e028876ed --- /dev/null +++ b/compiler/test/lvn/fold-comparisons.bril @@ -0,0 +1,25 @@ +# ARGS: -f + +@main(arg1: int, arg2: int) { + a: int = const 4; + b: int = const 3; + constant_fold1: bool = ne b a; + constant_fold2: bool = eq a b; + constant_fold3: bool = le a b; + constant_fold4: bool = lt b a; + constant_fold5: bool = gt b a; + constant_fold6: bool = ge b a; + + should_fold1: bool = eq arg1 arg1; + should_fold2: bool = ne arg1 arg1; + should_fold3: bool = le arg1 arg1; + should_fold4: bool = ge arg1 arg1; + + no_fold1: bool = eq arg1 arg2; + no_fold2: bool = ne arg1 arg2; + no_fold3: bool = le arg1 arg2; + no_fold4: bool = ge arg1 arg2; + + no_fold5: bool = lt arg1 arg1; + no_fold6: bool = gt arg2 arg2; +} diff --git a/compiler/test/lvn/fold-comparisons.out b/compiler/test/lvn/fold-comparisons.out new file mode 100644 index 000000000..fb5533919 --- /dev/null +++ b/compiler/test/lvn/fold-comparisons.out @@ -0,0 +1,20 @@ +@main(arg1: int, arg2: int) { + a: int = const 4; + b: int = const 3; + constant_fold1: bool = ne b a; + constant_fold2: bool = const false; + constant_fold3: bool = const false; + constant_fold4: bool = const true; + constant_fold5: bool = const false; + constant_fold6: bool = const false; + should_fold1: bool = eq arg1 arg1; + should_fold2: bool = ne arg1 arg1; + should_fold3: bool = le arg1 arg1; + should_fold4: bool = ge arg1 arg1; + no_fold1: bool = eq arg1 arg2; + no_fold2: bool = ne arg1 arg2; + no_fold3: bool = le arg1 arg2; + no_fold4: bool = ge arg1 arg2; + no_fold5: bool = lt arg1 arg1; + no_fold6: bool = gt arg2 arg2; +} diff --git a/compiler/test/lvn/idchain-nonlocal.bril b/compiler/test/lvn/idchain-nonlocal.bril new file mode 100644 index 000000000..01d2ecdcd --- /dev/null +++ b/compiler/test/lvn/idchain-nonlocal.bril @@ -0,0 +1,10 @@ +# ARGS: -p +@main { + x: int = const 4; + jmp .label; +.label: + copy1: int = id x; + copy2: int = id copy1; + copy3: int = id copy2; + print copy3; +} diff --git a/compiler/test/lvn/idchain-nonlocal.out b/compiler/test/lvn/idchain-nonlocal.out new file mode 100644 index 000000000..cf39a7a64 --- /dev/null +++ b/compiler/test/lvn/idchain-nonlocal.out @@ -0,0 +1,9 @@ +@main { + x: int = const 4; + jmp .label; +.label: + copy1: int = id x; + copy2: int = id x; + copy3: int = id x; + print x; +} diff --git a/compiler/test/lvn/idchain-prop.bril b/compiler/test/lvn/idchain-prop.bril new file mode 100644 index 000000000..534b94510 --- /dev/null +++ b/compiler/test/lvn/idchain-prop.bril @@ -0,0 +1,8 @@ +# ARGS: -p +@main { + x: int = const 4; + copy1: int = id x; + copy2: int = id copy1; + copy3: int = id copy2; + print copy3; +} diff --git a/compiler/test/lvn/idchain-prop.out b/compiler/test/lvn/idchain-prop.out new file mode 100644 index 000000000..b8ad16d03 --- /dev/null +++ b/compiler/test/lvn/idchain-prop.out @@ -0,0 +1,7 @@ +@main { + x: int = const 4; + copy1: int = const 4; + copy2: int = const 4; + copy3: int = const 4; + print x; +} diff --git a/compiler/test/lvn/idchain.bril b/compiler/test/lvn/idchain.bril new file mode 100644 index 000000000..83f377c38 --- /dev/null +++ b/compiler/test/lvn/idchain.bril @@ -0,0 +1,7 @@ +@main { + x: int = const 4; + copy1: int = id x; + copy2: int = id copy1; + copy3: int = id copy2; + print copy3; +} diff --git a/compiler/test/lvn/idchain.out b/compiler/test/lvn/idchain.out new file mode 100644 index 000000000..b8ad16d03 --- /dev/null +++ b/compiler/test/lvn/idchain.out @@ -0,0 +1,7 @@ +@main { + x: int = const 4; + copy1: int = const 4; + copy2: int = const 4; + copy3: int = const 4; + print x; +} diff --git a/compiler/test/lvn/logical-operators.bril b/compiler/test/lvn/logical-operators.bril new file mode 100644 index 000000000..fb243d8ef --- /dev/null +++ b/compiler/test/lvn/logical-operators.bril @@ -0,0 +1,27 @@ +# CMD: bril2json < {filename} | python3 ../../lvn.py | bril2txt +# ARGS: -f + +@main(arg1: bool, arg2: bool) { + t: bool = const true; + f: bool = const false; + + constant_fold1: bool = and f t; + constant_fold2: bool = and t f; + constant_fold3: bool = or t f; + constant_fold4: bool = or f t; + constant_fold5: bool = not t; + constant_fold6: bool = not f; + + should_fold1: bool = and f arg1; + should_fold2: bool = and arg1 f; + should_fold3: bool = or t arg1; + should_fold4: bool = or arg1 t; + + no_fold1: bool = and t arg1; + no_fold2: bool = and arg1 t; + no_fold3: bool = or f arg1; + no_fold4: bool = or arg1 f; + no_fold5: bool = and arg1 arg2; + no_fold6: bool = or arg1 arg2; + no_fold7: bool = not arg1; +} diff --git a/compiler/test/lvn/logical-operators.out b/compiler/test/lvn/logical-operators.out new file mode 100644 index 000000000..9f629592f --- /dev/null +++ b/compiler/test/lvn/logical-operators.out @@ -0,0 +1,21 @@ +@main(arg1: bool, arg2: bool) { + t: bool = const true; + f: bool = const false; + constant_fold1: bool = const false; + constant_fold2: bool = const false; + constant_fold3: bool = const true; + constant_fold4: bool = const true; + constant_fold5: bool = const false; + constant_fold6: bool = const true; + should_fold1: bool = const false; + should_fold2: bool = const false; + should_fold3: bool = const true; + should_fold4: bool = const true; + no_fold1: bool = id arg1; + no_fold2: bool = id arg1; + no_fold3: bool = id arg1; + no_fold4: bool = id arg1; + no_fold5: bool = and arg1 arg2; + no_fold6: bool = or arg1 arg2; + no_fold7: bool = not arg1; +} diff --git a/compiler/test/lvn/nonlocal.bril b/compiler/test/lvn/nonlocal.bril new file mode 100644 index 000000000..1fb0a56dd --- /dev/null +++ b/compiler/test/lvn/nonlocal.bril @@ -0,0 +1,10 @@ +@main { + a: int = const 4; + b: int = const 2; + sum1: int = add a b; + sum2: int = add a b; + jmp .label; +.label: + prod: int = mul sum1 sum2; + print prod; +} diff --git a/compiler/test/lvn/nonlocal.out b/compiler/test/lvn/nonlocal.out new file mode 100644 index 000000000..23ab396e2 --- /dev/null +++ b/compiler/test/lvn/nonlocal.out @@ -0,0 +1,10 @@ +@main { + a: int = const 4; + b: int = const 2; + sum1: int = const 6; + sum2: int = const 6; + jmp .label; +.label: + prod: int = mul sum1 sum2; + print prod; +} diff --git a/compiler/test/lvn/reassign.bril b/compiler/test/lvn/reassign.bril new file mode 100644 index 000000000..b3dabfe62 --- /dev/null +++ b/compiler/test/lvn/reassign.bril @@ -0,0 +1,5 @@ +@main { + a: int = const 100; + a: int = const 42; + print a; +} diff --git a/compiler/test/lvn/reassign.out b/compiler/test/lvn/reassign.out new file mode 100644 index 000000000..494994727 --- /dev/null +++ b/compiler/test/lvn/reassign.out @@ -0,0 +1,5 @@ +@main { + lvn.a.0: int = const 100; + a: int = const 42; + print a; +} diff --git a/compiler/test/lvn/redundant-dce.bril b/compiler/test/lvn/redundant-dce.bril new file mode 100644 index 000000000..0e3ee9091 --- /dev/null +++ b/compiler/test/lvn/redundant-dce.bril @@ -0,0 +1,8 @@ +@main { + a: int = const 4; + b: int = const 2; + sum1: int = add a b; + sum2: int = add a b; + prod: int = mul sum1 sum2; + print prod; +} diff --git a/compiler/test/lvn/redundant-dce.out b/compiler/test/lvn/redundant-dce.out new file mode 100644 index 000000000..9ac6eb244 --- /dev/null +++ b/compiler/test/lvn/redundant-dce.out @@ -0,0 +1,8 @@ +@main { + a: int = const 4; + b: int = const 2; + sum1: int = const 6; + sum2: int = const 6; + prod: int = const 36; + print prod; +} diff --git a/compiler/test/lvn/redundant.bril b/compiler/test/lvn/redundant.bril new file mode 100644 index 000000000..56ea25261 --- /dev/null +++ b/compiler/test/lvn/redundant.bril @@ -0,0 +1,9 @@ +# (a + b) * (a + b) +@main { + a: int = const 4; + b: int = const 2; + sum1: int = add a b; + sum2: int = add a b; + prod: int = mul sum1 sum2; + print prod; +} diff --git a/compiler/test/lvn/redundant.out b/compiler/test/lvn/redundant.out new file mode 100644 index 000000000..9ac6eb244 --- /dev/null +++ b/compiler/test/lvn/redundant.out @@ -0,0 +1,8 @@ +@main { + a: int = const 4; + b: int = const 2; + sum1: int = const 6; + sum2: int = const 6; + prod: int = const 36; + print prod; +} diff --git a/compiler/test/lvn/rename-fold.bril b/compiler/test/lvn/rename-fold.bril new file mode 100644 index 000000000..f01c52f42 --- /dev/null +++ b/compiler/test/lvn/rename-fold.bril @@ -0,0 +1,9 @@ +@main { + v1: int = const 4; + v2: int = const 0; + mul1: int = mul v1 v2; + add1: int = add v1 v2; + v2: int = const 3; + print mul1; + print add1; +} diff --git a/compiler/test/lvn/rename-fold.out b/compiler/test/lvn/rename-fold.out new file mode 100644 index 000000000..531d73536 --- /dev/null +++ b/compiler/test/lvn/rename-fold.out @@ -0,0 +1,9 @@ +@main { + v1: int = const 4; + lvn.v2.0: int = const 0; + mul1: int = const 0; + add1: int = const 4; + v2: int = const 3; + print lvn.v2.0; + print v1; +} diff --git a/compiler/test/lvn/turnt.toml b/compiler/test/lvn/turnt.toml new file mode 100644 index 000000000..98107873d --- /dev/null +++ b/compiler/test/lvn/turnt.toml @@ -0,0 +1 @@ +command = "bril2json < {filename} | python3 ../../lvn.py {args} | bril2txt" diff --git a/compiler/test/make_gold_tests.sh b/compiler/test/make_gold_tests.sh new file mode 100755 index 000000000..5cc56fd04 --- /dev/null +++ b/compiler/test/make_gold_tests.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +rm -r "$1-gold"; +mkdir "$1-gold"; + +QUOTE='"'; +echo "command = $QUOTE bril2json < {filename} | python3 ../../$1.py | brili {args} $QUOTE" >> "$1-gold"/turnt.toml; + +for prog in $1/*.bril; + do + outname=${prog%.*}; + outname=${outname#*/}; + cat $prog | grep -v 'CMD' | grep -v 'ARGS' > "$1-gold/$outname.bril"; + bril2json < $prog | brili > "$1-gold/$outname.out" 2> /dev/null; + bril2json < $prog | brili -p 2> "$1-gold/$outname.prof" > /dev/null; +done diff --git a/examples/test/lvn/turnt.toml b/examples/test/lvn/turnt.toml index 98107873d..71576bcc4 100644 --- a/examples/test/lvn/turnt.toml +++ b/examples/test/lvn/turnt.toml @@ -1 +1,2 @@ -command = "bril2json < {filename} | python3 ../../lvn.py {args} | bril2txt" +# command = "bril2json < {filename} | python3 ../../lvn.py {args} | bril2txt" +command = "bril2json < {filename} | python3 ../../../compiler/lvn.py {args} | bril2txt" diff --git a/examples/test/tdce/double-pass.out b/examples/test/tdce/double-pass.out index dd83901ed..ae7ac4d82 100644 --- a/examples/test/tdce/double-pass.out +++ b/examples/test/tdce/double-pass.out @@ -1,7 +1,6 @@ @main { a: int = const 4; b: int = const 2; - c: int = const 1; d: int = add a b; print d; } diff --git a/examples/test/tdce/reassign.out b/examples/test/tdce/reassign.out index b3dabfe62..728d98420 100644 --- a/examples/test/tdce/reassign.out +++ b/examples/test/tdce/reassign.out @@ -1,5 +1,4 @@ @main { - a: int = const 100; a: int = const 42; print a; } diff --git a/examples/test/tdce/turnt.toml b/examples/test/tdce/turnt.toml index fb55a0ef8..a06dfa1bd 100644 --- a/examples/test/tdce/turnt.toml +++ b/examples/test/tdce/turnt.toml @@ -1 +1,2 @@ -command = "bril2json < {filename} | python3 ../../tdce.py {args} | bril2txt" +#command = "bril2json < {filename} | python3 ../../tdce.py tdce+ {args} | bril2txt" +command = "bril2json < {filename} | python3 ../../../compiler/dce.py {args} | bril2txt"