From f3b3e20559d9f3a2bfdb6a5679be30d66ed51074 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Tue, 5 Jan 2021 21:35:09 -0500 Subject: [PATCH 1/9] Nonlocal variables~ --- examples/lvn.py | 64 +++++++++++++++++++ .../test/lvn/nonlocal-variable-reuse-2.bril | 10 +++ .../test/lvn/nonlocal-variable-reuse-2.out | 7 ++ .../test/lvn/nonlocal-variable-reuse-3.bril | 13 ++++ .../test/lvn/nonlocal-variable-reuse-3.out | 11 ++++ .../test/lvn/nonlocal-variable-reuse.bril | 9 +++ examples/test/lvn/nonlocal-variable-reuse.out | 7 ++ 7 files changed, 121 insertions(+) create mode 100644 examples/test/lvn/nonlocal-variable-reuse-2.bril create mode 100644 examples/test/lvn/nonlocal-variable-reuse-2.out create mode 100644 examples/test/lvn/nonlocal-variable-reuse-3.bril create mode 100644 examples/test/lvn/nonlocal-variable-reuse-3.out create mode 100644 examples/test/lvn/nonlocal-variable-reuse.bril create mode 100644 examples/test/lvn/nonlocal-variable-reuse.out diff --git a/examples/lvn.py b/examples/lvn.py index cf7f834bc..0fdc34724 100644 --- a/examples/lvn.py +++ b/examples/lvn.py @@ -64,6 +64,56 @@ def read_first(instrs): return read +def rename_nonlocal_duplicates(block): + """Renames any variables that + (1) share a name with an argument in an `id` op where the argument + is not defined in the current block, and + (2) appear after the `id` op. + This avoids a wrong copy propagation. For example, + 1 @main { + 2 a: int = const 42; + 3 .lbl: + 4 b: int = id a; + 5 a: int = const 5; + 6 print b; + 7 } + + Here, we replace line 5 with: + _a: int = const 5; + to ensure that the copy propagation leads to the correct value of `a`. + """ + all_vars = set(instr['dest'] for instr in block if 'dest' in instr) + current_vars = set() + + def fresh_id(v): + while v in all_vars: + v = '_{}'.format(v) + return v + + def rename_until_next_assign(old_var, new_var, index, instrs): + for i in range(index, len(instrs)): + instr = instrs[i] + if 'args' in instr and old_var in instr['args']: + instr['args'] = [new_var if x == old_var else x for x in instr['args']] + if instr.get('dest') == old_var: + return + + id2line = {} + for index, instr in enumerate(block): + if instr.get('op') == 'id': + id_arg = instr['args'][0] + if id_arg not in current_vars and id_arg != instr['dest']: + id2line[id_arg] = index + if 'dest' not in instr: + continue + dest = instr['dest'] + current_vars.add(dest) + if dest in id2line and id2line[dest] < index: + old_var = instr['dest'] + instr['dest'] = fresh_id(dest) + rename_until_next_assign(old_var, instr['dest'], index, block) + + def lvn_block(block, lookup, canonicalize, fold): """Use local value numbering to optimize a basic block. Modify the instructions in place. @@ -96,6 +146,9 @@ def lvn_block(block, lookup, canonicalize, fold): # Track constant values for values assigned with `const`. num2const = {} + # Update names to variables that are used in `id`, yet defined outside the local scope. + rename_nonlocal_duplicates(block) + # Initialize the table with numbers for input variables. These # variables are their own canonical source. for var in read_first(block): @@ -199,6 +252,9 @@ def _lookup(value2num, value): 'le': lambda a, b: a <= b, 'ne': lambda a, b: a != b, 'eq': lambda a, b: a == b, + 'or': lambda a, b: a or b, + 'and': lambda a, b: a and b, + 'not': lambda a: not a } @@ -212,6 +268,14 @@ def _fold(num2const, value): # Equivalent arguments may be evaluated for equality. # E.g. `eq x x`, where `x` is not a constant evaluates to `true`. return value.op != 'ne' + + if value.op in {'and', 'or'} and any(v in num2const for v in value.args): + # Short circuiting the logical operators `and` and `or` for two cases: + # (1) `and x c0` -> false, where `c0` a constant that evaluates to `false`. + # (2) `or x c1` -> true, where `c1` a constant that evaluates to `true`. + const_val = num2const[value.args[0] if value.args[0] in num2const else value.args[1]] + if (value.op == 'and' and not const_val) or (value.op == 'or' and const_val): + return const_val return None except ZeroDivisionError: # If we hit a dynamic error, bail! return None diff --git a/examples/test/lvn/nonlocal-variable-reuse-2.bril b/examples/test/lvn/nonlocal-variable-reuse-2.bril new file mode 100644 index 000000000..9e6c41f20 --- /dev/null +++ b/examples/test/lvn/nonlocal-variable-reuse-2.bril @@ -0,0 +1,10 @@ +# CMD: bril2json < {filename} | python3 ../../lvn.py -p | bril2txt +@main { + a: int = const 42; +.lbl: + # While `a` is outside the local scope, we essentially + # have a no-op here, so nonlocal re-naming isn't necessary. + a: int = id a; + a: int = const 5; + print a; +} diff --git a/examples/test/lvn/nonlocal-variable-reuse-2.out b/examples/test/lvn/nonlocal-variable-reuse-2.out new file mode 100644 index 000000000..f73fc3f0f --- /dev/null +++ b/examples/test/lvn/nonlocal-variable-reuse-2.out @@ -0,0 +1,7 @@ +@main { + a: int = const 42; +.lbl: + a: int = id a; + a: int = const 5; + print a; +} diff --git a/examples/test/lvn/nonlocal-variable-reuse-3.bril b/examples/test/lvn/nonlocal-variable-reuse-3.bril new file mode 100644 index 000000000..da07a1302 --- /dev/null +++ b/examples/test/lvn/nonlocal-variable-reuse-3.bril @@ -0,0 +1,13 @@ +# CMD: bril2json < {filename} | python3 ../../lvn.py -p | bril2txt +@main { + # This should re-name within local scope only with `lvn`. + a: int = const 3; + b: int = id a; + a: int = id b; + print b; + print a; + a: int = const 4; + print a; + a: int = const 5; + print a; +} diff --git a/examples/test/lvn/nonlocal-variable-reuse-3.out b/examples/test/lvn/nonlocal-variable-reuse-3.out new file mode 100644 index 000000000..793ff37e1 --- /dev/null +++ b/examples/test/lvn/nonlocal-variable-reuse-3.out @@ -0,0 +1,11 @@ +@main { + lvn.0: int = const 3; + b: int = const 3; + a: int = const 3; + print lvn.0; + print lvn.0; + lvn.1: int = const 4; + print lvn.1; + a: int = const 5; + print a; +} diff --git a/examples/test/lvn/nonlocal-variable-reuse.bril b/examples/test/lvn/nonlocal-variable-reuse.bril new file mode 100644 index 000000000..e42e798ff --- /dev/null +++ b/examples/test/lvn/nonlocal-variable-reuse.bril @@ -0,0 +1,9 @@ +# CMD: bril2json < {filename} | python3 ../../lvn.py -p | bril2txt +@main { + a: int = const 42; +.lbl: + b: int = id a; + # This should be re-named since `a` is defined outside of the local scope. + a: int = const 5; + print b; +} diff --git a/examples/test/lvn/nonlocal-variable-reuse.out b/examples/test/lvn/nonlocal-variable-reuse.out new file mode 100644 index 000000000..f5a556077 --- /dev/null +++ b/examples/test/lvn/nonlocal-variable-reuse.out @@ -0,0 +1,7 @@ +@main { + a: int = const 42; +.lbl: + b: int = id a; + _a: int = const 5; + print a; +} From b894d30872f98f89ccb3171d8b3e3cb672e564fc Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Wed, 6 Jan 2021 08:17:07 -0500 Subject: [PATCH 2/9] Cleaner iters --- examples/lvn.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/lvn.py b/examples/lvn.py index 0fdc34724..5756e8b3d 100644 --- a/examples/lvn.py +++ b/examples/lvn.py @@ -90,15 +90,15 @@ def fresh_id(v): v = '_{}'.format(v) return v - def rename_until_next_assign(old_var, new_var, index, instrs): - for i in range(index, len(instrs)): - instr = instrs[i] + def rename_until_next_assign(old_var, new_var, instrs): + for instr in instrs: if 'args' in instr and old_var in instr['args']: - instr['args'] = [new_var if x == old_var else x for x in instr['args']] + instr['args'] = [new_var if a == old_var else a for a in instr['args']] if instr.get('dest') == old_var: return id2line = {} + block_len = len(block) for index, instr in enumerate(block): if instr.get('op') == 'id': id_arg = instr['args'][0] @@ -111,7 +111,7 @@ def rename_until_next_assign(old_var, new_var, index, instrs): if dest in id2line and id2line[dest] < index: old_var = instr['dest'] instr['dest'] = fresh_id(dest) - rename_until_next_assign(old_var, instr['dest'], index, block) + rename_until_next_assign(old_var, instr['dest'], block[index + 1:block_len]) def lvn_block(block, lookup, canonicalize, fold): From 30f4efbcdcf2b6fa4cd90889a5def4d4dec0b646 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Wed, 6 Jan 2021 08:43:51 -0500 Subject: [PATCH 3/9] Comments, cleanup --- examples/lvn.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/lvn.py b/examples/lvn.py index 5756e8b3d..75a6c9c5a 100644 --- a/examples/lvn.py +++ b/examples/lvn.py @@ -83,22 +83,28 @@ def rename_nonlocal_duplicates(block): to ensure that the copy propagation leads to the correct value of `a`. """ all_vars = set(instr['dest'] for instr in block if 'dest' in instr) - current_vars = set() def fresh_id(v): + """Appends `_` to `v` until it is uniquely named in the local scope.""" while v in all_vars: v = '_{}'.format(v) return v def rename_until_next_assign(old_var, new_var, instrs): + """Renames all instances of `old_var` to `new_var` until the next + assignment of `old_var`. + """ for instr in instrs: if 'args' in instr and old_var in instr['args']: instr['args'] = [new_var if a == old_var else a for a in instr['args']] if instr.get('dest') == old_var: return + # A running set to track which variables have been defined locally. + current_vars = set() + # Mapping from `id` op of a non-local variable to its line number. id2line = {} - block_len = len(block) + for index, instr in enumerate(block): if instr.get('op') == 'id': id_arg = instr['args'][0] @@ -111,7 +117,7 @@ def rename_until_next_assign(old_var, new_var, instrs): if dest in id2line and id2line[dest] < index: old_var = instr['dest'] instr['dest'] = fresh_id(dest) - rename_until_next_assign(old_var, instr['dest'], block[index + 1:block_len]) + rename_until_next_assign(old_var, instr['dest'], block[index + 1:len(block)]) def lvn_block(block, lookup, canonicalize, fold): From 8dc24a5511e416b5ed3c3069d92f9c12b283fe0e Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Wed, 6 Jan 2021 08:49:19 -0500 Subject: [PATCH 4/9] Comments. --- examples/lvn.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/lvn.py b/examples/lvn.py index 75a6c9c5a..4747c24f5 100644 --- a/examples/lvn.py +++ b/examples/lvn.py @@ -100,7 +100,7 @@ def rename_until_next_assign(old_var, new_var, instrs): if instr.get('dest') == old_var: return - # A running set to track which variables have been defined locally. + # A running set to track which variables have been assigned locally. current_vars = set() # Mapping from `id` op of a non-local variable to its line number. id2line = {} @@ -109,15 +109,19 @@ def rename_until_next_assign(old_var, new_var, instrs): if instr.get('op') == 'id': id_arg = instr['args'][0] if id_arg not in current_vars and id_arg != instr['dest']: + # Argument of this `id` op is not defined locally. id2line[id_arg] = index if 'dest' not in instr: continue dest = instr['dest'] current_vars.add(dest) if dest in id2line and id2line[dest] < index: + # Local assignment shares a name with + # previous `id` of a non-local variable. old_var = instr['dest'] instr['dest'] = fresh_id(dest) - rename_until_next_assign(old_var, instr['dest'], block[index + 1:len(block)]) + rename_until_next_assign(old_var, instr['dest'], + block[index + 1:len(block)]) def lvn_block(block, lookup, canonicalize, fold): From ac7f889753e23b1934c6e8ed102670c1eeeee418 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Wed, 6 Jan 2021 08:51:22 -0500 Subject: [PATCH 5/9] eob --- examples/lvn.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/lvn.py b/examples/lvn.py index 4747c24f5..e7b52bc41 100644 --- a/examples/lvn.py +++ b/examples/lvn.py @@ -120,8 +120,7 @@ def rename_until_next_assign(old_var, new_var, instrs): # previous `id` of a non-local variable. old_var = instr['dest'] instr['dest'] = fresh_id(dest) - rename_until_next_assign(old_var, instr['dest'], - block[index + 1:len(block)]) + rename_until_next_assign(old_var, instr['dest'], block[index + 1:]) def lvn_block(block, lookup, canonicalize, fold): From 38dad152b027febdb51e3f7e6e5107435c0310a6 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Wed, 13 Jan 2021 12:15:02 -0500 Subject: [PATCH 6/9] Df fix --- examples/df.py | 27 +++++++++++++++++-- examples/test/df/cond-args-defined.bril | 6 +++++ examples/test/df/cond-args-defined.out | 3 +++ .../{cond-args.bril => cond-args-live.bril} | 0 .../df/{cond-args.out => cond-args-live.out} | 0 5 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 examples/test/df/cond-args-defined.bril create mode 100644 examples/test/df/cond-args-defined.out rename examples/test/df/{cond-args.bril => cond-args-live.bril} (100%) rename examples/test/df/{cond-args.out => cond-args-live.out} (100%) diff --git a/examples/df.py b/examples/df.py index 08483bba0..35a858d6a 100644 --- a/examples/df.py +++ b/examples/df.py @@ -1,6 +1,6 @@ import sys import json -from collections import namedtuple +from collections import namedtuple, OrderedDict from form_blocks import form_blocks import cfg @@ -20,6 +20,28 @@ def union(sets): return out +def with_func_args(func, blocks): + """Inserts function arguments in a pre-cursor block, so that + they're not missed in the analysis. For example, + @main(x: int) { ... } + will insert the following pre-cursor block: + + .__main_arguments: + x: int = id x; + """ + if 'args' not in func: + return blocks + + blocks = list(blocks.items()) + # Id each argument of the function, to ensure it is not skipped in the worklist. + pre_cursor = [{'op': 'id', 'dest': a['name'], 'type': a['type'], 'args': [a['name']]} for a in func['args']] + # Jump to original entry block. + pre_cursor.append({'op': 'jmp', 'labels': [blocks[0][0]]}) + + blocks.insert(0, ('__{}_arguments'.format(func['name']), pre_cursor)) + return OrderedDict([(k, v) for k, v in blocks]) + + def df_worklist(blocks, analysis): """The worklist algorithm for iterating a data flow analysis to a fixed point. @@ -85,7 +107,8 @@ def run_df(bril, analysis): blocks = cfg.block_map(form_blocks(func['instrs'])) cfg.add_terminators(blocks) - in_, out = df_worklist(blocks, analysis) + # Insert a pre-cursor block for function arguments. + in_, out = df_worklist(with_func_args(func, blocks), analysis) for block in blocks: print('{}:'.format(block)) print(' in: ', fmt(in_[block])) diff --git a/examples/test/df/cond-args-defined.bril b/examples/test/df/cond-args-defined.bril new file mode 100644 index 000000000..439e75300 --- /dev/null +++ b/examples/test/df/cond-args-defined.bril @@ -0,0 +1,6 @@ +# ARGS: defined + +@main(awesome_integer: int) { +.entry: + print awesome_integer; +} diff --git a/examples/test/df/cond-args-defined.out b/examples/test/df/cond-args-defined.out new file mode 100644 index 000000000..588df27f2 --- /dev/null +++ b/examples/test/df/cond-args-defined.out @@ -0,0 +1,3 @@ +entry: + in: awesome_integer + out: awesome_integer diff --git a/examples/test/df/cond-args.bril b/examples/test/df/cond-args-live.bril similarity index 100% rename from examples/test/df/cond-args.bril rename to examples/test/df/cond-args-live.bril diff --git a/examples/test/df/cond-args.out b/examples/test/df/cond-args-live.out similarity index 100% rename from examples/test/df/cond-args.out rename to examples/test/df/cond-args-live.out From 21943733b7259e7c7e975fc42c7cc5168bbf8fab Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Wed, 13 Jan 2021 12:17:41 -0500 Subject: [PATCH 7/9] merge --- examples/lvn.py | 68 +------------------ .../test/lvn/nonlocal-variable-reuse-2.bril | 10 --- .../test/lvn/nonlocal-variable-reuse-2.out | 7 -- .../test/lvn/nonlocal-variable-reuse-3.bril | 13 ---- .../test/lvn/nonlocal-variable-reuse-3.out | 11 --- .../test/lvn/nonlocal-variable-reuse.bril | 9 --- examples/test/lvn/nonlocal-variable-reuse.out | 7 -- 7 files changed, 2 insertions(+), 123 deletions(-) delete mode 100644 examples/test/lvn/nonlocal-variable-reuse-2.bril delete mode 100644 examples/test/lvn/nonlocal-variable-reuse-2.out delete mode 100644 examples/test/lvn/nonlocal-variable-reuse-3.bril delete mode 100644 examples/test/lvn/nonlocal-variable-reuse-3.out delete mode 100644 examples/test/lvn/nonlocal-variable-reuse.bril delete mode 100644 examples/test/lvn/nonlocal-variable-reuse.out diff --git a/examples/lvn.py b/examples/lvn.py index e7b52bc41..cd6c16ace 100644 --- a/examples/lvn.py +++ b/examples/lvn.py @@ -64,72 +64,11 @@ def read_first(instrs): return read -def rename_nonlocal_duplicates(block): - """Renames any variables that - (1) share a name with an argument in an `id` op where the argument - is not defined in the current block, and - (2) appear after the `id` op. - This avoids a wrong copy propagation. For example, - 1 @main { - 2 a: int = const 42; - 3 .lbl: - 4 b: int = id a; - 5 a: int = const 5; - 6 print b; - 7 } - - Here, we replace line 5 with: - _a: int = const 5; - to ensure that the copy propagation leads to the correct value of `a`. - """ - all_vars = set(instr['dest'] for instr in block if 'dest' in instr) - - def fresh_id(v): - """Appends `_` to `v` until it is uniquely named in the local scope.""" - while v in all_vars: - v = '_{}'.format(v) - return v - - def rename_until_next_assign(old_var, new_var, instrs): - """Renames all instances of `old_var` to `new_var` until the next - assignment of `old_var`. - """ - for instr in instrs: - if 'args' in instr and old_var in instr['args']: - instr['args'] = [new_var if a == old_var else a for a in instr['args']] - if instr.get('dest') == old_var: - return - - # A running set to track which variables have been assigned locally. - current_vars = set() - # Mapping from `id` op of a non-local variable to its line number. - id2line = {} - - for index, instr in enumerate(block): - if instr.get('op') == 'id': - id_arg = instr['args'][0] - if id_arg not in current_vars and id_arg != instr['dest']: - # Argument of this `id` op is not defined locally. - id2line[id_arg] = index - if 'dest' not in instr: - continue - dest = instr['dest'] - current_vars.add(dest) - if dest in id2line and id2line[dest] < index: - # Local assignment shares a name with - # previous `id` of a non-local variable. - old_var = instr['dest'] - instr['dest'] = fresh_id(dest) - rename_until_next_assign(old_var, instr['dest'], block[index + 1:]) - - def lvn_block(block, lookup, canonicalize, fold): """Use local value numbering to optimize a basic block. Modify the instructions in place. - You can extend the basic LVN algorithm to bring interesting language semantics with these functions: - - `lookup`. Arguments: a value-to-number map and a value. Return the corresponding number (or None if it does not exist). - `canonicalize`. Argument: a value. Returns an equivalent value in @@ -155,9 +94,6 @@ def lvn_block(block, lookup, canonicalize, fold): # Track constant values for values assigned with `const`. num2const = {} - # Update names to variables that are used in `id`, yet defined outside the local scope. - rename_nonlocal_duplicates(block) - # Initialize the table with numbers for input variables. These # variables are their own canonical source. for var in read_first(block): @@ -220,7 +156,7 @@ def lvn_block(block, lookup, canonicalize, fold): num2var[newnum] = var instr['dest'] = var - if val: + if val is not None: # Is this value foldable to a constant? const = fold(num2const, val) if const is not None: @@ -320,4 +256,4 @@ def lvn(bril, prop=False, canon=False, fold=False): if __name__ == '__main__': bril = json.load(sys.stdin) lvn(bril, '-p' in sys.argv, '-c' in sys.argv, '-f' in sys.argv) - json.dump(bril, sys.stdout, indent=2, sort_keys=True) + json.dump(bril, sys.stdout, indent=2, sort_keys=True) \ No newline at end of file diff --git a/examples/test/lvn/nonlocal-variable-reuse-2.bril b/examples/test/lvn/nonlocal-variable-reuse-2.bril deleted file mode 100644 index 9e6c41f20..000000000 --- a/examples/test/lvn/nonlocal-variable-reuse-2.bril +++ /dev/null @@ -1,10 +0,0 @@ -# CMD: bril2json < {filename} | python3 ../../lvn.py -p | bril2txt -@main { - a: int = const 42; -.lbl: - # While `a` is outside the local scope, we essentially - # have a no-op here, so nonlocal re-naming isn't necessary. - a: int = id a; - a: int = const 5; - print a; -} diff --git a/examples/test/lvn/nonlocal-variable-reuse-2.out b/examples/test/lvn/nonlocal-variable-reuse-2.out deleted file mode 100644 index f73fc3f0f..000000000 --- a/examples/test/lvn/nonlocal-variable-reuse-2.out +++ /dev/null @@ -1,7 +0,0 @@ -@main { - a: int = const 42; -.lbl: - a: int = id a; - a: int = const 5; - print a; -} diff --git a/examples/test/lvn/nonlocal-variable-reuse-3.bril b/examples/test/lvn/nonlocal-variable-reuse-3.bril deleted file mode 100644 index da07a1302..000000000 --- a/examples/test/lvn/nonlocal-variable-reuse-3.bril +++ /dev/null @@ -1,13 +0,0 @@ -# CMD: bril2json < {filename} | python3 ../../lvn.py -p | bril2txt -@main { - # This should re-name within local scope only with `lvn`. - a: int = const 3; - b: int = id a; - a: int = id b; - print b; - print a; - a: int = const 4; - print a; - a: int = const 5; - print a; -} diff --git a/examples/test/lvn/nonlocal-variable-reuse-3.out b/examples/test/lvn/nonlocal-variable-reuse-3.out deleted file mode 100644 index 793ff37e1..000000000 --- a/examples/test/lvn/nonlocal-variable-reuse-3.out +++ /dev/null @@ -1,11 +0,0 @@ -@main { - lvn.0: int = const 3; - b: int = const 3; - a: int = const 3; - print lvn.0; - print lvn.0; - lvn.1: int = const 4; - print lvn.1; - a: int = const 5; - print a; -} diff --git a/examples/test/lvn/nonlocal-variable-reuse.bril b/examples/test/lvn/nonlocal-variable-reuse.bril deleted file mode 100644 index e42e798ff..000000000 --- a/examples/test/lvn/nonlocal-variable-reuse.bril +++ /dev/null @@ -1,9 +0,0 @@ -# CMD: bril2json < {filename} | python3 ../../lvn.py -p | bril2txt -@main { - a: int = const 42; -.lbl: - b: int = id a; - # This should be re-named since `a` is defined outside of the local scope. - a: int = const 5; - print b; -} diff --git a/examples/test/lvn/nonlocal-variable-reuse.out b/examples/test/lvn/nonlocal-variable-reuse.out deleted file mode 100644 index f5a556077..000000000 --- a/examples/test/lvn/nonlocal-variable-reuse.out +++ /dev/null @@ -1,7 +0,0 @@ -@main { - a: int = const 42; -.lbl: - b: int = id a; - _a: int = const 5; - print a; -} From 483c11c2234b6cfad6e34313654a704893d06f11 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Wed, 13 Jan 2021 12:19:00 -0500 Subject: [PATCH 8/9] S --- examples/lvn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/lvn.py b/examples/lvn.py index cd6c16ace..4b57a553c 100644 --- a/examples/lvn.py +++ b/examples/lvn.py @@ -256,4 +256,4 @@ def lvn(bril, prop=False, canon=False, fold=False): if __name__ == '__main__': bril = json.load(sys.stdin) lvn(bril, '-p' in sys.argv, '-c' in sys.argv, '-f' in sys.argv) - json.dump(bril, sys.stdout, indent=2, sort_keys=True) \ No newline at end of file + json.dump(bril, sys.stdout, indent=2, sort_keys=True) From fae7df823c61002b8a9bf0873cea2a1c6a052288 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Wed, 13 Jan 2021 12:20:54 -0500 Subject: [PATCH 9/9] fact-defined --- examples/test/df/fact-defined.bril | 24 +++++++++++++++++++ examples/test/df/fact-defined.out | 12 ++++++++++ .../test/df/{fact.bril => fact-live.bril} | 0 examples/test/df/{fact.out => fact-live.out} | 0 4 files changed, 36 insertions(+) create mode 100644 examples/test/df/fact-defined.bril create mode 100644 examples/test/df/fact-defined.out rename examples/test/df/{fact.bril => fact-live.bril} (100%) rename examples/test/df/{fact.out => fact-live.out} (100%) diff --git a/examples/test/df/fact-defined.bril b/examples/test/df/fact-defined.bril new file mode 100644 index 000000000..b86be5137 --- /dev/null +++ b/examples/test/df/fact-defined.bril @@ -0,0 +1,24 @@ +# ARGS: defined + +@main { + result: int = const 1; + i: int = const 8; + +.header: + # Enter body if i >= 0. + zero: int = const 0; + cond: bool = gt i zero; + br cond .body .end; + +.body: + result: int = mul result i; + + # i-- + one: int = const 1; + i: int = sub i one; + + jmp .header; + +.end: + print result; +} diff --git a/examples/test/df/fact-defined.out b/examples/test/df/fact-defined.out new file mode 100644 index 000000000..2c8f1514c --- /dev/null +++ b/examples/test/df/fact-defined.out @@ -0,0 +1,12 @@ +b1: + in: ∅ + out: i, result +header: + in: cond, i, one, result, zero + out: cond, i, one, result, zero +body: + in: cond, i, one, result, zero + out: cond, i, one, result, zero +end: + in: cond, i, one, result, zero + out: cond, i, one, result, zero diff --git a/examples/test/df/fact.bril b/examples/test/df/fact-live.bril similarity index 100% rename from examples/test/df/fact.bril rename to examples/test/df/fact-live.bril diff --git a/examples/test/df/fact.out b/examples/test/df/fact-live.out similarity index 100% rename from examples/test/df/fact.out rename to examples/test/df/fact-live.out