Skip to content

Commit 3d263bf

Browse files
authored
Merge pull request #73775 from slavapestov/more-sil-cloner-cleanup
More SILCloner cleanups
2 parents 2318b47 + 5511504 commit 3d263bf

File tree

12 files changed

+100
-183
lines changed

12 files changed

+100
-183
lines changed

include/swift/SIL/SILBasicBlock.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ public SwiftObjectHeader {
174174
/// This method unlinks 'self' from the containing SILFunction and deletes it.
175175
void eraseFromParent();
176176

177+
/// Replaces usages of this block with 'undef's and then deletes it.
178+
void removeDeadBlock();
179+
177180
/// Remove all instructions of a SILGlobalVariable's static initializer block.
178181
void clearStaticInitializerBlock(SILModule &module);
179182

include/swift/SIL/SILCloner.h

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -449,29 +449,90 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
449449
SILLocation remapLocation(SILLocation Loc) { return Loc; }
450450
const SILDebugScope *remapScope(const SILDebugScope *DS) { return DS; }
451451

452+
bool shouldSubstOpaqueArchetypes() const { return false; }
453+
452454
SILType remapType(SILType Ty) {
453455
if (Functor.SubsMap || Ty.hasLocalArchetype()) {
454456
Ty = Ty.subst(Builder.getModule(), Functor, Functor,
455457
CanGenericSignature());
456458
}
457459

460+
if (asImpl().shouldSubstOpaqueArchetypes()) {
461+
auto context = getBuilder().getTypeExpansionContext();
462+
463+
if (!Ty.hasOpaqueArchetype() ||
464+
!context.shouldLookThroughOpaqueTypeArchetypes())
465+
return Ty;
466+
467+
// Remap types containing opaque result types in the current context.
468+
Ty = getBuilder().getTypeLowering(Ty).getLoweredType().getCategoryType(
469+
Ty.getCategory());
470+
}
471+
458472
return Ty;
459473
}
460474

461475
CanType remapASTType(CanType ty) {
462476
if (Functor.SubsMap || ty->hasLocalArchetype())
463477
ty = ty.subst(Functor, Functor)->getCanonicalType();
464478

479+
if (asImpl().shouldSubstOpaqueArchetypes()) {
480+
auto context = getBuilder().getTypeExpansionContext();
481+
482+
if (!ty->hasOpaqueArchetype() ||
483+
!context.shouldLookThroughOpaqueTypeArchetypes())
484+
return ty;
485+
486+
// Remap types containing opaque result types in the current context.
487+
return substOpaqueTypesWithUnderlyingTypes(ty, context,
488+
/*allowLoweredTypes=*/false);
489+
}
490+
465491
return ty;
466492
}
467493

468494
ProtocolConformanceRef remapConformance(Type Ty, ProtocolConformanceRef C) {
469-
if (Functor.SubsMap || Ty->hasLocalArchetype())
495+
if (Functor.SubsMap || Ty->hasLocalArchetype()) {
470496
C = C.subst(Ty, Functor, Functor);
497+
if (asImpl().shouldSubstOpaqueArchetypes())
498+
Ty = Ty.subst(Functor, Functor);
499+
}
500+
501+
if (asImpl().shouldSubstOpaqueArchetypes()) {
502+
auto context = getBuilder().getTypeExpansionContext();
503+
504+
if (!Ty->hasOpaqueArchetype() ||
505+
!context.shouldLookThroughOpaqueTypeArchetypes())
506+
return C;
507+
508+
return substOpaqueTypesWithUnderlyingTypes(C, Ty, context);
509+
}
471510

472511
return C;
473512
}
474513

514+
SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) {
515+
// If we have local archetypes to substitute, do so now.
516+
if (Subs.hasLocalArchetypes() || Functor.SubsMap)
517+
Subs = Subs.subst(Functor, Functor);
518+
519+
if (asImpl().shouldSubstOpaqueArchetypes()) {
520+
auto context = getBuilder().getTypeExpansionContext();
521+
522+
if (!Subs.hasOpaqueArchetypes() ||
523+
!context.shouldLookThroughOpaqueTypeArchetypes())
524+
return Subs;
525+
526+
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
527+
context.getContext(), context.getResilienceExpansion(),
528+
context.isWholeModuleContext());
529+
return Subs.subst(replacer, replacer,
530+
SubstFlags::SubstituteOpaqueArchetypes);
531+
}
532+
533+
return Subs;
534+
}
535+
475536
/// Get the value that takes the place of the given `Value` within the cloned
476537
/// region. The given value must already have been mapped by this cloner.
477538
SILValue getMappedValue(SILValue Value);
@@ -481,14 +542,6 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
481542
SILBasicBlock *remapBasicBlock(SILBasicBlock *BB);
482543
void postProcess(SILInstruction *Orig, SILInstruction *Cloned);
483544

484-
SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) {
485-
// If we have local archetypes to substitute, do so now.
486-
if (Subs.hasLocalArchetypes() || Functor.SubsMap)
487-
Subs = Subs.subst(Functor, Functor);
488-
489-
return Subs;
490-
}
491-
492545
/// This is called by either of the top-level visitors, cloneReachableBlocks
493546
/// or cloneSILFunction, after all other visitors are have been called.
494547

include/swift/SIL/TypeSubstCloner.h

Lines changed: 4 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -175,70 +175,15 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
175175
}
176176

177177
protected:
178+
bool shouldSubstOpaqueArchetypes() const { return true; }
179+
178180
SILType remapType(SILType Ty) {
179181
SILType &Sty = TypeCache[Ty];
180-
if (!Sty) {
181-
Sty = Ty;
182-
183-
Sty = Sty.subst(getBuilder().getModule(), Functor, Functor);
184-
185-
auto context = getBuilder().getTypeExpansionContext();
186-
187-
if (!Sty.hasOpaqueArchetype() ||
188-
!context.shouldLookThroughOpaqueTypeArchetypes())
189-
return Sty;
190-
191-
// Remap types containing opaque result types in the current context.
192-
Sty = getBuilder().getTypeLowering(Sty).getLoweredType().getCategoryType(
193-
Sty.getCategory());
194-
}
182+
if (!Sty)
183+
Sty = SILClonerWithScopes<ImplClass>::remapType(Ty);
195184
return Sty;
196185
}
197186

198-
CanType remapASTType(CanType ty) {
199-
auto substTy = ty.subst(Functor, Functor)->getCanonicalType();
200-
201-
auto context = getBuilder().getTypeExpansionContext();
202-
203-
if (!substTy->hasOpaqueArchetype() ||
204-
!context.shouldLookThroughOpaqueTypeArchetypes())
205-
return substTy;
206-
207-
// Remap types containing opaque result types in the current context.
208-
return substOpaqueTypesWithUnderlyingTypes(substTy, context,
209-
/*allowLoweredTypes=*/false);
210-
}
211-
212-
ProtocolConformanceRef remapConformance(Type ty,
213-
ProtocolConformanceRef conf) {
214-
auto substTy = ty.subst(Functor, Functor)->getCanonicalType();
215-
auto substConf = conf.subst(ty, Functor, Functor);
216-
217-
auto context = getBuilder().getTypeExpansionContext();
218-
219-
if (!substTy->hasOpaqueArchetype() ||
220-
!context.shouldLookThroughOpaqueTypeArchetypes())
221-
return substConf;
222-
223-
return substOpaqueTypesWithUnderlyingTypes(substConf, substTy, context);
224-
}
225-
226-
SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) {
227-
Subs = Subs.subst(Functor, Functor);
228-
229-
auto context = getBuilder().getTypeExpansionContext();
230-
231-
if (!Subs.hasOpaqueArchetypes() ||
232-
!context.shouldLookThroughOpaqueTypeArchetypes())
233-
return Subs;
234-
235-
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
236-
context.getContext(), context.getResilienceExpansion(),
237-
context.isWholeModuleContext());
238-
return Subs.subst(replacer, replacer,
239-
SubstFlags::SubstituteOpaqueArchetypes);
240-
}
241-
242187
void visitApplyInst(ApplyInst *Inst) {
243188
ApplySiteCloningHelper Helper(ApplySite(Inst), *this);
244189
ApplyInst *N =

include/swift/SILOptimizer/Utils/BasicBlockOptUtils.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,6 @@ class NonErrorHandlingBlocks {
8383
}
8484
};
8585

86-
/// Remove all instructions in the body of \p bb in safe manner by using
87-
/// undef.
88-
void clearBlockBody(SILBasicBlock *bb);
89-
90-
/// Handle the mechanical aspects of removing an unreachable block.
91-
void removeDeadBlock(SILBasicBlock *bb);
92-
9386
/// Remove all unreachable blocks in a function.
9487
bool removeUnreachableBlocks(SILFunction &f);
9588

lib/SIL/IR/SILBasicBlock.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,29 @@ void SILBasicBlock::eraseFromParent() {
127127
getParent()->eraseBlock(this);
128128
}
129129

130+
/// Handle the mechanical aspects of removing an unreachable block.
131+
void SILBasicBlock::removeDeadBlock() {
132+
for (SILArgument *arg : getArguments()) {
133+
arg->replaceAllUsesWithUndef();
134+
// To appease the ownership verifier, just set to None.
135+
arg->setOwnershipKind(OwnershipKind::None);
136+
}
137+
138+
// Instructions in the dead block may be used by other dead blocks. Replace
139+
// any uses of them with undef values.
140+
while (!empty()) {
141+
// Grab the last instruction in the bb.
142+
auto *inst = &back();
143+
144+
// Replace any still-remaining uses with undef values and erase.
145+
inst->replaceAllUsesOfAllResultsWithUndef();
146+
inst->eraseFromParent();
147+
}
148+
149+
// Now that the bb is empty, eliminate it.
150+
eraseFromParent();
151+
}
152+
130153
void SILBasicBlock::cloneArgumentList(SILBasicBlock *Other) {
131154
assert(Other->isEntry() == isEntry() &&
132155
"Expected to both blocks to be entries or not");

lib/SILGen/SILGenLocalArchetype.cpp

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -110,29 +110,9 @@ class LocalArchetypeTransform : public SILCloner<LocalArchetypeTransform> {
110110
// Insert the new entry block at the beginning.
111111
F.moveBlockBefore(clonedEntryBlock, F.begin());
112112

113-
// FIXME: This should be a common utility.
114-
115113
// Erase the old basic blocks.
116114
for (auto *bb : bbs) {
117-
for (SILArgument *arg : bb->getArguments()) {
118-
arg->replaceAllUsesWithUndef();
119-
// To appease the ownership verifier, just set to None.
120-
arg->setOwnershipKind(OwnershipKind::None);
121-
}
122-
123-
// Instructions in the dead block may be used by other dead blocks. Replace
124-
// any uses of them with undef values.
125-
while (!bb->empty()) {
126-
// Grab the last instruction in the bb.
127-
auto *inst = &bb->back();
128-
129-
// Replace any still-remaining uses with undef values and erase.
130-
inst->replaceAllUsesOfAllResultsWithUndef();
131-
inst->eraseFromParent();
132-
}
133-
134-
// Finally, erase the basic block itself.
135-
bb->eraseFromParent();
115+
bb->removeDeadBlock();
136116
}
137117
}
138118
};

lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ void ExistentialTransform::populateThunkBody() {
380380
/// Remove original body of F.
381381
for (auto It = F->begin(), End = F->end(); It != End;) {
382382
auto *BB = &*It++;
383-
removeDeadBlock(BB);
383+
BB->removeDeadBlock();
384384
}
385385

386386
/// Create a basic block and the function arguments.

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ bool SimplifyCFG::removeIfDead(SILBasicBlock *BB) {
642642
addToWorklist(S);
643643

644644
LLVM_DEBUG(llvm::dbgs() << "remove dead bb" << BB->getDebugID() << '\n');
645-
removeDeadBlock(BB);
645+
BB->removeDeadBlock();
646646
++NumBlocksDeleted;
647647
return true;
648648
}
@@ -1782,7 +1782,7 @@ bool SimplifyCFG::simplifySwitchEnumUnreachableBlocks(SwitchEnumInst *SEI) {
17821782
addToWorklist(SEI->getParent());
17831783
SILBuilderWithScope(SEI).createUnreachable(SEI->getLoc());
17841784
for (auto &succ : SEI->getSuccessors()) {
1785-
removeDeadBlock(succ.getBB());
1785+
succ.getBB()->removeDeadBlock();
17861786
}
17871787
SEI->eraseFromParent();
17881788
return true;

lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -40,56 +40,7 @@ class MapOpaqueArchetypes : public SILCloner<MapOpaqueArchetypes> {
4040
clonedEntryBlock = fun.createBasicBlock();
4141
}
4242

43-
SILType remapType(SILType Ty) {
44-
// Substitute local archetypes, if we have any.
45-
if (Ty.hasLocalArchetype()) {
46-
Ty = Ty.subst(getBuilder().getModule(), Functor, Functor,
47-
CanGenericSignature());
48-
}
49-
50-
if (!Ty.hasOpaqueArchetype() ||
51-
!getBuilder()
52-
.getTypeExpansionContext()
53-
.shouldLookThroughOpaqueTypeArchetypes())
54-
return Ty;
55-
56-
return getBuilder().getTypeLowering(Ty).getLoweredType().getCategoryType(
57-
Ty.getCategory());
58-
}
59-
60-
CanType remapASTType(CanType ty) {
61-
// Substitute local archetypes, if we have any.
62-
if (ty->hasLocalArchetype())
63-
ty = ty.subst(Functor, Functor)->getCanonicalType();
64-
65-
if (!ty->hasOpaqueArchetype() ||
66-
!getBuilder()
67-
.getTypeExpansionContext()
68-
.shouldLookThroughOpaqueTypeArchetypes())
69-
return ty;
70-
71-
return substOpaqueTypesWithUnderlyingTypes(
72-
ty,
73-
TypeExpansionContext(getBuilder().getFunction()),
74-
/*allowLoweredTypes=*/false);
75-
}
76-
77-
ProtocolConformanceRef remapConformance(Type ty,
78-
ProtocolConformanceRef conf) {
79-
// If we have local archetypes to substitute, do so now.
80-
if (ty->hasLocalArchetype()) {
81-
conf = conf.subst(ty, Functor, Functor);
82-
ty = ty.subst(Functor, Functor);
83-
}
84-
85-
auto context = getBuilder().getTypeExpansionContext();
86-
if (ty->hasOpaqueArchetype() &&
87-
context.shouldLookThroughOpaqueTypeArchetypes()) {
88-
conf =
89-
substOpaqueTypesWithUnderlyingTypes(conf, ty, context);
90-
}
91-
return conf;
92-
}
43+
bool shouldSubstOpaqueArchetypes() const { return true; }
9344

9445
void replace();
9546
};

lib/SILOptimizer/Utils/BasicBlockOptUtils.cpp

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -67,37 +67,6 @@ NonErrorHandlingBlocks::NonErrorHandlingBlocks(SILFunction *function)
6767
}
6868
}
6969

70-
/// Remove all instructions in the body of \p bb in safe manner by using
71-
/// undef.
72-
void swift::clearBlockBody(SILBasicBlock *bb) {
73-
74-
for (SILArgument *arg : bb->getArguments()) {
75-
arg->replaceAllUsesWithUndef();
76-
// To appease the ownership verifier, just set to None.
77-
arg->setOwnershipKind(OwnershipKind::None);
78-
}
79-
80-
// Instructions in the dead block may be used by other dead blocks. Replace
81-
// any uses of them with undef values.
82-
while (!bb->empty()) {
83-
// Grab the last instruction in the bb.
84-
auto *inst = &bb->back();
85-
86-
// Replace any still-remaining uses with undef values and erase.
87-
inst->replaceAllUsesOfAllResultsWithUndef();
88-
inst->eraseFromParent();
89-
}
90-
}
91-
92-
// Handle the mechanical aspects of removing an unreachable block.
93-
void swift::removeDeadBlock(SILBasicBlock *bb) {
94-
// Clear the body of bb.
95-
clearBlockBody(bb);
96-
97-
// Now that the bb is empty, eliminate it.
98-
bb->eraseFromParent();
99-
}
100-
10170
bool swift::removeUnreachableBlocks(SILFunction &f) {
10271
ReachableBlocks reachable(&f);
10372
// Visit all the blocks without doing any extra work.
@@ -109,7 +78,7 @@ bool swift::removeUnreachableBlocks(SILFunction &f) {
10978
for (auto ii = std::next(f.begin()), end = f.end(); ii != end;) {
11079
auto *bb = &*ii++;
11180
if (!reachable.isVisited(bb)) {
112-
removeDeadBlock(bb);
81+
bb->removeDeadBlock();
11382
changed = true;
11483
}
11584
}

0 commit comments

Comments
 (0)