From 06d0e1585d080ef647587abd86d556c13762e37e 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..51fbb070751f90 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 getTargetABIFromMD(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..d06b562655b93c 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::getTargetABIFromMD(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..f33e7f3c146d70 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::getTargetABIFromMD(*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..45152b60032c62 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::getTargetABIFromMD(*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 76268c950cf581..d6c5bbdcccf443 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -60,6 +60,7 @@ #include "llvm/Transforms/IPO/WholeProgramDevirt.h" #include "llvm/Transforms/ObjCARC.h" #include "llvm/Transforms/Utils/FunctionImportUtils.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" #include @@ -577,7 +578,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); @@ -587,7 +589,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( @@ -913,10 +915,10 @@ void ThinLTOCodeGenerator::internalize(Module &TheModule, */ void ThinLTOCodeGenerator::optimize(Module &TheModule) { initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple())); - + StringRef TargetABI = llvm::getTargetABIFromMD(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 @@ -991,8 +993,10 @@ void ThinLTOCodeGenerator::run() { auto TheModule = loadModuleFromInput(Mod.get(), Context, false, /*IsImporting*/ false); + StringRef TargetABI = llvm::getTargetABIFromMD(*TheModule); // CodeGen - auto OutputBuffer = codegenModule(*TheModule, *TMBuilder.create()); + auto OutputBuffer = + codegenModule(*TheModule, *TMBuilder.create(TargetABI)); if (SavedObjectsDirectoryPath.empty()) ProducedBinaries[count] = std::move(OutputBuffer); else @@ -1177,10 +1181,11 @@ void ThinLTOCodeGenerator::run() { saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc"); auto &ImportList = ImportLists[ModuleIdentifier]; + StringRef TargetABI = llvm::getTargetABIFromMD(*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..52a59053cf6c0e 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::getTargetABIFromMD(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);