Files
hakorune/src/llvm_py/instructions/call.py

80 lines
2.5 KiB
Python
Raw Normal View History

"""
Call instruction lowering
Handles regular function calls (not BoxCall or ExternCall)
"""
import llvmlite.ir as ir
from typing import Dict, List, Optional
def lower_call(
builder: ir.IRBuilder,
module: ir.Module,
func_name: str,
args: List[int],
dst_vid: Optional[int],
vmap: Dict[int, ir.Value],
resolver=None
) -> None:
"""
Lower MIR Call instruction
Args:
builder: Current LLVM IR builder
module: LLVM module
func_name: Function name to call
args: List of argument value IDs
dst_vid: Optional destination for return value
vmap: Value map
resolver: Optional resolver for type handling
"""
# Look up function in module
func = None
for f in module.functions:
if f.name == func_name:
func = f
break
if not func:
# Function not found - create declaration
# Default: i64(i64, ...) signature
ret_type = ir.IntType(64)
arg_types = [ir.IntType(64)] * len(args)
func_type = ir.FunctionType(ret_type, arg_types)
func = ir.Function(module, func_type, name=func_name)
# Prepare arguments
call_args = []
for i, arg_id in enumerate(args):
arg_val = vmap.get(arg_id)
if not arg_val:
# Default based on expected type
if i < len(func.args):
expected_type = func.args[i].type
else:
expected_type = ir.IntType(64)
if isinstance(expected_type, ir.IntType):
arg_val = ir.Constant(expected_type, 0)
elif isinstance(expected_type, ir.DoubleType):
arg_val = ir.Constant(expected_type, 0.0)
else:
arg_val = ir.Constant(expected_type, None)
# Type conversion if needed
if i < len(func.args):
expected_type = func.args[i].type
if hasattr(arg_val, 'type') and arg_val.type != expected_type:
if expected_type.is_pointer and isinstance(arg_val.type, ir.IntType):
arg_val = builder.inttoptr(arg_val, expected_type)
elif isinstance(expected_type, ir.IntType) and arg_val.type.is_pointer:
arg_val = builder.ptrtoint(arg_val, expected_type)
call_args.append(arg_val)
# Make the call
result = builder.call(func, call_args, name=f"call_{func_name}")
# Store result if needed
if dst_vid is not None:
vmap[dst_vid] = result