Skip to content

Stmts

For

For(
    iterable: SSAValue,
    body: Region,
    *initializers: SSAValue
)

Bases: Statement


              flowchart TD
              kirin.dialects.scf.stmts.For[For]
              kirin.ir.nodes.stmt.Statement[Statement]
              kirin.ir.nodes.base.IRNode[IRNode]
              kirin.print.printable.Printable[Printable]

                              kirin.ir.nodes.stmt.Statement --> kirin.dialects.scf.stmts.For
                                kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
                                kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
                




              click kirin.dialects.scf.stmts.For href "" "kirin.dialects.scf.stmts.For"
              click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
              click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
              click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
            
Source code in src/kirin/dialects/scf/stmts.py
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
def __init__(
    self,
    iterable: ir.SSAValue,
    body: ir.Region,
    *initializers: ir.SSAValue,
):
    stmt = body.blocks[0].last_stmt
    if isinstance(stmt, Yield):
        result_types = tuple(value.type for value in stmt.values)
    else:
        result_types = ()
    super().__init__(
        args=(iterable, *initializers),
        regions=(body,),
        result_types=result_types,
        args_slice={"iterable": 0, "initializers": slice(1, None)},
        attributes={"purity": ir.PyAttr(False)},
    )

verify

verify() -> None

run mandatory validation checks. This is not same as verify_type, which may be optional.

Source code in src/kirin/dialects/scf/stmts.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
def verify(self) -> None:
    from kirin.dialects.func import Return

    if len(self.body.blocks) != 1:
        raise ir.ValidationError(self, "for loop body must have a single block")

    if len(self.body.blocks[0].args) != len(self.initializers) + 1:
        raise ir.ValidationError(
            self,
            "for loop body must have arguments for all initializers and the loop variable",
        )

    stmt = self.body.blocks[0].last_stmt
    if stmt is None or not isinstance(stmt, (Yield, Return)):
        raise ir.ValidationError(
            self, "for loop body must terminate with a yield or return"
        )

    if isinstance(stmt, Return):
        return

    if len(stmt.values) != len(self.initializers):
        raise ir.ValidationError(
            self,
            "for loop body must have the same number of results as initializers",
        )
    if len(self.results) != len(stmt.values):
        raise ir.ValidationError(
            self,
            "for loop must have the same number of results as the yield in the body",
        )

IfElse

IfElse(
    cond: SSAValue,
    then_body: Region | Block,
    else_body: Region | Block | None = None,
)

Bases: Statement


              flowchart TD
              kirin.dialects.scf.stmts.IfElse[IfElse]
              kirin.ir.nodes.stmt.Statement[Statement]
              kirin.ir.nodes.base.IRNode[IRNode]
              kirin.print.printable.Printable[Printable]

                              kirin.ir.nodes.stmt.Statement --> kirin.dialects.scf.stmts.IfElse
                                kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
                                kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
                




              click kirin.dialects.scf.stmts.IfElse href "" "kirin.dialects.scf.stmts.IfElse"
              click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
              click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
              click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
            

Python-like if-else statement.

This statement has a condition, then body, and else body.

Then body either terminates with a yield statement or scf.return.

Source code in src/kirin/dialects/scf/stmts.py
30
31
32
33
34
35
36
37
38
39
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
def __init__(
    self,
    cond: ir.SSAValue,
    then_body: ir.Region | ir.Block,
    else_body: ir.Region | ir.Block | None = None,
):
    if then_body.IS_REGION:
        then_body_region = cast(Region, then_body)
        if then_body_region.blocks:
            then_body_block = then_body_region.blocks[-1]
        else:
            then_body_block = None
    else:  # then_body.IS_BLOCK:
        then_body_block = cast(Block, then_body)
        then_body_region = Region(then_body_block)

    if else_body is None:
        else_body_region = ir.Region()
        else_body_block = None
    elif else_body.IS_REGION:
        else_body_region = cast(Region, else_body)
        if not else_body_region.blocks:  # empty region
            else_body_block = None
        elif len(else_body_region.blocks) == 0:
            else_body_block = None
        else:
            else_body_block = else_body_region.blocks[0]
    else:  # else_body.IS_BLOCK:
        else_body_region = ir.Region(cast(Block, else_body))
        else_body_block = else_body

    # if either then or else body has yield, we generate results
    # we assume if both have yields, they have the same number of results
    results = ()
    if then_body_block is not None:
        then_yield = then_body_block.last_stmt
        else_body_block = cast(Block, else_body_block)
        else_yield = (
            else_body_block.last_stmt if else_body_block is not None else None
        )
        if then_yield is not None and isinstance(then_yield, Yield):
            results = then_yield.values
        elif else_yield is not None and isinstance(else_yield, Yield):
            results = else_yield.values

    result_types = tuple(value.type for value in results)
    super().__init__(
        args=(cond,),
        regions=(then_body_region, else_body_region),
        result_types=result_types,
        args_slice={"cond": 0},
        attributes={"purity": ir.PyAttr(False)},
    )

verify

verify() -> None

run mandatory validation checks. This is not same as verify_type, which may be optional.

Source code in src/kirin/dialects/scf/stmts.py
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def verify(self) -> None:
    from kirin.dialects.func import Return

    if len(self.then_body.blocks) != 1:
        raise ir.ValidationError(self, "then region must have a single block")

    if len(self.else_body.blocks) != 1:
        raise ir.ValidationError(self, "else region must have a single block")

    then_block = self.then_body.blocks[0]
    else_block = self.else_body.blocks[0]
    if len(then_block.args) != 1:
        raise ir.ValidationError(
            self, "then block must have a single argument for condition"
        )

    if len(else_block.args) != 1:
        raise ir.ValidationError(
            self, "else block must have a single argument for condition"
        )

    then_stmt = then_block.last_stmt
    else_stmt = else_block.last_stmt
    if then_stmt is None or not isinstance(then_stmt, (Yield, Return)):
        raise ir.ValidationError(
            self, "then block must terminate with a yield or return"
        )

    if else_stmt is None or not isinstance(else_stmt, (Yield, Return)):
        raise ir.ValidationError(
            self, "else block must terminate with a yield or return"
        )