[llvm] [CGData] Declare command line options in TableGen, one struct per library (PR #226087)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 23:02:22 PDT 2026


================
@@ -1680,3 +1680,36 @@ TODO: complete this section
 :::{todo}
 TODO: fill in this section
 :::
+
+## Declaring a Library's Options in TableGen
+
+A library can declare its options in a `.td` file instead of as `cl::opt`
+globals. `llvm-tblgen -gen-opt-parser-defs` generates a struct with a member
+per option, the table that parses them, and the hooks through which
+`cl::ParseCommandLineOptions` parses them and `-help-hidden` lists them.
+
+```text
+include "llvm/Option/OptParser.td"
+
+def FooOptions : OptionsStruct;
+// The spellings of FooMode, a C++ enumeration declared elsewhere.
+def FooMode : OptionEnum<"FooMode", [EnumMember<"Fast", "fast">,
+                                     EnumMember<"Small", "small">]>;
+
+defm Enable : BoolField<"foo-enable", "1", "Enable foo">;
+defm Threshold : ValueField<"foo-threshold", "unsigned", "8", "The threshold">;
+defm Mode : EnumField<"foo-mode", FooMode, "FooMode::Fast", "Foo's mode">;
+```
+
+The `defm` name is the member name. A `BoolField` is set by `-x`, `-no-x`, or
+`-x=true|false|1|0`; a `ValueField` of an integer type, `double`,
+or `std::string` by `-x=value` or `-x value`. Both accept `--` for `-`.
+
+The header declares the struct after including what the member defaults need,
+and one source file defines it and registers it with `cl::`.
+
+The library then lists `XXOptionsTableGen` under `DEPENDS` and `Option`
+under `LINK_COMPONENTS`. Code reads `XXOptions::Global.CodeGenDataGenerate`,
+the instance the command line sets. Keep the header in `lib/`, as private as the
+`static cl::opt` it replaces; another library that needs a value calls a
----------------
MaskRay wrote:

I have surveyed cross-library cl::opt reads. They are rare and we can define accessor functions (with `LLVMContext &` as parameter) for them. `llvm/lib/XXX` private structs suffice for the majority of cl::opt options.

```
Private is far more common. On main, 43 of the 54 libraries that define cl::opts have no reader outside the library, so they'd get a private home like CGData.

┌──────────────────────────────────┬───────────┬─────────┬──────────────────────────────────────────────────┐
│                                  │ Libraries │ Options │            Options read from outside             │
├──────────────────────────────────┼───────────┼─────────┼──────────────────────────────────────────────────┤
│ No outside reader (private fits) │ 43        │ 1,361   │ 0                                                │
├──────────────────────────────────┼───────────┼─────────┼──────────────────────────────────────────────────┤
│ Some outside reader              │ 11        │ 1,451   │ ~53 via extern, plus 11 via cl::location globals │
└──────────────────────────────────┴───────────┴─────────┴──────────────────────────────────────────────────┘

The 11 "shared" libraries share only a handful of knobs each. They look big because they include the largest homes: CodeGen with 456 options, Transforms/Instrumentation 286, Transforms/IPO 207, Analysis 196, Transforms/Utils 116.

┌────────────────────────────┬─────────┬─────────────────────────────────────────────────────────────────────┐
│          Library           │ Options │                          Read from outside                          │
├────────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────┤
│ Analysis                   │ 196     │ 14 (e.g. ViewBlockFreqFuncName → CodeGen)                           │
├────────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────┤
│ Transforms/IPO             │ 207     │ 11 (e.g. ForceImportAll → LTO)                                      │
├────────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────┤
│ ProfileData                │ 24      │ 7 (ProfileSummaryCutoffHot and similar → Analysis)                  │
├────────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────┤
│ Transforms/Utils           │ 116     │ 6                                                                   │
├────────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────┤
│ Transforms/Instrumentation │ 286     │ 3                                                                   │
├────────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────┤
│ IR                         │ 41      │ 3                                                                   │
├────────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────┤
│ MC                         │ 30      │ 3 (→ DirectX)                                                       │
├────────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────┤
│ Target/X86                 │ 67      │ 2 (→ bolt)                                                          │
├────────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────┤
│ CGData                     │ 13      │ 2 (→ LTO, llvm-cgdata; exported through a function and a parameter) │
├────────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────┤
│ CodeGen                    │ 456     │ 1 (→ CodeGen/AsmPrinter)                                            │
├────────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────┤
│ Support                    │ 15      │ 1                                                                   │
└────────────────────────────┴─────────┴─────────────────────────────────────────────────────────────────────┘
```

https://github.com/llvm/llvm-project/pull/226087


More information about the llvm-commits mailing list