/// Make sure GV is visible from both modules. Delete is true if it is /// being deleted from this module. /// This also makes sure GV cannot be dropped so that references from /// the split module remain valid. static void makeVisible(GlobalValue &GV, bool Delete, bool IsDeletePass) { bool Local = GV.hasLocalLinkage(); if (Local || Delete) { // This changes members from private -> hidden -> causes linker errors when using llvm-link if (!IsDeletePass) GV.setLinkage(GlobalValue::ExternalLinkage); if (Local) GV.setVisibility(GlobalValue::HiddenVisibility); return; } if (!GV.hasLinkOnceLinkage()) { assert(!GV.isDiscardableIfUnused()); return; } // Map linkonce* to weak* so that llvm doesn't drop this GV. switch(GV.getLinkage()) { default: llvm_unreachable("Unexpected linkage"); case GlobalValue::LinkOnceAnyLinkage: GV.setLinkage(GlobalValue::WeakAnyLinkage); return; case GlobalValue::LinkOnceODRLinkage: GV.setLinkage(GlobalValue::WeakODRLinkage); return; } }
GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV, bool ForDefinition) { GlobalValue *NewGV; if (auto *SGVar = dyn_cast<GlobalVariable>(SGV)) { NewGV = copyGlobalVariableProto(SGVar); } else if (auto *SF = dyn_cast<Function>(SGV)) { NewGV = copyFunctionProto(SF); } else { if (ForDefinition) NewGV = copyGlobalAliasProto(cast<GlobalAlias>(SGV)); else NewGV = new GlobalVariable( DstM, TypeMap.get(SGV->getType()->getElementType()), /*isConstant*/ false, GlobalValue::ExternalLinkage, /*init*/ nullptr, SGV->getName(), /*insertbefore*/ nullptr, SGV->getThreadLocalMode(), SGV->getType()->getAddressSpace()); } if (ForDefinition) NewGV->setLinkage(SGV->getLinkage()); else if (SGV->hasExternalWeakLinkage() || SGV->hasWeakLinkage() || SGV->hasLinkOnceLinkage()) NewGV->setLinkage(GlobalValue::ExternalWeakLinkage); NewGV->copyAttributesFrom(SGV); return NewGV; }
void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { bool DoPromote = false; if (GV.hasLocalLinkage() && ((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) { // Once we change the name or linkage it is difficult to determine // again whether we should promote since shouldPromoteLocalToGlobal needs // to locate the summary (based on GUID from name and linkage). Therefore, // use DoPromote result saved above. GV.setName(getName(&GV, DoPromote)); GV.setLinkage(getLinkage(&GV, DoPromote)); if (!GV.hasLocalLinkage()) GV.setVisibility(GlobalValue::HiddenVisibility); } else GV.setLinkage(getLinkage(&GV, /* DoPromote */ false)); // Remove functions imported as available externally defs from comdats, // as this is a declaration for the linker, and will be dropped eventually. // It is illegal for comdats to contain declarations. auto *GO = dyn_cast_or_null<GlobalObject>(&GV); if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) { // The IRMover should not have placed any imported declarations in // a comdat, so the only declaration that should be in a comdat // at this point would be a definition imported as available_externally. assert(GO->hasAvailableExternallyLinkage() && "Expected comdat on definition (possibly available external)"); GO->setComdat(nullptr); } }
/// Make sure GV is visible from both modules. Delete is true if it is /// being deleted from this module. /// This also makes sure GV cannot be dropped so that references from /// the split module remain valid. static void makeVisible(GlobalValue &GV, bool Delete) { bool Local = GV.hasLocalLinkage(); if (Local) GV.setVisibility(GlobalValue::HiddenVisibility); if (Local || Delete) { GV.setLinkage(GlobalValue::ExternalLinkage); return; } if (!GV.hasLinkOnceLinkage()) { assert(!GV.isDiscardableIfUnused()); return; } // Map linkonce* to weak* so that llvm doesn't drop this GV. switch(GV.getLinkage()) { default: llvm_unreachable("Unexpected linkage"); case GlobalValue::LinkOnceAnyLinkage: GV.setLinkage(GlobalValue::WeakAnyLinkage); return; case GlobalValue::LinkOnceODRLinkage: GV.setLinkage(GlobalValue::WeakODRLinkage); return; } }
void ThinLTOGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { if (GV.hasLocalLinkage() && (doPromoteLocalToGlobal(&GV) || isPerformingImport())) { GV.setName(getName(&GV)); GV.setLinkage(getLinkage(&GV)); if (!GV.hasLocalLinkage()) GV.setVisibility(GlobalValue::HiddenVisibility); if (isModuleExporting()) NewExportedValues.insert(&GV); return; } GV.setLinkage(getLinkage(&GV)); }
// llvm_mark_decl_weak - Used by varasm.c, called when a decl is found to be // weak, but it already had an llvm object created for it. This marks the LLVM // object weak as well. void llvm_mark_decl_weak(tree decl) { assert(DECL_LLVM_SET_P(decl) && DECL_WEAK(decl) && isa<GlobalValue>(DECL_LLVM(decl)) && "Decl isn't marked weak!"); GlobalValue *GV = cast<GlobalValue>(DECL_LLVM(decl)); // Do not mark something that is already known to be linkonce or internal. if (GV->hasExternalLinkage()) { if (GV->isDeclaration()) GV->setLinkage(GlobalValue::ExternalWeakLinkage); else GV->setLinkage(GlobalValue::WeakLinkage); } }
/// gold informs us that all symbols have been read. At this point, we use /// get_symbols to see if any of our definitions have been overridden by a /// native object file. Then, perform optimization and codegen. static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { if (Modules.empty()) return LDPS_OK; LLVMContext Context; std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context)); Linker L(Combined.get()); std::string DefaultTriple = sys::getDefaultTargetTriple(); StringSet<> Internalize; StringSet<> Maybe; for (claimed_file &F : Modules) { std::unique_ptr<Module> M = getModuleForFile(Context, F, ApiFile, Internalize, Maybe); if (!options::triple.empty()) M->setTargetTriple(options::triple.c_str()); else if (M->getTargetTriple().empty()) { M->setTargetTriple(DefaultTriple); } if (L.linkInModule(M.get())) message(LDPL_FATAL, "Failed to link module"); } for (const auto &Name : Internalize) { GlobalValue *GV = Combined->getNamedValue(Name.first()); if (GV) internalize(*GV); } for (const auto &Name : Maybe) { GlobalValue *GV = Combined->getNamedValue(Name.first()); if (!GV) continue; GV->setLinkage(GlobalValue::LinkOnceODRLinkage); if (canBeOmittedFromSymbolTable(GV)) internalize(*GV); } if (options::generate_bc_file != options::BC_NO) { std::string path; if (options::generate_bc_file == options::BC_ONLY) path = output_name; else path = output_name + ".bc"; saveBCFile(path, *L.getModule()); if (options::generate_bc_file == options::BC_ONLY) return LDPS_OK; } codegen(*L.getModule()); if (!options::extra_library_path.empty() && set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK) message(LDPL_FATAL, "Unable to set the extra library path."); return LDPS_OK; }
void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { // Check the summaries to see if the symbol gets resolved to a known local // definition. if (GV.hasName()) { ValueInfo VI = ImportIndex.getValueInfo(GV.getGUID()); if (VI) { // Need to check all summaries are local in case of hash collisions. bool IsLocal = VI.getSummaryList().size() && llvm::all_of(VI.getSummaryList(), [](const std::unique_ptr<GlobalValueSummary> &Summary) { return Summary->isDSOLocal(); }); if (IsLocal) GV.setDSOLocal(true); } } bool DoPromote = false; if (GV.hasLocalLinkage() && ((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) { // Once we change the name or linkage it is difficult to determine // again whether we should promote since shouldPromoteLocalToGlobal needs // to locate the summary (based on GUID from name and linkage). Therefore, // use DoPromote result saved above. GV.setName(getName(&GV, DoPromote)); GV.setLinkage(getLinkage(&GV, DoPromote)); if (!GV.hasLocalLinkage()) GV.setVisibility(GlobalValue::HiddenVisibility); } else GV.setLinkage(getLinkage(&GV, /* DoPromote */ false)); // Remove functions imported as available externally defs from comdats, // as this is a declaration for the linker, and will be dropped eventually. // It is illegal for comdats to contain declarations. auto *GO = dyn_cast_or_null<GlobalObject>(&GV); if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) { // The IRMover should not have placed any imported declarations in // a comdat, so the only declaration that should be in a comdat // at this point would be a definition imported as available_externally. assert(GO->hasAvailableExternallyLinkage() && "Expected comdat on definition (possibly available external)"); GO->setComdat(nullptr); } }
static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R) { if (V.hasLocalLinkage()) { if (R.needsRenaming(V)) V.setName(R.getRename(V)); V.setLinkage(GlobalValue::ExternalLinkage); V.setVisibility(GlobalValue::HiddenVisibility); } V.setUnnamedAddr(GlobalValue::UnnamedAddr::None); assert(!R.needsRenaming(V) && "Invalid global name."); }
GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV, bool ForDefinition) { GlobalValue *NewGV; if (auto *SGVar = dyn_cast<GlobalVariable>(SGV)) { NewGV = copyGlobalVariableProto(SGVar); } else if (auto *SF = dyn_cast<Function>(SGV)) { NewGV = copyFunctionProto(SF); } else { if (ForDefinition) NewGV = copyGlobalAliasProto(cast<GlobalAlias>(SGV)); else NewGV = new GlobalVariable( DstM, TypeMap.get(SGV->getValueType()), /*isConstant*/ false, GlobalValue::ExternalLinkage, /*init*/ nullptr, SGV->getName(), /*insertbefore*/ nullptr, SGV->getThreadLocalMode(), SGV->getType()->getAddressSpace()); } if (ForDefinition) NewGV->setLinkage(SGV->getLinkage()); else if (SGV->hasExternalWeakLinkage()) NewGV->setLinkage(GlobalValue::ExternalWeakLinkage); NewGV->copyAttributesFrom(SGV); if (auto *NewGO = dyn_cast<GlobalObject>(NewGV)) { // Metadata for global variables and function declarations is copied eagerly. if (isa<GlobalVariable>(SGV) || SGV->isDeclaration()) NewGO->copyMetadata(cast<GlobalObject>(SGV), 0); } // Remove these copied constants in case this stays a declaration, since // they point to the source module. If the def is linked the values will // be mapped in during linkFunctionBody. if (auto *NewF = dyn_cast<Function>(NewGV)) { NewF->setPersonalityFn(nullptr); NewF->setPrefixData(nullptr); NewF->setPrologueData(nullptr); } return NewGV; }
static void keepGlobalValue(GlobalValue &GV, std::vector<GlobalAlias *> &KeptAliases) { assert(!GV.hasLocalLinkage()); if (auto *GA = dyn_cast<GlobalAlias>(&GV)) KeptAliases.push_back(GA); switch (GV.getLinkage()) { default: break; case GlobalValue::LinkOnceAnyLinkage: GV.setLinkage(GlobalValue::WeakAnyLinkage); break; case GlobalValue::LinkOnceODRLinkage: GV.setLinkage(GlobalValue::WeakODRLinkage); break; } assert(!GV.isDiscardableIfUnused()); }
/// linkFunctionProto - Link the function in the source module into the /// destination module if needed, setting up mapping information. bool ModuleLinker::linkFunctionProto(Function *SF) { GlobalValue *DGV = getLinkedToGlobal(SF); llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility; if (DGV) { GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; bool LinkFromSrc = false; GlobalValue::VisibilityTypes NV; if (getLinkageResult(DGV, SF, NewLinkage, NV, LinkFromSrc)) return true; NewVisibility = NV; if (!LinkFromSrc) { // Set calculated linkage DGV->setLinkage(NewLinkage); DGV->setVisibility(*NewVisibility); // Make sure to remember this mapping. ValueMap[SF] = ConstantExpr::getBitCast(DGV, TypeMap.get(SF->getType())); // Track the function from the source module so we don't attempt to remap // it. DoNotLinkFromSource.insert(SF); return false; } } // If there is no linkage to be performed or we are linking from the source, // bring SF over. Function *NewDF = Function::Create(TypeMap.get(SF->getFunctionType()), SF->getLinkage(), SF->getName(), DstM); CopyGVAttributes(NewDF, SF); if (NewVisibility) NewDF->setVisibility(*NewVisibility); if (DGV) { // Any uses of DF need to change to NewDF, with cast. DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDF, DGV->getType())); DGV->eraseFromParent(); } else { // Internal, LO_ODR, or LO linkage - stick in set to ignore and lazily link. if (SF->hasLocalLinkage() || SF->hasLinkOnceLinkage() || SF->hasAvailableExternallyLinkage()) { DoNotLinkFromSource.insert(SF); LazilyLinkFunctions.push_back(SF); } } ValueMap[SF] = NewDF; return false; }
/// LinkAliasProto - Set up prototypes for any aliases that come over from the /// source module. bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) { GlobalValue *DGV = getLinkedToGlobal(SGA); llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility; if (DGV) { GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; GlobalValue::VisibilityTypes NV; bool LinkFromSrc = false; if (getLinkageResult(DGV, SGA, NewLinkage, NV, LinkFromSrc)) return true; NewVisibility = NV; if (!LinkFromSrc) { // Set calculated linkage. DGV->setLinkage(NewLinkage); DGV->setVisibility(*NewVisibility); // Make sure to remember this mapping. ValueMap[SGA] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGA->getType())); // Track the alias from the source module so we don't attempt to remap it. DoNotLinkFromSource.insert(SGA); return false; } } // If there is no linkage to be performed or we're linking from the source, // bring over SGA. GlobalAlias *NewDA = new GlobalAlias(TypeMap.get(SGA->getType()), SGA->getLinkage(), SGA->getName(), /*aliasee*/0, DstM); CopyGVAttributes(NewDA, SGA); if (NewVisibility) NewDA->setVisibility(*NewVisibility); if (DGV) { // Any uses of DGV need to change to NewDA, with cast. DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDA, DGV->getType())); DGV->eraseFromParent(); } ValueMap[SGA] = NewDA; return false; }
bool ModuleLinker::run() { Module &DstM = Mover.getModule(); DenseSet<const Comdat *> ReplacedDstComdats; for (const auto &SMEC : SrcM->getComdatSymbolTable()) { const Comdat &C = SMEC.getValue(); if (ComdatsChosen.count(&C)) continue; Comdat::SelectionKind SK; bool LinkFromSrc; if (getComdatResult(&C, SK, LinkFromSrc)) return true; ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc); if (!LinkFromSrc) continue; Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(C.getName()); if (DstCI == ComdatSymTab.end()) continue; // The source comdat is replacing the dest one. const Comdat *DstC = &DstCI->second; ReplacedDstComdats.insert(DstC); } // Alias have to go first, since we are not able to find their comdats // otherwise. for (auto I = DstM.alias_begin(), E = DstM.alias_end(); I != E;) { GlobalAlias &GV = *I++; dropReplacedComdat(GV, ReplacedDstComdats); } for (auto I = DstM.global_begin(), E = DstM.global_end(); I != E;) { GlobalVariable &GV = *I++; dropReplacedComdat(GV, ReplacedDstComdats); } for (auto I = DstM.begin(), E = DstM.end(); I != E;) { Function &GV = *I++; dropReplacedComdat(GV, ReplacedDstComdats); } for (GlobalVariable &GV : SrcM->globals()) if (GV.hasLinkOnceLinkage()) if (const Comdat *SC = GV.getComdat()) LazyComdatMembers[SC].push_back(&GV); for (Function &SF : *SrcM) if (SF.hasLinkOnceLinkage()) if (const Comdat *SC = SF.getComdat()) LazyComdatMembers[SC].push_back(&SF); for (GlobalAlias &GA : SrcM->aliases()) if (GA.hasLinkOnceLinkage()) if (const Comdat *SC = GA.getComdat()) LazyComdatMembers[SC].push_back(&GA); // Insert all of the globals in src into the DstM module... without linking // initializers (which could refer to functions not yet mapped over). for (GlobalVariable &GV : SrcM->globals()) if (linkIfNeeded(GV)) return true; for (Function &SF : *SrcM) if (linkIfNeeded(SF)) return true; for (GlobalAlias &GA : SrcM->aliases()) if (linkIfNeeded(GA)) return true; for (unsigned I = 0; I < ValuesToLink.size(); ++I) { GlobalValue *GV = ValuesToLink[I]; const Comdat *SC = GV->getComdat(); if (!SC) continue; for (GlobalValue *GV2 : LazyComdatMembers[SC]) { GlobalValue *DGV = getLinkedToGlobal(GV2); bool LinkFromSrc = true; if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) return true; if (LinkFromSrc) ValuesToLink.insert(GV2); } } if (shouldInternalizeLinkedSymbols()) { for (GlobalValue *GV : ValuesToLink) Internalize.insert(GV->getName()); } if (Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(), [this](GlobalValue &GV, IRMover::ValueAdder Add) { addLazyFor(GV, Add); })) return true; for (auto &P : Internalize) { GlobalValue *GV = DstM.getNamedValue(P.first()); GV->setLinkage(GlobalValue::InternalLinkage); } return false; }
static std::unique_ptr<Module> getModuleForFile(LLVMContext &Context, claimed_file &F, const void *View, ld_plugin_input_file &Info, raw_fd_ostream *ApiFile, StringSet<> &Internalize, StringSet<> &Maybe, std::vector<GlobalValue *> &Keep, StringMap<unsigned> &Realign) { MemoryBufferRef BufferRef(StringRef((const char *)View, Info.filesize), Info.name); ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr = object::IRObjectFile::create(BufferRef, Context); if (std::error_code EC = ObjOrErr.getError()) message(LDPL_FATAL, "Could not read bitcode from file : %s", EC.message().c_str()); object::IRObjectFile &Obj = **ObjOrErr; Module &M = Obj.getModule(); M.materializeMetadata(); UpgradeDebugInfo(M); SmallPtrSet<GlobalValue *, 8> Used; collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); unsigned SymNum = 0; for (auto &ObjSym : Obj.symbols()) { GlobalValue *GV = Obj.getSymbolGV(ObjSym.getRawDataRefImpl()); if (GV && GV->hasAppendingLinkage()) Keep.push_back(GV); if (shouldSkip(ObjSym.getFlags())) continue; ld_plugin_symbol &Sym = F.syms[SymNum]; ++SymNum; ld_plugin_symbol_resolution Resolution = (ld_plugin_symbol_resolution)Sym.resolution; if (options::generate_api_file) *ApiFile << Sym.name << ' ' << getResolutionName(Resolution) << '\n'; if (!GV) { freeSymName(Sym); continue; // Asm symbol. } ResolutionInfo &Res = ResInfo[Sym.name]; if (Resolution == LDPR_PREVAILING_DEF_IRONLY_EXP && !Res.IsLinkonceOdr) Resolution = LDPR_PREVAILING_DEF; // In ThinLTO mode change all prevailing resolutions to LDPR_PREVAILING_DEF. // For ThinLTO the IR files are compiled through the backend independently, // so we need to ensure that any prevailing linkonce copy will be emitted // into the object file by making it weak. Additionally, we can skip the // IRONLY handling for internalization, which isn't performed in ThinLTO // mode currently anyway. if (options::thinlto && (Resolution == LDPR_PREVAILING_DEF_IRONLY_EXP || Resolution == LDPR_PREVAILING_DEF_IRONLY)) Resolution = LDPR_PREVAILING_DEF; GV->setUnnamedAddr(Res.UnnamedAddr); GV->setVisibility(Res.Visibility); // Override gold's resolution for common symbols. We want the largest // one to win. if (GV->hasCommonLinkage()) { if (Resolution == LDPR_PREVAILING_DEF_IRONLY) Res.CommonInternal = true; if (Resolution == LDPR_PREVAILING_DEF_IRONLY || Resolution == LDPR_PREVAILING_DEF) Res.UseCommon = true; const DataLayout &DL = GV->getParent()->getDataLayout(); uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType()); unsigned Align = GV->getAlignment(); if (Res.UseCommon && Size >= Res.CommonSize) { // Take GV. if (Res.CommonInternal) Resolution = LDPR_PREVAILING_DEF_IRONLY; else Resolution = LDPR_PREVAILING_DEF; cast<GlobalVariable>(GV)->setAlignment( std::max(Res.CommonAlign, Align)); } else { // Do not take GV, it's smaller than what we already have in the // combined module. Resolution = LDPR_PREEMPTED_IR; if (Align > Res.CommonAlign) // Need to raise the alignment though. Realign[Sym.name] = Align; } Res.CommonSize = std::max(Res.CommonSize, Size); Res.CommonAlign = std::max(Res.CommonAlign, Align); } switch (Resolution) { case LDPR_UNKNOWN: llvm_unreachable("Unexpected resolution"); case LDPR_RESOLVED_IR: case LDPR_RESOLVED_EXEC: case LDPR_RESOLVED_DYN: case LDPR_PREEMPTED_IR: case LDPR_PREEMPTED_REG: break; case LDPR_UNDEF: if (!GV->isDeclarationForLinker()) assert(GV->hasComdat()); break; case LDPR_PREVAILING_DEF_IRONLY: { Keep.push_back(GV); // The IR linker has to be able to map this value to a declaration, // so we can only internalize after linking. if (!Used.count(GV)) Internalize.insert(GV->getName()); break; } case LDPR_PREVAILING_DEF: Keep.push_back(GV); // There is a non IR use, so we have to force optimizations to keep this. switch (GV->getLinkage()) { default: break; case GlobalValue::LinkOnceAnyLinkage: GV->setLinkage(GlobalValue::WeakAnyLinkage); break; case GlobalValue::LinkOnceODRLinkage: GV->setLinkage(GlobalValue::WeakODRLinkage); break; } break; case LDPR_PREVAILING_DEF_IRONLY_EXP: { // We can only check for address uses after we merge the modules. The // reason is that this GV might have a copy in another module // and in that module the address might be significant, but that // copy will be LDPR_PREEMPTED_IR. Maybe.insert(GV->getName()); Keep.push_back(GV); break; } } freeSymName(Sym); } return Obj.takeModule(); }
/// gold informs us that all symbols have been read. At this point, we use /// get_symbols to see if any of our definitions have been overridden by a /// native object file. Then, perform optimization and codegen. static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { if (Modules.empty()) return LDPS_OK; if (unsigned NumOpts = options::extra.size()) cl::ParseCommandLineOptions(NumOpts, &options::extra[0]); // If we are doing ThinLTO compilation, simply build the combined // module index/summary and emit it. We don't need to parse the modules // and link them in this case. if (options::thinlto) { ModuleSummaryIndex CombinedIndex; uint64_t NextModuleId = 0; for (claimed_file &F : Modules) { PluginInputFile InputFile(F.handle); std::unique_ptr<ModuleSummaryIndex> Index = getModuleSummaryIndexForFile(F, InputFile.file()); // Skip files without a module summary. if (Index) CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId); } std::error_code EC; raw_fd_ostream OS(output_name + ".thinlto.bc", EC, sys::fs::OpenFlags::F_None); if (EC) message(LDPL_FATAL, "Unable to open %s.thinlto.bc for writing: %s", output_name.data(), EC.message().c_str()); WriteIndexToFile(CombinedIndex, OS); OS.close(); if (options::thinlto_index_only) { cleanup_hook(); exit(0); } thinLTOBackends(ApiFile, CombinedIndex); return LDPS_OK; } LLVMContext Context; Context.setDiscardValueNames(options::DiscardValueNames); Context.enableDebugTypeODRUniquing(); // Merge debug info types. Context.setDiagnosticHandler(diagnosticHandlerForContext, nullptr, true); std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context)); IRMover L(*Combined); StringSet<> Internalize; StringSet<> Maybe; for (claimed_file &F : Modules) { PluginInputFile InputFile(F.handle); const void *View = getSymbolsAndView(F); if (!View) continue; if (linkInModule(Context, L, F, View, InputFile.file(), ApiFile, Internalize, Maybe)) message(LDPL_FATAL, "Failed to link module"); } for (const auto &Name : Internalize) { GlobalValue *GV = Combined->getNamedValue(Name.first()); if (GV) internalize(*GV); } for (const auto &Name : Maybe) { GlobalValue *GV = Combined->getNamedValue(Name.first()); if (!GV) continue; GV->setLinkage(GlobalValue::LinkOnceODRLinkage); if (canBeOmittedFromSymbolTable(GV)) internalize(*GV); } if (options::TheOutputType == options::OT_DISABLE) return LDPS_OK; if (options::TheOutputType != options::OT_NORMAL) { std::string path; if (options::TheOutputType == options::OT_BC_ONLY) path = output_name; else path = output_name + ".bc"; saveBCFile(path, *Combined); if (options::TheOutputType == options::OT_BC_ONLY) return LDPS_OK; } CodeGen codeGen(std::move(Combined)); codeGen.runAll(); if (!options::extra_library_path.empty() && set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK) message(LDPL_FATAL, "Unable to set the extra library path."); return LDPS_OK; }
void BitcodeCompiler::add(BitcodeFile &F) { std::unique_ptr<IRObjectFile> Obj = check(IRObjectFile::create(F.MB, Context)); std::vector<GlobalValue *> Keep; unsigned BodyIndex = 0; ArrayRef<SymbolBody *> Bodies = F.getSymbols(); Module &M = Obj->getModule(); if (M.getDataLayoutStr().empty()) fatal("invalid bitcode file: " + F.getName() + " has no datalayout"); // If a symbol appears in @llvm.used, the linker is required // to treat the symbol as there is a reference to the symbol // that it cannot see. Therefore, we can't internalize. SmallPtrSet<GlobalValue *, 8> Used; collectUsedGlobalVariables(M, Used, /* CompilerUsed */ false); for (const BasicSymbolRef &Sym : Obj->symbols()) { GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl()); // Ignore module asm symbols. if (!GV) continue; if (GV->hasAppendingLinkage()) { Keep.push_back(GV); continue; } if (BitcodeFile::shouldSkip(Sym)) continue; SymbolBody *B = Bodies[BodyIndex++]; if (!B || &B->repl() != B || !isa<DefinedBitcode>(B)) continue; switch (GV->getLinkage()) { default: break; case llvm::GlobalValue::LinkOnceAnyLinkage: GV->setLinkage(GlobalValue::WeakAnyLinkage); break; case llvm::GlobalValue::LinkOnceODRLinkage: GV->setLinkage(GlobalValue::WeakODRLinkage); break; } // We collect the set of symbols we want to internalize here // and change the linkage after the IRMover executed, i.e. after // we imported the symbols and satisfied undefined references // to it. We can't just change linkage here because otherwise // the IRMover will just rename the symbol. // Shared libraries need to be handled slightly differently. // For now, let's be conservative and just never internalize // symbols when creating a shared library. if (!Config->Shared && !Config->ExportDynamic && !B->isUsedInRegularObj() && !B->MustBeInDynSym) if (!Used.count(GV)) InternalizedSyms.insert(GV->getName()); Keep.push_back(GV); } Mover.move(Obj->takeModule(), Keep, [](GlobalValue &, IRMover::ValueAdder) {}); }
/// gold informs us that all symbols have been read. At this point, we use /// get_symbols to see if any of our definitions have been overridden by a /// native object file. Then, perform optimization and codegen. static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { if (Modules.empty()) return LDPS_OK; LLVMContext Context; Context.setDiagnosticHandler(diagnosticHandler, nullptr, true); // If we are doing ThinLTO compilation, simply build the combined // function index/summary and emit it. We don't need to parse the modules // and link them in this case. if (options::thinlto) { std::unique_ptr<FunctionInfoIndex> CombinedIndex(new FunctionInfoIndex()); uint64_t NextModuleId = 0; for (claimed_file &F : Modules) { ld_plugin_input_file File; if (get_input_file(F.handle, &File) != LDPS_OK) message(LDPL_FATAL, "Failed to get file information"); std::unique_ptr<FunctionInfoIndex> Index = getFunctionIndexForFile(Context, F, File); CombinedIndex->mergeFrom(std::move(Index), ++NextModuleId); } std::error_code EC; raw_fd_ostream OS(output_name + ".thinlto.bc", EC, sys::fs::OpenFlags::F_None); if (EC) message(LDPL_FATAL, "Unable to open %s.thinlto.bc for writing: %s", output_name.data(), EC.message().c_str()); WriteFunctionSummaryToFile(CombinedIndex.get(), OS); OS.close(); cleanup_hook(); exit(0); } std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context)); Linker L(Combined.get()); std::string DefaultTriple = sys::getDefaultTargetTriple(); StringSet<> Internalize; StringSet<> Maybe; for (claimed_file &F : Modules) { ld_plugin_input_file File; if (get_input_file(F.handle, &File) != LDPS_OK) message(LDPL_FATAL, "Failed to get file information"); std::unique_ptr<Module> M = getModuleForFile(Context, F, File, ApiFile, Internalize, Maybe); if (!options::triple.empty()) M->setTargetTriple(options::triple.c_str()); else if (M->getTargetTriple().empty()) { M->setTargetTriple(DefaultTriple); } if (L.linkInModule(M.get())) message(LDPL_FATAL, "Failed to link module"); if (release_input_file(F.handle) != LDPS_OK) message(LDPL_FATAL, "Failed to release file information"); } for (const auto &Name : Internalize) { GlobalValue *GV = Combined->getNamedValue(Name.first()); if (GV) internalize(*GV); } for (const auto &Name : Maybe) { GlobalValue *GV = Combined->getNamedValue(Name.first()); if (!GV) continue; GV->setLinkage(GlobalValue::LinkOnceODRLinkage); if (canBeOmittedFromSymbolTable(GV)) internalize(*GV); } if (options::TheOutputType == options::OT_DISABLE) return LDPS_OK; if (options::TheOutputType != options::OT_NORMAL) { std::string path; if (options::TheOutputType == options::OT_BC_ONLY) path = output_name; else path = output_name + ".bc"; saveBCFile(path, *L.getModule()); if (options::TheOutputType == options::OT_BC_ONLY) return LDPS_OK; } codegen(std::move(Combined)); if (!options::extra_library_path.empty() && set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK) message(LDPL_FATAL, "Unable to set the extra library path."); return LDPS_OK; }
void BitcodeCompiler::add(BitcodeFile &F) { std::unique_ptr<IRObjectFile> Obj = std::move(F.Obj); std::vector<GlobalValue *> Keep; unsigned BodyIndex = 0; ArrayRef<Symbol *> Syms = F.getSymbols(); Module &M = Obj->getModule(); if (M.getDataLayoutStr().empty()) fatal("invalid bitcode file: " + F.getName() + " has no datalayout"); // Discard non-compatible debug infos if necessary. M.materializeMetadata(); UpgradeDebugInfo(M); // If a symbol appears in @llvm.used, the linker is required // to treat the symbol as there is a reference to the symbol // that it cannot see. Therefore, we can't internalize. SmallPtrSet<GlobalValue *, 8> Used; collectUsedGlobalVariables(M, Used, /* CompilerUsed */ false); for (const BasicSymbolRef &Sym : Obj->symbols()) { uint32_t Flags = Sym.getFlags(); GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl()); if (GV && GV->hasAppendingLinkage()) Keep.push_back(GV); if (BitcodeFile::shouldSkip(Flags)) continue; Symbol *S = Syms[BodyIndex++]; if (Flags & BasicSymbolRef::SF_Undefined) { handleUndefinedAsmRefs(Sym, GV, AsmUndefinedRefs); continue; } auto *B = dyn_cast<DefinedBitcode>(S->body()); if (!B || B->File != &F) continue; // We collect the set of symbols we want to internalize here // and change the linkage after the IRMover executed, i.e. after // we imported the symbols and satisfied undefined references // to it. We can't just change linkage here because otherwise // the IRMover will just rename the symbol. if (GV && shouldInternalize(Used, S, GV)) InternalizedSyms.insert(GV->getName()); // At this point we know that either the combined LTO object will provide a // definition of a symbol, or we will internalize it. In either case, we // need to undefine the symbol. In the former case, the real definition // needs to be able to replace the original definition without conflicting. // In the latter case, we need to allow the combined LTO object to provide a // definition with the same name, for example when doing parallel codegen. undefine(S); if (!GV) // Module asm symbol. continue; switch (GV->getLinkage()) { default: break; case llvm::GlobalValue::LinkOnceAnyLinkage: GV->setLinkage(GlobalValue::WeakAnyLinkage); break; case llvm::GlobalValue::LinkOnceODRLinkage: GV->setLinkage(GlobalValue::WeakODRLinkage); break; } Keep.push_back(GV); } if (Error E = Mover.move(Obj->takeModule(), Keep, [](GlobalValue &, IRMover::ValueAdder) {})) { handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) { fatal("failed to link module " + F.getName() + ": " + EIB.message()); }); } }
bool ModuleLinker::run() { for (const auto &SMEC : SrcM.getComdatSymbolTable()) { const Comdat &C = SMEC.getValue(); if (ComdatsChosen.count(&C)) continue; Comdat::SelectionKind SK; bool LinkFromSrc; if (getComdatResult(&C, SK, LinkFromSrc)) return true; ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc); } for (GlobalVariable &GV : SrcM.globals()) if (const Comdat *SC = GV.getComdat()) ComdatMembers[SC].push_back(&GV); for (Function &SF : SrcM) if (const Comdat *SC = SF.getComdat()) ComdatMembers[SC].push_back(&SF); for (GlobalAlias &GA : SrcM.aliases()) if (const Comdat *SC = GA.getComdat()) ComdatMembers[SC].push_back(&GA); // Insert all of the globals in src into the DstM module... without linking // initializers (which could refer to functions not yet mapped over). for (GlobalVariable &GV : SrcM.globals()) if (linkIfNeeded(GV)) return true; for (Function &SF : SrcM) if (linkIfNeeded(SF)) return true; for (GlobalAlias &GA : SrcM.aliases()) if (linkIfNeeded(GA)) return true; if (ImportIndex) { ThinLTOGlobalProcessing ThinLTOProcessing(SrcM, ImportIndex, FunctionsToImport); if (ThinLTOProcessing.run()) return true; for (auto *GV : ThinLTOProcessing.getNewExportedValues()) ValuesToLink.insert(GV); } for (unsigned I = 0; I < ValuesToLink.size(); ++I) { GlobalValue *GV = ValuesToLink[I]; const Comdat *SC = GV->getComdat(); if (!SC) continue; for (GlobalValue *GV2 : ComdatMembers[SC]) ValuesToLink.insert(GV2); } if (shouldInternalizeLinkedSymbols()) { for (GlobalValue *GV : ValuesToLink) Internalize.insert(GV->getName()); } if (Mover.move(SrcM, ValuesToLink.getArrayRef(), [this](GlobalValue &GV, IRMover::ValueAdder Add) { addLazyFor(GV, Add); }, ValIDToTempMDMap, false)) return true; Module &DstM = Mover.getModule(); for (auto &P : Internalize) { GlobalValue *GV = DstM.getNamedValue(P.first()); GV->setLinkage(GlobalValue::InternalLinkage); } return false; }
void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { ValueInfo VI; if (GV.hasName()) { VI = ImportIndex.getValueInfo(GV.getGUID()); // Set synthetic function entry counts. if (VI && ImportIndex.hasSyntheticEntryCounts()) { if (Function *F = dyn_cast<Function>(&GV)) { if (!F->isDeclaration()) { for (auto &S : VI.getSummaryList()) { FunctionSummary *FS = dyn_cast<FunctionSummary>(S->getBaseObject()); if (FS->modulePath() == M.getModuleIdentifier()) { F->setEntryCount(Function::ProfileCount(FS->entryCount(), Function::PCT_Synthetic)); break; } } } } } // Check the summaries to see if the symbol gets resolved to a known local // definition. if (VI && VI.isDSOLocal()) { GV.setDSOLocal(true); if (GV.hasDLLImportStorageClass()) GV.setDLLStorageClass(GlobalValue::DefaultStorageClass); } } // Mark read-only variables which can be imported with specific attribute. // We can't internalize them now because IRMover will fail to link variable // definitions to their external declarations during ThinLTO import. We'll // internalize read-only variables later, after import is finished. // See internalizeImmutableGVs. // // If global value dead stripping is not enabled in summary then // propagateConstants hasn't been run. We can't internalize GV // in such case. if (!GV.isDeclaration() && VI && ImportIndex.withGlobalValueDeadStripping()) { const auto &SL = VI.getSummaryList(); auto *GVS = SL.empty() ? nullptr : dyn_cast<GlobalVarSummary>(SL[0].get()); if (GVS && GVS->isReadOnly()) cast<GlobalVariable>(&GV)->addAttribute("thinlto-internalize"); } bool DoPromote = false; if (GV.hasLocalLinkage() && ((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) { // Save the original name string before we rename GV below. auto Name = GV.getName().str(); // Once we change the name or linkage it is difficult to determine // again whether we should promote since shouldPromoteLocalToGlobal needs // to locate the summary (based on GUID from name and linkage). Therefore, // use DoPromote result saved above. GV.setName(getName(&GV, DoPromote)); GV.setLinkage(getLinkage(&GV, DoPromote)); if (!GV.hasLocalLinkage()) GV.setVisibility(GlobalValue::HiddenVisibility); // If we are renaming a COMDAT leader, ensure that we record the COMDAT // for later renaming as well. This is required for COFF. if (const auto *C = GV.getComdat()) if (C->getName() == Name) RenamedComdats.try_emplace(C, M.getOrInsertComdat(GV.getName())); } else GV.setLinkage(getLinkage(&GV, /* DoPromote */ false)); // Remove functions imported as available externally defs from comdats, // as this is a declaration for the linker, and will be dropped eventually. // It is illegal for comdats to contain declarations. auto *GO = dyn_cast<GlobalObject>(&GV); if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) { // The IRMover should not have placed any imported declarations in // a comdat, so the only declaration that should be in a comdat // at this point would be a definition imported as available_externally. assert(GO->hasAvailableExternallyLinkage() && "Expected comdat on definition (possibly available external)"); GO->setComdat(nullptr); } }
/// linkGlobalProto - Loop through the global variables in the src module and /// merge them into the dest module. bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) { GlobalValue *DGV = getLinkedToGlobal(SGV); llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility; if (DGV) { // Concatenation of appending linkage variables is magic and handled later. if (DGV->hasAppendingLinkage() || SGV->hasAppendingLinkage()) return linkAppendingVarProto(cast<GlobalVariable>(DGV), SGV); // Determine whether linkage of these two globals follows the source // module's definition or the destination module's definition. GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; GlobalValue::VisibilityTypes NV; bool LinkFromSrc = false; if (getLinkageResult(DGV, SGV, NewLinkage, NV, LinkFromSrc)) return true; NewVisibility = NV; // If we're not linking from the source, then keep the definition that we // have. if (!LinkFromSrc) { // Special case for const propagation. if (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV)) if (DGVar->isDeclaration() && SGV->isConstant() && !DGVar->isConstant()) DGVar->setConstant(true); // Set calculated linkage and visibility. DGV->setLinkage(NewLinkage); DGV->setVisibility(*NewVisibility); // Make sure to remember this mapping. ValueMap[SGV] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGV->getType())); // Track the source global so that we don't attempt to copy it over when // processing global initializers. DoNotLinkFromSource.insert(SGV); return false; } } // No linking to be performed or linking from the source: simply create an // identical version of the symbol over in the dest module... the // initializer will be filled in later by LinkGlobalInits. GlobalVariable *NewDGV = new GlobalVariable(*DstM, TypeMap.get(SGV->getType()->getElementType()), SGV->isConstant(), SGV->getLinkage(), /*init*/0, SGV->getName(), /*insertbefore*/0, SGV->isThreadLocal(), SGV->getType()->getAddressSpace()); // Propagate alignment, visibility and section info. CopyGVAttributes(NewDGV, SGV); if (NewVisibility) NewDGV->setVisibility(*NewVisibility); if (DGV) { DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV, DGV->getType())); DGV->eraseFromParent(); } // Make sure to remember this mapping. ValueMap[SGV] = NewDGV; return false; }
static void internalize(GlobalValue &GV) { if (GV.isDeclarationForLinker()) return; // We get here if there is a matching asm definition. if (!GV.hasLocalLinkage()) GV.setLinkage(GlobalValue::InternalLinkage); }
/// gold informs us that all symbols have been read. At this point, we use /// get_symbols to see if any of our definitions have been overridden by a /// native object file. Then, perform optimization and codegen. static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { if (Modules.empty()) return LDPS_OK; LLVMContext Context; Context.setDiagnosticHandler(diagnosticHandler, nullptr, true); std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context)); Linker L(Combined.get()); std::string DefaultTriple = sys::getDefaultTargetTriple(); StringSet<> Internalize; StringSet<> Maybe; for (claimed_file &F : Modules) { ld_plugin_input_file File; if (get_input_file(F.handle, &File) != LDPS_OK) message(LDPL_FATAL, "Failed to get file information"); std::unique_ptr<Module> M = getModuleForFile(Context, F, File, ApiFile, Internalize, Maybe); if (!options::triple.empty()) M->setTargetTriple(options::triple.c_str()); else if (M->getTargetTriple().empty()) { M->setTargetTriple(DefaultTriple); } if (L.linkInModule(M.get())) message(LDPL_FATAL, "Failed to link module"); if (release_input_file(F.handle) != LDPS_OK) message(LDPL_FATAL, "Failed to release file information"); } for (const auto &Name : Internalize) { GlobalValue *GV = Combined->getNamedValue(Name.first()); if (GV) internalize(*GV); } for (const auto &Name : Maybe) { GlobalValue *GV = Combined->getNamedValue(Name.first()); if (!GV) continue; GV->setLinkage(GlobalValue::LinkOnceODRLinkage); if (canBeOmittedFromSymbolTable(GV)) internalize(*GV); } // @LOCALMOD-BEGIN // Perform symbol wrapping. unsigned num_wrapped; if ((*get_num_wrapped)(&num_wrapped) != LDPS_OK) { (*message)(LDPL_ERROR, "Unable to get the number of wrapped symbols."); return LDPS_ERR; } for (unsigned i = 0; i < num_wrapped; ++i) { const char *sym; if ((*get_wrapped)(i, &sym) != LDPS_OK) { (*message)(LDPL_ERROR, "Unable to wrap symbol %u/%u.", i, num_wrapped); return LDPS_ERR; } wrapSymbol(Combined.get(), sym); } // @LOCALMOD-END if (options::TheOutputType == options::OT_DISABLE) return LDPS_OK; if (options::TheOutputType != options::OT_NORMAL) { std::string path; if (options::TheOutputType == options::OT_BC_ONLY) path = output_name; else path = output_name + ".bc"; saveBCFile(path, *L.getModule()); if (options::TheOutputType == options::OT_BC_ONLY) return LDPS_OK; } codegen(*L.getModule()); if (!options::extra_library_path.empty() && set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK) message(LDPL_FATAL, "Unable to set the extra library path."); return LDPS_OK; }
Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV, bool ForAlias) { GlobalValue *DGV = getLinkedToGlobal(SGV); bool ShouldLink = shouldLink(DGV, *SGV); // just missing from map if (ShouldLink) { auto I = ValueMap.find(SGV); if (I != ValueMap.end()) return cast<Constant>(I->second); I = AliasValueMap.find(SGV); if (I != AliasValueMap.end()) return cast<Constant>(I->second); } if (!ShouldLink && ForAlias) DGV = nullptr; // Handle the ultra special appending linkage case first. assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage()); if (SGV->hasAppendingLinkage()) return linkAppendingVarProto(cast_or_null<GlobalVariable>(DGV), cast<GlobalVariable>(SGV)); GlobalValue *NewGV; if (DGV && !ShouldLink) { NewGV = DGV; } else { // If we are done linking global value bodies (i.e. we are performing // metadata linking), don't link in the global value due to this // reference, simply map it to null. if (DoneLinkingBodies) return nullptr; NewGV = copyGlobalValueProto(SGV, ShouldLink); if (ShouldLink || !ForAlias) forceRenaming(NewGV, SGV->getName()); } // Overloaded intrinsics have overloaded types names as part of their // names. If we renamed overloaded types we should rename the intrinsic // as well. if (Function *F = dyn_cast<Function>(NewGV)) if (auto Remangled = Intrinsic::remangleIntrinsicFunction(F)) NewGV = Remangled.getValue(); if (ShouldLink || ForAlias) { if (const Comdat *SC = SGV->getComdat()) { if (auto *GO = dyn_cast<GlobalObject>(NewGV)) { Comdat *DC = DstM.getOrInsertComdat(SC->getName()); DC->setSelectionKind(SC->getSelectionKind()); GO->setComdat(DC); } } } if (!ShouldLink && ForAlias) NewGV->setLinkage(GlobalValue::InternalLinkage); Constant *C = NewGV; if (DGV) C = ConstantExpr::getBitCast(NewGV, TypeMap.get(SGV->getType())); if (DGV && NewGV != DGV) { DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, DGV->getType())); DGV->eraseFromParent(); } return C; }
static void internalize(GlobalValue &GV) { assert(!GV.hasLocalLinkage() && "Trying to internalize a symbol with local linkage!"); GV.setLinkage(GlobalValue::InternalLinkage); }