From: Amara Emerson Date: Tue, 8 Nov 2016 11:18:59 +0000 (+0000) Subject: Adds the loop end location to the loop metadata. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0a1b0ce7cf8a04268e57d7213fb98ca7d3cb6db7;p=llvm Adds the loop end location to the loop metadata. This additional information can be used to improve the locations when generating remarks for loops. Patch by Florian Hahn. Differential Revision: https://reviews.llvm.org/D25763 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@286227 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 2e7f4d016bb..55b5d1ac177 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -367,6 +367,27 @@ extern template class LoopBase; /// in the CFG are neccessarily loops. class Loop : public LoopBase { public: + /// \brief A range representing the start and end location of a loop. + class LocRange { + DebugLoc Start; + DebugLoc End; + + public: + LocRange() {} + LocRange(DebugLoc Start) : Start(std::move(Start)), End(std::move(Start)) {} + LocRange(DebugLoc Start, DebugLoc End) : Start(std::move(Start)), + End(std::move(End)) {} + + const DebugLoc &getStart() const { return Start; } + const DebugLoc &getEnd() const { return End; } + + /// \brief Check for null. + /// + explicit operator bool() const { + return Start && End; + } + }; + Loop() {} /// Return true if the specified value is loop invariant. @@ -474,6 +495,9 @@ public: /// it returns an unknown location. DebugLoc getStartLoc() const; + /// Return the source code span of the loop. + LocRange getLocRange() const; + StringRef getName() const { if (BasicBlock *Header = getHeader()) if (Header->hasName()) diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index d37443cbdbe..d8b8c89cb8d 100644 --- a/lib/Analysis/LoopInfo.cpp +++ b/lib/Analysis/LoopInfo.cpp @@ -305,23 +305,40 @@ bool Loop::isAnnotatedParallel() const { } DebugLoc Loop::getStartLoc() const { + return getLocRange().getStart(); +} + +Loop::LocRange Loop::getLocRange() const { // If we have a debug location in the loop ID, then use it. - if (MDNode *LoopID = getLoopID()) - for (unsigned i = 1, ie = LoopID->getNumOperands(); i < ie; ++i) - if (DILocation *L = dyn_cast(LoopID->getOperand(i))) - return DebugLoc(L); + if (MDNode *LoopID = getLoopID()) { + DebugLoc Start; + // We use the first DebugLoc in the header as the start location of the loop + // and if there is a second DebugLoc in the header we use it as end location + // of the loop. + for (unsigned i = 1, ie = LoopID->getNumOperands(); i < ie; ++i) { + if (DILocation *L = dyn_cast(LoopID->getOperand(i))) { + if (!Start) + Start = DebugLoc(L); + else + return LocRange(Start, DebugLoc(L)); + } + } + + if (Start) + return LocRange(Start); + } // Try the pre-header first. if (BasicBlock *PHeadBB = getLoopPreheader()) if (DebugLoc DL = PHeadBB->getTerminator()->getDebugLoc()) - return DL; + return LocRange(DL); // If we have no pre-header or there are no instructions with debug // info in it, try the header. if (BasicBlock *HeadBB = getHeader()) - return HeadBB->getTerminator()->getDebugLoc(); + return LocRange(HeadBB->getTerminator()->getDebugLoc()); - return DebugLoc(); + return LocRange(); } bool Loop::hasDedicatedExits() const {