summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJessica Paquette <jpaquette@apple.com>2018-01-19 21:21:49 +0000
committerJessica Paquette <jpaquette@apple.com>2018-01-19 21:21:49 +0000
commita499c3c29d18685499c1e173c16f60a901002538 (patch)
tree4efe1f9858500f5a000eb8917a36617455b17c7d
parent76657a9c44aa3a09854b8dc611872ab029706486 (diff)
downloadbcm5719-llvm-a499c3c29d18685499c1e173c16f60a901002538.tar.gz
bcm5719-llvm-a499c3c29d18685499c1e173c16f60a901002538.zip
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. llvm-svn: 322992
-rw-r--r--llvm/include/llvm/IR/DIBuilder.h5
-rw-r--r--llvm/lib/CodeGen/MachineOutliner.cpp107
-rw-r--r--llvm/lib/IR/DIBuilder.cpp4
-rw-r--r--llvm/test/CodeGen/X86/machine-outliner-disubprogram.ll19
4 files changed, 81 insertions, 54 deletions
diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h
index 3c2074dfe78..5244a4978df 100644
--- a/llvm/include/llvm/IR/DIBuilder.h
+++ b/llvm/include/llvm/IR/DIBuilder.h
@@ -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;
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index 171c0a270c7..c515fa8c1b3 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -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(Module &M, const OutlinedFunction &OF,
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 &M) {
// 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;
}
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index a00c595d01c..f8ae23d4395 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -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) {}
diff --git a/llvm/test/CodeGen/X86/machine-outliner-disubprogram.ll b/llvm/test/CodeGen/X86/machine-outliner-disubprogram.ll
index 6ce02c49f9f..1d789647ec7 100644
--- a/llvm/test/CodeGen/X86/machine-outliner-disubprogram.ll
+++ b/llvm/test/CodeGen/X86/machine-outliner-disubprogram.ll
@@ -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" }
OpenPOWER on IntegriCloud