From f9307a0f1040937cc7b11b43d10505c87bcb1d4a Mon Sep 17 00:00:00 2001 From: AdityaK Date: Fri, 26 Jul 2024 14:22:40 -0700 Subject: [PATCH] Use TargetABI to assign default-target features in getDefaultSubtargetFeatures It is currently not possible to provide any reasonable target-features for compiler generated functions (See: #69780) Having a target-abi will provide a way to add minimal requirements for target-features like `+d` for RISC-V. --- .../llvm/LTO/legacy/ThinLTOCodeGenerator.h | 2 +- .../llvm/TargetParser/SubtargetFeature.h | 3 ++- .../llvm/Transforms/Utils/ModuleUtils.h | 3 +++ llvm/lib/LTO/LTOBackend.cpp | 4 +++- llvm/lib/LTO/LTOCodeGenerator.cpp | 3 ++- llvm/lib/LTO/LTOModule.cpp | 3 ++- llvm/lib/LTO/ThinLTOCodeGenerator.cpp | 21 ++++++++++++------- llvm/lib/TargetParser/SubtargetFeature.cpp | 5 ++++- llvm/lib/Transforms/Utils/ModuleUtils.cpp | 8 +++++++ 9 files changed, 38 insertions(+), 14 deletions(-) diff --git a/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h b/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h index 7eb30d56e10c10..4ab1ca274dcd95 100644 --- a/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h +++ b/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h @@ -40,7 +40,7 @@ struct TargetMachineBuilder { std::optional RelocModel; CodeGenOptLevel CGOptLevel = CodeGenOptLevel::Aggressive; - std::unique_ptr create() const; + std::unique_ptr create(const StringRef TargetABI) const; }; /// This class define an interface similar to the LTOCodeGenerator, but adapted diff --git a/llvm/include/llvm/TargetParser/SubtargetFeature.h b/llvm/include/llvm/TargetParser/SubtargetFeature.h index 2e1f00dad2df36..24d911a469627a 100644 --- a/llvm/include/llvm/TargetParser/SubtargetFeature.h +++ b/llvm/include/llvm/TargetParser/SubtargetFeature.h @@ -195,7 +195,8 @@ class SubtargetFeatures { void dump() const; /// Adds the default features for the specified target triple. - void getDefaultSubtargetFeatures(const Triple& Triple); + void getDefaultSubtargetFeatures(const Triple &Triple, + const StringRef ABIInfo); /// Determine if a feature has a flag; '+' or '-' static bool hasFlag(StringRef Feature) { diff --git a/llvm/include/llvm/Transforms/Utils/ModuleUtils.h b/llvm/include/llvm/Transforms/Utils/ModuleUtils.h index 2a52d3ed1431e5..9b7d3554414bcc 100644 --- a/llvm/include/llvm/Transforms/Utils/ModuleUtils.h +++ b/llvm/include/llvm/Transforms/Utils/ModuleUtils.h @@ -97,6 +97,9 @@ void appendToUsed(Module &M, ArrayRef Values); /// Adds global values to the llvm.compiler.used list. void appendToCompilerUsed(Module &M, ArrayRef Values); +/// Returns the TargetABI Metadata if present, empty StringRef otherwise. +StringRef getTargetABIMD(Module &M); + /// Removes global values from the llvm.used and llvm.compiler.used arrays. \p /// ShouldRemove should return true for any initializer field that should not be /// included in the replacement global. diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index 4e58cd369c3ac9..1473769dd6b647 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -201,7 +201,9 @@ static std::unique_ptr createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) { StringRef TheTriple = M.getTargetTriple(); SubtargetFeatures Features; - Features.getDefaultSubtargetFeatures(Triple(TheTriple)); + StringRef TargetABI = llvm::getTargetABIMD(M); + + Features.getDefaultSubtargetFeatures(Triple(TheTriple), TargetABI); for (const std::string &A : Conf.MAttrs) Features.AddFeature(A); diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp index a192392e045851..03f437f207cd27 100644 --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -402,7 +402,8 @@ bool LTOCodeGenerator::determineTarget() { // Construct LTOModule, hand over ownership of module and target. Use MAttr as // the default set of features. SubtargetFeatures Features(join(Config.MAttrs, "")); - Features.getDefaultSubtargetFeatures(Triple); + StringRef TargetABI = llvm::getTargetABIMD(*MergedModule); + Features.getDefaultSubtargetFeatures(Triple, TargetABI); FeatureStr = Features.getString(); if (Config.CPU.empty()) Config.CPU = lto::getThinLTODefaultCPU(Triple); diff --git a/llvm/lib/LTO/LTOModule.cpp b/llvm/lib/LTO/LTOModule.cpp index eac78069f4d2bc..1c55a32a1fbf75 100644 --- a/llvm/lib/LTO/LTOModule.cpp +++ b/llvm/lib/LTO/LTOModule.cpp @@ -204,6 +204,7 @@ LTOModule::makeLTOModule(MemoryBufferRef Buffer, const TargetOptions &options, if (TripleStr.empty()) TripleStr = sys::getDefaultTargetTriple(); llvm::Triple Triple(TripleStr); + StringRef TargetABI = llvm::getTargetABIMD(*M); // find machine architecture for this module std::string errMsg; @@ -213,7 +214,7 @@ LTOModule::makeLTOModule(MemoryBufferRef Buffer, const TargetOptions &options, // construct LTOModule, hand over ownership of module and target SubtargetFeatures Features; - Features.getDefaultSubtargetFeatures(Triple); + Features.getDefaultSubtargetFeatures(Triple, TargetABI); std::string FeatureStr = Features.getString(); // Set a default CPU for Darwin triples. std::string CPU; diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp index 9d5a62fe10c8d7..7cedab078d2de1 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -60,6 +60,7 @@ #include "llvm/Transforms/IPO/Internalize.h" #include "llvm/Transforms/IPO/WholeProgramDevirt.h" #include "llvm/Transforms/ObjCARC.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" #include "llvm/Transforms/Utils/FunctionImportUtils.h" #include @@ -578,7 +579,8 @@ void ThinLTOCodeGenerator::crossReferenceSymbol(StringRef Name) { } // TargetMachine factory -std::unique_ptr TargetMachineBuilder::create() const { +std::unique_ptr +TargetMachineBuilder::create(const StringRef TargetABI) const { std::string ErrMsg; const Target *TheTarget = TargetRegistry::lookupTarget(TheTriple.str(), ErrMsg); @@ -588,7 +590,7 @@ std::unique_ptr TargetMachineBuilder::create() const { // Use MAttr as the default set of features. SubtargetFeatures Features(MAttr); - Features.getDefaultSubtargetFeatures(TheTriple); + Features.getDefaultSubtargetFeatures(TheTriple, TargetABI); std::string FeatureStr = Features.getString(); std::unique_ptr TM( @@ -914,10 +916,10 @@ void ThinLTOCodeGenerator::internalize(Module &TheModule, */ void ThinLTOCodeGenerator::optimize(Module &TheModule) { initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple())); - + StringRef TargetABI = llvm::getTargetABIMD(TheModule); // Optimize now - optimizeModule(TheModule, *TMBuilder.create(), OptLevel, Freestanding, - DebugPassManager, nullptr); + optimizeModule(TheModule, *TMBuilder.create(TargetABI), OptLevel, + Freestanding, DebugPassManager, nullptr); } /// Write out the generated object file, either from CacheEntryPath or from @@ -992,8 +994,10 @@ void ThinLTOCodeGenerator::run() { auto TheModule = loadModuleFromInput(Mod.get(), Context, false, /*IsImporting*/ false); + StringRef TargetABI = llvm::getTargetABIMD(*TheModule); // CodeGen - auto OutputBuffer = codegenModule(*TheModule, *TMBuilder.create()); + auto OutputBuffer = + codegenModule(*TheModule, *TMBuilder.create(TargetABI)); if (SavedObjectsDirectoryPath.empty()) ProducedBinaries[count] = std::move(OutputBuffer); else @@ -1181,10 +1185,11 @@ void ThinLTOCodeGenerator::run() { saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc"); auto &ImportList = ImportLists[ModuleIdentifier]; + StringRef TargetABI = llvm::getTargetABIMD(*TheModule); // Run the main process now, and generates a binary auto OutputBuffer = ProcessThinLTOModule( - *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList, - ExportList, GUIDPreservedSymbols, + *TheModule, *Index, ModuleMap, *TMBuilder.create(TargetABI), + ImportList, ExportList, GUIDPreservedSymbols, ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions, DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count, DebugPassManager); diff --git a/llvm/lib/TargetParser/SubtargetFeature.cpp b/llvm/lib/TargetParser/SubtargetFeature.cpp index 2c51c403c19349..a1cdcc0acdf197 100644 --- a/llvm/lib/TargetParser/SubtargetFeature.cpp +++ b/llvm/lib/TargetParser/SubtargetFeature.cpp @@ -68,7 +68,8 @@ LLVM_DUMP_METHOD void SubtargetFeatures::dump() const { } #endif -void SubtargetFeatures::getDefaultSubtargetFeatures(const Triple& Triple) { +void SubtargetFeatures::getDefaultSubtargetFeatures(const Triple &Triple, + const StringRef TargetABI) { // FIXME: This is an inelegant way of specifying the features of a // subtarget. It would be better if we could encode this information // into the IR. @@ -81,5 +82,7 @@ void SubtargetFeatures::getDefaultSubtargetFeatures(const Triple& Triple) { AddFeature("64bit"); AddFeature("altivec"); } + } else if (Triple.isRISCV64() && TargetABI.contains("lp64d")) { + AddFeature("+d"); } } diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp index 7249571f344938..823a7e5e2365c4 100644 --- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -163,6 +163,14 @@ void llvm::appendToCompilerUsed(Module &M, ArrayRef Values) { appendToUsedList(M, "llvm.compiler.used", Values); } +StringRef llvm::getTargetABIMD(Module &M) { + StringRef TargetABI = ""; + if (auto *TargetABIMD = + dyn_cast_or_null(M.getModuleFlag("target-abi"))) + TargetABI = TargetABIMD->getString(); + return TargetABI; +} + static void removeFromUsedList(Module &M, StringRef Name, function_ref ShouldRemove) { GlobalVariable *GV = M.getNamedGlobal(Name);