Rahul Joshi 22af0cd6f9
[LLVM][Intrinsics] Reduce stack size for Intrinsic::getAttributes (#152219)
This change fixes a stack size regression that got introduced in
0de0354aa8.
That change did 2 independent things:

1. Uniquify argument and function attributes separately so that we
generate a smaller number of unique sets as opposed to uniquifying them
together. This is beneficial for code size.
2. Eliminate the fixed size array `AS` and `NumAttrs` variable and
instead build the returned AttribteList in each case using an
initializer list.

The second part seems to have caused a regression in the stack size
usage of this function for Windows. This change essentially undoes part
2 and reinstates the use of the fixed size array `AS` which fixes this
stack size regression. The actual measured stack frame size for this
function before/after this change is as follows:

```
  Current trunk data for release build (x86_64 builds for Linux, x86 build for Windows):
  Compiler                              gcc-13.3.0      clang-18.1.3      MSVC 19.43.34810.0
  DLLVM_ENABLE_ASSERTIONS=OFF           0x120           0x110             0x54B0   
  DLLVM_ENABLE_ASSERTIONS=ON            0x2880          0x110             0x5250

  After applying the fix:
  Compiler                              gcc-13.3.0      clang-18.1.3      MSVC 19.43.34810.0
  DLLVM_ENABLE_ASSERTIONS=OFF           0x120           0x118             0x1240h                                               
  DLLVM_ENABLE_ASSERTIONS=ON            0x120           0x118             0x1240h  
```
Note that for Windows builds with assertions disabled, the stack frame
size for this function reduces from 21680 to 4672 which is a 4.6x
reduction. Stack frame size for GCC build with assertions also improved
and clang builds are unimpacted. The speculation is that clang and gcc
is able to reuse the stack space across these switch cases better with
existing code, but MSVC is not, and re-introducing the `AS` variable
forces all cases to use the same local variable, addressing the stack
space regression.
2025-08-06 07:09:52 -07:00
..

LLVM TableGen

The purpose of TableGen is to generate complex output files based on information from source files that are significantly easier to code than the output files would be, and also easier to maintain and modify over time.

The information is coded in a declarative style involving classes and records, which are then processed by TableGen.

class Hello <string _msg> {
  string msg = !strconcat("Hello ", _msg);
}

def HelloWorld: Hello<"world!"> {}
------------- Classes -----------------
class Hello<string Hello:_msg = ?> {
  string msg = !strconcat("Hello ", Hello:_msg);
}
------------- Defs -----------------
def HelloWorld {        // Hello
  string msg = "Hello world!";
}

Try this example on Compiler Explorer.

The internalized records are passed on to various backends, which extract information from a subset of the records and generate one or more output files.

These output files are typically .inc files for C++, but may be any type of file that the backend developer needs.

Resources for learning the language:

Writing TableGen backends:

TableGen in MLIR:

Useful tools: