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
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
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)
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
def terminator(self): """Block Op in block, which needs to be a terminator""" assert ops.is_terminator(self.ops.tail) return self.ops.tail
def is_terminated(self): """Returns whether the block is terminated""" return self.ops.tail and ops.is_terminator(self.ops.tail.opcode)