Skip to content

Commit f9e0649

Browse files
committed
[ome] Remove bad pattern of having a global SILBuilder with a global SILBuilderWithContext and multiple local SILBuilderWithScope.
To make it a little less verbose, I added an always inline helper method called: template <typename ResultTy> ResultTy OME::withBuilder(SILInstruction *insertPt, function_ref<ResultTy (SILBuilder &, SILLocation)> visitor) { SILBuilderWithScope builder(insertPt, builderContext); return visitor(builder, insertPt->getLoc()); } Since it is always inline there shouldn't be any perf impact and it should be like invoking a lambda in the caller directly in the same function that the lambda was declared in. I just couldn't type SILBuilderWithScope builder(insertPt, builderContext) all the time. Seems error prone.
1 parent d2e3171 commit f9e0649

File tree

1 file changed

+83
-37
lines changed

1 file changed

+83
-37
lines changed

lib/SILOptimizer/Mandatory/OwnershipModelEliminator.cpp

Lines changed: 83 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,35 @@ namespace {
5757
/// consistent non-ossa vs ossa code rather than an intermediate state.
5858
struct OwnershipModelEliminatorVisitor
5959
: SILInstructionVisitor<OwnershipModelEliminatorVisitor, bool> {
60-
SILBuilder &builder;
6160
SmallVector<SILInstruction *, 8> trackingList;
6261
SmallBlotSetVector<SILInstruction *, 8> instructionsToSimplify;
62+
63+
/// Points at either a user passed in SILBuilderContext or points at
64+
/// builderCtxStorage.
65+
SILBuilderContext builderCtx;
66+
6367
SILOpenedArchetypesTracker openedArchetypesTracker;
6468

65-
OwnershipModelEliminatorVisitor(SILBuilder &newBuilder)
66-
: builder(newBuilder),
67-
openedArchetypesTracker(&newBuilder.getFunction()) {
68-
newBuilder.setTrackingList(&trackingList);
69-
newBuilder.setOpenedArchetypesTracker(&openedArchetypesTracker);
69+
/// Construct an OME visitor for eliminating ownership from \p fn.
70+
OwnershipModelEliminatorVisitor(SILFunction &fn)
71+
: trackingList(), instructionsToSimplify(),
72+
builderCtx(fn.getModule(), &trackingList),
73+
openedArchetypesTracker(&fn) {
74+
builderCtx.setOpenedArchetypesTracker(&openedArchetypesTracker);
75+
}
76+
77+
/// A "syntactic" high level function that combines our insertPt with a
78+
/// builder ctx.
79+
///
80+
/// Since this is syntactic and we assume that our caller is passing in a
81+
/// lambda that if we inline will be eliminated, we mark this function always
82+
/// inline.
83+
template <typename ResultTy>
84+
ResultTy LLVM_ATTRIBUTE_ALWAYS_INLINE
85+
withBuilder(SILInstruction *insertPt,
86+
llvm::function_ref<ResultTy(SILBuilder &, SILLocation)> visitor) {
87+
SILBuilderWithScope builder(insertPt, builderCtx);
88+
return visitor(builder, insertPt->getLoc());
7089
}
7190

7291
void drainTrackingList() {
@@ -83,8 +102,6 @@ struct OwnershipModelEliminatorVisitor
83102
// Add any elements to the tracking list that we currently have in the
84103
// tracking list that we haven't added yet.
85104
drainTrackingList();
86-
builder.setInsertionPoint(instToVisit);
87-
builder.setCurrentDebugScope(instToVisit->getDebugScope());
88105
}
89106

90107
void eraseInstruction(SILInstruction *i) {
@@ -137,10 +154,12 @@ struct OwnershipModelEliminatorVisitor
137154
// We lower this to unchecked_bitwise_cast losing our assumption of layout
138155
// compatibility.
139156
bool visitUncheckedValueCastInst(UncheckedValueCastInst *uvci) {
140-
auto *newVal = builder.createUncheckedBitwiseCast(
141-
uvci->getLoc(), uvci->getOperand(), uvci->getType());
142-
eraseInstructionAndRAUW(uvci, newVal);
143-
return true;
157+
return withBuilder<bool>(uvci, [&](SILBuilder &b, SILLocation loc) {
158+
auto *newVal = b.createUncheckedBitwiseCast(loc, uvci->getOperand(),
159+
uvci->getType());
160+
eraseInstructionAndRAUW(uvci, newVal);
161+
return true;
162+
});
144163
}
145164

146165
void splitDestructure(SILInstruction *destructure,
@@ -157,8 +176,10 @@ bool OwnershipModelEliminatorVisitor::visitLoadInst(LoadInst *li) {
157176
if (qualifier == LoadOwnershipQualifier::Unqualified)
158177
return false;
159178

160-
SILValue result = builder.emitLoadValueOperation(
161-
li->getLoc(), li->getOperand(), li->getOwnershipQualifier());
179+
auto result = withBuilder<SILValue>(li, [&](SILBuilder &b, SILLocation loc) {
180+
return b.emitLoadValueOperation(loc, li->getOperand(),
181+
li->getOwnershipQualifier());
182+
});
162183

163184
// Then remove the qualified load and use the unqualified load as the def of
164185
// all of LI's uses.
@@ -174,8 +195,10 @@ bool OwnershipModelEliminatorVisitor::visitStoreInst(StoreInst *si) {
174195
if (qualifier == StoreOwnershipQualifier::Unqualified)
175196
return false;
176197

177-
builder.emitStoreValueOperation(si->getLoc(), si->getSrc(), si->getDest(),
178-
si->getOwnershipQualifier());
198+
withBuilder<void>(si, [&](SILBuilder &b, SILLocation loc) {
199+
b.emitStoreValueOperation(loc, si->getSrc(), si->getDest(),
200+
si->getOwnershipQualifier());
201+
});
179202

180203
// Then remove the qualified store.
181204
eraseInstruction(si);
@@ -184,8 +207,10 @@ bool OwnershipModelEliminatorVisitor::visitStoreInst(StoreInst *si) {
184207

185208
bool OwnershipModelEliminatorVisitor::visitStoreBorrowInst(
186209
StoreBorrowInst *si) {
187-
builder.emitStoreValueOperation(si->getLoc(), si->getSrc(), si->getDest(),
188-
StoreOwnershipQualifier::Init);
210+
withBuilder<void>(si, [&](SILBuilder &b, SILLocation loc) {
211+
b.emitStoreValueOperation(loc, si->getSrc(), si->getDest(),
212+
StoreOwnershipQualifier::Unqualified);
213+
});
189214

190215
// Then remove the qualified store.
191216
eraseInstruction(si);
@@ -194,23 +219,28 @@ bool OwnershipModelEliminatorVisitor::visitStoreBorrowInst(
194219

195220
bool OwnershipModelEliminatorVisitor::visitLoadBorrowInst(LoadBorrowInst *lbi) {
196221
// Break down the load borrow into an unqualified load.
197-
auto *unqualifiedLoad = builder.createLoad(
198-
lbi->getLoc(), lbi->getOperand(), LoadOwnershipQualifier::Unqualified);
222+
auto newLoad =
223+
withBuilder<SILValue>(lbi, [&](SILBuilder &b, SILLocation loc) {
224+
return b.createLoad(loc, lbi->getOperand(),
225+
LoadOwnershipQualifier::Unqualified);
226+
});
199227

200228
// Then remove the qualified load and use the unqualified load as the def of
201229
// all of LI's uses.
202-
eraseInstructionAndRAUW(lbi, unqualifiedLoad);
230+
eraseInstructionAndRAUW(lbi, newLoad);
203231
return true;
204232
}
205233

206234
bool OwnershipModelEliminatorVisitor::visitCopyValueInst(CopyValueInst *cvi) {
207235
// A copy_value of an address-only type cannot be replaced.
208-
if (cvi->getType().isAddressOnly(builder.getFunction()))
236+
if (cvi->getType().isAddressOnly(*cvi->getFunction()))
209237
return false;
210238

211239
// Now that we have set the unqualified ownership flag, destroy value
212240
// operation will delegate to the appropriate strong_release, etc.
213-
builder.emitCopyValueOperation(cvi->getLoc(), cvi->getOperand());
241+
withBuilder<void>(cvi, [&](SILBuilder &b, SILLocation loc) {
242+
b.emitCopyValueOperation(loc, cvi->getOperand());
243+
});
214244
eraseInstructionAndRAUW(cvi, cvi->getOperand());
215245
return true;
216246
}
@@ -219,7 +249,9 @@ bool OwnershipModelEliminatorVisitor::visitUnmanagedRetainValueInst(
219249
UnmanagedRetainValueInst *urvi) {
220250
// Now that we have set the unqualified ownership flag, destroy value
221251
// operation will delegate to the appropriate strong_release, etc.
222-
builder.emitCopyValueOperation(urvi->getLoc(), urvi->getOperand());
252+
withBuilder<void>(urvi, [&](SILBuilder &b, SILLocation loc) {
253+
b.emitCopyValueOperation(loc, urvi->getOperand());
254+
});
223255
eraseInstruction(urvi);
224256
return true;
225257
}
@@ -228,7 +260,9 @@ bool OwnershipModelEliminatorVisitor::visitUnmanagedReleaseValueInst(
228260
UnmanagedReleaseValueInst *urvi) {
229261
// Now that we have set the unqualified ownership flag, destroy value
230262
// operation will delegate to the appropriate strong_release, etc.
231-
builder.emitDestroyValueOperation(urvi->getLoc(), urvi->getOperand());
263+
withBuilder<void>(urvi, [&](SILBuilder &b, SILLocation loc) {
264+
b.emitDestroyValueOperation(loc, urvi->getOperand());
265+
});
232266
eraseInstruction(urvi);
233267
return true;
234268
}
@@ -237,21 +271,24 @@ bool OwnershipModelEliminatorVisitor::visitUnmanagedAutoreleaseValueInst(
237271
UnmanagedAutoreleaseValueInst *UAVI) {
238272
// Now that we have set the unqualified ownership flag, destroy value
239273
// operation will delegate to the appropriate strong_release, etc.
240-
builder.createAutoreleaseValue(UAVI->getLoc(), UAVI->getOperand(),
241-
UAVI->getAtomicity());
274+
withBuilder<void>(UAVI, [&](SILBuilder &b, SILLocation loc) {
275+
b.createAutoreleaseValue(loc, UAVI->getOperand(), UAVI->getAtomicity());
276+
});
242277
eraseInstruction(UAVI);
243278
return true;
244279
}
245280

246281
bool OwnershipModelEliminatorVisitor::visitDestroyValueInst(
247282
DestroyValueInst *dvi) {
248283
// A destroy_value of an address-only type cannot be replaced.
249-
if (dvi->getOperand()->getType().isAddressOnly(builder.getFunction()))
284+
if (dvi->getOperand()->getType().isAddressOnly(*dvi->getFunction()))
250285
return false;
251286

252287
// Now that we have set the unqualified ownership flag, destroy value
253288
// operation will delegate to the appropriate strong_release, etc.
254-
builder.emitDestroyValueOperation(dvi->getLoc(), dvi->getOperand());
289+
withBuilder<void>(dvi, [&](SILBuilder &b, SILLocation loc) {
290+
b.emitDestroyValueOperation(loc, dvi->getOperand());
291+
});
255292
eraseInstruction(dvi);
256293
return true;
257294
}
@@ -310,7 +347,8 @@ void OwnershipModelEliminatorVisitor::splitDestructure(
310347

311348
llvm::SmallVector<Projection, 8> projections;
312349
Projection::getFirstLevelProjections(
313-
opType, M, builder.getTypeExpansionContext(), projections);
350+
opType, M, TypeExpansionContext(*destructureInst->getFunction()),
351+
projections);
314352
assert(projections.size() == destructureInst->getNumResults());
315353

316354
auto destructureResults = destructureInst->getResults();
@@ -324,8 +362,10 @@ void OwnershipModelEliminatorVisitor::splitDestructure(
324362

325363
// Otherwise, create a projection.
326364
const auto &proj = projections[index];
327-
SingleValueInstruction *projInst =
328-
proj.createObjectProjection(builder, loc, destructureOperand).get();
365+
auto *projInst = withBuilder<SingleValueInstruction *>(
366+
destructureInst, [&](SILBuilder &b, SILLocation loc) {
367+
return proj.createObjectProjection(b, loc, destructureOperand).get();
368+
});
329369

330370
// First RAUW Result with ProjInst. This ensures that we have a complete IR
331371
// before we perform any simplifications.
@@ -362,8 +402,7 @@ static bool stripOwnership(SILFunction &func) {
362402

363403
bool madeChange = false;
364404
SmallVector<SILInstruction *, 32> createdInsts;
365-
SILBuilder builder(func);
366-
OwnershipModelEliminatorVisitor visitor(builder);
405+
OwnershipModelEliminatorVisitor visitor(func);
367406

368407
for (auto &block : func) {
369408
// Change all arguments to have OwnershipKind::None.
@@ -382,9 +421,16 @@ static bool stripOwnership(SILFunction &func) {
382421
}
383422
}
384423

385-
// Once we have finished processing all instructions, we should not be
386-
// consistently in non-ossa form. Now go through any instructions and simplify
387-
// using inst simplify.
424+
// Once we have finished processing all instructions, we should be
425+
// consistently in non-ossa form meaning that it is now safe for us to invoke
426+
// utilities that assume that they are in a consistent ossa or non-ossa form
427+
// such as inst simplify. Now go through any instructions and simplify using
428+
// inst simplify!
429+
//
430+
// DISCUSSION: We want our utilities to be able to assume if f.hasOwnership()
431+
// is false then the utility is allowed to assume the function the utility is
432+
// invoked within is in non-ossa form structurally (e.x.: non-ossa does not
433+
// have arguments on the default result of checked_cast_br).
388434
while (!visitor.instructionsToSimplify.empty()) {
389435
auto value = visitor.instructionsToSimplify.pop_back_val();
390436
if (!value.hasValue())

0 commit comments

Comments
 (0)