aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
authorgbtozers <stephen.tozer@sony.com>2020-09-30 19:15:44 +0100
committerStephen Tozer <Stephen.Tozer@Sony.com>2021-03-11 13:33:49 +0000
commitc0f3dfb9f119bb5f22dd8846f5502b6abaf026d3 (patch)
tree2cc0da19c4c2e97515466cbdf9273105603d4c87 /llvm/lib/Transforms/Utils/Local.cpp
parentea834c8365ca7c4f0b491f5de98c521df9401ea9 (diff)
downloadllvm-c0f3dfb9f119bb5f22dd8846f5502b6abaf026d3.zip
llvm-c0f3dfb9f119bb5f22dd8846f5502b6abaf026d3.tar.gz
llvm-c0f3dfb9f119bb5f22dd8846f5502b6abaf026d3.tar.bz2
[DebugInfo] Use variadic debug values to salvage BinOps and GEP instrs with non-const operands
This patch improves salvageDebugInfoImpl by allowing it to salvage arithmetic operations with two or more non-const operands; this includes the GetElementPtr instruction, and most Binary Operator instructions. These salvages produce DIArgList locations and are only valid for dbg.values, as currently variadic DIExpressions must use DW_OP_stack_value. This functionality is also only added for salvageDebugInfoForDbgValues; other functions that directly call salvageDebugInfoImpl (such as in ISel or Coroutine frame building) can be updated in a later patch. Differential Revision: https://reviews.llvm.org/D91722
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 64c2042..d9592a3 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1812,17 +1812,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;
}
@@ -1837,12 +1846,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;
}
@@ -1877,23 +1901,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.
@@ -1905,9 +1941,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();
@@ -1921,7 +1959,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);
};
@@ -1947,15 +1985,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;
}