Преглед изворни кода

Not create phi for resClass and resID of createHandle when all operands is the same. (#101)

Xiang Li пре 8 година
родитељ
комит
6153e6dd01

+ 24 - 5
lib/HLSL/DxilGenerationPass.cpp

@@ -1876,7 +1876,8 @@ void DxilGenerationPass::AddCreateHandleForPhiNode(std::unordered_map<Instructio
         handlePhi->getArgOperand(DXIL::OperandIndex::kCreateHandleResIDOpIdx));
     PHINode *resAddressPhi = cast<PHINode>(handlePhi->getArgOperand(
         DXIL::OperandIndex::kCreateHandleResIndexOpIdx));
-
+    Value *resClass0 = nullptr;
+    Value *resID0 = nullptr;
     for (unsigned i = 0; i < numOperands; i++) {
 
       BasicBlock *BB = phi->getIncomingBlock(i);
@@ -1900,11 +1901,26 @@ void DxilGenerationPass::AddCreateHandleForPhiNode(std::unordered_map<Instructio
       Value *resIDI =
           handleI->getArgOperand(DXIL::OperandIndex::kCreateHandleResIDOpIdx);
       resIDPhi->addIncoming(resIDI, BB);
-
+      if (i == 0) {
+        resClass0 = resClassI;
+        resID0 = resIDI;
+      } else {
+        if (resClass0 != resClassI)
+          resClass0 = nullptr;
+        if (resID0 != resIDI)
+          resID0 = nullptr;
+      }
       Value *resAddressI = handleI->getArgOperand(
           DXIL::OperandIndex::kCreateHandleResIndexOpIdx);
       resAddressPhi->addIncoming(resAddressI, BB);
     }
+
+    if (resClass0) {
+      handlePhi->setArgOperand(DXIL::OperandIndex::kCreateHandleResClassOpIdx, resClass0);
+    }
+    if (resID0) {
+      handlePhi->setArgOperand(DXIL::OperandIndex::kCreateHandleResIDOpIdx, resID0);
+    }
   }
 
   // Merge res class into imm.
@@ -2677,15 +2693,18 @@ void UpdateStructTypeForLegacyLayout(DxilResourceBase &Res, DxilTypeSystem &Type
     // Delete old GV.
     for (auto UserIt = GV->user_begin(); UserIt != GV->user_end(); ) {
       Value *User = *(UserIt++);
-      DXASSERT(User->user_empty(),
-               "GV user should not have use after HLOperationLower.");
       if (Instruction *I = dyn_cast<Instruction>(User)) {
+        if (!User->user_empty())
+          I->replaceAllUsesWith(UndefValue::get(I->getType()));
+
         I->eraseFromParent();
       } else {
         ConstantExpr *CE = cast<ConstantExpr>(User);
-        CE->dropAllReferences();
+        if (!CE->user_empty())
+          CE->replaceAllUsesWith(UndefValue::get(CE->getType()));
       }
     }
+    GV->removeDeadConstantUsers();
     GV->eraseFromParent();
   }
 }

+ 29 - 0
tools/clang/test/CodeGenHLSL/resPhi.hlsl

@@ -0,0 +1,29 @@
+// RUN: %dxc -E main -T cs_6_0 -Zi -Od %s | FileCheck %s
+
+// CHECK: @main
+
+RWStructuredBuffer<float2x2> oA[6];
+
+StructuredBuffer<float2x2> iA[6];
+
+uint s;
+
+[numthreads(8,8,1)]
+void main( uint2 tid : SV_DispatchThreadID, uint2 gid : SV_GroupID, uint2 gtid : SV_GroupThreadID, uint gidx : SV_GroupIndex )
+{
+
+RWStructuredBuffer<float2x2> o = oA[0];
+StructuredBuffer<float2x2> i = iA[0];
+
+if (s > 8) {
+    for (uint a = 0;a<3;a++) {
+      o = oA[a];
+      i = iA[a];
+      o[gid.x+a] = i[gid.x+a];
+    }
+
+}
+
+o[gid.x] = i[gid.x];
+
+}

+ 27 - 0
tools/clang/test/CodeGenHLSL/resPhi2.hlsl

@@ -0,0 +1,27 @@
+// RUN: %dxc -E main -T ps_6_0 -Zi -Od %s | FileCheck %s
+
+// CHECK: main
+
+float4 Tex2D(Texture2D<float4> t,
+  SamplerState s, float2 c) {
+  return t.Sample(s, c);
+}
+
+SamplerState g_ss;
+Texture2D<float4> g_texture[6];
+
+float4 main(float2 c: T) : SV_Target {
+  Texture2D<float4> texture;
+  float4 r = 0;
+  for (uint x=0;x<2;x++) {
+    texture = g_texture[x];
+    r += Tex2D(texture, g_ss, c);
+  if (c.x>0)
+    texture = g_texture[0];
+  else
+    texture = g_texture[2];
+
+    r += Tex2D(texture, g_ss, c);
+  }
+  return r;
+}

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

@@ -585,6 +585,8 @@ public:
   TEST_METHOD(CodeGenResourceInCBV2)
   TEST_METHOD(CodeGenResourceInTB2)
   TEST_METHOD(CodeGenResourceInTBV2)
+  TEST_METHOD(CodeGenResPhi)
+  TEST_METHOD(CodeGenResPhi2)
   TEST_METHOD(CodeGenRootSigEntry)
   TEST_METHOD(CodeGenCBufferStructArray)
   TEST_METHOD(PreprocessWhenValidThenOK)
@@ -2992,6 +2994,14 @@ TEST_F(CompilerTest, CodeGenResourceInTBV2) {
   CodeGenTestCheck(L"..\\CodeGenHLSL\\resource-in-tbv2.hlsl");
 }
 
+TEST_F(CompilerTest, CodeGenResPhi) {
+  CodeGenTestCheck(L"..\\CodeGenHLSL\\resPhi.hlsl");
+}
+
+TEST_F(CompilerTest, CodeGenResPhi2) {
+  CodeGenTestCheck(L"..\\CodeGenHLSL\\resPhi2.hlsl");
+}
+
 TEST_F(CompilerTest, CodeGenRootSigEntry) {
   CodeGenTest(L"..\\CodeGenHLSL\\rootSigEntry.hlsl");
 }