Index: llvm/trunk/include/llvm/Analysis/LoopInfo.h =================================================================== --- llvm/trunk/include/llvm/Analysis/LoopInfo.h +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h @@ -367,6 +367,27 @@ /// 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 @@ /// 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()) Index: llvm/trunk/lib/Analysis/LoopInfo.cpp =================================================================== --- llvm/trunk/lib/Analysis/LoopInfo.cpp +++ llvm/trunk/lib/Analysis/LoopInfo.cpp @@ -305,23 +305,40 @@ } 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 {