瀏覽代碼

Take care debug info in scalarizer. (#1917)

* Take care debug info in scalarizer.

* Make sure vector is a vector in debug info.
Xiang Li 6 年之前
父節點
當前提交
af869d0f48

+ 53 - 0
lib/Transforms/Scalar/Scalarizer.cpp

@@ -21,6 +21,8 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/IR/DebugInfo.h" // HLSL Change -debug info in scalarizer.
+#include "llvm/IR/DIBuilder.h" // HLSL Change -debug info in scalarizer.
 
 using namespace llvm;
 
@@ -673,6 +675,10 @@ bool Scalarizer::finish() {
   if (Gathered.empty())
     return false;
   // HLSL Change Begins.
+  Module &M = *Gathered.front().first->getModule();
+  LLVMContext &Ctx = M.getContext();
+  const DataLayout &DL = M.getDataLayout();
+  bool HasDbgInfo = getDebugMetadataVersionFromModule(M) != 0;
   // Map from an extract element inst to a Value which replaced it.
   DenseMap<Instruction *, Value*> EltMap;
   // HLSL Change Ends.
@@ -680,6 +686,36 @@ bool Scalarizer::finish() {
        GMI != GME; ++GMI) {
     Instruction *Op = GMI->first;
     ValueVector &CV = *GMI->second;
+    // HLSL Change Begin - debug info in scalarizer.
+    if (HasDbgInfo) {
+      if (auto *L = LocalAsMetadata::getIfExists(Op)) {
+        if (auto *DINode = MetadataAsValue::getIfExists(Ctx, L)) {
+          Type *Ty = Op->getType();
+          unsigned Count = Ty->getVectorNumElements();
+          Type *EltTy = Ty->getVectorElementType();
+          unsigned EltSize = DL.getTypeSizeInBits(EltTy);
+          for (User *U : DINode->users())
+            if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(U)) {
+              DIBuilder DIB(M, /*AllowUnresolved*/ false);
+              auto *VarInfo = DVI->getVariable();
+              DebugLoc DbgLoc = DVI->getDebugLoc();
+              unsigned Offset = 0;
+              for (unsigned I = 0; I < Count; ++I) {
+                // TODO: need to use DIExpression::createFragmentExpression for
+                // case DVI->getExpression is already bit piece.
+                DIExpression *EltExpr =
+                    DIB.createBitPieceExpression(Offset, EltSize);
+                Offset += EltSize;
+
+                DIB.insertDbgValueIntrinsic(CV[I], Offset, VarInfo, EltExpr,
+                                            DbgLoc, DVI);
+              }
+            }
+        }
+      }
+    }
+    // HLSL Change End.
+
     if (!Op->use_empty()) {
       // HLSL Change Begins.
       // Remove the extract element users if possible.
@@ -701,6 +737,23 @@ bool Scalarizer::finish() {
             } else
               break;
           }
+          if (HasDbgInfo) {
+            if (auto *L = LocalAsMetadata::getIfExists(CV[immIdx])) {
+              if (auto *DINode = MetadataAsValue::getIfExists(Ctx, L)) {
+                for (User *U : DINode->users())
+                  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);
+                  }
+              }
+            }
+          }
           EEI->replaceAllUsesWith(Elt);
 
           EltMap[EEI] = Elt;

+ 11 - 3
tools/clang/lib/AST/ASTContextHLSL.cpp

@@ -447,13 +447,21 @@ void hlsl::AddHLSLVectorTemplate(ASTContext& context, ClassTemplateDecl** vector
   templateRecordDecl->setLexicalDeclContext(currentDeclContext);
   templateRecordDecl->startDefinition();
 
-  // Add an 'h' field to hold the handle.
-  AddHLSLHandleField(context, templateRecordDecl, QualType(GetHLSLObjectHandleType(context)));
+  Expr *vecSizeExpr = DeclRefExpr::Create(
+      context, NestedNameSpecifierLoc(), NoLoc, colCountTemplateParamDecl,
+      false,
+      DeclarationNameInfo(colCountTemplateParamDecl->getDeclName(), NoLoc),
+      intType, ExprValueKind::VK_RValue);
 
-  // Add an operator[]. The operator ranges from zero to colcount-1, and returns a scalar.
   const unsigned int templateDepth = 0;
   QualType resultType = context.getTemplateTypeParmType(
     templateDepth, 0, ParameterPackFalse, elementTemplateParamDecl);
+  QualType vectorType = context.getDependentSizedExtVectorType(
+      resultType, vecSizeExpr, SourceLocation());
+  // Add an 'h' field to hold the handle.
+  AddHLSLHandleField(context, templateRecordDecl, vectorType);
+
+  // Add an operator[]. The operator ranges from zero to colcount-1, and returns a scalar.
 
   // ForConstTrue:
   QualType refResultType = context.getConstType(context.getLValueReferenceType(resultType));

+ 80 - 0
tools/clang/test/CodeGenHLSL/quick-test/inline_dbginfo.hlsl

@@ -0,0 +1,80 @@
+// RUN: %dxc -T ps_6_0 -E main -Zi %s | FileCheck %s
+
+// Make sure llvm.dbg.value exist.
+// CHECK: call void @llvm.dbg.value
+
+// Make sure vector is a vector in debug info.
+// CHECK: DIFlagVector
+
+typedef float4 MyCoolFloat4;
+
+static float4 myStaticGlobalVar = float4(1.0, 1.0, 1.0, 1.0);
+
+
+// Local var with same name as outer scope
+float4 localScopeVar_func(float4 val)
+{
+    float4 color = val * val;
+    return color;
+}
+
+// Local var with same name as register
+float4 localRegVar_func(float4 val)
+{
+    float4 r1 = val;
+    return r1;
+}
+
+// Array
+float4 array_func(float4 val)
+{
+    float result[4];
+    result[0] = val.x;
+    result[1] = val.y;
+    result[2] = val.z;
+    result[3] = val.w;
+    return float4(result[0], result[1], result[2], result[3]);
+}
+
+// Typedef
+float4 typedef_func(float4 val)
+{
+    MyCoolFloat4 result = val;
+    return result;
+}
+
+// Global
+float4 global_func(float4 val)
+{
+    myStaticGlobalVar *= val;
+    return myStaticGlobalVar;
+}
+
+float4 depth4(float4 val)
+{
+    val = val * val;
+    return val;
+}
+
+float4 depth3(float4 val)
+{
+    val = depth4(val) * val;
+    return val;
+}
+
+float4 depth2(float4 val)
+{
+    val = depth3(val) * val;
+    return val;
+}
+
+float4 main( float4 unused : SV_POSITION, float4 color : COLOR ) : SV_Target
+{
+    float4 ret1 = localScopeVar_func(color);
+    float4 ret2 = localRegVar_func(ret1);
+    float4 ret3 = array_func(ret2);
+    float4 ret4 = typedef_func(ret3);
+    float4 ret5 = global_func(ret4);
+    float4 ret6 = depth2(ret5);
+    return max(ret6, color);
+}