@@ -1593,120 +1593,120 @@ bool llvm::salvageDebugInfo(Instruction &I) {
1593
1593
if (DbgUsers.empty ())
1594
1594
return false ;
1595
1595
1596
- auto &M = *I.getModule ();
1597
- auto &DL = M.getDataLayout ();
1596
+ return salvageDebugInfoForDbgValues (I, DbgUsers);
1597
+ }
1598
+
1599
+ bool llvm::salvageDebugInfoForDbgValues (
1600
+ Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers) {
1598
1601
auto &Ctx = I.getContext ();
1599
1602
auto wrapMD = [&](Value *V) { return wrapValueInMetadata (Ctx, V); };
1600
1603
1601
- auto doSalvage = [&](DbgVariableIntrinsic *DII, SmallVectorImpl<uint64_t > &Ops) {
1602
- auto *DIExpr = DII->getExpression ();
1603
- if (!Ops.empty ()) {
1604
- // Do not add DW_OP_stack_value for DbgDeclare and DbgAddr, because they
1605
- // are implicitly pointing out the value as a DWARF memory location
1606
- // description.
1607
- bool WithStackValue = isa<DbgValueInst>(DII);
1608
- DIExpr = DIExpression::prependOpcodes (DIExpr, Ops, WithStackValue);
1609
- }
1604
+ for (auto *DII : DbgUsers) {
1605
+ // Do not add DW_OP_stack_value for DbgDeclare and DbgAddr, because they
1606
+ // are implicitly pointing out the value as a DWARF memory location
1607
+ // description.
1608
+ bool StackValue = isa<DbgValueInst>(DII);
1609
+
1610
+ DIExpression *DIExpr =
1611
+ salvageDebugInfoImpl (I, DII->getExpression (), StackValue);
1612
+
1613
+ // salvageDebugInfoImpl should fail on examining the first element of
1614
+ // DbgUsers, or none of them.
1615
+ if (!DIExpr)
1616
+ return false ;
1617
+
1610
1618
DII->setOperand (0 , wrapMD (I.getOperand (0 )));
1611
1619
DII->setOperand (2 , MetadataAsValue::get (Ctx, DIExpr));
1612
1620
LLVM_DEBUG (dbgs () << " SALVAGE: " << *DII << ' \n ' );
1621
+ }
1622
+
1623
+ return true ;
1624
+ }
1625
+
1626
+ DIExpression *llvm::salvageDebugInfoImpl (Instruction &I,
1627
+ DIExpression *SrcDIExpr,
1628
+ bool WithStackValue) {
1629
+ auto &M = *I.getModule ();
1630
+ auto &DL = M.getDataLayout ();
1631
+
1632
+ // Apply a vector of opcodes to the source DIExpression.
1633
+ auto doSalvage = [&](SmallVectorImpl<uint64_t > &Ops) -> DIExpression * {
1634
+ DIExpression *DIExpr = SrcDIExpr;
1635
+ if (!Ops.empty ()) {
1636
+ DIExpr = DIExpression::prependOpcodes (DIExpr, Ops, WithStackValue);
1637
+ }
1638
+ return DIExpr;
1613
1639
};
1614
1640
1615
- auto applyOffset = [&](DbgVariableIntrinsic *DII, uint64_t Offset) {
1641
+ // Apply the given offset to the source DIExpression.
1642
+ auto applyOffset = [&](uint64_t Offset) -> DIExpression * {
1616
1643
SmallVector<uint64_t , 8 > Ops;
1617
1644
DIExpression::appendOffset (Ops, Offset);
1618
- doSalvage (DII, Ops);
1645
+ return doSalvage (Ops);
1619
1646
};
1620
1647
1621
- auto applyOps = [&](DbgVariableIntrinsic *DII,
1622
- std::initializer_list<uint64_t > Opcodes) {
1648
+ // initializer-list helper for applying operators to the source DIExpression.
1649
+ auto applyOps =
1650
+ [&](std::initializer_list<uint64_t > Opcodes) -> DIExpression * {
1623
1651
SmallVector<uint64_t , 8 > Ops (Opcodes);
1624
- doSalvage (DII, Ops);
1652
+ return doSalvage (Ops);
1625
1653
};
1626
1654
1627
1655
if (auto *CI = dyn_cast<CastInst>(&I)) {
1628
1656
if (!CI->isNoopCast (DL))
1629
- return false ;
1657
+ return nullptr ;
1630
1658
1631
1659
// No-op casts are irrelevant for debug info.
1632
- MetadataAsValue *CastSrc = wrapMD (I.getOperand (0 ));
1633
- for (auto *DII : DbgUsers) {
1634
- DII->setOperand (0 , CastSrc);
1635
- LLVM_DEBUG (dbgs () << " SALVAGE: " << *DII << ' \n ' );
1636
- }
1637
- return true ;
1660
+ return SrcDIExpr;
1638
1661
} else if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
1639
1662
unsigned BitWidth =
1640
1663
M.getDataLayout ().getIndexSizeInBits (GEP->getPointerAddressSpace ());
1641
- // Rewrite a constant GEP into a DIExpression. Since we are performing
1642
- // arithmetic to compute the variable's *value* in the DIExpression, we
1643
- // need to mark the expression with a DW_OP_stack_value.
1664
+ // Rewrite a constant GEP into a DIExpression.
1644
1665
APInt Offset (BitWidth, 0 );
1645
- if (GEP->accumulateConstantOffset (M.getDataLayout (), Offset))
1646
- for (auto *DII : DbgUsers)
1647
- applyOffset (DII, Offset.getSExtValue ());
1648
- return true ;
1666
+ if (GEP->accumulateConstantOffset (M.getDataLayout (), Offset)) {
1667
+ return applyOffset (Offset.getSExtValue ());
1668
+ } else {
1669
+ return nullptr ;
1670
+ }
1649
1671
} else if (auto *BI = dyn_cast<BinaryOperator>(&I)) {
1650
1672
// Rewrite binary operations with constant integer operands.
1651
1673
auto *ConstInt = dyn_cast<ConstantInt>(I.getOperand (1 ));
1652
1674
if (!ConstInt || ConstInt->getBitWidth () > 64 )
1653
- return false ;
1675
+ return nullptr ;
1654
1676
1655
1677
uint64_t Val = ConstInt->getSExtValue ();
1656
- for (auto *DII : DbgUsers) {
1657
- switch (BI->getOpcode ()) {
1658
- case Instruction::Add:
1659
- applyOffset (DII, Val);
1660
- break ;
1661
- case Instruction::Sub:
1662
- applyOffset (DII, -int64_t (Val));
1663
- break ;
1664
- case Instruction::Mul:
1665
- applyOps (DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_mul});
1666
- break ;
1667
- case Instruction::SDiv:
1668
- applyOps (DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_div});
1669
- break ;
1670
- case Instruction::SRem:
1671
- applyOps (DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_mod});
1672
- break ;
1673
- case Instruction::Or:
1674
- applyOps (DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_or});
1675
- break ;
1676
- case Instruction::And:
1677
- applyOps (DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_and});
1678
- break ;
1679
- case Instruction::Xor:
1680
- applyOps (DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_xor});
1681
- break ;
1682
- case Instruction::Shl:
1683
- applyOps (DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_shl});
1684
- break ;
1685
- case Instruction::LShr:
1686
- applyOps (DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_shr});
1687
- break ;
1688
- case Instruction::AShr:
1689
- applyOps (DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_shra});
1690
- break ;
1691
- default :
1692
- // TODO: Salvage constants from each kind of binop we know about.
1693
- return false ;
1694
- }
1678
+ switch (BI->getOpcode ()) {
1679
+ case Instruction::Add:
1680
+ return applyOffset (Val);
1681
+ case Instruction::Sub:
1682
+ return applyOffset (-int64_t (Val));
1683
+ case Instruction::Mul:
1684
+ return applyOps ({dwarf::DW_OP_constu, Val, dwarf::DW_OP_mul});
1685
+ case Instruction::SDiv:
1686
+ return applyOps ({dwarf::DW_OP_constu, Val, dwarf::DW_OP_div});
1687
+ case Instruction::SRem:
1688
+ return applyOps ({dwarf::DW_OP_constu, Val, dwarf::DW_OP_mod});
1689
+ case Instruction::Or:
1690
+ return applyOps ({dwarf::DW_OP_constu, Val, dwarf::DW_OP_or});
1691
+ case Instruction::And:
1692
+ return applyOps ({dwarf::DW_OP_constu, Val, dwarf::DW_OP_and});
1693
+ case Instruction::Xor:
1694
+ return applyOps ({dwarf::DW_OP_constu, Val, dwarf::DW_OP_xor});
1695
+ case Instruction::Shl:
1696
+ return applyOps ({dwarf::DW_OP_constu, Val, dwarf::DW_OP_shl});
1697
+ case Instruction::LShr:
1698
+ return applyOps ({dwarf::DW_OP_constu, Val, dwarf::DW_OP_shr});
1699
+ case Instruction::AShr:
1700
+ return applyOps ({dwarf::DW_OP_constu, Val, dwarf::DW_OP_shra});
1701
+ default :
1702
+ // TODO: Salvage constants from each kind of binop we know about.
1703
+ return nullptr ;
1695
1704
}
1696
- return true ;
1697
1705
} else if (isa<LoadInst>(&I)) {
1698
- MetadataAsValue *AddrMD = wrapMD (I.getOperand (0 ));
1699
- for (auto *DII : DbgUsers) {
1700
- // Rewrite the load into DW_OP_deref.
1701
- auto *DIExpr = DII->getExpression ();
1702
- DIExpr = DIExpression::prepend (DIExpr, DIExpression::WithDeref);
1703
- DII->setOperand (0 , AddrMD);
1704
- DII->setOperand (2 , MetadataAsValue::get (Ctx, DIExpr));
1705
- LLVM_DEBUG (dbgs () << " SALVAGE: " << *DII << ' \n ' );
1706
- }
1707
- return true ;
1706
+ // Rewrite the load into DW_OP_deref.
1707
+ return DIExpression::prepend (SrcDIExpr, DIExpression::WithDeref);
1708
1708
}
1709
- return false ;
1709
+ return nullptr ;
1710
1710
}
1711
1711
1712
1712
// / A replacement for a dbg.value expression.
0 commit comments