|
@@ -128,6 +128,8 @@ public:
|
|
|
void CollectUsedInitFunctions(SetVector<StringRef> &addedFunctionSet,
|
|
|
SmallVector<StringRef, 4> &workList);
|
|
|
|
|
|
+ void FixIntrinsicOverloads();
|
|
|
+
|
|
|
private:
|
|
|
std::unique_ptr<llvm::Module> m_pModule;
|
|
|
DxilModule &m_DM;
|
|
@@ -188,7 +190,7 @@ DxilFunctionLinkInfo::DxilFunctionLinkInfo(Function *F) : func(F) {
|
|
|
DxilLib::DxilLib(std::unique_ptr<llvm::Module> pModule)
|
|
|
: m_pModule(std::move(pModule)), m_DM(m_pModule->GetOrCreateDxilModule()) {
|
|
|
Module &M = *m_pModule;
|
|
|
- const std::string &MID = M.getModuleIdentifier();
|
|
|
+ const std::string MID = (Twine(M.getModuleIdentifier()) + ".").str();
|
|
|
|
|
|
// Collect function defines.
|
|
|
for (Function &F : M.functions()) {
|
|
@@ -211,6 +213,14 @@ DxilLib::DxilLib(std::unique_ptr<llvm::Module> pModule)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void DxilLib::FixIntrinsicOverloads() {
|
|
|
+ // Fix DXIL overload name collisions that may be caused by name
|
|
|
+ // collisions between dxil ops with different overload types,
|
|
|
+ // when those types may have had the same name in the original
|
|
|
+ // modules.
|
|
|
+ m_DM.GetOP()->FixOverloadNames();
|
|
|
+}
|
|
|
+
|
|
|
void DxilLib::LazyLoadFunction(Function *F) {
|
|
|
DXASSERT(m_functionNameMap.count(F->getName()), "else invalid Function");
|
|
|
DxilFunctionLinkInfo *linkInfo = m_functionNameMap[F->getName()].get();
|
|
@@ -354,14 +364,24 @@ private:
|
|
|
bool AddResource(DxilResourceBase *res, llvm::GlobalVariable *GV);
|
|
|
void AddResourceToDM(DxilModule &DM);
|
|
|
llvm::MapVector<DxilFunctionLinkInfo *, DxilLib *> m_functionDefs;
|
|
|
- llvm::StringMap<llvm::Function *> m_functionDecls;
|
|
|
- // New created functions.
|
|
|
- llvm::StringMap<llvm::Function *> m_newFunctions;
|
|
|
- // New created globals.
|
|
|
- llvm::StringMap<llvm::GlobalVariable *> m_newGlobals;
|
|
|
- // Map for resource.
|
|
|
- llvm::StringMap<std::pair<DxilResourceBase *, llvm::GlobalVariable *>>
|
|
|
- m_resourceMap;
|
|
|
+
|
|
|
+ // Function decls, in order added.
|
|
|
+ llvm::MapVector<llvm::StringRef,
|
|
|
+ std::pair<llvm::SmallPtrSet<llvm::FunctionType *, 2>,
|
|
|
+ llvm::SmallVector<llvm::Function *, 2>>>
|
|
|
+ m_functionDecls;
|
|
|
+
|
|
|
+ // New created functions, in order added.
|
|
|
+ llvm::MapVector<llvm::StringRef, llvm::Function *> m_newFunctions;
|
|
|
+
|
|
|
+ // New created globals, in order added.
|
|
|
+ llvm::MapVector<llvm::StringRef, llvm::GlobalVariable *> m_newGlobals;
|
|
|
+
|
|
|
+ // Map for resource, ordered by name.
|
|
|
+ std::map<llvm::StringRef,
|
|
|
+ std::pair<DxilResourceBase *, llvm::GlobalVariable *>>
|
|
|
+ m_resourceMap;
|
|
|
+
|
|
|
LLVMContext &m_ctx;
|
|
|
dxilutil::ExportMap &m_exportMap;
|
|
|
unsigned m_valMajor, m_valMinor;
|
|
@@ -575,11 +595,15 @@ void DxilLinkJob::LinkNamedMDNodes(Module *pM, ValueToValueMapTy &vmap) {
|
|
|
|
|
|
void DxilLinkJob::AddFunctionDecls(Module *pM) {
|
|
|
for (auto &it : m_functionDecls) {
|
|
|
- Function *F = it.second;
|
|
|
- Function *NewF = Function::Create(F->getFunctionType(), F->getLinkage(),
|
|
|
- F->getName(), pM);
|
|
|
- NewF->setAttributes(F->getAttributes());
|
|
|
- m_newFunctions[NewF->getName()] = NewF;
|
|
|
+ for (auto F : it.second.second) {
|
|
|
+ Function *NewF = pM->getFunction(F->getName());
|
|
|
+ if (!NewF || F->getFunctionType() != NewF->getFunctionType()) {
|
|
|
+ NewF = Function::Create(F->getFunctionType(), F->getLinkage(),
|
|
|
+ F->getName(), pM);
|
|
|
+ NewF->setAttributes(F->getAttributes());
|
|
|
+ }
|
|
|
+ m_newFunctions[F->getName()] = NewF;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -934,7 +958,12 @@ void DxilLinkJob::AddFunction(
|
|
|
}
|
|
|
|
|
|
void DxilLinkJob::AddFunction(llvm::Function *F) {
|
|
|
- m_functionDecls[F->getName()] = F;
|
|
|
+ // Rarely, DXIL op overloads could collide, due to different types with same name.
|
|
|
+ // Later, we will rename these functions, but for now, we need to prevent clobbering
|
|
|
+ // an existing entry.
|
|
|
+ auto &entry = m_functionDecls[F->getName()];
|
|
|
+ if (entry.first.insert(F->getFunctionType()).second)
|
|
|
+ entry.second.push_back(F);
|
|
|
}
|
|
|
|
|
|
// Clone of StripDeadDebugInfo::runOnModule.
|
|
@@ -1315,6 +1344,11 @@ DxilLinkerImpl::Link(StringRef entry, StringRef profile, dxilutil::ExportMap &ex
|
|
|
for (auto &pLib : libSet) {
|
|
|
pLib->CollectUsedInitFunctions(addedFunctionSet, workList);
|
|
|
}
|
|
|
+
|
|
|
+ for (auto &pLib : libSet) {
|
|
|
+ pLib->FixIntrinsicOverloads();
|
|
|
+ }
|
|
|
+
|
|
|
// Add init functions if used.
|
|
|
// All init function already loaded in BuildGlobalUsage,
|
|
|
// so set bLazyLoadDone to true here.
|