Beispiel #1
0
def FunOptBasic(fun: ir.Fun, opt_stats: Dict[str, int],
                allow_conv_conversion: bool):
    opt_stats["merge_move"] += reaching_defs.FunMergeMoveWithSrcDef(fun)

    opt_stats["canonicalized"] += canonicalize.FunCanonicalize(fun)
    opt_stats["strength_red"] += lowering.FunStrengthReduction(fun)

    opt_stats["empty_bbls"] = cfg.FunRemoveEmptyBbls(fun)
    opt_stats["unreachable_bbls"] = cfg.FunRemoveUnreachableBbls(fun)
    reaching_defs.FunComputeReachingDefs(fun)
    reaching_defs.FunCheckReachingDefs(fun)
    opt_stats["reg_prop"] = reaching_defs.FunPropagateRegs(fun)
    opt_stats["const_prop"] += reaching_defs.FunPropagateConsts(fun)

    opt_stats["const_fold"] += reaching_defs.FunConstantFold(
        fun, allow_conv_conversion)

    opt_stats["canonicalized"] += canonicalize.FunCanonicalize(fun)
    opt_stats["strength_red"] += lowering.FunStrengthReduction(fun)

    opt_stats["ls_st_simplify"] += reaching_defs.FunLoadStoreSimplify(fun)

    opt_stats["move_elim"] += lowering.FunMoveElimination(fun)

    liveness.FunComputeLivenessInfo(fun)

    opt_stats["useless"] = liveness.FunRemoveUselessInstructions(fun)
    reg_stats.FunComputeRegStatsExceptLAC(fun)
    reg_stats.FunComputeRegStatsLAC(fun)

    opt_stats["dropped_regs"] += reg_stats.FunDropUnreferencedRegs(fun)
    opt_stats["separated_regs"] += reg_stats.FunSeparateLocalRegUsage(fun)
Beispiel #2
0
def FunCfgInit(fun: ir.Fun, unit: ir.Unit):
    cfg.FunSplitBbls(fun)
    cfg.FunInitCFG(fun)
    cfg.FunRemoveUnconditionalBranches(fun)
    cfg.FunRemoveEmptyBbls(fun)
    sanity.FunCheck(fun, unit, check_cfg=True,
                    check_push_pop=True,
                    check_fallthroughs=False)
Beispiel #3
0
    def testD(self):
        code = io.StringIO(r"""
.fun arm_syscall_write SIGNATURE [S32] = [S32 A32 U32]

.fun putchar NORMAL [] = [U32]

.fun writeln NORMAL [] = [A32 U32]
# live_out: ['r0', 'r1']
.reg S32 [$r0_S32 dummy]
.reg U32 [$r0_U32 $r1_U32 $r2_U32 len]
.reg A32 [$r0_A32 $r1_A32 buf]
.bbl start
    mov buf $r0_A32@r0                     # 0
    mov len $r1_U32@r1                     # 1
    mov $r2_U32@r2 len                     # 2
    mov $r1_A32@r1 buf                     # 3
    mov $r0_S32@r0 1                       # 4
    syscall arm_syscall_write 4:U32        # 5
    mov dummy $r0_S32@r0                   # 6
    mov $r0_U32@r0 10                      # 7
    bsr putchar                            # 8
    ret                                    # 9
""")
        cpu_regs = {"r0": ir.CpuReg("r0", 0), "r1": ir.CpuReg("r1", 1), "r2": ir.CpuReg("r2", 2)}
        unit = serialize.UnitParseFromAsm(code, cpu_regs=cpu_regs)

        fun = unit.fun_syms["arm_syscall_write"]
        fun.cpu_live_out = {cpu_regs["r0"]}
        fun.cpu_live_in = {cpu_regs["r0"], cpu_regs["r1"], cpu_regs["r2"]}

        fun = unit.fun_syms["putchar"]
        fun.cpu_live_in = {cpu_regs["r0"]}

        fun = unit.fun_syms["writeln"]
        cfg.FunSplitBbls(fun)
        cfg.FunInitCFG(fun)
        cfg.FunRemoveUnconditionalBranches(fun)
        cfg.FunRemoveEmptyBbls(fun)
        liveness.FunComputeLivenessInfo(fun)
        ranges = liveness.BblGetLiveRanges(fun.bbls[0], fun, fun.bbls[0].live_out, False)
        ranges.sort()
        print("TestD")
        for lr in ranges:
            print(lr)
        self.assertEqual(ranges, [
            liveness.LiveRange(liveness.BEFORE_BBL, 0, fun.reg_syms["$r0_A32"], 1),
            liveness.LiveRange(liveness.BEFORE_BBL, 1, fun.reg_syms["$r1_U32"], 1),
            liveness.LiveRange(0, 3, fun.reg_syms["buf"], 1),
            liveness.LiveRange(1, 2, fun.reg_syms["len"], 1),
            liveness.LiveRange(2, 5, fun.reg_syms["$r2_U32"], 0),
            liveness.LiveRange(3, 5, fun.reg_syms["$r1_A32"], 0),
            liveness.LiveRange(4, 5, fun.reg_syms["$r0_S32"], 0),
            liveness.LiveRange(5, 6, fun.reg_syms["$r0_S32"], 1),
            liveness.LiveRange(6, liveness.NO_USE, fun.reg_syms["dummy"], 0),
            liveness.LiveRange(7, 8, fun.reg_syms["$r0_U32"], 0),
        ])
Beispiel #4
0
    def testE(self):
        code = io.StringIO(r"""


.fun test NORMAL [F32 F32 F32 F32] = [F32 F32]
.reg F32 [a b add sub mul div  $s0_F32  $s1_F32  $s2_F32  $s3_F32]
.bbl start
    mov a $s0_F32@s0
    mov b $s1_F32@s1
    add add a b
    sub sub a b
    mul mul a b
    div div a b
    mov $s3_F32@s3 div
    mov $s2_F32@s2 mul
    mov $s1_F32@s1 sub
    mov $s0_F32@s0 add
    ret
""")
        cpu_regs = {
            "s0": ir.CpuReg("s0", 0),
            "s1": ir.CpuReg("s1", 1),
            "s2": ir.CpuReg("s2", 2),
            "s3": ir.CpuReg("s3", 2)
        }
        unit = serialize.UnitParseFromAsm(code, cpu_regs=cpu_regs)
        fun = unit.fun_syms["test"]
        fun.cpu_live_out = {
            cpu_regs["s0"], cpu_regs["s1"], cpu_regs["s2"], cpu_regs["s3"]
        }
        fun.cpu_live_in = {cpu_regs["s0"], cpu_regs["s1"]}
        cfg.FunSplitBblsAtTerminators(fun)
        cfg.FunInitCFG(fun)
        cfg.FunRemoveUnconditionalBranches(fun)
        cfg.FunRemoveEmptyBbls(fun)
        liveness.FunComputeLivenessInfo(fun)
        ranges = liveness.BblGetLiveRanges(fun.bbls[0], fun,
                                           fun.bbls[0].live_out)
        ranges.sort()
        print("TestE")
        for lr in ranges:
            print(lr)
Beispiel #5
0
    def testD(self):
        code = io.StringIO(r"""
.fun arm_syscall_write SIGNATURE [S32] = [S32 A32 U32]

.fun putchar NORMAL [] = [U32]

.fun writeln NORMAL [] = [A32 U32]
# live_out: ['r0', 'r1']
.reg S32 [$r0_S32 dummy]
.reg U32 [$r0_U32 $r1_U32 $r2_U32 len]
.reg A32 [$r0_A32 $r1_A32 buf]
.bbl start
    mov buf $r0_A32@r0                     # 0
    mov len $r1_U32@r1                     # 1
    mov $r2_U32@r2 len                     # 2
    mov $r1_A32@r1 buf                     # 3
    mov $r0_S32@r0 1                       # 4
    syscall arm_syscall_write 4:U32        # 5
    mov dummy $r0_S32@r0                   # 6
    mov $r0_U32@r0 10                      # 7
    bsr putchar                            # 8
    ret                                    # 9
""")
        cpu_regs = {
            "r0": ir.CpuReg("r0", 0),
            "r1": ir.CpuReg("r1", 1),
            "r2": ir.CpuReg("r2", 2)
        }
        unit = serialize.UnitParseFromAsm(code, cpu_regs=cpu_regs)

        fun = unit.fun_syms["arm_syscall_write"]
        fun.cpu_live_out = {cpu_regs["r0"]}
        fun.cpu_live_in = {cpu_regs["r0"], cpu_regs["r1"], cpu_regs["r2"]}

        fun = unit.fun_syms["putchar"]
        fun.cpu_live_in = {cpu_regs["r0"]}

        fun = unit.fun_syms["writeln"]
        cfg.FunSplitBblsAtTerminators(fun)
        cfg.FunInitCFG(fun)
        cfg.FunRemoveUnconditionalBranches(fun)
        cfg.FunRemoveEmptyBbls(fun)
        liveness.FunComputeLivenessInfo(fun)
        ranges = liveness.BblGetLiveRanges(fun.bbls[0], fun,
                                           fun.bbls[0].live_out)
        ranges.sort()
        print("TestD")
        for lr in ranges:
            print(lr)

        lr_r0 = liveness.LiveRange(liveness.BEFORE_BBL, 0,
                                   fun.reg_syms["$r0_A32"], 1)
        lr_r1 = liveness.LiveRange(liveness.BEFORE_BBL, 1,
                                   fun.reg_syms["$r1_U32"], 1)
        lr_buf = liveness.LiveRange(0, 3, fun.reg_syms["buf"], 1)
        lr_len = liveness.LiveRange(1, 2, fun.reg_syms["len"], 1)
        lr_r0_2 = liveness.LiveRange(5, 6, fun.reg_syms["$r0_S32"], 1)

        expected = [
            lr_r0,
            lr_r1,
            liveness.LiveRange(0,
                               0,
                               reg=ir.REG_INVALID,
                               num_uses=1,
                               uses=[lr_r0]),
            lr_buf,
            liveness.LiveRange(1,
                               1,
                               reg=ir.REG_INVALID,
                               num_uses=1,
                               uses=[lr_r1]),
            lr_len,
            liveness.LiveRange(2,
                               2,
                               reg=ir.REG_INVALID,
                               num_uses=1,
                               uses=[lr_len]),
            liveness.LiveRange(2, 5, fun.reg_syms["$r2_U32"], 0),
            liveness.LiveRange(3,
                               3,
                               reg=ir.REG_INVALID,
                               num_uses=1,
                               uses=[lr_buf]),
            liveness.LiveRange(3, 5, fun.reg_syms["$r1_A32"], 0),
            liveness.LiveRange(4, 5, fun.reg_syms["$r0_S32"], 0),
            lr_r0_2,
            liveness.LiveRange(6,
                               6,
                               reg=ir.REG_INVALID,
                               num_uses=1,
                               uses=[lr_r0_2]),
            liveness.LiveRange(6, liveness.NO_USE, fun.reg_syms["dummy"], 0),
            liveness.LiveRange(7, 8, fun.reg_syms["$r0_U32"], 0),
        ]
        # self.assertSequenceEqual(ranges, expected) # this does not work because of the uses field
        self.assertEqual(len(ranges), len(expected))
        for a, b in zip():
            self.assertEqual(a, b)