[llvm] [Sparc] Declare command line options in TableGen (PR #227977)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 00:06:23 PDT 2026
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/227977
>From 2c97469812a543464613f4f2a872fbb8e4b4916b Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 30 Sep 2026 23:02:54 -0700
Subject: [PATCH 1/2] [Sparc] Declare command line options in TableGen
Move the cl::opts into SparcOptions.td. SparcSubtarget.h declares the
struct and SparcTargetMachine.cpp defines it. LLVMInitializeSparcTarget
registers the options, so they cost no static initializer.
SparcTargetMachine holds a reference to SparcOptions::Global, and
SparcSubtarget forwards it, so code reads Subtarget.getCLOpts() rather
than the global.
`OptionsStruct<prefix = "sparc-">` is new: it strips the shared prefix
from member names, so -sparc-bpcc-offset-bits sets bpcc_offset_bits.
Aided by Opus 5.5
---
llvm/docs/CommandLine.md | 1 +
llvm/include/llvm/Option/LibraryOptions.td | 6 +++-
llvm/lib/Target/Sparc/CMakeLists.txt | 4 +++
llvm/lib/Target/Sparc/DelaySlotFiller.cpp | 15 +++-----
llvm/lib/Target/Sparc/SparcFrameLowering.cpp | 10 ++----
llvm/lib/Target/Sparc/SparcInstrInfo.cpp | 12 ++-----
llvm/lib/Target/Sparc/SparcOptions.td | 24 +++++++++++++
llvm/lib/Target/Sparc/SparcRegisterInfo.cpp | 11 ++----
llvm/lib/Target/Sparc/SparcSubtarget.cpp | 5 ++-
llvm/lib/Target/Sparc/SparcSubtarget.h | 10 +++++-
llvm/lib/Target/Sparc/SparcTargetMachine.cpp | 12 ++++---
llvm/lib/Target/Sparc/SparcTargetMachine.h | 3 ++
llvm/unittests/Option/LibraryOptionsTest.cpp | 34 +++++++++----------
llvm/unittests/Option/LibraryOpts.td | 2 +-
llvm/utils/TableGen/OptionParserEmitter.cpp | 19 +++++++----
.../secondary/llvm/lib/Target/Sparc/BUILD.gn | 8 +++++
.../llvm-project-overlay/llvm/BUILD.bazel | 12 +++++++
17 files changed, 118 insertions(+), 70 deletions(-)
create mode 100644 llvm/lib/Target/Sparc/SparcOptions.td
diff --git a/llvm/docs/CommandLine.md b/llvm/docs/CommandLine.md
index 13ab4b48eb9b5..844339d106021 100644
--- a/llvm/docs/CommandLine.md
+++ b/llvm/docs/CommandLine.md
@@ -1582,6 +1582,7 @@ defm : ValueField<"foo-path", "StringRef", "\"-\"", "The input path">;
The struct is in namespace `llvm` unless the def names another, as in `OptionsStruct<"mlir">`.
A member is named after its option, `enable_foo` for `-enable-foo`; a named `defm` such as `defm threshold` names it `threshold`.
+`OptionsStruct<prefix = "foo-">` drops that prefix from member names, so `-foo-path` sets `path`.
The `BoolField` is set by `-enable-foo` or `-enable-foo=true|false|1|0`.
A `ValueField`, of an integer type, `double`, or `StringRef`, is set by `-foo-threshold=8` or `-foo-threshold 8`.
diff --git a/llvm/include/llvm/Option/LibraryOptions.td b/llvm/include/llvm/Option/LibraryOptions.td
index 5f600a0a8e0ed..52af2a49c13d1 100644
--- a/llvm/include/llvm/Option/LibraryOptions.td
+++ b/llvm/include/llvm/Option/LibraryOptions.td
@@ -16,7 +16,11 @@
include "llvm/Option/OptParser.td"
-class OptionsStruct<string namespace = "llvm"> { string Namespace = namespace; }
+// A row whose spelling starts with prefix names its member without it.
+class OptionsStruct<string namespace = "llvm", string prefix = ""> {
+ string Namespace = namespace;
+ string MemberPrefix = prefix;
+}
// The member a row sets, the member's type and default value, and the value a
// Flag assigns. Other kinds parse their argument.
diff --git a/llvm/lib/Target/Sparc/CMakeLists.txt b/llvm/lib/Target/Sparc/CMakeLists.txt
index 5db9dbf623858..c915add38dcf2 100644
--- a/llvm/lib/Target/Sparc/CMakeLists.txt
+++ b/llvm/lib/Target/Sparc/CMakeLists.txt
@@ -14,6 +14,9 @@ tablegen(LLVM SparcGenSDNodeInfo.inc -gen-sd-node-info -sdnode-namespace=SPISD)
tablegen(LLVM SparcGenSearchableTables.inc -gen-searchable-tables)
tablegen(LLVM SparcGenSubtargetInfo.inc -gen-subtarget)
+set(LLVM_TARGET_DEFINITIONS SparcOptions.td)
+tablegen(LLVM SparcOptions.inc -gen-opt-parser-defs)
+
add_public_tablegen_target(SparcCommonTableGen)
add_llvm_target(SparcCodeGen
@@ -39,6 +42,7 @@ add_llvm_target(SparcCodeGen
CodeGenTypes
Core
MC
+ Option
SelectionDAG
SparcDesc
SparcInfo
diff --git a/llvm/lib/Target/Sparc/DelaySlotFiller.cpp b/llvm/lib/Target/Sparc/DelaySlotFiller.cpp
index c60b78fcecaf5..b5ae70ee36cac 100644
--- a/llvm/lib/Target/Sparc/DelaySlotFiller.cpp
+++ b/llvm/lib/Target/Sparc/DelaySlotFiller.cpp
@@ -20,7 +20,6 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/Support/CommandLine.h"
using namespace llvm;
@@ -28,12 +27,6 @@ using namespace llvm;
STATISTIC(FilledSlots, "Number of delay slots filled");
-static cl::opt<bool> DisableDelaySlotFiller(
- "disable-sparc-delay-filler",
- cl::init(false),
- cl::desc("Disable the Sparc delay slot filler."),
- cl::Hidden);
-
namespace {
struct Filler : public MachineFunctionPass {
const SparcSubtarget *Subtarget = nullptr;
@@ -108,9 +101,9 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
++I;
// If MI is restore, try combining it with previous inst.
- if (!DisableDelaySlotFiller &&
- (MI->getOpcode() == SP::RESTORErr
- || MI->getOpcode() == SP::RESTOREri)) {
+ if (!Subtarget->getCLOpts().disable_sparc_delay_filler &&
+ (MI->getOpcode() == SP::RESTORErr ||
+ MI->getOpcode() == SP::RESTOREri)) {
Changed |= tryCombineRestoreWithPrevInst(MBB, MI);
continue;
}
@@ -131,7 +124,7 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
MachineBasicBlock::iterator D = MBB.end();
- if (!DisableDelaySlotFiller)
+ if (!Subtarget->getCLOpts().disable_sparc_delay_filler)
D = findDelayInstr(MBB, MI);
++FilledSlots;
diff --git a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
index deb9b2026baaa..ab9192310d4e9 100644
--- a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
@@ -20,16 +20,9 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Support/CommandLine.h"
using namespace llvm;
-static cl::opt<bool>
-DisableLeafProc("disable-sparc-leaf-proc",
- cl::init(false),
- cl::desc("Disable Sparc leaf procedure optimization."),
- cl::Hidden);
-
SparcFrameLowering::SparcFrameLowering(const SparcSubtarget &ST)
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown,
ST.is64Bit() ? Align(16) : Align(8), 0,
@@ -317,7 +310,8 @@ void SparcFrameLowering::determineCalleeSaves(MachineFunction &MF,
BitVector &SavedRegs,
RegScavenger *RS) const {
TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
- if (!DisableLeafProc && isLeafProc(MF)) {
+ const SparcSubtarget &Subtarget = MF.getSubtarget<SparcSubtarget>();
+ if (!Subtarget.getCLOpts().disable_sparc_leaf_proc && isLeafProc(MF)) {
SparcMachineFunctionInfo *MFI = MF.getInfo<SparcMachineFunctionInfo>();
MFI->setLeafProc(true);
diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.cpp b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp
index 0a7ce19bf4f51..9f846b7a49373 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.cpp
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp
@@ -26,14 +26,6 @@ using namespace llvm;
#define GET_INSTRINFO_CTOR_DTOR
#include "SparcGenInstrInfo.inc"
-static cl::opt<unsigned> BPccDisplacementBits(
- "sparc-bpcc-offset-bits", cl::Hidden, cl::init(19),
- cl::desc("Restrict range of BPcc/FBPfcc instructions (DEBUG)"));
-
-static cl::opt<unsigned>
- BPrDisplacementBits("sparc-bpr-offset-bits", cl::Hidden, cl::init(16),
- cl::desc("Restrict range of BPr instructions (DEBUG)"));
-
// Pin the vtable to this file.
void SparcInstrInfo::anchor() {}
@@ -458,13 +450,13 @@ bool SparcInstrInfo::isBranchOffsetInRange(unsigned BranchOpc,
case SP::BPFCCANT:
case SP::FBCOND_V9:
case SP::FBCONDA_V9:
- return isIntN(BPccDisplacementBits, Offset >> 2);
+ return isIntN(Subtarget.getCLOpts().bpcc_offset_bits, Offset >> 2);
case SP::BPR:
case SP::BPRA:
case SP::BPRNT:
case SP::BPRANT:
- return isIntN(BPrDisplacementBits, Offset >> 2);
+ return isIntN(Subtarget.getCLOpts().bpr_offset_bits, Offset >> 2);
}
llvm_unreachable("Unknown branch instruction!");
diff --git a/llvm/lib/Target/Sparc/SparcOptions.td b/llvm/lib/Target/Sparc/SparcOptions.td
new file mode 100644
index 0000000000000..8d02271270e8e
--- /dev/null
+++ b/llvm/lib/Target/Sparc/SparcOptions.td
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/Option/LibraryOptions.td"
+
+def SparcOptions : OptionsStruct<prefix = "sparc-">;
+
+defm : BoolField<"disable-sparc-delay-filler", "false",
+ "Disable the Sparc delay slot filler">;
+defm : BoolField<"disable-sparc-leaf-proc", "false",
+ "Disable Sparc leaf procedure optimization">;
+defm : ValueField<"sparc-bpcc-offset-bits", "unsigned", "19",
+ "Restrict range of BPcc/FBPfcc instructions (DEBUG)">;
+defm : ValueField<"sparc-bpr-offset-bits", "unsigned", "16",
+ "Restrict range of BPr instructions (DEBUG)">;
+defm : BoolField<"sparc-enable-branch-relax", "true",
+ "Relax out of range conditional branches">;
+defm : BoolField<"sparc-reserve-app-registers", "false",
+ "Reserve application registers (%g2-%g4)">;
diff --git a/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp b/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
index 5c2af0aa55b2c..93b329a0d5bad 100644
--- a/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
+++ b/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
@@ -19,7 +19,6 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/IR/Type.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
@@ -27,10 +26,6 @@ using namespace llvm;
#define GET_REGINFO_TARGET_DESC
#include "SparcGenRegisterInfo.inc"
-static cl::opt<bool>
-ReserveAppRegisters("sparc-reserve-app-registers", cl::Hidden, cl::init(false),
- cl::desc("Reserve application registers (%g2-%g4)"));
-
SparcRegisterInfo::SparcRegisterInfo(const SparcSubtarget &STI)
: SparcGenRegisterInfo(SP::O7), Is64Bit(STI.is64Bit()) {}
@@ -57,7 +52,7 @@ BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
Reserved.set(SP::G1);
// G1-G4 can be used in applications.
- if (ReserveAppRegisters) {
+ if (Subtarget.getCLOpts().reserve_app_registers) {
Reserved.set(SP::G2);
Reserved.set(SP::G3);
Reserved.set(SP::G4);
@@ -76,9 +71,9 @@ BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
// Also reserve the register pair aliases covering the above
// registers, with the same conditions.
Reserved.set(SP::G0_G1);
- if (ReserveAppRegisters)
+ if (Subtarget.getCLOpts().reserve_app_registers)
Reserved.set(SP::G2_G3);
- if (ReserveAppRegisters || !Subtarget.is64Bit())
+ if (Subtarget.getCLOpts().reserve_app_registers || !Subtarget.is64Bit())
Reserved.set(SP::G4_G5);
Reserved.set(SP::O6_O7);
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
index 03183e1c4fad1..e320c1a79e784 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
@@ -12,6 +12,7 @@
#include "SparcSubtarget.h"
#include "SparcSelectionDAGInfo.h"
+#include "SparcTargetMachine.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/MathExtras.h"
@@ -54,8 +55,10 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(
}
SparcSubtarget::SparcSubtarget(const StringRef &CPU, const StringRef &TuneCPU,
- const StringRef &FS, const TargetMachine &TM)
+ const StringRef &FS,
+ const SparcTargetMachine &TM)
: SparcGenSubtargetInfo(TM.getTargetTriple(), CPU, TuneCPU, FS),
+ CLOpts(TM.getCLOpts()),
ReserveRegister(TM.getMCRegisterInfo().getNumRegs()),
InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
TLInfo(TM, *this), FrameLowering(*this) {
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.h b/llvm/lib/Target/Sparc/SparcSubtarget.h
index 02d56eb8f3000..b99f771871008 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.h
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.h
@@ -22,13 +22,19 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/TargetParser/Triple.h"
+#define OPTIONS_STRUCT_DECL
+#include "SparcOptions.inc"
+
#define GET_SUBTARGETINFO_HEADER
#include "SparcGenSubtargetInfo.inc"
namespace llvm {
+class SparcTargetMachine;
class StringRef;
class SparcSubtarget : public SparcGenSubtargetInfo {
+ const SparcOptions &CLOpts;
+
// ReserveRegister[i] - Register #i is not available as a general purpose
// register.
BitVector ReserveRegister;
@@ -46,10 +52,12 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
public:
SparcSubtarget(const StringRef &CPU, const StringRef &TuneCPU,
- const StringRef &FS, const TargetMachine &TM);
+ const StringRef &FS, const SparcTargetMachine &TM);
~SparcSubtarget() override;
+ const SparcOptions &getCLOpts() const { return CLOpts; }
+
const SparcInstrInfo *getInstrInfo() const override { return &InstrInfo; }
const TargetFrameLowering *getFrameLowering() const override {
return &FrameLowering;
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
index 849448c286b47..0588bb4a90b04 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -19,15 +19,20 @@
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Option/LibraryOptions.h"
#include "llvm/Support/Compiler.h"
#include <optional>
using namespace llvm;
+#define OPTIONS_STRUCT_DEFS
+#include "SparcOptions.inc"
+
extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcTarget() {
// Register the target.
RegisterTargetMachine<SparcV8TargetMachine> X(getTheSparcTarget());
RegisterTargetMachine<SparcV9TargetMachine> Y(getTheSparcV9Target());
RegisterTargetMachine<SparcelTargetMachine> Z(getTheSparcelTarget());
+ static opt::RegisterLibraryOptions<SparcOptions> O;
PassRegistry &PR = *PassRegistry::getPassRegistry();
initializeSparcAsmPrinterPass(PR);
@@ -35,10 +40,6 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcTarget() {
initializeErrataWorkaroundPass(PR);
}
-static cl::opt<bool>
- BranchRelaxation("sparc-enable-branch-relax", cl::Hidden, cl::init(true),
- cl::desc("Relax out of range conditional branches"));
-
static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
return RM.value_or(Reloc::Static);
}
@@ -83,6 +84,7 @@ SparcTargetMachine::SparcTargetMachine(const Target &T, const Triple &TT,
getEffectiveSparcCodeModel(CM, getEffectiveRelocModel(RM),
TT.isSPARC64(), JIT),
OL),
+ CLOpts(SparcOptions::Global),
TLOF(std::make_unique<SparcELFTargetObjectFile>()) {
initAsmInfo();
}
@@ -161,7 +163,7 @@ bool SparcPassConfig::addInstSelector() {
}
void SparcPassConfig::addPreEmitPass(){
- if (BranchRelaxation)
+ if (getSparcTargetMachine().getCLOpts().enable_branch_relax)
addPass(&BranchRelaxationPassID);
addPass(createSparcDelaySlotFillerPass());
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.h b/llvm/lib/Target/Sparc/SparcTargetMachine.h
index 2fbfd397325b6..28b4cb24e2242 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.h
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.h
@@ -22,6 +22,7 @@
namespace llvm {
class SparcTargetMachine : public CodeGenTargetMachineImpl {
+ const SparcOptions &CLOpts;
std::unique_ptr<TargetLoweringObjectFile> TLOF;
mutable StringMap<std::unique_ptr<SparcSubtarget>> SubtargetMap;
@@ -33,6 +34,8 @@ class SparcTargetMachine : public CodeGenTargetMachineImpl {
bool JIT);
~SparcTargetMachine() override;
+ const SparcOptions &getCLOpts() const { return CLOpts; }
+
const SparcSubtarget *getSubtargetImpl(const Function &F) const override;
// Pass Pipeline Configuration
diff --git a/llvm/unittests/Option/LibraryOptionsTest.cpp b/llvm/unittests/Option/LibraryOptionsTest.cpp
index 4e32caf953f6b..f13147b9feab5 100644
--- a/llvm/unittests/Option/LibraryOptionsTest.cpp
+++ b/llvm/unittests/Option/LibraryOptionsTest.cpp
@@ -25,9 +25,9 @@ namespace {
// The struct -gen-opt-parser-defs generates: every spelling sets its member.
TEST(LibraryOptionsTest, Apply) {
TestLibraryOptions O;
- EXPECT_FALSE(O.lib_enable);
- EXPECT_EQ(O.lib_count, 3u);
- EXPECT_EQ(O.lib_ratio, 0.5);
+ EXPECT_FALSE(O.enable);
+ EXPECT_EQ(O.count, 3u);
+ EXPECT_EQ(O.ratio, 0.5);
EXPECT_EQ(O.Path, "p");
auto Apply = [&](std::initializer_list<const char *> Argv) {
@@ -42,21 +42,21 @@ TEST(LibraryOptionsTest, Apply) {
EXPECT_THAT(Apply({"-lib-enable", "--lib-count=7", "-lib-ratio", "0.25",
"-lib-path=a=b"}),
testing::Each(true));
- EXPECT_TRUE(O.lib_enable);
- EXPECT_EQ(O.lib_count, 7u);
- EXPECT_EQ(O.lib_ratio, 0.25);
+ EXPECT_TRUE(O.enable);
+ EXPECT_EQ(O.count, 7u);
+ EXPECT_EQ(O.ratio, 0.25);
EXPECT_EQ(O.Path, "a=b");
EXPECT_THAT(Apply({"-lib-enable=false"}), testing::Each(true));
- EXPECT_FALSE(O.lib_enable);
+ EXPECT_FALSE(O.enable);
EXPECT_THAT(Apply({"-lib-enable=1"}), testing::Each(true));
- EXPECT_TRUE(O.lib_enable);
+ EXPECT_TRUE(O.enable);
// A rejected value leaves the member unchanged.
EXPECT_THAT(Apply({"-lib-enable=2", "-lib-count=-1", "-lib-ratio=y"}),
testing::Each(false));
- EXPECT_TRUE(O.lib_enable);
- EXPECT_EQ(O.lib_count, 7u);
- EXPECT_EQ(O.lib_ratio, 0.25);
+ EXPECT_TRUE(O.enable);
+ EXPECT_EQ(O.count, 7u);
+ EXPECT_EQ(O.ratio, 0.25);
}
// What cl:: sees of the struct, without cl::.
@@ -82,14 +82,14 @@ TEST(LibraryOptionsTest, Parser) {
return std::to_string(Consumed) + " " + Err;
};
EXPECT_EQ(Parse({"-lib-count", "5"}), "2 ");
- EXPECT_EQ(TestLibraryOptions::Global.lib_count, 5u);
+ EXPECT_EQ(TestLibraryOptions::Global.count, 5u);
EXPECT_EQ(Parse({"-lib-count=x", "-lib-enable"}),
"1 invalid value 'x' in '-lib-count=x'");
EXPECT_EQ(Parse({"-lib-count"}),
"1 option '-lib-count' requires an argument");
EXPECT_EQ(Parse({"-lib-other"}), "1 unknown argument '-lib-other'");
P.reset();
- EXPECT_EQ(TestLibraryOptions::Global.lib_count, 3u);
+ EXPECT_EQ(TestLibraryOptions::Global.count, 3u);
}
// A static RegisterLibraryOptions connects the struct's Global to cl::.
@@ -100,14 +100,14 @@ TEST(LibraryOptionsTest, Register) {
std::string Path = "-lib-path=q";
const char *Args[] = {"prog", "-lib-count", "5", "-lib-enable", Path.c_str()};
EXPECT_TRUE(cl::ParseCommandLineOptions(std::size(Args), Args, "", &nulls()));
- EXPECT_EQ(G.lib_count, 5u);
- EXPECT_TRUE(G.lib_enable);
+ EXPECT_EQ(G.count, 5u);
+ EXPECT_TRUE(G.enable);
// A StringRef member does not refer to the caller's argument.
Path.assign(Path.size(), 'x');
EXPECT_EQ(G.Path, "q");
cl::ResetAllOptionOccurrences();
- EXPECT_EQ(G.lib_count, 3u);
- EXPECT_FALSE(G.lib_enable);
+ EXPECT_EQ(G.count, 3u);
+ EXPECT_FALSE(G.enable);
EXPECT_EQ(G.Path, "p");
cl::ResetCommandLineParser();
}
diff --git a/llvm/unittests/Option/LibraryOpts.td b/llvm/unittests/Option/LibraryOpts.td
index 1afdda1adcb41..bee1462651db1 100644
--- a/llvm/unittests/Option/LibraryOpts.td
+++ b/llvm/unittests/Option/LibraryOpts.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def TestLibraryOptions : OptionsStruct<"test">;
+def TestLibraryOptions : OptionsStruct<"test", prefix = "lib-">;
defm : BoolField<"lib-enable", "0", "A bool">;
defm : ValueField<"lib-count", "unsigned", "3", "An unsigned">;
diff --git a/llvm/utils/TableGen/OptionParserEmitter.cpp b/llvm/utils/TableGen/OptionParserEmitter.cpp
index a41ddd5872ed7..06f883e0ada71 100644
--- a/llvm/utils/TableGen/OptionParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptionParserEmitter.cpp
@@ -230,9 +230,12 @@ static MarshallingInfo createMarshallingInfo(const Record &R) {
return Ret;
}
-// -foo-bar and -foo-bar= become foo_bar.
-static std::string getSpellingIdentifier(const Record &R) {
- std::string ID = R.getValueAsString("Name").rtrim('=').str();
+// -foo-bar and -foo-bar= become foo_bar, or bar if Prefix is "foo-".
+static std::string getSpellingIdentifier(const Record &R,
+ StringRef Prefix = "") {
+ StringRef Spelling = R.getValueAsString("Name").rtrim('=');
+ Spelling.consume_front(Prefix);
+ std::string ID = Spelling.str();
llvm::replace(ID, '-', '_');
if (ID.empty() || isDigit(ID[0]) ||
!all_of(ID, [](char C) { return isAlnum(C) || C == '_'; }))
@@ -243,9 +246,10 @@ static std::string getSpellingIdentifier(const Record &R) {
// `defm : BoolField<"foo-bar", ...>` declares member foo_bar, and a named defm
// names it.
-static std::string getMemberName(const Record &R) {
+static std::string getMemberName(const Record &R, StringRef Prefix) {
StringRef Name = R.getValueAsString("FieldName");
- return Name.starts_with("anonymous_") ? getSpellingIdentifier(R) : Name.str();
+ return Name.starts_with("anonymous_") ? getSpellingIdentifier(R, Prefix)
+ : Name.str();
}
// The OPT_ name of an option of an OptionsStruct. `defm :` rows are named
@@ -291,10 +295,11 @@ static void emitOptionsStruct(const Record &Struct,
llvm::sort(ByID, [](const Record *A, const Record *B) {
return A->getID() < B->getID();
});
+ StringRef Prefix = Struct.getValueAsString("MemberPrefix");
std::vector<Member> Members;
StringMap<unsigned> MemberIndex;
for (const Record *R : ByID) {
- Member M{getMemberName(*R), R->getValueAsString("FieldType"),
+ Member M{getMemberName(*R, Prefix), R->getValueAsString("FieldType"),
R->getValueAsString("FieldDefault"),
R->getValueAsString("Name").rtrim('=')};
auto [It, Inserted] = MemberIndex.try_emplace(M.Name, Members.size());
@@ -346,7 +351,7 @@ static void emitOptionsStruct(const Record &Struct,
OS << " switch (A.getOption().getID()) {\n";
for (const Record *R : Fields) {
OS << " case OPT_" << getStructOptionID(*R) << ":\n";
- std::string Member = getMemberName(*R);
+ std::string Member = getMemberName(*R, Prefix);
if (!R->getValue("FieldValue"))
OS << " return llvm::opt::parseArgValue(A.getValue(), " << Member
<< ");\n";
diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/Sparc/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/Sparc/BUILD.gn
index e39c4ad3b318a..5c8a4ebaa07e0 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Target/Sparc/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Target/Sparc/BUILD.gn
@@ -21,11 +21,18 @@ tablegen("SparcGenSDNodeInfo") {
td_file = "Sparc.td"
}
+tablegen("SparcOptions") {
+ visibility = [ ":LLVMSparcCodeGen" ]
+ args = [ "-gen-opt-parser-defs" ]
+ td_file = "SparcOptions.td"
+}
+
static_library("LLVMSparcCodeGen") {
deps = [
":SparcGenCallingConv",
":SparcGenDAGISel",
":SparcGenSDNodeInfo",
+ ":SparcOptions",
"MCTargetDesc",
"TargetInfo",
"//llvm/include/llvm/Config:llvm-config",
@@ -34,6 +41,7 @@ static_library("LLVMSparcCodeGen") {
"//llvm/lib/CodeGen/SelectionDAG",
"//llvm/lib/IR",
"//llvm/lib/MC",
+ "//llvm/lib/Option",
"//llvm/lib/Support",
"//llvm/lib/Target",
"//llvm/lib/TargetParser",
diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
index 797d128f9e29b..d7f699c9bf80f 100644
--- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
@@ -3384,6 +3384,9 @@ llvm_target_lib_list = [lib for lib in [
"lib/Target/Sparc/SparcGenSDNodeInfo.inc",
),
],
+ "tbl_deps": [
+ ":SparcOptionsTableGen",
+ ],
},
{
"name": "SPIRV",
@@ -3921,6 +3924,15 @@ gentbl_cc_library(
],
)
+gentbl_cc_library(
+ name = "SparcOptionsTableGen",
+ strip_include_prefix = "lib/Target/Sparc",
+ tbl_outs = {"lib/Target/Sparc/SparcOptions.inc": ["-gen-opt-parser-defs"]},
+ tblgen = ":llvm-tblgen",
+ td_file = "lib/Target/Sparc/SparcOptions.td",
+ deps = [":OptParserTdFiles"],
+)
+
gentbl_cc_library(
name = "webassembly_isel_target_gen",
strip_include_prefix = "lib/Target/WebAssembly",
>From 1485e0022723e673b99af306b1d031c404a2fc14 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Thu, 1 Oct 2026 00:06:07 -0700
Subject: [PATCH 2/2] SparcSubtarget for home; fix clang-format
---
llvm/lib/Target/Sparc/SparcFrameLowering.cpp | 1 -
llvm/lib/Target/Sparc/SparcSubtarget.cpp | 4 ++++
llvm/lib/Target/Sparc/SparcTargetMachine.cpp | 3 ---
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
index ab9192310d4e9..53e6523aee4e1 100644
--- a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
@@ -317,5 +317,4 @@ void SparcFrameLowering::determineCalleeSaves(MachineFunction &MF,
remapRegsForLeafProc(MF);
}
-
}
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
index e320c1a79e784..a79a8f0272a32 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
@@ -15,6 +15,7 @@
#include "SparcTargetMachine.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Option/LibraryOptions.h"
#include "llvm/Support/MathExtras.h"
using namespace llvm;
@@ -25,6 +26,9 @@ using namespace llvm;
#define GET_SUBTARGETINFO_CTOR
#include "SparcGenSubtargetInfo.inc"
+#define OPTIONS_STRUCT_DEFS
+#include "SparcOptions.inc"
+
void SparcSubtarget::anchor() { }
SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
index 0588bb4a90b04..0fa50b3d45ea7 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -24,9 +24,6 @@
#include <optional>
using namespace llvm;
-#define OPTIONS_STRUCT_DEFS
-#include "SparcOptions.inc"
-
extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcTarget() {
// Register the target.
RegisterTargetMachine<SparcV8TargetMachine> X(getTheSparcTarget());
More information about the llvm-commits
mailing list