11"""Intermediate representation of functions."""
2- import re
32
4- from typing import List , Optional , Sequence , Dict
3+ from typing import List , Optional , Sequence
54from typing_extensions import Final
65
76from mypy .nodes import FuncDef , Block , ARG_POS , ARG_OPT , ARG_NAMED_OPT
87
98from mypyc .common import JsonDict
10- from mypyc .ir .ops import (
11- DeserMaps , Goto , Branch , Return , Unreachable , BasicBlock , Environment
12- )
9+ from mypyc .ir .ops import DeserMaps , BasicBlock , Environment
1310from mypyc .ir .rtypes import RType , deserialize_type
14- from mypyc .ir .const_int import find_constant_integer_registers
1511from mypyc .namegen import NameGenerator
1612
1713
@@ -195,8 +191,11 @@ def fullname(self) -> str:
195191 def cname (self , names : NameGenerator ) -> str :
196192 return self .decl .cname (names )
197193
198- def __str__ (self ) -> str :
199- return '\n ' .join (format_func (self ))
194+ def __repr__ (self ) -> str :
195+ if self .class_name :
196+ return '<FuncIR {}.{}>' .format (self .class_name , self .name )
197+ else :
198+ return '<FuncIR {}>' .format (self .name )
200199
201200 def serialize (self ) -> JsonDict :
202201 # We don't include blocks or env in the serialized version
@@ -218,58 +217,3 @@ def deserialize(cls, data: JsonDict, ctx: DeserMaps) -> 'FuncIR':
218217
219218
220219INVALID_FUNC_DEF = FuncDef ('<INVALID_FUNC_DEF>' , [], Block ([])) # type: Final
221-
222-
223- def format_blocks (blocks : List [BasicBlock ],
224- env : Environment ,
225- const_regs : Dict [str , int ]) -> List [str ]:
226- """Format a list of IR basic blocks into a human-readable form."""
227- # First label all of the blocks
228- for i , block in enumerate (blocks ):
229- block .label = i
230-
231- handler_map = {} # type: Dict[BasicBlock, List[BasicBlock]]
232- for b in blocks :
233- if b .error_handler :
234- handler_map .setdefault (b .error_handler , []).append (b )
235-
236- lines = []
237- for i , block in enumerate (blocks ):
238- handler_msg = ''
239- if block in handler_map :
240- labels = sorted (env .format ('%l' , b .label ) for b in handler_map [block ])
241- handler_msg = ' (handler for {})' .format (', ' .join (labels ))
242-
243- lines .append (env .format ('%l:%s' , block .label , handler_msg ))
244- ops = block .ops
245- if (isinstance (ops [- 1 ], Goto ) and i + 1 < len (blocks )
246- and ops [- 1 ].label == blocks [i + 1 ]):
247- # Hide the last goto if it just goes to the next basic block.
248- ops = ops [:- 1 ]
249- # load int registers start with 'i'
250- regex = re .compile (r'\bi[0-9]+\b' )
251- for op in ops :
252- if op .name not in const_regs :
253- line = ' ' + op .to_str (env )
254- line = regex .sub (lambda i : str (const_regs [i .group ()]) if i .group () in const_regs
255- else i .group (), line )
256- lines .append (line )
257-
258- if not isinstance (block .ops [- 1 ], (Goto , Branch , Return , Unreachable )):
259- # Each basic block needs to exit somewhere.
260- lines .append (' [MISSING BLOCK EXIT OPCODE]' )
261- return lines
262-
263-
264- def format_func (fn : FuncIR ) -> List [str ]:
265- lines = []
266- cls_prefix = fn .class_name + '.' if fn .class_name else ''
267- lines .append ('def {}{}({}):' .format (cls_prefix , fn .name ,
268- ', ' .join (arg .name for arg in fn .args )))
269- # compute constants
270- const_regs = find_constant_integer_registers (fn .blocks )
271- for line in fn .env .to_lines (const_regs ):
272- lines .append (' ' + line )
273- code = format_blocks (fn .blocks , fn .env , const_regs )
274- lines .extend (code )
275- return lines
0 commit comments