void LTOCodeGenerator:: applyRestriction(GlobalValue &GV, ArrayRef<StringRef> Libcalls, std::vector<const char*> &MustPreserveList, SmallPtrSetImpl<GlobalValue*> &AsmUsed, Mangler &Mangler) { // There are no restrictions to apply to declarations. if (GV.isDeclaration()) return; // There is nothing more restrictive than private linkage. if (GV.hasPrivateLinkage()) return; SmallString<64> Buffer; TargetMach->getNameWithPrefix(Buffer, &GV, Mangler); if (MustPreserveSymbols.count(Buffer)) MustPreserveList.push_back(GV.getName().data()); if (AsmUndefinedRefs.count(Buffer)) AsmUsed.insert(&GV); // Conservatively append user-supplied runtime library functions to // llvm.compiler.used. These could be internalized and deleted by // optimizations like -globalopt, causing problems when later optimizations // add new library calls (e.g., llvm.memset => memset and printf => puts). // Leave it to the linker to remove any dead code (e.g. with -dead_strip). if (isa<Function>(GV) && std::binary_search(Libcalls.begin(), Libcalls.end(), GV.getName())) AsmUsed.insert(&GV); }
static bool isDeclaration(const GlobalValue &V) { if (V.hasAvailableExternallyLinkage()) return true; if (V.isMaterializable()) return false; return V.isDeclaration(); }
static bool shouldInternalize(const GlobalValue &GV, const std::set<std::string> &ExternalNames, bool OnlyHidden) { if (OnlyHidden && !GV.hasHiddenVisibility()) return false; // Function must be defined here if (GV.isDeclaration()) return false; // Available externally is really just a "declaration with a body". if (GV.hasAvailableExternallyLinkage()) return false; // Assume that dllexported symbols are referenced elsewhere if (GV.hasDLLExportStorageClass()) return false; // Already has internal linkage if (GV.hasLocalLinkage()) return false; // Marked to keep external? if (ExternalNames.count(GV.getName())) return false; return true; }
static bool shouldInternalize(const GlobalValue &GV, const std::set<std::string> &ExternalNames, const std::set<std::string> &DSONames) { // Function must be defined here if (GV.isDeclaration()) return false; // Available externally is really just a "declaration with a body". if (GV.hasAvailableExternallyLinkage()) return false; // Already has internal linkage if (GV.hasLocalLinkage()) return false; // Marked to keep external? if (ExternalNames.count(GV.getName())) return false; // Not needed for the symbol table? if (!DSONames.count(GV.getName())) return true; // Not a linkonce. Someone can depend on it being on the symbol table. if (!GV.hasLinkOnceLinkage()) return false; // The address is not important, we can hide it. if (GV.hasUnnamedAddr()) return true; // FIXME: Check if the address is used. return false; }
// 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); } }
void LTOCodeGenerator:: applyRestriction(GlobalValue &GV, std::vector<const char*> &mustPreserveList, SmallPtrSet<GlobalValue*, 8> &asmUsed, Mangler &mangler) { SmallString<64> Buffer; mangler.getNameWithPrefix(Buffer, &GV, false); if (GV.isDeclaration()) return; if (_mustPreserveSymbols.count(Buffer)) mustPreserveList.push_back(GV.getName().data()); if (_asmUndefinedRefs.count(Buffer)) asmUsed.insert(&GV); }
static char TypeCharForSymbol(GlobalValue &GV) { if (GV.isDeclaration()) return 'U'; if (GV.hasLinkOnceLinkage()) return 'C'; if (GV.hasCommonLinkage()) return 'C'; if (GV.hasWeakLinkage()) return 'W'; if (isa<Function>(GV) && GV.hasInternalLinkage()) return 't'; if (isa<Function>(GV)) return 'T'; if (isa<GlobalVariable>(GV) && GV.hasInternalLinkage()) return 'd'; if (isa<GlobalVariable>(GV)) return 'D'; if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(&GV)) { const GlobalValue *AliasedGV = GA->getAliasedGlobal(); if (isa<Function>(AliasedGV)) return 'T'; if (isa<GlobalVariable>(AliasedGV)) return 'D'; } return '?'; }
static bool useExistingDest(GlobalValue &SGV, GlobalValue *DGV, bool ShouldLink) { if (!DGV) return false; if (SGV.isDeclaration()) return true; if (DGV->isDeclarationForLinker() && !SGV.isDeclarationForLinker()) return false; if (ShouldLink) return false; return true; }
void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { const TargetRegisterInfo &RI = *TM.getRegisterInfo(); switch (MO.getType()) { case MachineOperand::MO_Register: O << RI.get(MO.getReg()).AsmName; return; case MachineOperand::MO_Immediate: cerr << "printOp() does not handle immediate values\n"; abort(); return; case MachineOperand::MO_MachineBasicBlock: printBasicBlockLabel(MO.getMBB()); return; case MachineOperand::MO_ConstantPoolIndex: O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" << MO.getIndex(); return; case MachineOperand::MO_ExternalSymbol: O << MO.getSymbolName(); return; case MachineOperand::MO_GlobalAddress: { GlobalValue *GV = MO.getGlobal(); O << Mang->getValueName(GV); if (GV->isDeclaration() && GV->hasExternalWeakLinkage()) ExtWeakSymbols.insert(GV); return; } case MachineOperand::MO_JumpTableIndex: O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << MO.getIndex(); return; default: O << "<unknown operand type: " << MO.getType() << ">"; return; } }
bool IRLinker::shouldLink(GlobalValue *DGV, GlobalValue &SGV) { if (ValuesToLink.count(&SGV) || SGV.hasLocalLinkage()) return true; if (DGV && !DGV->isDeclarationForLinker()) return false; if (SGV.hasAvailableExternallyLinkage()) return true; if (SGV.isDeclaration() || DoneLinkingBodies) return false; // Callback to the client to give a chance to lazily add the Global to the // list of value to link. bool LazilyAdded = false; AddLazyFor(SGV, [this, &LazilyAdded](GlobalValue &GV) { maybeAdd(&GV); LazilyAdded = true; }); return LazilyAdded; }
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); } }
// destructively move the contents of src into dest // this assumes that the targets of the two modules are the same // including the DataLayout and ModuleFlags (for example) // and that there is no module-level assembly static void jl_merge_module(Module *dest, std::unique_ptr<Module> src) { assert(dest != src.get()); for (Module::global_iterator I = src->global_begin(), E = src->global_end(); I != E;) { GlobalVariable *sG = &*I; GlobalValue *dG = dest->getNamedValue(sG->getName()); ++I; // Replace a declaration with the definition: if (dG) { if (sG->isDeclaration()) { sG->replaceAllUsesWith(dG); sG->eraseFromParent(); continue; } else { dG->replaceAllUsesWith(sG); dG->eraseFromParent(); } } // Reparent the global variable: sG->removeFromParent(); dest->getGlobalList().push_back(sG); // Comdat is owned by the Module, recreate it in the new parent: addComdat(sG); } for (Module::iterator I = src->begin(), E = src->end(); I != E;) { Function *sG = &*I; GlobalValue *dG = dest->getNamedValue(sG->getName()); ++I; // Replace a declaration with the definition: if (dG) { if (sG->isDeclaration()) { sG->replaceAllUsesWith(dG); sG->eraseFromParent(); continue; } else { dG->replaceAllUsesWith(sG); dG->eraseFromParent(); } } // Reparent the global variable: sG->removeFromParent(); dest->getFunctionList().push_back(sG); // Comdat is owned by the Module, recreate it in the new parent: addComdat(sG); } for (Module::alias_iterator I = src->alias_begin(), E = src->alias_end(); I != E;) { GlobalAlias *sG = &*I; GlobalValue *dG = dest->getNamedValue(sG->getName()); ++I; if (dG) { if (!dG->isDeclaration()) { // aliases are always definitions, so this test is reversed from the above two sG->replaceAllUsesWith(dG); sG->eraseFromParent(); continue; } else { dG->replaceAllUsesWith(sG); dG->eraseFromParent(); } } sG->removeFromParent(); dest->getAliasList().push_back(sG); } // metadata nodes need to be explicitly merged not just copied // so there are special passes here for each known type of metadata NamedMDNode *sNMD = src->getNamedMetadata("llvm.dbg.cu"); if (sNMD) { NamedMDNode *dNMD = dest->getOrInsertNamedMetadata("llvm.dbg.cu"); #ifdef LLVM35 for (NamedMDNode::op_iterator I = sNMD->op_begin(), E = sNMD->op_end(); I != E; ++I) { dNMD->addOperand(*I); } #else for (unsigned i = 0, l = sNMD->getNumOperands(); i < l; i++) { dNMD->addOperand(sNMD->getOperand(i)); } #endif } }
ModuleSummaryIndex llvm::buildModuleSummaryIndex( const Module &M, std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback, ProfileSummaryInfo *PSI) { ModuleSummaryIndex Index; // Identify the local values in the llvm.used and llvm.compiler.used sets, // which should not be exported as they would then require renaming and // promotion, but we may have opaque uses e.g. in inline asm. We collect them // here because we use this information to mark functions containing inline // assembly calls as not importable. SmallPtrSet<GlobalValue *, 8> LocalsUsed; SmallPtrSet<GlobalValue *, 8> Used; // First collect those in the llvm.used set. collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); // Next collect those in the llvm.compiler.used set. collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ true); DenseSet<GlobalValue::GUID> CantBePromoted; for (auto *V : Used) { if (V->hasLocalLinkage()) { LocalsUsed.insert(V); CantBePromoted.insert(V->getGUID()); } } // Compute summaries for all functions defined in module, and save in the // index. for (auto &F : M) { if (F.isDeclaration()) continue; BlockFrequencyInfo *BFI = nullptr; std::unique_ptr<BlockFrequencyInfo> BFIPtr; if (GetBFICallback) BFI = GetBFICallback(F); else if (F.getEntryCount().hasValue()) { LoopInfo LI{DominatorTree(const_cast<Function &>(F))}; BranchProbabilityInfo BPI{F, LI}; BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI); BFI = BFIPtr.get(); } computeFunctionSummary(Index, M, F, BFI, PSI, !LocalsUsed.empty(), CantBePromoted); } // Compute summaries for all variables defined in module, and save in the // index. for (const GlobalVariable &G : M.globals()) { if (G.isDeclaration()) continue; computeVariableSummary(Index, G, CantBePromoted); } // Compute summaries for all aliases defined in module, and save in the // index. for (const GlobalAlias &A : M.aliases()) computeAliasSummary(Index, A, CantBePromoted); for (auto *V : LocalsUsed) { auto *Summary = Index.getGlobalValueSummary(*V); assert(Summary && "Missing summary for global value"); Summary->setNotEligibleToImport(); } // The linker doesn't know about these LLVM produced values, so we need // to flag them as live in the index to ensure index-based dead value // analysis treats them as live roots of the analysis. setLiveRoot(Index, "llvm.used"); setLiveRoot(Index, "llvm.compiler.used"); setLiveRoot(Index, "llvm.global_ctors"); setLiveRoot(Index, "llvm.global_dtors"); setLiveRoot(Index, "llvm.global.annotations"); if (!M.getModuleInlineAsm().empty()) { // Collect the local values defined by module level asm, and set up // summaries for these symbols so that they can be marked as NoRename, // to prevent export of any use of them in regular IR that would require // renaming within the module level asm. Note we don't need to create a // summary for weak or global defs, as they don't need to be flagged as // NoRename, and defs in module level asm can't be imported anyway. // Also, any values used but not defined within module level asm should // be listed on the llvm.used or llvm.compiler.used global and marked as // referenced from there. ModuleSymbolTable::CollectAsmSymbols( Triple(M.getTargetTriple()), M.getModuleInlineAsm(), [&M, &Index, &CantBePromoted](StringRef Name, object::BasicSymbolRef::Flags Flags) { // Symbols not marked as Weak or Global are local definitions. if (Flags & (object::BasicSymbolRef::SF_Weak | object::BasicSymbolRef::SF_Global)) return; GlobalValue *GV = M.getNamedValue(Name); if (!GV) return; assert(GV->isDeclaration() && "Def in module asm already has definition"); GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage, /* NotEligibleToImport */ true, /* LiveRoot */ true); CantBePromoted.insert(GlobalValue::getGUID(Name)); // Create the appropriate summary type. if (isa<Function>(GV)) { std::unique_ptr<FunctionSummary> Summary = llvm::make_unique<FunctionSummary>( GVFlags, 0, ArrayRef<ValueInfo>{}, ArrayRef<FunctionSummary::EdgeTy>{}, ArrayRef<GlobalValue::GUID>{}); Index.addGlobalValueSummary(Name, std::move(Summary)); } else { std::unique_ptr<GlobalVarSummary> Summary = llvm::make_unique<GlobalVarSummary>(GVFlags, ArrayRef<ValueInfo>{}); Index.addGlobalValueSummary(Name, std::move(Summary)); } }); } for (auto &GlobalList : Index) { assert(GlobalList.second.size() == 1 && "Expected module's index to have one summary per GUID"); auto &Summary = GlobalList.second[0]; bool AllRefsCanBeExternallyReferenced = llvm::all_of(Summary->refs(), [&](const ValueInfo &VI) { return !CantBePromoted.count(VI.getValue()->getGUID()); }); if (!AllRefsCanBeExternallyReferenced) { Summary->setNotEligibleToImport(); continue; } if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) { bool AllCallsCanBeExternallyReferenced = llvm::all_of( FuncSummary->calls(), [&](const FunctionSummary::EdgeTy &Edge) { auto GUID = Edge.first.isGUID() ? Edge.first.getGUID() : Edge.first.getValue()->getGUID(); return !CantBePromoted.count(GUID); }); if (!AllCallsCanBeExternallyReferenced) Summary->setNotEligibleToImport(); } } return Index; }
bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { GlobalValue *DGV = getLinkedToGlobal(&GV); if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration())) return false; if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) { auto *DGVar = dyn_cast<GlobalVariable>(DGV); auto *SGVar = dyn_cast<GlobalVariable>(&GV); if (DGVar && SGVar) { if (DGVar->isDeclaration() && SGVar->isDeclaration() && (!DGVar->isConstant() || !SGVar->isConstant())) { DGVar->setConstant(false); SGVar->setConstant(false); } if (DGVar->hasCommonLinkage() && SGVar->hasCommonLinkage()) { unsigned Align = std::max(DGVar->getAlignment(), SGVar->getAlignment()); SGVar->setAlignment(Align); DGVar->setAlignment(Align); } } GlobalValue::VisibilityTypes Visibility = getMinVisibility(DGV->getVisibility(), GV.getVisibility()); DGV->setVisibility(Visibility); GV.setVisibility(Visibility); bool HasUnnamedAddr = GV.hasUnnamedAddr() && DGV->hasUnnamedAddr(); DGV->setUnnamedAddr(HasUnnamedAddr); GV.setUnnamedAddr(HasUnnamedAddr); } // Don't want to append to global_ctors list, for example, when we // are importing for ThinLTO, otherwise the global ctors and dtors // get executed multiple times for local variables (the latter causing // double frees). if (GV.hasAppendingLinkage() && isPerformingImport()) return false; if (isPerformingImport()) { if (!doImportAsDefinition(&GV)) return false; } else if (!DGV && !shouldOverrideFromSrc() && (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || GV.hasAvailableExternallyLinkage())) return false; if (GV.isDeclaration()) return false; if (const Comdat *SC = GV.getComdat()) { bool LinkFromSrc; Comdat::SelectionKind SK; std::tie(SK, LinkFromSrc) = ComdatsChosen[SC]; if (!LinkFromSrc) return false; } bool LinkFromSrc = true; if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, GV)) return true; if (LinkFromSrc) ValuesToLink.insert(&GV); return false; }
bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, const GlobalValue &Src) { // Should we unconditionally use the Src? if (shouldOverrideFromSrc()) { LinkFromSrc = true; return false; } // We always have to add Src if it has appending linkage. if (Src.hasAppendingLinkage()) { // Should have prevented importing for appending linkage in linkIfNeeded. assert(!isPerformingImport()); LinkFromSrc = true; return false; } if (isPerformingImport()) { // LinkFromSrc iff this is a global requested for importing. LinkFromSrc = GlobalsToImport->count(&Src); return false; } bool SrcIsDeclaration = Src.isDeclarationForLinker(); bool DestIsDeclaration = Dest.isDeclarationForLinker(); if (SrcIsDeclaration) { // If Src is external or if both Src & Dest are external.. Just link the // external globals, we aren't adding anything. if (Src.hasDLLImportStorageClass()) { // If one of GVs is marked as DLLImport, result should be dllimport'ed. LinkFromSrc = DestIsDeclaration; return false; } // If the Dest is weak, use the source linkage. if (Dest.hasExternalWeakLinkage()) { LinkFromSrc = true; return false; } // Link an available_externally over a declaration. LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration(); return false; } if (DestIsDeclaration) { // If Dest is external but Src is not: LinkFromSrc = true; return false; } if (Src.hasCommonLinkage()) { if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) { LinkFromSrc = true; return false; } if (!Dest.hasCommonLinkage()) { LinkFromSrc = false; return false; } const DataLayout &DL = Dest.getParent()->getDataLayout(); uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType()); uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType()); LinkFromSrc = SrcSize > DestSize; return false; } if (Src.isWeakForLinker()) { assert(!Dest.hasExternalWeakLinkage()); assert(!Dest.hasAvailableExternallyLinkage()); if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) { LinkFromSrc = true; return false; } LinkFromSrc = false; return false; } if (Dest.isWeakForLinker()) { assert(Src.hasExternalLinkage()); LinkFromSrc = true; return false; } assert(!Src.hasExternalWeakLinkage()); assert(!Dest.hasExternalWeakLinkage()); assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() && "Unexpected linkage type!"); return emitError("Linking globals named '" + Src.getName() + "': symbol multiply defined!"); }
Error IRLinker::run() { // Ensure metadata materialized before value mapping. if (SrcM->getMaterializer()) if (Error Err = SrcM->getMaterializer()->materializeMetadata()) return Err; // Inherit the target data from the source module if the destination module // doesn't have one already. if (DstM.getDataLayout().isDefault()) DstM.setDataLayout(SrcM->getDataLayout()); if (SrcM->getDataLayout() != DstM.getDataLayout()) { emitWarning("Linking two modules of different data layouts: '" + SrcM->getModuleIdentifier() + "' is '" + SrcM->getDataLayoutStr() + "' whereas '" + DstM.getModuleIdentifier() + "' is '" + DstM.getDataLayoutStr() + "'\n"); } // Copy the target triple from the source to dest if the dest's is empty. if (DstM.getTargetTriple().empty() && !SrcM->getTargetTriple().empty()) DstM.setTargetTriple(SrcM->getTargetTriple()); Triple SrcTriple(SrcM->getTargetTriple()), DstTriple(DstM.getTargetTriple()); if (!SrcM->getTargetTriple().empty() && !triplesMatch(SrcTriple, DstTriple)) emitWarning("Linking two modules of different target triples: " + SrcM->getModuleIdentifier() + "' is '" + SrcM->getTargetTriple() + "' whereas '" + DstM.getModuleIdentifier() + "' is '" + DstM.getTargetTriple() + "'\n"); DstM.setTargetTriple(mergeTriples(SrcTriple, DstTriple)); // Append the module inline asm string. if (LinkModuleInlineAsm && !SrcM->getModuleInlineAsm().empty()) { if (DstM.getModuleInlineAsm().empty()) DstM.setModuleInlineAsm(SrcM->getModuleInlineAsm()); else DstM.setModuleInlineAsm(DstM.getModuleInlineAsm() + "\n" + SrcM->getModuleInlineAsm()); } // Loop over all of the linked values to compute type mappings. computeTypeMapping(); std::reverse(Worklist.begin(), Worklist.end()); while (!Worklist.empty()) { GlobalValue *GV = Worklist.back(); Worklist.pop_back(); // Already mapped. if (ValueMap.find(GV) != ValueMap.end() || AliasValueMap.find(GV) != AliasValueMap.end()) continue; assert(!GV->isDeclaration()); Mapper.mapValue(*GV); if (FoundError) return std::move(*FoundError); } // Note that we are done linking global value bodies. This prevents // metadata linking from creating new references. DoneLinkingBodies = true; Mapper.addFlags(RF_NullMapMissingGlobalValues); // Remap all of the named MDNodes in Src into the DstM module. We do this // after linking GlobalValues so that MDNodes that reference GlobalValues // are properly remapped. linkNamedMDNodes(); // Merge the module flags into the DstM module. return linkModuleFlagsMetadata(); }
void IA64AsmPrinter::printOp(const MachineOperand &MO, bool isBRCALLinsn /* = false */) { const TargetRegisterInfo &RI = *TM.getRegisterInfo(); switch (MO.getType()) { case MachineOperand::MO_Register: O << RI.get(MO.getReg()).AsmName; return; case MachineOperand::MO_Immediate: O << MO.getImm(); return; case MachineOperand::MO_MachineBasicBlock: printBasicBlockLabel(MO.getMBB()); return; case MachineOperand::MO_ConstantPoolIndex: { O << "@gprel(" << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" << MO.getIndex() << ")"; return; } case MachineOperand::MO_GlobalAddress: { // functions need @ltoff(@fptr(fn_name)) form GlobalValue *GV = MO.getGlobal(); Function *F = dyn_cast<Function>(GV); bool Needfptr=false; // if we're computing an address @ltoff(X), do // we need to decorate it so it becomes // @ltoff(@fptr(X)) ? if (F && !isBRCALLinsn /*&& F->isDeclaration()*/) Needfptr=true; // if this is the target of a call instruction, we should define // the function somewhere (GNU gas has no problem without this, but // Intel ias rightly complains of an 'undefined symbol') if (F /*&& isBRCALLinsn*/ && F->isDeclaration()) ExternalFunctionNames.insert(Mang->getValueName(MO.getGlobal())); else if (GV->isDeclaration()) // e.g. stuff like 'stdin' ExternalObjectNames.insert(Mang->getValueName(MO.getGlobal())); if (!isBRCALLinsn) O << "@ltoff("; if (Needfptr) O << "@fptr("; O << Mang->getValueName(MO.getGlobal()); if (Needfptr && !isBRCALLinsn) O << "#))"; // close both fptr( and ltoff( else { if (Needfptr) O << "#)"; // close only fptr( if (!isBRCALLinsn) O << "#)"; // close only ltoff( } int Offset = MO.getOffset(); if (Offset > 0) O << " + " << Offset; else if (Offset < 0) O << " - " << -Offset; return; } case MachineOperand::MO_ExternalSymbol: O << MO.getSymbolName(); ExternalFunctionNames.insert(MO.getSymbolName()); return; default: O << "<AsmPrinter: unknown operand type: " << MO.getType() << " >"; return; } }
bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, const GlobalValue &Src) { // Should we unconditionally use the Src? if (shouldOverrideFromSrc()) { LinkFromSrc = true; return false; } // We always have to add Src if it has appending linkage. if (Src.hasAppendingLinkage()) { // Should have prevented importing for appending linkage in linkIfNeeded. assert(!isPerformingImport()); LinkFromSrc = true; return false; } bool SrcIsDeclaration = Src.isDeclarationForLinker(); bool DestIsDeclaration = Dest.isDeclarationForLinker(); if (isPerformingImport()) { if (isa<Function>(&Src)) { // For functions, LinkFromSrc iff this is a function requested // for importing. For variables, decide below normally. LinkFromSrc = GlobalsToImport->count(&Src); return false; } // Check if this is an alias with an already existing definition // in Dest, which must have come from a prior importing pass from // the same Src module. Unlike imported function and variable // definitions, which are imported as available_externally and are // not definitions for the linker, that is not a valid linkage for // imported aliases which must be definitions. Simply use the existing // Dest copy. if (isa<GlobalAlias>(&Src) && !DestIsDeclaration) { assert(isa<GlobalAlias>(&Dest)); LinkFromSrc = false; return false; } } if (SrcIsDeclaration) { // If Src is external or if both Src & Dest are external.. Just link the // external globals, we aren't adding anything. if (Src.hasDLLImportStorageClass()) { // If one of GVs is marked as DLLImport, result should be dllimport'ed. LinkFromSrc = DestIsDeclaration; return false; } // If the Dest is weak, use the source linkage. if (Dest.hasExternalWeakLinkage()) { LinkFromSrc = true; return false; } // Link an available_externally over a declaration. LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration(); return false; } if (DestIsDeclaration) { // If Dest is external but Src is not: LinkFromSrc = true; return false; } if (Src.hasCommonLinkage()) { if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) { LinkFromSrc = true; return false; } if (!Dest.hasCommonLinkage()) { LinkFromSrc = false; return false; } const DataLayout &DL = Dest.getParent()->getDataLayout(); uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType()); uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType()); LinkFromSrc = SrcSize > DestSize; return false; } if (Src.isWeakForLinker()) { assert(!Dest.hasExternalWeakLinkage()); assert(!Dest.hasAvailableExternallyLinkage()); if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) { LinkFromSrc = true; return false; } LinkFromSrc = false; return false; } if (Dest.isWeakForLinker()) { assert(Src.hasExternalLinkage()); LinkFromSrc = true; return false; } assert(!Src.hasExternalWeakLinkage()); assert(!Dest.hasExternalWeakLinkage()); assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() && "Unexpected linkage type!"); return emitError("Linking globals named '" + Src.getName() + "': symbol multiply defined!"); }
std::unique_ptr<llvm::Module> klee::linkModules(std::vector<std::unique_ptr<llvm::Module>> &modules, llvm::StringRef entryFunction, std::string &errorMsg) { assert(!modules.empty() && "modules list should not be empty"); if (entryFunction.empty()) { // If no entry function is provided, link all modules together into one std::unique_ptr<llvm::Module> composite = std::move(modules.back()); modules.pop_back(); // Just link all modules together for (auto &module : modules) { if (linkTwoModules(composite.get(), std::move(module), errorMsg)) continue; // Linking failed errorMsg = "Linking archive module with composite failed:" + errorMsg; return nullptr; } // clean up every module as we already linked in every module modules.clear(); return composite; } // Starting from the module containing the entry function, resolve unresolved // dependencies recursively // search for the module containing the entry function std::unique_ptr<llvm::Module> composite; for (auto &module : modules) { if (!module || !module->getNamedValue(entryFunction)) continue; if (composite) { errorMsg = "Function " + entryFunction.str() + " defined in different modules (" + module->getModuleIdentifier() + " already defined in: " + composite->getModuleIdentifier() + ")"; return nullptr; } composite = std::move(module); } // fail if not found if (!composite) { errorMsg = "'" + entryFunction.str() + "' function not found in module."; return nullptr; } while (true) { std::set<std::string> undefinedSymbols; GetAllUndefinedSymbols(composite.get(), undefinedSymbols); // Stop in nothing is undefined if (undefinedSymbols.empty()) break; bool merged = false; for (auto &module : modules) { if (!module) continue; for (auto symbol : undefinedSymbols) { GlobalValue *GV = dyn_cast_or_null<GlobalValue>(module->getNamedValue(symbol)); if (!GV || GV->isDeclaration()) continue; // Found symbol, therefore merge in module KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Found " << GV->getName() << " in " << module->getModuleIdentifier() << "\n"); if (linkTwoModules(composite.get(), std::move(module), errorMsg)) { module = nullptr; merged = true; break; } // Linking failed errorMsg = "Linking archive module with composite failed:" + errorMsg; return nullptr; } } if (!merged) break; } // Condense the module array std::vector<std::unique_ptr<llvm::Module>> LeftoverModules; for (auto &module : modules) { if (module) LeftoverModules.emplace_back(std::move(module)); } modules.swap(LeftoverModules); return composite; }