diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/MachineOutliner.cpp | 107 | ||||
-rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 4 |
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) {} |