[llvm] [RISCV] Collect function features in AsmPrinter before emission (#76231) (PR #76437)

via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 27 04:29:06 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Andreu Carminati (andcarminati)

<details>
<summary>Changes</summary>

When performing LTO, if we use just TM MCSubtargetInfo feature flags, it will be incomplete because these informations will be in function's Subtarget. In this way, we collect the flags of all functions and postpone the attribute emission to the end of the file emission.

---
Full diff: https://github.com/llvm/llvm-project/pull/76437.diff


2 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp (+24-8) 
- (added) llvm/test/CodeGen/RISCV/flags-collect-asmprinter.ll (+28) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index 0fd514fa87cd2f..75224bbbb62524 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -54,11 +54,16 @@ extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
 namespace {
 class RISCVAsmPrinter : public AsmPrinter {
   const RISCVSubtarget *STI;
+  std::unique_ptr<MCSubtargetInfo> CommonSTI;
 
 public:
   explicit RISCVAsmPrinter(TargetMachine &TM,
                            std::unique_ptr<MCStreamer> Streamer)
-      : AsmPrinter(TM, std::move(Streamer)) {}
+      : AsmPrinter(TM, std::move(Streamer)) {
+    std::unique_ptr<MCSubtargetInfo> STIPtr(
+        TM.getTarget().createMCSubtargetInfo("", "", ""));
+    CommonSTI = std::move(STIPtr);
+  }
 
   StringRef getPassName() const override { return "RISC-V Assembly Printer"; }
 
@@ -71,6 +76,8 @@ class RISCVAsmPrinter : public AsmPrinter {
   void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
                        const MachineInstr &MI);
 
+  bool doInitialization(Module &M) override;
+
   bool runOnMachineFunction(MachineFunction &MF) override;
 
   void emitInstruction(const MachineInstr *MI) override;
@@ -363,6 +370,12 @@ bool RISCVAsmPrinter::emitDirectiveOptionArch() {
   return false;
 }
 
+bool RISCVAsmPrinter::doInitialization(Module &M) {
+
+  CommonSTI->setFeatureBits(TM.getMCSubtargetInfo()->getFeatureBits());
+  return AsmPrinter::doInitialization(M);
+}
+
 bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   STI = &MF.getSubtarget<RISCVSubtarget>();
   RISCVTargetStreamer &RTS =
@@ -370,6 +383,10 @@ bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   bool EmittedOptionArch = emitDirectiveOptionArch();
 
+  // Collect flags from this function.
+  CommonSTI->setFeatureBits(CommonSTI->getFeatureBits() |
+                            STI->getFeatureBits());
+
   SetupMachineFunction(MF);
   emitFunctionBody();
 
@@ -384,26 +401,25 @@ void RISCVAsmPrinter::emitStartOfAsmFile(Module &M) {
   if (const MDString *ModuleTargetABI =
           dyn_cast_or_null<MDString>(M.getModuleFlag("target-abi")))
     RTS.setTargetABI(RISCVABI::getTargetABI(ModuleTargetABI->getString()));
-  if (TM.getTargetTriple().isOSBinFormatELF())
-    emitAttributes();
 }
 
 void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) {
   RISCVTargetStreamer &RTS =
       static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
 
-  if (TM.getTargetTriple().isOSBinFormatELF())
+  if (TM.getTargetTriple().isOSBinFormatELF()) {
+    emitAttributes();
     RTS.finishAttributeSection();
+  }
+
   EmitHwasanMemaccessSymbols(M);
 }
 
 void RISCVAsmPrinter::emitAttributes() {
   RISCVTargetStreamer &RTS =
       static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
-  // Use MCSubtargetInfo from TargetMachine. Individual functions may have
-  // attributes that differ from other functions in the module and we have no
-  // way to know which function is correct.
-  RTS.emitTargetAttributes(*TM.getMCSubtargetInfo(), /*EmitStackAlign*/ true);
+  // Use MCSubtargetInfo with flags collected from all functions.
+  RTS.emitTargetAttributes(*CommonSTI.get(), /*EmitStackAlign*/ true);
 }
 
 void RISCVAsmPrinter::emitFunctionEntryLabel() {
diff --git a/llvm/test/CodeGen/RISCV/flags-collect-asmprinter.ll b/llvm/test/CodeGen/RISCV/flags-collect-asmprinter.ll
new file mode 100644
index 00000000000000..6a0758eeb6e2d1
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/flags-collect-asmprinter.ll
@@ -0,0 +1,28 @@
+; RUN: llc -mtriple=riscv32  -verify-machineinstrs < %s -filetype=obj -o %t
+; RUN: llvm-readelf -A %t | FileCheck %s
+
+; CHECK: Value: rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0
+define dso_local i32 @func0() #0 {
+entry:
+  ret i32 0
+}
+
+define dso_local i32 @func1() #1 {
+entry:
+  ret i32 0
+}
+
+define dso_local i32 @func2() #2 {
+entry:
+  ret i32 0
+}
+
+define dso_local i32 @func3() #3 {
+entry:
+  ret i32 0
+}
+
+attributes #0 = { nounwind "target-features"="+32bit,+d,+zicsr" }
+attributes #1 = { nounwind "target-features"="+32bit,+d,+f,+m" }
+attributes #2 = { nounwind "target-features"="+32bit,+f,+c" }
+attributes #3 = { nounwind "target-features"="+32bit,+a" }

``````````

</details>


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


More information about the llvm-commits mailing list