Ejemplo n.º 1
0
    def op_FOR_ITER(self, inst, iterator, indval, pred):
        """
        Assign new block other this instruction.
        """
        assert inst.offset in self.blocks, "FOR_ITER must be block head"

        # Mark this block as the loop condition
        loop = self.syntax_blocks[-1]
        loop.condition = self.current_block_offset

        # Emit code
        val = self.get(iterator)
        iternext = ir.Expr.iternext(value=val, loc=self.loc)
        self.store(iternext, indval)

        itervalid = ir.Expr.itervalid(value=val, loc=self.loc)
        self.store(itervalid, pred)

        # Conditional jump
        br = ir.Branch(cond=self.get(pred),
                       truebr=inst.next,
                       falsebr=inst.get_jump_target(),
                       loc=self.loc)
        self.current_block.append(br)

        # Add event listener to mark the following blocks as loop body
        def mark_as_body(offset, block):
            loop.body.append(offset)

        self._block_actions[loop] = mark_as_body
Ejemplo n.º 2
0
def mk_loop_header(typemap, phi_var, calltypes, scope, loc):
    """make a block that is a loop header updating iteration variables.
    target labels in branch need to be set.
    """
    # iternext_var = iternext(phi_var)
    iternext_var = ir.Var(scope, mk_unique_var("$iternext_var"), loc)
    typemap[iternext_var.name] = types.containers.Pair(
        types.intp, types.boolean)
    iternext_call = ir.Expr.iternext(phi_var, loc)
    calltypes[iternext_call] = signature(
        types.containers.Pair(
            types.intp,
            types.boolean),
        types.range_iter64_type)
    iternext_assign = ir.Assign(iternext_call, iternext_var, loc)
    # pair_first_var = pair_first(iternext_var)
    pair_first_var = ir.Var(scope, mk_unique_var("$pair_first_var"), loc)
    typemap[pair_first_var.name] = types.intp
    pair_first_call = ir.Expr.pair_first(iternext_var, loc)
    pair_first_assign = ir.Assign(pair_first_call, pair_first_var, loc)
    # pair_second_var = pair_second(iternext_var)
    pair_second_var = ir.Var(scope, mk_unique_var("$pair_second_var"), loc)
    typemap[pair_second_var.name] = types.boolean
    pair_second_call = ir.Expr.pair_second(iternext_var, loc)
    pair_second_assign = ir.Assign(pair_second_call, pair_second_var, loc)
    # phi_b_var = pair_first_var
    phi_b_var = ir.Var(scope, mk_unique_var("$phi"), loc)
    typemap[phi_b_var.name] = types.intp
    phi_b_assign = ir.Assign(pair_first_var, phi_b_var, loc)
    # branch pair_second_var body_block out_block
    branch = ir.Branch(pair_second_var, -1, -1, loc)
    header_block = ir.Block(scope, loc)
    header_block.body = [iternext_assign, pair_first_assign,
                         pair_second_assign, phi_b_assign, branch]
    return header_block
Ejemplo n.º 3
0
 def _op_JUMP_IF(self, inst, pred, iftrue):
     brs = {
         True: inst.get_jump_target(),
         False: inst.next,
     }
     truebr = brs[iftrue]
     falsebr = brs[not iftrue]
     bra = ir.Branch(cond=self.get(pred), truebr=truebr, falsebr=falsebr,
                     loc=self.loc)
     self.current_block.append(bra)
Ejemplo n.º 4
0
 def test_branch(self):
     a = ir.Branch(self.var_a, 1, 2, self.loc1)
     b = ir.Branch(self.var_a, 1, 2, self.loc1)
     c = ir.Branch(self.var_a, 1, 2, self.loc2)
     d = ir.Branch(self.var_b, 1, 2, self.loc1)
     e = ir.Branch(self.var_a, 2, 2, self.loc1)
     f = ir.Branch(self.var_a, 1, 3, self.loc1)
     self.check(a, same=[b, c], different=[d, e, f])
Ejemplo n.º 5
0
    def replace_target(term, src, dst):
        def replace(target):
            return (dst if target == src else target)

        if isinstance(term, ir.Branch):
            return ir.Branch(cond=term.cond,
                             truebr=replace(term.truebr),
                             falsebr=replace(term.falsebr),
                             loc=term.loc)
        elif isinstance(term, ir.Jump):
            return ir.Jump(target=replace(term.target), loc=term.loc)
        else:
            assert not term.get_targets()
            return term
Ejemplo n.º 6
0
 def _op_JUMP_IF(self, inst, pred, iftrue):
     brs = {
         True: inst.get_jump_target(),
         False: inst.next,
     }
     truebr = brs[iftrue]
     falsebr = brs[not iftrue]
     bra = ir.Branch(cond=self.get(pred),
                     truebr=truebr,
                     falsebr=falsebr,
                     loc=self.loc)
     self.current_block.append(bra)
     # In a while loop?
     self._determine_while_condition((truebr, falsebr))
Ejemplo n.º 7
0
    def op_FOR_ITER(self, inst, iterator, pair, indval, pred):
        """
        Assign new block other this instruction.
        """
        assert inst.offset in self.blocks, "FOR_ITER must be block head"

        # Emit code
        val = self.get(iterator)

        pairval = ir.Expr.iternext(value=val, loc=self.loc)
        self.store(pairval, pair)

        iternext = ir.Expr.pair_first(value=self.get(pair), loc=self.loc)
        self.store(iternext, indval)

        isvalid = ir.Expr.pair_second(value=self.get(pair), loc=self.loc)
        self.store(isvalid, pred)

        # Conditional jump
        br = ir.Branch(cond=self.get(pred), truebr=inst.next,
                       falsebr=inst.get_jump_target(),
                       loc=self.loc)
        self.current_block.append(br)