// getOrInsertFunction - Look up the specified function in the module symbol // table. If it does not exist, add a prototype for the function and return // it. This is nice because it allows most passes to get away with not handling // the symbol table directly for this common task. // Constant *Module::getOrInsertFunction(StringRef Name, FunctionType *Ty, AttrListPtr AttributeList) { // See if we have a definition for the specified function already. GlobalValue *F = getNamedValue(Name); if (F == 0) { // Nope, add it Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name); if (!New->isIntrinsic()) // Intrinsics get attrs set on construction New->setAttributes(AttributeList); FunctionList.push_back(New); return New; // Return the new prototype. } // Okay, the function exists. Does it have externally visible linkage? if (F->hasLocalLinkage()) { // Clear the function's name. F->setName(""); // Retry, now there won't be a conflict. Constant *NewF = getOrInsertFunction(Name, Ty); F->setName(Name); return NewF; } // If the function exists but has the wrong type, return a bitcast to the // right type. if (F->getType() != PointerType::getUnqual(Ty)) return ConstantExpr::getBitCast(F, PointerType::getUnqual(Ty)); // Otherwise, we just found the existing function or a prototype. return F; }
// getOrInsertFunction - Look up the specified function in the module symbol // table. If it does not exist, add a prototype for the function and return // it. This is nice because it allows most passes to get away with not handling // the symbol table directly for this common task. // Constant *Module::getOrInsertFunction(const std::string &Name, const FunctionType *Ty) { ValueSymbolTable &SymTab = getValueSymbolTable(); // See if we have a definition for the specified function already. GlobalValue *F = dyn_cast_or_null<GlobalValue>(SymTab.lookup(Name)); if (F == 0) { // Nope, add it Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name); FunctionList.push_back(New); return New; // Return the new prototype. } // Okay, the function exists. Does it have externally visible linkage? if (F->hasInternalLinkage()) { // Clear the function's name. F->setName(""); // Retry, now there won't be a conflict. Constant *NewF = getOrInsertFunction(Name, Ty); F->setName(&Name[0], Name.size()); return NewF; } // If the function exists but has the wrong type, return a bitcast to the // right type. if (F->getType() != PointerType::getUnqual(Ty)) return ConstantExpr::getBitCast(F, PointerType::getUnqual(Ty)); // Otherwise, we just found the existing function or a prototype. return F; }
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 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); } }
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."); }
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)); }
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); } }
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); } }