Skip to content

Commit a5b47e1

Browse files
committed
[cast-opt] Add a new callback: ReplaceValueUsesAction.
This is the first in a series of patches to update the cast optimizer for ownership and multiple value instructions. This specific patch is NFC.
1 parent 48e48f2 commit a5b47e1

File tree

5 files changed

+116
-57
lines changed

5 files changed

+116
-57
lines changed

include/swift/SILOptimizer/Utils/CastOptimizer.h

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,25 @@ class SILOptFunctionBuilder;
3434
class CastOptimizer {
3535
SILOptFunctionBuilder &FunctionBuilder;
3636

37-
// Callback to be called when uses of an instruction should be replaced.
38-
std::function<void(SingleValueInstruction *I, ValueBase *V)>
37+
/// Callback that replaces the first SILValue's uses with a use of the second
38+
/// value.
39+
std::function<void(SILValue, SILValue)> ReplaceValueUsesAction;
40+
41+
/// Callback that replaces a SingleValueInstruction with a ValueBase after
42+
/// updating any status in the caller.
43+
std::function<void(SingleValueInstruction *, ValueBase *)>
3944
ReplaceInstUsesAction;
4045

41-
// Callback to call when an instruction needs to be erased.
46+
/// Callback that erases an instruction and performs any state updates in the
47+
/// caller required.
4248
std::function<void(SILInstruction *)> EraseInstAction;
4349

44-
// Callback to call after an optimization was performed based on the fact
45-
// that a cast will succeed.
50+
/// Callback to call after an optimization was performed based on the fact
51+
/// that a cast will succeed.
4652
std::function<void()> WillSucceedAction;
4753

48-
// Callback to call after an optimization was performed based on the fact
49-
// that a cast will fail.
54+
/// Callback to call after an optimization was performed based on the fact
55+
/// that a cast will fail.
5056
std::function<void()> WillFailAction;
5157

5258
/// Optimize a cast from a bridged ObjC type into
@@ -69,12 +75,15 @@ class CastOptimizer {
6975

7076
public:
7177
CastOptimizer(SILOptFunctionBuilder &FunctionBuilder,
72-
std::function<void(SingleValueInstruction *I, ValueBase *V)>
78+
std::function<void(SILValue, SILValue)> ReplaceValueUsesAction,
79+
std::function<void(SingleValueInstruction *, ValueBase *)>
7380
ReplaceInstUsesAction,
7481
std::function<void(SILInstruction *)> EraseAction,
7582
std::function<void()> WillSucceedAction,
7683
std::function<void()> WillFailAction = []() {})
77-
: FunctionBuilder(FunctionBuilder), ReplaceInstUsesAction(ReplaceInstUsesAction),
84+
: FunctionBuilder(FunctionBuilder),
85+
ReplaceValueUsesAction(ReplaceValueUsesAction),
86+
ReplaceInstUsesAction(ReplaceInstUsesAction),
7887
EraseInstAction(EraseAction), WillSucceedAction(WillSucceedAction),
7988
WillFailAction(WillFailAction) {}
8089

@@ -84,11 +93,13 @@ class CastOptimizer {
8493
// arguments. It seems the number of the default argument with lambda is
8594
// limited.
8695
CastOptimizer(SILOptFunctionBuilder &FunctionBuilder,
96+
std::function<void(SILValue, SILValue)> ReplaceValueUsesAction,
8797
std::function<void(SingleValueInstruction *I, ValueBase *V)>
8898
ReplaceInstUsesAction,
8999
std::function<void(SILInstruction *)> EraseAction =
90100
[](SILInstruction *) {})
91-
: CastOptimizer(FunctionBuilder, ReplaceInstUsesAction, EraseAction, []() {}, []() {}) {}
101+
: CastOptimizer(FunctionBuilder, ReplaceValueUsesAction,
102+
ReplaceInstUsesAction, EraseAction, []() {}, []() {}) {}
92103

93104
/// Simplify checked_cast_br. It may change the control flow.
94105
SILInstruction *simplifyCheckedCastBranchInst(CheckedCastBranchInst *Inst);

lib/SILOptimizer/SILCombiner/SILCombine.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,15 @@ void SILCombiner::replaceInstUsesWith(SingleValueInstruction &I, ValueBase *V) {
279279
I.replaceAllUsesWith(V);
280280
}
281281

282+
void SILCombiner::replaceValueUsesWith(SILValue oldValue, SILValue newValue) {
283+
Worklist.addUsersToWorklist(oldValue); // Add all modified instrs to worklist.
284+
285+
LLVM_DEBUG(llvm::dbgs() << "SC: Replacing " << oldValue << "\n"
286+
<< " with " << newValue << '\n');
287+
288+
oldValue->replaceAllUsesWith(newValue);
289+
}
290+
282291
/// Replace all of the results of the old instruction with the
283292
/// corresponding results of the new instruction.
284293
void SILCombiner::replaceInstUsesPairwiseWith(SILInstruction *oldI,

lib/SILOptimizer/SILCombiner/SILCombiner.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ class SILCombineWorklist {
9191
add(UI->getUser());
9292
}
9393

94+
void addUsersToWorklist(SILValue value) {
95+
for (auto *use : value->getUses())
96+
add(use->getUser());
97+
}
98+
9499
/// When an instruction has been simplified, add all of its users to the
95100
/// worklist, since additional simplifications of its users may have been
96101
/// exposed.
@@ -147,13 +152,17 @@ class SILCombiner :
147152
CastOptimizer CastOpt;
148153

149154
public:
150-
SILCombiner(SILOptFunctionBuilder &FuncBuilder,
151-
SILBuilder &B, AliasAnalysis *AA, DominanceAnalysis *DA,
155+
SILCombiner(SILOptFunctionBuilder &FuncBuilder, SILBuilder &B,
156+
AliasAnalysis *AA, DominanceAnalysis *DA,
152157
ProtocolConformanceAnalysis *PCA, ClassHierarchyAnalysis *CHA,
153158
bool removeCondFails)
154159
: AA(AA), DA(DA), PCA(PCA), CHA(CHA), Worklist(), MadeChange(false),
155160
RemoveCondFails(removeCondFails), Iteration(0), Builder(B),
156161
CastOpt(FuncBuilder,
162+
/* ReplaceValueUsesAction */
163+
[&](SILValue Original, SILValue Replacement) {
164+
replaceValueUsesWith(Original, Replacement);
165+
},
157166
/* ReplaceInstUsesAction */
158167
[&](SingleValueInstruction *I, ValueBase *V) {
159168
replaceInstUsesWith(*I, V);
@@ -179,6 +188,12 @@ class SILCombiner :
179188
// so that the combiner will know that I was modified.
180189
void replaceInstUsesWith(SingleValueInstruction &I, ValueBase *V);
181190

191+
// This method is to be used when a value is found to be dead,
192+
// replaceable with another preexisting expression. Here we add all
193+
// uses of oldValue to the worklist, replace all uses of oldValue
194+
// with newValue.
195+
void replaceValueUsesWith(SILValue oldValue, SILValue newValue);
196+
182197
void replaceInstUsesPairwiseWith(SILInstruction *oldI, SILInstruction *newI);
183198

184199
// Some instructions can never be "trivially dead" due to side effects or

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1934,20 +1934,26 @@ bool SimplifyCFG::simplifyCheckedCastBranchBlock(CheckedCastBranchInst *CCBI) {
19341934
auto ThisBB = CCBI->getParent();
19351935

19361936
bool MadeChange = false;
1937-
CastOptimizer CastOpt(FuncBuilder,
1938-
[&MadeChange](SILInstruction *I,
1939-
ValueBase *V) { /* ReplaceInstUsesAction */
1937+
CastOptimizer CastOpt(
1938+
FuncBuilder,
1939+
/* ReplaceValueUsesAction */
1940+
[&MadeChange](SILValue oldValue, SILValue newValue) {
19401941
MadeChange = true;
19411942
},
1942-
[&MadeChange](SILInstruction *I) { /* EraseInstAction */
1943+
/* ReplaceInstUsesAction */
1944+
[&MadeChange](SILInstruction *I, ValueBase *V) { MadeChange = true; },
1945+
/* EraseInstAction */
1946+
[&MadeChange](SILInstruction *I) {
19431947
MadeChange = true;
19441948
I->eraseFromParent();
19451949
},
1946-
[&]() { /* WillSucceedAction */
1950+
/* WillSucceedAction */
1951+
[&]() {
19471952
MadeChange |= removeIfDead(FailureBB);
19481953
addToWorklist(ThisBB);
19491954
},
1950-
[&]() { /* WillFailAction */
1955+
/* WillFailAction */
1956+
[&]() {
19511957
MadeChange |= removeIfDead(SuccessBB);
19521958
addToWorklist(ThisBB);
19531959
});
@@ -1965,21 +1971,26 @@ bool SimplifyCFG::simplifyCheckedCastValueBranchBlock(
19651971
bool MadeChange = false;
19661972
CastOptimizer CastOpt(
19671973
FuncBuilder,
1968-
[&MadeChange](SILInstruction *I,
1969-
ValueBase *V) { /* ReplaceInstUsesAction */
1970-
MadeChange = true;
1974+
/* ReplaceValueUsesAction */
1975+
[&MadeChange](SILValue oldValue, SILValue newValue) {
1976+
MadeChange = true;
19711977
},
1972-
[&MadeChange](SILInstruction *I) { /* EraseInstAction */
1973-
MadeChange = true;
1974-
I->eraseFromParent();
1978+
/* ReplaceInstUsesAction */
1979+
[&MadeChange](SILInstruction *I, ValueBase *V) { MadeChange = true; },
1980+
/* EraseInstAction */
1981+
[&MadeChange](SILInstruction *I) {
1982+
MadeChange = true;
1983+
I->eraseFromParent();
19751984
},
1976-
[&]() { /* WillSucceedAction */
1977-
MadeChange |= removeIfDead(FailureBB);
1978-
addToWorklist(ThisBB);
1985+
/* WillSucceedAction */
1986+
[&]() {
1987+
MadeChange |= removeIfDead(FailureBB);
1988+
addToWorklist(ThisBB);
19791989
},
1980-
[&]() { /* WillFailAction */
1981-
MadeChange |= removeIfDead(SuccessBB);
1982-
addToWorklist(ThisBB);
1990+
/* WillFailAction */
1991+
[&]() {
1992+
MadeChange |= removeIfDead(SuccessBB);
1993+
addToWorklist(ThisBB);
19831994
});
19841995

19851996
MadeChange |= bool(CastOpt.simplifyCheckedCastValueBranchInst(CCBI));
@@ -1994,19 +2005,24 @@ simplifyCheckedCastAddrBranchBlock(CheckedCastAddrBranchInst *CCABI) {
19942005
auto ThisBB = CCABI->getParent();
19952006

19962007
bool MadeChange = false;
1997-
CastOptimizer CastOpt(FuncBuilder,
1998-
[&MadeChange](SILInstruction *I, ValueBase *V) {
1999-
MadeChange = true;
2000-
}, /* ReplaceInstUsesAction */
2001-
[&MadeChange](SILInstruction *I) { /* EraseInstAction */
2008+
CastOptimizer CastOpt(
2009+
FuncBuilder,
2010+
/* ReplaceValueUsesAction */
2011+
[&MadeChange](SILValue, SILValue) { MadeChange = true; },
2012+
/* ReplaceInstUsesAction */
2013+
[&MadeChange](SILInstruction *I, ValueBase *V) { MadeChange = true; },
2014+
/* EraseInstAction */
2015+
[&MadeChange](SILInstruction *I) {
20022016
MadeChange = true;
20032017
I->eraseFromParent();
20042018
},
2005-
[&]() { /* WillSucceedAction */
2019+
/* WillSucceedAction */
2020+
[&]() {
20062021
MadeChange |= removeIfDead(FailureBB);
20072022
addToWorklist(ThisBB);
20082023
},
2009-
[&]() { /* WillFailAction */
2024+
/* WillFailAction */
2025+
[&]() {
20102026
MadeChange |= removeIfDead(SuccessBB);
20112027
addToWorklist(ThisBB);
20122028
});

lib/SILOptimizer/Utils/ConstantFolding.cpp

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,26 +1439,34 @@ ConstantFolder::processWorkList() {
14391439
llvm::DenseSet<SILInstruction *> ErrorSet;
14401440
llvm::SetVector<SILInstruction *> FoldedUsers;
14411441
CastOptimizer CastOpt(FuncBuilder,
1442-
[&](SingleValueInstruction *I, ValueBase *V) { /* ReplaceInstUsesAction */
1443-
1444-
InvalidateInstructions = true;
1445-
I->replaceAllUsesWith(V);
1446-
},
1447-
[&](SILInstruction *I) { /* EraseAction */
1448-
auto *TI = dyn_cast<TermInst>(I);
1449-
1450-
if (TI) {
1451-
// Invalidate analysis information related to branches. Replacing
1452-
// unconditional_check_branch type instructions by a trap will also
1453-
// invalidate branches/the CFG.
1454-
InvalidateBranches = true;
1455-
}
1456-
1457-
InvalidateInstructions = true;
1458-
1459-
WorkList.remove(I);
1460-
I->eraseFromParent();
1461-
});
1442+
/* ReplaceValueUsesAction */
1443+
[&](SILValue oldValue, SILValue newValue) {
1444+
InvalidateInstructions = true;
1445+
oldValue->replaceAllUsesWith(newValue);
1446+
},
1447+
/* ReplaceInstUsesAction */
1448+
[&](SingleValueInstruction *I, ValueBase *V) {
1449+
InvalidateInstructions = true;
1450+
I->replaceAllUsesWith(V);
1451+
},
1452+
/* EraseAction */
1453+
[&](SILInstruction *I) {
1454+
auto *TI = dyn_cast<TermInst>(I);
1455+
1456+
if (TI) {
1457+
// Invalidate analysis information related to
1458+
// branches. Replacing
1459+
// unconditional_check_branch type instructions
1460+
// by a trap will also invalidate branches/the
1461+
// CFG.
1462+
InvalidateBranches = true;
1463+
}
1464+
1465+
InvalidateInstructions = true;
1466+
1467+
WorkList.remove(I);
1468+
I->eraseFromParent();
1469+
});
14621470

14631471
while (!WorkList.empty()) {
14641472
SILInstruction *I = WorkList.pop_back_val();

0 commit comments

Comments
 (0)