def format_blocks(blocks: List[BasicBlock], env: Environment) -> List[str]: # First label all of the blocks for i, block in enumerate(blocks): block.label = i handler_map = {} # type: Dict[BasicBlock, List[BasicBlock]] for b in blocks: if b.error_handler: handler_map.setdefault(b.error_handler, []).append(b) lines = [] for i, block in enumerate(blocks): i == len(blocks) - 1 handler_msg = '' if block in handler_map: labels = sorted( env.format('%l', b.label) for b in handler_map[block]) handler_msg = ' (handler for {})'.format(', '.join(labels)) lines.append(env.format('%l:%s', block.label, handler_msg)) ops = block.ops if (isinstance(ops[-1], Goto) and i + 1 < len(blocks) and ops[-1].label == blocks[i + 1]): # Hide the last goto if it just goes to the next basic block. ops = ops[:-1] for op in ops: line = ' ' + op.to_str(env) lines.append(line) if not isinstance(block.ops[-1], (Goto, Branch, Return, Unreachable)): # Each basic block needs to exit somewhere. lines.append(' [MISSING BLOCK EXIT OPCODE]') return lines
def format_blocks(blocks: List[BasicBlock], env: Environment, const_regs: Dict[str, int]) -> List[str]: """Format a list of IR basic blocks into a human-readable form.""" # First label all of the blocks for i, block in enumerate(blocks): block.label = i handler_map = {} # type: Dict[BasicBlock, List[BasicBlock]] for b in blocks: if b.error_handler: handler_map.setdefault(b.error_handler, []).append(b) lines = [] for i, block in enumerate(blocks): handler_msg = '' if block in handler_map: labels = sorted( env.format('%l', b.label) for b in handler_map[block]) handler_msg = ' (handler for {})'.format(', '.join(labels)) lines.append(env.format('%l:%s', block.label, handler_msg)) ops = block.ops if (isinstance(ops[-1], Goto) and i + 1 < len(blocks) and ops[-1].label == blocks[i + 1]): # Hide the last goto if it just goes to the next basic block. ops = ops[:-1] # load int registers start with 'i' regex = re.compile(r'\bi[0-9]+\b') for op in ops: if op.name not in const_regs: line = ' ' + op.to_str(env) line = regex.sub( lambda i: str(const_regs[i.group()]) if i.group() in const_regs else i.group(), line) lines.append(line) if not isinstance(block.ops[-1], (Goto, Branch, Return, Unreachable)): # Each basic block needs to exit somewhere. lines.append(' [MISSING BLOCK EXIT OPCODE]') return lines