1111from .ast2hir import get_function_hir
1212from .. import TileTypeError
1313from .._coroutine_util import resume_after , run_coroutine
14- from .._exception import Loc , TileSyntaxError , TileInternalError , TileError , TileRecursionError
14+ from .._exception import Loc , FunctionDesc , TileSyntaxError , TileInternalError , TileError , \
15+ TileRecursionError
1516from .._execution import is_stub
1617from .._ir import hir , ir
1718from .._ir .ir import Var , IRContext , BoundMethodValue , ClosureValue , TupleValue
@@ -35,10 +36,11 @@ def hir2ir(func_hir: hir.Function,
3536 run_coroutine (_hir2ir_coroutine (func_hir , param_aggregate_vars , ir_ctx ))
3637
3738
38- async def _hir2ir_coroutine (func_hir : hir .Function ,
39- param_aggregate_vars : Sequence [ir .Var ],
40- ir_ctx : IRContext ):
41- scope = _create_scope (func_hir , ir_ctx , call_site = None , parent_scopes = ())
39+ async def _hir2ir_coroutine (
40+ func_hir : hir .Function , param_aggregate_vars : Sequence [ir .Var ], ir_ctx : IRContext
41+ ):
42+ scope = _create_scope (func_hir , ir_ctx , call_site = None , parent_scopes = (),
43+ concrete_func_desc = func_hir .desc )
4244 for local_idx , var in zip (func_hir .param_local_indices , param_aggregate_vars , strict = True ):
4345 scope .local [local_idx ] = var
4446
@@ -56,9 +58,28 @@ async def _hir2ir_coroutine(func_hir: hir.Function,
5658
5759
5860def _create_scope (func_hir : hir .Function , ir_ctx : IRContext , call_site : Loc | None ,
59- parent_scopes : tuple [LocalScope , ...]) -> Scope :
61+ parent_scopes : tuple [LocalScope , ...],
62+ concrete_func_desc : FunctionDesc ) -> Scope :
6063 local_scope = LocalScope (func_hir .local_names , ir_ctx )
61- return Scope (parent_scopes + (local_scope ,), None , None , call_site , IntMap (), func_hir )
64+ return Scope (parent_scopes + (local_scope ,), None , None , call_site , IntMap (), func_hir ,
65+ concrete_func_desc = concrete_func_desc )
66+
67+
68+ def _concretize_func_desc (func_hir : hir .Function , ir_ctx : IRContext ) -> FunctionDesc :
69+ # Mint a fresh FunctionDesc whose `specialization_id` makes its synthesized
70+ # linkage name unique across every inlining.
71+ return dataclasses .replace (func_hir .desc ,
72+ specialization_id = ir_ctx .next_function_specialization_id ())
73+
74+
75+ def retarget_loc (loc : Loc , scope : Scope ) -> Loc :
76+ # Splice in the scope's call site and, if this loc belongs to the function
77+ # currently being inlined, swap in the per-specialization FunctionDesc so
78+ # emitted ops carry the right debug info.
79+ new_function = loc .function
80+ if loc .function is scope .func_hir .desc :
81+ new_function = scope .concrete_func_desc
82+ return dataclasses .replace (loc , function = new_function , call_site = scope .call_site )
6283
6384
6485async def dispatch_hir_block (block : hir .Block , cur_builder : ir .Builder | None = None ):
@@ -72,7 +93,7 @@ async def _dispatch_hir_block_inner(block: hir.Block, builder: ir.Builder):
7293 try :
7394 scope = Scope .get_current ()
7495 for cursor , call in enumerate (block .calls ):
75- loc = call .loc . with_call_site ( scope . call_site )
96+ loc = retarget_loc ( call .loc , scope )
7697 with _wrap_exceptions (loc ), builder .change_loc (loc ):
7798 await _dispatch_call (call , scope )
7899 if builder .is_terminated :
@@ -81,7 +102,7 @@ async def _dispatch_hir_block_inner(block: hir.Block, builder: ir.Builder):
81102 return
82103 cursor = len (block .calls )
83104
84- loc = block .jump_loc . with_call_site ( scope . call_site )
105+ loc = retarget_loc ( block .jump_loc , scope )
85106 with _wrap_exceptions (loc ), builder .change_loc (loc ):
86107 _dispatch_hir_jump (block , scope )
87108 except Exception :
@@ -155,9 +176,13 @@ async def _call_user_defined(callee_hir: hir.Function,
155176 raise TileSyntaxError ("Variadic keyword parameters in user-defined"
156177 " functions are not supported" )
157178
158- # Activate a fresh Scope.
179+ # Activate a fresh Scope. Each inlining gets its own concretized
180+ # FunctionDesc so that DI never merges two specializations whose generated
181+ # IR might differ.
159182 new_scope = _create_scope (callee_hir , builder .ir_ctx , call_site = builder .loc ,
160- parent_scopes = parent_scopes )
183+ parent_scopes = parent_scopes ,
184+ concrete_func_desc = _concretize_func_desc (callee_hir ,
185+ builder .ir_ctx ))
161186 with new_scope .make_current ():
162187 # Call store_var() to bind arguments to parameters.
163188 for arg , local_idx , param_loc in zip (arg_list , callee_hir .param_local_indices ,
0 commit comments