Prechádzať zdrojové kódy

Bitpiece size fix; not creating Bitpiece when it encompasses the entire variable. (#1950)

Adam Yang 6 rokov pred
rodič
commit
4870297404

+ 4 - 0
lib/IR/DIBuilder.cpp

@@ -625,7 +625,11 @@ DIExpression *DIBuilder::createExpression(ArrayRef<int64_t> Signed) {
 
 DIExpression *DIBuilder::createBitPieceExpression(unsigned OffsetInBytes,
                                                   unsigned SizeInBytes) {
+#if 0 // HLSL Change
   uint64_t Addr[] = {dwarf::DW_OP_bit_piece, OffsetInBytes, SizeInBytes};
+#else // HLSL Change
+  uint64_t Addr[] = {dwarf::DW_OP_bit_piece, OffsetInBytes*8, SizeInBytes*8};
+#endif // HLSL Change
   return DIExpression::get(VMContext, Addr);
 }
 

+ 4 - 0
lib/Transforms/Scalar/SROA.cpp

@@ -4326,7 +4326,11 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
             continue;
           Size = std::min(Size, AbsEnd - Start);
         }
+#if 0 // HLSL Change
         PieceExpr = DIB.createBitPieceExpression(Start, Size);
+#else // HLSL Change
+        PieceExpr = DIB.createBitPieceExpression(Start / 8, Size / 8);
+#endif // HLSL Change
       }
 
       // Remove any existing dbg.declare intrinsic describing the same alloca.

+ 37 - 0
lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp

@@ -1565,6 +1565,10 @@ bool SROA_HLSL::performScalarRepl(Function &F, DxilTypeSystem &typeSys) {
                       std::function<bool(AllocaInst *, AllocaInst *)>>
       WorkList(size_cmp);
   std::unordered_map<AllocaInst*, DbgDeclareInst*> DDIMap;
+  // HLSL Change - Begin
+  std::unordered_map<AllocaInst*, unsigned> OffsetMap; // Map to keep track the offset of an alloca
+                                                       // in the variable that it's a part of.
+  // HLSL Change - End
   // Scan the entry basic block, adding allocas to the worklist.
   BasicBlock &BB = F.getEntryBlock();
   for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
@@ -1654,6 +1658,12 @@ bool SROA_HLSL::performScalarRepl(Function &F, DxilTypeSystem &typeSys) {
             }
           }
         }
+// HLSL Change - Begin
+        unsigned parentOffset = 0;
+        auto offsetIt = OffsetMap.find(AI);
+        if (offsetIt != OffsetMap.end())
+          parentOffset = offsetIt->second;
+// HLSL Change - End
 
         DbgDeclareInst *DDI = nullptr;
         unsigned debugOffset = 0;
@@ -1668,8 +1678,21 @@ bool SROA_HLSL::performScalarRepl(Function &F, DxilTypeSystem &typeSys) {
           if (DDI) {
             Type *Ty = Elt->getAllocatedType();
             unsigned size = DL.getTypeAllocSize(Ty);
+#if 0 // HLSL Change
             DIExpression *DDIExp =
                 DIB.createBitPieceExpression(debugOffset, size);
+#else // HLSL Change
+
+            DIExpression *DDIExp = nullptr;
+            if (parentOffset+debugOffset == 0 && DL.getTypeAllocSize(AI->getAllocatedType()) == size) {
+              std::vector<uint64_t> args;
+              DDIExp = DIB.createExpression(args);
+            }
+            else {
+              DDIExp = DIB.createBitPieceExpression(parentOffset+debugOffset, size);
+            }
+            OffsetMap[Elt] = parentOffset+debugOffset;
+#endif // HLSL Change
             debugOffset += size;
             DbgDeclareInst *EltDDI = cast<DbgDeclareInst>(DIB.insertDeclare(
                 Elt, DDI->getVariable(), DDIExp, DDI->getDebugLoc(), DDI));
@@ -5608,7 +5631,21 @@ void SROA_Parameter_HLSL::flattenArgument(
         if (Ty->isPointerTy())
           Ty = Ty->getPointerElementType();
         unsigned size = DL.getTypeAllocSize(Ty);
+#if 0 // HLSL Change
         DIExpression *DDIExp = DIB.createBitPieceExpression(debugOffset, size);
+#else // HLSL Change
+        Type *argTy = Arg->getType();
+        if (argTy->isPointerTy())
+          argTy = argTy->getPointerElementType();
+        DIExpression *DDIExp = nullptr;
+        if (debugOffset == 0 && DL.getTypeAllocSize(argTy) == size) {
+          std::vector<uint64_t> Addr;
+          DDIExp = DIB.createExpression(Addr);
+        }
+        else {
+          DDIExp = DIB.createBitPieceExpression(debugOffset, size);
+        }
+#endif // HLSL Change
         debugOffset += size;
         DIB.insertDeclare(TmpV, DDI->getVariable(), DDIExp, DDI->getDebugLoc(),
                           Builder.GetInsertPoint());

+ 5 - 3
lib/Transforms/Scalar/Scalarizer.cpp

@@ -704,7 +704,7 @@ bool Scalarizer::finish() {
                 // TODO: need to use DIExpression::createFragmentExpression for
                 // case DVI->getExpression is already bit piece.
                 DIExpression *EltExpr =
-                    DIB.createBitPieceExpression(Offset, EltSize);
+                    DIB.createBitPieceExpression(Offset / 8, EltSize / 8);
                 Offset += EltSize;
 
                 DIB.insertDbgValueIntrinsic(CV[I], Offset, VarInfo, EltExpr,
@@ -740,14 +740,16 @@ bool Scalarizer::finish() {
           if (HasDbgInfo) {
             if (auto *L = LocalAsMetadata::getIfExists(CV[immIdx])) {
               if (auto *DINode = MetadataAsValue::getIfExists(Ctx, L)) {
-                for (User *U : DINode->users())
+                // Putting old users in an array, so we don't keep looping over new
+                // users as we add more.
+                SmallVector<User *, 4> OldUsers(DINode->user_begin(), DINode->user_end());
+                for (User *U : OldUsers)
                   if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(U)) {
                     auto *Expr = DVI->getExpression();
                     DIBuilder DIB(M, /*AllowUnresolved*/ false);
                     auto *VarInfo = DVI->getVariable();
                     DebugLoc DbgLoc = DVI->getDebugLoc();
                     unsigned Offset = 0;
-
                     DIB.insertDbgValueIntrinsic(EEI, Offset, VarInfo, Expr,
                                                 DbgLoc, DVI);
                   }

+ 29 - 0
tools/clang/test/CodeGenHLSL/debug/array_piece.hlsl

@@ -0,0 +1,29 @@
+// RUN: %dxc -Zi -E main -T ps_6_0 %s | FileCheck %s
+
+// Make sure the bit pieces have the offset in bits
+// CHECK-DAG: !{{[0-9]+}} = !DIExpression(DW_OP_bit_piece, 0, 32)
+// CHECK-DAG: !{{[0-9]+}} = !DIExpression(DW_OP_bit_piece, 32, 32)
+// CHECK-DAG: !{{[0-9]+}} = !DIExpression(DW_OP_bit_piece, 64, 32)
+// CHECK-DAG: !{{[0-9]+}} = !DIExpression(DW_OP_bit_piece, 96, 32)
+
+float main(float a : A, float b : B, float c : C, float d : D, float e : E) : SV_Target {
+  float s[4] = {
+    a+b,
+    b+c,
+    c+d,
+    d+e,
+  };
+
+  [unroll]
+  for (int i = 0; i < 4; i++)
+    s[i] *= s[i];
+
+  float result = 0;
+
+  [unroll]
+  for (int i = 0; i < 4; i++)
+    result += s[i];
+
+  return result;
+}
+

+ 25 - 0
tools/clang/test/CodeGenHLSL/debug/full_var_no_bitpiece.hlsl

@@ -0,0 +1,25 @@
+// RUN: %dxc -Zi -E main -T ps_6_0 %s | FileCheck %s
+
+// Make sure there's no bit piece debug expression when
+// the element covers the whole variable.
+
+// CHECK-NOT: !{{[0-9]+}} = !DIExpression(DW_OP_bit_piece
+
+float main(float a : A, float b : B) : SV_Target {
+  float s[1] = {
+    a+b,
+  };
+
+  [unroll]
+  for (int i = 0; i < 1; i++)
+    s[i] *= s[i];
+
+  float result = 0;
+
+  [unroll]
+  for (int i = 0; i < 1; i++)
+    result += s[i];
+
+  return result;
+}
+

+ 27 - 0
tools/clang/test/CodeGenHLSL/debug/nested_struct.hlsl

@@ -0,0 +1,27 @@
+// RUN: %dxc -Zi -E main -Od -T ps_6_0 %s | FileCheck %s
+
+// Make sure all elements of the struct (even when there are nested structs)
+// are at distinct offsets.
+
+// CHECK-DAG: !{{[0-9]+}} = !DIExpression(DW_OP_bit_piece, 0, 32)
+// CHECK-DAG: !{{[0-9]+}} = !DIExpression(DW_OP_bit_piece, 32, 32)
+// CHECK-DAG: !{{[0-9]+}} = !DIExpression(DW_OP_bit_piece, 64, 32)
+
+struct K {
+  float foo;
+};
+
+struct S {
+  float foo;
+  K bar;
+  float baz;
+};
+
+float main(float a : A, float b : B) : SV_Target {
+  S s;
+  s.foo = a;
+  s.bar.foo = a+b;
+  s.baz = a+b;
+  return s.bar.foo + s.foo + s.baz;
+}
+

+ 22 - 0
tools/clang/test/CodeGenHLSL/debug/nested_struct_arg.hlsl

@@ -0,0 +1,22 @@
+// RUN: %dxc -Zi -E main -Od -T ps_6_0 %s | FileCheck %s
+
+// Make sure all elements of the struct in an arg (even when there are nested
+// structs) are at distinct offsets.
+
+// CHECK-DAG: DW_OP_bit_piece
+
+
+struct K_ARG {
+  float foo : KFOO;
+};
+
+struct S_ARG {
+  float foo : FOO;
+  K_ARG bar;
+  float baz : BAZ;
+};
+
+float main(S_ARG s) : SV_Target {
+  return s.bar.foo + s.foo + s.baz;
+}
+

+ 18 - 0
tools/clang/test/CodeGenHLSL/debug/struct_piece.hlsl

@@ -0,0 +1,18 @@
+// RUN: %dxc -Od -Zi -E main -T ps_6_0 %s | FileCheck %s
+
+// Make sure the bit pieces have the offset in bits
+// CHECK-DAG: !{{[0-9]+}} = !DIExpression(DW_OP_bit_piece, 0, 32)
+// CHECK-DAG: !{{[0-9]+}} = !DIExpression(DW_OP_bit_piece, 32, 32)
+
+struct S {
+  float foo;
+  float bar;
+};
+
+float main(float a : A) : SV_Target {
+  S s;
+  s.foo = a * a;
+  s.bar = a + a;
+  return s.foo + s.bar;
+}
+

+ 5 - 0
tools/clang/unittests/HLSL/CompilerTest.cpp

@@ -922,6 +922,7 @@ public:
   TEST_METHOD(SubobjectCodeGenErrors)
   TEST_METHOD(ShaderCompatSuite)
   TEST_METHOD(Unroll)
+  TEST_METHOD(DebugInfo)
   TEST_METHOD(QuickTest)
   TEST_METHOD(QuickLlTest)
   BEGIN_TEST_METHOD(ManualFileCheckTest)
@@ -5762,6 +5763,10 @@ TEST_F(CompilerTest, Unroll) {
   CodeGenTestCheckBatchDir(L"..\\CodeGenHLSL\\unroll");
 }
 
+TEST_F(CompilerTest, DebugInfo) {
+  CodeGenTestCheckBatchDir(L"..\\CodeGenHLSL\\debug");
+}
+
 TEST_F(CompilerTest, ShaderCompatSuite) {
   CodeGenTestCheckBatchDir(L"..\\CodeGenHLSL\\shader-compat-suite");
 }