Пример #1
0
def after_branch_decrefs(label: Label, pre_live: AnalysisDict,
                         source_borrowed: Set[Register],
                         source_live_regs: Set[Register],
                         env: Environment) -> List[Op]:
    target_pre_live = pre_live[label, 0]
    decref = source_live_regs - target_pre_live - source_borrowed
    if decref:
        return [DecRef(reg, env.types[reg]) for reg in sorted(decref)]
    return []
Пример #2
0
def add_block(decincs: DecIncs, cache: BlockCache, blocks: List[BasicBlock],
              label: BasicBlock) -> BasicBlock:
    decs, incs = decincs
    if not decs and not incs:
        return label

    # TODO: be able to share *partial* results
    if (label, decincs) in cache:
        return cache[label, decincs]

    block = BasicBlock()
    blocks.append(block)
    block.ops.extend(DecRef(reg, is_xdec=xdec) for reg, xdec in decs)
    block.ops.extend(IncRef(reg) for reg in incs)
    block.ops.append(Goto(label))
    cache[label, decincs] = block
    return block
Пример #3
0
def transform_block(block: BasicBlock, pre_live: AnalysisDict[Register],
                    post_live: AnalysisDict[Register],
                    pre_borrow: AnalysisDict[Register],
                    env: Environment) -> None:
    old_ops = block.ops
    ops = []  # type: List[Op]
    for i, op in enumerate(old_ops):
        key = (block.label, i)
        if isinstance(op, (Assign, Cast, Box)):
            # These operations just copy/steal a reference and don't create new
            # references.
            if op.src in post_live[key] or op.src in pre_borrow[key]:
                ops.append(IncRef(op.src, env.types[op.src]))
                if (op.dest not in pre_borrow[key]
                        and op.dest in pre_live[key]):
                    ops.append(DecRef(op.dest, env.types[op.dest]))
            ops.append(op)
            if op.dest not in post_live[key]:
                ops.append(DecRef(op.dest, env.types[op.dest]))
        elif isinstance(op, RegisterOp):
            # These operations construct a new reference.
            tmp_reg = None  # type: Optional[Register]
            if (op.dest not in pre_borrow[key] and op.dest in pre_live[key]):
                if op.dest not in op.sources():
                    ops.append(DecRef(op.dest, env.types[op.dest]))
                else:
                    tmp_reg = env.add_temp(env.types[op.dest])
                    ops.append(Assign(tmp_reg, op.dest))
            ops.append(op)
            for src in op.unique_sources():
                # Decrement source that won't be live afterwards.
                if src not in post_live[key] and src not in pre_borrow[key]:
                    if src != op.dest:
                        ops.append(DecRef(src, env.types[src]))
            if op.dest is not None and op.dest not in post_live[key]:
                ops.append(DecRef(op.dest, env.types[op.dest]))
            if tmp_reg is not None:
                ops.append(DecRef(tmp_reg, env.types[tmp_reg]))
        elif isinstance(op, Return) and op.reg in pre_borrow[key]:
            # The return op returns a new reference.
            ops.append(IncRef(op.reg, env.types[op.reg]))
            ops.append(op)
        else:
            ops.append(op)
    block.ops = ops
Пример #4
0
 def test_dec_ref_tuple_nested(self) -> None:
     self.assert_emit(DecRef(self.tt), 'CPyTagged_DecRef(cpy_r_tt.f0.f0);')
Пример #5
0
 def test_dec_ref(self) -> None:
     self.assert_emit(DecRef(self.m), "CPyTagged_DecRef(cpy_r_m);")
Пример #6
0
def maybe_append_dec_ref(ops: List[Op], dest: Value,
                         defined: 'AnalysisDict[Value]',
                         key: Tuple[BasicBlock, int]) -> None:
    if dest.type.is_refcounted:
        ops.append(DecRef(dest, is_xdec=is_maybe_undefined(defined[key],
                                                           dest)))
Пример #7
0
def maybe_append_dec_ref(ops: List[Op], dest: Value) -> None:
    if dest.type.is_refcounted:
        ops.append(DecRef(dest))
Пример #8
0
 def test_dec_ref_tuple_nested(self) -> None:
     tuple_type = TupleRType(
         [TupleRType([IntRType(), BoolRType()]),
          BoolRType()])
     self.assert_emit(DecRef(self.m, tuple_type),
                      'CPyTagged_DecRef(cpy_r_m.f0.f0);')