Skip to content

Scf

scf

ScfFunctions dataclass

Bases: InterpreterFunctions

Source code in xdsl/interpreters/scf.py
@register_impls
class ScfFunctions(InterpreterFunctions):
    @impl(scf.IfOp)
    def run_if(self, interpreter: Interpreter, op: scf.IfOp, args: PythonValues):
        (cond,) = args
        region = op.true_region if cond else op.false_region
        results = interpreter.run_ssacfg_region(region, ())
        return results

    @impl(scf.ForOp)
    def run_for(
        self, interpreter: Interpreter, op: scf.ForOp, args: PythonValues
    ) -> PythonValues:
        lb, ub, step, *packed_args = args
        loop_args = tuple(packed_args)

        for i in range(lb, ub, step):
            loop_args = interpreter.run_ssacfg_region(
                op.body, (i, *loop_args), "for_loop"
            )

        return loop_args

    @impl_terminator(scf.YieldOp)
    def run_br(
        self, _interpreter: Interpreter, op: scf.YieldOp, args: PythonValues
    ) -> tuple[TerminatorValue, PythonValues]:
        return ReturnedValues(args), ()

    @impl_terminator(scf.ConditionOp)
    def run_condition(
        self, _interpreter: Interpreter, op: scf.ConditionOp, args: PythonValues
    ) -> tuple[TerminatorValue, PythonValues]:
        return ReturnedValues(args), ()

    @impl(scf.WhileOp)
    def run_while(
        self, interpreter: Interpreter, op: scf.WhileOp, args: PythonValues
    ) -> PythonValues:
        loop_args = args

        while True:
            # while "before" region is terminated by an scf.condition op, of which `args[0]` is the i1 condition operand and
            # `args[1:]` are the values forwarded to the after-region (if the condition holds) or returned as the results of the
            # op (otherwise).
            condition, *forwarded_args = interpreter.run_ssacfg_region(
                op.before_region, loop_args, "while.before_region"
            )
            if not condition:
                return tuple(forwarded_args)

            loop_args = interpreter.run_ssacfg_region(
                op.after_region, tuple(forwarded_args), "while.after_region"
            )

    @impl(scf.IndexSwitchOp)
    def run_index_switch(
        self, interpreter: Interpreter, op: scf.IndexSwitchOp, args: PythonValues
    ) -> PythonValues:
        index = args[0]
        cases: tuple[int, ...] = op.cases.get_values()
        try:
            case = cases.index(index)
        except ValueError:
            return interpreter.run_ssacfg_region(
                op.default_region, (), "index_switch.case default"
            )

        return interpreter.run_ssacfg_region(
            op.case_regions[case], (), f"index_switch.case {case}"
        )

run_if(interpreter: Interpreter, op: scf.IfOp, args: PythonValues)

Source code in xdsl/interpreters/scf.py
@impl(scf.IfOp)
def run_if(self, interpreter: Interpreter, op: scf.IfOp, args: PythonValues):
    (cond,) = args
    region = op.true_region if cond else op.false_region
    results = interpreter.run_ssacfg_region(region, ())
    return results

run_for(interpreter: Interpreter, op: scf.ForOp, args: PythonValues) -> PythonValues

Source code in xdsl/interpreters/scf.py
@impl(scf.ForOp)
def run_for(
    self, interpreter: Interpreter, op: scf.ForOp, args: PythonValues
) -> PythonValues:
    lb, ub, step, *packed_args = args
    loop_args = tuple(packed_args)

    for i in range(lb, ub, step):
        loop_args = interpreter.run_ssacfg_region(
            op.body, (i, *loop_args), "for_loop"
        )

    return loop_args

run_br(_interpreter: Interpreter, op: scf.YieldOp, args: PythonValues) -> tuple[TerminatorValue, PythonValues]

Source code in xdsl/interpreters/scf.py
@impl_terminator(scf.YieldOp)
def run_br(
    self, _interpreter: Interpreter, op: scf.YieldOp, args: PythonValues
) -> tuple[TerminatorValue, PythonValues]:
    return ReturnedValues(args), ()

run_condition(_interpreter: Interpreter, op: scf.ConditionOp, args: PythonValues) -> tuple[TerminatorValue, PythonValues]

Source code in xdsl/interpreters/scf.py
@impl_terminator(scf.ConditionOp)
def run_condition(
    self, _interpreter: Interpreter, op: scf.ConditionOp, args: PythonValues
) -> tuple[TerminatorValue, PythonValues]:
    return ReturnedValues(args), ()

run_while(interpreter: Interpreter, op: scf.WhileOp, args: PythonValues) -> PythonValues

Source code in xdsl/interpreters/scf.py
@impl(scf.WhileOp)
def run_while(
    self, interpreter: Interpreter, op: scf.WhileOp, args: PythonValues
) -> PythonValues:
    loop_args = args

    while True:
        # while "before" region is terminated by an scf.condition op, of which `args[0]` is the i1 condition operand and
        # `args[1:]` are the values forwarded to the after-region (if the condition holds) or returned as the results of the
        # op (otherwise).
        condition, *forwarded_args = interpreter.run_ssacfg_region(
            op.before_region, loop_args, "while.before_region"
        )
        if not condition:
            return tuple(forwarded_args)

        loop_args = interpreter.run_ssacfg_region(
            op.after_region, tuple(forwarded_args), "while.after_region"
        )

run_index_switch(interpreter: Interpreter, op: scf.IndexSwitchOp, args: PythonValues) -> PythonValues

Source code in xdsl/interpreters/scf.py
@impl(scf.IndexSwitchOp)
def run_index_switch(
    self, interpreter: Interpreter, op: scf.IndexSwitchOp, args: PythonValues
) -> PythonValues:
    index = args[0]
    cases: tuple[int, ...] = op.cases.get_values()
    try:
        case = cases.index(index)
    except ValueError:
        return interpreter.run_ssacfg_region(
            op.default_region, (), "index_switch.case default"
        )

    return interpreter.run_ssacfg_region(
        op.case_regions[case], (), f"index_switch.case {case}"
    )