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 void DumpSymbolNameForGlobalValue(GlobalValue &GV) { // Private linkage and available_externally linkage don't exist in symtab. if (GV.hasPrivateLinkage() || GV.hasLinkerPrivateLinkage() || GV.hasLinkerPrivateWeakLinkage() || GV.hasAvailableExternallyLinkage()) return; const std::string SymbolAddrStr = " "; // Not used yet... char TypeChar = TypeCharForSymbol(GV); if ((TypeChar != 'U') && UndefinedOnly) return; if ((TypeChar == 'U') && DefinedOnly) return; if (GV.hasLocalLinkage () && ExternalOnly) return; if (OutputFormat == posix) { outs() << GV.getName () << " " << TypeCharForSymbol(GV) << " " << SymbolAddrStr << "\n"; } else if (OutputFormat == bsd) { outs() << SymbolAddrStr << " " << TypeCharForSymbol(GV) << " " << GV.getName () << "\n"; } else if (OutputFormat == sysv) { std::string PaddedName (GV.getName ()); while (PaddedName.length () < 20) PaddedName += " "; outs() << PaddedName << "|" << SymbolAddrStr << "| " << TypeCharForSymbol(GV) << " | | | |\n"; } }
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; }
void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) { if (!shouldLinkReferencedLinkOnce()) // For ThinLTO we don't import more than what was required. // The client has to guarantee that the linkonce will be availabe at link // time (by promoting it to weak for instance). return; // Add these to the internalize list if (!GV.hasLinkOnceLinkage() && !shouldLinkOnlyNeeded()) return; if (shouldInternalizeLinkedSymbols()) Internalize.insert(GV.getName()); Add(GV); const Comdat *SC = GV.getComdat(); if (!SC) return; for (GlobalValue *GV2 : LazyComdatMembers[SC]) { GlobalValue *DGV = getLinkedToGlobal(GV2); bool LinkFromSrc = true; if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) return; if (!LinkFromSrc) continue; if (shouldInternalizeLinkedSymbols()) Internalize.insert(GV2->getName()); Add(*GV2); } }
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; }
void LTOCodeGenerator:: applyRestriction(GlobalValue &GV, std::vector<const char*> &MustPreserveList, std::vector<const char*> &DSOList, 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 (DSOSymbols.count(Buffer)) DSOList.push_back(GV.getName().data()); if (AsmUndefinedRefs.count(Buffer)) AsmUsed.insert(&GV); }
Module * llvmutil_extractmodule(Module * OrigMod, TargetMachine * TM, std::vector<llvm::GlobalValue*> * livevalues, std::vector<std::string> * symbolnames, bool internalizeandoptimize) { assert(symbolnames == NULL || livevalues->size() == symbolnames->size()); ValueToValueMapTy VMap; #if LLVM_VERSION >= 34 Module * M = llvmutil_extractmodulewithproperties(OrigMod->getModuleIdentifier(), OrigMod, (llvm::GlobalValue **)&(*livevalues)[0], livevalues->size(), AlwaysCopy, NULL, VMap); #else Module * M = CloneModule(OrigMod, VMap); internalizeandoptimize = true; //we need to do this regardless of the input because it is the only way we can extract just the needed functions from the module #endif //rename values to symbolsnames std::vector<const char *> names; for(size_t i = 0; i < livevalues->size(); i++) { GlobalValue * fn = cast<GlobalValue>(VMap[(*livevalues)[i]]); const std::string & name = (*symbolnames)[i]; GlobalValue * gv = M->getNamedValue(name); if(gv) { //if there is already a symbol with this name, rename it gv->setName(Twine((*symbolnames)[i],"_renamed")); } fn->setName(name); //and set our function to this name assert(fn->getName() == name); names.push_back(name.c_str()); //internalize pass has weird interface, so we need to copy the names here } if (!internalizeandoptimize) return M; //at this point we run optimizations on the module //first internalize all functions not mentioned in "names" using an internalize pass and then perform //standard optimizations PassManager MPM; llvmutil_addtargetspecificpasses(&MPM, TM); MPM.add(createVerifierPass()); //make sure we haven't messed stuff up yet MPM.add(createInternalizePass(names)); MPM.add(createGlobalDCEPass()); //run this early since anything not in the table of exported functions is still in this module //this will remove dead functions PassManagerBuilder PMB; PMB.OptLevel = 3; PMB.SizeLevel = 0; #if LLVM_VERSION >= 35 PMB.LoopVectorize = true; PMB.SLPVectorize = true; #endif PMB.populateModulePassManager(MPM); MPM.run(*M); return M; }
void Variables::changeGlobal(Change* change, Module &module) { GlobalValue* oldTarget = dyn_cast<GlobalValue>(change->getValue()); Type* oldType = oldTarget->getType()->getElementType(); Type* newType = change->getType()[0]; errs() << "Changing the precision of variable \"" << oldTarget->getName() << "\" from " << *oldType << " to " << *newType << ".\n"; if (diffTypes(oldType, newType)) { Constant *initializer; GlobalVariable* newTarget; if (PointerType *newPointerType = dyn_cast<PointerType>(newType)) { initializer = ConstantPointerNull::get(newPointerType); newTarget = new GlobalVariable(module, newType, false, GlobalValue::CommonLinkage, initializer, ""); } else if (ArrayType * atype = dyn_cast<ArrayType>(newType)) { // preparing initializer Type *temp = Type::getFloatTy(module.getContext()); vector<Constant*> operands; operands.push_back(ConstantFP::get(temp, 0)); ArrayRef<Constant*> *arrayRef = new ArrayRef<Constant*>(operands); initializer = ConstantArray::get(atype, *arrayRef); newTarget = new GlobalVariable(module, newType, false, GlobalValue::CommonLinkage, initializer, ""); } else { initializer = ConstantFP::get(newType, 0); newTarget = new GlobalVariable(module, newType, false, GlobalValue::CommonLinkage, initializer, ""); } /* GlobalVariable* newTarget = new GlobalVariable(module, newType, false, GlobalValue::CommonLinkage, initializer, ""); */ unsigned alignment = getAlignment(newType); newTarget->setAlignment(alignment); newTarget->takeName(oldTarget); // iterating through instructions using old AllocaInst Value::use_iterator it = oldTarget->use_begin(); for(; it != oldTarget->use_end(); it++) { Transformer::transform(it, newTarget, oldTarget, newType, oldType, alignment); } //oldTarget->eraseFromParent(); } else { errs() << "No changes required.\n"; } return; }
static void DumpSymbolNameForGlobalValue(GlobalValue &GV) { const std::string SymbolAddrStr = " "; // Not used yet... char TypeChar = TypeCharForSymbol (GV); if ((TypeChar != 'U') && UndefinedOnly) return; if ((TypeChar == 'U') && DefinedOnly) return; if (GV.hasLocalLinkage () && ExternalOnly) return; if (OutputFormat == posix) { std::cout << GV.getName () << " " << TypeCharForSymbol (GV) << " " << SymbolAddrStr << "\n"; } else if (OutputFormat == bsd) { std::cout << SymbolAddrStr << " " << TypeCharForSymbol (GV) << " " << GV.getName () << "\n"; } else if (OutputFormat == sysv) { std::string PaddedName (GV.getName ()); while (PaddedName.length () < 20) PaddedName += " "; std::cout << PaddedName << "|" << SymbolAddrStr << "| " << TypeCharForSymbol (GV) << " | | | |\n"; } }
static void DumpSymbolNameForGlobalValue(GlobalValue &GV) { // Private linkage and available_externally linkage don't exist in symtab. if (GV.hasPrivateLinkage() || GV.hasLinkerPrivateLinkage() || GV.hasLinkerPrivateWeakLinkage() || GV.hasAvailableExternallyLinkage()) return; char TypeChar = TypeCharForSymbol(GV); if (GV.hasLocalLinkage () && ExternalOnly) return; NMSymbol s; s.Address = object::UnknownAddressOrSize; s.Size = object::UnknownAddressOrSize; s.TypeChar = TypeChar; s.Name = GV.getName(); SymbolList.push_back(s); }
void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) { // Add these to the internalize list if (!GV.hasLinkOnceLinkage()) return; if (shouldInternalizeLinkedSymbols()) Internalize.insert(GV.getName()); Add(GV); const Comdat *SC = GV.getComdat(); if (!SC) return; for (GlobalValue *GV2 : ComdatMembers[SC]) { if (!GV2->hasLocalLinkage() && shouldInternalizeLinkedSymbols()) Internalize.insert(GV2->getName()); Add(*GV2); } }
bool UnsafeTypeCastingCheck::doInitialization(llvm::Module &mod) { errs() << "initialization... \n"; for (Module::global_iterator git = mod.global_begin() ; git != mod.global_end() ; git++) { GlobalValue *gv = dyn_cast<GlobalValue>(git); string gv_name = gv->getName().str(); if (gv_name.compare("blockDim") == 0 || gv_name.compare("gridDim") == 0 || gv_name.compare("blockIdx") == 0 || gv_name.compare("threadIdx") == 0) { setPointedType(gv, UINT_UT); } } // get utcc_assert function call (assertion) code_modified = false; assert_func = mod.getFunction("utcc_assert"); assert(assert_func != NULL); return false; }
void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) { // Add these to the internalize list if (!GV.hasLinkOnceLinkage()) return; if (shouldInternalizeLinkedSymbols()) Internalize.insert(GV.getName()); Add(GV); const Comdat *SC = GV.getComdat(); if (!SC) return; for (GlobalValue *GV2 : LazyComdatMembers[SC]) { GlobalValue *DGV = getLinkedToGlobal(GV2); bool LinkFromSrc = true; if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) return; if (!LinkFromSrc) continue; if (shouldInternalizeLinkedSymbols()) Internalize.insert(GV2->getName()); Add(*GV2); } }
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::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!"); }
static std::unique_ptr<Module> getModuleForFile(LLVMContext &Context, claimed_file &F, ld_plugin_input_file &Info, raw_fd_ostream *ApiFile, StringSet<> &Internalize, StringSet<> &Maybe) { if (get_symbols(F.handle, F.syms.size(), F.syms.data()) != LDPS_OK) message(LDPL_FATAL, "Failed to get symbol information"); const void *View; if (get_view(F.handle, &View) != LDPS_OK) message(LDPL_FATAL, "Failed to get a view of file"); 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); DenseSet<GlobalValue *> Drop; std::vector<GlobalAlias *> KeptAliases; unsigned SymNum = 0; for (auto &ObjSym : Obj.symbols()) { 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'; GlobalValue *GV = Obj.getSymbolGV(ObjSym.getRawDataRefImpl()); if (!GV) { freeSymName(Sym); continue; // Asm symbol. } if (Resolution != LDPR_PREVAILING_DEF_IRONLY && GV->hasCommonLinkage()) { // Common linkage is special. There is no single symbol that wins the // resolution. Instead we have to collect the maximum alignment and size. // The IR linker does that for us if we just pass it every common GV. // We still have to keep track of LDPR_PREVAILING_DEF_IRONLY so we // internalize once the IR linker has done its job. freeSymName(Sym); continue; } switch (Resolution) { case LDPR_UNKNOWN: llvm_unreachable("Unexpected resolution"); case LDPR_RESOLVED_IR: case LDPR_RESOLVED_EXEC: case LDPR_RESOLVED_DYN: assert(GV->isDeclarationForLinker()); break; case LDPR_UNDEF: if (!GV->isDeclarationForLinker()) { assert(GV->hasComdat()); Drop.insert(GV); } break; case LDPR_PREVAILING_DEF_IRONLY: { keepGlobalValue(*GV, KeptAliases); if (!Used.count(GV)) { // Since we use the regular lib/Linker, we cannot just internalize GV // now or it will not be copied to the merged module. Instead we force // it to be copied and then internalize it. Internalize.insert(GV->getName()); } break; } case LDPR_PREVAILING_DEF: keepGlobalValue(*GV, KeptAliases); break; case LDPR_PREEMPTED_IR: // Gold might have selected a linkonce_odr and preempted a weak_odr. // In that case we have to make sure we don't end up internalizing it. if (!GV->isDiscardableIfUnused()) Maybe.erase(GV->getName()); // fall-through case LDPR_PREEMPTED_REG: Drop.insert(GV); 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. if (GV->hasLinkOnceODRLinkage()) Maybe.insert(GV->getName()); keepGlobalValue(*GV, KeptAliases); break; } } freeSymName(Sym); } ValueToValueMapTy VM; LocalValueMaterializer Materializer(Drop); for (GlobalAlias *GA : KeptAliases) { // Gold told us to keep GA. It is possible that a GV usied in the aliasee // expression is being dropped. If that is the case, that GV must be copied. Constant *Aliasee = GA->getAliasee(); Constant *Replacement = mapConstantToLocalCopy(Aliasee, VM, &Materializer); GA->setAliasee(Replacement); } for (auto *GV : Drop) drop(*GV); return Obj.takeModule(); }
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); } }
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!"); }
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) {}); }
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(); }
bool InternalizePass::runOnModule(Module &M) { CallGraphWrapperPass *CGPass = getAnalysisIfAvailable<CallGraphWrapperPass>(); CallGraph *CG = CGPass ? &CGPass->getCallGraph() : 0; CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0; bool Changed = false; SmallPtrSet<GlobalValue *, 8> Used; collectUsedGlobalVariables(M, Used, false); // We must assume that globals in llvm.used have a reference that not even // the linker can see, so we don't internalize them. // For llvm.compiler.used the situation is a bit fuzzy. The assembler and // linker can drop those symbols. If this pass is running as part of LTO, // one might think that it could just drop llvm.compiler.used. The problem // is that even in LTO llvm doesn't see every reference. For example, // we don't see references from function local inline assembly. To be // conservative, we internalize symbols in llvm.compiler.used, but we // keep llvm.compiler.used so that the symbol is not deleted by llvm. for (SmallPtrSet<GlobalValue *, 8>::iterator I = Used.begin(), E = Used.end(); I != E; ++I) { GlobalValue *V = *I; ExternalNames.insert(V->getName()); } // Mark all functions not in the api as internal. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (!shouldInternalize(*I, ExternalNames, OnlyHidden)) continue; I->setLinkage(GlobalValue::InternalLinkage); if (ExternalNode) // Remove a callgraph edge from the external node to this function. ExternalNode->removeOneAbstractEdgeTo((*CG)[I]); Changed = true; ++NumFunctions; DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n"); } // Never internalize the llvm.used symbol. It is used to implement // attribute((used)). // FIXME: Shouldn't this just filter on llvm.metadata section?? ExternalNames.insert("llvm.used"); ExternalNames.insert("llvm.compiler.used"); // Never internalize anchors used by the machine module info, else the info // won't find them. (see MachineModuleInfo.) ExternalNames.insert("llvm.global_ctors"); ExternalNames.insert("llvm.global_dtors"); ExternalNames.insert("llvm.global.annotations"); // Never internalize symbols code-gen inserts. // FIXME: We should probably add this (and the __stack_chk_guard) via some // type of call-back in CodeGen. ExternalNames.insert("__stack_chk_fail"); ExternalNames.insert("__stack_chk_guard"); // Mark all global variables with initializers that are not in the api as // internal as well. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (!shouldInternalize(*I, ExternalNames, OnlyHidden)) continue; I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumGlobals; DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n"); } // Mark all aliases that are not in the api as internal as well. for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) { if (!shouldInternalize(*I, ExternalNames, OnlyHidden)) continue; I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumAliases; DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n"); } return Changed; }
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; }