Exemple #1
0
def _RunLinearScan(bbl: ir.Bbl, fun: ir.Fun, live_ranges: List[liveness.LiveRange], allow_spilling,
                   gpr_regs_lac: int, gpr_regs_not_lac: int,
                   flt_regs_lac: int,
                   flt_regs_not_lac: int):
    pool = CpuRegPool(fun, bbl, allow_spilling,
                      gpr_regs_lac, gpr_regs_not_lac, flt_regs_lac, flt_regs_not_lac)
    for lr in live_ranges:
        # since we are operating on a BBL we cannot change LiveRanges
        # extending beyond the BBL.
        # reg_kinds_fixed (e.g. Machine) regs are assumed to be
        # pre-allocated and will not change

        if liveness.LiveRangeFlag.PRE_ALLOC in lr.flags:
            assert lr.cpu_reg is not ir.CPU_REG_INVALID and lr.cpu_reg is not ir.CPU_REG_SPILL

            pool.add_reserved_range(lr)
        else:
            lr.cpu_reg = ir.CPU_REG_INVALID

    # print (f"{pool}")
    # print(f"\nPY {bbl.name}")
    # for lr in live_ranges:
    #    print(f"{lr}")

    # print ("\n".join(serialize.BblRenderToAsm(bbl)))
    n = [0]

    def logger(lr, message):
        m = f"{n[0]} {lr} {message}"
        n[0] += 1
        print(m)

    reg_alloc.RegisterAssignerLinearScanFancy(live_ranges, pool, None)
Exemple #2
0
def GetData():
    global TRACES, POOL, LIVE_RANGES
    TRACES = []
    POOL = TestRegPool(A32_REGS)
    for lr in LIVE_RANGES:
        if LiveRangeFlag.PRE_ALLOC not in lr.flags:
            lr.cpu_reg = ir.CPU_REG_INVALID
        else:
            POOL.add_reserved_range(lr)
    try:
        reg_alloc.RegisterAssignerLinearScanFancy(LIVE_RANGES, POOL, debug=logger)
    except Exception as e:
        TRACES.append(f"EXCEPTION {e}")
    live_ranges = []
    for lr in LIVE_RANGES:
        flags = [f.name for f in LiveRangeFlag if f in lr.flags]
        if lr.uses:
            interval = f"{lr.def_pos}"
            payload = " ".join([f"({x.reg.name} {x.def_pos})" for x in lr.uses])
        else:
            interval = f"{lr.def_pos} - {lr.last_use_pos}"
            payload = f"{lr.reg.name}:{lr.reg.kind.name}"
            if lr.cpu_reg is not ir.CPU_REG_INVALID:
                payload += f" <b>{lr.cpu_reg.name}</b>"
        live_ranges.append((interval, "|".join(flags), payload))
    available = []
    for name, key in [("GPR", GPR_NOT_LAC), ("GPR_LAC", GPR_LAC),
                      ("FLT", FLT_NOT_LAC), ("FLT_LAC", FLT_LAC)]:
        regs = sorted(POOL.available[key])
        available.append((name, " ".join(r.name for r in regs)))
    return bytes(json.dumps([available, TRACES, live_ranges]), 'utf-8')
def GetData():
    global TRACES, POOL, LIVE_RANGES
    TRACES = []
    POOL = regs.CpuRegPool(
        None,
        None,
        True,
        regs.GPR_REGS_MASK & regs.GPR_LAC_REGS_MASK,  #
        regs.GPR_REGS_MASK & ~regs.GPR_LAC_REGS_MASK,  #
        regs.FLT_REGS_MASK & regs.FLT_LAC_REGS_MASK,  #
        regs.FLT_REGS_MASK & ~regs.FLT_LAC_REGS_MASK)
    for lr in LIVE_RANGES:
        if liveness.LiveRangeFlag.PRE_ALLOC in lr.flags:
            POOL.add_reserved_range(lr)
        else:
            lr.cpu_reg = ir.CPU_REG_INVALID

    reg_alloc.RegisterAssignerLinearScanFancy(LIVE_RANGES, POOL, debug=logger)

    live_ranges = []
    for lr in LIVE_RANGES:
        flags = [f.name for f in liveness.LiveRangeFlag if f in lr.flags]
        if lr.uses:
            flags.append("USES")
            interval = f"{lr.def_pos}"
            payload = " ".join(
                [f"({x.reg.name} {x.def_pos})" for x in lr.uses])
        else:
            interval = f"{lr.def_pos} - {lr.last_use_pos}"
            payload = f"{lr.reg.name}:{lr.reg.kind.name}"
            if lr.cpu_reg is not ir.CPU_REG_INVALID:
                payload += f" <b>{lr.cpu_reg.name}</b>"
        live_ranges.append((interval, "|".join(flags), payload))
    return bytes(json.dumps([TRACES, live_ranges]), 'utf-8')
Exemple #4
0
    def testBacktrack(self):
        # this is a good example for linear scan producing pretty bad assignments
        code = io.StringIO(r"""
.fun main NORMAL [U32 U32 U32 U32] = [U32 U32 U32 U32]

.bbl start
    poparg w:U32 
    poparg x:U32 
    poparg y:U32 
    poparg z:U32 
    
    mov a:U32 1
    mov b:U32 2
    mov c:U32 3
    mov d:U32 4
    
    cmpeq e:U32 a b c d
    
    pusharg z
    pusharg y
    pusharg x
    pusharg w
    ret
        """)

        unit = serialize.UnitParseFromAsm(code, False)
        fun = unit.fun_syms["main"]
        bbl = fun.bbls[0]

        _DumpBblWithLineNumbers(bbl)

        live_ranges = liveness.BblGetLiveRanges(bbl, fun, set(), True)
        live_ranges.sort()

        pool = TestRegPool(MakeGenericCpuRegs(4))
        reg_alloc.RegisterAssignerLinearScan(live_ranges, pool)
        for n, lr in enumerate(live_ranges):
            # print (lr)
            if not lr.uses:
                if n <= 3:
                    assert lr.cpu_reg.no == n
                else:
                    assert lr.cpu_reg is ir.CPU_REG_SPILL, f"unexpected reg {lr}"

        live_ranges = liveness.BblGetLiveRanges(bbl, fun, set(), True)
        live_ranges.sort()
        pool = TestRegPool(MakeGenericCpuRegs(8))
        reg_alloc.RegisterAssignerLinearScanFancy(live_ranges, pool, False)
        for n, lr in enumerate(live_ranges):
            # print (lr)
            assert lr.cpu_reg != ir.CPU_REG_SPILL, f"unexpected reg {lr}"