diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 98 |
1 files changed, 68 insertions, 30 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 13a2f30..38ecb75 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1736,17 +1736,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; } @@ -1761,12 +1770,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; } @@ -1801,23 +1825,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. @@ -1829,9 +1865,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(); @@ -1845,7 +1883,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); }; @@ -1871,15 +1909,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; } |