Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions include/swift/SIL/ApplySite.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<void(SILBasicBlock::iterator)> func) {
auto *ti = dyn_cast<TermInst>(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) {
Expand Down
42 changes: 12 additions & 30 deletions lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<void(SILBasicBlock::iterator)> &&fun) {
auto *ti = dyn_cast<TermInst>(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).
///
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
});
}
}

Expand Down