Prechádzať zdrojové kódy

Fix nondeterminism sources in the linker. (#2383)

Tristan Labelle 6 rokov pred
rodič
commit
1156209ad6
2 zmenil súbory, kde vykonal 20 pridanie a 25 odobranie
  1. 2 3
      include/dxc/HLSL/DxilExportMap.h
  2. 18 22
      lib/HLSL/DxilLinker.cpp

+ 2 - 3
include/dxc/HLSL/DxilExportMap.h

@@ -20,8 +20,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/MapVector.h"
 
 namespace llvm {
 class Function;
@@ -34,7 +33,7 @@ namespace dxilutil {
   public:
     typedef std::unordered_set<std::string> StringStore;
     typedef std::set<llvm::StringRef> NameSet;
-    typedef llvm::DenseMap< llvm::Function*, NameSet > RenameMap;
+    typedef llvm::MapVector< llvm::Function*, NameSet > RenameMap;
     typedef llvm::StringMap< llvm::StringSet<> > ExportMapByString;
     typedef ExportMapByString::iterator iterator;
     typedef ExportMapByString::const_iterator const_iterator;

+ 18 - 22
lib/HLSL/DxilLinker.cpp

@@ -17,8 +17,10 @@
 #include "dxc/DXIL/DxilSampler.h"
 #include "dxc/DXIL/DxilUtil.h"
 #include "dxc/Support/Global.h"
-#include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Instructions.h"
@@ -50,7 +52,7 @@ using namespace hlsl;
 namespace {
 
 void CollectUsedFunctions(Constant *C,
-                          std::unordered_set<Function *> &funcSet) {
+                          llvm::SetVector<Function *> &funcSet) {
   for (User *U : C->users()) {
     if (Instruction *I = dyn_cast<Instruction>(U)) {
       funcSet.insert(I->getParent()->getParent());
@@ -64,7 +66,7 @@ void CollectUsedFunctions(Constant *C,
 template <class T>
 void AddResourceMap(
     const std::vector<std::unique_ptr<T>> &resTab, DXIL::ResourceClass resClass,
-    std::unordered_map<const llvm::Constant *, DxilResourceBase *> &resMap,
+    llvm::MapVector<const llvm::Constant *, DxilResourceBase *> &resMap,
     DxilModule &DM) {
   for (auto &Res : resTab) {
     resMap[Res->GetGlobalSymbol()] = Res.get();
@@ -101,9 +103,9 @@ namespace {
 struct DxilFunctionLinkInfo {
   DxilFunctionLinkInfo(llvm::Function *F);
   llvm::Function *func;
-  std::unordered_set<llvm::Function *> usedFunctions;
-  std::unordered_set<llvm::GlobalVariable *> usedGVs;
-  std::unordered_set<DxilResourceBase *> usedResources;
+  // SetVectors for deterministic iteration
+  llvm::SetVector<llvm::Function *> usedFunctions;
+  llvm::SetVector<llvm::GlobalVariable *> usedGVs;
 };
 
 // Library to link.
@@ -131,10 +133,10 @@ private:
   DxilModule &m_DM;
   // Map from name to Link info for extern functions.
   llvm::StringMap<std::unique_ptr<DxilFunctionLinkInfo>> m_functionNameMap;
-  // Map from resource link global to resource.
-  std::unordered_map<const llvm::Constant *, DxilResourceBase *> m_resourceMap;
-  // Set of initialize functions for global variable.
-  std::unordered_set<llvm::Function *> m_initFuncSet;
+  // Map from resource link global to resource. MapVector for deterministic iteration.
+  llvm::MapVector<const llvm::Constant *, DxilResourceBase *> m_resourceMap;
+  // Set of initialize functions for global variable. SetVector for deterministic iteration.
+  llvm::SetVector<llvm::Function *> m_initFuncSet;
 };
 
 struct DxilLinkJob;
@@ -264,7 +266,7 @@ void DxilLib::BuildGlobalUsage() {
 
   // Build used globals.
   for (GlobalVariable &GV : M.globals()) {
-    std::unordered_set<Function *> funcSet;
+    llvm::SetVector<Function *> funcSet;
     CollectUsedFunctions(&GV, funcSet);
     for (Function *F : funcSet) {
       DXASSERT(m_functionNameMap.count(F->getName()), "must exist in table");
@@ -292,7 +294,7 @@ void DxilLib::CollectUsedInitFunctions(StringSet<> &addedFunctionSet,
     // If function other than Ctor used GV of Ctor.
     // Add Ctor to usedFunctions for it.
     for (GlobalVariable *GV : linkInfo->usedGVs) {
-      std::unordered_set<Function *> funcSet;
+      llvm::SetVector<Function *> funcSet;
       CollectUsedFunctions(GV, funcSet);
       bool bAdded = false;
       for (Function *F : funcSet) {
@@ -348,8 +350,7 @@ private:
   void AddFunctionDecls(Module *pM);
   bool AddGlobals(DxilModule &DM, ValueToValueMapTy &vmap);
   void CloneFunctions(ValueToValueMapTy &vmap);
-  void AddFunctions(DxilModule &DM, ValueToValueMapTy &vmap,
-                    std::unordered_set<Function *> &initFuncSet);
+  void AddFunctions(DxilModule &DM, ValueToValueMapTy &vmap);
   bool AddResource(DxilResourceBase *res, llvm::GlobalVariable *GV);
   void AddResourceToDM(DxilModule &DM);
   std::unordered_map<DxilFunctionLinkInfo *, DxilLib *> m_functionDefs;
@@ -658,8 +659,7 @@ void DxilLinkJob::CloneFunctions(ValueToValueMapTy &vmap) {
   }
 }
 
-void DxilLinkJob::AddFunctions(DxilModule &DM, ValueToValueMapTy &vmap,
-                               std::unordered_set<Function *> &initFuncSet) {
+void DxilLinkJob::AddFunctions(DxilModule &DM, ValueToValueMapTy &vmap) {
   DxilTypeSystem &typeSys = DM.GetTypeSystem();
   Module *pM = DM.GetModule();
   for (auto &it : m_functionDefs) {
@@ -684,8 +684,6 @@ void DxilLinkJob::AddFunctions(DxilModule &DM, ValueToValueMapTy &vmap,
 
     // Add to function map.
     m_newFunctions[NewF->getName()] = NewF;
-    if (pLib->IsInitFunc(F))
-      initFuncSet.insert(NewF);
 
     vmap[F] = NewF;
   }
@@ -730,9 +728,8 @@ DxilLinkJob::Link(std::pair<DxilFunctionLinkInfo *, DxilLib *> &entryLinkPair,
 
   ValueToValueMapTy vmap;
 
-  std::unordered_set<Function *> initFuncSet;
   // Add function
-  AddFunctions(DM, vmap, initFuncSet);
+  AddFunctions(DM, vmap);
 
   // Set Entry
   Function *NewEntryFunc = m_newFunctions[entryFunc->getName()];
@@ -822,9 +819,8 @@ DxilLinkJob::LinkToLib(const ShaderModel *pSM) {
 
   ValueToValueMapTy vmap;
 
-  std::unordered_set<Function *> initFuncSet;
   // Add function
-  AddFunctions(DM, vmap, initFuncSet);
+  AddFunctions(DM, vmap);
 
   // Set DxilFunctionProps.
   DxilEntryPropsMap EntryPropMap;