Example #1
0
    def convert_if(self, ifObj):
        def create_adhoc_assembler():
            new_assembler = Assembler()
            new_assembler.aliases = self.aliases
            new_assembler._gen_label_cnt = self._gen_label_cnt
            return new_assembler

        label_cnt = self._gen_label_cnt
        self._gen_label_cnt += 1

        true_branch_assembler = create_adhoc_assembler()
        true_branch_assembler.convert(ifObj.true_branch)
        self._gen_label_cnt = true_branch_assembler._gen_label_cnt

        false_branch_assembler = create_adhoc_assembler()
        false_branch_assembler.convert(ifObj.false_branch)
        self._gen_label_cnt = false_branch_assembler._gen_label_cnt

        self.convert_condjump(
            p.JumpCondOp("_hrm_" + str(label_cnt), "j" + ifObj.condition))
        for false_branch_codeline in false_branch_assembler.code:
            self.code.append(false_branch_codeline)
        self.convert_jump(p.JumpOp("_hrm_endif_" + str(label_cnt)))
        self.convert_label(p.LabelStmt("_hrm_" + str(label_cnt)))
        for true_branch_codeline in true_branch_assembler.code:
            self.code.append(true_branch_codeline)
        self.convert_label(p.LabelStmt("_hrm_endif_" + str(label_cnt)))
Example #2
0
def test_compress_jcond_multi():
    start_ast = [
        parser.LabelStmt("start"),
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpCondOp("if", "ez"),
            parser.OutboxOp(),
            parser.JumpOp("endif"),
        parser.LabelStmt("if"),
            parser.JumpOp("interm_first"),
        parser.LabelStmt("endif"),
        parser.OutboxOp(),
        parser.LabelStmt("interm_first"),
        parser.JumpOp("interm_last"),
        parser.LabelStmt("interm_last"),
        parser.JumpOp("start")
    ]
    expected_ast = [
        parser.LabelStmt("start"),
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpCondOp("start", "ez"),
            parser.OutboxOp(),
            parser.JumpOp("endif"),
        parser.LabelStmt("if"),
            parser.JumpOp("start"),
        parser.LabelStmt("endif"),
        parser.OutboxOp(),
        parser.LabelStmt("interm_first"),
        parser.JumpOp("start"),
        parser.LabelStmt("interm_last"),
        parser.JumpOp("start")
    ]
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
def test_convert_jmpthenlabel_check():
    code = [
        p.LabelStmt("alreadySorted"),
        p.AssignOp(src="inbox", dst="emp"),
        p.IfOp("neg", [p.JumpOp("alreadySorted")], []),
        p.IfOp("ez", [p.JumpOp("alreadySorted")],
               [p.AssignOp(src="0", dst="emp")])
    ]
    expected_ast = [
        p.LabelStmt("alreadySorted"),
        p.AssignOp(src="inbox", dst="emp"),
        p.JumpCondOp(condition="jneg", label_name="alreadySorted"),
        # pass
        #    p.JumpOp("_hrm_endif_1"),
        # p.LabelStmt("_hrm_endif_1"),
        p.JumpCondOp(condition="jez", label_name="alreadySorted"),
        p.AssignOp(src="0", dst="emp")
        #    p.JumpOp("_hrm_unreachable"),
        # p.LabelStmt("_hrm_unreachable")
    ]
    result_ast = conversion.convert_ifnz_to_ifez(code)
    result_ast = conversion.convert_iftojump(result_ast)
    result_ast = conversion.compress_jumps(result_ast)
    result_ast = conversion.remove_unreachable_code(result_ast)

    ast = conversion.fix_jmp_then_label(result_ast)

    assert ast == expected_ast
Example #4
0
def test_unreachable_jumps():
    start_ast = [
        parser.LabelStmt("start"),
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpOp("label_a"),
        parser.LabelStmt("label_a"),
        parser.JumpOp("label_b"),
        parser.LabelStmt("label_b"),
        parser.JumpOp("label_c"),
        parser.LabelStmt("label_c"),
        parser.JumpOp("label_z"),
        parser.JumpOp("start"),
        parser.LabelStmt("label_z")
    ]
    expected_ast = [
        parser.AssignOp(src="inbox", dst="emp"),
        # the indented part is needed in this test.
        # when run from `hrmc`, it'd be optimized
        # because of the previous 'jump compression' optimization,
        # but we are not using an optimized ast here.
        parser.JumpOp("label_a"),
        parser.LabelStmt("label_a"),
        parser.JumpOp("label_b"),
        parser.LabelStmt("label_b"),
        parser.JumpOp("label_c"),
        parser.LabelStmt("label_c"),
        parser.JumpOp("_hrm_unreachable"),
        parser.LabelStmt("_hrm_unreachable")
    ]
    ast = remove_unreachable_code(start_ast)
    assert ast == expected_ast
Example #5
0
def test_still_reachable():
    start_ast = [
        parser.JumpOp("skip"),
        parser.LabelStmt("ahah"),
        parser.OutboxOp(),
        parser.LabelStmt("skip"),
        parser.JumpOp("ahah")
    ]

    ast = remove_unreachable_code(start_ast)
    assert ast == start_ast
Example #6
0
def test_dont_keep_only_last_label_on_instruction():
    start_ast = [
        parser.AssignOp(src='inbox', dst='emp'),
        parser.JumpCondOp(label_name='_hrm_1', condition='jez'),
        parser.OutboxOp(),
        parser.JumpOp(label_name="_hrm_endif_1"),
        parser.LabelStmt("_hrm_1"),
        parser.LabelStmt("_hrm_endif_1"),
        parser.AssignOp(src="inbox", dst="emp")
    ]
    ast = remove_unreachable_code(start_ast)
    assert parser.LabelStmt("_hrm_endif_1") in ast
    assert parser.LabelStmt("_hrm_1") in ast
Example #7
0
def test_no_operation_ignored_in_nonlooping_code():
    start_ast = [
        parser.JumpCondOp("_hrm_1", "jez"),
        parser.IncrOp("a_field"),
        parser.JumpOp("the_fence"),
        parser.LabelStmt("_hrm_1"),
        parser.IncrOp("b_field"),
        parser.LabelStmt("the_fence"),
        parser.IncrOp("c_field")
    ]
    ast = remove_unreachable_code(start_ast)
    assert parser.IncrOp("b_field") in start_ast
    assert parser.IncrOp("b_field") in ast
Example #8
0
def test_compress_jcond_no_compress():
    start_ast = [
        parser.JumpCondOp("label", "ez"),
          parser.OutboxOp(),
          parser.JumpOp("endif"),
        parser.LabelStmt("label"),
          parser.OutboxOp(),
        parser.LabelStmt("endif"),
        parser.OutboxOp()
    ]
    expected_ast = start_ast
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
def test_convert_jmpthenlabel_used_elsewhere():
    start_ast = [
        p.JumpOp(label_name="start"),
        p.LabelStmt("start"),
        p.AssignOp(src="inbox", dst="emp"),
        p.JumpOp("start")
    ]
    expected_ast = [
        p.LabelStmt("start"),
        p.AssignOp(src="inbox", dst="emp"),
        p.JumpOp("start")
    ]
    ast = conversion.fix_jmp_then_label(start_ast)
    assert ast == expected_ast
Example #10
0
def test_dont_optimize_jumps_with_missing_label_in_chain():
    start_ast = [
            parser.LabelStmt("start"),
            parser.AssignOp(src="inbox", dst="emp"),
            parser.JumpOp(label_name="a"),
            parser.OutboxOp(),
            parser.JumpOp(label_name="start"),
            parser.LabelStmt("a"),
            parser.JumpOp(label_name="b"),
            parser.LabelStmt("b"),
            parser.JumpOp(label_name="misspelled_start"),
            parser.LabelStmt("misspelled_start"),
    ]
    expected_ast = [
            parser.LabelStmt("start"),
            parser.AssignOp(src="inbox", dst="emp"),
            parser.JumpOp(label_name="misspelled_start"),
            parser.OutboxOp(),
            parser.JumpOp(label_name="start"),
            parser.LabelStmt("a"),
            parser.JumpOp(label_name="misspelled_start"),
            parser.LabelStmt("b"),
            parser.JumpOp(label_name="misspelled_start"),
            parser.LabelStmt("misspelled_start"),
    ]
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
Example #11
0
def test_convert_iftojump_onlyfalsebranch():
    code = [
        p.IfOp("ez", [], [
            p.OutboxOp()
        ])]
    expected_ast = [
        p.JumpCondOp(condition="jez", label_name="_hrm_1"),
        p.OutboxOp(),
        p.JumpOp("_hrm_endif_1"),
        p.LabelStmt("_hrm_1"),
        p.LabelStmt("_hrm_endif_1")
    ]
    ast = c.convert_iftojump(code)
    assert ast == expected_ast
Example #12
0
def test_dont_remove_series_of_jumps():
    start_ast = [
        parser.JumpOp("jump1"),
        parser.LabelStmt("jump1"),
        parser.JumpOp("jump2"),
        parser.LabelStmt("jump2"),
        parser.JumpOp("jump3"),
        parser.LabelStmt("jump3"),
        parser.JumpOp("jump4"),
        parser.LabelStmt("jump4"),
        parser.AssignOp("inbox", "emp")
    ]

    ast = remove_unreachable_code(start_ast)
    assert ast == start_ast
Example #13
0
def test_labelinast_valid_access():
    start_ast = [
        parser.LabelStmt("test"),
        parser.JumpOp("test")
    ]
    labels_positions, _ = labels_in_ast(start_ast)
    assert "test" in labels_positions
Example #14
0
def test_labelinast_invalid_access():
    start_ast = [
        parser.OutboxOp(),
        parser.LabelStmt("test")
    ]
    labels_positions, _ = labels_in_ast(start_ast)
    assert "test" not in labels_positions
Example #15
0
def test_unreachable_condjumps():
    start_ast = [
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpCondOp("_hrm_1", "jez"),
        parser.OutboxOp(),
        parser.LabelStmt("_hrm_1"),
        parser.LabelStmt("_hrm_endif_1")
    ]
    expected_ast = [
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpCondOp("_hrm_unreachable", "jez"),
        parser.OutboxOp(),
        parser.LabelStmt("_hrm_unreachable")
    ]
    ast = remove_unreachable_code(start_ast)
    assert ast == expected_ast
Example #16
0
def test_no_compress():
    expected_ast = start_ast = [
        parser.JumpOp("test"),
        parser.LabelStmt("test"),
        parser.OutboxOp()
    ]
    ast = compress_jumps(start_ast)
    assert expected_ast == ast
Example #17
0
def test_avoid_loop():
    start_ast = [
        parser.LabelStmt("test"),
        parser.JumpOp("test")
    ]
    expected_ast = start_ast
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
Example #18
0
def test_compress_single_jump():
    start_ast = [
        parser.JumpOp("test"),
        parser.LabelStmt("test"),
        parser.JumpOp("wow"),
        parser.LabelStmt("wow"),
        parser.OutboxOp()
    ]
    expected_ast = [
        parser.JumpOp("wow"),
        parser.LabelStmt("test"),
        parser.JumpOp("wow"),
        parser.LabelStmt("wow"),
        parser.OutboxOp()
    ]
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
Example #19
0
def test_skip_operation():
    start_ast = [
        parser.AssignOp("inbox", "emp"),
        parser.JumpOp("label"),
        parser.OutboxOp(),
        parser.LabelStmt("label"),
        parser.AddOp("tmp")
    ]
    expected_ast = [
        parser.AssignOp("inbox", "emp"),
        parser.JumpOp("label"),
        parser.LabelStmt("label"),
        parser.AddOp("tmp")
    ]

    ast = remove_unreachable_code(start_ast)
    assert ast == expected_ast
def test_convert_jmpthenlabel_conditionaljumps_multiple():
    start_ast = [
        p.JumpCondOp(condition="jneg", label_name="other"),
        p.JumpCondOp(condition="jez", label_name="output"),
        p.LabelStmt("output"),
        p.OutboxOp(),
        p.LabelStmt("other"),
        p.AssignOp(src="inbox", dst="emp")
    ]
    expected_ast = [
        p.JumpCondOp(condition="jneg", label_name="other"),
        p.OutboxOp(),
        p.LabelStmt("other"),
        p.AssignOp(src="inbox", dst="emp")
    ]
    ast = conversion.fix_jmp_then_label(start_ast)

    assert ast == expected_ast
Example #21
0
def test_labelinast_nojump():
    start_ast = [
        parser.OutboxOp(),
        parser.LabelStmt("test"),
        parser.OutboxOp()
    ]
    labels_positions, _ = labels_in_ast(start_ast)
    assert "test" in labels_positions
    assert labels_positions["test"] == 2
Example #22
0
def test_dont_optimize_jumps_2():
    start_ast = [
            parser.JumpOp(label_name="start"),
            parser.LabelStmt("start"),
            parser.AssignOp(src="inbox", dst="emp"),
            parser.JumpOp("start")
    ]
    ast = compress_jumps(start_ast)
    assert ast == start_ast
def test_convert_jmpthenlabel_conditionaljumps_leading_to_same_instr():
    start_ast = [
        p.JumpCondOp(condition="ez", label_name="output"),
        p.LabelStmt("output"),
        p.OutboxOp()
    ]
    expected_ast = [p.OutboxOp()]
    ast = conversion.fix_jmp_then_label(start_ast)
    assert ast == expected_ast
Example #24
0
def test_dont_optimize_jumps_2():
    start_ast = [
        parser.JumpOp(label_name="start"),
        parser.LabelStmt("start"),
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpOp("start")
    ]
    ast = remove_unreachable_code(start_ast)
    assert ast == start_ast
Example #25
0
def test_endless_program_1():
    start_ast = [
        parser.LabelStmt("label"),
        parser.AssignOp("inbox", "emp"),
        parser.JumpOp("label")
    ]
    ast = remove_unreachable_code(start_ast)

    assert start_ast == ast
Example #26
0
def test_convert_iftojump_onlytruebranch_consecutive():
    code = [
        p.IfOp("ez", [p.OutboxOp()], []),
        p.IfOp("ez", [p.OutboxOp()], [])]
    expected_ast = [
        # first IF
        p.JumpCondOp(condition="jez", label_name="_hrm_1"),
        p.JumpOp("_hrm_endif_1"),
        p.LabelStmt("_hrm_1"),
        p.OutboxOp(),
        p.LabelStmt("_hrm_endif_1"),
        # second IF
        p.JumpCondOp(condition="jez", label_name="_hrm_2"),
        p.JumpOp("_hrm_endif_2"),
        p.LabelStmt("_hrm_2"),
        p.OutboxOp(),
        p.LabelStmt("_hrm_endif_2")]
    ast = c.convert_iftojump(code)
    assert ast == expected_ast
Example #27
0
def test_jcond_avoid_loop():
    start_ast = [
        parser.LabelStmt("test"),
        parser.JumpCondOp("test", "ez"),
        parser.OutboxOp(),
        parser.JumpOp("test"),
    ]
    expected_ast = start_ast
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
Example #28
0
def test_dont_optimize_conditional_jumps():
    """
    if ez then
        # nothing, but the `jez` must not be removed!
        # if removed, the program becomes only `outbox`,
        # that is incorrect.
    else
        outbox
    endif
    """
    start_ast = [
            parser.JumpCondOp(label_name='_hrm_1', condition='jez'),
            parser.OutboxOp(),
            parser.JumpOp(label_name="_hrm_endif_1"),
            parser.LabelStmt(label_name="_hrm_1"),
            parser.LabelStmt(label_name="_hrm_endif_1")
    ]
    ast = compress_jumps(start_ast)
    assert parser.JumpCondOp(label_name="_hrm_1", condition="jez") in ast
Example #29
0
def test_compress_multi_jump():
    start_ast = [
        parser.JumpOp("first"),
        parser.LabelStmt("first"), parser.JumpOp("second"),
        parser.LabelStmt("second"), parser.JumpOp("third"),
        parser.LabelStmt("third"), parser.JumpOp("fourth"),
        parser.LabelStmt("fourth"), parser.JumpOp("last"),
        parser.LabelStmt("last"), parser.OutboxOp()
    ]
    expected_ast = [
        parser.JumpOp("last"),
        parser.LabelStmt("first"), parser.JumpOp("last"),
        parser.LabelStmt("second"), parser.JumpOp("last"),
        parser.LabelStmt("third"), parser.JumpOp("last"),
        parser.LabelStmt("fourth"), parser.JumpOp("last"),
        parser.LabelStmt("last"), parser.OutboxOp()
    ]
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
Example #30
0
def test_jcond_no_jump_in_false():
    start_ast = [
        parser.AssignOp("inbox", "emp"),
        parser.JumpCondOp(condition="ez", label_name="truebranch"),
        parser.OutboxOp(),
        parser.LabelStmt("truebranch"),
        parser.AddOp("tmp")
    ]

    ast = remove_unreachable_code(start_ast)
    assert ast == start_ast