ソースを参照

Printing out line num and debug variable and expression when disassembling. (#2738)

Adam Yang 5 年 前
コミット
8d79e009a5

+ 4 - 0
include/llvm/IR/Metadata.h

@@ -966,6 +966,10 @@ public:
   static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);
   static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
   static MDNode *getMostGenericAliasScope(MDNode *A, MDNode *B);
+
+  /// \brief Methods to print body of node, ie. without the '<addr> = ' prefix
+  void printAsBody(raw_ostream &OS, const Module *M = nullptr) const; // HLSL Change
+  void printAsBody(raw_ostream &OS, ModuleSlotTracker &MST, const Module *M = nullptr) const; // HLSL Change
 };
 
 /// \brief Tuple of metadata.

+ 13 - 0
lib/IR/AsmWriter.cpp

@@ -3352,6 +3352,19 @@ void Metadata::print(raw_ostream &OS, ModuleSlotTracker &MST,
   printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false);
 }
 
+// HLSL Change Begin
+void MDNode::printAsBody(raw_ostream &OS, const Module *M) const {
+  ModuleSlotTracker MST(M, true);
+  printAsBody(OS, MST, M);
+}
+void MDNode::printAsBody(raw_ostream &OS, ModuleSlotTracker &MST, const Module *M) const {
+  TypePrinting TypePrinter;
+  if (M)
+    TypePrinter.incorporateTypes(*M);
+  WriteMDNodeBodyInternal(OS, this, &TypePrinter, MST.getMachine(), M);
+}
+// HLSL Change end
+
 // Value::dump - allow easy printing of Values from the debugger.
 LLVM_DUMP_METHOD
 void Value::dump() const { print(dbgs()); dbgs() << '\n'; }

+ 40 - 0
tools/clang/test/HLSLFileCheck/dxil/debug/line_num_disasm.hlsl

@@ -0,0 +1,40 @@
+// RUN: %dxc -E main -T ps_6_0 %s -Zi -Od | FileCheck %s
+
+[RootSignature("")]
+float main(float a : A) : SV_Target {
+  float2 xy = float2(0,0);
+  xy.x = sin(a);
+  // CHECK: call float @dx.op.unary.f32(i32 13,
+  // CHECK-SAME: line:6
+
+  // CHECK: call void @llvm.dbg.value(
+  // CHECK-SAME: var:"xy"
+  // CHECK-SAME: !DIExpression(DW_OP_bit_piece, 0, 32)
+
+  xy.y = cos(xy.x);
+  // CHECK: call float @dx.op.unary.f32(i32 12,
+  // CHECK-SAME: line:14
+
+  // CHECK: call void @llvm.dbg.value(
+  // CHECK-SAME: var:"xy"
+  // CHECK-SAME: !DIExpression(DW_OP_bit_piece, 32, 32)
+
+  float z = abs(xy.y);
+  // CHECK: call float @dx.op.unary.f32(i32 6,
+  // CHECK-SAME: line:22
+
+  // CHECK: call void @llvm.dbg.value(
+  // CHECK-SAME: var:"z"
+  // CHECK-SAME: !DIExpression()
+
+  float w = tan(z);
+  // CHECK: call float @dx.op.unary.f32(i32 14,
+  // CHECK-SAME: line:30
+
+  // CHECK: call void @llvm.dbg.value(
+  // CHECK-SAME: var:"w"
+  // CHECK-SAME: !DIExpression()
+
+  return w;
+}
+

+ 3 - 3
tools/clang/test/HLSLFileCheck/dxil/debug/locals/scalarized_vector.hlsl

@@ -4,8 +4,8 @@
 
 // CHECK: %[[x:.*]] = add i32
 // CHECK: %[[y:.*]] = add i32
-// CHECK-DAG: call void @llvm.dbg.value(metadata i32 %[[x]], i64 0, metadata ![[vec:.*]], metadata ![[xexp:.*]])
-// CHECK-DAG: call void @llvm.dbg.value(metadata i32 %[[y]], i64 0, metadata ![[vec]], metadata ![[yexp:.*]])
+// CHECK-DAG: call void @llvm.dbg.value(metadata i32 %[[x]], i64 0, metadata ![[vec:.*]], metadata ![[xexp:.*]]), !dbg
+// CHECK-DAG: call void @llvm.dbg.value(metadata i32 %[[y]], i64 0, metadata ![[vec]], metadata ![[yexp:.*]]), !dbg
 
 // Exclude quoted source file (see readme)
 // CHECK-LABEL: {{!"[^"]*\\0A[^"]*"}}
@@ -18,4 +18,4 @@ int2 main(int2 a : A, int2 b : B) : OUT
 {
     int2 vec = a + b;
     return vec;
-}
+}

+ 2 - 2
tools/clang/test/HLSLFileCheck/dxil/debug/types/double.hlsl

@@ -4,7 +4,7 @@
 
 // CHECK: %[[bufret:.*]] = call %dx.types.CBufRet.f64 @dx.op.cbufferLoadLegacy.f64
 // CHECK: %[[d:.*]] = extractvalue %dx.types.CBufRet.f64 %[[bufret]], 0
-// CHECK: call void @llvm.dbg.value(metadata double %[[d]], i64 0, metadata ![[divar:.*]], metadata ![[diexpr:.*]])
+// CHECK: call void @llvm.dbg.value(metadata double %[[d]], i64 0, metadata ![[divar:.*]], metadata ![[diexpr:.*]]), !dbg
 
 // CHECK: !DIBasicType(name: "double", size: 64, align: 64, encoding: DW_ATE_float)
 
@@ -19,4 +19,4 @@ float main() : OUT
 {
     double d = cb_d;
     return (float)d;
-}
+}

+ 2 - 2
tools/clang/test/HLSLFileCheck/dxil/debug/types/half.hlsl

@@ -4,7 +4,7 @@
 
 // CHECK: %[[bufret:.*]] = call %dx.types.CBufRet.f16.8 @dx.op.cbufferLoadLegacy.f16
 // CHECK: %[[h:.*]] = extractvalue %dx.types.CBufRet.f16.8 %[[bufret]], 0
-// CHECK: call void @llvm.dbg.value(metadata half %[[h]], i64 0, metadata ![[divar:.*]], metadata ![[diexpr:.*]])
+// CHECK: call void @llvm.dbg.value(metadata half %[[h]], i64 0, metadata ![[divar:.*]], metadata ![[diexpr:.*]]), !dbg
 
 // CHECK: !DIBasicType(name: "half", size: 16, align: 16, encoding: DW_ATE_float)
 
@@ -19,4 +19,4 @@ float main() : OUT
 {
     half h = cb_h;
     return (float)h;
-}
+}

+ 26 - 0
tools/clang/tools/dxcompiler/dxcdisassembler.cpp

@@ -23,7 +23,9 @@
 #include "dxc/DXIL/DxilOperations.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/AssemblyAnnotationWriter.h"
+#include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Support/Format.h"
 #include "dxc/DxilContainer/DxilPipelineStateValidation.h"
@@ -1287,6 +1289,30 @@ class DxcAssemblyAnnotationWriter : public llvm::AssemblyAnnotationWriter {
 public:
   ~DxcAssemblyAnnotationWriter() {}
   void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
+    if (const Instruction *I = dyn_cast<Instruction>(&V)) {
+      if (isa<DbgInfoIntrinsic>(I)) {
+        DILocalVariable *Var = nullptr;
+        DIExpression *Expr = nullptr;
+        if (const DbgDeclareInst *DI = dyn_cast<DbgDeclareInst>(I)) {
+          Var = DI->getVariable();
+          Expr = DI->getExpression();
+        }
+        else if (const DbgValueInst *DI = dyn_cast<DbgValueInst>(I)) {
+          Var = DI->getVariable();
+          Expr = DI->getExpression();
+        }
+
+        if (Var && Expr) {
+          OS << " ; var:\"" << Var->getName() << "\"" << " ";
+          Expr->printAsBody(OS);
+        }
+      }
+      else {
+        DebugLoc Loc = I->getDebugLoc();
+        if (Loc && Loc.getLine() != 0)
+          OS << " ; line:" << Loc.getLine() << " col:" << Loc.getCol();
+      }
+    }
     const CallInst *CI = dyn_cast<const CallInst>(&V);
     if (!CI) {
       return;