Dynamic Jump table (original) (raw)

December 7, 2025, 3:49pm 1

Hi, I’m trying to model a dynamic jump table in MLIR. What I want is:

A pseudo-example of the intended IR:

hw.append_target ^b1
hw.append_target ^b2
hw.execute

^b1:
    // some code
    return

^b2:
// some code
    return

^b3:
// some code
    return

The difficulty I’m running into is:

I’m unsure what the right MLIR-idiomatic approach is for representing this kind of dynamic control-flow structure.

Does anyone have suggestions on how to model a dynamic jump table in MLIR?
Are there existing patterns or dialects that do something similar?

ftynse December 9, 2025, 1:00pm 2

I would suggest using multiple ops with single-block regions and symbol name and going through symbols for dispatch. This is a more flexible form of control flow.

Otherwise, you can look at how blockaddr is implemented in the LLVM dialect: 'llvm' Dialect - MLIR. It has a similar problem of needing a block as operand.

roiQM December 9, 2025, 1:44pm 3

My initial approach was the first option, but it would require using nested symbol tables for my IR. That sometimes feels “awkward” in MLIR, since SymbolTable methods don’t traverse into nested tables (If I understand correctly)

Thanks for you reply :folded_hands:

What about an operation with multiple-regions instead?

That said I’m not sure about how you’re doing the dispatch here, your snippet isn’t explicit enough to me.

roiQM December 9, 2025, 1:51pm 5

It simply dispatches an instruction address.
@mehdi_amini How would you reference a region?

ftynse December 9, 2025, 10:17pm 6

By its number… Ugly but works. Also works for blocks technically, but easier to break including by generic CFG simplifications that may, e.g., deduplicate identical regions.

ftynse December 10, 2025, 6:58am 7

Separately, adding support for traversing nested symbol tables would be a welcome addition upstream.

roiQM December 10, 2025, 3:13pm 8

I guess doing so you need to be careful to not break shadowing?

That comes down to a switch actually: 'scf' Dialect - MLIR

I don’t quite follow: can you write a snippet of IR showing what you want and what does not work?

roiQM December 10, 2025, 6:28pm 10

For example:

module {

    myDialect.opWithSymbolTable @opWithSymbolTable {

        myDialect.myOp @mySymbol(): () -> ()

        myDialect.nestedOpWithSymbolTable {

            myDialect.ref(@mySymbol) : () -> ()

        }

    }

}

Correct me if im wrong, but doing
symbolTable.rename(myOp, newSymbolname)

wont rename the reference
myDialect.ref(@mySymbol) : () -> ()
because its nested inside a symbol table.

Also the lookup method applied from ref would stop on the first symbol table and fail to find the declaration.
There may be some logic behind this behaviors and I’m not modeling my IR correctly.

Right, this is by design. You cannot access a parent symbol table, you can access nested ones.

Why would you need this for your “switch” though?

roiQM December 10, 2025, 7:06pm 12

I don’t, its “collateral damage” :slight_smile: . Choosing the symbol suggestion will make me add a symbol table to the parent op of the “switch”, and that in turn will cause me to need to access the parent symbol table.