Skip to content

Warning

This page is under construction. The content may be incomplete or incorrect. Submit an issue on GitHub if you need help or want to contribute.

Core Python Dialects

This page contains the core Python dialects that are used most frequently when designing an embedded DSL in Python.

Reference

Base

kirin.dialects.py.base

Base dialect for Python.

This dialect does not contain statements. It only contains lowering rules for ast.Name and ast.Expr.

dialect module-attribute

dialect = Dialect('py.base')

PythonLowering

Bases: FromPythonAST

lower_Expr

lower_Expr(
    state: lowering.LoweringState, node: ast.Expr
) -> lowering.Result
Source code in src/kirin/dialects/py/base.py
31
32
33
34
def lower_Expr(
    self, state: lowering.LoweringState, node: ast.Expr
) -> lowering.Result:
    return state.visit(node.value)

lower_Name

lower_Name(
    state: lowering.LoweringState, node: ast.Name
) -> lowering.Result
Source code in src/kirin/dialects/py/base.py
17
18
19
20
21
22
23
24
25
26
27
28
29
def lower_Name(
    self, state: lowering.LoweringState, node: ast.Name
) -> lowering.Result:
    name = node.id
    if isinstance(node.ctx, ast.Load):
        value = state.current_frame.get(name)
        if value is None:
            raise exceptions.DialectLoweringError(f"{name} is not defined")
        return lowering.Result(value)
    elif isinstance(node.ctx, ast.Store):
        raise exceptions.DialectLoweringError("unhandled store operation")
    else:  # Del
        raise exceptions.DialectLoweringError("unhandled del operation")

Constant

kirin.dialects.py.constant

Constant statement for Python dialect.

This module contains the dialect for the Python constant statement, including:

  • The Constant statement class.
  • The lowering pass for the constant statement.
  • The concrete implementation of the constant statement.
  • The Julia emitter for the constant statement.

This dialect maps ast.Constant nodes to the Constant statement.

T module-attribute

T = TypeVar('T', covariant=True)

dialect module-attribute

dialect = Dialect('py.constant')

Concrete dataclass

Concrete()

Bases: MethodTable

constant

constant(interp, frame: interp.Frame, stmt: Constant)
Source code in src/kirin/dialects/py/constant.py
69
70
71
@interp.impl(Constant)
def constant(self, interp, frame: interp.Frame, stmt: Constant):
    return (stmt.value,)

Constant kirin-statement

Constant(value: T | ir.PyAttr[T])

Bases: Statement, Generic[T]

Source code in src/kirin/dialects/py/constant.py
34
35
36
37
38
39
40
def __init__(self, value: T | ir.PyAttr[T]) -> None:
    if not isinstance(value, ir.PyAttr):
        value = ir.PyAttr(value)
    super().__init__(
        attributes={"value": value},
        result_types=(value.type,),
    )

name class-attribute instance-attribute

name = 'constant'

result kirin-result

result: ResultValue = result()

traits class-attribute instance-attribute

traits = frozenset(
    {Pure(), ConstantLike(), FromPythonCall()}
)

value kirin-attribute kw-only

value: T = attribute()

print_impl

print_impl(printer: Printer) -> None
Source code in src/kirin/dialects/py/constant.py
42
43
44
45
46
47
48
def print_impl(self, printer: Printer) -> None:
    printer.print_name(self)
    printer.plain_print(" ")
    printer.plain_print(repr(self.value))
    with printer.rich(style="comment"):
        printer.plain_print(" : ")
        printer.print(self.result.type)

typecheck

typecheck() -> None

check the type of the statement.

Note
  1. Statement should implement typecheck. this is done automatically via @statement, but in the case manualy implementation is needed, it should be implemented here.
  2. This API should be called after all the types are figured out (by typeinfer)
Source code in src/kirin/dialects/py/constant.py
50
51
52
53
54
def typecheck(self) -> None:
    if not isinstance(self.result.type, types.TypeAttribute):
        raise exceptions.VerificationError(
            self, f"Expected result type to be PyType, got {self.result.type}"
        )

JuliaTable dataclass

JuliaTable()

Bases: MethodTable

emit_Constant

emit_Constant(
    emit: EmitJulia, frame: EmitStrFrame, stmt: Constant
)
Source code in src/kirin/dialects/py/constant.py
77
78
79
@interp.impl(Constant)
def emit_Constant(self, emit: EmitJulia, frame: EmitStrFrame, stmt: Constant):
    return (emit.emit_attribute(ir.PyAttr(stmt.value)),)

Lowering

Bases: FromPythonAST

lower_Constant

lower_Constant(
    state: lowering.LoweringState, node: ast.Constant
) -> lowering.Result
Source code in src/kirin/dialects/py/constant.py
60
61
62
63
def lower_Constant(
    self, state: lowering.LoweringState, node: ast.Constant
) -> lowering.Result:
    return lowering.Result(state.append_stmt(Constant(node.value)))

UnaryOp

kirin.dialects.py.unary.stmts

T module-attribute

T = TypeVar('T')

Invert kirin-statement

Invert(value: ir.SSAValue)

Bases: UnaryOp

name class-attribute instance-attribute

name = 'invert'

Not kirin-statement

Not(value: ir.SSAValue)

Bases: UnaryOp

name class-attribute instance-attribute

name = 'not'

UAdd kirin-statement

UAdd(value: ir.SSAValue)

Bases: UnaryOp

name class-attribute instance-attribute

name = 'uadd'

USub kirin-statement

USub(value: ir.SSAValue)

Bases: UnaryOp

name class-attribute instance-attribute

name = 'usub'

UnaryOp kirin-statement

UnaryOp(value: ir.SSAValue)

Bases: Statement

result kirin-result

result: ResultValue = result(T)

traits class-attribute instance-attribute

traits = frozenset({Pure(), FromPythonCall()})

value kirin-argument

value: SSAValue = argument(T, print=False)

BinOp

kirin.dialects.py.binop.stmts

T module-attribute

T = TypeVar('T')

Add kirin-statement

Add(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'add'

BinOp kirin-statement

BinOp(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Statement

lhs kirin-argument

lhs: SSAValue = argument(T, print=False)

result kirin-result

result: ResultValue = result(T)

rhs kirin-argument

rhs: SSAValue = argument(T, print=False)

traits class-attribute instance-attribute

traits = frozenset({Pure(), FromPythonCall()})

BitAnd kirin-statement

BitAnd(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'bitand'

BitOr kirin-statement

BitOr(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'bitor'

BitXor kirin-statement

BitXor(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'bitxor'

Div kirin-statement

Div(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'div'

FloorDiv kirin-statement

FloorDiv(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'floordiv'

LShift kirin-statement

LShift(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'lshift'

MatMult kirin-statement

MatMult(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'matmult'

Mod kirin-statement

Mod(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'mod'

Mult kirin-statement

Mult(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'mult'

Pow kirin-statement

Pow(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'pow'

RShift kirin-statement

RShift(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'rshift'

Sub kirin-statement

Sub(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BinOp

name class-attribute instance-attribute

name = 'sub'

Assertion

kirin.dialects.py.assertion

Assertion dialect for Python.

This module contains the dialect for the Python assert statement, including:

  • The Assert statement class.
  • The lowering pass for the assert statement.
  • The concrete implementation of the assert statement.
  • The type inference implementation of the assert statement.
  • The Julia emitter for the assert statement.

This dialect maps ast.Assert nodes to the Assert statement.

dialect module-attribute

dialect = Dialect('py.assert')

Assert kirin-statement

Assert(message: ir.SSAValue)

Bases: Statement

condition instance-attribute

condition: SSAValue

message kirin-argument

message: SSAValue = argument(String)

print_impl

print_impl(printer: Printer) -> None
Source code in src/kirin/dialects/py/assertion.py
29
30
31
32
33
34
35
36
37
38
def print_impl(self, printer: Printer) -> None:
    with printer.rich(style="keyword"):
        printer.print_name(self)

    printer.plain_print(" ")
    printer.print(self.condition)

    if self.message:
        printer.plain_print(", ")
        printer.print(self.message)

Concrete dataclass

Concrete()

Bases: MethodTable

assert_stmt

assert_stmt(
    interp_: interp.Interpreter,
    frame: interp.Frame,
    stmt: Assert,
)
Source code in src/kirin/dialects/py/assertion.py
62
63
64
65
66
67
68
69
70
71
72
@interp.impl(Assert)
def assert_stmt(
    self, interp_: interp.Interpreter, frame: interp.Frame, stmt: Assert
):
    if frame.get(stmt.condition) is True:
        return ()

    if stmt.message:
        raise interp.WrapException(AssertionError(frame.get(stmt.message)))
    else:
        raise interp.WrapException(AssertionError("Assertion failed"))

EmitJulia dataclass

EmitJulia()

Bases: MethodTable

emit_assert

emit_assert(
    interp: julia.EmitJulia,
    frame: EmitStrFrame,
    stmt: Assert,
)
Source code in src/kirin/dialects/py/assertion.py
86
87
88
89
90
91
@interp.impl(Assert)
def emit_assert(self, interp: julia.EmitJulia, frame: EmitStrFrame, stmt: Assert):
    interp.writeln(
        frame, f"@assert {frame.get(stmt.condition)} {frame.get(stmt.message)}"
    )
    return ()

Lowering

Bases: FromPythonAST

lower_Assert

lower_Assert(
    state: lowering.LoweringState, node: ast.Assert
) -> lowering.Result
Source code in src/kirin/dialects/py/assertion.py
44
45
46
47
48
49
50
51
52
53
54
55
56
def lower_Assert(
    self, state: lowering.LoweringState, node: ast.Assert
) -> lowering.Result:
    from kirin.dialects.py.constant import Constant

    cond = state.visit(node.test).expect_one()
    if node.msg:
        message = state.visit(node.msg).expect_one()
        state.append_stmt(Assert(condition=cond, message=message))
    else:
        message_stmt = state.append_stmt(Constant(""))
        state.append_stmt(Assert(condition=cond, message=message_stmt.result))
    return lowering.Result()

TypeInfer dataclass

TypeInfer()

Bases: MethodTable

assert_stmt

assert_stmt(interp, frame, stmt: Assert)
Source code in src/kirin/dialects/py/assertion.py
78
79
80
@interp.impl(Assert)
def assert_stmt(self, interp, frame, stmt: Assert):
    return (types.Bottom,)

Assignment

kirin.dialects.py.assign

Assignment dialect for Python.

This module contains the dialect for the Python assignment statement, including:

  • Statements: Alias, SetItem.
  • The lowering pass for the assignments.
  • The concrete implementation of the assignment statements.

This dialects maps Python assignment syntax.

T module-attribute

T = TypeVar('T')

dialect module-attribute

dialect = Dialect('py.assign')

Alias kirin-statement

Alias(value: ir.SSAValue, *, target: ir.PyAttr[str])

Bases: Statement

name class-attribute instance-attribute

name = 'alias'

result kirin-result

result: ResultValue = result(T)

target kirin-attribute kw-only

target: PyAttr[str] = attribute()

traits class-attribute instance-attribute

traits = frozenset({Pure(), FromPythonCall()})

value kirin-argument

value: SSAValue = argument(T)

print_impl

print_impl(printer: Printer) -> None
Source code in src/kirin/dialects/py/assign.py
31
32
33
34
35
36
37
38
39
40
def print_impl(self, printer: Printer) -> None:
    printer.print_name(self)
    printer.plain_print(" ")
    with printer.rich(style="symbol"):
        printer.plain_print(self.target.data)

    with printer.rich(style="keyword"):
        printer.plain_print(" = ")

    printer.print(self.value)

Concrete dataclass

Concrete()

Bases: MethodTable

alias

alias(interp, frame: interp.Frame, stmt: Alias)
Source code in src/kirin/dialects/py/assign.py
55
56
57
@interp.impl(Alias)
def alias(self, interp, frame: interp.Frame, stmt: Alias):
    return (frame.get(stmt.value),)

setindex

setindex(interp, frame: interp.Frame, stmt: SetItem)
Source code in src/kirin/dialects/py/assign.py
59
60
61
62
@interp.impl(SetItem)
def setindex(self, interp, frame: interp.Frame, stmt: SetItem):
    frame.get(stmt.obj)[frame.get(stmt.index)] = frame.get(stmt.value)
    return (None,)

Lowering

Bases: FromPythonAST

lower_Assign

lower_Assign(
    state: lowering.LoweringState, node: ast.Assign
) -> lowering.Result
Source code in src/kirin/dialects/py/assign.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
def lower_Assign(
    self, state: lowering.LoweringState, node: ast.Assign
) -> lowering.Result:
    results: lowering.Result = state.visit(node.value)
    assert len(node.targets) == len(
        results
    ), "number of targets and results do not match"

    current_frame = state.current_frame
    match node:
        case ast.Assign(
            targets=[ast.Name(lhs_name, ast.Store())], value=ast.Name(_, ast.Load())
        ):
            stmt = Alias(
                value=results[0], target=ir.PyAttr(lhs_name)
            )  # NOTE: this is guaranteed to be one result
            stmt.result.name = lhs_name
            current_frame.defs[lhs_name] = state.append_stmt(stmt).result
        case _:
            for target, value in zip(node.targets, results.values):
                match target:
                    # NOTE: if the name exists new ssa value will be
                    # used in the future to shadow the old one
                    case ast.Name(name, ast.Store()):
                        value.name = name
                        current_frame.defs[name] = value
                    case ast.Subscript(obj, slice):
                        obj = state.visit(obj).expect_one()
                        slice = state.visit(slice).expect_one()
                        stmt = SetItem(obj=obj, index=slice, value=value)
                        state.append_stmt(stmt)
                    case _:
                        raise exceptions.DialectLoweringError(
                            f"unsupported target {target}"
                        )
    return lowering.Result()  # python assign does not have value

SetItem kirin-statement

SetItem(
    obj: ir.SSAValue, value: ir.SSAValue, index: ir.SSAValue
)

Bases: Statement

index kirin-argument

index: SSAValue = argument(print=False)

name class-attribute instance-attribute

name = 'setitem'

obj kirin-argument

obj: SSAValue = argument(print=False)

traits class-attribute instance-attribute

traits = frozenset({FromPythonCall()})

value kirin-argument

value: SSAValue = argument(print=False)

Unpack

kirin.dialects.py.unpack

The unpack dialect for Python.

This module contains the dialect for the Python unpack semantics, including:

  • The Unpack statement class.
  • The lowering pass for the unpack statement.
  • The concrete implementation of the unpack statement.
  • The type inference implementation of the unpack statement.
  • A helper function unpacking for unpacking Python AST nodes during lowering.

dialect module-attribute

dialect = Dialect('py.unpack')

Concrete dataclass

Concrete()

Bases: MethodTable

unpack

unpack(
    interp: interp.Interpreter,
    frame: interp.Frame,
    stmt: Unpack,
)
Source code in src/kirin/dialects/py/unpack.py
47
48
49
@interp.impl(Unpack)
def unpack(self, interp: interp.Interpreter, frame: interp.Frame, stmt: Unpack):
    return tuple(frame.get(stmt.value))

TypeInfer dataclass

TypeInfer()

Bases: MethodTable

unpack

unpack(
    interp,
    frame: interp.Frame[types.TypeAttribute],
    stmt: Unpack,
)
Source code in src/kirin/dialects/py/unpack.py
55
56
57
58
59
60
61
62
63
64
65
@interp.impl(Unpack)
def unpack(self, interp, frame: interp.Frame[types.TypeAttribute], stmt: Unpack):
    value = frame.get(stmt.value)
    if isinstance(value, types.Generic) and value.is_subseteq(types.Tuple):
        if value.vararg:
            rest = tuple(value.vararg.typ for _ in stmt.names[len(value.vars) :])
            return tuple(value.vars) + rest
        else:
            return value.vars
    # TODO: support unpacking other types
    return tuple(types.Any for _ in stmt.names)

Unpack kirin-statement

Unpack(value: ir.SSAValue, names: tuple[str | None, ...])

Bases: Statement

Source code in src/kirin/dialects/py/unpack.py
27
28
29
30
31
32
33
34
35
36
def __init__(self, value: ir.SSAValue, names: tuple[str | None, ...]):
    result_types = [types.Any] * len(names)
    super().__init__(
        args=(value,),
        result_types=result_types,
        args_slice={"value": 0},
        attributes={"names": ir.PyAttr(names)},
    )
    for result, name in zip(self.results, names):
        result.name = name

names kirin-attribute kw-only

names: tuple[str | None, ...] = attribute()

value kirin-argument

value: SSAValue = argument(Any)

print_impl

print_impl(printer: Printer) -> None
Source code in src/kirin/dialects/py/unpack.py
38
39
40
41
def print_impl(self, printer: Printer) -> None:
    printer.print_name(self)
    printer.plain_print(" ")
    printer.print(self.value)

unpacking

unpacking(
    state: lowering.LoweringState,
    node: ast.expr,
    value: ir.SSAValue,
)
Source code in src/kirin/dialects/py/unpack.py
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
def unpacking(state: lowering.LoweringState, node: ast.expr, value: ir.SSAValue):
    if isinstance(node, ast.Name):
        state.current_frame.defs[node.id] = value
        value.name = node.id
        return
    elif not isinstance(node, ast.Tuple):
        raise DialectLoweringError(f"unsupported unpack node {node}")

    names: list[str | None] = []
    continue_unpack: list[int] = []
    for idx, item in enumerate(node.elts):
        if isinstance(item, ast.Name):
            names.append(item.id)
        else:
            names.append(None)
            continue_unpack.append(idx)
    stmt = state.append_stmt(Unpack(value, tuple(names)))
    for name, result in zip(names, stmt.results):
        if name is not None:
            state.current_frame.defs[name] = result

    for idx in continue_unpack:
        unpacking(state, node.elts[idx], stmt.results[idx])

Boolean Operation

kirin.dialects.py.boolop

Boolean operators for Python dialect.

This module contains the dialect for the Python boolean operators, including:

  • The And and Or statement classes.
  • The lowering pass for the boolean operators.
  • The concrete implementation of the boolean operators.
  • The Julia emitter for the boolean operators.

This dialect maps ast.BoolOp nodes to the And and Or statements.

dialect module-attribute

dialect = Dialect('py.boolop')

And kirin-statement

And(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BoolOp

name class-attribute instance-attribute

name = 'and'

BoolOp kirin-statement

BoolOp(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Statement

lhs kirin-argument

lhs: SSAValue = argument(print=False)

result kirin-result

result: ResultValue = result(Bool)

rhs kirin-argument

rhs: SSAValue = argument(print=False)

traits class-attribute instance-attribute

traits = frozenset({Pure(), FromPythonCall()})

BoolOpMethod dataclass

BoolOpMethod()

Bases: MethodTable

and_

and_(interp, frame: interp.Frame, stmt: And)
Source code in src/kirin/dialects/py/boolop.py
66
67
68
@interp.impl(And)
def and_(self, interp, frame: interp.Frame, stmt: And):
    return (frame.get(stmt.lhs) and frame.get(stmt.rhs),)

or_

or_(interp, frame: interp.Frame, stmt: Or)
Source code in src/kirin/dialects/py/boolop.py
70
71
72
@interp.impl(Or)
def or_(self, interp, frame: interp.Frame, stmt: Or):
    return (frame.get(stmt.lhs) or frame.get(stmt.rhs),)

JuliaTable dataclass

JuliaTable()

Bases: MethodTable

emit_And

emit_And(emit: EmitJulia, frame: EmitStrFrame, stmt: And)
Source code in src/kirin/dialects/py/boolop.py
78
79
80
@interp.impl(And)
def emit_And(self, emit: EmitJulia, frame: EmitStrFrame, stmt: And):
    return emit.emit_binaryop(frame, "&&", stmt.lhs, stmt.rhs, stmt.result)

emit_Or

emit_Or(emit: EmitJulia, frame: EmitStrFrame, stmt: Or)
Source code in src/kirin/dialects/py/boolop.py
82
83
84
@interp.impl(Or)
def emit_Or(self, emit: EmitJulia, frame: EmitStrFrame, stmt: Or):
    return emit.emit_binaryop(frame, "||", stmt.lhs, stmt.rhs, stmt.result)

Or kirin-statement

Or(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: BoolOp

name class-attribute instance-attribute

name = 'or'

PythonLowering

Bases: FromPythonAST

lower_BoolOp

lower_BoolOp(
    state: lowering.LoweringState, node: ast.BoolOp
) -> lowering.Result
Source code in src/kirin/dialects/py/boolop.py
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
def lower_BoolOp(
    self, state: lowering.LoweringState, node: ast.BoolOp
) -> lowering.Result:
    lhs = state.visit(node.values[0]).expect_one()
    match node.op:
        case ast.And():
            boolop = And
        case ast.Or():
            boolop = Or
        case _:
            raise DialectLoweringError(f"unsupported boolop {node.op}")

    for value in node.values[1:]:
        lhs = state.append_stmt(
            boolop(lhs=lhs, rhs=state.visit(value).expect_one())
        ).result
    return lowering.Result(lhs)

Comparison

kirin.dialects.py.cmp.stmts

Cmp kirin-statement

Cmp(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Statement

lhs kirin-argument

lhs: SSAValue = argument()

result kirin-result

result: ResultValue = result(Bool)

rhs kirin-argument

rhs: SSAValue = argument()

traits class-attribute instance-attribute

traits = frozenset({Pure(), FromPythonCall()})

Eq kirin-statement

Eq(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Cmp

name class-attribute instance-attribute

name = 'eq'

Gt kirin-statement

Gt(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Cmp

name class-attribute instance-attribute

name = 'gt'

GtE kirin-statement

GtE(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Cmp

name class-attribute instance-attribute

name = 'gte'

In kirin-statement

In(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Cmp

name class-attribute instance-attribute

name = 'in'

Is kirin-statement

Is(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Cmp

name class-attribute instance-attribute

name = 'is'

IsNot kirin-statement

IsNot(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Cmp

name class-attribute instance-attribute

name = 'is_not'

Lt kirin-statement

Lt(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Cmp

name class-attribute instance-attribute

name = 'lt'

LtE kirin-statement

LtE(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Cmp

name class-attribute instance-attribute

name = 'lte'

NotEq kirin-statement

NotEq(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Cmp

name class-attribute instance-attribute

name = 'ne'

NotIn kirin-statement

NotIn(lhs: ir.SSAValue, rhs: ir.SSAValue)

Bases: Cmp

name class-attribute instance-attribute

name = 'not_in'