2
0
Эх сурвалжийг харах

Just run clang format on PIX passes (#2611)

Zero code change here, except moving the #include for DxilOperations.h to be on its own in a few files, in order to cope with our clang-format's habit of ordering includes alphabetically.
This is in preparation for a real change coming next.
Jeff Noyle 5 жил өмнө
parent
commit
d4c31404c3

+ 163 - 107
lib/DxilPIXPasses/DxilAddPixelHitInstrumentation.cpp

@@ -10,12 +10,13 @@
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "dxc/HLSL/DxilGenerationPass.h"
 #include "dxc/DXIL/DxilOperations.h"
+
 #include "dxc/DXIL/DxilInstructions.h"
 #include "dxc/DXIL/DxilModule.h"
-#include "dxc/DxilPIXPasses/DxilPIXPasses.h"
 #include "dxc/DXIL/DxilUtil.h"
+#include "dxc/DxilPIXPasses/DxilPIXPasses.h"
+#include "dxc/HLSL/DxilGenerationPass.h"
 
 #include "llvm/IR/PassManager.h"
 #include "llvm/Transforms/Utils/Local.h"
@@ -39,8 +40,7 @@ public:
   bool runOnModule(Module &M) override;
 };
 
-void DxilAddPixelHitInstrumentation::applyOptions(PassOptions O)
-{
+void DxilAddPixelHitInstrumentation::applyOptions(PassOptions O) {
   GetPassOptionBool(O, "force-early-z", &ForceEarlyZ, false);
   GetPassOptionBool(O, "add-pixel-cost", &AddPixelCost, false);
   GetPassOptionInt(O, "rt-width", &RTWidth, 0);
@@ -48,64 +48,73 @@ void DxilAddPixelHitInstrumentation::applyOptions(PassOptions O)
   GetPassOptionInt(O, "sv-position-index", &SVPositionIndex, 0);
 }
 
-bool DxilAddPixelHitInstrumentation::runOnModule(Module &M)
-{
+bool DxilAddPixelHitInstrumentation::runOnModule(Module &M) {
   // This pass adds instrumentation for pixel hit counting and pixel cost.
 
   DxilModule &DM = M.GetOrCreateDxilModule();
-  LLVMContext & Ctx = M.getContext();
+  LLVMContext &Ctx = M.getContext();
   OP *HlslOP = DM.GetOP();
 
-  // ForceEarlyZ is incompatible with the discard function (the Z has to be tested/written, and may be written before the shader even runs)
-  if (ForceEarlyZ)
-  {
+  // ForceEarlyZ is incompatible with the discard function (the Z has to be
+  // tested/written, and may be written before the shader even runs)
+  if (ForceEarlyZ) {
     DM.m_ShaderFlags.SetForceEarlyDepthStencil(true);
   }
-  
-  hlsl::DxilSignature & InputSignature = DM.GetInputSignature();
 
-  auto & InputElements = InputSignature.GetElements();
+  hlsl::DxilSignature &InputSignature = DM.GetInputSignature();
+
+  auto &InputElements = InputSignature.GetElements();
 
   unsigned SV_Position_ID;
 
-  auto SV_Position = std::find_if(InputElements.begin(), InputElements.end(), [](const std::unique_ptr<DxilSignatureElement> & Element) {
-    return Element->GetSemantic()->GetKind() == hlsl::DXIL::SemanticKind::Position; });
+  auto SV_Position =
+      std::find_if(InputElements.begin(), InputElements.end(),
+                   [](const std::unique_ptr<DxilSignatureElement> &Element) {
+                     return Element->GetSemantic()->GetKind() ==
+                            hlsl::DXIL::SemanticKind::Position;
+                   });
 
-  // SV_Position, if present, has to have full mask, so we needn't worry 
+  // SV_Position, if present, has to have full mask, so we needn't worry
   // about the shader having selected components that don't include x or y.
   // If not present, we add it.
-  if ( SV_Position == InputElements.end() ) {
-    auto SVPosition = llvm::make_unique<DxilSignatureElement>(DXIL::SigPointKind::PSIn);
-    SVPosition->Initialize("Position", hlsl::CompType::getF32(), hlsl::DXIL::InterpolationMode::Linear, 1, 4, SVPositionIndex == -1 ? 0 : SVPositionIndex, 0);
+  if (SV_Position == InputElements.end()) {
+    auto SVPosition =
+        llvm::make_unique<DxilSignatureElement>(DXIL::SigPointKind::PSIn);
+    SVPosition->Initialize("Position", hlsl::CompType::getF32(),
+                           hlsl::DXIL::InterpolationMode::Linear, 1, 4,
+                           SVPositionIndex == -1 ? 0 : SVPositionIndex, 0);
     SVPosition->AppendSemanticIndex(0);
     SVPosition->SetSigPointKind(DXIL::SigPointKind::PSIn);
     SVPosition->SetKind(hlsl::DXIL::SemanticKind::Position);
 
     auto index = InputSignature.AppendElement(std::move(SVPosition));
     SV_Position_ID = InputElements[index]->GetID();
-  }
-  else {
+  } else {
     SV_Position_ID = SV_Position->get()->GetID();
   }
 
   auto EntryPointFunction = DM.GetEntryFunction();
 
-  auto & EntryBlock = EntryPointFunction->getEntryBlock();
+  auto &EntryBlock = EntryPointFunction->getEntryBlock();
 
   CallInst *HandleForUAV;
   {
-    IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(DM.GetEntryFunction()));
-    
-    unsigned int UAVResourceHandle = static_cast<unsigned int>(DM.GetUAVs().size());
+    IRBuilder<> Builder(
+        dxilutil::FirstNonAllocaInsertionPt(DM.GetEntryFunction()));
+
+    unsigned int UAVResourceHandle =
+        static_cast<unsigned int>(DM.GetUAVs().size());
 
     // Set up a UAV with structure of a single int
-    SmallVector<llvm::Type*, 1> Elements{ Type::getInt32Ty(Ctx) };
-    llvm::StructType *UAVStructTy = llvm::StructType::create(Elements, "class.RWStructuredBuffer");
+    SmallVector<llvm::Type *, 1> Elements{Type::getInt32Ty(Ctx)};
+    llvm::StructType *UAVStructTy =
+        llvm::StructType::create(Elements, "class.RWStructuredBuffer");
     std::unique_ptr<DxilResource> pUAV = llvm::make_unique<DxilResource>();
     pUAV->SetGlobalName("PIX_CountUAVName");
     pUAV->SetGlobalSymbol(UndefValue::get(UAVStructTy->getPointerTo()));
     pUAV->SetID(UAVResourceHandle);
-    pUAV->SetSpaceID((unsigned int)-2); // This is the reserved-for-tools register space
+    pUAV->SetSpaceID(
+        (unsigned int)-2); // This is the reserved-for-tools register space
     pUAV->SetSampleCount(1);
     pUAV->SetGloballyCoherent(false);
     pUAV->SetHasCounter(false);
@@ -116,11 +125,11 @@ bool DxilAddPixelHitInstrumentation::runOnModule(Module &M)
     pUAV->SetRW(true);
 
     auto pAnnotation = DM.GetTypeSystem().GetStructAnnotation(UAVStructTy);
-    if (pAnnotation == nullptr)
-    {
+    if (pAnnotation == nullptr) {
       pAnnotation = DM.GetTypeSystem().AddStructAnnotation(UAVStructTy);
       pAnnotation->GetFieldAnnotation(0).SetCBufferOffset(0);
-      pAnnotation->GetFieldAnnotation(0).SetCompType(hlsl::DXIL::ComponentType::I32);
+      pAnnotation->GetFieldAnnotation(0).SetCompType(
+          hlsl::DXIL::ComponentType::I32);
       pAnnotation->GetFieldAnnotation(0).SetFieldName("count");
     }
 
@@ -129,118 +138,163 @@ bool DxilAddPixelHitInstrumentation::runOnModule(Module &M)
     assert((unsigned)ID == UAVResourceHandle);
 
     // Create handle for the newly-added UAV
-    Function* CreateHandleOpFunc = HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
-    Constant* CreateHandleOpcodeArg = HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
-    Constant* UAVArg = HlslOP->GetI8Const(static_cast<std::underlying_type<DxilResourceBase::Class>::type>(DXIL::ResourceClass::UAV));
-    Constant* MetaDataArg = HlslOP->GetU32Const(ID); // position of the metadata record in the corresponding metadata list
-    Constant* IndexArg = HlslOP->GetU32Const(0); // 
-    Constant* FalseArg = HlslOP->GetI1Const(0); // non-uniform resource index: false
-    HandleForUAV = Builder.CreateCall(CreateHandleOpFunc,
-    { CreateHandleOpcodeArg, UAVArg, MetaDataArg, IndexArg, FalseArg }, "PIX_CountUAV_Handle");
+    Function *CreateHandleOpFunc =
+        HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
+    Constant *CreateHandleOpcodeArg =
+        HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
+    Constant *UAVArg = HlslOP->GetI8Const(
+        static_cast<std::underlying_type<DxilResourceBase::Class>::type>(
+            DXIL::ResourceClass::UAV));
+    Constant *MetaDataArg =
+        HlslOP->GetU32Const(ID); // position of the metadata record in the
+                                 // corresponding metadata list
+    Constant *IndexArg = HlslOP->GetU32Const(0); //
+    Constant *FalseArg =
+        HlslOP->GetI1Const(0); // non-uniform resource index: false
+    HandleForUAV = Builder.CreateCall(
+        CreateHandleOpFunc,
+        {CreateHandleOpcodeArg, UAVArg, MetaDataArg, IndexArg, FalseArg},
+        "PIX_CountUAV_Handle");
 
     DM.ReEmitDxilResources();
   }
-  // todo: is it a reasonable assumption that there will be a "Ret" in the entry block, and that these are the only
-  // points from which the shader can exit (except for a pixel-kill?)
-  auto & Instructions = EntryBlock.getInstList();
+  // todo: is it a reasonable assumption that there will be a "Ret" in the entry
+  // block, and that these are the only points from which the shader can exit
+  // (except for a pixel-kill?)
+  auto &Instructions = EntryBlock.getInstList();
   auto It = Instructions.begin();
-  while(It != Instructions.end()) {
+  while (It != Instructions.end()) {
     auto ThisInstruction = It++;
     LlvmInst_Ret Ret(ThisInstruction);
     if (Ret) {
-      // Check that there is at least one instruction preceding the Ret (no need to instrument it if there isn't)
+      // Check that there is at least one instruction preceding the Ret (no need
+      // to instrument it if there isn't)
       if (ThisInstruction->getPrevNode() != nullptr) {
 
         // Start adding instructions right before the Ret:
         IRBuilder<> Builder(ThisInstruction);
 
         // ------------------------------------------------------------------------------------------------------------
-        // Generate instructions to increment (by one) a UAV value corresponding to the pixel currently being rendered
+        // Generate instructions to increment (by one) a UAV value corresponding
+        // to the pixel currently being rendered
         // ------------------------------------------------------------------------------------------------------------
 
         // Useful constants
-        Constant* Zero32Arg = HlslOP->GetU32Const(0);
-        Constant* Zero8Arg = HlslOP->GetI8Const(0);
-        Constant* One32Arg = HlslOP->GetU32Const(1);
-        Constant* One8Arg = HlslOP->GetI8Const(1);
-        UndefValue* UndefArg = UndefValue::get(Type::getInt32Ty(Ctx));
-        Constant* NumPixelsByteOffsetArg = HlslOP->GetU32Const(NumPixels * 4);
-
-        // Step 1: Convert SV_POSITION to UINT          
-        Value * XAsInt;
-        Value * YAsInt;
+        Constant *Zero32Arg = HlslOP->GetU32Const(0);
+        Constant *Zero8Arg = HlslOP->GetI8Const(0);
+        Constant *One32Arg = HlslOP->GetU32Const(1);
+        Constant *One8Arg = HlslOP->GetI8Const(1);
+        UndefValue *UndefArg = UndefValue::get(Type::getInt32Ty(Ctx));
+        Constant *NumPixelsByteOffsetArg = HlslOP->GetU32Const(NumPixels * 4);
+
+        // Step 1: Convert SV_POSITION to UINT
+        Value *XAsInt;
+        Value *YAsInt;
         {
-          auto LoadInputOpFunc = HlslOP->GetOpFunc(DXIL::OpCode::LoadInput, Type::getFloatTy(Ctx));
-          Constant* LoadInputOpcode = HlslOP->GetU32Const((unsigned)DXIL::OpCode::LoadInput);
-          Constant*  SV_Pos_ID = HlslOP->GetU32Const(SV_Position_ID);
-          auto XPos = Builder.CreateCall(LoadInputOpFunc,
-          { LoadInputOpcode, SV_Pos_ID, Zero32Arg /*row*/, Zero8Arg /*column*/, UndefArg }, "XPos");
-          auto YPos = Builder.CreateCall(LoadInputOpFunc,
-          { LoadInputOpcode, SV_Pos_ID, Zero32Arg /*row*/, One8Arg /*column*/, UndefArg }, "YPos");
-
-          XAsInt = Builder.CreateCast(Instruction::CastOps::FPToUI, XPos, Type::getInt32Ty(Ctx), "XIndex");
-          YAsInt = Builder.CreateCast(Instruction::CastOps::FPToUI, YPos, Type::getInt32Ty(Ctx), "YIndex");
+          auto LoadInputOpFunc =
+              HlslOP->GetOpFunc(DXIL::OpCode::LoadInput, Type::getFloatTy(Ctx));
+          Constant *LoadInputOpcode =
+              HlslOP->GetU32Const((unsigned)DXIL::OpCode::LoadInput);
+          Constant *SV_Pos_ID = HlslOP->GetU32Const(SV_Position_ID);
+          auto XPos =
+              Builder.CreateCall(LoadInputOpFunc,
+                                 {LoadInputOpcode, SV_Pos_ID, Zero32Arg /*row*/,
+                                  Zero8Arg /*column*/, UndefArg},
+                                 "XPos");
+          auto YPos =
+              Builder.CreateCall(LoadInputOpFunc,
+                                 {LoadInputOpcode, SV_Pos_ID, Zero32Arg /*row*/,
+                                  One8Arg /*column*/, UndefArg},
+                                 "YPos");
+
+          XAsInt = Builder.CreateCast(Instruction::CastOps::FPToUI, XPos,
+                                      Type::getInt32Ty(Ctx), "XIndex");
+          YAsInt = Builder.CreateCast(Instruction::CastOps::FPToUI, YPos,
+                                      Type::getInt32Ty(Ctx), "YIndex");
         }
 
         // Step 2: Calculate pixel index
-        Value * Index;
+        Value *Index;
         {
-          Constant* RTWidthArg = HlslOP->GetI32Const(RTWidth);
+          Constant *RTWidthArg = HlslOP->GetI32Const(RTWidth);
           auto YOffset = Builder.CreateMul(YAsInt, RTWidthArg, "YOffset");
-          auto Elementoffset = Builder.CreateAdd(XAsInt, YOffset, "ElementOffset");
-          Index = Builder.CreateMul(Elementoffset, HlslOP->GetU32Const(4), "ByteIndex");
+          auto Elementoffset =
+              Builder.CreateAdd(XAsInt, YOffset, "ElementOffset");
+          Index = Builder.CreateMul(Elementoffset, HlslOP->GetU32Const(4),
+                                    "ByteIndex");
         }
 
         // Insert the UAV increment instruction:
-        Function* AtomicOpFunc = HlslOP->GetOpFunc(OP::OpCode::AtomicBinOp, Type::getInt32Ty(Ctx));
-        Constant* AtomicBinOpcode = HlslOP->GetU32Const((unsigned)OP::OpCode::AtomicBinOp);
-        Constant* AtomicAdd = HlslOP->GetU32Const((unsigned)DXIL::AtomicBinOpCode::Add);
+        Function *AtomicOpFunc =
+            HlslOP->GetOpFunc(OP::OpCode::AtomicBinOp, Type::getInt32Ty(Ctx));
+        Constant *AtomicBinOpcode =
+            HlslOP->GetU32Const((unsigned)OP::OpCode::AtomicBinOp);
+        Constant *AtomicAdd =
+            HlslOP->GetU32Const((unsigned)DXIL::AtomicBinOpCode::Add);
         {
-          (void)Builder.CreateCall(AtomicOpFunc, {
-            AtomicBinOpcode,// i32, ; opcode
-            HandleForUAV,   // %dx.types.Handle, ; resource handle
-            AtomicAdd,      // i32, ; binary operation code : EXCHANGE, IADD, AND, OR, XOR, IMIN, IMAX, UMIN, UMAX
-            Index,          // i32, ; coordinate c0: byte offset
-            UndefArg,       // i32, ; coordinate c1 (unused)
-            UndefArg,       // i32, ; coordinate c2 (unused)
-            One32Arg        // i32); increment value
-          }, "UAVIncResult");
+          (void)Builder.CreateCall(
+              AtomicOpFunc,
+              {
+                  AtomicBinOpcode, // i32, ; opcode
+                  HandleForUAV,    // %dx.types.Handle, ; resource handle
+                  AtomicAdd, // i32, ; binary operation code : EXCHANGE, IADD,
+                             // AND, OR, XOR, IMIN, IMAX, UMIN, UMAX
+                  Index,     // i32, ; coordinate c0: byte offset
+                  UndefArg,  // i32, ; coordinate c1 (unused)
+                  UndefArg,  // i32, ; coordinate c2 (unused)
+                  One32Arg   // i32); increment value
+              },
+              "UAVIncResult");
         }
 
         if (AddPixelCost) {
           // ------------------------------------------------------------------------------------------------------------
-          // Generate instructions to increment a value corresponding to the current pixel in the second half of the UAV, 
-          // by an amount proportional to the estimated average cost of each pixel in the current draw call.
+          // Generate instructions to increment a value corresponding to the
+          // current pixel in the second half of the UAV, by an amount
+          // proportional to the estimated average cost of each pixel in the
+          // current draw call.
           // ------------------------------------------------------------------------------------------------------------
 
-          // Step 1: Retrieve weight value from UAV; it will be placed after the range we're writing to
-          Value * Weight;
+          // Step 1: Retrieve weight value from UAV; it will be placed after the
+          // range we're writing to
+          Value *Weight;
           {
-            Function* LoadWeight = HlslOP->GetOpFunc(OP::OpCode::BufferLoad, Type::getInt32Ty(Ctx));
-            Constant* LoadWeightOpcode = HlslOP->GetU32Const((unsigned)DXIL::OpCode::BufferLoad);
-            Constant* OffsetIntoUAV = HlslOP->GetU32Const(NumPixels * 2 * 4);
-            auto WeightStruct = Builder.CreateCall(LoadWeight, {
-              LoadWeightOpcode, // i32 opcode
-              HandleForUAV,     // %dx.types.Handle, ; resource handle
-              OffsetIntoUAV,    // i32 c0: byte offset
-              UndefArg          // i32 c1: unused
-            }, "WeightStruct");
-            Weight = Builder.CreateExtractValue(WeightStruct, static_cast<uint64_t>(0LL), "Weight");
+            Function *LoadWeight = HlslOP->GetOpFunc(OP::OpCode::BufferLoad,
+                                                     Type::getInt32Ty(Ctx));
+            Constant *LoadWeightOpcode =
+                HlslOP->GetU32Const((unsigned)DXIL::OpCode::BufferLoad);
+            Constant *OffsetIntoUAV = HlslOP->GetU32Const(NumPixels * 2 * 4);
+            auto WeightStruct = Builder.CreateCall(
+                LoadWeight,
+                {
+                    LoadWeightOpcode, // i32 opcode
+                    HandleForUAV,     // %dx.types.Handle, ; resource handle
+                    OffsetIntoUAV,    // i32 c0: byte offset
+                    UndefArg          // i32 c1: unused
+                },
+                "WeightStruct");
+            Weight = Builder.CreateExtractValue(
+                WeightStruct, static_cast<uint64_t>(0LL), "Weight");
           }
 
-          // Step 2: Update write position ("Index") to second half of the UAV 
-          auto OffsetIndex = Builder.CreateAdd(Index, NumPixelsByteOffsetArg, "OffsetByteIndex");
+          // Step 2: Update write position ("Index") to second half of the UAV
+          auto OffsetIndex = Builder.CreateAdd(Index, NumPixelsByteOffsetArg,
+                                               "OffsetByteIndex");
 
           // Step 3: Increment UAV value by the weight
-          (void)Builder.CreateCall(AtomicOpFunc,{
-            AtomicBinOpcode,          // i32, ; opcode
-            HandleForUAV,   // %dx.types.Handle, ; resource handle
-            AtomicAdd,      // i32, ; binary operation code : EXCHANGE, IADD, AND, OR, XOR, IMIN, IMAX, UMIN, UMAX
-            OffsetIndex,    // i32, ; coordinate c0: byte offset
-            UndefArg,       // i32, ; coordinate c1 (unused)
-            UndefArg,       // i32, ; coordinate c2 (unused)
-            Weight          // i32); increment value
-          }, "UAVIncResult2");
+          (void)Builder.CreateCall(
+              AtomicOpFunc,
+              {
+                  AtomicBinOpcode, // i32, ; opcode
+                  HandleForUAV,    // %dx.types.Handle, ; resource handle
+                  AtomicAdd,   // i32, ; binary operation code : EXCHANGE, IADD,
+                               // AND, OR, XOR, IMIN, IMAX, UMIN, UMAX
+                  OffsetIndex, // i32, ; coordinate c0: byte offset
+                  UndefArg,    // i32, ; coordinate c1 (unused)
+                  UndefArg,    // i32, ; coordinate c2 (unused)
+                  Weight       // i32); increment value
+              },
+              "UAVIncResult2");
         }
       }
     }
@@ -257,4 +311,6 @@ ModulePass *llvm::createDxilAddPixelHitInstrumentationPass() {
   return new DxilAddPixelHitInstrumentation();
 }
 
-INITIALIZE_PASS(DxilAddPixelHitInstrumentation, "hlsl-dxil-add-pixel-hit-instrmentation", "DXIL Count completed PS invocations and costs", false, false)
+INITIALIZE_PASS(DxilAddPixelHitInstrumentation,
+                "hlsl-dxil-add-pixel-hit-instrmentation",
+                "DXIL Count completed PS invocations and costs", false, false)

+ 22 - 15
lib/DxilPIXPasses/DxilAnnotateWithVirtualRegister.cpp

@@ -20,10 +20,10 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/InstIterator.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/Instructions.h"
-#include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/ModuleSlotTracker.h"
 #include "llvm/IR/Type.h"
@@ -46,7 +46,8 @@ public:
 private:
   void AnnotateValues(llvm::Instruction *pI);
   void AnnotateStore(llvm::Instruction *pI);
-  bool IsAllocaRegisterWrite(llvm::Value *V, llvm::AllocaInst **pAI, llvm::Value **pIdx);
+  bool IsAllocaRegisterWrite(llvm::Value *V, llvm::AllocaInst **pAI,
+                             llvm::Value **pIdx);
   void AnnotateAlloca(llvm::AllocaInst *pAlloca);
   void AnnotateGeneric(llvm::Instruction *pI);
   void AssignNewDxilRegister(llvm::Instruction *pI);
@@ -54,7 +55,7 @@ private:
 
   hlsl::DxilModule *m_DM;
   std::uint32_t m_uVReg;
-  std::unique_ptr < llvm::ModuleSlotTracker > m_MST;
+  std::unique_ptr<llvm::ModuleSlotTracker> m_MST;
   void Init(llvm::Module &M) {
     m_DM = &M.GetOrCreateDxilModule();
     m_uVReg = 0;
@@ -132,7 +133,8 @@ void DxilAnnotateWithVirtualRegister::AnnotateStore(llvm::Instruction *pI) {
   PixAllocaRegWrite::AddMD(m_DM->GetCtx(), pSt, AllocaReg, Index);
 }
 
-bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite(llvm::Value *V, llvm::AllocaInst **pAI, llvm::Value **pIdx) {
+bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite(
+    llvm::Value *V, llvm::AllocaInst **pAI, llvm::Value **pIdx) {
   llvm::IRBuilder<> B(m_DM->GetCtx());
 
   *pAI = nullptr;
@@ -144,7 +146,8 @@ bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite(llvm::Value *V, llvm
       return false;
     }
 
-    llvm::SmallVector<llvm::Value *, 2> Indices(pGEP->idx_begin(), pGEP->idx_end());
+    llvm::SmallVector<llvm::Value *, 2> Indices(pGEP->idx_begin(),
+                                                pGEP->idx_end());
     if (Indices.size() != 2) {
       return false;
     }
@@ -153,7 +156,7 @@ bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite(llvm::Value *V, llvm
     if (pIdx0 == nullptr || pIdx0->getLimitedValue() != 0) {
       return false;
     }
-    
+
     *pAI = Alloca;
     *pIdx = Indices[1];
     return true;
@@ -173,12 +176,11 @@ bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite(llvm::Value *V, llvm
   return false;
 }
 
-void DxilAnnotateWithVirtualRegister::AnnotateAlloca(llvm::AllocaInst *pAlloca) {
+void DxilAnnotateWithVirtualRegister::AnnotateAlloca(
+    llvm::AllocaInst *pAlloca) {
   llvm::Type *pAllocaTy = pAlloca->getType()->getElementType();
-  if (pAllocaTy->isFloatTy() ||
-      pAllocaTy->isIntegerTy() ||
-      pAllocaTy->isHalfTy() ||
-      pAllocaTy->isIntegerTy(16)) {
+  if (pAllocaTy->isFloatTy() || pAllocaTy->isIntegerTy() ||
+      pAllocaTy->isHalfTy() || pAllocaTy->isIntegerTy(16)) {
     AssignNewAllocaRegister(pAlloca, 1);
   } else if (auto *AT = llvm::dyn_cast<llvm::ArrayType>(pAllocaTy)) {
     AssignNewAllocaRegister(pAlloca, AT->getNumElements());
@@ -194,7 +196,8 @@ void DxilAnnotateWithVirtualRegister::AnnotateGeneric(llvm::Instruction *pI) {
   AssignNewDxilRegister(pI);
 }
 
-void DxilAnnotateWithVirtualRegister::AssignNewDxilRegister(llvm::Instruction *pI) {
+void DxilAnnotateWithVirtualRegister::AssignNewDxilRegister(
+    llvm::Instruction *pI) {
   PixDxilReg::AddMD(m_DM->GetCtx(), pI, m_uVReg);
   if (OSOverride != nullptr) {
     static constexpr bool DontPrintType = false;
@@ -204,7 +207,8 @@ void DxilAnnotateWithVirtualRegister::AssignNewDxilRegister(llvm::Instruction *p
   m_uVReg++;
 }
 
-void DxilAnnotateWithVirtualRegister::AssignNewAllocaRegister(llvm::AllocaInst *pAlloca, std::uint32_t C) {
+void DxilAnnotateWithVirtualRegister::AssignNewAllocaRegister(
+    llvm::AllocaInst *pAlloca, std::uint32_t C) {
   PixAllocaReg::AddMD(m_DM->GetCtx(), pAlloca, m_uVReg, C);
   if (OSOverride != nullptr) {
     static constexpr bool DontPrintType = false;
@@ -213,11 +217,14 @@ void DxilAnnotateWithVirtualRegister::AssignNewAllocaRegister(llvm::AllocaInst *
   }
   m_uVReg += C;
 }
-}
+} // namespace
 
 using namespace llvm;
 
-INITIALIZE_PASS(DxilAnnotateWithVirtualRegister, DEBUG_TYPE, "Annotates each instruction in the DXIL module with a virtual register number", false, false)
+INITIALIZE_PASS(DxilAnnotateWithVirtualRegister, DEBUG_TYPE,
+                "Annotates each instruction in the DXIL module with a virtual "
+                "register number",
+                false, false)
 
 ModulePass *llvm::createDxilAnnotateWithVirtualRegisterPass() {
   return new DxilAnnotateWithVirtualRegister();

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 460 - 304
lib/DxilPIXPasses/DxilDebugInstrumentation.cpp


+ 7 - 8
lib/DxilPIXPasses/DxilForceEarlyZ.cpp

@@ -9,9 +9,9 @@
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "dxc/HLSL/DxilGenerationPass.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/DxilPIXPasses/DxilPIXPasses.h"
+#include "dxc/HLSL/DxilGenerationPass.h"
 #include "llvm/IR/Module.h"
 
 using namespace llvm;
@@ -26,9 +26,7 @@ public:
   bool runOnModule(Module &M) override;
 };
 
-
-bool DxilForceEarlyZ::runOnModule(Module &M)
-{
+bool DxilForceEarlyZ::runOnModule(Module &M) {
   // This pass adds the force-early-z flag
 
   DxilModule &DM = M.GetOrCreateDxilModule();
@@ -42,8 +40,9 @@ bool DxilForceEarlyZ::runOnModule(Module &M)
 
 char DxilForceEarlyZ::ID = 0;
 
-ModulePass *llvm::createDxilForceEarlyZPass() {
-  return new DxilForceEarlyZ();
-}
+ModulePass *llvm::createDxilForceEarlyZPass() { return new DxilForceEarlyZ(); }
 
-INITIALIZE_PASS(DxilForceEarlyZ, "hlsl-dxil-force-early-z", "HLSL DXIL Force the early Z global flag, if shader has no discard calls", false, false)
+INITIALIZE_PASS(
+    DxilForceEarlyZ, "hlsl-dxil-force-early-z",
+    "HLSL DXIL Force the early Z global flag, if shader has no discard calls",
+    false, false)

+ 157 - 120
lib/DxilPIXPasses/DxilOutputColorBecomesConstant.cpp

@@ -10,10 +10,10 @@
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "dxc/HLSL/DxilGenerationPass.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/DXIL/DxilOperations.h"
 #include "dxc/DxilPIXPasses/DxilPIXPasses.h"
+#include "dxc/HLSL/DxilGenerationPass.h"
 #include "dxc/HLSL/DxilSpanAllocator.h"
 
 #include "llvm/IR/PassManager.h"
@@ -25,8 +25,7 @@ using namespace hlsl;
 
 class DxilOutputColorBecomesConstant : public ModulePass {
 
-  enum VisualizerInstrumentationMode
-  {
+  enum VisualizerInstrumentationMode {
     FromLiteralConstant,
     FromConstantBuffer
   };
@@ -37,11 +36,10 @@ class DxilOutputColorBecomesConstant : public ModulePass {
   float Alpha = 1.f;
   VisualizerInstrumentationMode Mode = FromLiteralConstant;
 
-  void visitOutputInstructionCallers(
-    Function * OutputFunction, 
-    const hlsl::DxilSignature &OutputSignature, 
-    OP * HlslOP, 
-    std::function<void(CallInst*)> Visitor);
+  void visitOutputInstructionCallers(Function *OutputFunction,
+                                     const hlsl::DxilSignature &OutputSignature,
+                                     OP *HlslOP,
+                                     std::function<void(CallInst *)> Visitor);
 
 public:
   static char ID; // Pass identification, replacement for typeid
@@ -63,26 +61,29 @@ void DxilOutputColorBecomesConstant::applyOptions(PassOptions O) {
 }
 
 void DxilOutputColorBecomesConstant::visitOutputInstructionCallers(
-  Function * OutputFunction,
-  const hlsl::DxilSignature &OutputSignature,
-  OP * HlslOP,
-  std::function<void(CallInst*)> Visitor) {
+    Function *OutputFunction, const hlsl::DxilSignature &OutputSignature,
+    OP *HlslOP, std::function<void(CallInst *)> Visitor) {
 
   auto OutputFunctionUses = OutputFunction->uses();
 
   for (Use &FunctionUse : OutputFunctionUses) {
     iterator_range<Value::user_iterator> FunctionUsers = FunctionUse->users();
-    for (User * FunctionUser : FunctionUsers) {
+    for (User *FunctionUser : FunctionUsers) {
       if (isa<Instruction>(FunctionUser)) {
         auto CallInstruction = cast<CallInst>(FunctionUser);
 
-        // Check if the instruction writes to a render target (as opposed to a system-value, such as RenderTargetArrayIndex)
-        Value *OutputID = CallInstruction->getArgOperand(DXIL::OperandIndex::kStoreOutputIDOpIdx);
-        unsigned SignatureElementIndex = cast<ConstantInt>(OutputID)->getLimitedValue();
-        const DxilSignatureElement &SignatureElement = OutputSignature.GetElement(SignatureElementIndex);
+        // Check if the instruction writes to a render target (as opposed to a
+        // system-value, such as RenderTargetArrayIndex)
+        Value *OutputID = CallInstruction->getArgOperand(
+            DXIL::OperandIndex::kStoreOutputIDOpIdx);
+        unsigned SignatureElementIndex =
+            cast<ConstantInt>(OutputID)->getLimitedValue();
+        const DxilSignatureElement &SignatureElement =
+            OutputSignature.GetElement(SignatureElementIndex);
 
         // We only modify the output color for RTV0
-        if (SignatureElement.GetSemantic()->GetKind() == DXIL::SemanticKind::Target &&
+        if (SignatureElement.GetSemantic()->GetKind() ==
+                DXIL::SemanticKind::Target &&
             SignatureElement.GetSemanticStartIndex() == 0) {
 
           // Replace the source operand with the appropriate constant value
@@ -93,138 +94,173 @@ void DxilOutputColorBecomesConstant::visitOutputInstructionCallers(
   }
 }
 
-bool DxilOutputColorBecomesConstant::runOnModule(Module &M)
-{
-  // This pass finds all users of the "StoreOutput" function, and replaces their source operands with a constant
-  // value. 
+bool DxilOutputColorBecomesConstant::runOnModule(Module &M) {
+  // This pass finds all users of the "StoreOutput" function, and replaces their
+  // source operands with a constant value.
 
   DxilModule &DM = M.GetOrCreateDxilModule();
 
-  LLVMContext & Ctx = M.getContext();
+  LLVMContext &Ctx = M.getContext();
 
   OP *HlslOP = DM.GetOP();
 
-  const hlsl::DxilSignature & OutputSignature = DM.GetOutputSignature();
+  const hlsl::DxilSignature &OutputSignature = DM.GetOutputSignature();
 
-  Function * FloatOutputFunction = HlslOP->GetOpFunc(DXIL::OpCode::StoreOutput, Type::getFloatTy(Ctx));
-  Function * IntOutputFunction = HlslOP->GetOpFunc(DXIL::OpCode::StoreOutput, Type::getInt32Ty(Ctx));
+  Function *FloatOutputFunction =
+      HlslOP->GetOpFunc(DXIL::OpCode::StoreOutput, Type::getFloatTy(Ctx));
+  Function *IntOutputFunction =
+      HlslOP->GetOpFunc(DXIL::OpCode::StoreOutput, Type::getInt32Ty(Ctx));
 
   bool hasFloatOutputs = false;
   bool hasIntOutputs = false;
 
-  visitOutputInstructionCallers(FloatOutputFunction, OutputSignature, HlslOP, [&hasFloatOutputs](CallInst *) {
-    hasFloatOutputs = true;
-  });
+  visitOutputInstructionCallers(
+      FloatOutputFunction, OutputSignature, HlslOP,
+      [&hasFloatOutputs](CallInst *) { hasFloatOutputs = true; });
 
-  visitOutputInstructionCallers(IntOutputFunction, OutputSignature, HlslOP, [&hasIntOutputs](CallInst *) {
-    hasIntOutputs = true;
-  });
+  visitOutputInstructionCallers(
+      IntOutputFunction, OutputSignature, HlslOP,
+      [&hasIntOutputs](CallInst *) { hasIntOutputs = true; });
 
-  if (!hasFloatOutputs && !hasIntOutputs)
-  {
+  if (!hasFloatOutputs && !hasIntOutputs) {
     return false;
   }
 
-  // Otherwise, we assume the shader outputs only one or the other (because the 0th RTV can't have a mixed type)
-  DXASSERT(!hasFloatOutputs || !hasIntOutputs, "Only one or the other type of output: float or int");
+  // Otherwise, we assume the shader outputs only one or the other (because the
+  // 0th RTV can't have a mixed type)
+  DXASSERT(!hasFloatOutputs || !hasIntOutputs,
+           "Only one or the other type of output: float or int");
 
   std::array<llvm::Value *, 4> ReplacementColors;
 
-  switch (Mode)
-  {
-    case FromLiteralConstant: {
-      if (hasFloatOutputs) {
-        ReplacementColors[0] = HlslOP->GetFloatConst(Red);
-        ReplacementColors[1] = HlslOP->GetFloatConst(Green);
-        ReplacementColors[2] = HlslOP->GetFloatConst(Blue);
-        ReplacementColors[3] = HlslOP->GetFloatConst(Alpha);
-      }
-      if (hasIntOutputs) {
-        ReplacementColors[0] = HlslOP->GetI32Const(static_cast<int>(Red));
-        ReplacementColors[1] = HlslOP->GetI32Const(static_cast<int>(Green));
-        ReplacementColors[2] = HlslOP->GetI32Const(static_cast<int>(Blue));
-        ReplacementColors[3] = HlslOP->GetI32Const(static_cast<int>(Alpha));
-      }
+  switch (Mode) {
+  case FromLiteralConstant: {
+    if (hasFloatOutputs) {
+      ReplacementColors[0] = HlslOP->GetFloatConst(Red);
+      ReplacementColors[1] = HlslOP->GetFloatConst(Green);
+      ReplacementColors[2] = HlslOP->GetFloatConst(Blue);
+      ReplacementColors[3] = HlslOP->GetFloatConst(Alpha);
+    }
+    if (hasIntOutputs) {
+      ReplacementColors[0] = HlslOP->GetI32Const(static_cast<int>(Red));
+      ReplacementColors[1] = HlslOP->GetI32Const(static_cast<int>(Green));
+      ReplacementColors[2] = HlslOP->GetI32Const(static_cast<int>(Blue));
+      ReplacementColors[3] = HlslOP->GetI32Const(static_cast<int>(Alpha));
     }
-    break;
-    case FromConstantBuffer: {
-
-      // Setup a constant buffer with a single float4 in it:
-      SmallVector<llvm::Type*, 4> Elements { Type::getFloatTy(Ctx), Type::getFloatTy(Ctx) , Type::getFloatTy(Ctx) , Type::getFloatTy(Ctx) };
-      llvm::StructType *CBStructTy = llvm::StructType::create(Elements, "PIX_ConstantColorCB_Type");
-      std::unique_ptr<DxilCBuffer> pCBuf = llvm::make_unique<DxilCBuffer>();
-      pCBuf->SetGlobalName("PIX_ConstantColorCBName");
-      pCBuf->SetGlobalSymbol(UndefValue::get(CBStructTy));
-      pCBuf->SetID(0);
-      pCBuf->SetSpaceID((unsigned int)-2); // This is the reserved-for-tools register space
-      pCBuf->SetLowerBound(0);
-      pCBuf->SetRangeSize(1);
-      pCBuf->SetSize(4);
-
-      ID = DM.AddCBuffer(std::move(pCBuf));
-
-      Instruction * entryPointInstruction = &*(DM.GetEntryFunction()->begin()->begin());
-      IRBuilder<> Builder(entryPointInstruction);
-
-      // Create handle for the newly-added constant buffer (which is achieved via a function call)
-      auto ConstantBufferName = "PIX_Constant_Color_CB_Handle";
-      Function *createHandle = HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
-      Constant *CreateHandleOpcodeArg = HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
-      Constant *CBVArg = HlslOP->GetI8Const(static_cast<std::underlying_type<DxilResourceBase::Class>::type>(DXIL::ResourceClass::CBuffer)); 
-      Constant *MetaDataArg = HlslOP->GetU32Const(ID); // position of the metadata record in the corresponding metadata list
-      Constant *IndexArg = HlslOP->GetU32Const(0); // 
-      Constant *FalseArg = HlslOP->GetI1Const(0); // non-uniform resource index: false
-      CallInst *callCreateHandle = Builder.CreateCall(createHandle, { CreateHandleOpcodeArg, CBVArg, MetaDataArg, IndexArg, FalseArg }, ConstantBufferName);
-
-      DM.ReEmitDxilResources();
+  } break;
+  case FromConstantBuffer: {
+
+    // Setup a constant buffer with a single float4 in it:
+    SmallVector<llvm::Type *, 4> Elements{
+        Type::getFloatTy(Ctx), Type::getFloatTy(Ctx), Type::getFloatTy(Ctx),
+        Type::getFloatTy(Ctx)};
+    llvm::StructType *CBStructTy =
+        llvm::StructType::create(Elements, "PIX_ConstantColorCB_Type");
+    std::unique_ptr<DxilCBuffer> pCBuf = llvm::make_unique<DxilCBuffer>();
+    pCBuf->SetGlobalName("PIX_ConstantColorCBName");
+    pCBuf->SetGlobalSymbol(UndefValue::get(CBStructTy));
+    pCBuf->SetID(0);
+    pCBuf->SetSpaceID(
+        (unsigned int)-2); // This is the reserved-for-tools register space
+    pCBuf->SetLowerBound(0);
+    pCBuf->SetRangeSize(1);
+    pCBuf->SetSize(4);
+
+    ID = DM.AddCBuffer(std::move(pCBuf));
+
+    Instruction *entryPointInstruction =
+        &*(DM.GetEntryFunction()->begin()->begin());
+    IRBuilder<> Builder(entryPointInstruction);
+
+    // Create handle for the newly-added constant buffer (which is achieved via
+    // a function call)
+    auto ConstantBufferName = "PIX_Constant_Color_CB_Handle";
+    Function *createHandle =
+        HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
+    Constant *CreateHandleOpcodeArg =
+        HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
+    Constant *CBVArg = HlslOP->GetI8Const(
+        static_cast<std::underlying_type<DxilResourceBase::Class>::type>(
+            DXIL::ResourceClass::CBuffer));
+    Constant *MetaDataArg =
+        HlslOP->GetU32Const(ID); // position of the metadata record in the
+                                 // corresponding metadata list
+    Constant *IndexArg = HlslOP->GetU32Const(0); //
+    Constant *FalseArg =
+        HlslOP->GetI1Const(0); // non-uniform resource index: false
+    CallInst *callCreateHandle = Builder.CreateCall(
+        createHandle,
+        {CreateHandleOpcodeArg, CBVArg, MetaDataArg, IndexArg, FalseArg},
+        ConstantBufferName);
+
+    DM.ReEmitDxilResources();
 
 #define PIX_CONSTANT_VALUE "PIX_Constant_Color_Value"
 
-      // Insert the Buffer load instruction:
-      Function *CBLoad = HlslOP->GetOpFunc(OP::OpCode::CBufferLoadLegacy, hasFloatOutputs ? Type::getFloatTy(Ctx) : Type::getInt32Ty(Ctx));
-      Constant *OpArg = HlslOP->GetU32Const((unsigned)OP::OpCode::CBufferLoadLegacy);
-      Value * ResourceHandle = callCreateHandle;
-      Constant *RowIndex = HlslOP->GetU32Const(0);
-      CallInst *loadLegacy = Builder.CreateCall(CBLoad, { OpArg, ResourceHandle, RowIndex }, PIX_CONSTANT_VALUE);
-
-      // Now extract four color values:
-      ReplacementColors[0] = Builder.CreateExtractValue(loadLegacy, 0, PIX_CONSTANT_VALUE "0");
-      ReplacementColors[1] = Builder.CreateExtractValue(loadLegacy, 1, PIX_CONSTANT_VALUE "1");
-      ReplacementColors[2] = Builder.CreateExtractValue(loadLegacy, 2, PIX_CONSTANT_VALUE "2");
-      ReplacementColors[3] = Builder.CreateExtractValue(loadLegacy, 3, PIX_CONSTANT_VALUE "3");
-    }
-    break;
-    default:
-      assert(false);
-      return 0;
+    // Insert the Buffer load instruction:
+    Function *CBLoad = HlslOP->GetOpFunc(
+        OP::OpCode::CBufferLoadLegacy,
+        hasFloatOutputs ? Type::getFloatTy(Ctx) : Type::getInt32Ty(Ctx));
+    Constant *OpArg =
+        HlslOP->GetU32Const((unsigned)OP::OpCode::CBufferLoadLegacy);
+    Value *ResourceHandle = callCreateHandle;
+    Constant *RowIndex = HlslOP->GetU32Const(0);
+    CallInst *loadLegacy = Builder.CreateCall(
+        CBLoad, {OpArg, ResourceHandle, RowIndex}, PIX_CONSTANT_VALUE);
+
+    // Now extract four color values:
+    ReplacementColors[0] =
+        Builder.CreateExtractValue(loadLegacy, 0, PIX_CONSTANT_VALUE "0");
+    ReplacementColors[1] =
+        Builder.CreateExtractValue(loadLegacy, 1, PIX_CONSTANT_VALUE "1");
+    ReplacementColors[2] =
+        Builder.CreateExtractValue(loadLegacy, 2, PIX_CONSTANT_VALUE "2");
+    ReplacementColors[3] =
+        Builder.CreateExtractValue(loadLegacy, 3, PIX_CONSTANT_VALUE "3");
+  } break;
+  default:
+    assert(false);
+    return 0;
   }
 
   bool Modified = false;
 
-  // The StoreOutput function can store either a float or an integer, depending on the intended output
-  // render-target resource view.
+  // The StoreOutput function can store either a float or an integer, depending
+  // on the intended output render-target resource view.
   if (hasFloatOutputs) {
-    visitOutputInstructionCallers(FloatOutputFunction, OutputSignature, HlslOP, 
-      [&ReplacementColors, &Modified](CallInst * CallInstruction) {
-      Modified = true;
-      // The output column is the channel (red, green, blue or alpha) within the output pixel
-      Value * OutputColumnOperand = CallInstruction->getOperand(hlsl::DXIL::OperandIndex::kStoreOutputColOpIdx);
-      ConstantInt * OutputColumnConstant = cast<ConstantInt>(OutputColumnOperand);
-      APInt OutputColumn = OutputColumnConstant->getValue();
-      CallInstruction->setOperand(hlsl::DXIL::OperandIndex::kStoreOutputValOpIdx, ReplacementColors[*OutputColumn.getRawData()]);
-    });
+    visitOutputInstructionCallers(
+        FloatOutputFunction, OutputSignature, HlslOP,
+        [&ReplacementColors, &Modified](CallInst *CallInstruction) {
+          Modified = true;
+          // The output column is the channel (red, green, blue or alpha) within
+          // the output pixel
+          Value *OutputColumnOperand = CallInstruction->getOperand(
+              hlsl::DXIL::OperandIndex::kStoreOutputColOpIdx);
+          ConstantInt *OutputColumnConstant =
+              cast<ConstantInt>(OutputColumnOperand);
+          APInt OutputColumn = OutputColumnConstant->getValue();
+          CallInstruction->setOperand(
+              hlsl::DXIL::OperandIndex::kStoreOutputValOpIdx,
+              ReplacementColors[*OutputColumn.getRawData()]);
+        });
   }
 
   if (hasIntOutputs) {
-    visitOutputInstructionCallers(IntOutputFunction, OutputSignature, HlslOP, 
-    [&ReplacementColors, &Modified](CallInst * CallInstruction) {
-      Modified = true;
-      // The output column is the channel (red, green, blue or alpha) within the output pixel
-      Value * OutputColumnOperand = CallInstruction->getOperand(hlsl::DXIL::OperandIndex::kStoreOutputColOpIdx);
-      ConstantInt * OutputColumnConstant = cast<ConstantInt>(OutputColumnOperand);
-      APInt OutputColumn = OutputColumnConstant->getValue();
-      CallInstruction->setOperand(hlsl::DXIL::OperandIndex::kStoreOutputValOpIdx, ReplacementColors[*OutputColumn.getRawData()]);
-    });
+    visitOutputInstructionCallers(
+        IntOutputFunction, OutputSignature, HlslOP,
+        [&ReplacementColors, &Modified](CallInst *CallInstruction) {
+          Modified = true;
+          // The output column is the channel (red, green, blue or alpha) within
+          // the output pixel
+          Value *OutputColumnOperand = CallInstruction->getOperand(
+              hlsl::DXIL::OperandIndex::kStoreOutputColOpIdx);
+          ConstantInt *OutputColumnConstant =
+              cast<ConstantInt>(OutputColumnOperand);
+          APInt OutputColumn = OutputColumnConstant->getValue();
+          CallInstruction->setOperand(
+              hlsl::DXIL::OperandIndex::kStoreOutputValOpIdx,
+              ReplacementColors[*OutputColumn.getRawData()]);
+        });
   }
 
   return Modified;
@@ -236,4 +272,5 @@ ModulePass *llvm::createDxilOutputColorBecomesConstantPass() {
   return new DxilOutputColorBecomesConstant();
 }
 
-INITIALIZE_PASS(DxilOutputColorBecomesConstant, "hlsl-dxil-constantColor", "DXIL Constant Color Mod", false, false)
+INITIALIZE_PASS(DxilOutputColorBecomesConstant, "hlsl-dxil-constantColor",
+                "DXIL Constant Color Mod", false, false)

+ 5 - 6
lib/DxilPIXPasses/DxilPIXPasses.cpp

@@ -9,14 +9,14 @@
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "dxc/Support/WinIncludes.h"
-#include "dxc/Support/Global.h"
 #include "dxc/DxilPIXPasses/DxilPIXPasses.h"
+#include "dxc/Support/Global.h"
+#include "dxc/Support/WinIncludes.h"
 
+#include "llvm/IR/LegacyPassManager.h"
 #include "llvm/Pass.h"
 #include "llvm/PassInfo.h"
 #include "llvm/Support/SourceMgr.h"
-#include "llvm/IR/LegacyPassManager.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 
 using namespace llvm;
@@ -25,8 +25,7 @@ using namespace hlsl;
 namespace hlsl {
 
 HRESULT SetupRegistryPassForPIX() {
-  try
-  {
+  try {
     PassRegistry &Registry = *PassRegistry::getPassRegistry();
     /* <py::lines('INIT-PASSES')>hctdb_instrhelp.get_init_passes(set(["pix"]))</py>*/
     // INIT-PASSES:BEGIN
@@ -44,4 +43,4 @@ HRESULT SetupRegistryPassForPIX() {
   return S_OK;
 }
 
-}
+} // namespace hlsl

+ 74 - 43
lib/DxilPIXPasses/DxilPIXVirtualRegisters.cpp

@@ -15,22 +15,26 @@
 #include "dxc/Support/Global.h"
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/InstIterator.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/Instructions.h"
-#include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Type.h"
 
-void pix_dxil::PixDxilInstNum::AddMD(llvm::LLVMContext &Ctx, llvm::Instruction *pI, std::uint32_t InstNum) {
+void pix_dxil::PixDxilInstNum::AddMD(llvm::LLVMContext &Ctx,
+                                     llvm::Instruction *pI,
+                                     std::uint32_t InstNum) {
   llvm::IRBuilder<> B(Ctx);
   pI->setMetadata(
-    llvm::StringRef(MDName),
-    llvm::MDNode::get(Ctx, { llvm::ConstantAsMetadata::get(B.getInt32(ID)),
-                             llvm::ConstantAsMetadata::get(B.getInt32(InstNum)) }));
+      llvm::StringRef(MDName),
+      llvm::MDNode::get(Ctx,
+                        {llvm::ConstantAsMetadata::get(B.getInt32(ID)),
+                         llvm::ConstantAsMetadata::get(B.getInt32(InstNum))}));
 }
 
-bool pix_dxil::PixDxilInstNum::FromInst(llvm::Instruction *pI, std::uint32_t *pInstNum) {
+bool pix_dxil::PixDxilInstNum::FromInst(llvm::Instruction *pI,
+                                        std::uint32_t *pInstNum) {
   *pInstNum = 0;
 
   auto *mdNodes = pI->getMetadata(MDName);
@@ -43,12 +47,14 @@ bool pix_dxil::PixDxilInstNum::FromInst(llvm::Instruction *pI, std::uint32_t *pI
     return false;
   }
 
-  auto *mdID = llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(0));
+  auto *mdID =
+      llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(0));
   if (mdID == nullptr || mdID->getLimitedValue() != ID) {
     return false;
   }
 
-  auto *mdInstNum = llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(1));
+  auto *mdInstNum =
+      llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(1));
   if (mdInstNum == nullptr) {
     return false;
   }
@@ -57,15 +63,18 @@ bool pix_dxil::PixDxilInstNum::FromInst(llvm::Instruction *pI, std::uint32_t *pI
   return true;
 }
 
-void pix_dxil::PixDxilReg::AddMD(llvm::LLVMContext &Ctx, llvm::Instruction *pI, std::uint32_t RegNum) {
+void pix_dxil::PixDxilReg::AddMD(llvm::LLVMContext &Ctx, llvm::Instruction *pI,
+                                 std::uint32_t RegNum) {
   llvm::IRBuilder<> B(Ctx);
   pI->setMetadata(
       llvm::StringRef(MDName),
-      llvm::MDNode::get(Ctx, { llvm::ConstantAsMetadata::get(B.getInt32(ID)),
-                               llvm::ConstantAsMetadata::get(B.getInt32(RegNum)) }));
+      llvm::MDNode::get(Ctx,
+                        {llvm::ConstantAsMetadata::get(B.getInt32(ID)),
+                         llvm::ConstantAsMetadata::get(B.getInt32(RegNum))}));
 }
 
-bool pix_dxil::PixDxilReg::FromInst(llvm::Instruction *pI, std::uint32_t *pRegNum) {
+bool pix_dxil::PixDxilReg::FromInst(llvm::Instruction *pI,
+                                    std::uint32_t *pRegNum) {
   *pRegNum = 0;
 
   auto *mdNodes = pI->getMetadata(MDName);
@@ -78,12 +87,14 @@ bool pix_dxil::PixDxilReg::FromInst(llvm::Instruction *pI, std::uint32_t *pRegNu
     return false;
   }
 
-  auto *mdID = llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(0));
+  auto *mdID =
+      llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(0));
   if (mdID == nullptr || mdID->getLimitedValue() != ID) {
     return false;
   }
 
-  auto *mdRegNum = llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(1));
+  auto *mdRegNum =
+      llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(1));
   if (mdRegNum == nullptr) {
     return false;
   }
@@ -92,18 +103,22 @@ bool pix_dxil::PixDxilReg::FromInst(llvm::Instruction *pI, std::uint32_t *pRegNu
   return true;
 }
 
-static bool ParsePixAllocaReg(llvm::MDNode *MD, std::uint32_t *RegNum, std::uint32_t *Count) {
+static bool ParsePixAllocaReg(llvm::MDNode *MD, std::uint32_t *RegNum,
+                              std::uint32_t *Count) {
   if (MD->getNumOperands() != 3) {
     return false;
   }
 
   auto *mdID = llvm::mdconst::dyn_extract<llvm::ConstantInt>(MD->getOperand(0));
-  if (mdID == nullptr || mdID->getLimitedValue() != pix_dxil::PixAllocaReg::ID) {
+  if (mdID == nullptr ||
+      mdID->getLimitedValue() != pix_dxil::PixAllocaReg::ID) {
     return false;
   }
 
-  auto *mdRegNum = llvm::mdconst::dyn_extract<llvm::ConstantInt>(MD->getOperand(1));
-  auto *mdCount = llvm::mdconst::dyn_extract<llvm::ConstantInt>(MD->getOperand(2));
+  auto *mdRegNum =
+      llvm::mdconst::dyn_extract<llvm::ConstantInt>(MD->getOperand(1));
+  auto *mdCount =
+      llvm::mdconst::dyn_extract<llvm::ConstantInt>(MD->getOperand(2));
 
   if (mdRegNum == nullptr || mdCount == nullptr) {
     return false;
@@ -114,16 +129,21 @@ static bool ParsePixAllocaReg(llvm::MDNode *MD, std::uint32_t *RegNum, std::uint
   return true;
 }
 
-void pix_dxil::PixAllocaReg::AddMD(llvm::LLVMContext &Ctx, llvm::AllocaInst *pAlloca, std::uint32_t RegNum, std::uint32_t Count) {
+void pix_dxil::PixAllocaReg::AddMD(llvm::LLVMContext &Ctx,
+                                   llvm::AllocaInst *pAlloca,
+                                   std::uint32_t RegNum, std::uint32_t Count) {
   llvm::IRBuilder<> B(Ctx);
   pAlloca->setMetadata(
       llvm::StringRef(MDName),
-      llvm::MDNode::get(Ctx, { llvm::ConstantAsMetadata::get(B.getInt32(ID)),
-                               llvm::ConstantAsMetadata::get(B.getInt32(RegNum)),
-                               llvm::ConstantAsMetadata::get(B.getInt32(Count)) }));
+      llvm::MDNode::get(Ctx,
+                        {llvm::ConstantAsMetadata::get(B.getInt32(ID)),
+                         llvm::ConstantAsMetadata::get(B.getInt32(RegNum)),
+                         llvm::ConstantAsMetadata::get(B.getInt32(Count))}));
 }
 
-bool pix_dxil::PixAllocaReg::FromInst(llvm::AllocaInst *pAlloca, std::uint32_t *pRegBase, std::uint32_t *pRegSize) {
+bool pix_dxil::PixAllocaReg::FromInst(llvm::AllocaInst *pAlloca,
+                                      std::uint32_t *pRegBase,
+                                      std::uint32_t *pRegSize) {
   *pRegBase = 0;
   *pRegSize = 0;
 
@@ -139,18 +159,21 @@ namespace pix_dxil {
 namespace PixAllocaRegWrite {
 static constexpr uint32_t IndexIsConst = 1;
 static constexpr uint32_t IndexIsPixInst = 2;
-}  // namespace PixAllocaRegWrite
-}  // namespace pix_dxil {
+} // namespace PixAllocaRegWrite
+} // namespace pix_dxil
 
-void pix_dxil::PixAllocaRegWrite::AddMD(llvm::LLVMContext &Ctx, llvm::StoreInst *pSt, llvm::MDNode *pAllocaReg, llvm::Value *Index) {
+void pix_dxil::PixAllocaRegWrite::AddMD(llvm::LLVMContext &Ctx,
+                                        llvm::StoreInst *pSt,
+                                        llvm::MDNode *pAllocaReg,
+                                        llvm::Value *Index) {
   llvm::IRBuilder<> B(Ctx);
   if (auto *C = llvm::dyn_cast<llvm::ConstantInt>(Index)) {
     pSt->setMetadata(
-      llvm::StringRef(MDName),
-      llvm::MDNode::get(Ctx, { llvm::ConstantAsMetadata::get(B.getInt32(ID)),
-                               pAllocaReg,
-                               llvm::ConstantAsMetadata::get(B.getInt32(IndexIsConst)),
-                               llvm::ConstantAsMetadata::get(C) }));
+        llvm::StringRef(MDName),
+        llvm::MDNode::get(
+            Ctx, {llvm::ConstantAsMetadata::get(B.getInt32(ID)), pAllocaReg,
+                  llvm::ConstantAsMetadata::get(B.getInt32(IndexIsConst)),
+                  llvm::ConstantAsMetadata::get(C)}));
   }
 
   if (auto *I = llvm::dyn_cast<llvm::Instruction>(Index)) {
@@ -159,15 +182,18 @@ void pix_dxil::PixAllocaRegWrite::AddMD(llvm::LLVMContext &Ctx, llvm::StoreInst
       return;
     }
     pSt->setMetadata(
-      llvm::StringRef(MDName),
-      llvm::MDNode::get(Ctx, { llvm::ConstantAsMetadata::get(B.getInt32(ID)),
-                               pAllocaReg,
-                               llvm::ConstantAsMetadata::get(B.getInt32(IndexIsPixInst)),
-                               llvm::ConstantAsMetadata::get(B.getInt32(InstNum)) }));
+        llvm::StringRef(MDName),
+        llvm::MDNode::get(
+            Ctx, {llvm::ConstantAsMetadata::get(B.getInt32(ID)), pAllocaReg,
+                  llvm::ConstantAsMetadata::get(B.getInt32(IndexIsPixInst)),
+                  llvm::ConstantAsMetadata::get(B.getInt32(InstNum))}));
   }
 }
 
-bool pix_dxil::PixAllocaRegWrite::FromInst(llvm::StoreInst *pI, std::uint32_t *pRegBase, std::uint32_t *pRegSize, llvm::Value **pIndex) {
+bool pix_dxil::PixAllocaRegWrite::FromInst(llvm::StoreInst *pI,
+                                           std::uint32_t *pRegBase,
+                                           std::uint32_t *pRegSize,
+                                           llvm::Value **pIndex) {
   *pRegBase = 0;
   *pRegSize = 0;
   *pIndex = nullptr;
@@ -177,27 +203,31 @@ bool pix_dxil::PixAllocaRegWrite::FromInst(llvm::StoreInst *pI, std::uint32_t *p
     return false;
   }
 
-  auto *mdID = llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(0));
+  auto *mdID =
+      llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(0));
   if (mdID == nullptr || mdID->getLimitedValue() != ID) {
     return false;
   }
 
   auto *mdAllocaReg = llvm::dyn_cast<llvm::MDNode>(mdNodes->getOperand(1));
-  if (mdAllocaReg == nullptr || !ParsePixAllocaReg(mdAllocaReg, pRegBase, pRegSize)) {
+  if (mdAllocaReg == nullptr ||
+      !ParsePixAllocaReg(mdAllocaReg, pRegBase, pRegSize)) {
     return false;
   }
 
-  auto *mdIndexType = llvm::dyn_cast<llvm::ConstantAsMetadata>(mdNodes->getOperand(2));
+  auto *mdIndexType =
+      llvm::dyn_cast<llvm::ConstantAsMetadata>(mdNodes->getOperand(2));
   if (mdIndexType == nullptr) {
     return false;
   }
 
-  auto* cIndexType = llvm::dyn_cast<llvm::ConstantInt>(mdIndexType->getValue());
+  auto *cIndexType = llvm::dyn_cast<llvm::ConstantInt>(mdIndexType->getValue());
   if (cIndexType == nullptr) {
     return false;
   }
 
-  auto *mdIndex = llvm::dyn_cast<llvm::ConstantAsMetadata>(mdNodes->getOperand(3));
+  auto *mdIndex =
+      llvm::dyn_cast<llvm::ConstantAsMetadata>(mdNodes->getOperand(3));
   if (mdIndex == nullptr) {
     return false;
   }
@@ -217,7 +247,8 @@ bool pix_dxil::PixAllocaRegWrite::FromInst(llvm::StoreInst *pI, std::uint32_t *p
   }
 
   case IndexIsPixInst: {
-    for (llvm::Instruction &I : llvm::inst_range(pI->getParent()->getParent())) {
+    for (llvm::Instruction &I :
+         llvm::inst_range(pI->getParent()->getParent())) {
       uint32_t InstNum;
       if (PixDxilInstNum::FromInst(&I, &InstNum)) {
         *pIndex = &I;

+ 29 - 19
lib/DxilPIXPasses/DxilReduceMSAAToSingleSample.cpp

@@ -9,15 +9,16 @@
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "dxc/HLSL/DxilGenerationPass.h"
 #include "dxc/DXIL/DxilOperations.h"
+
 #include "dxc/DXIL/DxilInstructions.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/DxilPIXPasses/DxilPIXPasses.h"
+#include "dxc/HLSL/DxilGenerationPass.h"
 
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/PassManager.h"
-#include "llvm/IR/Constants.h"
 
 using namespace llvm;
 using namespace hlsl;
@@ -27,43 +28,50 @@ class DxilReduceMSAAToSingleSample : public ModulePass {
 public:
   static char ID; // Pass identification, replacement for typeid
   explicit DxilReduceMSAAToSingleSample() : ModulePass(ID) {}
-  const char *getPassName() const override { return "HLSL DXIL Reduce all MSAA reads to single-sample reads"; }
+  const char *getPassName() const override {
+    return "HLSL DXIL Reduce all MSAA reads to single-sample reads";
+  }
   bool runOnModule(Module &M) override;
 };
 
-bool DxilReduceMSAAToSingleSample::runOnModule(Module &M)
-{
+bool DxilReduceMSAAToSingleSample::runOnModule(Module &M) {
   DxilModule &DM = M.GetOrCreateDxilModule();
 
-  LLVMContext & Ctx = M.getContext();
+  LLVMContext &Ctx = M.getContext();
   OP *HlslOP = DM.GetOP();
 
-  // FP16 type doesn't have its own identity, and is covered by float type... 
-
+  // FP16 type doesn't have its own identity, and is covered by float type...
 
-  auto TextureLoadOverloads = std::vector<Type*>{ Type::getFloatTy(Ctx), Type::getInt16Ty(Ctx), Type::getInt32Ty(Ctx) };
+  auto TextureLoadOverloads = std::vector<Type *>{
+      Type::getFloatTy(Ctx), Type::getInt16Ty(Ctx), Type::getInt32Ty(Ctx)};
 
   bool Modified = false;
 
-  for (const auto & Overload : TextureLoadOverloads) {
+  for (const auto &Overload : TextureLoadOverloads) {
 
-    Function * TexLoadFunction = HlslOP->GetOpFunc(DXIL::OpCode::TextureLoad, Overload);
+    Function *TexLoadFunction =
+        HlslOP->GetOpFunc(DXIL::OpCode::TextureLoad, Overload);
     auto TexLoadFunctionUses = TexLoadFunction->uses();
 
-    for (auto FI = TexLoadFunctionUses.begin(); FI != TexLoadFunctionUses.end(); ) {
-      auto & FunctionUse = *FI++;
+    for (auto FI = TexLoadFunctionUses.begin();
+         FI != TexLoadFunctionUses.end();) {
+      auto &FunctionUse = *FI++;
       auto FunctionUser = FunctionUse.getUser();
       auto instruction = cast<Instruction>(FunctionUser);
       DxilInst_TextureLoad LoadInstruction(instruction);
       auto TextureHandle = LoadInstruction.get_srv();
       auto TextureHandleInst = cast<CallInst>(TextureHandle);
       DxilInst_CreateHandle createHandle(TextureHandleInst);
-      // Dynamic rangeId is not supported 
-      if (isa<ConstantInt>(createHandle.get_rangeId())){
-        unsigned rangeId = cast<ConstantInt>(createHandle.get_rangeId())->getLimitedValue();
-        if (static_cast<DXIL::ResourceClass>(createHandle.get_resourceClass_val()) == DXIL::ResourceClass::SRV) {
+      // Dynamic rangeId is not supported
+      if (isa<ConstantInt>(createHandle.get_rangeId())) {
+        unsigned rangeId =
+            cast<ConstantInt>(createHandle.get_rangeId())->getLimitedValue();
+        if (static_cast<DXIL::ResourceClass>(
+                createHandle.get_resourceClass_val()) ==
+            DXIL::ResourceClass::SRV) {
           auto Resource = DM.GetSRV(rangeId);
-          if (Resource.GetKind() == DXIL::ResourceKind::Texture2DMS || Resource.GetKind() == DXIL::ResourceKind::Texture2DMSArray) {
+          if (Resource.GetKind() == DXIL::ResourceKind::Texture2DMS ||
+              Resource.GetKind() == DXIL::ResourceKind::Texture2DMSArray) {
             // "2" is the mip-level/sample-index operand index:
             // https://github.com/Microsoft/DirectXShaderCompiler/blob/master/docs/DXIL.rst#textureload
             instruction->setOperand(2, HlslOP->GetI32Const(0));
@@ -83,4 +91,6 @@ ModulePass *llvm::createDxilReduceMSAAToSingleSamplePass() {
   return new DxilReduceMSAAToSingleSample();
 }
 
-INITIALIZE_PASS(DxilReduceMSAAToSingleSample, "hlsl-dxil-reduce-msaa-to-single", "HLSL DXIL Reduce all MSAA writes to single-sample writes", false, false)
+INITIALIZE_PASS(DxilReduceMSAAToSingleSample, "hlsl-dxil-reduce-msaa-to-single",
+                "HLSL DXIL Reduce all MSAA writes to single-sample writes",
+                false, false)

+ 15 - 10
lib/DxilPIXPasses/DxilRemoveDiscards.cpp

@@ -9,10 +9,10 @@
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "dxc/HLSL/DxilGenerationPass.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/DXIL/DxilOperations.h"
 #include "dxc/DxilPIXPasses/DxilPIXPasses.h"
+#include "dxc/HLSL/DxilGenerationPass.h"
 
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/PassManager.h"
@@ -25,24 +25,28 @@ class DxilRemoveDiscards : public ModulePass {
 public:
   static char ID; // Pass identification, replacement for typeid
   explicit DxilRemoveDiscards() : ModulePass(ID) {}
-  const char *getPassName() const override { return "DXIL Remove all discard instructions"; }
+  const char *getPassName() const override {
+    return "DXIL Remove all discard instructions";
+  }
   bool runOnModule(Module &M) override;
 };
 
-bool DxilRemoveDiscards::runOnModule(Module &M)
-{
-  // This pass removes all instances of the discard instruction within the shader.
+bool DxilRemoveDiscards::runOnModule(Module &M) {
+  // This pass removes all instances of the discard instruction within the
+  // shader.
   DxilModule &DM = M.GetOrCreateDxilModule();
 
-  LLVMContext & Ctx = M.getContext();
+  LLVMContext &Ctx = M.getContext();
   OP *HlslOP = DM.GetOP();
-  Function * DiscardFunction = HlslOP->GetOpFunc(DXIL::OpCode::Discard, Type::getVoidTy(Ctx));
+  Function *DiscardFunction =
+      HlslOP->GetOpFunc(DXIL::OpCode::Discard, Type::getVoidTy(Ctx));
   auto DiscardFunctionUses = DiscardFunction->uses();
 
   bool Modified = false;
 
-  for (auto FI = DiscardFunctionUses.begin(); FI != DiscardFunctionUses.end(); ) {
-    auto & FunctionUse = *FI++;
+  for (auto FI = DiscardFunctionUses.begin();
+       FI != DiscardFunctionUses.end();) {
+    auto &FunctionUse = *FI++;
     auto FunctionUser = FunctionUse.getUser();
     auto instruction = cast<Instruction>(FunctionUser);
     instruction->eraseFromParent();
@@ -58,4 +62,5 @@ ModulePass *llvm::createDxilRemoveDiscardsPass() {
   return new DxilRemoveDiscards();
 }
 
-INITIALIZE_PASS(DxilRemoveDiscards, "hlsl-dxil-remove-discards", "HLSL DXIL Remove all discard instructions", false, false)
+INITIALIZE_PASS(DxilRemoveDiscards, "hlsl-dxil-remove-discards",
+                "HLSL DXIL Remove all discard instructions", false, false)

+ 218 - 155
lib/DxilPIXPasses/DxilShaderAccessTracking.cpp

@@ -10,11 +10,12 @@
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "dxc/HLSL/DxilGenerationPass.h"
 #include "dxc/DXIL/DxilOperations.h"
+
 #include "dxc/DXIL/DxilInstructions.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/DxilPIXPasses/DxilPIXPasses.h"
+#include "dxc/HLSL/DxilGenerationPass.h"
 #include "dxc/HLSL/DxilSpanAllocator.h"
 
 #include "llvm/IR/PassManager.h"
@@ -29,9 +30,7 @@
 using namespace llvm;
 using namespace hlsl;
 
-
-void ThrowIf(bool a)
-{
+void ThrowIf(bool a) {
   if (a) {
     throw ::hlsl::Exception(E_INVALIDARG);
   }
@@ -40,19 +39,20 @@ void ThrowIf(bool a)
 //---------------------------------------------------------------------------------------------------------------------------------
 // These types are taken from PIX's ShaderAccessHelpers.h
 
-enum class ShaderAccessFlags : uint32_t
-{
+enum class ShaderAccessFlags : uint32_t {
   None = 0,
   Read = 1 << 0,
   Write = 1 << 1,
 
-  // "Counter" access is only applicable to UAVs; it means the counter buffer attached to the UAV
-  // was accessed, but not necessarily the UAV resource.
+  // "Counter" access is only applicable to UAVs; it means the counter buffer
+  // attached to the UAV was accessed, but not necessarily the UAV resource.
   Counter = 1 << 2,
 
   // Descriptor-only read (if any), but not the resource contents (if any).
-  // Used for GetDimensions, samplers, and secondary texture for sampler feedback.
-  // TODO: Make this a unique value if supported in PIX, then enable GetDimensions
+  // Used for GetDimensions, samplers, and secondary texture for sampler
+  // feedback.
+  // TODO: Make this a unique value if supported in PIX, then enable
+  // GetDimensions
   DescriptorRead = 1 << 0,
 };
 
@@ -72,16 +72,16 @@ static uint32_t OffsetFromAccess(ShaderAccessFlags access) {
   }
 }
 
-// This enum doesn't have to match PIX's version, because the values are received from PIX encoded in ASCII.
-// However, for ease of comparing this code with PIX, and to be less confusing to future maintainers, this
-// enum does indeed match the same-named enum in PIX.
-enum class RegisterType
-{
+// This enum doesn't have to match PIX's version, because the values are
+// received from PIX encoded in ASCII. However, for ease of comparing this code
+// with PIX, and to be less confusing to future maintainers, this enum does
+// indeed match the same-named enum in PIX.
+enum class RegisterType {
   CBV,
   SRV,
   UAV,
-  RTV, // not used. 
-  DSV, // not used. 
+  RTV, // not used.
+  DSV, // not used.
   Sampler,
   SOV, // not used.
   Invalid,
@@ -89,46 +89,51 @@ enum class RegisterType
 };
 
 RegisterType RegisterTypeFromResourceClass(DXIL::ResourceClass c) {
-  switch (c)
-  {
-  case DXIL::ResourceClass::SRV    : return RegisterType::SRV    ; break;
-  case DXIL::ResourceClass::UAV    : return RegisterType::UAV    ; break;
-  case DXIL::ResourceClass::CBuffer: return RegisterType::CBV    ; break;
-  case DXIL::ResourceClass::Sampler: return RegisterType::Sampler; break;
-  case DXIL::ResourceClass::Invalid: return RegisterType::Invalid; break;
+  switch (c) {
+  case DXIL::ResourceClass::SRV:
+    return RegisterType::SRV;
+    break;
+  case DXIL::ResourceClass::UAV:
+    return RegisterType::UAV;
+    break;
+  case DXIL::ResourceClass::CBuffer:
+    return RegisterType::CBV;
+    break;
+  case DXIL::ResourceClass::Sampler:
+    return RegisterType::Sampler;
+    break;
+  case DXIL::ResourceClass::Invalid:
+    return RegisterType::Invalid;
+    break;
   default:
     ThrowIf(true);
     return RegisterType::Invalid;
   }
 }
 
-struct RegisterTypeAndSpace
-{
-  bool operator < (const RegisterTypeAndSpace & o) const {
+struct RegisterTypeAndSpace {
+  bool operator<(const RegisterTypeAndSpace &o) const {
     return static_cast<int>(Type) < static_cast<int>(o.Type) ||
-      (static_cast<int>(Type) == static_cast<int>(o.Type) && Space < o.Space);
+           (static_cast<int>(Type) == static_cast<int>(o.Type) &&
+            Space < o.Space);
   }
   RegisterType Type;
-  unsigned     Space;
+  unsigned Space;
 };
 
 // Identifies a bind point as defined by the root signature
-struct RSRegisterIdentifier
-{
+struct RSRegisterIdentifier {
   RegisterType Type;
-  unsigned     Space;
-  unsigned     Index;
-
-  bool operator < (const RSRegisterIdentifier & o) const {
-    return
-      static_cast<unsigned>(Type) < static_cast<unsigned>(o.Type) &&
-      Space < o.Space &&
-      Index < o.Index;
+  unsigned Space;
+  unsigned Index;
+
+  bool operator<(const RSRegisterIdentifier &o) const {
+    return static_cast<unsigned>(Type) < static_cast<unsigned>(o.Type) &&
+           Space < o.Space && Index < o.Index;
   }
 };
 
-struct SlotRange
-{
+struct SlotRange {
   unsigned startSlot;
   unsigned numSlots;
 
@@ -136,10 +141,9 @@ struct SlotRange
   unsigned numInvariableSlots;
 };
 
-
 struct DxilResourceAndClass {
-  DxilResourceBase * resource;
-  Value * index;
+  DxilResourceBase *resource;
+  Value *index;
   DXIL::ResourceClass resClass;
 };
 
@@ -149,26 +153,30 @@ class DxilShaderAccessTracking : public ModulePass {
 public:
   static char ID; // Pass identification, replacement for typeid
   explicit DxilShaderAccessTracking() : ModulePass(ID) {}
-  const char *getPassName() const override { return "DXIL shader access tracking"; }
+  const char *getPassName() const override {
+    return "DXIL shader access tracking";
+  }
   bool runOnModule(Module &M) override;
   void applyOptions(PassOptions O) override;
 
 private:
-  void EmitAccess(LLVMContext & Ctx, OP *HlslOP, IRBuilder<> &, Value *slot, ShaderAccessFlags access);
-  bool EmitResourceAccess(DxilResourceAndClass &res, Instruction * instruction, OP * HlslOP, LLVMContext & Ctx, ShaderAccessFlags readWrite);
+  void EmitAccess(LLVMContext &Ctx, OP *HlslOP, IRBuilder<> &, Value *slot,
+                  ShaderAccessFlags access);
+  bool EmitResourceAccess(DxilResourceAndClass &res, Instruction *instruction,
+                          OP *HlslOP, LLVMContext &Ctx,
+                          ShaderAccessFlags readWrite);
 
 private:
   bool m_CheckForDynamicIndexing = false;
   std::map<RegisterTypeAndSpace, SlotRange> m_slotAssignments;
-  std::map<llvm::Function*, CallInst *> m_FunctionToUAVHandle;
+  std::map<llvm::Function *, CallInst *> m_FunctionToUAVHandle;
   std::set<RSRegisterIdentifier> m_DynamicallyIndexedBindPoints;
 };
 
-static unsigned DeserializeInt(std::deque<char> & q) {
+static unsigned DeserializeInt(std::deque<char> &q) {
   unsigned i = 0;
 
-  while(!q.empty() && isdigit(q.front()))
-  {
+  while (!q.empty() && isdigit(q.front())) {
     i *= 10;
     i += q.front() - '0';
     q.pop_front();
@@ -176,38 +184,47 @@ static unsigned DeserializeInt(std::deque<char> & q) {
   return i;
 }
 
-static char DequeFront(std::deque<char> & q) {
+static char DequeFront(std::deque<char> &q) {
   ThrowIf(q.empty());
   auto c = q.front();
   q.pop_front();
   return c;
 }
 
-static RegisterType ParseRegisterType(std::deque<char> & q) {
-  switch (DequeFront(q))
-  {
-  case 'C': return RegisterType::CBV;
-  case 'S': return RegisterType::SRV;
-  case 'U': return RegisterType::UAV;
-  case 'M': return RegisterType::Sampler;
-  case 'I': return RegisterType::Invalid;
-  default: return RegisterType::Terminator;
+static RegisterType ParseRegisterType(std::deque<char> &q) {
+  switch (DequeFront(q)) {
+  case 'C':
+    return RegisterType::CBV;
+  case 'S':
+    return RegisterType::SRV;
+  case 'U':
+    return RegisterType::UAV;
+  case 'M':
+    return RegisterType::Sampler;
+  case 'I':
+    return RegisterType::Invalid;
+  default:
+    return RegisterType::Terminator;
   }
 }
 
 static char EncodeRegisterType(RegisterType r) {
-  switch (r)
-  {
-  case RegisterType::CBV:     return 'C';
-  case RegisterType::SRV:     return 'S';
-  case RegisterType::UAV:     return 'U';
-  case RegisterType::Sampler: return 'M';
-  case RegisterType::Invalid: return 'I';
+  switch (r) {
+  case RegisterType::CBV:
+    return 'C';
+  case RegisterType::SRV:
+    return 'S';
+  case RegisterType::UAV:
+    return 'U';
+  case RegisterType::Sampler:
+    return 'M';
+  case RegisterType::Invalid:
+    return 'I';
   }
   return '.';
 }
 
-static void ValidateDelimiter(std::deque<char> & q, char d) {
+static void ValidateDelimiter(std::deque<char> &q, char d) {
   ThrowIf(q.front() != d);
   q.pop_front();
 }
@@ -222,7 +239,8 @@ void DxilShaderAccessTracking::applyOptions(PassOptions O) {
     std::deque<char> config;
     config.assign(configOption.begin(), configOption.end());
 
-    // Parse slot assignments. Compare with PIX's ShaderAccessHelpers.cpp (TrackingConfiguration::SerializedRepresentation)
+    // Parse slot assignments. Compare with PIX's ShaderAccessHelpers.cpp
+    // (TrackingConfiguration::SerializedRepresentation)
     RegisterType rt = ParseRegisterType(config);
     while (rt != RegisterType::Terminator) {
 
@@ -253,65 +271,87 @@ void DxilShaderAccessTracking::EmitAccess(LLVMContext &Ctx, OP *HlslOP,
                                           IRBuilder<> &Builder,
                                           Value *ByteIndex,
                                           ShaderAccessFlags access) {
-  
-  unsigned OffsetForAccessType = static_cast<unsigned>(OffsetFromAccess(access) * BytesPerDWORD);
-  auto OffsetByteIndex = Builder.CreateAdd(ByteIndex, HlslOP->GetU32Const(OffsetForAccessType), "OffsetByteIndex");
-
-  UndefValue* UndefIntArg = UndefValue::get(Type::getInt32Ty(Ctx));
-  Constant* LiteralOne = HlslOP->GetU32Const(1);
-  Constant* ElementMask = HlslOP->GetI8Const(1);
-
-  Function* StoreFunc = HlslOP->GetOpFunc(OP::OpCode::BufferStore, Type::getInt32Ty(Ctx));
-  Constant* StoreOpcode = HlslOP->GetU32Const((unsigned)OP::OpCode::BufferStore);
-  (void)Builder.CreateCall(StoreFunc, {
-      StoreOpcode,       // i32, ; opcode
-      m_FunctionToUAVHandle.at(Builder.GetInsertBlock()->getParent()), // %dx.types.Handle, ; resource handle
-      OffsetByteIndex,   // i32, ; coordinate c0: byte offset
-      UndefIntArg,       // i32, ; coordinate c1 (unused)
-      LiteralOne,        // i32, ; value v0
-      UndefIntArg,       // i32, ; value v1
-      UndefIntArg,       // i32, ; value v2
-      UndefIntArg,       // i32, ; value v3
-      ElementMask        // i8 ; just the first value is used
-  });
+
+  unsigned OffsetForAccessType =
+      static_cast<unsigned>(OffsetFromAccess(access) * BytesPerDWORD);
+  auto OffsetByteIndex = Builder.CreateAdd(
+      ByteIndex, HlslOP->GetU32Const(OffsetForAccessType), "OffsetByteIndex");
+
+  UndefValue *UndefIntArg = UndefValue::get(Type::getInt32Ty(Ctx));
+  Constant *LiteralOne = HlslOP->GetU32Const(1);
+  Constant *ElementMask = HlslOP->GetI8Const(1);
+
+  Function *StoreFunc =
+      HlslOP->GetOpFunc(OP::OpCode::BufferStore, Type::getInt32Ty(Ctx));
+  Constant *StoreOpcode =
+      HlslOP->GetU32Const((unsigned)OP::OpCode::BufferStore);
+  (void)Builder.CreateCall(
+      StoreFunc,
+      {
+          StoreOpcode, // i32, ; opcode
+          m_FunctionToUAVHandle.at(
+              Builder.GetInsertBlock()
+                  ->getParent()), // %dx.types.Handle, ; resource handle
+          OffsetByteIndex,        // i32, ; coordinate c0: byte offset
+          UndefIntArg,            // i32, ; coordinate c1 (unused)
+          LiteralOne,             // i32, ; value v0
+          UndefIntArg,            // i32, ; value v1
+          UndefIntArg,            // i32, ; value v2
+          UndefIntArg,            // i32, ; value v3
+          ElementMask             // i8 ; just the first value is used
+      });
 }
 
-bool DxilShaderAccessTracking::EmitResourceAccess(DxilResourceAndClass &res, Instruction * instruction, OP * HlslOP, LLVMContext & Ctx, ShaderAccessFlags readWrite) {
+bool DxilShaderAccessTracking::EmitResourceAccess(DxilResourceAndClass &res,
+                                                  Instruction *instruction,
+                                                  OP *HlslOP, LLVMContext &Ctx,
+                                                  ShaderAccessFlags readWrite) {
 
-  RegisterTypeAndSpace typeAndSpace{ RegisterTypeFromResourceClass(res.resClass), res.resource->GetSpaceID() };
+  RegisterTypeAndSpace typeAndSpace{RegisterTypeFromResourceClass(res.resClass),
+                                    res.resource->GetSpaceID()};
 
   auto slot = m_slotAssignments.find(typeAndSpace);
   // If the assignment isn't found, we assume it's not accessed
   if (slot != m_slotAssignments.end()) {
 
     IRBuilder<> Builder(instruction);
-    Value * slotIndex;
+    Value *slotIndex;
 
     if (isa<ConstantInt>(res.index)) {
       unsigned index = cast<ConstantInt>(res.index)->getLimitedValue();
       if (index > slot->second.numSlots) {
         // out-of-range accesses are written to slot zero:
         slotIndex = HlslOP->GetU32Const(0);
+      } else {
+        slotIndex = HlslOP->GetU32Const((slot->second.startSlot + index) *
+                                        DWORDsPerResource * BytesPerDWORD);
       }
-      else {
-        slotIndex = HlslOP->GetU32Const((slot->second.startSlot + index) * DWORDsPerResource * BytesPerDWORD);
-      }
-    }
-    else {
-      RSRegisterIdentifier id{ typeAndSpace.Type, typeAndSpace.Space,  res.resource->GetID() };
+    } else {
+      RSRegisterIdentifier id{typeAndSpace.Type, typeAndSpace.Space,
+                              res.resource->GetID()};
       m_DynamicallyIndexedBindPoints.emplace(std::move(id));
 
-
-      // CompareWithSlotLimit will contain 1 if the access is out-of-bounds (both over- and and under-flow 
-      // via the unsigned >= with slot count)
-      auto CompareWithSlotLimit = Builder.CreateICmpUGE(res.index, HlslOP->GetU32Const(slot->second.numSlots), "CompareWithSlotLimit");
-      auto CompareWithSlotLimitAsUint = Builder.CreateCast(Instruction::CastOps::ZExt, CompareWithSlotLimit, Type::getInt32Ty(Ctx), "CompareWithSlotLimitAsUint");
-
-      // IsInBounds will therefore contain 0 if the access is out-of-bounds, and 1 otherwise.
-      auto IsInBounds = Builder.CreateSub(HlslOP->GetU32Const(1), CompareWithSlotLimitAsUint, "IsInBounds");
-
-      auto SlotDwordOffset = Builder.CreateAdd(res.index, HlslOP->GetU32Const(slot->second.startSlot), "SlotDwordOffset");
-      auto SlotByteOffset = Builder.CreateMul(SlotDwordOffset, HlslOP->GetU32Const(DWORDsPerResource * BytesPerDWORD),"SlotByteOffset");
+      // CompareWithSlotLimit will contain 1 if the access is out-of-bounds
+      // (both over- and and under-flow via the unsigned >= with slot count)
+      auto CompareWithSlotLimit = Builder.CreateICmpUGE(
+          res.index, HlslOP->GetU32Const(slot->second.numSlots),
+          "CompareWithSlotLimit");
+      auto CompareWithSlotLimitAsUint = Builder.CreateCast(
+          Instruction::CastOps::ZExt, CompareWithSlotLimit,
+          Type::getInt32Ty(Ctx), "CompareWithSlotLimitAsUint");
+
+      // IsInBounds will therefore contain 0 if the access is out-of-bounds, and
+      // 1 otherwise.
+      auto IsInBounds = Builder.CreateSub(
+          HlslOP->GetU32Const(1), CompareWithSlotLimitAsUint, "IsInBounds");
+
+      auto SlotDwordOffset = Builder.CreateAdd(
+          res.index, HlslOP->GetU32Const(slot->second.startSlot),
+          "SlotDwordOffset");
+      auto SlotByteOffset = Builder.CreateMul(
+          SlotDwordOffset,
+          HlslOP->GetU32Const(DWORDsPerResource * BytesPerDWORD),
+          "SlotByteOffset");
 
       // This will drive an out-of-bounds access slot down to 0
       slotIndex = Builder.CreateMul(SlotByteOffset, IsInBounds, "slotIndex");
@@ -324,24 +364,23 @@ bool DxilShaderAccessTracking::EmitResourceAccess(DxilResourceAndClass &res, Ins
   return false; // did not modify
 }
 
+DxilResourceAndClass GetResourceFromHandle(Value *resHandle, DxilModule &DM) {
 
-DxilResourceAndClass GetResourceFromHandle(Value * resHandle, DxilModule &DM) {
-
-  DxilResourceAndClass ret{ nullptr, nullptr, DXIL::ResourceClass::Invalid };
+  DxilResourceAndClass ret{nullptr, nullptr, DXIL::ResourceClass::Invalid};
 
   CallInst *handle = cast<CallInst>(resHandle);
   DxilInst_CreateHandle createHandle(handle);
 
-
   // Dynamic rangeId is not supported - skip and let validation report the
   // error.
   if (!isa<ConstantInt>(createHandle.get_rangeId()))
     return ret;
 
   unsigned rangeId =
-    cast<ConstantInt>(createHandle.get_rangeId())->getLimitedValue();
+      cast<ConstantInt>(createHandle.get_rangeId())->getLimitedValue();
 
-  auto resClass = static_cast<DXIL::ResourceClass>(createHandle.get_resourceClass_val());
+  auto resClass =
+      static_cast<DXIL::ResourceClass>(createHandle.get_resourceClass_val());
 
   switch (resClass) {
   case DXIL::ResourceClass::SRV:
@@ -367,12 +406,11 @@ DxilResourceAndClass GetResourceFromHandle(Value * resHandle, DxilModule &DM) {
   return ret;
 }
 
-bool DxilShaderAccessTracking::runOnModule(Module &M)
-{
+bool DxilShaderAccessTracking::runOnModule(Module &M) {
   // This pass adds instrumentation for shader access to resources
 
   DxilModule &DM = M.GetOrCreateDxilModule();
-  LLVMContext & Ctx = M.getContext();
+  LLVMContext &Ctx = M.getContext();
   OP *HlslOP = DM.GetOP();
 
   bool Modified = false;
@@ -381,13 +419,14 @@ bool DxilShaderAccessTracking::runOnModule(Module &M)
 
     bool FoundDynamicIndexing = false;
 
-    auto CreateHandleFn = HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
+    auto CreateHandleFn =
+        HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
     auto CreateHandleUses = CreateHandleFn->uses();
-    for (auto FI = CreateHandleUses.begin(); FI != CreateHandleUses.end(); ) {
-      auto & FunctionUse = *FI++;
+    for (auto FI = CreateHandleUses.begin(); FI != CreateHandleUses.end();) {
+      auto &FunctionUse = *FI++;
       auto FunctionUser = FunctionUse.getUser();
       auto instruction = cast<Instruction>(FunctionUser);
-      Value * index = instruction->getOperand(3);
+      Value *index = instruction->getOperand(3);
       if (!isa<Constant>(index)) {
         FoundDynamicIndexing = true;
         break;
@@ -400,8 +439,7 @@ bool DxilShaderAccessTracking::runOnModule(Module &M)
         FOS << "FoundDynamicIndexing";
       }
     }
-  }
-  else {
+  } else {
     {
       if (DM.m_ShaderFlags.GetForceEarlyDepthStencil()) {
         if (OSOverride != nullptr) {
@@ -410,20 +448,24 @@ bool DxilShaderAccessTracking::runOnModule(Module &M)
         }
       }
 
-      for (llvm::Function & F : M.functions()) {
+      for (llvm::Function &F : M.functions()) {
         if (!F.getBasicBlockList().empty()) {
           IRBuilder<> Builder(F.getEntryBlock().getFirstInsertionPt());
 
-          unsigned int UAVResourceHandle = static_cast<unsigned int>(DM.GetUAVs().size());
+          unsigned int UAVResourceHandle =
+              static_cast<unsigned int>(DM.GetUAVs().size());
 
           // Set up a UAV with structure of a single int
-          SmallVector<llvm::Type*, 1> Elements{ Type::getInt32Ty(Ctx) };
-          llvm::StructType *UAVStructTy = llvm::StructType::create(Elements, "class.RWStructuredBuffer");
-          std::unique_ptr<DxilResource> pUAV = llvm::make_unique<DxilResource>();
+          SmallVector<llvm::Type *, 1> Elements{Type::getInt32Ty(Ctx)};
+          llvm::StructType *UAVStructTy =
+              llvm::StructType::create(Elements, "class.RWStructuredBuffer");
+          std::unique_ptr<DxilResource> pUAV =
+              llvm::make_unique<DxilResource>();
           pUAV->SetGlobalName("PIX_CountUAVName");
           pUAV->SetGlobalSymbol(UndefValue::get(UAVStructTy->getPointerTo()));
           pUAV->SetID(UAVResourceHandle);
-          pUAV->SetSpaceID((unsigned int)-2); // This is the reserved-for-tools register space
+          pUAV->SetSpaceID((
+              unsigned int)-2); // This is the reserved-for-tools register space
           pUAV->SetSampleCount(1);
           pUAV->SetGloballyCoherent(false);
           pUAV->SetHasCounter(false);
@@ -432,12 +474,14 @@ bool DxilShaderAccessTracking::runOnModule(Module &M)
           pUAV->SetRangeSize(1);
           pUAV->SetKind(DXIL::ResourceKind::RawBuffer);
 
-          auto pAnnotation = DM.GetTypeSystem().GetStructAnnotation(UAVStructTy);
+          auto pAnnotation =
+              DM.GetTypeSystem().GetStructAnnotation(UAVStructTy);
           if (pAnnotation == nullptr) {
 
             pAnnotation = DM.GetTypeSystem().AddStructAnnotation(UAVStructTy);
             pAnnotation->GetFieldAnnotation(0).SetCBufferOffset(0);
-            pAnnotation->GetFieldAnnotation(0).SetCompType(hlsl::DXIL::ComponentType::I32);
+            pAnnotation->GetFieldAnnotation(0).SetCompType(
+                hlsl::DXIL::ComponentType::I32);
             pAnnotation->GetFieldAnnotation(0).SetFieldName("count");
           }
 
@@ -446,28 +490,40 @@ bool DxilShaderAccessTracking::runOnModule(Module &M)
           assert((unsigned)ID == UAVResourceHandle);
 
           // Create handle for the newly-added UAV
-          Function* CreateHandleOpFunc = HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
-          Constant* CreateHandleOpcodeArg = HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
-          Constant* UAVArg = HlslOP->GetI8Const(static_cast<std::underlying_type<DxilResourceBase::Class>::type>(DXIL::ResourceClass::UAV));
-          Constant* MetaDataArg = HlslOP->GetU32Const(ID); // position of the metadata record in the corresponding metadata list
-          Constant* IndexArg = HlslOP->GetU32Const(0); // 
-          Constant* FalseArg = HlslOP->GetI1Const(0); // non-uniform resource index: false
-          m_FunctionToUAVHandle[&F] = Builder.CreateCall(CreateHandleOpFunc,
-            { CreateHandleOpcodeArg, UAVArg, MetaDataArg, IndexArg, FalseArg }, "PIX_CountUAV_Handle");
+          Function *CreateHandleOpFunc = HlslOP->GetOpFunc(
+              DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
+          Constant *CreateHandleOpcodeArg =
+              HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
+          Constant *UAVArg = HlslOP->GetI8Const(
+              static_cast<std::underlying_type<DxilResourceBase::Class>::type>(
+                  DXIL::ResourceClass::UAV));
+          Constant *MetaDataArg =
+              HlslOP->GetU32Const(ID); // position of the metadata record in the
+                                       // corresponding metadata list
+          Constant *IndexArg = HlslOP->GetU32Const(0); //
+          Constant *FalseArg =
+              HlslOP->GetI1Const(0); // non-uniform resource index: false
+          m_FunctionToUAVHandle[&F] = Builder.CreateCall(
+              CreateHandleOpFunc,
+              {CreateHandleOpcodeArg, UAVArg, MetaDataArg, IndexArg, FalseArg},
+              "PIX_CountUAV_Handle");
         }
       }
       DM.ReEmitDxilResources();
     }
 
-    for (llvm::Function & F : M.functions()) {
+    for (llvm::Function &F : M.functions()) {
       // Only used DXIL intrinsics:
-      if (!F.isDeclaration() || F.isIntrinsic() || F.use_empty() || !OP::IsDxilOpFunc(&F))
+      if (!F.isDeclaration() || F.isIntrinsic() || F.use_empty() ||
+          !OP::IsDxilOpFunc(&F))
         continue;
 
       // Gather handle parameter indices, if any
-      FunctionType *fnTy = cast<FunctionType>(F.getType()->getPointerElementType());
+      FunctionType *fnTy =
+          cast<FunctionType>(F.getType()->getPointerElementType());
       SmallVector<unsigned, 4> handleParams;
-      for (unsigned iParam = 1; iParam < fnTy->getFunctionNumParams(); ++iParam) {
+      for (unsigned iParam = 1; iParam < fnTy->getFunctionNumParams();
+           ++iParam) {
         if (fnTy->getParamType(iParam) == HlslOP->GetHandleType())
           handleParams.push_back(iParam);
       }
@@ -475,13 +531,14 @@ bool DxilShaderAccessTracking::runOnModule(Module &M)
         continue;
 
       auto FunctionUses = F.uses();
-      for (auto FI = FunctionUses.begin(); FI != FunctionUses.end(); ) {
-        auto & FunctionUse = *FI++;
+      for (auto FI = FunctionUses.begin(); FI != FunctionUses.end();) {
+        auto &FunctionUse = *FI++;
         auto FunctionUser = FunctionUse.getUser();
         auto Call = cast<CallInst>(FunctionUser);
         auto opCode = OP::GetDxilOpFuncCallInst(Call);
 
-        // Base Read/Write on function attribute - should match for all normal resource operations
+        // Base Read/Write on function attribute - should match for all normal
+        // resource operations
         ShaderAccessFlags readWrite = ShaderAccessFlags::Write;
         if (OP::GetMemAccessAttr(opCode) == llvm::Attribute::AttrKind::ReadOnly)
           readWrite = ShaderAccessFlags::Read;
@@ -489,7 +546,8 @@ bool DxilShaderAccessTracking::runOnModule(Module &M)
         // Special cases
         switch (opCode) {
         case DXIL::OpCode::GetDimensions:
-          // readWrite = ShaderAccessFlags::DescriptorRead;  // TODO: Support GetDimensions
+          // readWrite = ShaderAccessFlags::DescriptorRead;  // TODO: Support
+          // GetDimensions
           continue;
         case DXIL::OpCode::BufferUpdateCounter:
           readWrite = ShaderAccessFlags::Counter;
@@ -497,7 +555,8 @@ bool DxilShaderAccessTracking::runOnModule(Module &M)
         case DXIL::OpCode::TraceRay:
         case DXIL::OpCode::RayQuery_TraceRayInline:
           // Read of AccelerationStructure; doesn't match function attribute
-          // readWrite = ShaderAccessFlags::Read;  // TODO: Support TraceRay[Inline]
+          // readWrite = ShaderAccessFlags::Read;  // TODO: Support
+          // TraceRay[Inline]
           continue;
         default:
           break;
@@ -506,7 +565,8 @@ bool DxilShaderAccessTracking::runOnModule(Module &M)
         for (unsigned iParam : handleParams) {
           auto res = GetResourceFromHandle(Call->getArgOperand(iParam), DM);
           // Don't instrument the accesses to the UAV that we just added
-          if (res.resClass == DXIL::ResourceClass::UAV && res.resource->GetSpaceID() == (unsigned)-2) {
+          if (res.resClass == DXIL::ResourceClass::UAV &&
+              res.resource->GetSpaceID() == (unsigned)-2) {
             break;
           }
           if (EmitResourceAccess(res, Call, HlslOP, Ctx, readWrite)) {
@@ -521,8 +581,9 @@ bool DxilShaderAccessTracking::runOnModule(Module &M)
     if (OSOverride != nullptr) {
       formatted_raw_ostream FOS(*OSOverride);
       FOS << "DynamicallyIndexedBindPoints=";
-      for (auto const & bp : m_DynamicallyIndexedBindPoints) {
-        FOS << EncodeRegisterType(bp.Type) << bp.Space << ':' << bp.Index <<';';
+      for (auto const &bp : m_DynamicallyIndexedBindPoints) {
+        FOS << EncodeRegisterType(bp.Type) << bp.Space << ':' << bp.Index
+            << ';';
       }
       FOS << ".";
     }
@@ -537,4 +598,6 @@ ModulePass *llvm::createDxilShaderAccessTrackingPass() {
   return new DxilShaderAccessTracking();
 }
 
-INITIALIZE_PASS(DxilShaderAccessTracking, "hlsl-dxil-pix-shader-access-instrumentation", "HLSL DXIL shader access tracking for PIX", false, false)
+INITIALIZE_PASS(DxilShaderAccessTracking,
+                "hlsl-dxil-pix-shader-access-instrumentation",
+                "HLSL DXIL shader access tracking for PIX", false, false)

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно