diff --git a/include/swift/Basic/STLExtras.h b/include/swift/Basic/STLExtras.h index 063be8271ca..29e0434793b 100644 --- a/include/swift/Basic/STLExtras.h +++ b/include/swift/Basic/STLExtras.h @@ -180,6 +180,14 @@ inline void set_union_for_each(const Container1 &C1, const Container2 &C2, set_union_for_each(C1.begin(), C1.end(), C2.begin(), C2.end(), f); } +/// Takes an iterator and an iterator pointing to the end of the iterator range. +/// If the iterator already points to the end of its range, simply return it, +/// otherwise return the the next element. +template +inline Iterator next_or_end(Iterator it, Iterator end) { + return (it == end) ? end : std::next(it); +} + /// @} /// A range of iterators. diff --git a/lib/SILGen/SILGenEpilog.cpp b/lib/SILGen/SILGenEpilog.cpp index 483bd704732..d7e669dd194 100644 --- a/lib/SILGen/SILGenEpilog.cpp +++ b/lib/SILGen/SILGenEpilog.cpp @@ -130,8 +130,7 @@ SILGenFunction::emitEpilogBB(SILLocation TopLevel) { B.setInsertionPoint(pred); } else { // Move the epilog block to the end of the ordinary section. - auto endOfOrdinarySection = - (StartOfPostmatter ? SILFunction::iterator(StartOfPostmatter) : F.end()); + auto endOfOrdinarySection = StartOfPostmatter; B.moveBlockTo(epilogBB, endOfOrdinarySection); // Emit the epilog into the epilog bb. Its arguments are the diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index b7f6a77cafd..e94b96e0d49 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -34,12 +34,9 @@ using namespace Lowering; //===----------------------------------------------------------------------===// SILGenFunction::SILGenFunction(SILGenModule &SGM, SILFunction &F) - : SGM(SGM), F(F), - B(*this, createBasicBlock()), - OpenedArchetypesTracker(F), - CurrentSILLoc(F.getLocation()), - Cleanups(*this) -{ + : SGM(SGM), F(F), StartOfPostmatter(F.end()), B(*this, createBasicBlock()), + OpenedArchetypesTracker(F), CurrentSILLoc(F.getLocation()), + Cleanups(*this) { B.setCurrentDebugScope(F.getDebugScope()); B.setOpenedArchetypesTracker(&OpenedArchetypesTracker); } @@ -875,8 +872,8 @@ SILGenBuilder::SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB, SmallVectorImpl *insertedInsts) : SILBuilder(insertBB, insertedInsts), SGM(gen.SGM) {} SILGenBuilder::SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB, - SILInstruction *insertInst) - : SILBuilder(insertBB, insertInst->getIterator()), SGM(gen.SGM) {} + SILBasicBlock::iterator insertInst) + : SILBuilder(insertBB, insertInst), SGM(gen.SGM) {} MetatypeInst *SILGenBuilder::createMetatype(SILLocation loc, SILType metatype) { auto theMetatype = metatype.castTo(); diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h index 008bdab9e8d..1a70eb9caee 100644 --- a/lib/SILGen/SILGenFunction.h +++ b/lib/SILGen/SILGenFunction.h @@ -184,7 +184,7 @@ public: SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB, SmallVectorImpl *insertedInsts); SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB, - SILInstruction *insertInst); + SILBasicBlock::iterator insertInst); SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB) : SILGenBuilder(gen, &*insertBB) {} @@ -193,10 +193,10 @@ public: : SILGenBuilder(gen, &*insertBB, insertedInsts) {} SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB, SILInstruction *insertInst) - : SILGenBuilder(gen, &*insertBB, insertInst) {} + : SILGenBuilder(gen, &*insertBB, insertInst->getIterator()) {} SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB, SILBasicBlock::iterator insertInst) - : SILGenBuilder(gen, &*insertBB, &*insertInst) {} + : SILGenBuilder(gen, &*insertBB, insertInst) {} // Metatype instructions use the conformances necessary to instantiate the // type. @@ -319,7 +319,7 @@ public: /// /// (This field must precede B because B's initializer calls /// createBasicBlock().) - SILBasicBlock *StartOfPostmatter = nullptr; + SILFunction::iterator StartOfPostmatter; /// The current section of the function that we're emitting code in. /// @@ -328,12 +328,12 @@ public: /// normal code sequence. /// /// If the current function section is Ordinary, and - /// StartOfPostmatter is non-null, the current insertion block - /// should be ordered before that. - /// + /// StartOfPostmatter does not point to the function end, the current + /// insertion block should be ordered before that. + /// /// If the current function section is Postmatter, StartOfPostmatter - /// is non-null and the current insertion block is ordered after - /// that (inclusive). + /// does not point to the function end and the current insertion block is + /// ordered after that (inclusive). /// /// (This field must precede B because B's initializer calls /// createBasicBlock().) @@ -1624,7 +1624,8 @@ public: : SGF(SGF), SavedIP(SGF.B.getInsertionBB()), SavedSection(SGF.CurFunctionSection) { FunctionSection section = (optSection ? *optSection : SavedSection); - assert((section != FunctionSection::Postmatter || SGF.StartOfPostmatter) && + assert((section != FunctionSection::Postmatter || + SGF.StartOfPostmatter != SGF.F.end()) && "trying to move to postmatter without a registered start " "of postmatter?"); diff --git a/lib/SILGen/SILGenGlobalVariable.cpp b/lib/SILGen/SILGenGlobalVariable.cpp index 2bcecade52d..741665c2bae 100644 --- a/lib/SILGen/SILGenGlobalVariable.cpp +++ b/lib/SILGen/SILGenGlobalVariable.cpp @@ -110,7 +110,7 @@ SILGenFunction::emitGlobalVariableRef(SILLocation loc, VarDecl *var) { // Global variables can be accessed directly with global_addr. Emit this // instruction into the prolog of the function so we can memoize/CSE it in // VarLocs. - auto entryBB = getFunction().getBlocks().begin(); + auto entryBB = getFunction().begin(); SILGenBuilder prologueB(*this, entryBB, entryBB->begin()); prologueB.setTrackingList(B.getTrackingList()); diff --git a/lib/SILGen/SILGenStmt.cpp b/lib/SILGen/SILGenStmt.cpp index d8d528ecb28..31f39463592 100644 --- a/lib/SILGen/SILGenStmt.cpp +++ b/lib/SILGen/SILGenStmt.cpp @@ -52,9 +52,9 @@ SILBasicBlock *SILGenFunction::createBasicBlock(FunctionSection section) { case FunctionSection::Ordinary: { // The end of the ordinary section is just the end of the function // unless postmatter blocks exist. - SILBasicBlock *afterBB = - (StartOfPostmatter ? &*std::prev(StartOfPostmatter->getIterator()) - : nullptr); + SILBasicBlock *afterBB = (StartOfPostmatter != F.end()) + ? &*std::prev(StartOfPostmatter) + : nullptr; return new (F.getModule()) SILBasicBlock(&F, afterBB); } @@ -62,7 +62,8 @@ SILBasicBlock *SILGenFunction::createBasicBlock(FunctionSection section) { // The end of the postmatter section is always the end of the function. // Register the new block as the start of the postmatter if needed. SILBasicBlock *newBB = new (F.getModule()) SILBasicBlock(&F, nullptr); - if (!StartOfPostmatter) StartOfPostmatter = newBB; + if (StartOfPostmatter == F.end()) + StartOfPostmatter = newBB->getIterator(); return newBB; } @@ -73,8 +74,9 @@ SILBasicBlock *SILGenFunction::createBasicBlock(FunctionSection section) { void SILGenFunction::eraseBasicBlock(SILBasicBlock *block) { assert(block->pred_empty() && "erasing block with predecessors"); assert(block->empty() && "erasing block with content"); - if (block == StartOfPostmatter) { - StartOfPostmatter = &*std::next(block->getIterator()); + SILFunction::iterator blockIt = block->getIterator(); + if (blockIt == StartOfPostmatter) { + StartOfPostmatter = next_or_end(blockIt, F.end()); } block->eraseFromParent(); } diff --git a/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp b/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp index 0530fa330cd..7a83bf3eef1 100644 --- a/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp +++ b/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp @@ -133,15 +133,16 @@ static FullApplySite speculateMonomorphicTarget(FullApplySite AI, // See if Continue has a release on self as the instruction right after the // apply. If it exists, move it into position in the diamond. - if (auto *Release = - dyn_cast(std::next(Continue->begin()))) { - if (Release->getOperand() == CMI->getOperand()) { - VirtBuilder.createStrongRelease(Release->getLoc(), CMI->getOperand(), - Atomicity::Atomic); - IdenBuilder.createStrongRelease( - Release->getLoc(), DownCastedClassInstance, Atomicity::Atomic); - Release->eraseFromParent(); - } + SILBasicBlock::iterator next = + next_or_end(Continue->begin(), Continue->end()); + auto *Release = + (next == Continue->end()) ? nullptr : dyn_cast(next); + if (Release && Release->getOperand() == CMI->getOperand()) { + VirtBuilder.createStrongRelease(Release->getLoc(), CMI->getOperand(), + Atomicity::Atomic); + IdenBuilder.createStrongRelease(Release->getLoc(), DownCastedClassInstance, + Atomicity::Atomic); + Release->eraseFromParent(); } // Create a PHInode for returning the return value from both apply diff --git a/lib/SILOptimizer/Transforms/StackPromotion.cpp b/lib/SILOptimizer/Transforms/StackPromotion.cpp index 68c915673e9..0a1e10743c6 100644 --- a/lib/SILOptimizer/Transforms/StackPromotion.cpp +++ b/lib/SILOptimizer/Transforms/StackPromotion.cpp @@ -319,7 +319,7 @@ template <> struct GraphTraits return nodes_iterator(SP->getFunction()->end(), SP->getFunction()->end()); } static unsigned size(GraphType SP) { - return std::distance(nodes_begin(SP), nodes_end(SP)); + return std::distance(SP->getFunction()->begin(), SP->getFunction()->end()); } };