diff options
-rw-r--r-- | llvm/lib/Transforms/IPO/FunctionImport.cpp | 38 | ||||
-rw-r--r-- | llvm/test/Transforms/FunctionImport/funcimport.ll | 10 |
2 files changed, 46 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp index c874e4f5da7..bd6eb8391dc 100644 --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -131,10 +131,24 @@ bool FunctionImporter::importFunctions(Module &M) { // The function that we will import! GlobalValue *SGV = Module.getNamedValue(CalledFunctionName); + StringRef ImportFunctionName = CalledFunctionName; + if (!SGV) { + // Might be local in source Module, promoted/renamed in dest Module M. + std::pair<StringRef, StringRef> Split = + CalledFunctionName.split(".llvm."); + SGV = Module.getNamedValue(Split.first); +#ifndef NDEBUG + // Assert that Split.second is module id + uint64_t ModuleId; + assert(!Split.second.getAsInteger(10, ModuleId)); + assert(ModuleId == Index.getModuleId(FileName)); +#endif + } Function *F = dyn_cast<Function>(SGV); if (!F && isa<GlobalAlias>(SGV)) { auto *SGA = dyn_cast<GlobalAlias>(SGV); F = dyn_cast<Function>(SGA->getBaseObject()); + ImportFunctionName = F->getName(); } if (!F) { errs() << "Can't load function '" << CalledFunctionName << "' in Module '" @@ -156,8 +170,28 @@ bool FunctionImporter::importFunctions(Module &M) { if (L.linkInModule(&Module, Linker::Flags::None, &Index, F)) report_fatal_error("Function Import: link error"); - // TODO: Process the newly imported function and add callees to the - // worklist. + // Process the newly imported function and add callees to the worklist. + GlobalValue *NewGV = M.getNamedValue(ImportFunctionName); + assert(NewGV); + Function *NewF = dyn_cast<Function>(NewGV); + assert(NewF); + + for (auto &BB : *NewF) { + for (auto &I : BB) { + if (isa<CallInst>(I)) { + DEBUG(dbgs() << "Found a call: '" << I << "'\n"); + auto CalledFunction = cast<CallInst>(I).getCalledFunction(); + // Insert any new external calls that have not already been + // added to set/worklist. + if (CalledFunction && CalledFunction->hasName() && + CalledFunction->isDeclaration() && + !CalledFunctions.count(CalledFunction->getName())) { + CalledFunctions.insert(CalledFunction->getName()); + Worklist.push_back(CalledFunction->getName()); + } + } + } + } Changed = true; } diff --git a/llvm/test/Transforms/FunctionImport/funcimport.ll b/llvm/test/Transforms/FunctionImport/funcimport.ll index 43b2fb7919d..553d05bfcf3 100644 --- a/llvm/test/Transforms/FunctionImport/funcimport.ll +++ b/llvm/test/Transforms/FunctionImport/funcimport.ll @@ -31,9 +31,19 @@ declare void @analias(...) #1 ; CHECK-DAG: define available_externally i32 @referencestatics(i32 %i) declare i32 @referencestatics(...) #1 +; The import of referencestatics will expose call to staticfunc that +; should in turn be imported as a promoted/renamed and hidden function. +; Ensure that the call is to the properly-renamed function. +; CHECK-DAG: %call = call i32 @staticfunc.llvm.2() +; CHECK-DAG: define available_externally hidden i32 @staticfunc.llvm.2() + ; CHECK-DAG: define available_externally i32 @referenceglobals(i32 %i) declare i32 @referenceglobals(...) #1 +; The import of referenceglobals will expose call to globalfunc1 that +; should in turn be imported. +; CHECK-DAG: define available_externally void @globalfunc1() + ; CHECK-DAG: define available_externally i32 @referencecommon(i32 %i) declare i32 @referencecommon(...) #1 |