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
def test_compress_jcond_single(): 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("start"), parser.LabelStmt("endif"), parser.OutboxOp() ] 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() ] ast = compress_jumps(start_ast) assert ast == expected_ast
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
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
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
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_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
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_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
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
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
def calculate_optimized_ast(fhandle, args): result_ast = p.parse_it(fhandle) checker.perform_label_checks(result_ast) checker.perform_variable_checks(result_ast) result_ast = conversion.convert_ifnz_to_ifez(result_ast) result_ast = conversion.convert_iftojump(result_ast) if not args.no_jump_compression: result_ast = conversion.compress_jumps(result_ast) if not args.no_unreachable: result_ast = conversion.remove_unreachable_code(result_ast) if not args.no_jmp_then_label: unchanged = False while not unchanged: new_ast = conversion.fix_jmp_then_label(result_ast) unchanged = new_ast == result_ast result_ast = new_ast return result_ast
def test_jcond_lone_label(): start_ast = [ parser.LabelStmt("start"), parser.AssignOp(src="inbox", dst="emp"), parser.JumpCondOp("if", "ez"), parser.JumpOp("start"), parser.JumpOp("_generated_endif"), parser.LabelStmt("if"), parser.JumpOp("start"), parser.LabelStmt("_generated_endif") ] expected_ast = [ parser.LabelStmt("start"), parser.AssignOp(src="inbox", dst="emp"), parser.JumpCondOp("start", "ez"), parser.JumpOp("start"), parser.JumpOp("_generated_endif"), parser.LabelStmt("if"), parser.JumpOp("start"), parser.LabelStmt("_generated_endif") ] ast = compress_jumps(start_ast) assert ast == expected_ast