@@ -1208,14 +1208,24 @@ LLVMToSPIRVDbgTran::transDbgGlobalVariable(const DIGlobalVariable *GV) {
1208
1208
Ops.push_back (transDbgEntry (StaticMember)->getId ());
1209
1209
1210
1210
// Check if Ops[VariableIdx] has no information
1211
- if (isNonSemanticDebugInfo () && Ops[VariableIdx] == getDebugInfoNoneId () ) {
1211
+ if (isNonSemanticDebugInfo ()) {
1212
1212
// Check if GV has an associated GVE with a non-empty DIExpression.
1213
1213
// The non-empty DIExpression gives the initial value of the GV.
1214
1214
for (const DIGlobalVariableExpression *GVE : DIF.global_variables ()) {
1215
1215
if ( // GVE matches GV
1216
1216
GVE->getVariable () == GV &&
1217
1217
// DIExpression is non-empty
1218
1218
GVE->getExpression ()->getNumElements ()) {
1219
+ if (Ops[VariableIdx] != getDebugInfoNoneId ()) {
1220
+ #ifdef SPIRV_HAS_DIOP_DIEXPRESSION
1221
+ if (GVE->getExpression ()->holdsNewElements ()) {
1222
+ Ops.resize (MaxOperandCount, getDebugInfoNoneId ());
1223
+ Ops[DIOpBasedExprIdx] =
1224
+ transDbgExpression (GVE->getExpression ())->getId ();
1225
+ }
1226
+ #endif
1227
+ break ;
1228
+ }
1219
1229
// Repurpose VariableIdx operand to hold the initial value held in the
1220
1230
// GVE's DIExpression
1221
1231
Ops[VariableIdx] = transDbgExpression (GVE->getExpression ())->getId ();
@@ -1608,21 +1618,96 @@ LLVMToSPIRVDbgTran::transDbgLocalVariable(const DILocalVariable *Var) {
1608
1618
1609
1619
// DWARF Operations and expressions
1610
1620
1621
+ template <>
1622
+ void LLVMToSPIRVDbgTran::transDIOpOperand (SPIRVWordVec &Vec, unsigned Idx,
1623
+ llvm::Type *Ty) {
1624
+ Vec[Idx] = SPIRVWriter->transType (Ty)->getId ();
1625
+ }
1626
+
1627
+ template <>
1628
+ void LLVMToSPIRVDbgTran::transDIOpOperand (SPIRVWordVec &Vec, unsigned Idx,
1629
+ uint32_t UInt) {
1630
+ Vec[Idx] = UInt;
1631
+ if (isNonSemanticDebugInfo ())
1632
+ transformToConstant (Vec, {Idx});
1633
+ }
1634
+
1635
+ template <>
1636
+ void LLVMToSPIRVDbgTran::transDIOpOperand (SPIRVWordVec &Vec, unsigned Idx,
1637
+ llvm::ConstantData *Data) {
1638
+ Vec[Idx] = SPIRVWriter->transConstant (Data)->getId ();
1639
+ }
1640
+
1611
1641
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgExpression (const DIExpression *Expr) {
1612
1642
SPIRVWordVec Operations;
1643
+
1644
+ #ifdef SPIRV_HAS_DIOP_DIEXPRESSION
1645
+ if (auto NewElems = Expr->getNewElementsRef ()) {
1646
+ if (!(BM->allowExtraDIExpressions () ||
1647
+ BM->getDebugInfoEIS () == SPIRVEIS_NonSemantic_Shader_DebugInfo_200))
1648
+ report_fatal_error (
1649
+ llvm::Twine (" unsupported DIOp-based opcode found in DIExpression" ));
1650
+
1651
+ for (DIOp::Variant DIOp : *NewElems) {
1652
+ using namespace SPIRVDebug ::Operand::Operation;
1653
+
1654
+ unsigned BitcodeID = llvm::DIOp::getBitcodeID (DIOp);
1655
+ SPIRVDebug::ExpressionOpCode OC =
1656
+ SPIRV::DbgExpressionDIOpBasedOpCodeMap::map (BitcodeID);
1657
+ if (OpCountMap.find (OC) == OpCountMap.end ())
1658
+ report_fatal_error (
1659
+ llvm::Twine (" unknown DIOp-based opcode found in DIExpression" ));
1660
+
1661
+ unsigned OpCount = OpCountMap[OC];
1662
+ SPIRVWordVec Op (OpCount);
1663
+ Op[OpCodeIdx] = OC;
1664
+ if (isNonSemanticDebugInfo ())
1665
+ transformToConstant (Op, {OpCodeIdx});
1666
+
1667
+ #define HANDLE_OP1 (Name, OpType, OpName ) \
1668
+ case llvm::DIOp::Name::getBitcodeID (): \
1669
+ assert (OpCount == 2 ); \
1670
+ transDIOpOperand<OpType>(Op, 1 , \
1671
+ std::get<llvm::DIOp::Name>(DIOp).get ##OpName ()); \
1672
+ break ;
1673
+ #define HANDLE_OP2 (Name, OpType1, OpName1, OpType2, OpName2 ) \
1674
+ case llvm::DIOp::Name::getBitcodeID (): \
1675
+ assert (OpCount == 3 ); \
1676
+ transDIOpOperand<OpType1>( \
1677
+ Op, 1 , std::get<llvm::DIOp::Name>(DIOp).get ##OpName1 ()); \
1678
+ transDIOpOperand<OpType2>( \
1679
+ Op, 2 , std::get<llvm::DIOp::Name>(DIOp).get ##OpName2 ()); \
1680
+ break ;
1681
+
1682
+ switch (BitcodeID) {
1683
+ #include " llvm/IR/DIExprOps.def"
1684
+ default :
1685
+ // This is the OP0 case.
1686
+ assert (OpCount == 1 );
1687
+ break ;
1688
+ }
1689
+
1690
+ auto *Operation =
1691
+ BM->addDebugInfo (SPIRVDebug::Operation, getVoidTy (), Op);
1692
+ Operations.push_back (Operation->getId ());
1693
+ }
1694
+
1695
+ return BM->addDebugInfo (SPIRVDebug::Expression, getVoidTy (), Operations);
1696
+ }
1697
+ #endif
1698
+
1613
1699
for (unsigned I = 0 , N = Expr->getNumElements (); I < N; ++I) {
1614
1700
using namespace SPIRVDebug ::Operand::Operation;
1615
1701
auto DWARFOpCode = static_cast <dwarf::LocationAtom>(Expr->getElement (I));
1616
1702
1617
1703
SPIRVDebug::ExpressionOpCode OC =
1618
1704
SPIRV::DbgExpressionOpCodeMap::map (DWARFOpCode);
1619
1705
if (OpCountMap.find (OC) == OpCountMap.end ())
1620
- report_fatal_error (llvm::Twine ( " unknown opcode found in DIExpression" ) );
1706
+ report_fatal_error (" unknown opcode found in DIExpression" );
1621
1707
if (OC > SPIRVDebug::Fragment &&
1622
1708
!(BM->allowExtraDIExpressions () ||
1623
1709
BM->getDebugInfoEIS () == SPIRVEIS_NonSemantic_Shader_DebugInfo_200))
1624
- report_fatal_error (
1625
- llvm::Twine (" unsupported opcode found in DIExpression" ));
1710
+ report_fatal_error (" unsupported opcode found in DIExpression" );
1626
1711
1627
1712
unsigned OpCount = OpCountMap[OC];
1628
1713
SPIRVWordVec Op (OpCount);
0 commit comments