[llvm] r322992 - Add optional DICompileUnit to DIBuilder + make outliner debug info use it

Jessica Paquette via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 19 13:21:49 PST 2018


Author: paquette
Date: Fri Jan 19 13:21:49 2018
New Revision: 322992

URL: http://llvm.org/viewvc/llvm-project?rev=322992&view=rev
Log:
Add optional DICompileUnit to DIBuilder + make outliner debug info use it

Previously, the DIBuilder didn't expose functionality to set its compile unit
in any other way than calling createCompileUnit. This meant that the outliner,
which creates new functions, had to create a new compile unit for its debug
info.

This commit adds an optional parameter in the DIBuilder's constructor which
lets you set its CU at construction.

It also changes the MachineOutliner so that it keeps track of the DISubprograms
for each outlined sequence. If debugging information is requested, then it
uses one of the outlined sequence's DISubprograms to grab a CU. It then uses
that CU to construct the DISubprogram for the new outlined function.

The test has also been updated to reflect this change.

See https://reviews.llvm.org/D42254 for more information. Also see the e-mail
discussion on D42254 in llvm-commits for more context.


Modified:
    llvm/trunk/include/llvm/IR/DIBuilder.h
    llvm/trunk/lib/CodeGen/MachineOutliner.cpp
    llvm/trunk/lib/IR/DIBuilder.cpp
    llvm/trunk/test/CodeGen/X86/machine-outliner-disubprogram.ll

Modified: llvm/trunk/include/llvm/IR/DIBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DIBuilder.h?rev=322992&r1=322991&r2=322992&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DIBuilder.h (original)
+++ llvm/trunk/include/llvm/IR/DIBuilder.h Fri Jan 19 13:21:49 2018
@@ -90,7 +90,10 @@ namespace llvm {
     ///
     /// If \c AllowUnresolved, collect unresolved nodes attached to the module
     /// in order to resolve cycles during \a finalize().
-    explicit DIBuilder(Module &M, bool AllowUnresolved = true);
+    ///
+    /// If \p CU is given a value other than nullptr, then set \p CUNode to CU.
+    explicit DIBuilder(Module &M, bool AllowUnresolved = true,
+                       DICompileUnit *CU = nullptr);
     DIBuilder(const DIBuilder &) = delete;
     DIBuilder &operator=(const DIBuilder &) = delete;
 

Modified: llvm/trunk/lib/CodeGen/MachineOutliner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineOutliner.cpp?rev=322992&r1=322991&r2=322992&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineOutliner.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineOutliner.cpp Fri Jan 19 13:21:49 2018
@@ -68,6 +68,7 @@
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Mangler.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
@@ -97,6 +98,9 @@ private:
   /// The number of instructions in this \p Candidate.
   unsigned Len;
 
+  /// The MachineFunction containing this \p Candidate.
+  MachineFunction *MF = nullptr;
+
 public:
   /// Set to false if the candidate overlapped with another candidate.
   bool InCandidateList = true;
@@ -108,6 +112,15 @@ public:
   /// Contains all target-specific information for this \p Candidate.
   TargetInstrInfo::MachineOutlinerInfo MInfo;
 
+  /// If there is a DISubprogram associated with the function that this
+  /// Candidate lives in, return it.
+  DISubprogram *getSubprogramOrNull() const {
+    assert(MF && "Candidate has no MF!");
+    if (DISubprogram *SP = MF->getFunction().getSubprogram())
+      return SP;
+    return nullptr;
+  }
+
   /// Return the number of instructions in this Candidate.
   unsigned getLength() const { return Len; }
 
@@ -126,8 +139,9 @@ public:
   /// for some given candidate.
   unsigned Benefit = 0;
 
-  Candidate(unsigned StartIdx, unsigned Len, unsigned FunctionIdx)
-      : StartIdx(StartIdx), Len(Len), FunctionIdx(FunctionIdx) {}
+  Candidate(unsigned StartIdx, unsigned Len, unsigned FunctionIdx,
+            MachineFunction *MF)
+      : StartIdx(StartIdx), Len(Len), MF(MF), FunctionIdx(FunctionIdx) {}
 
   Candidate() {}
 
@@ -163,6 +177,15 @@ public:
   /// Contains all target-specific information for this \p OutlinedFunction.
   TargetInstrInfo::MachineOutlinerInfo MInfo;
 
+  /// If there is a DISubprogram for any Candidate for this outlined function,
+  /// then return it. Otherwise, return nullptr.
+  DISubprogram *getSubprogramOrNull() const {
+    for (const auto &C : Candidates)
+      if (DISubprogram *SP = C->getSubprogramOrNull())
+        return SP;
+    return nullptr;
+  }
+
   /// Return the number of candidates for this \p OutlinedFunction.
   unsigned getOccurrenceCount() { return OccurrenceCount; }
 
@@ -979,9 +1002,13 @@ unsigned MachineOutliner::findCandidates
           MachineBasicBlock::iterator StartIt = Mapper.InstrList[StartIdx];
           MachineBasicBlock::iterator EndIt = Mapper.InstrList[EndIdx];
 
+          // Save the MachineFunction containing the Candidate.
+          MachineFunction *MF = StartIt->getParent()->getParent();
+          assert(MF && "Candidate doesn't have a MF?");
+
           // Save the candidate and its location.
           CandidatesForRepeatedSeq.emplace_back(StartIdx, StringLen,
-                                                FunctionList.size());
+                                                FunctionList.size(), MF);
           RepeatedSequenceLocs.emplace_back(std::make_pair(StartIt, EndIt));
         }
       }
@@ -1246,6 +1273,44 @@ MachineOutliner::createOutlinedFunction(
 
   TII.insertOutlinerEpilogue(MBB, MF, OF.MInfo);
 
+  // If there's a DISubprogram associated with this outlined function, then
+  // emit debug info for the outlined function.
+  if (DISubprogram *SP = OF.getSubprogramOrNull()) {
+    // We have a DISubprogram. Get its DICompileUnit.
+    DICompileUnit *CU = SP->getUnit();
+    DIBuilder DB(M, true, CU);
+    DIFile *Unit = SP->getFile();
+    Mangler Mg;
+
+    // Walk over each IR function we created in the outliner and create
+    // DISubprograms for each function.
+    for (Function *F : CreatedIRFunctions) {
+      // Get the mangled name of the function for the linkage name.
+      std::string Dummy;
+      llvm::raw_string_ostream MangledNameStream(Dummy);
+      Mg.getNameWithPrefix(MangledNameStream, F, false);
+
+      DISubprogram *SP = DB.createFunction(
+          Unit /* Context */, F->getName(), StringRef(MangledNameStream.str()),
+          Unit /* File */,
+          0 /* Line 0 is reserved for compiler-generated code. */,
+          DB.createSubroutineType(
+              DB.getOrCreateTypeArray(None)), /* void type */
+          false, true, 0, /* Line 0 is reserved for compiler-generated code. */
+          DINode::DIFlags::FlagArtificial /* Compiler-generated code. */,
+          true /* Outlined code is optimized code by definition. */);
+
+      // Don't add any new variables to the subprogram.
+      DB.finalizeSubprogram(SP);
+
+      // Attach subprogram to the function.
+      F->setSubprogram(SP);
+    }
+
+    // We're done with the DIBuilder.
+    DB.finalize();
+  }
+
   return &MF;
 }
 
@@ -1388,41 +1453,5 @@ bool MachineOutliner::runOnModule(Module
   // Outline each of the candidates and return true if something was outlined.
   bool OutlinedSomething = outline(M, CandidateList, FunctionList, Mapper);
 
-  // If we have a compile unit, and we've outlined something, then set debug
-  // information on the outlined function.
-  if (M.debug_compile_units_begin() != M.debug_compile_units_end() &&
-      OutlinedSomething) {
-    std::unique_ptr<DIBuilder> DB = llvm::make_unique<DIBuilder>(M);
-
-    // Create a compile unit for the outlined function.
-    DICompileUnit *MCU = *M.debug_compile_units_begin();
-    DIFile *Unit = DB->createFile(M.getName(), "/");
-    DB->createCompileUnit(MCU->getSourceLanguage(), Unit, "machine-outliner",
-                          true, "", MCU->getRuntimeVersion(), StringRef(),
-                          DICompileUnit::DebugEmissionKind::NoDebug);
-
-    // Walk over each IR function we created in the outliner and create
-    // DISubprograms for each function.
-    for (Function *F : CreatedIRFunctions) {
-      DISubprogram *SP = DB->createFunction(
-          Unit /* Context */, F->getName(),
-          StringRef() /* Empty linkage name. */, Unit /* File */,
-          0 /* Line numbers don't matter*/,
-          DB->createSubroutineType(DB->getOrCreateTypeArray(None)), /* void */
-          false, true, 0, /* Line in scope doesn't matter*/
-          DINode::DIFlags::FlagArtificial /* Compiler-generated code. */,
-          true /* Outlined code is optimized code by definition. */);
-
-      // Don't add any new variables to the subprogram.
-      DB->finalizeSubprogram(SP);
-
-      // Attach subprogram to the function.
-      F->setSubprogram(SP);
-    }
-
-    // We're done with the DIBuilder.
-    DB->finalize();
-  }
-
   return OutlinedSomething;
 }

Modified: llvm/trunk/lib/IR/DIBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DIBuilder.cpp?rev=322992&r1=322991&r2=322992&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DIBuilder.cpp (original)
+++ llvm/trunk/lib/IR/DIBuilder.cpp Fri Jan 19 13:21:49 2018
@@ -30,8 +30,8 @@ cl::opt<bool>
                llvm::cl::desc("Use llvm.dbg.addr for all local variables"),
                cl::init(false), cl::Hidden);
 
-DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes)
-  : M(m), VMContext(M.getContext()), CUNode(nullptr),
+DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU)
+  : M(m), VMContext(M.getContext()), CUNode(CU),
       DeclareFn(nullptr), ValueFn(nullptr),
       AllowUnresolvedNodes(AllowUnresolvedNodes) {}
 

Modified: llvm/trunk/test/CodeGen/X86/machine-outliner-disubprogram.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/machine-outliner-disubprogram.ll?rev=322992&r1=322991&r2=322992&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/machine-outliner-disubprogram.ll (original)
+++ llvm/trunk/test/CodeGen/X86/machine-outliner-disubprogram.ll Fri Jan 19 13:21:49 2018
@@ -108,31 +108,26 @@ entry:
   ret i32 0, !dbg !73
 }
 
-; CHECK [[UNIT:![0-9]+]] = distinct !DICompileUnit
-; CHECK-SAME: file: [[FILE:![0-9]+]],
-; CHECK-SAME: producer: "machine-outliner",
-; CHECK-SAME: isOptimized: true, runtimeVersion: 0, emissionKind: NoDebug
-
 ; CHECK: distinct !DISubprogram(name: "OUTLINED_FUNCTION_1",
-; CHECK-SAME: scope: [[FILE]],
-; CHECK-SAME: file: [[FILE]],
+; CHECK-SAME: scope: !1,
+; CHECK-SAME: file: !1,
 ; CHECK-SAME: type: [[TYPE:![0-9]+]],
 ; CHECK-SAME: isLocal: false, 
 ; CHECK-SAME: isDefinition: true,
 ; CHECK-SAME: flags: DIFlagArtificial,
 ; CHECK-SAME: isOptimized: true,
-; CHECK-SAME: unit: [[UNIT]],
+; CHECK-SAME: unit: !0,
 ; CHECK-SAME: variables: [[VARS:![0-9]+]]
 
-; CHECK: distinct !DISubprogram(name: "OUTLINED_FUNCTION_1",
-; CHECK-SAME: scope: [[FILE]],
-; CHECK-SAME: file: [[FILE]],
+; CHECK: distinct !DISubprogram(name: "OUTLINED_FUNCTION_0",
+; CHECK-SAME: scope: !1,
+; CHECK-SAME: file: !1,
 ; CHECK-SAME: type: [[TYPE]],
 ; CHECK-SAME: isLocal: false, 
 ; CHECK-SAME: isDefinition: true,
 ; CHECK-SAME: flags: DIFlagArtificial,
 ; CHECK-SAME: isOptimized: true,
-; CHECK-SAME: unit: [[UNIT]],
+; CHECK-SAME: unit: !0,
 ; CHECK-SAME: variables: [[VARS]]
 
 attributes #0 = { noinline noredzone nounwind optnone ssp uwtable "no-frame-pointer-elim"="true"  }




More information about the llvm-commits mailing list