Beispiel #1
0
    def splitblock(self, name=None, terminate=False):
        """Split the current block, returning (old_block, new_block)"""
        # -------------------------------------------------
        # Sanity check

        # Allow splitting only after leaders and before terminator
        # TODO: error check

        # -------------------------------------------------
        # Split

        oldblock = self._curblock
        newblock = self.func.new_block(name or 'block', after=self._curblock)
        op = self._lastop

        # Terminate if requested and not done already
        if terminate and not ops.is_terminator(op):
            op = self.jump(newblock)

        # -------------------------------------------------
        # Move ops after the split to new block

        if op:
            if op == 'head':
                trailing = list(self._curblock.ops)
            elif op == 'tail':
                trailing = []
            else:
                trailing = list(op.block.ops.iter_from(op))[1:]

            for op in trailing:
                op.unlink()
            newblock.extend(trailing)

        # -------------------------------------------------
        # Patch phis

        if terminate:
            self._patch_phis(oldblock.ops, oldblock, newblock)
        else:
            for op in oldblock:
                for use in self.func.uses[op]:
                    if use.opcode == 'phi':
                        raise error.CompileError(
                            "Splitting this block would corrupt some phis")

        self._patch_phis(newblock.ops, oldblock, newblock)

        return oldblock, newblock
Beispiel #2
0
    def splitblock(self, name=None, terminate=False):
        """Split the current block, returning (old_block, new_block)"""
        # -------------------------------------------------
        # Sanity check

        # Allow splitting only after leaders and before terminator
        # TODO: error check

        # -------------------------------------------------
        # Split

        oldblock = self._curblock
        newblock = self.func.new_block(name or 'block', after=self._curblock)
        op = self._lastop

        # Terminate if requested and not done already
        if terminate and not ops.is_terminator(op):
            op = self.jump(newblock)

        # -------------------------------------------------
        # Move ops after the split to new block

        if op:
            if op == 'head':
                trailing = list(self._curblock.ops)
            elif op == 'tail':
                trailing = []
            else:
                trailing = list(op.block.ops.iter_from(op))[1:]

            for op in trailing:
                op.unlink()
            newblock.extend(trailing)

        # -------------------------------------------------
        # Patch phis

        if terminate:
            self._patch_phis(oldblock.ops, oldblock, newblock)
        else:
            for op in oldblock:
                for use in self.func.uses[op]:
                    if use.opcode == 'phi':
                        raise error.CompileError(
                            "Splitting this block would corrupt some phis")

        self._patch_phis(newblock.ops, oldblock, newblock)

        return oldblock, newblock
Beispiel #3
0
    def splitblock(self, name=None, terminate=False):
        """Split the current block, returning (old_block, new_block)"""
        self._assert_position()
        name = self.func.temp(name or 'block')
        newblock = self.func.add_block(name, after=self._curblock)
        op = self._lastop

        # Terminate if requested and not done already
        if terminate and not ops.is_terminator(op):
            op = self.jump(newblock)

        if op:
            # Move any tailing Ops...
            trailing = list(op.block.ops.iter_from(op))[1:]
            for op in trailing:
                op.unlink()
            newblock.extend(trailing)

        return self._curblock, newblock
Beispiel #4
0
    def splitblock(self, name=None, terminate=False):
        """Split the current block, returning (old_block, new_block)"""
        self._assert_position()
        name = self.func.temp(name or 'block')
        newblock = self.func.add_block(name, after=self._curblock)
        op = self._lastop

        # Terminate if requested and not done already
        if terminate and not ops.is_terminator(op):
            op = self.jump(newblock)

        if op:
            # Move any tailing Ops...
            trailing = list(op.block.ops.iter_from(op))[1:]
            for op in trailing:
                op.unlink()
            newblock.extend(trailing)

        return self._curblock, newblock
Beispiel #5
0
    def _loop(self, init, cond, next, body):
        _, exit_block = self.builder.splitblock(self.func.temp("exit"))
        _, body_block = self.builder.splitblock(self.func.temp("body"))
        _, cond_block = self.builder.splitblock(self.func.temp("cond"))

        self.visitif(init)
        self.builder.jump(cond_block)

        with self.builder.at_front(cond_block):
            cond = self.visit(cond, type=types.Bool)
            self.builder.cbranch(cond, body_block, exit_block)

        with self.builder.at_front(body_block):
            self.visit(body)
            self.visitif(next)
            bb = self.builder.basic_block
            if not bb.tail or not ops.is_terminator(bb.tail.opcode):
                self.builder.jump(cond_block)

        self.builder.position_at_end(exit_block)
Beispiel #6
0
    def _loop(self, init, cond, next, body):
        _, exit_block = self.builder.splitblock(self.func.temp("exit"))
        _, body_block = self.builder.splitblock(self.func.temp("body"))
        _, cond_block = self.builder.splitblock(self.func.temp("cond"))

        self.visitif(init)
        self.builder.jump(cond_block)

        with self.builder.at_front(cond_block):
            cond = self.visit(cond, type=types.Bool)
            self.builder.cbranch(cond, body_block, exit_block)

        with self.builder.at_front(body_block):
            self.visit(body)
            self.visitif(next)
            bb = self.builder.basic_block
            if not bb.tail or not ops.is_terminator(bb.tail.opcode):
                self.builder.jump(cond_block)

        self.builder.position_at_end(exit_block)
Beispiel #7
0
    def splitblock(self, name=None, terminate=False):
        """Split the current block, returning (old_block, new_block)"""
        newblock = self.func.new_block(name or 'block', after=self._curblock)
        op = self._lastop

        # Terminate if requested and not done already
        if terminate and not ops.is_terminator(op):
            op = self.jump(newblock)

        if op:
            # Move any tailing Ops...
            if op == 'head':
                trailing = list(self._curblock.ops)
            elif op == 'tail':
                trailing = []
            else:
                trailing = list(op.block.ops.iter_from(op))[1:]

            for op in trailing:
                op.unlink()
            newblock.extend(trailing)

        return self._curblock, newblock
Beispiel #8
0
 def terminator(self):
     """Block Op in block, which needs to be a terminator"""
     assert ops.is_terminator(self.ops.tail)
     return self.ops.tail
Beispiel #9
0
 def terminator(self):
     """Block Op in block, which needs to be a terminator"""
     assert ops.is_terminator(self.ops.tail)
     return self.ops.tail
Beispiel #10
0
 def is_terminated(self):
     """Returns whether the block is terminated"""
     return self.ops.tail and ops.is_terminator(self.ops.tail.opcode)
Beispiel #11
0
 def is_terminated(self):
     """Returns whether the block is terminated"""
     return self.ops.tail and ops.is_terminator(self.ops.tail.opcode)