浏览代码

Moved debug values to the ResRet struct.

Tristan Labelle 6 年之前
父节点
当前提交
0a801dae8e

+ 1 - 0
include/dxc/DXIL/DxilUtil.h

@@ -97,6 +97,7 @@ namespace dxilutil {
                                       unsigned startOpIdx,
                                       unsigned numOperands);
   bool SimplifyTrivialPHIs(llvm::BasicBlock *BB);
+  void MigrateDebugValue(llvm::Value *Old, llvm::Value *New);
   void ScatterDebugValueToVectorElements(llvm::Value *Val);
   std::unique_ptr<llvm::Module> LoadModuleFromBitcode(llvm::StringRef BC,
     llvm::LLVMContext &Ctx, std::string &DiagStr);

+ 18 - 1
lib/DXIL/DxilUtil.cpp

@@ -340,6 +340,21 @@ static DbgValueInst *FindDbgValueInst(Value *Val) {
   return nullptr;
 }
 
+void MigrateDebugValue(Value *Old, Value *New) {
+  DbgValueInst *DbgValInst = FindDbgValueInst(Old);
+  if (DbgValInst == nullptr) return;
+  
+  DbgValInst->setOperand(0, MetadataAsValue::get(New->getContext(), ValueAsMetadata::get(New)));
+
+  // Move the dbg value after the new instruction
+  if (Instruction *NewInst = dyn_cast<Instruction>(New)) {
+    if (NewInst->getNextNode() != DbgValInst) {
+      DbgValInst->removeFromParent();
+      DbgValInst->insertAfter(NewInst);
+    }
+  }
+}
+
 // Propagates any llvm.dbg.value instruction for a given vector
 // to the elements that were used to create it through a series
 // of insertelement instructions.
@@ -373,7 +388,9 @@ void ScatterDebugValueToVectorElements(Value *Val) {
     }
 
     DIExpression *DIExpr = DbgInfoBuilder.createBitPieceExpression(OffsetInBits, ElemSizeInBits);
-    DbgInfoBuilder.insertDbgValueIntrinsic(NewElt, EltIdx, VecDbgValInst->getVariable(),
+    // Offset is basically unused and deprecated in later LLVM versions.
+    // Emit it as zero otherwise later versions of the bitcode reader will drop the intrinsic.
+    DbgInfoBuilder.insertDbgValueIntrinsic(NewElt, /* Offset */ 0, VecDbgValInst->getVariable(),
       DIExpr, VecDbgValInst->getDebugLoc(), InsertElt);
     Val = InsertElt->getOperand(0);
   }

+ 10 - 15
lib/HLSL/HLOperationLower.cpp

@@ -2710,16 +2710,14 @@ void GenerateDxilSample(CallInst *CI, Function *F, ArrayRef<Value *> sampleArgs,
 
   CallInst *call = Builder.CreateCall(F, sampleArgs);
 
+  dxilutil::MigrateDebugValue(CI, call);
+
   // extract value part
   Value *retVal = ScalarizeResRet(CI->getType(), call, Builder);
 
   // Replace ret val.
   CI->replaceAllUsesWith(retVal);
 
-  // Update the debug info
-  if (retVal->getType()->isVectorTy())
-    dxilutil::ScatterDebugValueToVectorElements(retVal);
-
   // get status
   if (status) {
     UpdateStatus(call, status, Builder, hlslOp);
@@ -3005,6 +3003,8 @@ void GenerateDxilGather(CallInst *CI, Function *F,
 
   CallInst *call = Builder.CreateCall(F, gatherArgs);
 
+  dxilutil::MigrateDebugValue(CI, call);
+
   Value *retVal;
   if (!helper.hasSampleOffsets) {
     // extract value part
@@ -3035,9 +3035,6 @@ void GenerateDxilGather(CallInst *CI, Function *F,
   // Replace ret val.
   CI->replaceAllUsesWith(retVal);
 
-  if (retVal->getType()->isVectorTy())
-    dxilutil::ScatterDebugValueToVectorElements(retVal);
-
   // Get status
   if (helper.status) {
     UpdateStatus(call, helper.status, Builder, hlslOp);
@@ -3299,7 +3296,7 @@ static Constant *GetRawBufferMaskForETy(Type *Ty, unsigned NumComponents, hlsl::
   return OP->GetI8Const(mask);
 }
 
-void GenerateStructBufLd(Value *handle, Value *bufIdx, Value *offset,
+Value *GenerateStructBufLd(Value *handle, Value *bufIdx, Value *offset,
   Value *status, Type *EltTy,
   MutableArrayRef<Value *> resultElts, hlsl::OP *OP,
   IRBuilder<> &Builder, unsigned NumComponents, Constant *alignment);
@@ -3330,12 +3327,12 @@ void TranslateLoad(ResLoadHelper &helper, HLResource::Kind RK,
   if (RK == HLResource::Kind::StructuredBuffer) {
     // Basic type case for StructuredBuffer::Load()
     Value *ResultElts[4];
-    GenerateStructBufLd(helper.handle, helper.addr, OP->GetU32Const(0),
+    Value *StructBufLoad = GenerateStructBufLd(helper.handle, helper.addr, OP->GetU32Const(0),
       helper.status, EltTy, ResultElts, OP, Builder, numComponents, Alignment);
+    dxilutil::MigrateDebugValue(helper.retVal, StructBufLoad);
     Value *retValNew = ScalarizeElements(Ty, ResultElts, Builder);
     helper.retVal->replaceAllUsesWith(retValNew);
     helper.retVal = retValNew;
-    if (Ty->isVectorTy()) dxilutil::ScatterDebugValueToVectorElements(retValNew);
     return;
   }
 
@@ -3417,6 +3414,7 @@ void TranslateLoad(ResLoadHelper &helper, HLResource::Kind RK,
 
   Value *ResRet =
       Builder.CreateCall(F, loadArgs, OP->GetOpCodeName(opcode));
+  dxilutil::MigrateDebugValue(helper.retVal, ResRet);
 
   Value *retValNew = nullptr;
   if (!is64 || !isTyped) {
@@ -3442,9 +3440,6 @@ void TranslateLoad(ResLoadHelper &helper, HLResource::Kind RK,
   helper.retVal->replaceAllUsesWith(retValNew);
   // Save new ret val.
   helper.retVal = retValNew;
-  // Update debug info
-  if (retValNew->getType()->isVectorTy())
-    dxilutil::ScatterDebugValueToVectorElements(retValNew);
   // get status
   UpdateStatus(ResRet, helper.status, Builder, OP);
 }
@@ -5945,7 +5940,7 @@ Value *GEPIdxToOffset(GetElementPtrInst *GEP, IRBuilder<> &Builder,
   return addr;
 }
 
-void GenerateStructBufLd(Value *handle, Value *bufIdx, Value *offset,
+Value *GenerateStructBufLd(Value *handle, Value *bufIdx, Value *offset,
                          Value *status, Type *EltTy,
                          MutableArrayRef<Value *> resultElts, hlsl::OP *OP,
                          IRBuilder<> &Builder, unsigned NumComponents, Constant *alignment) {
@@ -5970,7 +5965,7 @@ void GenerateStructBufLd(Value *handle, Value *bufIdx, Value *offset,
 
   // status
   UpdateStatus(Ld, status, Builder, OP);
-  return;
+  return Ld;
 }
 
 void GenerateStructBufSt(Value *handle, Value *bufIdx, Value *offset,

+ 1 - 5
tools/clang/test/CodeGenHLSL/debug/locals/structuredbuffer_load.hlsl

@@ -4,19 +4,15 @@
 // is preserved after scalarization and optims.
 
 // CHECK: call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32
+// CHECK: call void @llvm.dbg.value
 // CHECK: extractvalue %dx.types.ResRet.i32
 // CHECK: extractvalue %dx.types.ResRet.i32
-// CHECK: call void @llvm.dbg.value
-// CHECK: call void @llvm.dbg.value
 // CHECK: call void @dx.op.storeOutput.i32
 // CHECK: call void @dx.op.storeOutput.i32
 
 // Exclude quoted source file (see readme)
 // CHECK: {{!"[^"]*\\0A[^"]*"}}
 
-// CHECK: !DIExpression(DW_OP_bit_piece, 0, 32)
-// CHECK: !DIExpression(DW_OP_bit_piece, 32, 32)
-
 StructuredBuffer<int2> buf;
 int2 main() : OUT
 {

+ 1 - 9
tools/clang/test/CodeGenHLSL/debug/locals/texture_load.hlsl

@@ -4,14 +4,11 @@
 // is preserved after scalarization and optims.
 
 // CHECK: call %dx.types.ResRet.f32 @dx.op.textureLoad.f32
-// CHECK: extractvalue %dx.types.ResRet.f32
 // CHECK: call void @llvm.dbg.value
 // CHECK: extractvalue %dx.types.ResRet.f32
-// CHECK: call void @llvm.dbg.value
 // CHECK: extractvalue %dx.types.ResRet.f32
-// CHECK: call void @llvm.dbg.value
 // CHECK: extractvalue %dx.types.ResRet.f32
-// CHECK: call void @llvm.dbg.value
+// CHECK: extractvalue %dx.types.ResRet.f32
 // CHECK: call void @dx.op.storeOutput.f32
 // CHECK: call void @dx.op.storeOutput.f32
 // CHECK: call void @dx.op.storeOutput.f32
@@ -20,11 +17,6 @@
 // Exclude quoted source file (see readme)
 // CHECK: {{!"[^"]*\\0A[^"]*"}}
 
-// CHECK: !DIExpression(DW_OP_bit_piece, 0, 32)
-// CHECK: !DIExpression(DW_OP_bit_piece, 32, 32)
-// CHECK: !DIExpression(DW_OP_bit_piece, 64, 32)
-// CHECK: !DIExpression(DW_OP_bit_piece, 96, 32)
-
 Texture1D<float4> tex;
 float4 main() : SV_Target
 {

+ 1 - 9
tools/clang/test/CodeGenHLSL/debug/locals/texture_sample.hlsl

@@ -4,14 +4,11 @@
 // is preserved after scalarization and optims.
 
 // CHECK: call %dx.types.ResRet.f32 @dx.op.sample.f32
-// CHECK: extractvalue %dx.types.ResRet.f32
 // CHECK: call void @llvm.dbg.value
 // CHECK: extractvalue %dx.types.ResRet.f32
-// CHECK: call void @llvm.dbg.value
 // CHECK: extractvalue %dx.types.ResRet.f32
-// CHECK: call void @llvm.dbg.value
 // CHECK: extractvalue %dx.types.ResRet.f32
-// CHECK: call void @llvm.dbg.value
+// CHECK: extractvalue %dx.types.ResRet.f32
 // CHECK: call void @dx.op.storeOutput.f32
 // CHECK: call void @dx.op.storeOutput.f32
 // CHECK: call void @dx.op.storeOutput.f32
@@ -20,11 +17,6 @@
 // Exclude quoted source file (see readme)
 // CHECK: {{!"[^"]*\\0A[^"]*"}}
 
-// CHECK: !DIExpression(DW_OP_bit_piece, 0, 32)
-// CHECK: !DIExpression(DW_OP_bit_piece, 32, 32)
-// CHECK: !DIExpression(DW_OP_bit_piece, 64, 32)
-// CHECK: !DIExpression(DW_OP_bit_piece, 96, 32)
-
 sampler samp;
 Texture2D<float4> tex;
 float4 main() : SV_Target