Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
Show First 20 Lines • Show All 403 Lines • ▼ Show 20 Lines | |||||
/// | /// | ||||
/// then the instruction marked with (*) can be removed. Variable "x" is already | /// then the instruction marked with (*) can be removed. Variable "x" is already | ||||
/// described as being mapped to the SSA value X1. | /// described as being mapped to the SSA value X1. | ||||
/// | /// | ||||
/// Possible improvements: | /// Possible improvements: | ||||
/// - Keep track of non-overlapping fragments. | /// - Keep track of non-overlapping fragments. | ||||
static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { | static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { | ||||
SmallVector<DbgValueInst *, 8> ToBeRemoved; | SmallVector<DbgValueInst *, 8> ToBeRemoved; | ||||
DenseMap<DebugVariable, std::pair<Value *, DIExpression *> > VariableMap; | DenseMap<DebugVariable, std::pair<Value *, DIExpression *>> VariableMap; | ||||
auto ShouldRemove = [&](DebugVariable Var, const DbgValueInst *DVI) { | |||||
auto VMI = VariableMap.find(Var); | |||||
// Check if this is the first time we've encountered this variable. | |||||
if (VMI == VariableMap.end()) | |||||
return false; | |||||
// Check if this is a new value for an existing variable. | |||||
if (VMI->second.first != DVI->getValue() || | |||||
VMI->second.second != DVI->getExpression()) | |||||
return false; | |||||
// The fix to PR47946 introduces InlineLowerDbgDeclare which scans | |||||
// backwards through debug intrinsics from inlined callsites to find the | |||||
// dbg.value+deref which LowerDbgDeclare may have inserted before calls. To | |||||
bjope: Not sure I understand exactly how/if this motivates why the dbg.value should be kept. If we… | |||||
// improve the efficacy of the fix we avoid removing dbg.value+drefers | |||||
// here. | |||||
if (DVI->getExpression()->startsWithDeref()) | |||||
return false; | |||||
return true; | |||||
}; | |||||
for (auto &I : *BB) { | for (auto &I : *BB) { | ||||
if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(&I)) { | if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(&I)) { | ||||
DebugVariable Key(DVI->getVariable(), | DebugVariable Key(DVI->getVariable(), NoneType(), | ||||
NoneType(), | |||||
DVI->getDebugLoc()->getInlinedAt()); | DVI->getDebugLoc()->getInlinedAt()); | ||||
auto VMI = VariableMap.find(Key); | if (ShouldRemove(Key, DVI)) | ||||
// Update the map if we found a new value/expression describing the | |||||
// variable, or if the variable wasn't mapped already. | |||||
if (VMI == VariableMap.end() || | |||||
VMI->second.first != DVI->getValue() || | |||||
VMI->second.second != DVI->getExpression()) { | |||||
VariableMap[Key] = { DVI->getValue(), DVI->getExpression() }; | |||||
continue; | |||||
} | |||||
// Found an identical mapping. Remember the instruction for later removal. | |||||
ToBeRemoved.push_back(DVI); | ToBeRemoved.push_back(DVI); | ||||
else | |||||
VariableMap[Key] = {DVI->getValue(), DVI->getExpression()}; | |||||
} | } | ||||
} | } | ||||
for (auto &Instr : ToBeRemoved) | for (auto &Instr : ToBeRemoved) | ||||
Instr->eraseFromParent(); | Instr->eraseFromParent(); | ||||
return !ToBeRemoved.empty(); | return !ToBeRemoved.empty(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,006 Lines • Show Last 20 Lines |
Not sure I understand exactly how/if this motivates why the dbg.value should be kept. If we first say that the variable is at address X, and then later say that the variable is at address X, the second statement seem redundant to me.