@@ -290,6 +290,22 @@ llvm::cl::opt<bool> DisableMoveOnlyAddressCheckerLifetimeExtension(
290
290
// MARK: Utilities
291
291
// ===----------------------------------------------------------------------===//
292
292
293
+ struct RAIILLVMDebug {
294
+ StringRef str;
295
+
296
+ RAIILLVMDebug (StringRef str) : str(str) {
297
+ LLVM_DEBUG (llvm::dbgs () << " ===>>> Starting " << str << ' \n ' );
298
+ }
299
+
300
+ RAIILLVMDebug (StringRef str, SILInstruction *u) : str(str) {
301
+ LLVM_DEBUG (llvm::dbgs () << " ===>>> Starting " << str << " :" << *u);
302
+ }
303
+
304
+ ~RAIILLVMDebug () {
305
+ LLVM_DEBUG (llvm::dbgs () << " ===<<< Completed " << str << ' \n ' );
306
+ }
307
+ };
308
+
293
309
static void insertDebugValueBefore (SILInstruction *insertPt,
294
310
DebugVarCarryingInst debugVar,
295
311
llvm::function_ref<SILValue ()> operand) {
@@ -3121,6 +3137,8 @@ bool MoveOnlyAddressCheckerPImpl::performSingleCheck(
3121
3137
// [copy] + begin_borrow for further processing. This just eliminates a case
3122
3138
// that the checker doesn't need to know about.
3123
3139
{
3140
+ RAIILLVMDebug l (" CopiedLoadBorrowEliminationVisitor" );
3141
+
3124
3142
CopiedLoadBorrowEliminationState state (markedAddress->getFunction ());
3125
3143
CopiedLoadBorrowEliminationVisitor copiedLoadBorrowEliminator (state);
3126
3144
if (AddressUseKind::Unknown ==
@@ -3142,12 +3160,16 @@ bool MoveOnlyAddressCheckerPImpl::performSingleCheck(
3142
3160
// SILGen will treat y as a separate rvalue from x and will create a temporary
3143
3161
// allocation. In contrast if we have a var, we treat x like an lvalue and
3144
3162
// just create GEPs appropriately.
3145
- if (eliminateTemporaryAllocationsFromLet (markedAddress)) {
3146
- LLVM_DEBUG (
3147
- llvm::dbgs ()
3148
- << " Succeeded in eliminating temporary allocations! Fn after:\n " ;
3149
- markedAddress->getFunction ()->dump ());
3150
- changed = true ;
3163
+ {
3164
+ RAIILLVMDebug l (" temporary allocations from rvalue accesses" );
3165
+
3166
+ if (eliminateTemporaryAllocationsFromLet (markedAddress)) {
3167
+ LLVM_DEBUG (
3168
+ llvm::dbgs ()
3169
+ << " Succeeded in eliminating temporary allocations! Fn after:\n " ;
3170
+ markedAddress->getFunction ()->dump ());
3171
+ changed = true ;
3172
+ }
3151
3173
}
3152
3174
3153
3175
// Then gather all uses of our address by walking from def->uses. We use this
@@ -3156,10 +3178,16 @@ bool MoveOnlyAddressCheckerPImpl::performSingleCheck(
3156
3178
GatherUsesVisitor visitor (*this , addressUseState, markedAddress,
3157
3179
diagnosticEmitter);
3158
3180
SWIFT_DEFER { visitor.clear (); };
3159
- visitor.reset (markedAddress);
3160
- if (AddressUseKind::Unknown == std::move (visitor).walk (markedAddress)) {
3161
- LLVM_DEBUG (llvm::dbgs () << " Failed access path visit: " << *markedAddress);
3162
- return false ;
3181
+
3182
+ {
3183
+ RAIILLVMDebug l (" main use gathering visitor" );
3184
+
3185
+ visitor.reset (markedAddress);
3186
+ if (AddressUseKind::Unknown == std::move (visitor).walk (markedAddress)) {
3187
+ LLVM_DEBUG (llvm::dbgs ()
3188
+ << " Failed access path visit: " << *markedAddress);
3189
+ return false ;
3190
+ }
3163
3191
}
3164
3192
3165
3193
// If we found a load [copy] or copy_addr that requires multiple copies or an
@@ -3187,18 +3215,28 @@ bool MoveOnlyAddressCheckerPImpl::performSingleCheck(
3187
3215
// ===---
3188
3216
// Liveness Checking
3189
3217
//
3218
+
3190
3219
SmallVector<SILBasicBlock *, 32 > discoveredBlocks;
3191
3220
FieldSensitiveMultiDefPrunedLiveRange liveness (fn, markedAddress,
3192
3221
&discoveredBlocks);
3193
- addressUseState.initializeLiveness (liveness);
3194
3222
3195
- // Then compute the takes that are within the cumulative boundary of
3196
- // liveness that we have computed. If we find any, they are the errors ones.
3197
- GlobalLivenessChecker emitter (addressUseState, diagnosticEmitter, liveness);
3223
+ {
3224
+ RAIILLVMDebug logger (" liveness initialization" );
3198
3225
3199
- // If we had any errors, we do not want to modify the SIL... just bail.
3200
- if (emitter.compute ()) {
3201
- return true ;
3226
+ addressUseState.initializeLiveness (liveness);
3227
+ }
3228
+
3229
+ {
3230
+ RAIILLVMDebug l (" global liveness checking" );
3231
+
3232
+ // Then compute the takes that are within the cumulative boundary of
3233
+ // liveness that we have computed. If we find any, they are the errors ones.
3234
+ GlobalLivenessChecker emitter (addressUseState, diagnosticEmitter, liveness);
3235
+
3236
+ // If we had any errors, we do not want to modify the SIL... just bail.
3237
+ if (emitter.compute ()) {
3238
+ return true ;
3239
+ }
3202
3240
}
3203
3241
3204
3242
// ===
@@ -3242,15 +3280,40 @@ bool MoveOnlyAddressCheckerPImpl::performSingleCheck(
3242
3280
// MARK: Top Level Entrypoint
3243
3281
// ===----------------------------------------------------------------------===//
3244
3282
3283
+ #ifndef NDEBUG
3284
+ static llvm::cl::opt<uint64_t > NumTopLevelToProcess (
3285
+ " sil-move-only-address-checker-num-top-level-to-process" ,
3286
+ llvm::cl::desc (" Allows for bisecting on move introducer that causes an "
3287
+ " error. Only meant for debugging!" ),
3288
+ llvm::cl::init(UINT64_MAX));
3289
+ #endif
3290
+
3291
+ static llvm::cl::opt<bool > DumpSILBeforeRemovingMarkMustCheck (
3292
+ " sil-move-only-address-checker-dump-before-removing-mark-must-check" ,
3293
+ llvm::cl::desc (" When bisecting it is useful to dump the SIL before the "
3294
+ " rest of the checker removes mark_must_check. This lets one "
3295
+ " grab the SIL of a bad variable after all of the rest have "
3296
+ " been processed to work with further in sil-opt." ),
3297
+ llvm::cl::init(false ));
3298
+
3245
3299
bool MoveOnlyAddressChecker::check (
3246
3300
SmallSetVector<MarkMustCheckInst *, 32 > &moveIntroducersToProcess) {
3247
3301
assert (moveIntroducersToProcess.size () &&
3248
3302
" Must have checks to process to call this function" );
3249
3303
MoveOnlyAddressCheckerPImpl pimpl (fn, diagnosticEmitter, domTree, poa,
3250
3304
allocator);
3251
3305
3306
+ #ifndef NDEBUG
3307
+ static uint64_t numProcessed = 0 ;
3308
+ #endif
3252
3309
for (auto *markedValue : moveIntroducersToProcess) {
3253
- LLVM_DEBUG (llvm::dbgs () << " Visiting: " << *markedValue);
3310
+ #ifndef NDEBUG
3311
+ ++numProcessed;
3312
+ if (NumTopLevelToProcess <= numProcessed)
3313
+ break ;
3314
+ #endif
3315
+ LLVM_DEBUG (llvm::dbgs ()
3316
+ << " ======>>> Visiting top level: " << *markedValue);
3254
3317
3255
3318
// Perform our address check.
3256
3319
unsigned diagnosticEmittedByEarlierPassCount =
@@ -3271,5 +3334,10 @@ bool MoveOnlyAddressChecker::check(
3271
3334
}
3272
3335
}
3273
3336
3337
+ if (DumpSILBeforeRemovingMarkMustCheck) {
3338
+ LLVM_DEBUG (llvm::dbgs ()
3339
+ << " Dumping SIL before removing mark must checks!\n " ;
3340
+ fn->dump ());
3341
+ }
3274
3342
return pimpl.changed ;
3275
3343
}
0 commit comments