Skip to content

Commit 5b1f02d

Browse files
authored
Merge pull request #37081 from gottesmm/pr-f4e3be62c879d615aa05c8181a481e36205ea258
[sil-optimizer] Fix feedback from #37016 and finish removing confusing constructors
2 parents 6845fbf + b6bfea1 commit 5b1f02d

File tree

7 files changed

+77
-60
lines changed

7 files changed

+77
-60
lines changed

include/swift/SILOptimizer/Utils/CanonicalizeInstruction.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,22 @@ struct CanonicalizeInstruction {
4646
CanonicalizeInstruction(const char *passDebugType,
4747
DeadEndBlocks &deadEndBlocks)
4848
: deadEndBlocks(deadEndBlocks),
49-
callbacks(
50-
[&](SILInstruction *toDelete) { killInstruction(toDelete); },
51-
[&](SILInstruction *newInst) { notifyNewInstruction(newInst); },
52-
[&](Operand *use, SILValue newValue) {
53-
use->set(newValue);
54-
notifyHasNewUsers(newValue);
55-
}) {
49+
callbacks() {
5650
#ifndef NDEBUG
5751
if (llvm::DebugFlag && !llvm::isCurrentDebugType(debugType))
5852
debugType = passDebugType;
5953
#endif
54+
callbacks = InstModCallbacks()
55+
.onDelete([&](SILInstruction *toDelete) {
56+
killInstruction(toDelete);
57+
})
58+
.onCreateNewInst([&](SILInstruction *newInst) {
59+
notifyNewInstruction(newInst);
60+
})
61+
.onSetUseValue([&](Operand *use, SILValue newValue) {
62+
use->set(newValue);
63+
notifyHasNewUsers(newValue);
64+
});
6065
}
6166

6267
virtual ~CanonicalizeInstruction();

include/swift/SILOptimizer/Utils/InstOptUtils.h

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,6 @@ template <class T> class NullablePtr;
4848
/// that in a loop this property should predict well since you have a single
4949
/// branch that is going to go the same way everytime.
5050
class InstModCallbacks {
51-
/// A function that takes in an instruction and deletes the inst.
52-
///
53-
/// Default implementation is instToDelete->eraseFromParent();
54-
std::function<void(SILInstruction *instToDelete)> deleteInstFunc;
55-
5651
/// A function that is called to notify that a new function was created.
5752
///
5853
/// Default implementation is a no-op, but we still mark madeChange.
@@ -66,37 +61,47 @@ class InstModCallbacks {
6661
/// iterators.
6762
std::function<void(Operand *use, SILValue newValue)> setUseValueFunc;
6863

64+
/// A function that takes in an instruction and deletes the inst.
65+
///
66+
/// Default implementation is instToDelete->eraseFromParent();
67+
///
68+
/// NOTE: The reason why we have deleteInstFunc and notifyWillBeDeletedFunc is
69+
/// InstModCallback supports 2 stage deletion where a callee passed
70+
/// InstModCallback is allowed to drop all references to the instruction
71+
/// before calling deleteInstFunc. In contrast, notifyWillBeDeletedFunc
72+
/// assumes that the IR is in a good form before being called so that the
73+
/// caller can via the callback gather state about the instruction that will
74+
/// be deleted. As an example, see InstructionDeleter::deleteInstruction() in
75+
/// InstOptUtils.cpp.
76+
std::function<void(SILInstruction *instToDelete)> deleteInstFunc;
77+
6978
/// If non-null, called before an instruction is deleted or has its references
70-
/// dropped.
79+
/// dropped. If null, no-op.
80+
///
81+
/// NOTE: The reason why we have deleteInstFunc and notifyWillBeDeletedFunc is
82+
/// InstModCallback supports 2 stage deletion where a callee passed
83+
/// InstModCallback is allowed to drop all references to the instruction
84+
/// before calling deleteInstFunc. In contrast, notifyWillBeDeletedFunc
85+
/// assumes that the IR is in a good form before being called so that the
86+
/// caller can via the callback gather state about the instruction that will
87+
/// be deleted. As an example, see InstructionDeleter::deleteInstruction() in
88+
/// InstOptUtils.cpp.
89+
///
90+
/// NOTE: This is called in InstModCallback::deleteInst() if one does not use
91+
/// a default bool argument to disable the notification. In general that
92+
/// should only be done when one is writing custom handling and is performing
93+
/// the notification ones self. It is assumed that the notification will be
94+
/// called with a valid instruction.
7195
std::function<void(SILInstruction *instThatWillBeDeleted)>
7296
notifyWillBeDeletedFunc;
7397

7498
/// A boolean that tracks if any of our callbacks were ever called.
7599
bool wereAnyCallbacksInvoked = false;
76100

77101
public:
78-
InstModCallbacks(decltype(deleteInstFunc) deleteInstFunc)
79-
: deleteInstFunc(deleteInstFunc) {}
80-
81-
InstModCallbacks(decltype(deleteInstFunc) deleteInstFunc,
82-
decltype(createdNewInstFunc) createdNewInstFunc)
83-
: deleteInstFunc(deleteInstFunc), createdNewInstFunc(createdNewInstFunc) {
84-
}
85-
86-
InstModCallbacks(decltype(deleteInstFunc) deleteInstFunc,
87-
decltype(setUseValueFunc) setUseValueFunc)
88-
: deleteInstFunc(deleteInstFunc), setUseValueFunc(setUseValueFunc) {}
89-
90-
InstModCallbacks(decltype(deleteInstFunc) deleteInstFunc,
91-
decltype(createdNewInstFunc) createdNewInstFunc,
92-
decltype(setUseValueFunc) setUseValueFunc)
93-
: deleteInstFunc(deleteInstFunc), createdNewInstFunc(createdNewInstFunc),
94-
setUseValueFunc(setUseValueFunc) {}
95-
96102
InstModCallbacks() = default;
97103
~InstModCallbacks() = default;
98104
InstModCallbacks(const InstModCallbacks &) = default;
99-
InstModCallbacks(InstModCallbacks &&) = default;
100105

101106
/// Return a copy of self with deleteInstFunc set to \p newDeleteInstFunc.
102107
InstModCallbacks onDelete(decltype(deleteInstFunc) newDeleteInstFunc) const {

lib/SILOptimizer/Mandatory/MandatoryCombine.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -143,18 +143,22 @@ class MandatoryCombiner final
143143
DeadEndBlocks &deadEndBlocks)
144144
: compilingWithOptimization(optimized), worklist("MC"), madeChange(false),
145145
iteration(0),
146-
instModCallbacks(
147-
[&](SILInstruction *instruction) {
148-
worklist.erase(instruction);
149-
instructionsPendingDeletion.push_back(instruction);
150-
},
151-
[&](SILInstruction *instruction) { worklist.add(instruction); },
152-
[this](Operand *use, SILValue newValue) {
153-
use->set(newValue);
154-
worklist.add(use->getUser());
155-
}),
146+
instModCallbacks(),
156147
createdInstructions(createdInstructions),
157-
deadEndBlocks(deadEndBlocks){};
148+
deadEndBlocks(deadEndBlocks) {
149+
instModCallbacks = InstModCallbacks()
150+
.onDelete([&](SILInstruction *instruction) {
151+
worklist.erase(instruction);
152+
instructionsPendingDeletion.push_back(instruction);
153+
})
154+
.onCreateNewInst([&](SILInstruction *instruction) {
155+
worklist.add(instruction);
156+
})
157+
.onSetUseValue([this](Operand *use, SILValue newValue) {
158+
use->set(newValue);
159+
worklist.add(use->getUser());
160+
});
161+
};
158162

159163
void addReachableCodeToWorklist(SILFunction &function);
160164

lib/SILOptimizer/Mandatory/OwnershipModelEliminator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ static bool stripOwnership(SILFunction &func) {
527527
auto value = visitor.instructionsToSimplify.pop_back_val();
528528
if (!value.hasValue())
529529
continue;
530-
InstModCallbacks callbacks([&](SILInstruction *instToErase) {
530+
auto callbacks = InstModCallbacks().onDelete([&](SILInstruction *instToErase) {
531531
visitor.eraseInstruction(instToErase);
532532
});
533533
// We are no longer in OSSA, so we don't need to pass in a deBlocks.

lib/SILOptimizer/SILCombiner/SILCombiner.h

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,19 +116,21 @@ class SILCombiner :
116116
},
117117
/* EraseAction */
118118
[&](SILInstruction *I) { eraseInstFromFunction(*I); }),
119-
instModCallbacks(
120-
[&](SILInstruction *instToDelete) {
121-
eraseInstFromFunction(*instToDelete);
122-
},
123-
[&](SILInstruction *newlyCreatedInst) {
124-
Worklist.add(newlyCreatedInst);
125-
},
126-
[&](Operand *use, SILValue newValue) {
127-
use->set(newValue);
128-
Worklist.add(use->getUser());
129-
}),
119+
instModCallbacks(),
130120
deBlocks(&B.getFunction()),
131-
ownershipFixupContext(instModCallbacks, deBlocks) {}
121+
ownershipFixupContext(instModCallbacks, deBlocks) {
122+
instModCallbacks = InstModCallbacks()
123+
.onDelete([&](SILInstruction *instToDelete) {
124+
eraseInstFromFunction(*instToDelete);
125+
})
126+
.onCreateNewInst([&](SILInstruction *newlyCreatedInst) {
127+
Worklist.add(newlyCreatedInst);
128+
})
129+
.onSetUseValue([&](Operand *use, SILValue newValue) {
130+
use->set(newValue);
131+
Worklist.add(use->getUser());
132+
});
133+
}
132134

133135
bool runOnFunction(SILFunction &F);
134136

lib/SILOptimizer/SemanticARC/SemanticARCOptVisitor.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ struct LLVM_LIBRARY_VISIBILITY SemanticARCOptVisitor
5252
explicit SemanticARCOptVisitor(SILFunction &fn, DeadEndBlocks &deBlocks,
5353
bool onlyMandatoryOpts)
5454
: ctx(fn, deBlocks, onlyMandatoryOpts,
55-
InstModCallbacks(
56-
[this](SILInstruction *inst) { eraseInstruction(inst); },
57-
[this](Operand *use, SILValue newValue) {
55+
InstModCallbacks()
56+
.onDelete(
57+
[this](SILInstruction *inst) { eraseInstruction(inst); })
58+
.onSetUseValue([this](Operand *use, SILValue newValue) {
5859
use->set(newValue);
5960
worklist.insert(newValue);
6061
})) {}

lib/SILOptimizer/Transforms/TempRValueElimination.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ void TempRValueOptPass::run() {
783783
}
784784
}
785785

786-
InstModCallbacks callbacks(
786+
auto callbacks = InstModCallbacks().onDelete(
787787
[](SILInstruction *instToKill) {
788788
// SimplifyInstruction is not in the business of removing
789789
// copy_addr. If it were, then we would need to update deadCopies.

0 commit comments

Comments
 (0)