summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/MachineOutliner.cpp107
-rw-r--r--llvm/lib/IR/DIBuilder.cpp4
2 files changed, 70 insertions, 41 deletions
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) {}
OpenPOWER on IntegriCloud