aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
authorStephen Tozer <Stephen.Tozer@Sony.com>2021-04-22 12:06:52 +0100
committerStephen Tozer <Stephen.Tozer@Sony.com>2021-04-23 10:54:01 +0100
commit791930d74087b8ae8901172861a0fd21a211e436 (patch)
treed8ec9714036b2e96dfc3946d1aaebd0302ef4988 /llvm/lib/Transforms/Utils/Local.cpp
parent151e244fe687901e69e4a3c569ef3bb252b7e4fc (diff)
downloadllvm-791930d74087b8ae8901172861a0fd21a211e436.zip
llvm-791930d74087b8ae8901172861a0fd21a211e436.tar.gz
llvm-791930d74087b8ae8901172861a0fd21a211e436.tar.bz2
Re-reapply "[DebugInfo] Use variadic debug values to salvage BinOps and GEP instrs with non-const operands"
Previous build failures were caused by an error in bitcode reading and writing for DIArgList metadata, which has been fixed in e5d844b587. There were also some unnecessary asserts that were being triggered on certain builds, which have been removed. This reverts commit dad5caa59e6b2bde8d6cf5b64a972c393c526c82.
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp98
1 files changed, 68 insertions, 30 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index beea211..255bb8d 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1729,17 +1729,26 @@ void llvm::salvageDebugInfoForDbgValues(
is_contained(DIILocation, &I) &&
"DbgVariableIntrinsic must use salvaged instruction as its location");
unsigned LocNo = std::distance(DIILocation.begin(), find(DIILocation, &I));
-
- DIExpression *DIExpr =
- salvageDebugInfoImpl(I, DII->getExpression(), StackValue, LocNo);
+ SmallVector<Value *, 4> AdditionalValues;
+ DIExpression *SalvagedExpr = salvageDebugInfoImpl(
+ I, DII->getExpression(), StackValue, LocNo, AdditionalValues);
// salvageDebugInfoImpl should fail on examining the first element of
// DbgUsers, or none of them.
- if (!DIExpr)
+ if (!SalvagedExpr)
break;
DII->replaceVariableLocationOp(&I, I.getOperand(0));
- DII->setExpression(DIExpr);
+ if (AdditionalValues.empty()) {
+ DII->setExpression(SalvagedExpr);
+ } else if (isa<DbgValueInst>(DII)) {
+ DII->addVariableLocationOps(AdditionalValues, SalvagedExpr);
+ } else {
+ // Do not salvage using DIArgList for dbg.addr/dbg.declare, as it is
+ // currently only valid for stack value expressions.
+ Value *Undef = UndefValue::get(I.getOperand(0)->getType());
+ DII->replaceVariableLocationOp(I.getOperand(0), Undef);
+ }
LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n');
Salvaged = true;
}
@@ -1754,12 +1763,27 @@ void llvm::salvageDebugInfoForDbgValues(
}
bool getSalvageOpsForGEP(GetElementPtrInst *GEP, const DataLayout &DL,
- SmallVectorImpl<uint64_t> &Opcodes) {
+ uint64_t CurrentLocOps,
+ SmallVectorImpl<uint64_t> &Opcodes,
+ SmallVectorImpl<Value *> &AdditionalValues) {
unsigned BitWidth = DL.getIndexSizeInBits(GEP->getPointerAddressSpace());
- // Rewrite a constant GEP into a DIExpression.
+ // Rewrite a GEP into a DIExpression.
+ SmallDenseMap<Value *, APInt, 8> VariableOffsets;
APInt ConstantOffset(BitWidth, 0);
- if (!GEP->accumulateConstantOffset(DL, ConstantOffset))
+ if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset))
return false;
+ if (!VariableOffsets.empty() && !CurrentLocOps) {
+ Opcodes.insert(Opcodes.begin(), {dwarf::DW_OP_LLVM_arg, 0});
+ CurrentLocOps = 1;
+ }
+ for (auto Offset : VariableOffsets) {
+ AdditionalValues.push_back(Offset.first);
+ assert(Offset.second.isStrictlyPositive() &&
+ "Expected strictly positive multiplier for offset.");
+ Opcodes.append({dwarf::DW_OP_LLVM_arg, CurrentLocOps++, dwarf::DW_OP_constu,
+ Offset.second.getZExtValue(), dwarf::DW_OP_mul,
+ dwarf::DW_OP_plus});
+ }
DIExpression::appendOffset(Opcodes, ConstantOffset.getSExtValue());
return true;
}
@@ -1794,23 +1818,35 @@ uint64_t getDwarfOpForBinOp(Instruction::BinaryOps Opcode) {
}
}
-bool getSalvageOpsForBinOp(BinaryOperator *BI,
- SmallVectorImpl<uint64_t> &Opcodes) {
- // Rewrite binary operations with constant integer operands.
+bool getSalvageOpsForBinOp(BinaryOperator *BI, uint64_t CurrentLocOps,
+ SmallVectorImpl<uint64_t> &Opcodes,
+ SmallVectorImpl<Value *> &AdditionalValues) {
+ // Handle binary operations with constant integer operands as a special case.
auto *ConstInt = dyn_cast<ConstantInt>(BI->getOperand(1));
- if (!ConstInt || ConstInt->getBitWidth() > 64)
+ // Values wider than 64 bits cannot be represented within a DIExpression.
+ if (ConstInt && ConstInt->getBitWidth() > 64)
return false;
- uint64_t Val = ConstInt->getSExtValue();
+
Instruction::BinaryOps BinOpcode = BI->getOpcode();
- // Add or Sub Instructions with a constant operand can potentially be
- // simplified.
- if (BinOpcode == Instruction::Add || BinOpcode == Instruction::Sub) {
- uint64_t Offset = BinOpcode == Instruction::Add ? Val : -int64_t(Val);
- DIExpression::appendOffset(Opcodes, Offset);
- return true;
+ // Push any Constant Int operand onto the expression stack.
+ if (ConstInt) {
+ uint64_t Val = ConstInt->getSExtValue();
+ // Add or Sub Instructions with a constant operand can potentially be
+ // simplified.
+ if (BinOpcode == Instruction::Add || BinOpcode == Instruction::Sub) {
+ uint64_t Offset = BinOpcode == Instruction::Add ? Val : -int64_t(Val);
+ DIExpression::appendOffset(Opcodes, Offset);
+ return true;
+ }
+ Opcodes.append({dwarf::DW_OP_constu, Val});
+ } else {
+ if (!CurrentLocOps) {
+ Opcodes.append({dwarf::DW_OP_LLVM_arg, 0});
+ CurrentLocOps = 1;
+ }
+ Opcodes.append({dwarf::DW_OP_LLVM_arg, CurrentLocOps});
+ AdditionalValues.push_back(BI->getOperand(1));
}
- // Add constant int operand to expression stack.
- Opcodes.append({dwarf::DW_OP_constu, Val});
// Add salvaged binary operator to expression stack, if it has a valid
// representation in a DIExpression.
@@ -1822,9 +1858,11 @@ bool getSalvageOpsForBinOp(BinaryOperator *BI,
return true;
}
-DIExpression *llvm::salvageDebugInfoImpl(Instruction &I,
- DIExpression *SrcDIExpr,
- bool WithStackValue, unsigned LocNo) {
+DIExpression *
+llvm::salvageDebugInfoImpl(Instruction &I, DIExpression *SrcDIExpr,
+ bool WithStackValue, unsigned LocNo,
+ SmallVectorImpl<Value *> &AdditionalValues) {
+ uint64_t CurrentLocOps = SrcDIExpr->getNumLocationOperands();
auto &M = *I.getModule();
auto &DL = M.getDataLayout();
@@ -1838,7 +1876,7 @@ DIExpression *llvm::salvageDebugInfoImpl(Instruction &I,
};
// initializer-list helper for applying operators to the source DIExpression.
- auto applyOps = [&](ArrayRef<uint64_t> Opcodes) -> DIExpression * {
+ auto applyOps = [&](ArrayRef<uint64_t> Opcodes) {
SmallVector<uint64_t, 8> Ops(Opcodes.begin(), Opcodes.end());
return doSalvage(Ops);
};
@@ -1864,15 +1902,15 @@ DIExpression *llvm::salvageDebugInfoImpl(Instruction &I,
SmallVector<uint64_t, 8> Ops;
if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
- if (getSalvageOpsForGEP(GEP, DL, Ops))
+ if (getSalvageOpsForGEP(GEP, DL, CurrentLocOps, Ops, AdditionalValues))
return doSalvage(Ops);
} else if (auto *BI = dyn_cast<BinaryOperator>(&I)) {
- if (getSalvageOpsForBinOp(BI, Ops))
+ if (getSalvageOpsForBinOp(BI, CurrentLocOps, Ops, AdditionalValues))
return doSalvage(Ops);
}
- // *Not* to do: we should not attempt to salvage load instructions,
- // because the validity and lifetime of a dbg.value containing
- // DW_OP_deref becomes difficult to analyze. See PR40628 for examples.
+ // *Not* to do: we should not attempt to salvage load instructions,
+ // because the validity and lifetime of a dbg.value containing
+ // DW_OP_deref becomes difficult to analyze. See PR40628 for examples.
return nullptr;
}