Browse Source

Code cleanup. (#469)

1. Move DxilEmitMetadata out of DxilGenerationPass.cpp
2. Move helper function out of HLModule.
Xiang Li 8 years ago
parent
commit
96c9c0597c

+ 34 - 0
include/dxc/HLSL/DxilUtil.h

@@ -0,0 +1,34 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// DxilUtil.h                                                                //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Dxil helper functions.                                                    //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+namespace llvm {
+class Type;
+class GlobalVariable;
+}
+
+namespace hlsl {
+
+class DxilFieldAnnotation;
+class DxilTypeSystem;
+
+namespace dxilutil {
+  unsigned
+  GetLegacyCBufferFieldElementSize(DxilFieldAnnotation &fieldAnnotation,
+                                   llvm::Type *Ty, DxilTypeSystem &typeSys);
+  llvm::Type *GetArrayEltTy(llvm::Type *Ty);
+
+  bool IsStaticGlobal(llvm::GlobalVariable *GV);
+  bool IsSharedMemoryGlobal(llvm::GlobalVariable *GV);
+}
+
+}

+ 0 - 7
include/dxc/HLSL/HLModule.h

@@ -154,13 +154,6 @@ public:
   static bool IsStreamOutputPtrType(llvm::Type *Ty);
   static bool IsStreamOutputType(llvm::Type *Ty);
   static bool IsHLSLObjectType(llvm::Type *Ty);
-  static unsigned
-  GetLegacyCBufferFieldElementSize(DxilFieldAnnotation &fieldAnnotation,
-                                   llvm::Type *Ty, DxilTypeSystem &typeSys);
-  static llvm::Type *GetArrayEltTy(llvm::Type *Ty);
-
-  static bool IsStaticGlobal(llvm::GlobalVariable *GV);
-  static bool IsSharedMemoryGlobal(llvm::GlobalVariable *GV);
   static void GetParameterRowsAndCols(llvm::Type *Ty, unsigned &rows, unsigned &cols,
                                       DxilParameterAnnotation &paramAnnotation);
   static const char *GetLegacyDataLayoutDesc();

+ 2 - 0
lib/HLSL/CMakeLists.txt

@@ -20,6 +20,7 @@ add_llvm_library(LLVMHLSL
   DxilModule.cpp
   DxilOperations.cpp
   DxilOutputColorBecomesConstant.cpp
+  DxilPreparePasses.cpp
   DxilRemoveDiscards.cpp
   DxilReduceMSAAToSingleSample.cpp
   DxilPreserveAllOutputs.cpp
@@ -32,6 +33,7 @@ add_llvm_library(LLVMHLSL
   DxilSignature.cpp
   DxilSignatureElement.cpp
   DxilTypeSystem.cpp
+  DxilUtil.cpp
   DxilValidation.cpp
   DxcOptimizer.cpp
   HLMatrixLowerPass.cpp

+ 3 - 330
lib/HLSL/DxilGenerationPass.cpp

@@ -20,6 +20,7 @@
 #include "dxc/HLSL/DxilTypeSystem.h"
 #include "dxc/HLSL/HLOperationLower.h"
 #include "HLSignatureLower.h"
+#include "dxc/HLSL/DxilUtil.h"
 
 #include "llvm/IR/GetElementPtrTypeIterator.h"
 #include "llvm/IR/IRBuilder.h"
@@ -31,7 +32,6 @@
 #include "llvm/IR/PassManager.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/Pass.h"
-#include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Transforms/Utils/SSAUpdater.h"
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Transforms/Utils/PromoteMemToReg.h"
@@ -328,33 +328,6 @@ private:
   // Input module is not optimized.
   bool NotOptimized;
 };
-
-class SimplifyInst : public FunctionPass {
-public:
-  static char ID;
-
-  SimplifyInst() : FunctionPass(ID) {
-    initializeScalarizerPass(*PassRegistry::getPassRegistry());
-  }
-
-  bool runOnFunction(Function &F) override;
-
-private:
-};
-}
-
-char SimplifyInst::ID = 0;
-
-FunctionPass *llvm::createSimplifyInstPass() { return new SimplifyInst(); }
-
-INITIALIZE_PASS(SimplifyInst, "simplify-inst", "Simplify Instructions", false, false)
-
-bool SimplifyInst::runOnFunction(Function &F) {
-  for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) {
-    BasicBlock *BB = BBI;
-    llvm::SimplifyInstructionsInBlock(BB, nullptr);
-  }
-  return true;
 }
 
 static Value *MergeImmResClass(Value *resClass) {
@@ -1329,306 +1302,6 @@ ModulePass *llvm::createHLEnsureMetadataPass() {
 
 INITIALIZE_PASS(HLEnsureMetadata, "hlsl-hlensure", "HLSL High-Level Metadata Ensure", false, false)
 
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-class DxilLoadMetadata : public ModulePass {
-public:
-  static char ID; // Pass identification, replacement for typeid
-  explicit DxilLoadMetadata () : ModulePass(ID) {}
-
-  const char *getPassName() const override { return "HLSL load DxilModule from metadata"; }
-
-  bool runOnModule(Module &M) override {
-    if (!M.HasDxilModule()) {
-      (void)M.GetOrCreateDxilModule();
-      return true;
-    }
-
-    return false;
-  }
-};
-}
-
-char DxilLoadMetadata::ID = 0;
-
-ModulePass *llvm::createDxilLoadMetadataPass() {
-  return new DxilLoadMetadata();
-}
-
-INITIALIZE_PASS(DxilLoadMetadata, "hlsl-dxilload", "HLSL load DxilModule from metadata", false, false)
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-Function *StripFunctionParameter(Function *F, DxilModule &DM,
-    DenseMap<const Function *, DISubprogram *> &FunctionDIs) {
-  Module &M = *DM.GetModule();
-  Type *VoidTy = Type::getVoidTy(M.getContext());
-  FunctionType *FT = FunctionType::get(VoidTy, false);
-  for (auto &arg : F->args()) {
-    if (!arg.user_empty())
-      return nullptr;
-    DbgDeclareInst *DDI = llvm::FindAllocaDbgDeclare(&arg);
-    if (DDI) {
-      DDI->eraseFromParent();
-    }
-  }
-
-  Function *NewFunc = Function::Create(FT, F->getLinkage());
-  M.getFunctionList().insert(F, NewFunc);
-  // Splice the body of the old function right into the new function.
-  NewFunc->getBasicBlockList().splice(NewFunc->begin(), F->getBasicBlockList());
-
-  // Patch the pointer to LLVM function in debug info descriptor.
-  auto DI = FunctionDIs.find(F);
-  if (DI != FunctionDIs.end()) {
-    DISubprogram *SP = DI->second;
-    SP->replaceFunction(NewFunc);
-    // Ensure the map is updated so it can be reused on subsequent argument
-    // promotions of the same function.
-    FunctionDIs.erase(DI);
-    FunctionDIs[NewFunc] = SP;
-  }
-  NewFunc->takeName(F);
-  if (DM.HasDxilFunctionProps(F)) {
-    DM.ReplaceDxilEntrySignature(F, NewFunc);
-    DM.ReplaceDxilFunctionProps(F, NewFunc);
-  }
-
-  DM.GetTypeSystem().EraseFunctionAnnotation(F);
-  F->eraseFromParent();
-  DM.GetTypeSystem().AddFunctionAnnotation(NewFunc);
-  return NewFunc;
-}
-
-void CheckInBoundForTGSM(GlobalVariable &GV, const DataLayout &DL) {
-  for (User *U : GV.users()) {
-    if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) {
-      bool allImmIndex = true;
-      for (auto Idx = GEP->idx_begin(), E = GEP->idx_end(); Idx != E; Idx++) {
-        if (!isa<ConstantInt>(Idx)) {
-          allImmIndex = false;
-          break;
-        }
-      }
-      if (!allImmIndex)
-        GEP->setIsInBounds(false);
-      else {
-        Value *Ptr = GEP->getPointerOperand();
-        unsigned size =
-            DL.getTypeAllocSize(Ptr->getType()->getPointerElementType());
-        unsigned valSize =
-            DL.getTypeAllocSize(GEP->getType()->getPointerElementType());
-        SmallVector<Value *, 8> Indices(GEP->idx_begin(), GEP->idx_end());
-        unsigned offset =
-            DL.getIndexedOffset(GEP->getPointerOperandType(), Indices);
-        if ((offset + valSize) > size)
-          GEP->setIsInBounds(false);
-      }
-    }
-  }
-}
-
-class DxilEmitMetadata : public ModulePass {
-public:
-  static char ID; // Pass identification, replacement for typeid
-  explicit DxilEmitMetadata() : ModulePass(ID) {}
-
-  const char *getPassName() const override { return "HLSL DXIL Metadata Emit"; }
-
-  void patchValidation_1_1(Module &M) {
-    for (iplist<Function>::iterator F : M.getFunctionList()) {
-      for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE;
-           ++BBI) {
-        BasicBlock *BB = BBI;
-        for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE;
-             ++II) {
-          Instruction *I = II;
-          if (I->hasMetadataOtherThanDebugLoc()) {
-            SmallVector<std::pair<unsigned, MDNode*>, 2> MDs;
-            I->getAllMetadataOtherThanDebugLoc(MDs);
-            for (auto &MD : MDs) {
-              unsigned kind = MD.first;
-              // Remove Metadata which validation_1_0 not allowed.
-              bool bNeedPatch = kind == LLVMContext::MD_tbaa ||
-                  kind == LLVMContext::MD_prof ||
-                  (kind > LLVMContext::MD_fpmath &&
-                  kind <= LLVMContext::MD_dereferenceable_or_null);
-              if (bNeedPatch)
-                I->setMetadata(kind, nullptr);
-            }
-          }
-        }
-      }
-    }
-  }
-
-  bool runOnModule(Module &M) override {
-    if (M.HasDxilModule()) {
-      DxilModule &DM = M.GetDxilModule();
-      // Remove store undef output.
-      hlsl::OP *hlslOP = M.GetDxilModule().GetOP();
-      unsigned ValMajor = 0;
-      unsigned ValMinor = 0;
-      M.GetDxilModule().GetValidatorVersion(ValMajor, ValMinor);
-      if (ValMajor == 1 && ValMinor <= 1) {
-        patchValidation_1_1(M);
-      }
-      for (iplist<Function>::iterator F : M.getFunctionList()) {
-        if (!hlslOP->IsDxilOpFunc(F))
-          continue;
-
-        // Check store output.
-        FunctionType *FT = F->getFunctionType();
-        // Num params not match.
-        if (FT->getNumParams() !=
-            (DXIL::OperandIndex::kStoreOutputValOpIdx + 1))
-          continue;
-
-        Type *overloadTy =
-            FT->getParamType(DXIL::OperandIndex::kStoreOutputValOpIdx);
-        // overload illegal.
-        if (!hlslOP->IsOverloadLegal(DXIL::OpCode::StoreOutput, overloadTy))
-          continue;
-        Function *storeOutput =
-            hlslOP->GetOpFunc(DXIL::OpCode::StoreOutput, overloadTy);
-        // Not store output.
-        if (storeOutput != F)
-          continue;
-
-        for (auto it = F->user_begin(); it != F->user_end();) {
-          CallInst *CI = dyn_cast<CallInst>(*(it++));
-          if (!CI)
-            continue;
-
-          Value *V =
-              CI->getArgOperand(DXIL::OperandIndex::kStoreOutputValOpIdx);
-          // Remove the store of undef.
-          if (isa<UndefValue>(V))
-            CI->eraseFromParent();
-        }
-      }
-      // Remove unused external functions.
-      // For none library profile, remove unused functions except entry and
-      // patchconstant function.
-      Function *EntryFunc = DM.GetEntryFunction();
-      Function *PatchConstantFunc = DM.GetPatchConstantFunction();
-      bool IsLib = DM.GetShaderModel()->IsLib();
-
-      std::vector<Function *> deadList;
-      for (iplist<Function>::iterator F : M.getFunctionList()) {
-        if (&(*F) == EntryFunc || &(*F) == PatchConstantFunc)
-          continue;
-        if (F->isDeclaration() || !IsLib) {
-          if (F->user_empty())
-            deadList.emplace_back(F);
-        }
-      }
-
-      for (Function *F : deadList)
-        F->eraseFromParent();
-
-      // Remove unused internal global.
-      std::vector<GlobalVariable *> staticGVs;
-      for (GlobalVariable &GV : M.globals()) {
-        if (HLModule::IsStaticGlobal(&GV) ||
-            HLModule::IsSharedMemoryGlobal(&GV)) {
-          staticGVs.emplace_back(&GV);
-        }
-      }
-
-      for (GlobalVariable *GV : staticGVs) {
-        bool onlyStoreUse = true;
-        for (User *user : GV->users()) {
-          if (isa<StoreInst>(user))
-            continue;
-          if (isa<ConstantExpr>(user) && user->user_empty())
-            continue;
-          onlyStoreUse = false;
-          break;
-        }
-        if (onlyStoreUse) {
-          for (auto UserIt = GV->user_begin(); UserIt != GV->user_end();) {
-            Value *User = *(UserIt++);
-            if (Instruction *I = dyn_cast<Instruction>(User)) {
-              I->eraseFromParent();
-            } else {
-              ConstantExpr *CE = cast<ConstantExpr>(User);
-              CE->dropAllReferences();
-            }
-          }
-          GV->eraseFromParent();
-        }
-      }
-
-      const DataLayout &DL = M.getDataLayout();
-      // Clear inbound for GEP which has none-const index.
-      for (GlobalVariable &GV : M.globals()) {
-        if (HLModule::IsSharedMemoryGlobal(&GV)) {
-          CheckInBoundForTGSM(GV, DL);
-        }
-      }
-
-      DenseMap<const Function *, DISubprogram *> FunctionDIs =
-          makeSubprogramMap(M);
-      // Strip parameters of entry function.
-      if (!IsLib) {
-        if (Function *PatchConstantFunc = DM.GetPatchConstantFunction()) {
-          PatchConstantFunc =
-              StripFunctionParameter(PatchConstantFunc, DM, FunctionDIs);
-          if (PatchConstantFunc)
-            DM.SetPatchConstantFunction(PatchConstantFunc);
-        }
-
-        if (Function *EntryFunc = DM.GetEntryFunction()) {
-          StringRef Name = DM.GetEntryFunctionName();
-          EntryFunc->setName(Name);
-          EntryFunc = StripFunctionParameter(EntryFunc, DM, FunctionDIs);
-          if (EntryFunc)
-            DM.SetEntryFunction(EntryFunc);
-        }
-      } else {
-        std::vector<Function *> entries;
-        for (iplist<Function>::iterator F : M.getFunctionList()) {
-          if (DM.HasDxilFunctionProps(F)) {
-            entries.emplace_back(F);
-          }
-        }
-        for (Function *entry : entries) {
-          DxilFunctionProps &props = DM.GetDxilFunctionProps(entry);
-          if (props.IsHS()) {
-            // Strip patch constant function first.
-            Function *patchConstFunc = StripFunctionParameter(
-                props.ShaderProps.HS.patchConstantFunc, DM, FunctionDIs);
-            props.ShaderProps.HS.patchConstantFunc = patchConstFunc;
-          }
-          StripFunctionParameter(entry, DM, FunctionDIs);
-        }
-      }
-
-      DM.CollectShaderFlags(); // Update flags to reflect any changes.
-                               // Update Validator Version
-      DM.UpgradeToMinValidatorVersion();
-      DM.EmitDxilMetadata();
-      return true;
-    }
-
-    return false;
-  }
-};
-}
-
-char DxilEmitMetadata::ID = 0;
-
-ModulePass *llvm::createDxilEmitMetadataPass() {
-  return new DxilEmitMetadata();
-}
-
-INITIALIZE_PASS(DxilEmitMetadata, "hlsl-dxilemit", "HLSL DXIL Metadata Emit", false, false)
-
 
 ///////////////////////////////////////////////////////////////////////////////
 // Precise propagate.
@@ -1877,7 +1550,7 @@ void DxilLegalizeResourceUsePass::PromoteLocalResource(Function &F) {
     // the entry node
     for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
       if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) { // Is it an alloca?
-        if (HandleTy == HLModule::GetArrayEltTy(AI->getAllocatedType())) {
+        if (HandleTy == dxilutil::GetArrayEltTy(AI->getAllocatedType())) {
           DXASSERT(isAllocaPromotable(AI), "otherwise, non-promotable resource array alloca found");
           Allocas.push_back(AI);
         }
@@ -1920,7 +1593,7 @@ void DxilLegalizeStaticResourceUsePass::PromoteStaticGlobalResources(
   std::set<GlobalVariable *> staticResources;
   for (auto &GV : M.globals()) {
     if (GV.getLinkage() == GlobalValue::LinkageTypes::InternalLinkage &&
-        HandleTy == HLModule::GetArrayEltTy(GV.getType())) {
+        HandleTy == dxilutil::GetArrayEltTy(GV.getType())) {
       staticResources.insert(&GV);
     }
   }

+ 364 - 0
lib/HLSL/DxilPreparePasses.cpp

@@ -0,0 +1,364 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// DxilPreparePasses.cpp                                                     //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Passes to prepare DxilModule.                                             //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "dxc/HLSL/DxilGenerationPass.h"
+#include "dxc/HLSL/DxilOperations.h"
+#include "dxc/HLSL/DxilModule.h"
+#include "dxc/Support/Global.h"
+#include "dxc/HLSL/DxilTypeSystem.h"
+#include "dxc/HLSL/DxilUtil.h"
+#include "dxc/HLSL/DxilFunctionProps.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include <memory>
+#include <unordered_set>
+
+using namespace llvm;
+using namespace hlsl;
+
+namespace {
+class SimplifyInst : public FunctionPass {
+public:
+  static char ID;
+
+  SimplifyInst() : FunctionPass(ID) {
+    initializeScalarizerPass(*PassRegistry::getPassRegistry());
+  }
+
+  bool runOnFunction(Function &F) override;
+
+private:
+};
+}
+
+char SimplifyInst::ID = 0;
+
+FunctionPass *llvm::createSimplifyInstPass() { return new SimplifyInst(); }
+
+INITIALIZE_PASS(SimplifyInst, "simplify-inst", "Simplify Instructions", false, false)
+
+bool SimplifyInst::runOnFunction(Function &F) {
+  for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) {
+    BasicBlock *BB = BBI;
+    llvm::SimplifyInstructionsInBlock(BB, nullptr);
+  }
+  return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace {
+class DxilLoadMetadata : public ModulePass {
+public:
+  static char ID; // Pass identification, replacement for typeid
+  explicit DxilLoadMetadata () : ModulePass(ID) {}
+
+  const char *getPassName() const override { return "HLSL load DxilModule from metadata"; }
+
+  bool runOnModule(Module &M) override {
+    if (!M.HasDxilModule()) {
+      (void)M.GetOrCreateDxilModule();
+      return true;
+    }
+
+    return false;
+  }
+};
+}
+
+char DxilLoadMetadata::ID = 0;
+
+ModulePass *llvm::createDxilLoadMetadataPass() {
+  return new DxilLoadMetadata();
+}
+
+INITIALIZE_PASS(DxilLoadMetadata, "hlsl-dxilload", "HLSL load DxilModule from metadata", false, false)
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+Function *StripFunctionParameter(Function *F, DxilModule &DM,
+    DenseMap<const Function *, DISubprogram *> &FunctionDIs) {
+  Module &M = *DM.GetModule();
+  Type *VoidTy = Type::getVoidTy(M.getContext());
+  FunctionType *FT = FunctionType::get(VoidTy, false);
+  for (auto &arg : F->args()) {
+    if (!arg.user_empty())
+      return nullptr;
+    DbgDeclareInst *DDI = llvm::FindAllocaDbgDeclare(&arg);
+    if (DDI) {
+      DDI->eraseFromParent();
+    }
+  }
+
+  Function *NewFunc = Function::Create(FT, F->getLinkage());
+  M.getFunctionList().insert(F, NewFunc);
+  // Splice the body of the old function right into the new function.
+  NewFunc->getBasicBlockList().splice(NewFunc->begin(), F->getBasicBlockList());
+
+  // Patch the pointer to LLVM function in debug info descriptor.
+  auto DI = FunctionDIs.find(F);
+  if (DI != FunctionDIs.end()) {
+    DISubprogram *SP = DI->second;
+    SP->replaceFunction(NewFunc);
+    // Ensure the map is updated so it can be reused on subsequent argument
+    // promotions of the same function.
+    FunctionDIs.erase(DI);
+    FunctionDIs[NewFunc] = SP;
+  }
+  NewFunc->takeName(F);
+  if (DM.HasDxilFunctionProps(F)) {
+    DM.ReplaceDxilEntrySignature(F, NewFunc);
+    DM.ReplaceDxilFunctionProps(F, NewFunc);
+  }
+
+  DM.GetTypeSystem().EraseFunctionAnnotation(F);
+  F->eraseFromParent();
+  DM.GetTypeSystem().AddFunctionAnnotation(NewFunc);
+  return NewFunc;
+}
+
+void CheckInBoundForTGSM(GlobalVariable &GV, const DataLayout &DL) {
+  for (User *U : GV.users()) {
+    if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) {
+      bool allImmIndex = true;
+      for (auto Idx = GEP->idx_begin(), E = GEP->idx_end(); Idx != E; Idx++) {
+        if (!isa<ConstantInt>(Idx)) {
+          allImmIndex = false;
+          break;
+        }
+      }
+      if (!allImmIndex)
+        GEP->setIsInBounds(false);
+      else {
+        Value *Ptr = GEP->getPointerOperand();
+        unsigned size =
+            DL.getTypeAllocSize(Ptr->getType()->getPointerElementType());
+        unsigned valSize =
+            DL.getTypeAllocSize(GEP->getType()->getPointerElementType());
+        SmallVector<Value *, 8> Indices(GEP->idx_begin(), GEP->idx_end());
+        unsigned offset =
+            DL.getIndexedOffset(GEP->getPointerOperandType(), Indices);
+        if ((offset + valSize) > size)
+          GEP->setIsInBounds(false);
+      }
+    }
+  }
+}
+
+class DxilEmitMetadata : public ModulePass {
+public:
+  static char ID; // Pass identification, replacement for typeid
+  explicit DxilEmitMetadata() : ModulePass(ID) {}
+
+  const char *getPassName() const override { return "HLSL DXIL Metadata Emit"; }
+
+  void patchValidation_1_1(Module &M) {
+    for (iplist<Function>::iterator F : M.getFunctionList()) {
+      for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE;
+           ++BBI) {
+        BasicBlock *BB = BBI;
+        for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE;
+             ++II) {
+          Instruction *I = II;
+          if (I->hasMetadataOtherThanDebugLoc()) {
+            SmallVector<std::pair<unsigned, MDNode*>, 2> MDs;
+            I->getAllMetadataOtherThanDebugLoc(MDs);
+            for (auto &MD : MDs) {
+              unsigned kind = MD.first;
+              // Remove Metadata which validation_1_0 not allowed.
+              bool bNeedPatch = kind == LLVMContext::MD_tbaa ||
+                  kind == LLVMContext::MD_prof ||
+                  (kind > LLVMContext::MD_fpmath &&
+                  kind <= LLVMContext::MD_dereferenceable_or_null);
+              if (bNeedPatch)
+                I->setMetadata(kind, nullptr);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  bool runOnModule(Module &M) override {
+    if (M.HasDxilModule()) {
+      DxilModule &DM = M.GetDxilModule();
+      // Remove store undef output.
+      hlsl::OP *hlslOP = M.GetDxilModule().GetOP();
+      unsigned ValMajor = 0;
+      unsigned ValMinor = 0;
+      M.GetDxilModule().GetValidatorVersion(ValMajor, ValMinor);
+      if (ValMajor == 1 && ValMinor <= 1) {
+        patchValidation_1_1(M);
+      }
+      for (iplist<Function>::iterator F : M.getFunctionList()) {
+        if (!hlslOP->IsDxilOpFunc(F))
+          continue;
+
+        // Check store output.
+        FunctionType *FT = F->getFunctionType();
+        // Num params not match.
+        if (FT->getNumParams() !=
+            (DXIL::OperandIndex::kStoreOutputValOpIdx + 1))
+          continue;
+
+        Type *overloadTy =
+            FT->getParamType(DXIL::OperandIndex::kStoreOutputValOpIdx);
+        // overload illegal.
+        if (!hlslOP->IsOverloadLegal(DXIL::OpCode::StoreOutput, overloadTy))
+          continue;
+        Function *storeOutput =
+            hlslOP->GetOpFunc(DXIL::OpCode::StoreOutput, overloadTy);
+        // Not store output.
+        if (storeOutput != F)
+          continue;
+
+        for (auto it = F->user_begin(); it != F->user_end();) {
+          CallInst *CI = dyn_cast<CallInst>(*(it++));
+          if (!CI)
+            continue;
+
+          Value *V =
+              CI->getArgOperand(DXIL::OperandIndex::kStoreOutputValOpIdx);
+          // Remove the store of undef.
+          if (isa<UndefValue>(V))
+            CI->eraseFromParent();
+        }
+      }
+      // Remove unused external functions.
+      // For none library profile, remove unused functions except entry and
+      // patchconstant function.
+      Function *EntryFunc = DM.GetEntryFunction();
+      Function *PatchConstantFunc = DM.GetPatchConstantFunction();
+      bool IsLib = DM.GetShaderModel()->IsLib();
+
+      std::vector<Function *> deadList;
+      for (iplist<Function>::iterator F : M.getFunctionList()) {
+        if (&(*F) == EntryFunc || &(*F) == PatchConstantFunc)
+          continue;
+        if (F->isDeclaration() || !IsLib) {
+          if (F->user_empty())
+            deadList.emplace_back(F);
+        }
+      }
+
+      for (Function *F : deadList)
+        F->eraseFromParent();
+
+      // Remove unused internal global.
+      std::vector<GlobalVariable *> staticGVs;
+      for (GlobalVariable &GV : M.globals()) {
+        if (dxilutil::IsStaticGlobal(&GV) ||
+            dxilutil::IsSharedMemoryGlobal(&GV)) {
+          staticGVs.emplace_back(&GV);
+        }
+      }
+
+      for (GlobalVariable *GV : staticGVs) {
+        bool onlyStoreUse = true;
+        for (User *user : GV->users()) {
+          if (isa<StoreInst>(user))
+            continue;
+          if (isa<ConstantExpr>(user) && user->user_empty())
+            continue;
+          onlyStoreUse = false;
+          break;
+        }
+        if (onlyStoreUse) {
+          for (auto UserIt = GV->user_begin(); UserIt != GV->user_end();) {
+            Value *User = *(UserIt++);
+            if (Instruction *I = dyn_cast<Instruction>(User)) {
+              I->eraseFromParent();
+            } else {
+              ConstantExpr *CE = cast<ConstantExpr>(User);
+              CE->dropAllReferences();
+            }
+          }
+          GV->eraseFromParent();
+        }
+      }
+
+      const DataLayout &DL = M.getDataLayout();
+      // Clear inbound for GEP which has none-const index.
+      for (GlobalVariable &GV : M.globals()) {
+        if (dxilutil::IsSharedMemoryGlobal(&GV)) {
+          CheckInBoundForTGSM(GV, DL);
+        }
+      }
+
+      DenseMap<const Function *, DISubprogram *> FunctionDIs =
+          makeSubprogramMap(M);
+      // Strip parameters of entry function.
+      if (!IsLib) {
+        if (Function *PatchConstantFunc = DM.GetPatchConstantFunction()) {
+          PatchConstantFunc =
+              StripFunctionParameter(PatchConstantFunc, DM, FunctionDIs);
+          if (PatchConstantFunc)
+            DM.SetPatchConstantFunction(PatchConstantFunc);
+        }
+
+        if (Function *EntryFunc = DM.GetEntryFunction()) {
+          StringRef Name = DM.GetEntryFunctionName();
+          EntryFunc->setName(Name);
+          EntryFunc = StripFunctionParameter(EntryFunc, DM, FunctionDIs);
+          if (EntryFunc)
+            DM.SetEntryFunction(EntryFunc);
+        }
+      } else {
+        std::vector<Function *> entries;
+        for (iplist<Function>::iterator F : M.getFunctionList()) {
+          if (DM.HasDxilFunctionProps(F)) {
+            entries.emplace_back(F);
+          }
+        }
+        for (Function *entry : entries) {
+          DxilFunctionProps &props = DM.GetDxilFunctionProps(entry);
+          if (props.IsHS()) {
+            // Strip patch constant function first.
+            Function *patchConstFunc = StripFunctionParameter(
+                props.ShaderProps.HS.patchConstantFunc, DM, FunctionDIs);
+            props.ShaderProps.HS.patchConstantFunc = patchConstFunc;
+          }
+          StripFunctionParameter(entry, DM, FunctionDIs);
+        }
+      }
+
+      DM.CollectShaderFlags(); // Update flags to reflect any changes.
+                               // Update Validator Version
+      DM.UpgradeToMinValidatorVersion();
+      DM.EmitDxilMetadata();
+      return true;
+    }
+
+    return false;
+  }
+};
+}
+
+char DxilEmitMetadata::ID = 0;
+
+ModulePass *llvm::createDxilEmitMetadataPass() {
+  return new DxilEmitMetadata();
+}
+
+INITIALIZE_PASS(DxilEmitMetadata, "hlsl-dxilemit", "HLSL DXIL Metadata Emit", false, false)

+ 85 - 0
lib/HLSL/DxilUtil.cpp

@@ -0,0 +1,85 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// DxilUtil.cpp                                                              //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Dxil helper functions.                                                    //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include "llvm/IR/GlobalVariable.h"
+#include "dxc/HLSL/DxilTypeSystem.h"
+#include "dxc/HLSL/DxilUtil.h"
+
+using namespace llvm;
+using namespace hlsl;
+
+namespace hlsl {
+
+namespace dxilutil {
+
+Type *GetArrayEltTy(Type *Ty) {
+  if (isa<PointerType>(Ty))
+    Ty = Ty->getPointerElementType();
+  while (isa<ArrayType>(Ty)) {
+    Ty = Ty->getArrayElementType();
+  }
+  return Ty;
+}
+
+unsigned
+GetLegacyCBufferFieldElementSize(DxilFieldAnnotation &fieldAnnotation,
+                                           llvm::Type *Ty,
+                                           DxilTypeSystem &typeSys) {
+  while (isa<ArrayType>(Ty)) {
+    Ty = Ty->getArrayElementType();
+  }
+
+  // Bytes.
+  unsigned compSize = fieldAnnotation.GetCompType().Is64Bit()?8:4;
+  unsigned fieldSize = compSize;
+  if (Ty->isVectorTy()) {
+    fieldSize *= Ty->getVectorNumElements();
+  } else if (StructType *ST = dyn_cast<StructType>(Ty)) {
+    DxilStructAnnotation *EltAnnotation = typeSys.GetStructAnnotation(ST);
+    if (EltAnnotation) {
+      fieldSize = EltAnnotation->GetCBufferSize();
+    } else {
+      // Calculate size when don't have annotation.
+      if (fieldAnnotation.HasMatrixAnnotation()) {
+        const DxilMatrixAnnotation &matAnnotation =
+            fieldAnnotation.GetMatrixAnnotation();
+        unsigned rows = matAnnotation.Rows;
+        unsigned cols = matAnnotation.Cols;
+        if (matAnnotation.Orientation == MatrixOrientation::ColumnMajor) {
+          rows = cols;
+          cols = matAnnotation.Rows;
+        } else if (matAnnotation.Orientation != MatrixOrientation::RowMajor) {
+          // Invalid matrix orientation.
+          fieldSize = 0;
+        }
+        fieldSize = (rows - 1) * 16 + cols * 4;
+      } else {
+        // Cannot find struct annotation.
+        fieldSize = 0;
+      }
+    }
+  }
+  return fieldSize;
+}
+
+bool IsStaticGlobal(GlobalVariable *GV) {
+  return GV->getLinkage() == GlobalValue::LinkageTypes::InternalLinkage &&
+         GV->getType()->getPointerAddressSpace() == DXIL::kDefaultAddrSpace;
+}
+
+bool IsSharedMemoryGlobal(llvm::GlobalVariable *GV) {
+  return GV->getType()->getPointerAddressSpace() == DXIL::kTGSMAddrSpace;
+}
+
+}
+
+}

+ 5 - 9
lib/HLSL/DxilValidation.cpp

@@ -16,7 +16,7 @@
 #include "dxc/HLSL/DxilShaderModel.h"
 #include "dxc/HLSL/DxilContainer.h"
 #include "dxc/Support/Global.h"
-#include "dxc/HLSL/HLModule.h"
+#include "dxc/HLSL/DxilUtil.h"
 #include "dxc/HLSL/DxilInstructions.h"
 #include "dxc/HLSL/ReducibilityAnalysis.h"
 #include "dxc/Support/WinIncludes.h"
@@ -2593,11 +2593,7 @@ static void ValidateFunction(Function &F, ValidationContext &ValCtx) {
         argTy = argTy->getArrayElementType();
       }
 
-      DxilParameterAnnotation &paramAnnoation =
-          funcAnnotation->GetParameterAnnotation(arg.getArgNo());
-
-      if (argTy->isStructTy() && !HLModule::IsStreamOutputType(argTy) &&
-          !paramAnnoation.HasMatrixAnnotation()) {
+      if (argTy->isStructTy()) {
         if (arg.hasName())
           ValCtx.EmitFormatError(
               ValidationRule::DeclFnFlattenParam,
@@ -2621,7 +2617,7 @@ static void ValidateFunction(Function &F, ValidationContext &ValCtx) {
 static void ValidateGlobalVariable(GlobalVariable &GV,
                                    ValidationContext &ValCtx) {
   bool isInternalGV =
-      HLModule::IsStaticGlobal(&GV) || HLModule::IsSharedMemoryGlobal(&GV);
+      dxilutil::IsStaticGlobal(&GV) || dxilutil::IsSharedMemoryGlobal(&GV);
 
   if (!isInternalGV) {
     if (!GV.user_empty()) {
@@ -2646,7 +2642,7 @@ static void ValidateGlobalVariable(GlobalVariable &GV,
     }
 
     // Validate type for internal globals.
-    if (HLModule::IsStaticGlobal(&GV) || HLModule::IsSharedMemoryGlobal(&GV)) {
+    if (dxilutil::IsStaticGlobal(&GV) || dxilutil::IsSharedMemoryGlobal(&GV)) {
       Type *Ty = GV.getType()->getPointerElementType();
       ValidateType(Ty, ValCtx);
     }
@@ -2931,7 +2927,7 @@ CollectCBufferRanges(DxilStructAnnotation *annotation,
 
     unsigned offset = fieldAnnotation.GetCBufferOffset();
 
-    unsigned EltSize = HLModule::GetLegacyCBufferFieldElementSize(
+    unsigned EltSize = dxilutil::GetLegacyCBufferFieldElementSize(
         fieldAnnotation, EltTy, typeSys);
 
     bool bOutOfBound = false;

+ 3 - 2
lib/HLSL/HLMatrixLowerPass.cpp

@@ -13,6 +13,7 @@
 #include "dxc/HLSL/HLMatrixLowerPass.h"
 #include "dxc/HLSL/HLOperations.h"
 #include "dxc/HLSL/HLModule.h"
+#include "dxc/HLSL/DxilUtil.h"
 #include "dxc/HlslIntrinsicOp.h"
 #include "dxc/Support/Global.h"
 #include "dxc/HLSL/DxilOperations.h"
@@ -177,8 +178,8 @@ public:
     }
     std::vector<GlobalVariable*> staticGVs;
     for (GlobalVariable &GV : M.globals()) {
-      if (HLModule::IsStaticGlobal(&GV) ||
-          HLModule::IsSharedMemoryGlobal(&GV)) {
+      if (dxilutil::IsStaticGlobal(&GV) ||
+          dxilutil::IsSharedMemoryGlobal(&GV)) {
         staticGVs.emplace_back(&GV);
       }
     }

+ 0 - 59
lib/HLSL/HLModule.cpp

@@ -791,65 +791,6 @@ bool HLModule::IsHLSLObjectType(llvm::Type *Ty) {
   return false;
 }
 
-Type *HLModule::GetArrayEltTy(Type *Ty) {
-  if (isa<PointerType>(Ty))
-    Ty = Ty->getPointerElementType();
-  while (isa<ArrayType>(Ty)) {
-    Ty = Ty->getArrayElementType();
-  }
-  return Ty;
-}
-
-unsigned
-HLModule::GetLegacyCBufferFieldElementSize(DxilFieldAnnotation &fieldAnnotation,
-                                           llvm::Type *Ty,
-                                           DxilTypeSystem &typeSys) {
-  while (isa<ArrayType>(Ty)) {
-    Ty = Ty->getArrayElementType();
-  }
-
-  // Bytes.
-  unsigned compSize = fieldAnnotation.GetCompType().Is64Bit()?8:4;
-  unsigned fieldSize = compSize;
-  if (Ty->isVectorTy()) {
-    fieldSize *= Ty->getVectorNumElements();
-  } else if (StructType *ST = dyn_cast<StructType>(Ty)) {
-    DxilStructAnnotation *EltAnnotation = typeSys.GetStructAnnotation(ST);
-    if (EltAnnotation) {
-      fieldSize = EltAnnotation->GetCBufferSize();
-    } else {
-      // Calculate size when don't have annotation.
-      if (fieldAnnotation.HasMatrixAnnotation()) {
-        const DxilMatrixAnnotation &matAnnotation =
-            fieldAnnotation.GetMatrixAnnotation();
-        unsigned rows = matAnnotation.Rows;
-        unsigned cols = matAnnotation.Cols;
-        if (matAnnotation.Orientation == MatrixOrientation::ColumnMajor) {
-          rows = cols;
-          cols = matAnnotation.Rows;
-        } else if (matAnnotation.Orientation != MatrixOrientation::RowMajor) {
-          // Invalid matrix orientation.
-          fieldSize = 0;
-        }
-        fieldSize = (rows - 1) * 16 + cols * 4;
-      } else {
-        // Cannot find struct annotation.
-        fieldSize = 0;
-      }
-    }
-  }
-  return fieldSize;
-}
-
-bool HLModule::IsStaticGlobal(GlobalVariable *GV) {
-  return GV->getLinkage() == GlobalValue::LinkageTypes::InternalLinkage &&
-         GV->getType()->getPointerAddressSpace() == DXIL::kDefaultAddrSpace;
-}
-
-bool HLModule::IsSharedMemoryGlobal(llvm::GlobalVariable *GV) {
-  return GV->getType()->getPointerAddressSpace() == DXIL::kTGSMAddrSpace;
-}
-
 void HLModule::GetParameterRowsAndCols(Type *Ty, unsigned &rows, unsigned &cols,
                                        DxilParameterAnnotation &paramAnnotation) {
   if (Ty->isPointerTy())

+ 5 - 4
lib/HLSL/HLOperationLower.cpp

@@ -13,6 +13,7 @@
 #include "dxc/HLSL/DxilOperations.h"
 #include "dxc/HLSL/HLMatrixLowerHelper.h"
 #include "dxc/HLSL/HLModule.h"
+#include "dxc/HLSL/DxilUtil.h"
 #include "dxc/HLSL/HLOperationLower.h"
 #include "dxc/HLSL/HLOperationLowerExtension.h"
 #include "dxc/HLSL/HLOperations.h"
@@ -4614,7 +4615,7 @@ void TranslateCBGep(GetElementPtrInst *GEP, Value *handle, Value *baseOffset,
       } else {
         DXASSERT(fieldAnnotation, "must be a field");
         if (ArrayType *AT = dyn_cast<ArrayType>(EltTy)) {
-          unsigned EltSize = HLModule::GetLegacyCBufferFieldElementSize(
+          unsigned EltSize = dxilutil::GetLegacyCBufferFieldElementSize(
               *fieldAnnotation, EltTy, dxilTypeSys);
 
           // Decide the nested array size.
@@ -4651,7 +4652,7 @@ void TranslateCBGep(GetElementPtrInst *GEP, Value *handle, Value *baseOffset,
       offset = Builder.CreateAdd(offset, hlslOP->GetU32Const(structOffset));
     } else if (GEPIt->isArrayTy()) {
       DXASSERT(fieldAnnotation != nullptr, "must a field");
-      unsigned EltSize = HLModule::GetLegacyCBufferFieldElementSize(
+      unsigned EltSize = dxilutil::GetLegacyCBufferFieldElementSize(
               *fieldAnnotation, *GEPIt, dxilTypeSys);
       // Decide the nested array size.
       unsigned nestedArraySize = 1;
@@ -5103,7 +5104,7 @@ void TranslateCBGepLegacy(GetElementPtrInst *GEP, Value *handle,
       } else {
         DXASSERT(fieldAnnotation, "must be a field");
         if (ArrayType *AT = dyn_cast<ArrayType>(EltTy)) {
-          unsigned EltSize = HLModule::GetLegacyCBufferFieldElementSize(
+          unsigned EltSize = dxilutil::GetLegacyCBufferFieldElementSize(
               *fieldAnnotation, EltTy, dxilTypeSys);
 
           // Decide the nested array size.
@@ -5154,7 +5155,7 @@ void TranslateCBGepLegacy(GetElementPtrInst *GEP, Value *handle,
         legacyIndex = Builder.CreateAdd(legacyIndex, hlslOP->GetU32Const(idxInc));
     } else if (GEPIt->isArrayTy()) {
       DXASSERT(fieldAnnotation != nullptr, "must a field");
-      unsigned EltSize = HLModule::GetLegacyCBufferFieldElementSize(
+      unsigned EltSize = dxilutil::GetLegacyCBufferFieldElementSize(
               *fieldAnnotation, *GEPIt, dxilTypeSys);
       // Decide the nested array size.
       unsigned nestedArraySize = 1;

+ 13 - 12
lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp

@@ -49,6 +49,7 @@
 #include "dxc/HLSL/HLOperations.h"
 #include "dxc/HLSL/DxilConstants.h"
 #include "dxc/HLSL/HLModule.h"
+#include "dxc/HLSL/DxilUtil.h"
 #include "dxc/HLSL/DxilModule.h"
 #include "dxc/HlslIntrinsicOp.h"
 #include "dxc/HLSL/DxilTypeSystem.h"
@@ -2604,7 +2605,7 @@ static bool isVectorOrStructArray(Type *T) {
   if (!T->isArrayTy())
     return false;
 
-  T = HLModule::GetArrayEltTy(T);
+  T = dxilutil::GetArrayEltTy(T);
 
   return T->isStructTy() || T->isVectorTy();
 }
@@ -3922,8 +3923,8 @@ public:
     // Flatten internal global.
     std::vector<GlobalVariable *> staticGVs;
     for (GlobalVariable &GV : M.globals()) {
-      if (HLModule::IsStaticGlobal(&GV) ||
-          HLModule::IsSharedMemoryGlobal(&GV)) {
+      if (dxilutil::IsStaticGlobal(&GV) ||
+          dxilutil::IsSharedMemoryGlobal(&GV)) {
         staticGVs.emplace_back(&GV);
       } else {
         // merge GEP use for global.
@@ -3937,8 +3938,8 @@ public:
     // Remove unused internal global.
     staticGVs.clear();
     for (GlobalVariable &GV : M.globals()) {
-      if (HLModule::IsStaticGlobal(&GV) ||
-          HLModule::IsSharedMemoryGlobal(&GV)) {
+      if (dxilutil::IsStaticGlobal(&GV) ||
+          dxilutil::IsSharedMemoryGlobal(&GV)) {
         staticGVs.emplace_back(&GV);
       }
     }
@@ -4797,8 +4798,8 @@ void SROA_Parameter_HLSL::replaceCastParameter(
       }
     }
 
-    Type *NewEltTy = HLModule::GetArrayEltTy(NewTy);
-    Type *OldEltTy = HLModule::GetArrayEltTy(OldTy);
+    Type *NewEltTy = dxilutil::GetArrayEltTy(NewTy);
+    Type *OldEltTy = dxilutil::GetArrayEltTy(OldTy);
 
     if (NewEltTy == HandlePtrTy) {
       // Save resource attribute.
@@ -5129,7 +5130,7 @@ void SROA_Parameter_HLSL::flattenArgument(
           EltAnnotation.SetSemanticString(semantic);
         } else if (!eltSem.empty() &&
                  semanticTypeMap.count(eltSem) == 0) {
-          Type *EltTy = HLModule::GetArrayEltTy(Ty);
+          Type *EltTy = dxilutil::GetArrayEltTy(Ty);
           DXASSERT(EltTy->isStructTy(), "must be a struct type to has semantic.");
           semanticTypeMap[eltSem] = EltTy->getStructElementType(i);
         }
@@ -6218,7 +6219,7 @@ public:
     std::vector<GlobalVariable *> staticGVs;
     for (GlobalVariable &GV : M.globals()) {
       bool isStaticGlobal =
-          HLModule::IsStaticGlobal(&GV) &&
+          dxilutil::IsStaticGlobal(&GV) &&
           GV.getType()->getAddressSpace() == DXIL::kDefaultAddrSpace;
 
       if (isStaticGlobal &&
@@ -6388,7 +6389,7 @@ bool LowerTypePass::runOnModule(Module &M) {
   // Work on internal global.
   std::vector<GlobalVariable *> vecGVs;
   for (GlobalVariable &GV : M.globals()) {
-    if (HLModule::IsStaticGlobal(&GV) || HLModule::IsSharedMemoryGlobal(&GV)) {
+    if (dxilutil::IsStaticGlobal(&GV) || dxilutil::IsSharedMemoryGlobal(&GV)) {
       if (needToLower(&GV) && !GV.user_empty())
         vecGVs.emplace_back(&GV);
     }
@@ -6528,7 +6529,7 @@ bool DynamicIndexingVectorToArray::needToLower(Value *V) {
     // Array must be replaced even without dynamic indexing to remove vector
     // type in dxil.
     // TODO: optimize static array index in later pass.
-    Type *EltTy = HLModule::GetArrayEltTy(AT);
+    Type *EltTy = dxilutil::GetArrayEltTy(AT);
     return isa<VectorType>(EltTy);
   }
   return false;
@@ -6888,7 +6889,7 @@ void ResourceToHandle::initialize(Module &M) {
 
 bool ResourceToHandle::needToLower(Value *V) {
   Type *Ty = V->getType()->getPointerElementType();
-  Ty = HLModule::GetArrayEltTy(Ty);
+  Ty = dxilutil::GetArrayEltTy(Ty);
   return (HLModule::IsHLSLObjectType(Ty) && !HLModule::IsStreamOutputType(Ty));
 }
 

+ 4 - 3
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -17,6 +17,7 @@
 #include "dxc/HlslIntrinsicOp.h"
 #include "dxc/HLSL/HLMatrixLowerHelper.h"
 #include "dxc/HLSL/HLModule.h"
+#include "dxc/HLSL/DxilUtil.h"
 #include "dxc/HLSL/HLOperations.h"
 #include "dxc/HLSL/DxilOperations.h"
 #include "dxc/HLSL/DxilTypeSystem.h"
@@ -3809,7 +3810,7 @@ static void SimpleTransformForHLDXIR(llvm::Module *pM) {
   deadInsts.clear();
 
   for (GlobalVariable &GV : pM->globals()) {
-    if (HLModule::IsStaticGlobal(&GV)) {
+    if (dxilutil::IsStaticGlobal(&GV)) {
       for (User *U : GV.users()) {
         if (BitCastOperator *BCO = dyn_cast<BitCastOperator>(U)) {
           SimplifyBitCast(BCO, deadInsts);
@@ -5629,8 +5630,8 @@ void CGMSHLSLRuntime::EmitHLSLFlatConversionAggregateCopy(CodeGenFunction &CGF,
     unsigned size = TheModule.getDataLayout().getTypeAllocSize(SrcPtrTy);
     CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, size, 1);
     return;
-  } else if (HLModule::IsHLSLObjectType(HLModule::GetArrayEltTy(SrcPtrTy)) &&
-             HLModule::IsHLSLObjectType(HLModule::GetArrayEltTy(DestPtrTy))) {
+  } else if (HLModule::IsHLSLObjectType(dxilutil::GetArrayEltTy(SrcPtrTy)) &&
+             HLModule::IsHLSLObjectType(dxilutil::GetArrayEltTy(DestPtrTy))) {
     unsigned sizeSrc = TheModule.getDataLayout().getTypeAllocSize(SrcPtrTy);
     unsigned sizeDest = TheModule.getDataLayout().getTypeAllocSize(DestPtrTy);
     CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, std::max(sizeSrc, sizeDest), 1);