@@ -284,6 +284,58 @@ bool OwnershipModelEliminatorVisitor::visitDestructureTupleInst(
284
284
// Top Level Entry Point
285
285
// ===----------------------------------------------------------------------===//
286
286
287
+ static bool stripOwnership (SILFunction &F) {
288
+ // If F is an external declaration, do not process it.
289
+ if (F.isExternalDeclaration ())
290
+ return false ;
291
+
292
+ // Set F to have unqualified ownership.
293
+ F.setOwnershipEliminated ();
294
+
295
+ bool MadeChange = false ;
296
+ SILBuilder B (F);
297
+ OwnershipModelEliminatorVisitor Visitor (B);
298
+
299
+ for (auto &BB : F) {
300
+ // Change all arguments to have ValueOwnershipKind::Any.
301
+ for (auto *Arg : BB.getArguments ()) {
302
+ Arg->setOwnershipKind (ValueOwnershipKind::Any);
303
+ }
304
+
305
+ for (auto II = BB.begin (), IE = BB.end (); II != IE;) {
306
+ // Since we are going to be potentially removing instructions, we need
307
+ // to make sure to increment our iterator before we perform any
308
+ // visits.
309
+ SILInstruction *I = &*II;
310
+ ++II;
311
+
312
+ MadeChange |= Visitor.visit (I);
313
+ }
314
+ }
315
+ return MadeChange;
316
+ }
317
+
318
+ static void prepareNonTransparentSILFunctionForOptimization (ModuleDecl *,
319
+ SILFunction *F) {
320
+ if (!F->hasOwnership () || F->isTransparent ())
321
+ return ;
322
+
323
+ LLVM_DEBUG (llvm::dbgs () << " After deserialization, stripping ownership in:"
324
+ << F->getName () << " \n " );
325
+
326
+ stripOwnership (*F);
327
+ }
328
+
329
+ static void prepareSILFunctionForOptimization (ModuleDecl *, SILFunction *F) {
330
+ if (!F->hasOwnership ())
331
+ return ;
332
+
333
+ LLVM_DEBUG (llvm::dbgs () << " After deserialization, stripping ownership in:"
334
+ << F->getName () << " \n " );
335
+
336
+ stripOwnership (*F);
337
+ }
338
+
287
339
namespace {
288
340
289
341
struct OwnershipModelEliminator : SILModuleTransform {
@@ -297,48 +349,38 @@ struct OwnershipModelEliminator : SILModuleTransform {
297
349
getModule ()->dump (DumpBefore.c_str ());
298
350
}
299
351
300
- for (auto &F : *getModule ()) {
352
+ auto &Mod = *getModule ();
353
+ for (auto &F : Mod) {
301
354
// If F does not have ownership, skip it. We have no further work to do.
302
355
if (!F.hasOwnership ())
303
356
continue ;
304
357
305
- // If we were asked to not strip ownership from transparent functions,
306
- // continue.
358
+ // If we were asked to not strip ownership from transparent functions in
359
+ // /our/ module, continue.
307
360
if (SkipTransparent && F.isTransparent ())
308
361
continue ;
309
362
310
- // Set F to have unqualified ownership.
311
- F.setOwnershipEliminated ();
312
-
313
- bool MadeChange = false ;
314
- SILBuilder B (F);
315
- OwnershipModelEliminatorVisitor Visitor (B);
316
-
317
- for (auto &BB : F) {
318
- // Change all arguments to have ValueOwnershipKind::Any.
319
- for (auto *Arg : BB.getArguments ()) {
320
- Arg->setOwnershipKind (ValueOwnershipKind::Any);
321
- }
322
-
323
- for (auto II = BB.begin (), IE = BB.end (); II != IE;) {
324
- // Since we are going to be potentially removing instructions, we need
325
- // to make sure to increment our iterator before we perform any
326
- // visits.
327
- SILInstruction *I = &*II;
328
- ++II;
329
-
330
- MadeChange |= Visitor.visit (I);
331
- }
332
- }
333
-
334
- if (MadeChange) {
363
+ if (stripOwnership (F)) {
335
364
auto InvalidKind =
336
365
SILAnalysis::InvalidationKind::BranchesAndInstructions;
337
366
invalidateAnalysis (&F, InvalidKind);
338
367
}
339
368
}
340
- }
341
369
370
+ // If we were asked to strip transparent, we are at the beginning of the
371
+ // performance pipeline. In such a case, we register a handler so that all
372
+ // future things we deserialize have ownership stripped.
373
+ using NotificationHandlerTy =
374
+ FunctionBodyDeserializationNotificationHandler;
375
+ std::unique_ptr<DeserializationNotificationHandler> ptr;
376
+ if (SkipTransparent) {
377
+ ptr.reset (new NotificationHandlerTy (
378
+ prepareNonTransparentSILFunctionForOptimization));
379
+ } else {
380
+ ptr.reset (new NotificationHandlerTy (prepareSILFunctionForOptimization));
381
+ }
382
+ Mod.registerDeserializationNotificationHandler (std::move (ptr));
383
+ }
342
384
};
343
385
344
386
} // end anonymous namespace
0 commit comments