@@ -4313,12 +4313,31 @@ bool InstCombinerImpl::tryToSinkInstruction(Instruction *I,
43134313 // mark the location undef: we know it was supposed to receive a new location
43144314 // here, but that computation has been sunk.
43154315 SmallVector<DbgVariableIntrinsic *, 2 > DbgUsers;
4316- findDbgUsers (DbgUsers, I);
4316+ SmallVector<DPValue *, 2 > DPValues;
4317+ findDbgUsers (DbgUsers, I, &DPValues);
4318+ if (!DbgUsers.empty ())
4319+ tryToSinkInstructionDbgValues (I, InsertPos, SrcBlock, DestBlock, DbgUsers);
4320+ if (!DPValues.empty ())
4321+ tryToSinkInstructionDPValues (I, InsertPos, SrcBlock, DestBlock, DPValues);
4322+
4323+ // PS: there are numerous flaws with this behaviour, not least that right now
4324+ // assignments can be re-ordered past other assignments to the same variable
4325+ // if they use different Values. Creating more undef assignements can never be
4326+ // undone. And salvaging all users outside of this block can un-necessarily
4327+ // alter the lifetime of the live-value that the variable refers to.
4328+ // Some of these things can be resolved by tolerating debug use-before-defs in
4329+ // LLVM-IR, however it depends on the instruction-referencing CodeGen backend
4330+ // being used for more architectures.
43174331
4332+ return true ;
4333+ }
4334+
4335+ void InstCombinerImpl::tryToSinkInstructionDbgValues (
4336+ Instruction *I, BasicBlock::iterator InsertPos, BasicBlock *SrcBlock,
4337+ BasicBlock *DestBlock, SmallVectorImpl<DbgVariableIntrinsic *> &DbgUsers) {
43184338 // For all debug values in the destination block, the sunk instruction
43194339 // will still be available, so they do not need to be dropped.
43204340 SmallVector<DbgVariableIntrinsic *, 2 > DbgUsersToSalvage;
4321- SmallVector<DPValue *, 2 > DPValuesToSalvage;
43224341 for (auto &DbgUser : DbgUsers)
43234342 if (DbgUser->getParent () != DestBlock)
43244343 DbgUsersToSalvage.push_back (DbgUser);
@@ -4362,19 +4381,140 @@ bool InstCombinerImpl::tryToSinkInstruction(Instruction *I,
43624381
43634382 // Perform salvaging without the clones, then sink the clones.
43644383 if (!DIIClones.empty ()) {
4365- // RemoveDIs: pass in empty vector of DPValues until we get to instrumenting
4366- // this pass.
4367- SmallVector<DPValue *, 1 > DummyDPValues;
4368- salvageDebugInfoForDbgValues (*I, DbgUsersToSalvage, DummyDPValues);
4384+ salvageDebugInfoForDbgValues (*I, DbgUsersToSalvage, {});
43694385 // The clones are in reverse order of original appearance, reverse again to
43704386 // maintain the original order.
43714387 for (auto &DIIClone : llvm::reverse (DIIClones)) {
43724388 DIIClone->insertBefore (&*InsertPos);
43734389 LLVM_DEBUG (dbgs () << " SINK: " << *DIIClone << ' \n ' );
43744390 }
43754391 }
4392+ }
43764393
4377- return true ;
4394+ void InstCombinerImpl::tryToSinkInstructionDPValues (
4395+ Instruction *I, BasicBlock::iterator InsertPos, BasicBlock *SrcBlock,
4396+ BasicBlock *DestBlock, SmallVectorImpl<DPValue *> &DPValues) {
4397+ // Implementation of tryToSinkInstructionDbgValues, but for the DPValue of
4398+ // variable assignments rather than dbg.values.
4399+
4400+ // Fetch all DPValues not already in the destination.
4401+ SmallVector<DPValue *, 2 > DPValuesToSalvage;
4402+ for (auto &DPV : DPValues)
4403+ if (DPV->getParent () != DestBlock)
4404+ DPValuesToSalvage.push_back (DPV);
4405+
4406+ // Fetch a second collection, of DPValues in the source block that we're going
4407+ // to sink.
4408+ SmallVector<DPValue *> DPValuesToSink;
4409+ for (DPValue *DPV : DPValuesToSalvage)
4410+ if (DPV->getParent () == SrcBlock)
4411+ DPValuesToSink.push_back (DPV);
4412+
4413+ // Sort DPValues according to their position in the block. This is a partial
4414+ // order: DPValues attached to different instructions will be ordered by the
4415+ // instruction order, but DPValues attached to the same instruction won't
4416+ // have an order.
4417+ auto Order = [](DPValue *A, DPValue *B) -> bool {
4418+ return B->getInstruction ()->comesBefore (A->getInstruction ());
4419+ };
4420+ llvm::stable_sort (DPValuesToSink, Order);
4421+
4422+ // If there are two assignments to the same variable attached to the same
4423+ // instruction, the ordering between the two assignments is important. Scan
4424+ // for this (rare) case and establish which is the last assignment.
4425+ using InstVarPair = std::pair<const Instruction *, DebugVariable>;
4426+ SmallDenseMap<InstVarPair, DPValue *> FilterOutMap;
4427+ if (DPValuesToSink.size () > 1 ) {
4428+ SmallDenseMap<InstVarPair, unsigned > CountMap;
4429+ // Count how many assignments to each variable there is per instruction.
4430+ for (DPValue *DPV : DPValuesToSink) {
4431+ DebugVariable DbgUserVariable =
4432+ DebugVariable (DPV->getVariable (), DPV->getExpression (),
4433+ DPV->getDebugLoc ()->getInlinedAt ());
4434+ CountMap[std::make_pair (DPV->getInstruction (), DbgUserVariable)] += 1 ;
4435+ }
4436+
4437+ // If there are any instructions with two assignments, add them to the
4438+ // FilterOutMap to record that they need extra filtering.
4439+ SmallPtrSet<const Instruction *, 4 > DupSet;
4440+ for (auto It : CountMap) {
4441+ if (It.second > 1 ) {
4442+ FilterOutMap[It.first ] = nullptr ;
4443+ DupSet.insert (It.first .first );
4444+ }
4445+ }
4446+
4447+ // For all instruction/variable pairs needing extra filtering, find the
4448+ // latest assignment.
4449+ for (const Instruction *Inst : DupSet) {
4450+ for (DPValue &DPV : llvm::reverse (Inst->getDbgValueRange ())) {
4451+ DebugVariable DbgUserVariable =
4452+ DebugVariable (DPV.getVariable (), DPV.getExpression (),
4453+ DPV.getDebugLoc ()->getInlinedAt ());
4454+ auto FilterIt =
4455+ FilterOutMap.find (std::make_pair (Inst, DbgUserVariable));
4456+ if (FilterIt == FilterOutMap.end ())
4457+ continue ;
4458+ if (FilterIt->second != nullptr )
4459+ continue ;
4460+ FilterIt->second = &DPV;
4461+ }
4462+ }
4463+ }
4464+
4465+ // Perform cloning of the DPValues that we plan on sinking, filter out any
4466+ // duplicate assignments identified above.
4467+ SmallVector<DPValue *, 2 > DPVClones;
4468+ SmallSet<DebugVariable, 4 > SunkVariables;
4469+ for (DPValue *DPV : DPValuesToSink) {
4470+ if (DPV->Type == DPValue::LocationType::Declare)
4471+ continue ;
4472+
4473+ DebugVariable DbgUserVariable =
4474+ DebugVariable (DPV->getVariable (), DPV->getExpression (),
4475+ DPV->getDebugLoc ()->getInlinedAt ());
4476+
4477+ // For any variable where there were multiple assignments in the same place,
4478+ // ignore all but the last assignment.
4479+ if (!FilterOutMap.empty ()) {
4480+ InstVarPair IVP = std::make_pair (DPV->getInstruction (), DbgUserVariable);
4481+ auto It = FilterOutMap.find (IVP);
4482+
4483+ // Filter out.
4484+ if (It != FilterOutMap.end () && It->second != DPV)
4485+ continue ;
4486+ }
4487+
4488+ if (!SunkVariables.insert (DbgUserVariable).second )
4489+ continue ;
4490+
4491+ if (DPV->isDbgAssign ())
4492+ continue ;
4493+
4494+ DPVClones.emplace_back (DPV->clone ());
4495+ LLVM_DEBUG (dbgs () << " CLONE: " << *DPVClones.back () << ' \n ' );
4496+ }
4497+
4498+ // Perform salvaging without the clones, then sink the clones.
4499+ if (DPVClones.empty ())
4500+ return ;
4501+
4502+ salvageDebugInfoForDbgValues (*I, {}, DPValuesToSalvage);
4503+
4504+ // The clones are in reverse order of original appearance. Assert that the
4505+ // head bit is set on the iterator as we _should_ have received it via
4506+ // getFirstInsertionPt. Inserting like this will reverse the clone order as
4507+ // we'll repeatedly insert at the head, such as:
4508+ // DPV-3 (third insertion goes here)
4509+ // DPV-2 (second insertion goes here)
4510+ // DPV-1 (first insertion goes here)
4511+ // Any-Prior-DPVs
4512+ // InsertPtInst
4513+ assert (InsertPos.getHeadBit ());
4514+ for (DPValue *DPVClone : DPVClones) {
4515+ InsertPos->getParent ()->insertDPValueBefore (DPVClone, InsertPos);
4516+ LLVM_DEBUG (dbgs () << " SINK: " << *DPVClone << ' \n ' );
4517+ }
43784518}
43794519
43804520bool InstCombinerImpl::run () {
0 commit comments