Explorar o código

Merged PR 27: Keep resource global in LLVMUsed and remove in RemoveResourceSymbols

- prevents GV removal while resource still points to it
Xiang_Li (XBox) %!s(int64=7) %!d(string=hai) anos
pai
achega
4a0950ea79

+ 1 - 0
include/dxc/HLSL/DxilModule.h

@@ -156,6 +156,7 @@ public:
   /// Emit llvm.used array to make sure that optimizations do not remove unreferenced globals.
   void EmitLLVMUsed();
   std::vector<llvm::GlobalVariable* > &GetLLVMUsed();
+  void ClearLLVMUsed();
 
   // ViewId state.
   DxilViewIdState &GetViewIdState();

+ 2 - 0
lib/HLSL/DxilCondenseResources.cpp

@@ -459,6 +459,8 @@ public:
   bool runOnModule(Module &M) override {
     DxilModule &DM = M.GetOrCreateDxilModule();
     m_DM = &DM;
+    // Clear llvm used to remove unused resource.
+    m_DM->ClearLLVMUsed();
     m_bIsLib = DM.GetShaderModel()->IsLib();
 
     // Switch tbuffers to SRVs, as they have been treated as cbuffers up to this

+ 6 - 0
lib/HLSL/DxilGenerationPass.cpp

@@ -149,27 +149,33 @@ void InitDxilModuleFromHLModule(HLModule &H, DxilModule &M, DxilEntrySignature *
   M.SetEntryFunction(EntryFn);
   M.SetEntryFunctionName(H.GetEntryFunctionName());
 
+  std::vector<GlobalVariable* > &LLVMUsed = M.GetLLVMUsed();
+
   // Resources
   for (auto && C : H.GetCBuffers()) {
     auto b = make_unique<DxilCBuffer>();
     InitResourceBase(C.get(), b.get());
     b->SetSize(C->GetSize());
+    LLVMUsed.emplace_back(cast<GlobalVariable>(b->GetGlobalSymbol()));
     M.AddCBuffer(std::move(b));
   }
   for (auto && C : H.GetUAVs()) {
     auto b = make_unique<DxilResource>();
     InitResource(C.get(), b.get());
+    LLVMUsed.emplace_back(cast<GlobalVariable>(b->GetGlobalSymbol()));
     M.AddUAV(std::move(b));
   }
   for (auto && C : H.GetSRVs()) {
     auto b = make_unique<DxilResource>();
     InitResource(C.get(), b.get());
+    LLVMUsed.emplace_back(cast<GlobalVariable>(b->GetGlobalSymbol()));
     M.AddSRV(std::move(b));
   }
   for (auto && C : H.GetSamplers()) {
     auto b = make_unique<DxilSampler>();
     InitResourceBase(C.get(), b.get());
     b->SetSamplerKind(C->GetSamplerKind());
+    LLVMUsed.emplace_back(cast<GlobalVariable>(b->GetGlobalSymbol()));
     M.AddSampler(std::move(b));
   }
 

+ 25 - 10
lib/HLSL/DxilModule.cpp

@@ -931,6 +931,7 @@ void DxilModule::RemoveFunction(llvm::Function *F) {
 }
 
 void DxilModule::RemoveUnusedResources() {
+  DXASSERT(!m_pSM->IsLib(), "this function not work on library");
   hlsl::OP *hlslOP = GetOP();
   Function *createHandleFunc = hlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(GetCtx()));
   if (createHandleFunc->user_empty()) {
@@ -1003,6 +1004,7 @@ static void RemoveResourceSymbols(std::vector<std::unique_ptr<TResource>> &vec)
     GV->removeDeadConstantUsers();
     if (GV->user_empty()) {
       p = vec.erase(c);
+      GV->eraseFromParent();
     }
   }
 }
@@ -1159,19 +1161,25 @@ void DxilModule::ResetEntrySignatureMap(
   m_DxilEntrySignatureMap = std::move(SigMap);
 }
 
+static const StringRef llvmUsedName = "llvm.used";
+
 void DxilModule::EmitLLVMUsed() {
+  if (GlobalVariable *oldGV = m_pModule->getGlobalVariable(llvmUsedName)) {
+    oldGV->eraseFromParent();
+  }
   if (m_LLVMUsed.empty())
     return;
 
-  vector<llvm::Constant*> GVs;
+  vector<llvm::Constant *> GVs;
   Type *pI8PtrType = Type::getInt8PtrTy(m_Ctx, DXIL::kDefaultAddrSpace);
 
   GVs.resize(m_LLVMUsed.size());
   for (size_t i = 0, e = m_LLVMUsed.size(); i != e; i++) {
     Constant *pConst = cast<Constant>(&*m_LLVMUsed[i]);
-    PointerType * pPtrType = dyn_cast<PointerType>(pConst->getType());
+    PointerType *pPtrType = dyn_cast<PointerType>(pConst->getType());
     if (pPtrType->getPointerAddressSpace() != DXIL::kDefaultAddrSpace) {
-      // Cast pointer to addrspace 0, as LLVMUsed elements must have the same type.
+      // Cast pointer to addrspace 0, as LLVMUsed elements must have the same
+      // type.
       GVs[i] = ConstantExpr::getAddrSpaceCast(pConst, pI8PtrType);
     } else {
       GVs[i] = ConstantExpr::getPointerCast(pConst, pI8PtrType);
@@ -1180,18 +1188,25 @@ void DxilModule::EmitLLVMUsed() {
 
   ArrayType *pATy = ArrayType::get(pI8PtrType, GVs.size());
 
-  StringRef llvmUsedName = "llvm.used";
+  GlobalVariable *pGV =
+      new GlobalVariable(*m_pModule, pATy, false, GlobalValue::AppendingLinkage,
+                         ConstantArray::get(pATy, GVs), llvmUsedName);
+
+  pGV->setSection("llvm.metadata");
+}
 
+void DxilModule::ClearLLVMUsed() {
   if (GlobalVariable *oldGV = m_pModule->getGlobalVariable(llvmUsedName)) {
     oldGV->eraseFromParent();
   }
+  if (m_LLVMUsed.empty())
+    return;
 
-  GlobalVariable *pGV = new GlobalVariable(*m_pModule, pATy, false,
-                                           GlobalValue::AppendingLinkage,
-                                           ConstantArray::get(pATy, GVs),
-                                           llvmUsedName);
-
-  pGV->setSection("llvm.metadata");
+  for (size_t i = 0, e = m_LLVMUsed.size(); i != e; i++) {
+    Constant *pConst = cast<Constant>(&*m_LLVMUsed[i]);
+    pConst->removeDeadConstantUsers();
+  }
+  m_LLVMUsed.clear();
 }
 
 vector<GlobalVariable* > &DxilModule::GetLLVMUsed() {