@@ -4217,12 +4217,29 @@ bool InstCombinerImpl::tryToSinkInstruction(Instruction *I,
4217
4217
// mark the location undef: we know it was supposed to receive a new location
4218
4218
// here, but that computation has been sunk.
4219
4219
SmallVector<DbgVariableIntrinsic *, 2 > DbgUsers;
4220
- findDbgUsers (DbgUsers, I);
4220
+ SmallVector<DPValue *, 2 > DPValues;
4221
+ findDbgUsers (DbgUsers, I, &DPValues);
4222
+ tryToSinkInstructionDbgValues (I, InsertPos, SrcBlock, DestBlock, DbgUsers);
4223
+ tryToSinkInstructionDPValues (I, InsertPos, SrcBlock, DestBlock, DPValues);
4224
+
4225
+ // PS: there are numerous flaws with this behaviour, not least that right now
4226
+ // assignments can be re-ordered past other assignments to the same variable
4227
+ // if they use different Values. Creating more undef assignements can never be
4228
+ // undone. And salvaging all users outside of this block can un-necessarily
4229
+ // alter the lifetime of the live-value that the variable refers to.
4230
+ // Some of these things can be resolved by tolerating debug use-before-defs in
4231
+ // LLVM-IR, however it depends on the instruction-referencing CodeGen backend
4232
+ // being used for more architectures.
4221
4233
4234
+ return true ;
4235
+ }
4236
+
4237
+ void InstCombinerImpl::tryToSinkInstructionDbgValues (
4238
+ Instruction *I, BasicBlock::iterator InsertPos, BasicBlock *SrcBlock,
4239
+ BasicBlock *DestBlock, SmallVectorImpl<DbgVariableIntrinsic *> &DbgUsers) {
4222
4240
// For all debug values in the destination block, the sunk instruction
4223
4241
// will still be available, so they do not need to be dropped.
4224
4242
SmallVector<DbgVariableIntrinsic *, 2 > DbgUsersToSalvage;
4225
- SmallVector<DPValue *, 2 > DPValuesToSalvage;
4226
4243
for (auto &DbgUser : DbgUsers)
4227
4244
if (DbgUser->getParent () != DestBlock)
4228
4245
DbgUsersToSalvage.push_back (DbgUser);
@@ -4266,19 +4283,140 @@ bool InstCombinerImpl::tryToSinkInstruction(Instruction *I,
4266
4283
4267
4284
// Perform salvaging without the clones, then sink the clones.
4268
4285
if (!DIIClones.empty ()) {
4269
- // RemoveDIs: pass in empty vector of DPValues until we get to instrumenting
4270
- // this pass.
4271
- SmallVector<DPValue *, 1 > DummyDPValues;
4272
- salvageDebugInfoForDbgValues (*I, DbgUsersToSalvage, DummyDPValues);
4286
+ salvageDebugInfoForDbgValues (*I, DbgUsersToSalvage, {});
4273
4287
// The clones are in reverse order of original appearance, reverse again to
4274
4288
// maintain the original order.
4275
4289
for (auto &DIIClone : llvm::reverse (DIIClones)) {
4276
4290
DIIClone->insertBefore (&*InsertPos);
4277
4291
LLVM_DEBUG (dbgs () << " SINK: " << *DIIClone << ' \n ' );
4278
4292
}
4279
4293
}
4294
+ }
4280
4295
4281
- return true ;
4296
+ void InstCombinerImpl::tryToSinkInstructionDPValues (
4297
+ Instruction *I, BasicBlock::iterator InsertPos, BasicBlock *SrcBlock,
4298
+ BasicBlock *DestBlock, SmallVectorImpl<DPValue *> &DPValues) {
4299
+ // Implementation of tryToSinkInstructionDbgValues, but for the DPValue of
4300
+ // variable assignments rather than dbg.values.
4301
+
4302
+ // Fetch all DPValues not already in the destination.
4303
+ SmallVector<DPValue *, 2 > DPValuesToSalvage;
4304
+ for (auto &DPV : DPValues)
4305
+ if (DPV->getParent () != DestBlock)
4306
+ DPValuesToSalvage.push_back (DPV);
4307
+
4308
+ // Fetch a second collection, of DPValues in the source block that we're going
4309
+ // to sink.
4310
+ SmallVector<DPValue *> DPValuesToSink;
4311
+ for (DPValue *DPV : DPValuesToSalvage)
4312
+ if (DPV->getParent () == SrcBlock)
4313
+ DPValuesToSink.push_back (DPV);
4314
+
4315
+ // Sort DPValues according to their position in the block. This is a partial
4316
+ // order: DPValues attached to different instructions will be ordered by the
4317
+ // instruction order, but DPValues attached to the same instruction won't
4318
+ // have an order.
4319
+ auto Order = [](DPValue *A, DPValue *B) -> bool {
4320
+ return B->getInstruction ()->comesBefore (A->getInstruction ());
4321
+ };
4322
+ llvm::stable_sort (DPValuesToSink, Order);
4323
+
4324
+ // If there are two assignments to the same variable attached to the same
4325
+ // instruction, the ordering between the two assignments is important. Scan
4326
+ // for this (rare) case and establish which is the last assignment.
4327
+ using InstVarPair = std::pair<const Instruction *, DebugVariable>;
4328
+ SmallDenseMap<InstVarPair, DPValue *> FilterOutMap;
4329
+ if (DPValuesToSink.size () > 1 ) {
4330
+ SmallDenseMap<InstVarPair, unsigned > CountMap;
4331
+ // Count how many assignments to each variable there is per instruction.
4332
+ for (DPValue *DPV : DPValuesToSink) {
4333
+ DebugVariable DbgUserVariable =
4334
+ DebugVariable (DPV->getVariable (), DPV->getExpression (),
4335
+ DPV->getDebugLoc ()->getInlinedAt ());
4336
+ CountMap[std::make_pair (DPV->getInstruction (), DbgUserVariable)] += 1 ;
4337
+ }
4338
+
4339
+ // If there are any instructions with two assignments, add them to the
4340
+ // FilterOutMap to record that they need extra filtering.
4341
+ SmallPtrSet<const Instruction *, 4 > DupSet;
4342
+ for (auto It : CountMap) {
4343
+ if (It.second > 1 ) {
4344
+ FilterOutMap[It.first ] = nullptr ;
4345
+ DupSet.insert (It.first .first );
4346
+ }
4347
+ }
4348
+
4349
+ // For all instruction/variable pairs needing extra filtering, find the
4350
+ // latest assignment.
4351
+ for (const Instruction *Inst : DupSet) {
4352
+ for (DPValue &DPV : llvm::reverse (Inst->getDbgValueRange ())) {
4353
+ DebugVariable DbgUserVariable =
4354
+ DebugVariable (DPV.getVariable (), DPV.getExpression (),
4355
+ DPV.getDebugLoc ()->getInlinedAt ());
4356
+ auto FilterIt =
4357
+ FilterOutMap.find (std::make_pair (Inst, DbgUserVariable));
4358
+ if (FilterIt == FilterOutMap.end ())
4359
+ continue ;
4360
+ if (FilterIt->second != nullptr )
4361
+ continue ;
4362
+ FilterIt->second = &DPV;
4363
+ }
4364
+ }
4365
+ }
4366
+
4367
+ // Perform cloning of the DPValues that we plan on sinking, filter out any
4368
+ // duplicate assignments identified above.
4369
+ SmallVector<DPValue *, 2 > DPVClones;
4370
+ SmallSet<DebugVariable, 4 > SunkVariables;
4371
+ for (DPValue *DPV : DPValuesToSink) {
4372
+ if (DPV->Type == DPValue::LocationType::Declare)
4373
+ continue ;
4374
+
4375
+ DebugVariable DbgUserVariable =
4376
+ DebugVariable (DPV->getVariable (), DPV->getExpression (),
4377
+ DPV->getDebugLoc ()->getInlinedAt ());
4378
+
4379
+ // For any variable where there were multiple assignments in the same place,
4380
+ // ignore all but the last assignment.
4381
+ if (!FilterOutMap.empty ()) {
4382
+ InstVarPair IVP = std::make_pair (DPV->getInstruction (), DbgUserVariable);
4383
+ auto It = FilterOutMap.find (IVP);
4384
+
4385
+ // Filter out.
4386
+ if (It != FilterOutMap.end () && It->second != DPV)
4387
+ continue ;
4388
+ }
4389
+
4390
+ if (!SunkVariables.insert (DbgUserVariable).second )
4391
+ continue ;
4392
+
4393
+ // FIXME: dbg.assign equivalence. dbg.assigns here enter the SunkVariables
4394
+ // map, but don't actually get sunk.
4395
+
4396
+ DPVClones.emplace_back (DPV->clone ());
4397
+ LLVM_DEBUG (dbgs () << " CLONE: " << *DPVClones.back () << ' \n ' );
4398
+ }
4399
+
4400
+ // Perform salvaging without the clones, then sink the clones.
4401
+ if (DPVClones.empty ())
4402
+ return ;
4403
+
4404
+ salvageDebugInfoForDbgValues (*I, {}, DPValuesToSalvage);
4405
+
4406
+ // The clones are in reverse order of original appearance. Assert that the
4407
+ // head bit is set on the iterator as we _should_ have received it via
4408
+ // getFirstInsertionPt. Inserting like this will reverse the clone order as
4409
+ // we'll repeatedly insert at the head, such as:
4410
+ // DPV-3 (third insertion goes here)
4411
+ // DPV-2 (second insertion goes here)
4412
+ // DPV-1 (first insertion goes here)
4413
+ // Any-Prior-DPVs
4414
+ // InsertPtInst
4415
+ assert (InsertPos.getHeadBit ());
4416
+ for (DPValue *DPVClone : DPVClones) {
4417
+ InsertPos->getParent ()->insertDPValueBefore (DPVClone, InsertPos);
4418
+ LLVM_DEBUG (dbgs () << " SINK: " << *DPVClone << ' \n ' );
4419
+ }
4282
4420
}
4283
4421
4284
4422
bool InstCombinerImpl::run () {
0 commit comments