diff options
author | Jeremy Morse <jeremy.morse.llvm@gmail.com> | 2019-02-05 11:11:28 +0000 |
---|---|---|
committer | Jeremy Morse <jeremy.morse.llvm@gmail.com> | 2019-02-05 11:11:28 +0000 |
commit | 84ca706be1dba3b9a7eb10a3620dfd13f089907e (patch) | |
tree | 8a304e1d92f58578297ce3f036ff80121d08f4c6 /llvm/lib/Transforms/Utils | |
parent | 72798954544f46111a106c44b26e5ad8b77bbd05 (diff) | |
download | bcm5719-llvm-84ca706be1dba3b9a7eb10a3620dfd13f089907e.tar.gz bcm5719-llvm-84ca706be1dba3b9a7eb10a3620dfd13f089907e.zip |
[DebugInfo][NFCI] Split salvageDebugInfo into helper functions
Some use cases are appearing where salvaging is needed that does not
correspond to an instruction being deleted -- for example an instruction
being sunk, or a Value not being available in a block being isel'd.
Enable more fine grained control over how salavging occurs by splitting
the logic into helper functions, separating things that are specific to
working on DbgVariableIntrinsics from those specific to interpreting IR
and building DIExpressions.
Differential Revision: https://reviews.llvm.org/D57696
llvm-svn: 353156
Diffstat (limited to 'llvm/lib/Transforms/Utils')
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 164 |
1 files changed, 82 insertions, 82 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index a05a7a23457..e5238a915ad 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1593,120 +1593,120 @@ bool llvm::salvageDebugInfo(Instruction &I) { if (DbgUsers.empty()) return false; - auto &M = *I.getModule(); - auto &DL = M.getDataLayout(); + return salvageDebugInfoForDbgValues(I, DbgUsers); +} + +bool llvm::salvageDebugInfoForDbgValues( + Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers) { auto &Ctx = I.getContext(); auto wrapMD = [&](Value *V) { return wrapValueInMetadata(Ctx, V); }; - auto doSalvage = [&](DbgVariableIntrinsic *DII, SmallVectorImpl<uint64_t> &Ops) { - auto *DIExpr = DII->getExpression(); - if (!Ops.empty()) { - // Do not add DW_OP_stack_value for DbgDeclare and DbgAddr, because they - // are implicitly pointing out the value as a DWARF memory location - // description. - bool WithStackValue = isa<DbgValueInst>(DII); - DIExpr = DIExpression::prependOpcodes(DIExpr, Ops, WithStackValue); - } + for (auto *DII : DbgUsers) { + // Do not add DW_OP_stack_value for DbgDeclare and DbgAddr, because they + // are implicitly pointing out the value as a DWARF memory location + // description. + bool StackValue = isa<DbgValueInst>(DII); + + DIExpression *DIExpr = + salvageDebugInfoImpl(I, DII->getExpression(), StackValue); + + // salvageDebugInfoImpl should fail on examining the first element of + // DbgUsers, or none of them. + if (!DIExpr) + return false; + DII->setOperand(0, wrapMD(I.getOperand(0))); DII->setOperand(2, MetadataAsValue::get(Ctx, DIExpr)); LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n'); + } + + return true; +} + +DIExpression *llvm::salvageDebugInfoImpl(Instruction &I, + DIExpression *SrcDIExpr, + bool WithStackValue) { + auto &M = *I.getModule(); + auto &DL = M.getDataLayout(); + + // Apply a vector of opcodes to the source DIExpression. + auto doSalvage = [&](SmallVectorImpl<uint64_t> &Ops) -> DIExpression * { + DIExpression *DIExpr = SrcDIExpr; + if (!Ops.empty()) { + DIExpr = DIExpression::prependOpcodes(DIExpr, Ops, WithStackValue); + } + return DIExpr; }; - auto applyOffset = [&](DbgVariableIntrinsic *DII, uint64_t Offset) { + // Apply the given offset to the source DIExpression. + auto applyOffset = [&](uint64_t Offset) -> DIExpression * { SmallVector<uint64_t, 8> Ops; DIExpression::appendOffset(Ops, Offset); - doSalvage(DII, Ops); + return doSalvage(Ops); }; - auto applyOps = [&](DbgVariableIntrinsic *DII, - std::initializer_list<uint64_t> Opcodes) { + // initializer-list helper for applying operators to the source DIExpression. + auto applyOps = + [&](std::initializer_list<uint64_t> Opcodes) -> DIExpression * { SmallVector<uint64_t, 8> Ops(Opcodes); - doSalvage(DII, Ops); + return doSalvage(Ops); }; if (auto *CI = dyn_cast<CastInst>(&I)) { if (!CI->isNoopCast(DL)) - return false; + return nullptr; // No-op casts are irrelevant for debug info. - MetadataAsValue *CastSrc = wrapMD(I.getOperand(0)); - for (auto *DII : DbgUsers) { - DII->setOperand(0, CastSrc); - LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n'); - } - return true; + return SrcDIExpr; } else if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) { unsigned BitWidth = M.getDataLayout().getIndexSizeInBits(GEP->getPointerAddressSpace()); - // Rewrite a constant GEP into a DIExpression. Since we are performing - // arithmetic to compute the variable's *value* in the DIExpression, we - // need to mark the expression with a DW_OP_stack_value. + // Rewrite a constant GEP into a DIExpression. APInt Offset(BitWidth, 0); - if (GEP->accumulateConstantOffset(M.getDataLayout(), Offset)) - for (auto *DII : DbgUsers) - applyOffset(DII, Offset.getSExtValue()); - return true; + if (GEP->accumulateConstantOffset(M.getDataLayout(), Offset)) { + return applyOffset(Offset.getSExtValue()); + } else { + return nullptr; + } } else if (auto *BI = dyn_cast<BinaryOperator>(&I)) { // Rewrite binary operations with constant integer operands. auto *ConstInt = dyn_cast<ConstantInt>(I.getOperand(1)); if (!ConstInt || ConstInt->getBitWidth() > 64) - return false; + return nullptr; uint64_t Val = ConstInt->getSExtValue(); - for (auto *DII : DbgUsers) { - switch (BI->getOpcode()) { - case Instruction::Add: - applyOffset(DII, Val); - break; - case Instruction::Sub: - applyOffset(DII, -int64_t(Val)); - break; - case Instruction::Mul: - applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_mul}); - break; - case Instruction::SDiv: - applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_div}); - break; - case Instruction::SRem: - applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_mod}); - break; - case Instruction::Or: - applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_or}); - break; - case Instruction::And: - applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_and}); - break; - case Instruction::Xor: - applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_xor}); - break; - case Instruction::Shl: - applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_shl}); - break; - case Instruction::LShr: - applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_shr}); - break; - case Instruction::AShr: - applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_shra}); - break; - default: - // TODO: Salvage constants from each kind of binop we know about. - return false; - } + switch (BI->getOpcode()) { + case Instruction::Add: + return applyOffset(Val); + case Instruction::Sub: + return applyOffset(-int64_t(Val)); + case Instruction::Mul: + return applyOps({dwarf::DW_OP_constu, Val, dwarf::DW_OP_mul}); + case Instruction::SDiv: + return applyOps({dwarf::DW_OP_constu, Val, dwarf::DW_OP_div}); + case Instruction::SRem: + return applyOps({dwarf::DW_OP_constu, Val, dwarf::DW_OP_mod}); + case Instruction::Or: + return applyOps({dwarf::DW_OP_constu, Val, dwarf::DW_OP_or}); + case Instruction::And: + return applyOps({dwarf::DW_OP_constu, Val, dwarf::DW_OP_and}); + case Instruction::Xor: + return applyOps({dwarf::DW_OP_constu, Val, dwarf::DW_OP_xor}); + case Instruction::Shl: + return applyOps({dwarf::DW_OP_constu, Val, dwarf::DW_OP_shl}); + case Instruction::LShr: + return applyOps({dwarf::DW_OP_constu, Val, dwarf::DW_OP_shr}); + case Instruction::AShr: + return applyOps({dwarf::DW_OP_constu, Val, dwarf::DW_OP_shra}); + default: + // TODO: Salvage constants from each kind of binop we know about. + return nullptr; } - return true; } else if (isa<LoadInst>(&I)) { - MetadataAsValue *AddrMD = wrapMD(I.getOperand(0)); - for (auto *DII : DbgUsers) { - // Rewrite the load into DW_OP_deref. - auto *DIExpr = DII->getExpression(); - DIExpr = DIExpression::prepend(DIExpr, DIExpression::WithDeref); - DII->setOperand(0, AddrMD); - DII->setOperand(2, MetadataAsValue::get(Ctx, DIExpr)); - LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n'); - } - return true; + // Rewrite the load into DW_OP_deref. + return DIExpression::prepend(SrcDIExpr, DIExpression::WithDeref); } - return false; + return nullptr; } /// A replacement for a dbg.value expression. |