Skip to content

Commit 8278332

Browse files
committed
SILCloner should not introduce new critical edges.
Also, it must update the DomTree for any CFG changes except for the addition of cloned blocks.
1 parent f5b5147 commit 8278332

File tree

4 files changed

+38
-14
lines changed

4 files changed

+38
-14
lines changed

include/swift/SIL/SILCloner.h

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
#define SWIFT_SIL_SILCLONER_H
1919

2020
#include "swift/AST/ProtocolConformance.h"
21-
#include "swift/SIL/SILOpenedArchetypesTracker.h"
21+
#include "swift/SIL/BasicBlockUtils.h"
22+
#include "swift/SIL/Dominance.h"
2223
#include "swift/SIL/SILBuilder.h"
2324
#include "swift/SIL/SILDebugScope.h"
25+
#include "swift/SIL/SILOpenedArchetypesTracker.h"
2426
#include "swift/SIL/SILVisitor.h"
2527

2628
namespace swift {
@@ -44,6 +46,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
4446
/// MARK: Context shared with CRTP extensions.
4547

4648
SILBuilder Builder;
49+
DominanceInfo *DomTree = nullptr;
4750
TypeSubstitutionMap OpenedExistentialSubs;
4851
SILOpenedArchetypesTracker OpenedArchetypesTracker;
4952

@@ -75,12 +78,15 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
7578
using SILInstructionVisitor<ImplClass>::asImpl;
7679

7780
explicit SILCloner(SILFunction &F,
78-
SILOpenedArchetypesTracker &OpenedArchetypesTracker)
79-
: Builder(F), OpenedArchetypesTracker(OpenedArchetypesTracker) {
81+
SILOpenedArchetypesTracker &OpenedArchetypesTracker,
82+
DominanceInfo *DT = nullptr)
83+
: Builder(F), DomTree(DT),
84+
OpenedArchetypesTracker(OpenedArchetypesTracker) {
8085
Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
8186
}
8287

83-
explicit SILCloner(SILFunction &F) : Builder(F), OpenedArchetypesTracker(&F) {
88+
explicit SILCloner(SILFunction &F, DominanceInfo *DT = nullptr)
89+
: Builder(F), DomTree(DT), OpenedArchetypesTracker(&F) {
8490
Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
8591
}
8692

@@ -442,8 +448,9 @@ class SILClonerWithScopes : public SILCloner<ImplClass> {
442448
public:
443449
SILClonerWithScopes(SILFunction &To,
444450
SILOpenedArchetypesTracker &OpenedArchetypesTracker,
451+
DominanceInfo *DT = nullptr,
445452
bool Disable = false)
446-
: SILCloner<ImplClass>(To, OpenedArchetypesTracker) {
453+
: SILCloner<ImplClass>(To, OpenedArchetypesTracker, DT) {
447454

448455
// We only want to do this when we generate cloned functions, not
449456
// when we inline.
@@ -694,17 +701,36 @@ void SILCloner<ImplClass>::visitBlocksDepthFirst(SILBasicBlock *startBB) {
694701
asImpl().visitInstructionsInBlock(BB);
695702

696703
unsigned dfsSuccStartIdx = dfsWorklist.size();
697-
for (auto &succ : BB->getSuccessors()) {
704+
705+
// splitEdge may rewrite BB's successors during this loop.
706+
for (unsigned succIdx = 0, numSucc = BB->getSuccessors().size();
707+
succIdx != numSucc; ++succIdx) {
708+
698709
// Only visit a successor that has not already been visited and was not
699710
// premapped by the client.
700-
if (BBMap.count(succ))
701-
continue;
702-
711+
if (BBMap.count(BB->getSuccessors()[succIdx])) {
712+
// After cloning BB, this successor may be a new CFG merge. If it is
713+
// valid to branch directly from the BB to its clone do nothing; if not,
714+
// split the edge from BB->succ and clone the new block.
715+
//
716+
// A CFG merge may require new block arguments, so check for both a
717+
// critical edge and the ability to add branch arguments (BranchInst).
718+
if (BB->getSingleSuccessorBlock()
719+
&& isa<BranchInst>(BB->getTerminator())) {
720+
continue;
721+
}
722+
// This predecessor has multiple successors, so cloning it without
723+
// cloning its successors would create a critical edge.
724+
splitEdge(BB->getTerminator(), succIdx, DomTree);
725+
assert(!BBMap.count(BB->getSuccessors()[succIdx]));
726+
}
703727
// Map the successor to a new BB. Layout the cloned blocks in the order
704728
// they are visited and cloned.
705729
lastClonedBB =
706730
getBuilder().getFunction().createBasicBlockAfter(lastClonedBB);
707731

732+
// After splitting, BB has stable successors.
733+
auto &succ = BB->getSuccessors()[succIdx];
708734
BBMap.insert(std::make_pair(succ.getBB(), lastClonedBB));
709735

710736
dfsWorklist.push_back(succ);

include/swift/SIL/TypeSubstCloner.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,9 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
144144
SILFunction &From,
145145
SubstitutionMap ApplySubs,
146146
SILOpenedArchetypesTracker &OpenedArchetypesTracker,
147+
DominanceInfo *DT = nullptr,
147148
bool Inlining = false)
148-
: SILClonerWithScopes<ImplClass>(To, OpenedArchetypesTracker, Inlining),
149+
: SILClonerWithScopes<ImplClass>(To, OpenedArchetypesTracker, DT, Inlining),
149150
SwiftMod(From.getModule().getSwiftModule()),
150151
SubsMap(ApplySubs),
151152
Original(From),

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2834,9 +2834,6 @@ bool SimplifyCFG::tailDuplicateObjCMethodCallSuccessorBlocks() {
28342834
continue;
28352835

28362836
Cloner.cloneBranchTarget(Branch);
2837-
2838-
// Does not currently update DominanceInfo.
2839-
Cloner.splitCriticalEdges(nullptr, nullptr);
28402837
Cloner.updateSSAAfterCloning();
28412838

28422839
Changed = true;

lib/SILOptimizer/Utils/SILInliner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ SILInlineCloner::SILInlineCloner(
374374
SILOpenedArchetypesTracker &openedArchetypesTracker,
375375
SILInliner::DeletionFuncTy deletionCallback)
376376
: SuperTy(*apply.getFunction(), *calleeFunction, applySubs,
377-
openedArchetypesTracker, /*Inlining=*/true),
377+
openedArchetypesTracker, /*DT=*/nullptr, /*Inlining=*/true),
378378
FuncBuilder(funcBuilder), IKind(inlineKind), Apply(apply),
379379
DeletionCallback(deletionCallback) {
380380

0 commit comments

Comments
 (0)