diff --git a/include/swift/SIL/ApplySite.h b/include/swift/SIL/ApplySite.h index b441a2af2c2fb..b8069a93ae65a 100644 --- a/include/swift/SIL/ApplySite.h +++ b/include/swift/SIL/ApplySite.h @@ -21,6 +21,7 @@ #ifndef SWIFT_SIL_APPLYSITE_H #define SWIFT_SIL_APPLYSITE_H +#include "swift/SIL/SILBasicBlock.h" #include "swift/SIL/SILInstruction.h" namespace swift { @@ -397,6 +398,24 @@ class ApplySite { } } + /// If this is a terminator apply site, then pass the first instruction of + /// each successor to fun. Otherwise, pass std::next(Inst). + /// + /// The intention is that this abstraction will enable the compiler writer to + /// ignore whether or not an apply site is a terminator when inserting + /// instructions after an apply site. This results in eliminating unnecessary + /// if-else code otherwise required to handle such situations. + void insertAfter(llvm::function_ref func) { + auto *ti = dyn_cast(Inst); + if (!ti) { + return func(std::next(Inst->getIterator())); + } + + for (auto *succBlock : ti->getSuccessorBlocks()) { + func(succBlock->begin()); + } + } + static ApplySite getFromOpaqueValue(void *p) { return ApplySite(p); } friend bool operator==(ApplySite lhs, ApplySite rhs) { diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp index d22c2c4caca0b..76341b3f62278 100644 --- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp +++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp @@ -53,21 +53,6 @@ static SILValue stripCopiesAndBorrows(SILValue v) { return v; } -/// If \p applySite is a terminator then pass the first instruction of each -/// successor to fun. Otherwise, pass std::next(applySite). -static void -insertAfterApply(SILInstruction *applySite, - llvm::function_ref &&fun) { - auto *ti = dyn_cast(applySite); - if (!ti) { - return fun(std::next(applySite->getIterator())); - } - - for (auto *succBlocks : ti->getSuccessorBlocks()) { - fun(succBlocks->begin()); - } -} - /// Fixup reference counts after inlining a function call (which is a no-op /// unless the function is a thick function). /// @@ -174,13 +159,12 @@ static void fixupReferenceCounts( // insert a destroy after the apply since the leak will just cover the // other path. if (!error.getFoundOverConsume()) { - insertAfterApply( - applySite.getInstruction(), [&](SILBasicBlock::iterator iter) { - if (hasOwnership) { - SILBuilderWithScope(iter).createEndBorrow(loc, argument); - } - SILBuilderWithScope(iter).emitDestroyValueOperation(loc, copy); - }); + applySite.insertAfter([&](SILBasicBlock::iterator iter) { + if (hasOwnership) { + SILBuilderWithScope(iter).createEndBorrow(loc, argument); + } + SILBuilderWithScope(iter).emitDestroyValueOperation(loc, copy); + }); } v = argument; break; @@ -215,10 +199,9 @@ static void fixupReferenceCounts( } } - insertAfterApply( - applySite.getInstruction(), [&](SILBasicBlock::iterator iter) { - SILBuilderWithScope(iter).emitDestroyValueOperation(loc, v); - }); + applySite.insertAfter([&](SILBasicBlock::iterator iter) { + SILBuilderWithScope(iter).emitDestroyValueOperation(loc, v); + }); break; } @@ -263,10 +246,9 @@ static void fixupReferenceCounts( // Destroy the callee as the apply would have done if our function is not // callee guaranteed. if (!isCalleeGuaranteed) { - insertAfterApply( - applySite.getInstruction(), [&](SILBasicBlock::iterator iter) { - SILBuilderWithScope(iter).emitDestroyValueOperation(loc, calleeValue); - }); + applySite.insertAfter([&](SILBasicBlock::iterator iter) { + SILBuilderWithScope(iter).emitDestroyValueOperation(loc, calleeValue); + }); } }