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); } }
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)); }
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 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"; } }
// 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; }
/// 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; } }
/// 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; } }
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 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."); }
bool FunctionImportGlobalProcessing::isNonRenamableLocal( const GlobalValue &GV) const { if (!GV.hasLocalLinkage()) return false; // This needs to stay in sync with the logic in buildModuleSummaryIndex. if (GV.hasSection()) return true; if (Used.count(const_cast<GlobalValue *>(&GV))) return true; return false; }
JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) { JITSymbolFlags Flags = JITSymbolFlags::None; if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage()) Flags |= JITSymbolFlags::Weak; if (GV.hasCommonLinkage()) Flags |= JITSymbolFlags::Common; if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility()) Flags |= JITSymbolFlags::Exported; if (isa<Function>(GV)) Flags |= JITSymbolFlags::Callable; else if (isa<GlobalAlias>(GV) && isa<Function>(cast<GlobalAlias>(GV).getAliasee())) Flags |= JITSymbolFlags::Callable; return Flags; }
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); }
bool IRLinker::shouldLink(GlobalValue *DGV, GlobalValue &SGV) { if (ValuesToLink.count(&SGV)) return true; if (SGV.hasLocalLinkage()) return true; if (DGV && !DGV->isDeclaration()) return false; if (SGV.hasAvailableExternallyLinkage()) return true; if (DoneLinkingBodies) return false; AddLazyFor(SGV, [this](GlobalValue &GV) { maybeAdd(&GV); }); return ValuesToLink.count(&SGV); }
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()); }
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 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); // Record the linkage type of non-local symbols so they can be restored prior // to module splitting. if (ShouldRestoreGlobalsLinkage && !GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() && GV.hasName()) ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage())); }
SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { // FIXME there isn't actually debug info here DebugLoc dl = Op.getDebugLoc(); GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32); if (getTargetMachine().getRelocationModel() != Reloc::PIC_) { SDVTList VTs = DAG.getVTList(MVT::i32); MipsTargetObjectFile &TLOF = (MipsTargetObjectFile&)getObjFileLowering(); // %gp_rel relocation if (TLOF.IsGlobalInSmallSection(GV, getTargetMachine())) { SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, dl, VTs, &GA, 1); SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32); return DAG.getNode(ISD::ADD, dl, MVT::i32, GOT, GPRelNode); } // %hi/%lo relocation SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, VTs, &GA, 1); SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GA); return DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); } else { // Abicall relocations, TODO: make this cleaner. SDValue ResNode = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), GA, NULL, 0); // On functions and global targets not internal linked only // a load from got/GP is necessary for PIC to work. if (!GV->hasLocalLinkage() || isa<Function>(GV)) return ResNode; SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GA); return DAG.getNode(ISD::ADD, dl, MVT::i32, ResNode, Lo); } llvm_unreachable("Dont know how to handle GlobalAddress"); return SDValue(0,0); }
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"; } }
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); } }
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); }
/// LowerOperation - Provide custom lowering hooks for some operations. /// SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { DebugLoc dl = Op.getDebugLoc(); switch (Op.getOpcode()) { default: llvm_unreachable("Wasn't expecting to be able to lower this!"); case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: { unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); switch (IntNo) { default: break; // Don't custom lower most intrinsics. case Intrinsic::alpha_umulh: return DAG.getNode(ISD::MULHU, dl, MVT::i64, Op.getOperand(1), Op.getOperand(2)); } } case ISD::SRL_PARTS: { SDValue ShOpLo = Op.getOperand(0); SDValue ShOpHi = Op.getOperand(1); SDValue ShAmt = Op.getOperand(2); SDValue bm = DAG.getNode(ISD::SUB, dl, MVT::i64, DAG.getConstant(64, MVT::i64), ShAmt); SDValue BMCC = DAG.getSetCC(dl, MVT::i64, bm, DAG.getConstant(0, MVT::i64), ISD::SETLE); // if 64 - shAmt <= 0 SDValue Hi_Neg = DAG.getConstant(0, MVT::i64); SDValue ShAmt_Neg = DAG.getNode(ISD::SUB, dl, MVT::i64, DAG.getConstant(0, MVT::i64), bm); SDValue Lo_Neg = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpHi, ShAmt_Neg); // else SDValue carries = DAG.getNode(ISD::SHL, dl, MVT::i64, ShOpHi, bm); SDValue Hi_Pos = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpHi, ShAmt); SDValue Lo_Pos = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpLo, ShAmt); Lo_Pos = DAG.getNode(ISD::OR, dl, MVT::i64, Lo_Pos, carries); // Merge SDValue Hi = DAG.getNode(ISD::SELECT, dl, MVT::i64, BMCC, Hi_Neg, Hi_Pos); SDValue Lo = DAG.getNode(ISD::SELECT, dl, MVT::i64, BMCC, Lo_Neg, Lo_Pos); SDValue Ops[2] = { Lo, Hi }; return DAG.getMergeValues(Ops, 2, dl); } // case ISD::SRA_PARTS: // case ISD::SHL_PARTS: case ISD::SINT_TO_FP: { assert(Op.getOperand(0).getValueType() == MVT::i64 && "Unhandled SINT_TO_FP type in custom expander!"); SDValue LD; bool isDouble = Op.getValueType() == MVT::f64; LD = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, Op.getOperand(0)); SDValue FP = DAG.getNode(isDouble?AlphaISD::CVTQT_:AlphaISD::CVTQS_, dl, isDouble?MVT::f64:MVT::f32, LD); return FP; } case ISD::FP_TO_SINT: { bool isDouble = Op.getOperand(0).getValueType() == MVT::f64; SDValue src = Op.getOperand(0); if (!isDouble) //Promote src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, src); src = DAG.getNode(AlphaISD::CVTTQ_, dl, MVT::f64, src); return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i64, src); } case ISD::ConstantPool: { ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); Constant *C = CP->getConstVal(); SDValue CPI = DAG.getTargetConstantPool(C, MVT::i64, CP->getAlignment()); // FIXME there isn't really any debug info here SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, CPI, DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, CPI, Hi); return Lo; } case ISD::GlobalTLSAddress: llvm_unreachable("TLS not implemented for Alpha."); case ISD::GlobalAddress: { GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op); GlobalValue *GV = GSDN->getGlobal(); SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i64, GSDN->getOffset()); // FIXME there isn't really any debug info here // if (!GV->hasWeakLinkage() && !GV->isDeclaration() && !GV->hasLinkOnceLinkage()) { if (GV->hasLocalLinkage()) { SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, GA, DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, GA, Hi); return Lo; } else return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64, GA, DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); } case ISD::ExternalSymbol: { return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64, DAG.getTargetExternalSymbol(cast<ExternalSymbolSDNode>(Op) ->getSymbol(), MVT::i64), DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); } case ISD::UREM: case ISD::SREM: //Expand only on constant case if (Op.getOperand(1).getOpcode() == ISD::Constant) { EVT VT = Op.getNode()->getValueType(0); SDValue Tmp1 = Op.getNode()->getOpcode() == ISD::UREM ? BuildUDIV(Op.getNode(), DAG, NULL) : BuildSDIV(Op.getNode(), DAG, NULL); Tmp1 = DAG.getNode(ISD::MUL, dl, VT, Tmp1, Op.getOperand(1)); Tmp1 = DAG.getNode(ISD::SUB, dl, VT, Op.getOperand(0), Tmp1); return Tmp1; } //fall through case ISD::SDIV: case ISD::UDIV: if (Op.getValueType().isInteger()) { if (Op.getOperand(1).getOpcode() == ISD::Constant) return Op.getOpcode() == ISD::SDIV ? BuildSDIV(Op.getNode(), DAG, NULL) : BuildUDIV(Op.getNode(), DAG, NULL); const char* opstr = 0; switch (Op.getOpcode()) { case ISD::UREM: opstr = "__remqu"; break; case ISD::SREM: opstr = "__remq"; break; case ISD::UDIV: opstr = "__divqu"; break; case ISD::SDIV: opstr = "__divq"; break; } SDValue Tmp1 = Op.getOperand(0), Tmp2 = Op.getOperand(1), Addr = DAG.getExternalSymbol(opstr, MVT::i64); return DAG.getNode(AlphaISD::DivCall, dl, MVT::i64, Addr, Tmp1, Tmp2); } break; case ISD::VAARG: { SDValue Chain, DataPtr; LowerVAARG(Op.getNode(), Chain, DataPtr, DAG); SDValue Result; if (Op.getValueType() == MVT::i32) Result = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Chain, DataPtr, NULL, 0, MVT::i32); else Result = DAG.getLoad(Op.getValueType(), dl, Chain, DataPtr, NULL, 0); return Result; } case ISD::VACOPY: { SDValue Chain = Op.getOperand(0); SDValue DestP = Op.getOperand(1); SDValue SrcP = Op.getOperand(2); const Value *DestS = cast<SrcValueSDNode>(Op.getOperand(3))->getValue(); const Value *SrcS = cast<SrcValueSDNode>(Op.getOperand(4))->getValue(); SDValue Val = DAG.getLoad(getPointerTy(), dl, Chain, SrcP, SrcS, 0); SDValue Result = DAG.getStore(Val.getValue(1), dl, Val, DestP, DestS, 0); SDValue NP = DAG.getNode(ISD::ADD, dl, MVT::i64, SrcP, DAG.getConstant(8, MVT::i64)); Val = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Result, NP, NULL,0, MVT::i32); SDValue NPD = DAG.getNode(ISD::ADD, dl, MVT::i64, DestP, DAG.getConstant(8, MVT::i64)); return DAG.getTruncStore(Val.getValue(1), dl, Val, NPD, NULL, 0, MVT::i32); } case ISD::VASTART: { SDValue Chain = Op.getOperand(0); SDValue VAListP = Op.getOperand(1); const Value *VAListS = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); // vastart stores the address of the VarArgsBase and VarArgsOffset SDValue FR = DAG.getFrameIndex(VarArgsBase, MVT::i64); SDValue S1 = DAG.getStore(Chain, dl, FR, VAListP, VAListS, 0); SDValue SA2 = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP, DAG.getConstant(8, MVT::i64)); return DAG.getTruncStore(S1, dl, DAG.getConstant(VarArgsOffset, MVT::i64), SA2, NULL, 0, MVT::i32); } case ISD::RETURNADDR: return DAG.getNode(AlphaISD::GlobalRetAddr, DebugLoc::getUnknownLoc(), MVT::i64); //FIXME: implement case ISD::FRAMEADDR: break; } return SDValue(); }
static bool isNonRenamableLocal(const GlobalValue &GV) { return GV.hasSection() && GV.hasLocalLinkage(); }
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; }
static void internalize(GlobalValue &GV) { assert(!GV.hasLocalLinkage() && "Trying to internalize a symbol with local linkage!"); GV.setLinkage(GlobalValue::InternalLinkage); }