Skip to content

Commit af158aa

Browse files
authored
Merge pull request #2348 from swiftwasm/main
[pull] swiftwasm from main
2 parents 16d581f + 8f136f3 commit af158aa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+388
-110
lines changed

include/swift/SILOptimizer/Analysis/EscapeAnalysis.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,10 @@ class EscapeAnalysis : public BottomUpIPAnalysis {
11581158
/// Note that if \p RI is a retain-instruction always false is returned.
11591159
bool canEscapeTo(SILValue V, RefCountingInst *RI);
11601160

1161+
/// Returns true if the value \p V can escape to the destroy_value instruction
1162+
/// \p DVI.
1163+
bool canEscapeTo(SILValue V, DestroyValueInst *DVI);
1164+
11611165
/// Return true if \p releasedReference deinitialization may release memory
11621166
/// pointed to by \p accessedAddress.
11631167
bool mayReleaseContent(SILValue releasedReference, SILValue accessedAddress);

lib/SILOptimizer/Analysis/EscapeAnalysis.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,7 @@ void EscapeAnalysis::ConnectionGraph::computeUsePoints() {
870870
#include "swift/AST/ReferenceStorage.def"
871871
case SILInstructionKind::StrongReleaseInst:
872872
case SILInstructionKind::ReleaseValueInst:
873+
case SILInstructionKind::DestroyValueInst:
873874
case SILInstructionKind::ApplyInst:
874875
case SILInstructionKind::TryApplyInst: {
875876
/// Actually we only add instructions which may release a reference.
@@ -2589,8 +2590,9 @@ bool EscapeAnalysis::canEscapeToUsePoint(SILValue value,
25892590
SILInstruction *usePoint,
25902591
ConnectionGraph *conGraph) {
25912592

2592-
assert((FullApplySite::isa(usePoint) || isa<RefCountingInst>(usePoint))
2593-
&& "use points are only created for calls and refcount instructions");
2593+
assert((FullApplySite::isa(usePoint) || isa<RefCountingInst>(usePoint) ||
2594+
isa<DestroyValueInst>(usePoint)) &&
2595+
"use points are only created for calls and refcount instructions");
25942596

25952597
CGNode *node = conGraph->getValueContent(value);
25962598
if (!node)
@@ -2649,6 +2651,14 @@ bool EscapeAnalysis::canEscapeTo(SILValue V, RefCountingInst *RI) {
26492651
return canEscapeToUsePoint(V, RI, ConGraph);
26502652
}
26512653

2654+
bool EscapeAnalysis::canEscapeTo(SILValue V, DestroyValueInst *DVI) {
2655+
// If it's not uniquely identified we don't know anything about the value.
2656+
if (!isUniquelyIdentified(V))
2657+
return true;
2658+
auto *ConGraph = getConnectionGraph(DVI->getFunction());
2659+
return canEscapeToUsePoint(V, DVI, ConGraph);
2660+
}
2661+
26522662
/// Utility to get the function which contains both values \p V1 and \p V2.
26532663
static SILFunction *getCommonFunction(SILValue V1, SILValue V2) {
26542664
SILBasicBlock *BB1 = V1->getParentBlock();

lib/SILOptimizer/Analysis/MemoryBehavior.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ class MemoryBehaviorVisitor
182182
MemBehavior visitBuiltinInst(BuiltinInst *BI);
183183
MemBehavior visitStrongReleaseInst(StrongReleaseInst *BI);
184184
MemBehavior visitReleaseValueInst(ReleaseValueInst *BI);
185+
MemBehavior visitDestroyValueInst(DestroyValueInst *DVI);
185186
MemBehavior visitSetDeallocatingInst(SetDeallocatingInst *BI);
186187
MemBehavior visitBeginCOWMutationInst(BeginCOWMutationInst *BCMI);
187188
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
@@ -225,6 +226,7 @@ class MemoryBehaviorVisitor
225226
}
226227
REFCOUNTINC_MEMBEHAVIOR_INST(StrongRetainInst)
227228
REFCOUNTINC_MEMBEHAVIOR_INST(RetainValueInst)
229+
REFCOUNTINC_MEMBEHAVIOR_INST(CopyValueInst)
228230
#define UNCHECKED_REF_STORAGE(Name, ...) \
229231
REFCOUNTINC_MEMBEHAVIOR_INST(Name##RetainValueInst) \
230232
REFCOUNTINC_MEMBEHAVIOR_INST(StrongCopy##Name##ValueInst)
@@ -490,6 +492,13 @@ MemBehavior MemoryBehaviorVisitor::visitReleaseValueInst(ReleaseValueInst *SI) {
490492
return MemBehavior::MayHaveSideEffects;
491493
}
492494

495+
MemBehavior
496+
MemoryBehaviorVisitor::visitDestroyValueInst(DestroyValueInst *DVI) {
497+
if (!EA->canEscapeTo(V, DVI))
498+
return MemBehavior::None;
499+
return MemBehavior::MayHaveSideEffects;
500+
}
501+
493502
MemBehavior MemoryBehaviorVisitor::visitSetDeallocatingInst(SetDeallocatingInst *SDI) {
494503
return MemBehavior::None;
495504
}

lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,7 @@ std::string ExistentialTransform::createExistentialSpecializedFunctionName() {
292292
int Idx = IdxIt.first;
293293
Mangler.setArgumentExistentialToGeneric(Idx);
294294
}
295-
auto MangledName = Mangler.mangle();
296-
assert(!F->getModule().hasFunction(MangledName));
297-
return MangledName;
295+
return Mangler.mangle();
298296
}
299297

300298
/// Convert all existential argument types to generic argument type.
@@ -642,41 +640,47 @@ void ExistentialTransform::populateThunkBody() {
642640
/// its inline strategy as always inline.
643641
void ExistentialTransform::createExistentialSpecializedFunction() {
644642
std::string Name = createExistentialSpecializedFunctionName();
645-
SILLinkage linkage = getSpecializedLinkage(F, F->getLinkage());
646643

647-
/// Create devirtualized function type.
644+
/// Create devirtualized function type and populate ArgToGenericTypeMap.
648645
auto NewFTy = createExistentialSpecializedFunctionType();
649646

650-
auto NewFGenericSig = NewFTy->getInvocationGenericSignature();
651-
auto NewFGenericEnv = NewFGenericSig->getGenericEnvironment();
652-
653647
/// Step 1: Create the new protocol constrained generic function.
654-
NewF = FunctionBuilder.createFunction(
648+
if (auto *CachedFn = F->getModule().lookUpFunction(Name)) {
649+
// The specialized body still exists (because it is now called directly),
650+
// but the thunk has been dead-code eliminated.
651+
assert(CachedFn->getLoweredFunctionType() == NewFTy);
652+
NewF = CachedFn;
653+
} else {
654+
auto NewFGenericSig = NewFTy->getInvocationGenericSignature();
655+
auto NewFGenericEnv = NewFGenericSig->getGenericEnvironment();
656+
SILLinkage linkage = getSpecializedLinkage(F, F->getLinkage());
657+
658+
NewF = FunctionBuilder.createFunction(
655659
linkage, Name, NewFTy, NewFGenericEnv, F->getLocation(), F->isBare(),
656660
F->isTransparent(), F->isSerialized(), IsNotDynamic, F->getEntryCount(),
657661
F->isThunk(), F->getClassSubclassScope(), F->getInlineStrategy(),
658662
F->getEffectsKind(), nullptr, F->getDebugScope());
659-
/// Set the semantics attributes for the new function.
660-
for (auto &Attr : F->getSemanticsAttrs())
661-
NewF->addSemanticsAttr(Attr);
662663

663-
/// Set Unqualified ownership, if any.
664-
if (!F->hasOwnership()) {
665-
NewF->setOwnershipEliminated();
666-
}
664+
/// Set the semantics attributes for the new function.
665+
for (auto &Attr : F->getSemanticsAttrs())
666+
NewF->addSemanticsAttr(Attr);
667667

668-
/// Step 1a: Populate the body of NewF.
669-
SubstitutionMap Subs = SubstitutionMap::get(
668+
/// Set Unqualified ownership, if any.
669+
if (!F->hasOwnership()) {
670+
NewF->setOwnershipEliminated();
671+
}
672+
/// Step 1a: Populate the body of NewF.
673+
SubstitutionMap Subs = SubstitutionMap::get(
670674
NewFGenericSig,
671675
[&](SubstitutableType *type) -> Type {
672676
return NewFGenericEnv->mapTypeIntoContext(type);
673677
},
674678
LookUpConformanceInModule(F->getModule().getSwiftModule()));
675-
ExistentialSpecializerCloner cloner(F, NewF, Subs, ArgumentDescList,
676-
ArgToGenericTypeMap,
677-
ExistentialArgDescriptor);
678-
cloner.cloneAndPopulateFunction();
679-
679+
ExistentialSpecializerCloner cloner(F, NewF, Subs, ArgumentDescList,
680+
ArgToGenericTypeMap,
681+
ExistentialArgDescriptor);
682+
cloner.cloneAndPopulateFunction();
683+
}
680684
/// Step 2: Create the thunk with always_inline and populate its body.
681685
populateThunkBody();
682686

lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -146,15 +146,6 @@ static bool inline isPerformingRLE(RLEKind Kind) {
146146
/// general sense but are inert from a load store perspective.
147147
static bool isRLEInertInstruction(SILInstruction *Inst) {
148148
switch (Inst->getKind()) {
149-
#define UNCHECKED_REF_STORAGE(Name, ...) \
150-
case SILInstructionKind::StrongCopy##Name##ValueInst:
151-
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
152-
case SILInstructionKind::Name##RetainInst: \
153-
case SILInstructionKind::StrongRetain##Name##Inst: \
154-
case SILInstructionKind::StrongCopy##Name##ValueInst:
155-
#include "swift/AST/ReferenceStorage.def"
156-
case SILInstructionKind::StrongRetainInst:
157-
case SILInstructionKind::RetainValueInst:
158149
case SILInstructionKind::DeallocStackInst:
159150
case SILInstructionKind::CondFailInst:
160151
case SILInstructionKind::IsEscapingClosureInst:

lib/SILOptimizer/UtilityPasses/EscapeAnalysisDumper.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ class EscapeAnalysisDumper : public SILModuleTransform {
8585
<< " to " << ii;
8686
}
8787
}
88+
if (DestroyValueInst *dvi = dyn_cast<DestroyValueInst>(&ii)) {
89+
for (unsigned i = 0, e = Values.size(); i != e; ++i) {
90+
SILValue val = Values[i];
91+
bool escape = EA->canEscapeTo(val, dvi);
92+
llvm::outs() << (escape ? "May" : "No") << "Escape: " << val
93+
<< " to " << ii;
94+
}
95+
}
8896
}
8997
}
9098
}

test/Driver/Dependencies/check-interface-implementation-fine.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
// CHECK-FIRST: Handled c.swift
1515
// CHECK-FIRST: Handled bad.swift
1616

17-
// CHECK-RECORD-CLEAN-DAG: "./a.swift": [
18-
// CHECK-RECORD-CLEAN-DAG: "./bad.swift": [
19-
// CHECK-RECORD-CLEAN-DAG: "./c.swift": [
17+
// CHECK-RECORD-CLEAN-DAG: "{{(./)?}}a.swift": [
18+
// CHECK-RECORD-CLEAN-DAG: "{{(./)?}}bad.swift": [
19+
// CHECK-RECORD-CLEAN-DAG: "{{(./)?}}c.swift": [
2020

2121

2222
// RUN: touch -t 201401240006 %t/a.swift
@@ -29,9 +29,9 @@
2929
// CHECK-A: Handled bad.swift
3030
// NEGATIVE-A-NOT: Handled c.swift
3131

32-
// CHECK-RECORD-A-DAG: "./a.swift": [
33-
// CHECK-RECORD-A-DAG: "./bad.swift": !private [
34-
// CHECK-RECORD-A-DAG: "./c.swift": !private [
32+
// CHECK-RECORD-A-DAG: "{{(./)?}}a.swift": [
33+
// CHECK-RECORD-A-DAG: "{{(./)?}}bad.swift": !private [
34+
// CHECK-RECORD-A-DAG: "{{(./)?}}c.swift": !private [
3535

3636
// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path "%{python.unquoted};%S/Inputs/update-dependencies.py;%swift-dependency-tool" -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./a.swift ./bad.swift ./c.swift -module-name main -j1 -v -driver-show-incremental 2>&1 | %FileCheck -check-prefix CHECK-BC %s
3737

test/Driver/Dependencies/crash-added-fine.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
// CHECK-ADDED: Handled crash.swift
1818
// CHECK-ADDED-NOT: Handled
1919

20-
// CHECK-RECORD-ADDED-DAG: "./crash.swift": !private [
21-
// CHECK-RECORD-ADDED-DAG: "./main.swift": [
22-
// CHECK-RECORD-ADDED-DAG: "./other.swift": [
20+
// CHECK-RECORD-ADDED-DAG: "{{(./)?}}crash.swift": !private [
21+
// CHECK-RECORD-ADDED-DAG: "{{(./)?}}main.swift": [
22+
// CHECK-RECORD-ADDED-DAG: "{{(./)?}}other.swift": [
2323

2424

2525
// RUN: %empty-directory(%t)

test/Driver/Dependencies/crash-simple-fine.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020

2121
// RUN: %FileCheck -check-prefix=CHECK-RECORD %s < %t/main~buildrecord.swiftdeps
2222

23-
// CHECK-RECORD-DAG: "./crash.swift": !private [
24-
// CHECK-RECORD-DAG: "./main.swift": !private [
25-
// CHECK-RECORD-DAG: "./other.swift": !private [
23+
// CHECK-RECORD-DAG: "{{(./)?}}crash.swift": !private [
24+
// CHECK-RECORD-DAG: "{{(./)?}}main.swift": !private [
25+
// CHECK-RECORD-DAG: "{{(./)?}}other.swift": !private [
2626

2727
// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path "%{python.unquoted};%S/Inputs/update-dependencies.py;%swift-dependency-tool" -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./crash.swift ./main.swift ./other.swift -module-name main -j1 -v 2>&1 | %FileCheck -check-prefix=CHECK-THIRD %s
2828

test/Driver/Dependencies/dependencies-preservation-fine.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
// CHECK-OVERWRITTEN: options: "{{.*}}"
1717
// CHECK-OVERWRITTEN: build_time: [{{[0-9]*}}, {{[0-9]*}}]
1818
// CHECK-OVERWRITTEN: inputs:
19-
// CHECK-OVERWRITTEN: "./main.swift": [443865900, 0]
20-
// CHECK-OVERWRITTEN: "./other.swift": [443865900, 0]
19+
// CHECK-OVERWRITTEN: "{{(./)?}}main.swift": [443865900, 0]
20+
// CHECK-OVERWRITTEN: "{{(./)?}}other.swift": [443865900, 0]

0 commit comments

Comments
 (0)