[Beginner] Understanding Tablegen language

I am new to LLVM and I find TableGen language really cryptic. The reference manual to the language is not helpful either. I can look at the existing .td file and reverse engineer but I am looking for a detailed manual. Specifically, I have below questions:

  1. What is a basic syntax for writing a dag? From the lang ref manual I can see that its something like operator followed by ArgList which is enclosed in parentheses. Where does predicate fit in this picture? I don’t see any mention of predicates in lang ref manual. A DAG should have an operator, one or more return value and a bunch of arguments. Each of them would have a type. I am not sure how that maps to syntax provided by TableGen language. In TargetSelectionDAG.td I see (vt SDNode) in definition of ImmLeaf. Does that mean vt is return type of SDNode?

  2. Entity followed after “(” is always need to be an operator? or it can be ValueType or something else?

  3. What are keywords like “ins”, “outs” and “ops”? They are not mentioned in lang ref manual either.

  4. What is a “node” keyword?

  5. How are PatFrags used? I see some .td files I see, like X86InstrFMA.td, PatFrag MemFrag is passed as argument to multiclass and then used along with addr:$src3 in it. I really don’t understand what this means. Does this mean that whatever comes after PatFrag “object” is substituted as Args in PatFrag? e.g. TargetSelectionDAG defines

def not : PatFrag<(ops node:$in), (xor node:$in, -1)>; how do you visualize this?


BTech Student, VIT.

Part of the problem is that ISel patterns are like their own DSL inside the TableGen DSL, so keywords like “ins”, “outs”, and “ops” aren’t keywords at the TableGen level, but rather at the level of the ISel system implemented with TableGen. Copying existing patterns and reading the comments in Target.td and TargetSelectionDAG.td are the best ways I know of learning how this works. I haven’t seen a separate guide, although it would be very cool if one existed.

Concretely, a PatFrag is essentially just a macro for patterns. In your example, (ops node:$in) says that this pattern fragment takes a single argument called $in, which can be any other dag or dag operation. The right hand side (xor node:$in, -1) is what the pattern fragment expands to wherever it is used. So if I write a pattern that includes (not <some stuff>), that will expand to (xor <some stuff>, -1). “ops” here is just a marker operation (in the tablegen language sense, not in the instruction selection sense) to introduce the operands for the pattern fragment. If ISel were its own DSL rather than implemented on top of TableGen, this would probably have a more straightforward syntax (but then we’d have another separate DSL to deal with).

FWIW, there are also some third-party resources that may be of help:

"Lessons in TableGen"
FOSDEM 2019; Nicolai Hähnle
Slides: https://archive.fosdem.org/2019/schedule/event/llvm_tablegen/attachments/slides/3304/export/events/attachments/llvm_tablegen/slides/3304/tablegen.pdf

- What has TableGen ever done for us?: http://nhaehnle.blogspot.com/2018/02/tablegen-1-what-has-tablegen-ever-done.html
- Functional Programming: http://nhaehnle.blogspot.com/2018/02/tablegen-2-functional-programming.html
- Bits: http://nhaehnle.blogspot.com/2018/02/tablegen-3-bits.html
- Resolving variables: http://nhaehnle.blogspot.com/2018/03/tablegen-4-resolving-variables.html
- DAGs: http://nhaehnle.blogspot.com/2018/03/tablegen-5-dags.html

Some of the parts of TableGen used in SelectionDAG are in the backend docs (e.g., the keywords OP asked about):
& https://llvm.org/docs/WritingAnLLVMBackend.html#instruction-selector (has a simple example of `PatFrag` for `store`).

There are a few examples of simple .td files an LLVM backend in the following:

LLVM backend development by example (RISC-V)
2018 LLVM Developers’ Meeting; Alex Bradbury

2014 - Building an LLVM Backend - LLVM Developer's Meeting

llvm-leg: LEG Example Backend
LEG Example Backend: a simple example LLVM backend for an ARM-like architecture: 'LEG'.


Thanks Matt and Thomas. I will go through them.

Is there a backend to Tablegen which can dump a map of pattern-to-matched to instruction-to-be-generated?

–help doesn’t seem to indicate anything like that.

If you run tablgen with no arguments, it produces the fully expanded tablegen. You can directly view what ends up getting interpreted there


Adding -debug to a -gen-dag-isel run can also print useful information about the parsed patterns.

I use --print-records and then search for opcode name or pattern name and then look for “PatternToMatch” key. It is close to the map you’re looking for.

Thanks. -print-records is useful in addition to other tips.