Skip to content

Commit acebbdc

Browse files
authored
Merge pull request #2028 from swiftwasm/main
[pull] swiftwasm from main
2 parents 9ef12c3 + 5d30503 commit acebbdc

File tree

18 files changed

+478
-329
lines changed

18 files changed

+478
-329
lines changed

include/swift/SIL/ApplySite.h

+8-42
Original file line numberDiff line numberDiff line change
@@ -585,62 +585,28 @@ class FullApplySite : public ApplySite {
585585
llvm_unreachable("Covered switch isn't covered?!");
586586
}
587587

588-
/// If this is a terminator apply site, then pass the first instruction of
589-
/// each successor to fun. Otherwise, pass std::next(Inst).
588+
/// If this is a terminator apply site, then pass a builder to insert at the
589+
/// first instruction of each successor to \p func. Otherwise, pass a builder
590+
/// to insert at std::next(Inst).
590591
///
591592
/// The intention is that this abstraction will enable the compiler writer to
592593
/// ignore whether or not an apply site is a terminator when inserting
593594
/// instructions after an apply site. This results in eliminating unnecessary
594595
/// if-else code otherwise required to handle such situations.
595596
///
596-
/// NOTE: We return std::next() for begin_apply. If one wishes to insert code
597+
/// NOTE: We pass std::next() for begin_apply. If one wishes to insert code
597598
/// /after/ the end_apply/abort_apply, please use instead
598599
/// insertAfterFullEvaluation.
599-
void insertAfterInvocation(
600-
function_ref<void(SILBasicBlock::iterator)> func) const {
601-
switch (getKind()) {
602-
case FullApplySiteKind::ApplyInst:
603-
case FullApplySiteKind::BeginApplyInst:
604-
return func(std::next(getInstruction()->getIterator()));
605-
case FullApplySiteKind::TryApplyInst:
606-
for (auto *succBlock :
607-
cast<TermInst>(getInstruction())->getSuccessorBlocks()) {
608-
func(succBlock->begin());
609-
}
610-
return;
611-
}
612-
llvm_unreachable("Covered switch isn't covered");
613-
}
600+
void insertAfterInvocation(function_ref<void(SILBuilder &)> func) const;
614601

615-
/// Pass to func insertion points that are guaranteed to be immediately after
616-
/// this full apply site has completely finished executing.
602+
/// Pass a builder with insertion points that are guaranteed to be immediately
603+
/// after this full apply site has completely finished executing.
617604
///
618605
/// This is just like insertAfterInvocation except that if the full apply site
619606
/// is a begin_apply, we pass the insertion points after the end_apply,
620607
/// abort_apply rather than an insertion point right after the
621608
/// begin_apply. For such functionality, please invoke insertAfterInvocation.
622-
void insertAfterFullEvaluation(
623-
function_ref<void(SILBasicBlock::iterator)> func) const {
624-
switch (getKind()) {
625-
case FullApplySiteKind::ApplyInst:
626-
case FullApplySiteKind::TryApplyInst:
627-
return insertAfterInvocation(func);
628-
case FullApplySiteKind::BeginApplyInst:
629-
SmallVector<EndApplyInst *, 2> endApplies;
630-
SmallVector<AbortApplyInst *, 2> abortApplies;
631-
auto *bai = cast<BeginApplyInst>(getInstruction());
632-
bai->getCoroutineEndPoints(endApplies, abortApplies);
633-
for (auto *eai : endApplies) {
634-
func(std::next(eai->getIterator()));
635-
}
636-
for (auto *aai : abortApplies) {
637-
func(std::next(aai->getIterator()));
638-
}
639-
return;
640-
}
641-
642-
llvm_unreachable("covered switch isn't covered");
643-
}
609+
void insertAfterFullEvaluation(function_ref<void(SILBuilder &)> func) const;
644610

645611
/// Returns true if \p op is an operand that passes an indirect
646612
/// result argument to the apply site.

include/swift/SIL/SILBuilder.h

+14
Original file line numberDiff line numberDiff line change
@@ -2499,6 +2499,20 @@ class SILBuilderWithScope : public SILBuilder {
24992499
assert(DS && "Instruction without debug scope associated!");
25002500
setCurrentDebugScope(DS);
25012501
}
2502+
2503+
/// If \p inst is a terminator apply site, then pass a builder to insert at
2504+
/// the first instruction of each successor to \p func. Otherwise, pass a
2505+
/// builder to insert at std::next(inst).
2506+
///
2507+
/// The intention is that this abstraction will enable the compiler writer to
2508+
/// ignore whether or not \p inst is a terminator when inserting instructions
2509+
/// after \p inst.
2510+
///
2511+
/// Precondition: It's the responsibility of the caller to ensure that if
2512+
/// \p inst is a terminator, all successor blocks have only a single
2513+
/// predecessor block: the parent of \p inst.
2514+
static void insertAfter(SILInstruction *inst,
2515+
function_ref<void(SILBuilder &)> func);
25022516
};
25032517

25042518
class SavedInsertionPointRAII {

lib/SIL/IR/ApplySite.cpp

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===--- ApplySite.cpp - Wrapper around apply instructions ----------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "swift/SIL/ApplySite.h"
14+
#include "swift/SIL/SILBuilder.h"
15+
16+
17+
using namespace swift;
18+
19+
void FullApplySite::insertAfterInvocation(function_ref<void(SILBuilder &)> func) const {
20+
SILBuilderWithScope::insertAfter(getInstruction(), func);
21+
}
22+
23+
void FullApplySite::insertAfterFullEvaluation(
24+
function_ref<void(SILBuilder &)> func) const {
25+
switch (getKind()) {
26+
case FullApplySiteKind::ApplyInst:
27+
case FullApplySiteKind::TryApplyInst:
28+
return insertAfterInvocation(func);
29+
case FullApplySiteKind::BeginApplyInst:
30+
SmallVector<EndApplyInst *, 2> endApplies;
31+
SmallVector<AbortApplyInst *, 2> abortApplies;
32+
auto *bai = cast<BeginApplyInst>(getInstruction());
33+
bai->getCoroutineEndPoints(endApplies, abortApplies);
34+
for (auto *eai : endApplies) {
35+
SILBuilderWithScope builder(std::next(eai->getIterator()));
36+
func(builder);
37+
}
38+
for (auto *aai : abortApplies) {
39+
SILBuilderWithScope builder(std::next(aai->getIterator()));
40+
func(builder);
41+
}
42+
return;
43+
}
44+
llvm_unreachable("covered switch isn't covered");
45+
}
46+

lib/SIL/IR/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
target_sources(swiftSIL PRIVATE
22
AbstractionPattern.cpp
3+
ApplySite.cpp
34
Bridging.cpp
45
Linker.cpp
56
Notifications.cpp

lib/SIL/IR/SILBuilder.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -661,3 +661,19 @@ CheckedCastBranchInst *SILBuilder::createCheckedCastBranch(
661661
destLoweredTy, destFormalTy, successBB, failureBB,
662662
getFunction(), C.OpenedArchetypes, target1Count, target2Count));
663663
}
664+
665+
void SILBuilderWithScope::insertAfter(SILInstruction *inst,
666+
function_ref<void(SILBuilder &)> func) {
667+
if (isa<TermInst>(inst)) {
668+
for (const SILSuccessor &succ : inst->getParent()->getSuccessors()) {
669+
SILBasicBlock *succBlock = succ;
670+
assert(succBlock->getSinglePredecessorBlock() == inst->getParent() &&
671+
"the terminator instruction must not have critical successors");
672+
SILBuilderWithScope builder(succBlock->begin());
673+
func(builder);
674+
}
675+
} else {
676+
SILBuilderWithScope builder(std::next(inst->getIterator()));
677+
func(builder);
678+
}
679+
}

lib/SILOptimizer/Analysis/MemoryBehavior.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ static bool hasEscapingUses(SILValue address, int &numChecks) {
364364
case SILInstructionKind::CopyAddrInst:
365365
case SILInstructionKind::DestroyAddrInst:
366366
case SILInstructionKind::DeallocStackInst:
367+
case SILInstructionKind::EndAccessInst:
367368
// Those instructions have no result and cannot escape the address.
368369
break;
369370
case SILInstructionKind::ApplyInst:
@@ -373,6 +374,7 @@ static bool hasEscapingUses(SILValue address, int &numChecks) {
373374
// possible that an address, passed as an indirect parameter, escapes
374375
// the function in any way (which is not unsafe and undefined behavior).
375376
break;
377+
case SILInstructionKind::BeginAccessInst:
376378
case SILInstructionKind::OpenExistentialAddrInst:
377379
case SILInstructionKind::UncheckedTakeEnumDataAddrInst:
378380
case SILInstructionKind::StructElementAddrInst:

lib/SILOptimizer/Mandatory/MandatoryInlining.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ static bool fixupReferenceCounts(
123123
});
124124

125125
if (!consumedInLoop) {
126-
applySite.insertAfterInvocation([&](SILBasicBlock::iterator iter) {
127-
SILBuilderWithScope(iter).createDestroyAddr(loc, stackLoc);
128-
SILBuilderWithScope(iter).createDeallocStack(loc, stackLoc);
126+
applySite.insertAfterInvocation([&](SILBuilder &builder) {
127+
builder.createDestroyAddr(loc, stackLoc);
128+
builder.createDeallocStack(loc, stackLoc);
129129
});
130130
}
131131
v = stackLoc;
@@ -176,11 +176,11 @@ static bool fixupReferenceCounts(
176176
// uses in the top of a diamond and need to insert a destroy after the
177177
// apply since the leak will just cover the other path.
178178
if (!consumedInLoop) {
179-
applySite.insertAfterInvocation([&](SILBasicBlock::iterator iter) {
179+
applySite.insertAfterInvocation([&](SILBuilder &builder) {
180180
if (hasOwnership) {
181-
SILBuilderWithScope(iter).createEndBorrow(loc, argument);
181+
builder.createEndBorrow(loc, argument);
182182
}
183-
SILBuilderWithScope(iter).emitDestroyValueOperation(loc, copy);
183+
builder.emitDestroyValueOperation(loc, copy);
184184
});
185185
}
186186
v = argument;
@@ -217,8 +217,8 @@ static bool fixupReferenceCounts(
217217

218218
// Then insert destroys after the apply site since our value is not being
219219
// consumed as part of the actual apply.
220-
applySite.insertAfterInvocation([&](SILBasicBlock::iterator iter) {
221-
SILBuilderWithScope(iter).emitDestroyValueOperation(loc, v);
220+
applySite.insertAfterInvocation([&](SILBuilder &builder) {
221+
builder.emitDestroyValueOperation(loc, v);
222222
});
223223
break;
224224
}
@@ -263,8 +263,8 @@ static bool fixupReferenceCounts(
263263
// Destroy the callee as the apply would have done if our function is not
264264
// callee guaranteed.
265265
if (!isCalleeGuaranteed) {
266-
applySite.insertAfterInvocation([&](SILBasicBlock::iterator iter) {
267-
SILBuilderWithScope(iter).emitDestroyValueOperation(loc, calleeValue);
266+
applySite.insertAfterInvocation([&](SILBuilder &builder) {
267+
builder.emitDestroyValueOperation(loc, calleeValue);
268268
});
269269
}
270270
return invalidatedStackNesting;

0 commit comments

Comments
 (0)