[llvm] Use TargetABI to assign default-target features in getDefaultSubtargetFeatures (PR #100833)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 9 14:15:02 PDT 2024


https://github.com/hiraditya updated https://github.com/llvm/llvm-project/pull/100833

>From a65c4f556c1c417a16a1aacd0450afb07e3f90df Mon Sep 17 00:00:00 2001
From: AdityaK <hiraditya at msn.com>
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<Reloc::Model> RelocModel;
   CodeGenOptLevel CGOptLevel = CodeGenOptLevel::Aggressive;
 
-  std::unique_ptr<TargetMachine> create() const;
+  std::unique_ptr<TargetMachine> 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<GlobalValue *> Values);
 /// Adds global values to the llvm.compiler.used list.
 void appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> 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<TargetMachine>
 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 <numeric>
 
@@ -577,7 +578,8 @@ void ThinLTOCodeGenerator::crossReferenceSymbol(StringRef Name) {
 }
 
 // TargetMachine factory
-std::unique_ptr<TargetMachine> TargetMachineBuilder::create() const {
+std::unique_ptr<TargetMachine>
+TargetMachineBuilder::create(const StringRef TargetABI) const {
   std::string ErrMsg;
   const Target *TheTarget =
       TargetRegistry::lookupTarget(TheTriple.str(), ErrMsg);
@@ -587,7 +589,7 @@ std::unique_ptr<TargetMachine> 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<TargetMachine> 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<GlobalValue *> Values) {
   appendToUsedList(M, "llvm.compiler.used", Values);
 }
 
+StringRef llvm::getTargetABIFromMD(Module &M) {
+  StringRef TargetABI = "";
+  if (auto *TargetABIMD =
+          dyn_cast_or_null<MDString>(M.getModuleFlag("target-abi")))
+    TargetABI = TargetABIMD->getString();
+  return TargetABI;
+}
+
 static void removeFromUsedList(Module &M, StringRef Name,
                                function_ref<bool(Constant *)> ShouldRemove) {
   GlobalVariable *GV = M.getNamedGlobal(Name);



More information about the llvm-commits mailing list