[llvm] Merge sourcelocation in CSEMIRBuilder::getDominatingInstrForID. (PR #90922)

Shubham Sandeep Rastogi via llvm-commits llvm-commits at lists.llvm.org
Tue May 7 11:20:22 PDT 2024


https://github.com/rastogishubham updated https://github.com/llvm/llvm-project/pull/90922

>From 7d191558482a006c8aa629753696458251272f9f Mon Sep 17 00:00:00 2001
From: Shubham Sandeep Rastogi <srastogi22 at apple.com>
Date: Thu, 2 May 2024 15:17:12 -0700
Subject: [PATCH] Merge sourcelocation in
 CSEMIRBuilder::getDominatingInstrForID.

Make sure to merge the sourcelocation of the Dominating Instruction that
is hoisted in a basic block in the CSEMIRBuilder in the legalizer pass.

If this is not done, we can have a incorrect line table entry that makes
the instruction pointer jump around.

For example the line table without this patch looks like:

Address            Line   Column File   ISA Discriminator OpIndex Flags
------------------ ------ ------ ------ --- ------------- ------- -------------
0x0000000000000000      0      0      1   0             0       0  is_stmt
0x0000000000000010     11     14      1   0             0       0  is_stmt prologue_end
0x0000000000000028     12      1      1   0             0       0  is_stmt
0x000000000000002c     12     15      1   0             0       0
0x000000000000004c     12     13      1   0             0       0
0x000000000000005c     13      1      1   0             0       0  is_stmt
0x0000000000000064     12     13      1   0             0       0  is_stmt
0x000000000000007c     13      7      1   0             0       0  is_stmt
0x00000000000000c8     13      1      1   0             0       0
0x00000000000000e8     13      1      1   0             0       0  epilogue_begin
0x00000000000000f8     13      1      1   0             0       0  end_sequence

The line table entry for 0x000000000000005c should be 0
---
 .../llvm/CodeGen/GlobalISel/CSEMIRBuilder.h   |  7 +++--
 .../GlobalISel/LegalizationArtifactCombiner.h |  6 +++-
 .../CodeGen/GlobalISel/MachineIRBuilder.h     | 10 +++++--
 llvm/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp | 20 +++++++++----
 .../CodeGen/GlobalISel/MachineIRBuilder.cpp   |  8 +++--
 .../DebugInfo/merge-locations-legalizer.mir   | 30 +++++++++++++++++++
 6 files changed, 67 insertions(+), 14 deletions(-)
 create mode 100644 llvm/test/DebugInfo/merge-locations-legalizer.mir

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h
index 488df12f13f8d..8058751ee295c 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h
@@ -48,7 +48,8 @@ class CSEMIRBuilder : public MachineIRBuilder {
   /// current insertion point and return it. If not found, return Null
   /// MachineInstrBuilder.
   MachineInstrBuilder getDominatingInstrForID(FoldingSetNodeID &ID,
-                                              void *&NodeInsertPos);
+                                              void *&NodeInsertPos,
+                                              DILocation *Location = nullptr);
   /// Simple check if we can CSE (we have the CSEInfo) or if this Opcode is
   /// safe to CSE.
   bool canPerformCSEForOpc(unsigned Opc) const;
@@ -97,8 +98,8 @@ class CSEMIRBuilder : public MachineIRBuilder {
   // Bring in the other overload from the base class.
   using MachineIRBuilder::buildConstant;
 
-  MachineInstrBuilder buildConstant(const DstOp &Res,
-                                    const ConstantInt &Val) override;
+  MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val,
+                                    DILocation *Location = nullptr) override;
 
   // Bring in the other overload from the base class.
   using MachineIRBuilder::buildFConstant;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
index 305bef7dd3ea6..fc9232eeae0b6 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
@@ -26,6 +26,7 @@
 #include "llvm/CodeGen/Register.h"
 #include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/Support/Debug.h"
 
 #define DEBUG_TYPE "legalizer"
@@ -99,8 +100,11 @@ class LegalizationArtifactCombiner {
       const LLT DstTy = MRI.getType(DstReg);
       if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
         auto &CstVal = SrcMI->getOperand(1);
+        auto *MergedLocation = DILocation::getMergedLocation(
+            MI.getDebugLoc().get(), SrcMI->getDebugLoc().get());
         Builder.buildConstant(
-            DstReg, CstVal.getCImm()->getValue().sext(DstTy.getSizeInBits()));
+            DstReg, CstVal.getCImm()->getValue().sext(DstTy.getSizeInBits()),
+            MergedLocation);
         UpdatedDefs.push_back(DstReg);
         markInstAndDefDead(MI, *SrcMI, DeadInsts);
         return true;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index e15f7a7172e1a..d8b7f63226cf8 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -243,6 +243,10 @@ class MachineIRBuilder {
   }
 
 public:
+  /// This is the merged location of an instruction which is a result of a fold
+  /// in the legalizer.
+  DILocation *Location = nullptr;
+
   /// Some constructors for easy use.
   MachineIRBuilder() = default;
   MachineIRBuilder(MachineFunction &MF) { setMF(MF); }
@@ -857,7 +861,8 @@ class MachineIRBuilder {
   ///
   /// \return The newly created instruction.
   virtual MachineInstrBuilder buildConstant(const DstOp &Res,
-                                            const ConstantInt &Val);
+                                            const ConstantInt &Val,
+                                            DILocation *Location = nullptr);
 
   /// Build and insert \p Res = G_CONSTANT \p Val
   ///
@@ -868,7 +873,8 @@ class MachineIRBuilder {
   ///
   /// \return The newly created instruction.
   MachineInstrBuilder buildConstant(const DstOp &Res, int64_t Val);
-  MachineInstrBuilder buildConstant(const DstOp &Res, const APInt &Val);
+  MachineInstrBuilder buildConstant(const DstOp &Res, const APInt &Val,
+                                    DILocation *Location = nullptr);
 
   /// Build and insert \p Res = G_FCONSTANT \p Val
   ///
diff --git a/llvm/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp
index 551ba1e6036c1..d0685304fff83 100644
--- a/llvm/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp
@@ -34,9 +34,8 @@ bool CSEMIRBuilder::dominates(MachineBasicBlock::const_iterator A,
   return &*I == A;
 }
 
-MachineInstrBuilder
-CSEMIRBuilder::getDominatingInstrForID(FoldingSetNodeID &ID,
-                                       void *&NodeInsertPos) {
+MachineInstrBuilder CSEMIRBuilder::getDominatingInstrForID(
+    FoldingSetNodeID &ID, void *&NodeInsertPos, DILocation *Location) {
   GISelCSEInfo *CSEInfo = getCSEInfo();
   assert(CSEInfo && "Can't get here without setting CSEInfo");
   MachineBasicBlock *CurMBB = &getMBB();
@@ -51,6 +50,16 @@ CSEMIRBuilder::getDominatingInstrForID(FoldingSetNodeID &ID,
       // this builder will have the def ready.
       setInsertPt(*CurMBB, std::next(MII));
     } else if (!dominates(MI, CurrPos)) {
+      // Location represents the DILocation of an instruction (or merged
+      // location of instructions, if multiple instructions were folded) at the
+      // insertion point where MI is going to be moved to, since MI is going to
+      // be moved, it's DILocation needs to be updated to make sure the line
+      // table is correct.
+      if (Location) {
+        auto *Loc =
+            DILocation::getMergedLocation(Location, MI->getDebugLoc().get());
+        MI->setDebugLoc(Loc);
+      }
       CurMBB->splice(CurrPos, CurMBB, MI);
     }
     return MachineInstrBuilder(getMF(), MI);
@@ -321,7 +330,8 @@ MachineInstrBuilder CSEMIRBuilder::buildInstr(unsigned Opc,
 }
 
 MachineInstrBuilder CSEMIRBuilder::buildConstant(const DstOp &Res,
-                                                 const ConstantInt &Val) {
+                                                 const ConstantInt &Val,
+                                                 DILocation *Location) {
   constexpr unsigned Opc = TargetOpcode::G_CONSTANT;
   if (!canPerformCSEForOpc(Opc))
     return MachineIRBuilder::buildConstant(Res, Val);
@@ -337,7 +347,7 @@ MachineInstrBuilder CSEMIRBuilder::buildConstant(const DstOp &Res,
   profileMBBOpcode(ProfBuilder, Opc);
   profileDstOp(Res, ProfBuilder);
   ProfBuilder.addNodeIDMachineOperand(MachineOperand::CreateCImm(&Val));
-  MachineInstrBuilder MIB = getDominatingInstrForID(ID, InsertPos);
+  MachineInstrBuilder MIB = getDominatingInstrForID(ID, InsertPos, Location);
   if (MIB) {
     // Handle generating copies here.
     return generateCopiesIfRequired({Res}, MIB);
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 2e8407813ba64..561f356a3bc24 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -315,7 +315,8 @@ MachineInstrBuilder MachineIRBuilder::buildCopy(const DstOp &Res,
 }
 
 MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res,
-                                                    const ConstantInt &Val) {
+                                                    const ConstantInt &Val,
+                                                    DILocation *Location) {
   LLT Ty = Res.getLLTTy(*getMRI());
   LLT EltTy = Ty.getScalarType();
   assert(EltTy.getScalarSizeInBits() == Val.getBitWidth() &&
@@ -376,9 +377,10 @@ MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
 }
 
 MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res,
-                                                    const APInt &Val) {
+                                                    const APInt &Val,
+                                                    DILocation *Location) {
   ConstantInt *CI = ConstantInt::get(getMF().getFunction().getContext(), Val);
-  return buildConstant(Res, *CI);
+  return buildConstant(Res, *CI, Location);
 }
 
 MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
diff --git a/llvm/test/DebugInfo/merge-locations-legalizer.mir b/llvm/test/DebugInfo/merge-locations-legalizer.mir
new file mode 100644
index 0000000000000..fb57f63fd6a0c
--- /dev/null
+++ b/llvm/test/DebugInfo/merge-locations-legalizer.mir
@@ -0,0 +1,30 @@
+# This test checks to make sure that when an instruction (%3 in the test) is 
+# moved due to matching a result of a fold of two other instructions
+# (%1, and %2 in the test) in the legalizer, the DILocation of the 
+# instruction that is moved (%3) is updated appropriately.
+
+# RUN: llc %s -run-pass=legalizer -o - | FileCheck %s 
+# CHECK-NOT: %2:_(s32) = G_CONSTANT i32 0, debug-location !DILocation(line: 13
+# CHECK: %2:_(s32) = G_CONSTANT i32 0, debug-location !DILocation(line: 0,
+--- |
+  
+  define i32 @main(i32 %0, ptr %1) #0 !dbg !57 {
+  entry:
+    ret i32 0, !dbg !71
+  }
+  !3 = !DIFile(filename: "main.swift", directory: "/Volumes/Data/swift")
+  !23 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !3, sdk: "blah.sdk")
+  !57 = distinct !DISubprogram(name: "main", unit: !23)
+  !64 = distinct !DILexicalBlock(scope: !57, column: 1)
+  !66 = distinct !DILexicalBlock(scope: !64, column: 1)
+  !68 = !DILocation(line: 12, scope: !66)
+  !70 = distinct !DILexicalBlock(scope: !66, column: 1)
+  !71 = !DILocation(line: 13, scope: !70)
+name:            main
+body:             |
+  bb.0:
+    %1:_(s8) = G_CONSTANT i8 0, debug-location !68
+    %2:_(s32) = G_ANYEXT %1(s8), debug-location !68
+    $w2 = COPY %2(s32), debug-location !68
+    %3:_(s32) = G_CONSTANT i32 0, debug-location !71
+    $w0 = COPY %3(s32), debug-location !71



More information about the llvm-commits mailing list