Skip to content

Analysis

TypeInference dataclass

TypeInference(
    dialects: ir.DialectGroup,
    *,
    max_depth: int = 800,
    max_python_recursion_depth: int = 131072,
    debug: bool = False
)

Bases: Forward[TypeAttribute]

Type inference analysis for kirin.

This analysis uses the forward dataflow analysis framework to infer the types of the IR. The analysis uses the type information within the IR to determine the method dispatch.

The analysis will fallback to a type resolution algorithm if the type information is not available in the IR but the type information is available in the abstract values.

keys class-attribute instance-attribute

keys = ('typeinfer',)

The name of the interpreter to select from dialects by order. First matching key will be used.

lattice class-attribute instance-attribute

lattice = TypeAttribute

lattice type for the abstract interpreter.

eval_fallback

eval_fallback(
    frame: ForwardFrame[types.TypeAttribute],
    node: ir.Statement,
) -> interp.StatementResult[types.TypeAttribute]

The fallback implementation of statements.

This is called when no implementation is found for the statement.

Parameters:

Name Type Description Default
frame FrameType

the current frame

required
stmt

the statement to run

required

Returns:

Name Type Description
StatementResult StatementResult[ValueType]

the result of running the statement

Note

Overload this method to provide a fallback implementation for statements.

Source code in src/kirin/analysis/typeinfer/analysis.py
70
71
72
73
74
75
76
77
78
79
def eval_fallback(
    self, frame: ForwardFrame[types.TypeAttribute], node: ir.Statement
) -> interp.StatementResult[types.TypeAttribute]:
    resolve = TypeResolution()
    fs = fields(node)
    for f, value in zip(fs.args.values(), frame.get_values(node.args)):
        resolve.solve(f.type, value)
    for arg, f in zip(node.args, fs.args.values()):
        frame.set(arg, frame.get(arg).meet(resolve.substitute(f.type)))
    return tuple(resolve.substitute(result.type) for result in node.results)

frame_call

frame_call(
    frame: ForwardFrame[types.TypeAttribute],
    node: ir.Statement,
    *args: types.TypeAttribute,
    **kwargs: types.TypeAttribute
) -> types.TypeAttribute

Call a given callable node with the given arguments in a given frame.

This method is used to call a node that has a callable trait and a corresponding implementation of its callable region execution convention in the interpreter.

Source code in src/kirin/analysis/typeinfer/analysis.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
def frame_call(
    self,
    frame: ForwardFrame[types.TypeAttribute],
    node: ir.Statement,
    *args: types.TypeAttribute,
    **kwargs: types.TypeAttribute,
) -> types.TypeAttribute:
    trait = node.get_present_trait(ir.CallableStmtInterface)
    args = trait.align_input_args(node, *args, **kwargs)
    region = trait.get_callable_region(node)
    if self.state.depth >= self.max_depth:
        return self.recursion_limit_reached()

    if trait := node.get_trait(ir.HasSignature):
        signature: Signature[types.TypeAttribute] | None = trait.get_signature(node)
        args = (args[0],) + tuple(
            input.meet(arg) for input, arg in zip(signature.inputs, args[1:])
        )
    else:
        signature = None
    ret = self.frame_call_region(frame, node, region, *args)

    if isinstance(ret, interp.ReturnValue):
        return ret.value if signature is None else ret.value.meet(signature.output)
    elif not ret:  # empty result or None
        return self.void if signature is None else self.void.meet(signature.output)
    raise interp.InterpreterError(
        f"callable region {node.name} does not return `ReturnValue`, got {ret}"
    )

method_self

method_self(method: ir.Method) -> types.TypeAttribute

Return the self value for the given method.

Source code in src/kirin/analysis/typeinfer/analysis.py
37
38
def method_self(self, method: ir.Method) -> types.TypeAttribute:
    return method.self_type