From 0b40201e13996273490dcc7e95fd09dd74f4f903 Mon Sep 17 00:00:00 2001 From: Amara Emerson Date: Tue, 8 Nov 2016 11:18:59 +0000 Subject: [PATCH] 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 llvm-svn: 286227 --- llvm/include/llvm/Analysis/LoopInfo.h | 24 ++++++++++++++++++++++++ llvm/lib/Analysis/LoopInfo.cpp | 31 ++++++++++++++++++++++++------- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm/Analysis/LoopInfo.h b/llvm/include/llvm/Analysis/LoopInfo.h index 2e7f4d0..55b5d1a 100644 --- a/llvm/include/llvm/Analysis/LoopInfo.h +++ b/llvm/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/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp index d37443c..d8b8c89 100644 --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/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 { -- 2.7.4