10b57cec5SDimitry Andric //===-- Globals.cpp - Implement the GlobalValue & GlobalVariable class ----===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the GlobalValue & GlobalVariable classes for the IR
100b57cec5SDimitry Andric // library.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "LLVMContextImpl.h"
150b57cec5SDimitry Andric #include "llvm/IR/ConstantRange.h"
160b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
170b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
180b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h"
190b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
200b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h"
210b57cec5SDimitry Andric #include "llvm/IR/Module.h"
220b57cec5SDimitry Andric #include "llvm/Support/Error.h"
230b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
24*0fca6ea1SDimitry Andric #include "llvm/Support/MD5.h"
2506c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
260b57cec5SDimitry Andric using namespace llvm;
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
290b57cec5SDimitry Andric // GlobalValue Class
300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric // GlobalValue should be a Constant, plus a type, a module, some flags, and an
330b57cec5SDimitry Andric // intrinsic ID. Add an assert to prevent people from accidentally growing
340b57cec5SDimitry Andric // GlobalValue while adding flags.
350b57cec5SDimitry Andric static_assert(sizeof(GlobalValue) ==
360b57cec5SDimitry Andric sizeof(Constant) + 2 * sizeof(void *) + 2 * sizeof(unsigned),
370b57cec5SDimitry Andric "unexpected GlobalValue size growth");
380b57cec5SDimitry Andric
390b57cec5SDimitry Andric // GlobalObject adds a comdat.
400b57cec5SDimitry Andric static_assert(sizeof(GlobalObject) == sizeof(GlobalValue) + sizeof(void *),
410b57cec5SDimitry Andric "unexpected GlobalObject size growth");
420b57cec5SDimitry Andric
isMaterializable() const430b57cec5SDimitry Andric bool GlobalValue::isMaterializable() const {
440b57cec5SDimitry Andric if (const Function *F = dyn_cast<Function>(this))
450b57cec5SDimitry Andric return F->isMaterializable();
460b57cec5SDimitry Andric return false;
470b57cec5SDimitry Andric }
materialize()4806c3fb27SDimitry Andric Error GlobalValue::materialize() { return getParent()->materialize(this); }
490b57cec5SDimitry Andric
500b57cec5SDimitry Andric /// Override destroyConstantImpl to make sure it doesn't get called on
510b57cec5SDimitry Andric /// GlobalValue's because they shouldn't be treated like other constants.
destroyConstantImpl()520b57cec5SDimitry Andric void GlobalValue::destroyConstantImpl() {
530b57cec5SDimitry Andric llvm_unreachable("You can't GV->destroyConstantImpl()!");
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric
handleOperandChangeImpl(Value * From,Value * To)560b57cec5SDimitry Andric Value *GlobalValue::handleOperandChangeImpl(Value *From, Value *To) {
570b57cec5SDimitry Andric llvm_unreachable("Unsupported class for handleOperandChange()!");
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric
600b57cec5SDimitry Andric /// copyAttributesFrom - copy all additional attributes (those not needed to
610b57cec5SDimitry Andric /// create a GlobalValue) from the GlobalValue Src to this one.
copyAttributesFrom(const GlobalValue * Src)620b57cec5SDimitry Andric void GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
630b57cec5SDimitry Andric setVisibility(Src->getVisibility());
640b57cec5SDimitry Andric setUnnamedAddr(Src->getUnnamedAddr());
655ffd83dbSDimitry Andric setThreadLocalMode(Src->getThreadLocalMode());
660b57cec5SDimitry Andric setDLLStorageClass(Src->getDLLStorageClass());
670b57cec5SDimitry Andric setDSOLocal(Src->isDSOLocal());
680b57cec5SDimitry Andric setPartition(Src->getPartition());
6981ad6265SDimitry Andric if (Src->hasSanitizerMetadata())
7081ad6265SDimitry Andric setSanitizerMetadata(Src->getSanitizerMetadata());
7181ad6265SDimitry Andric else
7281ad6265SDimitry Andric removeSanitizerMetadata();
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric
getGUID(StringRef GlobalName)75*0fca6ea1SDimitry Andric GlobalValue::GUID GlobalValue::getGUID(StringRef GlobalName) {
76*0fca6ea1SDimitry Andric return MD5Hash(GlobalName);
77*0fca6ea1SDimitry Andric }
78*0fca6ea1SDimitry Andric
removeFromParent()790b57cec5SDimitry Andric void GlobalValue::removeFromParent() {
800b57cec5SDimitry Andric switch (getValueID()) {
810b57cec5SDimitry Andric #define HANDLE_GLOBAL_VALUE(NAME) \
820b57cec5SDimitry Andric case Value::NAME##Val: \
830b57cec5SDimitry Andric return static_cast<NAME *>(this)->removeFromParent();
840b57cec5SDimitry Andric #include "llvm/IR/Value.def"
850b57cec5SDimitry Andric default:
860b57cec5SDimitry Andric break;
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric llvm_unreachable("not a global");
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric
eraseFromParent()910b57cec5SDimitry Andric void GlobalValue::eraseFromParent() {
920b57cec5SDimitry Andric switch (getValueID()) {
930b57cec5SDimitry Andric #define HANDLE_GLOBAL_VALUE(NAME) \
940b57cec5SDimitry Andric case Value::NAME##Val: \
950b57cec5SDimitry Andric return static_cast<NAME *>(this)->eraseFromParent();
960b57cec5SDimitry Andric #include "llvm/IR/Value.def"
970b57cec5SDimitry Andric default:
980b57cec5SDimitry Andric break;
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric llvm_unreachable("not a global");
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric
~GlobalObject()10304eeddc0SDimitry Andric GlobalObject::~GlobalObject() { setComdat(nullptr); }
10404eeddc0SDimitry Andric
isInterposable() const1055ffd83dbSDimitry Andric bool GlobalValue::isInterposable() const {
1065ffd83dbSDimitry Andric if (isInterposableLinkage(getLinkage()))
1075ffd83dbSDimitry Andric return true;
1085ffd83dbSDimitry Andric return getParent() && getParent()->getSemanticInterposition() &&
1095ffd83dbSDimitry Andric !isDSOLocal();
1100b57cec5SDimitry Andric }
1115ffd83dbSDimitry Andric
canBenefitFromLocalAlias() const1125ffd83dbSDimitry Andric bool GlobalValue::canBenefitFromLocalAlias() const {
11304eeddc0SDimitry Andric // See AsmPrinter::getSymbolPreferLocal(). For a deduplicate comdat kind,
11404eeddc0SDimitry Andric // references to a discarded local symbol from outside the group are not
11504eeddc0SDimitry Andric // allowed, so avoid the local alias.
11604eeddc0SDimitry Andric auto isDeduplicateComdat = [](const Comdat *C) {
11704eeddc0SDimitry Andric return C && C->getSelectionKind() != Comdat::NoDeduplicate;
11804eeddc0SDimitry Andric };
1198833aad7SDimitry Andric return hasDefaultVisibility() &&
1208833aad7SDimitry Andric GlobalObject::isExternalLinkage(getLinkage()) && !isDeclaration() &&
12104eeddc0SDimitry Andric !isa<GlobalIFunc>(this) && !isDeduplicateComdat(getComdat());
1220b57cec5SDimitry Andric }
1230b57cec5SDimitry Andric
getDataLayout() const124*0fca6ea1SDimitry Andric const DataLayout &GlobalValue::getDataLayout() const {
125*0fca6ea1SDimitry Andric return getParent()->getDataLayout();
126*0fca6ea1SDimitry Andric }
127*0fca6ea1SDimitry Andric
setAlignment(MaybeAlign Align)1288bcb0991SDimitry Andric void GlobalObject::setAlignment(MaybeAlign Align) {
1295ffd83dbSDimitry Andric assert((!Align || *Align <= MaximumAlignment) &&
1300b57cec5SDimitry Andric "Alignment is greater than MaximumAlignment!");
1318bcb0991SDimitry Andric unsigned AlignmentData = encode(Align);
1320b57cec5SDimitry Andric unsigned OldData = getGlobalValueSubClassData();
1330b57cec5SDimitry Andric setGlobalValueSubClassData((OldData & ~AlignmentMask) | AlignmentData);
134bdd1243dSDimitry Andric assert(getAlign() == Align && "Alignment representation error!");
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric
setAlignment(Align Align)13706c3fb27SDimitry Andric void GlobalObject::setAlignment(Align Align) {
13806c3fb27SDimitry Andric assert(Align <= MaximumAlignment &&
13906c3fb27SDimitry Andric "Alignment is greater than MaximumAlignment!");
14006c3fb27SDimitry Andric unsigned AlignmentData = encode(Align);
14106c3fb27SDimitry Andric unsigned OldData = getGlobalValueSubClassData();
14206c3fb27SDimitry Andric setGlobalValueSubClassData((OldData & ~AlignmentMask) | AlignmentData);
14306c3fb27SDimitry Andric assert(getAlign() && *getAlign() == Align &&
14406c3fb27SDimitry Andric "Alignment representation error!");
14506c3fb27SDimitry Andric }
14606c3fb27SDimitry Andric
copyAttributesFrom(const GlobalObject * Src)1470b57cec5SDimitry Andric void GlobalObject::copyAttributesFrom(const GlobalObject *Src) {
1480b57cec5SDimitry Andric GlobalValue::copyAttributesFrom(Src);
1490eae32dcSDimitry Andric setAlignment(Src->getAlign());
1500b57cec5SDimitry Andric setSection(Src->getSection());
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric
getGlobalIdentifier(StringRef Name,GlobalValue::LinkageTypes Linkage,StringRef FileName)1530b57cec5SDimitry Andric std::string GlobalValue::getGlobalIdentifier(StringRef Name,
1540b57cec5SDimitry Andric GlobalValue::LinkageTypes Linkage,
1550b57cec5SDimitry Andric StringRef FileName) {
1560b57cec5SDimitry Andric // Value names may be prefixed with a binary '1' to indicate
1570b57cec5SDimitry Andric // that the backend should not modify the symbols due to any platform
1580b57cec5SDimitry Andric // naming convention. Do not include that '1' in the PGO profile name.
1597a6dacacSDimitry Andric Name.consume_front("\1");
1600b57cec5SDimitry Andric
161cb14a3feSDimitry Andric std::string GlobalName;
1620b57cec5SDimitry Andric if (llvm::GlobalValue::isLocalLinkage(Linkage)) {
1630b57cec5SDimitry Andric // For local symbols, prepend the main file name to distinguish them.
1640b57cec5SDimitry Andric // Do not include the full path in the file name since there's no guarantee
1650b57cec5SDimitry Andric // that it will stay the same, e.g., if the files are checked out from
1660b57cec5SDimitry Andric // version control in different locations.
1670b57cec5SDimitry Andric if (FileName.empty())
168cb14a3feSDimitry Andric GlobalName += "<unknown>";
1690b57cec5SDimitry Andric else
170cb14a3feSDimitry Andric GlobalName += FileName;
171cb14a3feSDimitry Andric
172*0fca6ea1SDimitry Andric GlobalName += GlobalIdentifierDelimiter;
1730b57cec5SDimitry Andric }
174cb14a3feSDimitry Andric GlobalName += Name;
175cb14a3feSDimitry Andric return GlobalName;
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric
getGlobalIdentifier() const1780b57cec5SDimitry Andric std::string GlobalValue::getGlobalIdentifier() const {
1790b57cec5SDimitry Andric return getGlobalIdentifier(getName(), getLinkage(),
1800b57cec5SDimitry Andric getParent()->getSourceFileName());
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric
getSection() const1830b57cec5SDimitry Andric StringRef GlobalValue::getSection() const {
1840b57cec5SDimitry Andric if (auto *GA = dyn_cast<GlobalAlias>(this)) {
1850b57cec5SDimitry Andric // In general we cannot compute this at the IR level, but we try.
186349cc55cSDimitry Andric if (const GlobalObject *GO = GA->getAliaseeObject())
1870b57cec5SDimitry Andric return GO->getSection();
1880b57cec5SDimitry Andric return "";
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric return cast<GlobalObject>(this)->getSection();
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric
getComdat() const1930b57cec5SDimitry Andric const Comdat *GlobalValue::getComdat() const {
1940b57cec5SDimitry Andric if (auto *GA = dyn_cast<GlobalAlias>(this)) {
1950b57cec5SDimitry Andric // In general we cannot compute this at the IR level, but we try.
196349cc55cSDimitry Andric if (const GlobalObject *GO = GA->getAliaseeObject())
1970b57cec5SDimitry Andric return const_cast<GlobalObject *>(GO)->getComdat();
1980b57cec5SDimitry Andric return nullptr;
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric // ifunc and its resolver are separate things so don't use resolver comdat.
2010b57cec5SDimitry Andric if (isa<GlobalIFunc>(this))
2020b57cec5SDimitry Andric return nullptr;
2030b57cec5SDimitry Andric return cast<GlobalObject>(this)->getComdat();
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric
setComdat(Comdat * C)20604eeddc0SDimitry Andric void GlobalObject::setComdat(Comdat *C) {
20704eeddc0SDimitry Andric if (ObjComdat)
20804eeddc0SDimitry Andric ObjComdat->removeUser(this);
20904eeddc0SDimitry Andric ObjComdat = C;
21004eeddc0SDimitry Andric if (C)
21104eeddc0SDimitry Andric C->addUser(this);
21204eeddc0SDimitry Andric }
21304eeddc0SDimitry Andric
getPartition() const2140b57cec5SDimitry Andric StringRef GlobalValue::getPartition() const {
2150b57cec5SDimitry Andric if (!hasPartition())
2160b57cec5SDimitry Andric return "";
2170b57cec5SDimitry Andric return getContext().pImpl->GlobalValuePartitions[this];
2180b57cec5SDimitry Andric }
2190b57cec5SDimitry Andric
setPartition(StringRef S)2200b57cec5SDimitry Andric void GlobalValue::setPartition(StringRef S) {
2210b57cec5SDimitry Andric // Do nothing if we're clearing the partition and it is already empty.
2220b57cec5SDimitry Andric if (!hasPartition() && S.empty())
2230b57cec5SDimitry Andric return;
2240b57cec5SDimitry Andric
2250b57cec5SDimitry Andric // Get or create a stable partition name string and put it in the table in the
2260b57cec5SDimitry Andric // context.
2270b57cec5SDimitry Andric if (!S.empty())
2280b57cec5SDimitry Andric S = getContext().pImpl->Saver.save(S);
2290b57cec5SDimitry Andric getContext().pImpl->GlobalValuePartitions[this] = S;
2300b57cec5SDimitry Andric
2310b57cec5SDimitry Andric // Update the HasPartition field. Setting the partition to the empty string
2320b57cec5SDimitry Andric // means this global no longer has a partition.
2330b57cec5SDimitry Andric HasPartition = !S.empty();
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric
23681ad6265SDimitry Andric using SanitizerMetadata = GlobalValue::SanitizerMetadata;
getSanitizerMetadata() const23781ad6265SDimitry Andric const SanitizerMetadata &GlobalValue::getSanitizerMetadata() const {
23881ad6265SDimitry Andric assert(hasSanitizerMetadata());
23981ad6265SDimitry Andric assert(getContext().pImpl->GlobalValueSanitizerMetadata.count(this));
24081ad6265SDimitry Andric return getContext().pImpl->GlobalValueSanitizerMetadata[this];
24181ad6265SDimitry Andric }
24281ad6265SDimitry Andric
setSanitizerMetadata(SanitizerMetadata Meta)24381ad6265SDimitry Andric void GlobalValue::setSanitizerMetadata(SanitizerMetadata Meta) {
24481ad6265SDimitry Andric getContext().pImpl->GlobalValueSanitizerMetadata[this] = Meta;
24581ad6265SDimitry Andric HasSanitizerMetadata = true;
24681ad6265SDimitry Andric }
24781ad6265SDimitry Andric
removeSanitizerMetadata()24881ad6265SDimitry Andric void GlobalValue::removeSanitizerMetadata() {
24981ad6265SDimitry Andric DenseMap<const GlobalValue *, SanitizerMetadata> &MetadataMap =
25081ad6265SDimitry Andric getContext().pImpl->GlobalValueSanitizerMetadata;
25181ad6265SDimitry Andric MetadataMap.erase(this);
25281ad6265SDimitry Andric HasSanitizerMetadata = false;
25381ad6265SDimitry Andric }
25481ad6265SDimitry Andric
setNoSanitizeMetadata()255*0fca6ea1SDimitry Andric void GlobalValue::setNoSanitizeMetadata() {
256*0fca6ea1SDimitry Andric SanitizerMetadata Meta;
257*0fca6ea1SDimitry Andric Meta.NoAddress = true;
258*0fca6ea1SDimitry Andric Meta.NoHWAddress = true;
259*0fca6ea1SDimitry Andric setSanitizerMetadata(Meta);
260*0fca6ea1SDimitry Andric }
261*0fca6ea1SDimitry Andric
getSectionImpl() const2620b57cec5SDimitry Andric StringRef GlobalObject::getSectionImpl() const {
2630b57cec5SDimitry Andric assert(hasSection());
2640b57cec5SDimitry Andric return getContext().pImpl->GlobalObjectSections[this];
2650b57cec5SDimitry Andric }
2660b57cec5SDimitry Andric
setSection(StringRef S)2670b57cec5SDimitry Andric void GlobalObject::setSection(StringRef S) {
2680b57cec5SDimitry Andric // Do nothing if we're clearing the section and it is already empty.
2690b57cec5SDimitry Andric if (!hasSection() && S.empty())
2700b57cec5SDimitry Andric return;
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andric // Get or create a stable section name string and put it in the table in the
2730b57cec5SDimitry Andric // context.
2740b57cec5SDimitry Andric if (!S.empty())
2750b57cec5SDimitry Andric S = getContext().pImpl->Saver.save(S);
2760b57cec5SDimitry Andric getContext().pImpl->GlobalObjectSections[this] = S;
2770b57cec5SDimitry Andric
2780b57cec5SDimitry Andric // Update the HasSectionHashEntryBit. Setting the section to the empty string
2790b57cec5SDimitry Andric // means this global no longer has a section.
2800b57cec5SDimitry Andric setGlobalObjectFlag(HasSectionHashEntryBit, !S.empty());
2810b57cec5SDimitry Andric }
2820b57cec5SDimitry Andric
isNobuiltinFnDef() const283bdd1243dSDimitry Andric bool GlobalValue::isNobuiltinFnDef() const {
284bdd1243dSDimitry Andric const Function *F = dyn_cast<Function>(this);
285bdd1243dSDimitry Andric if (!F || F->empty())
286bdd1243dSDimitry Andric return false;
287bdd1243dSDimitry Andric return F->hasFnAttribute(Attribute::NoBuiltin);
288bdd1243dSDimitry Andric }
289bdd1243dSDimitry Andric
isDeclaration() const2900b57cec5SDimitry Andric bool GlobalValue::isDeclaration() const {
2910b57cec5SDimitry Andric // Globals are definitions if they have an initializer.
2920b57cec5SDimitry Andric if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this))
2930b57cec5SDimitry Andric return GV->getNumOperands() == 0;
2940b57cec5SDimitry Andric
2950b57cec5SDimitry Andric // Functions are definitions if they have a body.
2960b57cec5SDimitry Andric if (const Function *F = dyn_cast<Function>(this))
2970b57cec5SDimitry Andric return F->empty() && !F->isMaterializable();
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric // Aliases and ifuncs are always definitions.
300349cc55cSDimitry Andric assert(isa<GlobalAlias>(this) || isa<GlobalIFunc>(this));
3010b57cec5SDimitry Andric return false;
3020b57cec5SDimitry Andric }
3030b57cec5SDimitry Andric
canIncreaseAlignment() const3045ffd83dbSDimitry Andric bool GlobalObject::canIncreaseAlignment() const {
3050b57cec5SDimitry Andric // Firstly, can only increase the alignment of a global if it
3060b57cec5SDimitry Andric // is a strong definition.
3070b57cec5SDimitry Andric if (!isStrongDefinitionForLinker())
3080b57cec5SDimitry Andric return false;
3090b57cec5SDimitry Andric
3100b57cec5SDimitry Andric // It also has to either not have a section defined, or, not have
3110b57cec5SDimitry Andric // alignment specified. (If it is assigned a section, the global
3120b57cec5SDimitry Andric // could be densely packed with other objects in the section, and
3130b57cec5SDimitry Andric // increasing the alignment could cause padding issues.)
31481ad6265SDimitry Andric if (hasSection() && getAlign())
3150b57cec5SDimitry Andric return false;
3160b57cec5SDimitry Andric
3170b57cec5SDimitry Andric // On ELF platforms, we're further restricted in that we can't
3180b57cec5SDimitry Andric // increase the alignment of any variable which might be emitted
3190b57cec5SDimitry Andric // into a shared library, and which is exported. If the main
3200b57cec5SDimitry Andric // executable accesses a variable found in a shared-lib, the main
3210b57cec5SDimitry Andric // exe actually allocates memory for and exports the symbol ITSELF,
3220b57cec5SDimitry Andric // overriding the symbol found in the library. That is, at link
3230b57cec5SDimitry Andric // time, the observed alignment of the variable is copied into the
3240b57cec5SDimitry Andric // executable binary. (A COPY relocation is also generated, to copy
3250b57cec5SDimitry Andric // the initial data from the shadowed variable in the shared-lib
3260b57cec5SDimitry Andric // into the location in the main binary, before running code.)
3270b57cec5SDimitry Andric //
3280b57cec5SDimitry Andric // And thus, even though you might think you are defining the
3290b57cec5SDimitry Andric // global, and allocating the memory for the global in your object
3300b57cec5SDimitry Andric // file, and thus should be able to set the alignment arbitrarily,
3310b57cec5SDimitry Andric // that's not actually true. Doing so can cause an ABI breakage; an
3320b57cec5SDimitry Andric // executable might have already been built with the previous
3330b57cec5SDimitry Andric // alignment of the variable, and then assuming an increased
3340b57cec5SDimitry Andric // alignment will be incorrect.
3350b57cec5SDimitry Andric
3360b57cec5SDimitry Andric // Conservatively assume ELF if there's no parent pointer.
3370b57cec5SDimitry Andric bool isELF =
3380b57cec5SDimitry Andric (!Parent || Triple(Parent->getTargetTriple()).isOSBinFormatELF());
3390b57cec5SDimitry Andric if (isELF && !isDSOLocal())
3400b57cec5SDimitry Andric return false;
3410b57cec5SDimitry Andric
342*0fca6ea1SDimitry Andric // GV with toc-data attribute is defined in a TOC entry. To mitigate TOC
343*0fca6ea1SDimitry Andric // overflow, the alignment of such symbol should not be increased. Otherwise,
344*0fca6ea1SDimitry Andric // padding is needed thus more TOC entries are wasted.
345*0fca6ea1SDimitry Andric bool isXCOFF =
346*0fca6ea1SDimitry Andric (!Parent || Triple(Parent->getTargetTriple()).isOSBinFormatXCOFF());
347*0fca6ea1SDimitry Andric if (isXCOFF)
348*0fca6ea1SDimitry Andric if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this))
349*0fca6ea1SDimitry Andric if (GV->hasAttribute("toc-data"))
350*0fca6ea1SDimitry Andric return false;
351*0fca6ea1SDimitry Andric
3520b57cec5SDimitry Andric return true;
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric
355fcaf7f86SDimitry Andric template <typename Operation>
356349cc55cSDimitry Andric static const GlobalObject *
findBaseObject(const Constant * C,DenseSet<const GlobalAlias * > & Aliases,const Operation & Op)357fcaf7f86SDimitry Andric findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases,
358fcaf7f86SDimitry Andric const Operation &Op) {
359fcaf7f86SDimitry Andric if (auto *GO = dyn_cast<GlobalObject>(C)) {
360fcaf7f86SDimitry Andric Op(*GO);
3610b57cec5SDimitry Andric return GO;
362fcaf7f86SDimitry Andric }
363fcaf7f86SDimitry Andric if (auto *GA = dyn_cast<GlobalAlias>(C)) {
364fcaf7f86SDimitry Andric Op(*GA);
365349cc55cSDimitry Andric if (Aliases.insert(GA).second)
366fcaf7f86SDimitry Andric return findBaseObject(GA->getOperand(0), Aliases, Op);
367fcaf7f86SDimitry Andric }
368349cc55cSDimitry Andric if (auto *CE = dyn_cast<ConstantExpr>(C)) {
369349cc55cSDimitry Andric switch (CE->getOpcode()) {
370349cc55cSDimitry Andric case Instruction::Add: {
371fcaf7f86SDimitry Andric auto *LHS = findBaseObject(CE->getOperand(0), Aliases, Op);
372fcaf7f86SDimitry Andric auto *RHS = findBaseObject(CE->getOperand(1), Aliases, Op);
373349cc55cSDimitry Andric if (LHS && RHS)
3740b57cec5SDimitry Andric return nullptr;
375349cc55cSDimitry Andric return LHS ? LHS : RHS;
376349cc55cSDimitry Andric }
377349cc55cSDimitry Andric case Instruction::Sub: {
378fcaf7f86SDimitry Andric if (findBaseObject(CE->getOperand(1), Aliases, Op))
379349cc55cSDimitry Andric return nullptr;
380fcaf7f86SDimitry Andric return findBaseObject(CE->getOperand(0), Aliases, Op);
381349cc55cSDimitry Andric }
382349cc55cSDimitry Andric case Instruction::IntToPtr:
383349cc55cSDimitry Andric case Instruction::PtrToInt:
384349cc55cSDimitry Andric case Instruction::BitCast:
385349cc55cSDimitry Andric case Instruction::GetElementPtr:
386fcaf7f86SDimitry Andric return findBaseObject(CE->getOperand(0), Aliases, Op);
387349cc55cSDimitry Andric default:
388349cc55cSDimitry Andric break;
389349cc55cSDimitry Andric }
390349cc55cSDimitry Andric }
391349cc55cSDimitry Andric return nullptr;
392349cc55cSDimitry Andric }
393349cc55cSDimitry Andric
getAliaseeObject() const394349cc55cSDimitry Andric const GlobalObject *GlobalValue::getAliaseeObject() const {
395349cc55cSDimitry Andric DenseSet<const GlobalAlias *> Aliases;
396fcaf7f86SDimitry Andric return findBaseObject(this, Aliases, [](const GlobalValue &) {});
3970b57cec5SDimitry Andric }
3980b57cec5SDimitry Andric
isAbsoluteSymbolRef() const3990b57cec5SDimitry Andric bool GlobalValue::isAbsoluteSymbolRef() const {
4000b57cec5SDimitry Andric auto *GO = dyn_cast<GlobalObject>(this);
4010b57cec5SDimitry Andric if (!GO)
4020b57cec5SDimitry Andric return false;
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric return GO->getMetadata(LLVMContext::MD_absolute_symbol);
4050b57cec5SDimitry Andric }
4060b57cec5SDimitry Andric
getAbsoluteSymbolRange() const407bdd1243dSDimitry Andric std::optional<ConstantRange> GlobalValue::getAbsoluteSymbolRange() const {
4080b57cec5SDimitry Andric auto *GO = dyn_cast<GlobalObject>(this);
4090b57cec5SDimitry Andric if (!GO)
410bdd1243dSDimitry Andric return std::nullopt;
4110b57cec5SDimitry Andric
4120b57cec5SDimitry Andric MDNode *MD = GO->getMetadata(LLVMContext::MD_absolute_symbol);
4130b57cec5SDimitry Andric if (!MD)
414bdd1243dSDimitry Andric return std::nullopt;
4150b57cec5SDimitry Andric
4160b57cec5SDimitry Andric return getConstantRangeFromMetadata(*MD);
4170b57cec5SDimitry Andric }
4180b57cec5SDimitry Andric
canBeOmittedFromSymbolTable() const4190b57cec5SDimitry Andric bool GlobalValue::canBeOmittedFromSymbolTable() const {
4200b57cec5SDimitry Andric if (!hasLinkOnceODRLinkage())
4210b57cec5SDimitry Andric return false;
4220b57cec5SDimitry Andric
4230b57cec5SDimitry Andric // We assume that anyone who sets global unnamed_addr on a non-constant
4240b57cec5SDimitry Andric // knows what they're doing.
4250b57cec5SDimitry Andric if (hasGlobalUnnamedAddr())
4260b57cec5SDimitry Andric return true;
4270b57cec5SDimitry Andric
4280b57cec5SDimitry Andric // If it is a non constant variable, it needs to be uniqued across shared
4290b57cec5SDimitry Andric // objects.
4300b57cec5SDimitry Andric if (auto *Var = dyn_cast<GlobalVariable>(this))
4310b57cec5SDimitry Andric if (!Var->isConstant())
4320b57cec5SDimitry Andric return false;
4330b57cec5SDimitry Andric
4340b57cec5SDimitry Andric return hasAtLeastLocalUnnamedAddr();
4350b57cec5SDimitry Andric }
4360b57cec5SDimitry Andric
4370b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4380b57cec5SDimitry Andric // GlobalVariable Implementation
4390b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4400b57cec5SDimitry Andric
GlobalVariable(Type * Ty,bool constant,LinkageTypes Link,Constant * InitVal,const Twine & Name,ThreadLocalMode TLMode,unsigned AddressSpace,bool isExternallyInitialized)4410b57cec5SDimitry Andric GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
4420b57cec5SDimitry Andric Constant *InitVal, const Twine &Name,
4430b57cec5SDimitry Andric ThreadLocalMode TLMode, unsigned AddressSpace,
4440b57cec5SDimitry Andric bool isExternallyInitialized)
4450b57cec5SDimitry Andric : GlobalObject(Ty, Value::GlobalVariableVal,
4460b57cec5SDimitry Andric OperandTraits<GlobalVariable>::op_begin(this),
4470b57cec5SDimitry Andric InitVal != nullptr, Link, Name, AddressSpace),
4480b57cec5SDimitry Andric isConstantGlobal(constant),
4490b57cec5SDimitry Andric isExternallyInitializedConstant(isExternallyInitialized) {
4500b57cec5SDimitry Andric assert(!Ty->isFunctionTy() && PointerType::isValidElementType(Ty) &&
4510b57cec5SDimitry Andric "invalid type for global variable");
4520b57cec5SDimitry Andric setThreadLocalMode(TLMode);
4530b57cec5SDimitry Andric if (InitVal) {
4540b57cec5SDimitry Andric assert(InitVal->getType() == Ty &&
4550b57cec5SDimitry Andric "Initializer should be the same type as the GlobalVariable!");
4560b57cec5SDimitry Andric Op<0>() = InitVal;
4570b57cec5SDimitry Andric }
4580b57cec5SDimitry Andric }
4590b57cec5SDimitry Andric
GlobalVariable(Module & M,Type * Ty,bool constant,LinkageTypes Link,Constant * InitVal,const Twine & Name,GlobalVariable * Before,ThreadLocalMode TLMode,std::optional<unsigned> AddressSpace,bool isExternallyInitialized)4600b57cec5SDimitry Andric GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
4610b57cec5SDimitry Andric LinkageTypes Link, Constant *InitVal,
4620b57cec5SDimitry Andric const Twine &Name, GlobalVariable *Before,
463e8d8bef9SDimitry Andric ThreadLocalMode TLMode,
464bdd1243dSDimitry Andric std::optional<unsigned> AddressSpace,
4650b57cec5SDimitry Andric bool isExternallyInitialized)
46606c3fb27SDimitry Andric : GlobalVariable(Ty, constant, Link, InitVal, Name, TLMode,
467e8d8bef9SDimitry Andric AddressSpace
468e8d8bef9SDimitry Andric ? *AddressSpace
46906c3fb27SDimitry Andric : M.getDataLayout().getDefaultGlobalsAddressSpace(),
47006c3fb27SDimitry Andric isExternallyInitialized) {
4710b57cec5SDimitry Andric if (Before)
47206c3fb27SDimitry Andric Before->getParent()->insertGlobalVariable(Before->getIterator(), this);
4730b57cec5SDimitry Andric else
47406c3fb27SDimitry Andric M.insertGlobalVariable(this);
4750b57cec5SDimitry Andric }
4760b57cec5SDimitry Andric
removeFromParent()4770b57cec5SDimitry Andric void GlobalVariable::removeFromParent() {
47806c3fb27SDimitry Andric getParent()->removeGlobalVariable(this);
4790b57cec5SDimitry Andric }
4800b57cec5SDimitry Andric
eraseFromParent()4810b57cec5SDimitry Andric void GlobalVariable::eraseFromParent() {
48206c3fb27SDimitry Andric getParent()->eraseGlobalVariable(this);
4830b57cec5SDimitry Andric }
4840b57cec5SDimitry Andric
setInitializer(Constant * InitVal)4850b57cec5SDimitry Andric void GlobalVariable::setInitializer(Constant *InitVal) {
4860b57cec5SDimitry Andric if (!InitVal) {
4870b57cec5SDimitry Andric if (hasInitializer()) {
4880b57cec5SDimitry Andric // Note, the num operands is used to compute the offset of the operand, so
4890b57cec5SDimitry Andric // the order here matters. Clearing the operand then clearing the num
4900b57cec5SDimitry Andric // operands ensures we have the correct offset to the operand.
4910b57cec5SDimitry Andric Op<0>().set(nullptr);
4920b57cec5SDimitry Andric setGlobalVariableNumOperands(0);
4930b57cec5SDimitry Andric }
4940b57cec5SDimitry Andric } else {
4950b57cec5SDimitry Andric assert(InitVal->getType() == getValueType() &&
4960b57cec5SDimitry Andric "Initializer type must match GlobalVariable type");
4970b57cec5SDimitry Andric // Note, the num operands is used to compute the offset of the operand, so
4980b57cec5SDimitry Andric // the order here matters. We need to set num operands to 1 first so that
4990b57cec5SDimitry Andric // we get the correct offset to the first operand when we set it.
5000b57cec5SDimitry Andric if (!hasInitializer())
5010b57cec5SDimitry Andric setGlobalVariableNumOperands(1);
5020b57cec5SDimitry Andric Op<0>().set(InitVal);
5030b57cec5SDimitry Andric }
5040b57cec5SDimitry Andric }
5050b57cec5SDimitry Andric
5060b57cec5SDimitry Andric /// Copy all additional attributes (those not needed to create a GlobalVariable)
5070b57cec5SDimitry Andric /// from the GlobalVariable Src to this one.
copyAttributesFrom(const GlobalVariable * Src)5080b57cec5SDimitry Andric void GlobalVariable::copyAttributesFrom(const GlobalVariable *Src) {
5090b57cec5SDimitry Andric GlobalObject::copyAttributesFrom(Src);
5100b57cec5SDimitry Andric setExternallyInitialized(Src->isExternallyInitialized());
5110b57cec5SDimitry Andric setAttributes(Src->getAttributes());
5125f757f3fSDimitry Andric if (auto CM = Src->getCodeModel())
5135f757f3fSDimitry Andric setCodeModel(*CM);
5140b57cec5SDimitry Andric }
5150b57cec5SDimitry Andric
dropAllReferences()5160b57cec5SDimitry Andric void GlobalVariable::dropAllReferences() {
5170b57cec5SDimitry Andric User::dropAllReferences();
5180b57cec5SDimitry Andric clearMetadata();
5190b57cec5SDimitry Andric }
5200b57cec5SDimitry Andric
setCodeModel(CodeModel::Model CM)5215f757f3fSDimitry Andric void GlobalVariable::setCodeModel(CodeModel::Model CM) {
5225f757f3fSDimitry Andric unsigned CodeModelData = static_cast<unsigned>(CM) + 1;
5235f757f3fSDimitry Andric unsigned OldData = getGlobalValueSubClassData();
5245f757f3fSDimitry Andric unsigned NewData = (OldData & ~(CodeModelMask << CodeModelShift)) |
5255f757f3fSDimitry Andric (CodeModelData << CodeModelShift);
5265f757f3fSDimitry Andric setGlobalValueSubClassData(NewData);
5275f757f3fSDimitry Andric assert(getCodeModel() == CM && "Code model representation error!");
5285f757f3fSDimitry Andric }
5295f757f3fSDimitry Andric
5300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5310b57cec5SDimitry Andric // GlobalAlias Implementation
5320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5330b57cec5SDimitry Andric
GlobalAlias(Type * Ty,unsigned AddressSpace,LinkageTypes Link,const Twine & Name,Constant * Aliasee,Module * ParentModule)5340b57cec5SDimitry Andric GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
5350b57cec5SDimitry Andric const Twine &Name, Constant *Aliasee,
5360b57cec5SDimitry Andric Module *ParentModule)
537349cc55cSDimitry Andric : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name,
538349cc55cSDimitry Andric AddressSpace) {
539349cc55cSDimitry Andric setAliasee(Aliasee);
5400b57cec5SDimitry Andric if (ParentModule)
54106c3fb27SDimitry Andric ParentModule->insertAlias(this);
5420b57cec5SDimitry Andric }
5430b57cec5SDimitry Andric
create(Type * Ty,unsigned AddressSpace,LinkageTypes Link,const Twine & Name,Constant * Aliasee,Module * ParentModule)5440b57cec5SDimitry Andric GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
5450b57cec5SDimitry Andric LinkageTypes Link, const Twine &Name,
5460b57cec5SDimitry Andric Constant *Aliasee, Module *ParentModule) {
5470b57cec5SDimitry Andric return new GlobalAlias(Ty, AddressSpace, Link, Name, Aliasee, ParentModule);
5480b57cec5SDimitry Andric }
5490b57cec5SDimitry Andric
create(Type * Ty,unsigned AddressSpace,LinkageTypes Linkage,const Twine & Name,Module * Parent)5500b57cec5SDimitry Andric GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
5510b57cec5SDimitry Andric LinkageTypes Linkage, const Twine &Name,
5520b57cec5SDimitry Andric Module *Parent) {
5530b57cec5SDimitry Andric return create(Ty, AddressSpace, Linkage, Name, nullptr, Parent);
5540b57cec5SDimitry Andric }
5550b57cec5SDimitry Andric
create(Type * Ty,unsigned AddressSpace,LinkageTypes Linkage,const Twine & Name,GlobalValue * Aliasee)5560b57cec5SDimitry Andric GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
5570b57cec5SDimitry Andric LinkageTypes Linkage, const Twine &Name,
5580b57cec5SDimitry Andric GlobalValue *Aliasee) {
5590b57cec5SDimitry Andric return create(Ty, AddressSpace, Linkage, Name, Aliasee, Aliasee->getParent());
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric
create(LinkageTypes Link,const Twine & Name,GlobalValue * Aliasee)5620b57cec5SDimitry Andric GlobalAlias *GlobalAlias::create(LinkageTypes Link, const Twine &Name,
5630b57cec5SDimitry Andric GlobalValue *Aliasee) {
564fe6060f1SDimitry Andric return create(Aliasee->getValueType(), Aliasee->getAddressSpace(), Link, Name,
5650b57cec5SDimitry Andric Aliasee);
5660b57cec5SDimitry Andric }
5670b57cec5SDimitry Andric
create(const Twine & Name,GlobalValue * Aliasee)5680b57cec5SDimitry Andric GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalValue *Aliasee) {
5690b57cec5SDimitry Andric return create(Aliasee->getLinkage(), Name, Aliasee);
5700b57cec5SDimitry Andric }
5710b57cec5SDimitry Andric
removeFromParent()57206c3fb27SDimitry Andric void GlobalAlias::removeFromParent() { getParent()->removeAlias(this); }
5730b57cec5SDimitry Andric
eraseFromParent()57406c3fb27SDimitry Andric void GlobalAlias::eraseFromParent() { getParent()->eraseAlias(this); }
5750b57cec5SDimitry Andric
setAliasee(Constant * Aliasee)5760b57cec5SDimitry Andric void GlobalAlias::setAliasee(Constant *Aliasee) {
5770b57cec5SDimitry Andric assert((!Aliasee || Aliasee->getType() == getType()) &&
5780b57cec5SDimitry Andric "Alias and aliasee types should match!");
579349cc55cSDimitry Andric Op<0>().set(Aliasee);
580349cc55cSDimitry Andric }
581349cc55cSDimitry Andric
getAliaseeObject() const582349cc55cSDimitry Andric const GlobalObject *GlobalAlias::getAliaseeObject() const {
583349cc55cSDimitry Andric DenseSet<const GlobalAlias *> Aliases;
584fcaf7f86SDimitry Andric return findBaseObject(getOperand(0), Aliases, [](const GlobalValue &) {});
5850b57cec5SDimitry Andric }
5860b57cec5SDimitry Andric
5870b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5880b57cec5SDimitry Andric // GlobalIFunc Implementation
5890b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5900b57cec5SDimitry Andric
GlobalIFunc(Type * Ty,unsigned AddressSpace,LinkageTypes Link,const Twine & Name,Constant * Resolver,Module * ParentModule)5910b57cec5SDimitry Andric GlobalIFunc::GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
5920b57cec5SDimitry Andric const Twine &Name, Constant *Resolver,
5930b57cec5SDimitry Andric Module *ParentModule)
594349cc55cSDimitry Andric : GlobalObject(Ty, Value::GlobalIFuncVal, &Op<0>(), 1, Link, Name,
595349cc55cSDimitry Andric AddressSpace) {
596349cc55cSDimitry Andric setResolver(Resolver);
5970b57cec5SDimitry Andric if (ParentModule)
59806c3fb27SDimitry Andric ParentModule->insertIFunc(this);
5990b57cec5SDimitry Andric }
6000b57cec5SDimitry Andric
create(Type * Ty,unsigned AddressSpace,LinkageTypes Link,const Twine & Name,Constant * Resolver,Module * ParentModule)6010b57cec5SDimitry Andric GlobalIFunc *GlobalIFunc::create(Type *Ty, unsigned AddressSpace,
6020b57cec5SDimitry Andric LinkageTypes Link, const Twine &Name,
6030b57cec5SDimitry Andric Constant *Resolver, Module *ParentModule) {
6040b57cec5SDimitry Andric return new GlobalIFunc(Ty, AddressSpace, Link, Name, Resolver, ParentModule);
6050b57cec5SDimitry Andric }
6060b57cec5SDimitry Andric
removeFromParent()60706c3fb27SDimitry Andric void GlobalIFunc::removeFromParent() { getParent()->removeIFunc(this); }
6080b57cec5SDimitry Andric
eraseFromParent()60906c3fb27SDimitry Andric void GlobalIFunc::eraseFromParent() { getParent()->eraseIFunc(this); }
610349cc55cSDimitry Andric
getResolverFunction() const611349cc55cSDimitry Andric const Function *GlobalIFunc::getResolverFunction() const {
612bdd1243dSDimitry Andric return dyn_cast<Function>(getResolver()->stripPointerCastsAndAliases());
613fcaf7f86SDimitry Andric }
614fcaf7f86SDimitry Andric
applyAlongResolverPath(function_ref<void (const GlobalValue &)> Op) const615fcaf7f86SDimitry Andric void GlobalIFunc::applyAlongResolverPath(
616fcaf7f86SDimitry Andric function_ref<void(const GlobalValue &)> Op) const {
617fcaf7f86SDimitry Andric DenseSet<const GlobalAlias *> Aliases;
618fcaf7f86SDimitry Andric findBaseObject(getResolver(), Aliases, Op);
619349cc55cSDimitry Andric }
620