Index: lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- lib/Transforms/IPO/FunctionImport.cpp +++ lib/Transforms/IPO/FunctionImport.cpp @@ -581,20 +581,24 @@ auto &ImportGUIDs = FunctionsToImportPerModule->second; // Find the globals to import DenseSet GlobalsToImport; - for (auto &GV : *SrcModule) { - if (!GV.hasName()) + for (Function &F : *SrcModule) { + if (!F.hasName()) continue; - auto GUID = GV.getGUID(); + auto GUID = F.getGUID(); auto Import = ImportGUIDs.count(GUID); DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing function " << GUID - << " " << GV.getName() << " from " + << " " << F.getName() << " from " << SrcModule->getSourceFileName() << "\n"); if (Import) { - GV.materialize(); - GlobalsToImport.insert(&GV); + F.materialize(); + // Add 'thin_lto_imported' metadata for statistics and debugging. + F.setMetadata("thin_lto_imported", + llvm::MDNode::get(DestModule.getContext(), + llvm::ArrayRef())); + GlobalsToImport.insert(&F); } } - for (auto &GV : SrcModule->globals()) { + for (GlobalVariable &GV : SrcModule->globals()) { if (!GV.hasName()) continue; auto GUID = GV.getGUID(); @@ -607,20 +611,20 @@ GlobalsToImport.insert(&GV); } } - for (auto &GV : SrcModule->aliases()) { - if (!GV.hasName()) + for (GlobalAlias &GA : SrcModule->aliases()) { + if (!GA.hasName()) continue; - auto GUID = GV.getGUID(); + auto GUID = GA.getGUID(); auto Import = ImportGUIDs.count(GUID); DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing alias " << GUID - << " " << GV.getName() << " from " + << " " << GA.getName() << " from " << SrcModule->getSourceFileName() << "\n"); if (Import) { // Alias can't point to "available_externally". However when we import // linkOnceODR the linkage does not change. So we import the alias // and aliasee only in this case. This has been handled by // computeImportForFunction() - GlobalObject *GO = GV.getBaseObject(); + GlobalObject *GO = GA.getBaseObject(); assert(GO->hasLinkOnceODRLinkage() && "Unexpected alias to a non-linkonceODR in import list"); #ifndef NDEBUG @@ -631,8 +635,8 @@ #endif GO->materialize(); GlobalsToImport.insert(GO); - GV.materialize(); - GlobalsToImport.insert(&GV); + GA.materialize(); + GlobalsToImport.insert(&GA); } } Index: test/Transforms/FunctionImport/funcimport.ll =================================================================== --- test/Transforms/FunctionImport/funcimport.ll +++ test/Transforms/FunctionImport/funcimport.ll @@ -14,7 +14,7 @@ ; Test import with smaller instruction limit and without the -disable-force-link-odr ; RUN: opt -function-import -summary-file %t3.thinlto.bc %t.bc -import-instr-limit=5 -S | FileCheck %s --check-prefix=INSTLIM5ODR -; INSTLIM5ODR: define linkonce_odr void @linkonceodr() +; INSTLIM5ODR: define linkonce_odr void @linkonceodr() { define i32 @main() #0 { @@ -47,7 +47,7 @@ declare void @linkoncealias(...) #1 ; INSTLIMDEF-DAG: Import referencestatics -; INSTLIMDEF-DAG: define available_externally i32 @referencestatics(i32 %i) +; INSTLIMDEF-DAG: define available_externally i32 @referencestatics(i32 %i) !thin_lto_imported !0 { ; INSTLIM5-DAG: declare i32 @referencestatics(...) declare i32 @referencestatics(...) #1 @@ -56,27 +56,27 @@ ; Ensure that the call is to the properly-renamed function. ; INSTLIMDEF-DAG: Import staticfunc ; INSTLIMDEF-DAG: %call = call i32 @staticfunc.llvm. -; INSTLIMDEF-DAG: define available_externally hidden i32 @staticfunc.llvm. +; INSTLIMDEF-DAG: define available_externally hidden i32 @staticfunc.llvm.{{.*}} !thin_lto_imported !0 { ; INSTLIMDEF-DAG: Import referenceglobals -; CHECK-DAG: define available_externally i32 @referenceglobals(i32 %i) +; CHECK-DAG: define available_externally i32 @referenceglobals(i32 %i) !thin_lto_imported !0 { declare i32 @referenceglobals(...) #1 ; The import of referenceglobals will expose call to globalfunc1 that ; should in turn be imported. ; INSTLIMDEF-DAG: Import globalfunc1 -; CHECK-DAG: define available_externally void @globalfunc1() +; CHECK-DAG: define available_externally void @globalfunc1() !thin_lto_imported !0 ; INSTLIMDEF-DAG: Import referencecommon -; CHECK-DAG: define available_externally i32 @referencecommon(i32 %i) +; CHECK-DAG: define available_externally i32 @referencecommon(i32 %i) !thin_lto_imported !0 { declare i32 @referencecommon(...) #1 ; INSTLIMDEF-DAG: Import setfuncptr -; CHECK-DAG: define available_externally void @setfuncptr() +; CHECK-DAG: define available_externally void @setfuncptr() !thin_lto_imported !0 { declare void @setfuncptr(...) #1 ; INSTLIMDEF-DAG: Import callfuncptr -; CHECK-DAG: define available_externally void @callfuncptr() +; CHECK-DAG: define available_externally void @callfuncptr() !thin_lto_imported !0 { declare void @callfuncptr(...) #1 ; Ensure that all uses of local variable @P which has used in setfuncptr @@ -87,7 +87,7 @@ ; Ensure that @referencelargelinkonce definition is pulled in, but later we ; also check that the linkonceodr function is not. -; CHECK-DAG: define available_externally void @referencelargelinkonce() +; CHECK-DAG: define available_externally void @referencelargelinkonce() !thin_lto_imported !0 { ; INSTLIM5-DAG: declare void @linkonceodr() declare void @referencelargelinkonce(...) @@ -100,7 +100,7 @@ declare void @linkoncefunc2(...) #1 ; INSTLIMDEF-DAG: Import funcwithpersonality -; INSTLIMDEF-DAG: define available_externally hidden void @funcwithpersonality.llvm.{{.*}}() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +; INSTLIMDEF-DAG: define available_externally hidden void @funcwithpersonality.llvm.{{.*}}() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !thin_lto_imported !0 { ; INSTLIM5-DAG: declare hidden void @funcwithpersonality.llvm.{{.*}}() ; INSTLIMDEF-DAG: Import globalfunc2