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/ADT/SmallPtrSet.h" 160b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 170b57cec5SDimitry Andric #include "llvm/IR/ConstantRange.h" 180b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 190b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 200b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h" 210b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 220b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 230b57cec5SDimitry Andric #include "llvm/IR/Module.h" 240b57cec5SDimitry Andric #include "llvm/IR/Operator.h" 250b57cec5SDimitry Andric #include "llvm/Support/Error.h" 260b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 270b57cec5SDimitry Andric using namespace llvm; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 300b57cec5SDimitry Andric // GlobalValue Class 310b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric // GlobalValue should be a Constant, plus a type, a module, some flags, and an 340b57cec5SDimitry Andric // intrinsic ID. Add an assert to prevent people from accidentally growing 350b57cec5SDimitry Andric // GlobalValue while adding flags. 360b57cec5SDimitry Andric static_assert(sizeof(GlobalValue) == 370b57cec5SDimitry Andric sizeof(Constant) + 2 * sizeof(void *) + 2 * sizeof(unsigned), 380b57cec5SDimitry Andric "unexpected GlobalValue size growth"); 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric // GlobalObject adds a comdat. 410b57cec5SDimitry Andric static_assert(sizeof(GlobalObject) == sizeof(GlobalValue) + sizeof(void *), 420b57cec5SDimitry Andric "unexpected GlobalObject size growth"); 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric bool GlobalValue::isMaterializable() const { 450b57cec5SDimitry Andric if (const Function *F = dyn_cast<Function>(this)) 460b57cec5SDimitry Andric return F->isMaterializable(); 470b57cec5SDimitry Andric return false; 480b57cec5SDimitry Andric } 490b57cec5SDimitry Andric Error GlobalValue::materialize() { 500b57cec5SDimitry Andric return getParent()->materialize(this); 510b57cec5SDimitry Andric } 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric /// Override destroyConstantImpl to make sure it doesn't get called on 540b57cec5SDimitry Andric /// GlobalValue's because they shouldn't be treated like other constants. 550b57cec5SDimitry Andric void GlobalValue::destroyConstantImpl() { 560b57cec5SDimitry Andric llvm_unreachable("You can't GV->destroyConstantImpl()!"); 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric Value *GlobalValue::handleOperandChangeImpl(Value *From, Value *To) { 600b57cec5SDimitry Andric llvm_unreachable("Unsupported class for handleOperandChange()!"); 610b57cec5SDimitry Andric } 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric /// copyAttributesFrom - copy all additional attributes (those not needed to 640b57cec5SDimitry Andric /// create a GlobalValue) from the GlobalValue Src to this one. 650b57cec5SDimitry Andric void GlobalValue::copyAttributesFrom(const GlobalValue *Src) { 660b57cec5SDimitry Andric setVisibility(Src->getVisibility()); 670b57cec5SDimitry Andric setUnnamedAddr(Src->getUnnamedAddr()); 680b57cec5SDimitry Andric setDLLStorageClass(Src->getDLLStorageClass()); 690b57cec5SDimitry Andric setDSOLocal(Src->isDSOLocal()); 700b57cec5SDimitry Andric setPartition(Src->getPartition()); 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric void GlobalValue::removeFromParent() { 740b57cec5SDimitry Andric switch (getValueID()) { 750b57cec5SDimitry Andric #define HANDLE_GLOBAL_VALUE(NAME) \ 760b57cec5SDimitry Andric case Value::NAME##Val: \ 770b57cec5SDimitry Andric return static_cast<NAME *>(this)->removeFromParent(); 780b57cec5SDimitry Andric #include "llvm/IR/Value.def" 790b57cec5SDimitry Andric default: 800b57cec5SDimitry Andric break; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric llvm_unreachable("not a global"); 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric void GlobalValue::eraseFromParent() { 860b57cec5SDimitry Andric switch (getValueID()) { 870b57cec5SDimitry Andric #define HANDLE_GLOBAL_VALUE(NAME) \ 880b57cec5SDimitry Andric case Value::NAME##Val: \ 890b57cec5SDimitry Andric return static_cast<NAME *>(this)->eraseFromParent(); 900b57cec5SDimitry Andric #include "llvm/IR/Value.def" 910b57cec5SDimitry Andric default: 920b57cec5SDimitry Andric break; 930b57cec5SDimitry Andric } 940b57cec5SDimitry Andric llvm_unreachable("not a global"); 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric unsigned GlobalValue::getAlignment() const { 980b57cec5SDimitry Andric if (auto *GA = dyn_cast<GlobalAlias>(this)) { 990b57cec5SDimitry Andric // In general we cannot compute this at the IR level, but we try. 1000b57cec5SDimitry Andric if (const GlobalObject *GO = GA->getBaseObject()) 1010b57cec5SDimitry Andric return GO->getAlignment(); 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric // FIXME: we should also be able to handle: 1040b57cec5SDimitry Andric // Alias = Global + Offset 1050b57cec5SDimitry Andric // Alias = Absolute 1060b57cec5SDimitry Andric return 0; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric return cast<GlobalObject>(this)->getAlignment(); 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric unsigned GlobalValue::getAddressSpace() const { 1120b57cec5SDimitry Andric PointerType *PtrTy = getType(); 1130b57cec5SDimitry Andric return PtrTy->getAddressSpace(); 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric void GlobalObject::setAlignment(unsigned Align) { 117*8bcb0991SDimitry Andric setAlignment(MaybeAlign(Align)); 118*8bcb0991SDimitry Andric } 119*8bcb0991SDimitry Andric 120*8bcb0991SDimitry Andric void GlobalObject::setAlignment(MaybeAlign Align) { 121*8bcb0991SDimitry Andric assert((!Align || Align <= MaximumAlignment) && 1220b57cec5SDimitry Andric "Alignment is greater than MaximumAlignment!"); 123*8bcb0991SDimitry Andric unsigned AlignmentData = encode(Align); 1240b57cec5SDimitry Andric unsigned OldData = getGlobalValueSubClassData(); 1250b57cec5SDimitry Andric setGlobalValueSubClassData((OldData & ~AlignmentMask) | AlignmentData); 126*8bcb0991SDimitry Andric assert(MaybeAlign(getAlignment()) == Align && 127*8bcb0991SDimitry Andric "Alignment representation error!"); 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric void GlobalObject::copyAttributesFrom(const GlobalObject *Src) { 1310b57cec5SDimitry Andric GlobalValue::copyAttributesFrom(Src); 132*8bcb0991SDimitry Andric setAlignment(MaybeAlign(Src->getAlignment())); 1330b57cec5SDimitry Andric setSection(Src->getSection()); 1340b57cec5SDimitry Andric } 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric std::string GlobalValue::getGlobalIdentifier(StringRef Name, 1370b57cec5SDimitry Andric GlobalValue::LinkageTypes Linkage, 1380b57cec5SDimitry Andric StringRef FileName) { 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric // Value names may be prefixed with a binary '1' to indicate 1410b57cec5SDimitry Andric // that the backend should not modify the symbols due to any platform 1420b57cec5SDimitry Andric // naming convention. Do not include that '1' in the PGO profile name. 1430b57cec5SDimitry Andric if (Name[0] == '\1') 1440b57cec5SDimitry Andric Name = Name.substr(1); 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric std::string NewName = Name; 1470b57cec5SDimitry Andric if (llvm::GlobalValue::isLocalLinkage(Linkage)) { 1480b57cec5SDimitry Andric // For local symbols, prepend the main file name to distinguish them. 1490b57cec5SDimitry Andric // Do not include the full path in the file name since there's no guarantee 1500b57cec5SDimitry Andric // that it will stay the same, e.g., if the files are checked out from 1510b57cec5SDimitry Andric // version control in different locations. 1520b57cec5SDimitry Andric if (FileName.empty()) 1530b57cec5SDimitry Andric NewName = NewName.insert(0, "<unknown>:"); 1540b57cec5SDimitry Andric else 1550b57cec5SDimitry Andric NewName = NewName.insert(0, FileName.str() + ":"); 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric return NewName; 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric std::string GlobalValue::getGlobalIdentifier() const { 1610b57cec5SDimitry Andric return getGlobalIdentifier(getName(), getLinkage(), 1620b57cec5SDimitry Andric getParent()->getSourceFileName()); 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric StringRef GlobalValue::getSection() const { 1660b57cec5SDimitry Andric if (auto *GA = dyn_cast<GlobalAlias>(this)) { 1670b57cec5SDimitry Andric // In general we cannot compute this at the IR level, but we try. 1680b57cec5SDimitry Andric if (const GlobalObject *GO = GA->getBaseObject()) 1690b57cec5SDimitry Andric return GO->getSection(); 1700b57cec5SDimitry Andric return ""; 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric return cast<GlobalObject>(this)->getSection(); 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric const Comdat *GlobalValue::getComdat() const { 1760b57cec5SDimitry Andric if (auto *GA = dyn_cast<GlobalAlias>(this)) { 1770b57cec5SDimitry Andric // In general we cannot compute this at the IR level, but we try. 1780b57cec5SDimitry Andric if (const GlobalObject *GO = GA->getBaseObject()) 1790b57cec5SDimitry Andric return const_cast<GlobalObject *>(GO)->getComdat(); 1800b57cec5SDimitry Andric return nullptr; 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric // ifunc and its resolver are separate things so don't use resolver comdat. 1830b57cec5SDimitry Andric if (isa<GlobalIFunc>(this)) 1840b57cec5SDimitry Andric return nullptr; 1850b57cec5SDimitry Andric return cast<GlobalObject>(this)->getComdat(); 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric StringRef GlobalValue::getPartition() const { 1890b57cec5SDimitry Andric if (!hasPartition()) 1900b57cec5SDimitry Andric return ""; 1910b57cec5SDimitry Andric return getContext().pImpl->GlobalValuePartitions[this]; 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric void GlobalValue::setPartition(StringRef S) { 1950b57cec5SDimitry Andric // Do nothing if we're clearing the partition and it is already empty. 1960b57cec5SDimitry Andric if (!hasPartition() && S.empty()) 1970b57cec5SDimitry Andric return; 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric // Get or create a stable partition name string and put it in the table in the 2000b57cec5SDimitry Andric // context. 2010b57cec5SDimitry Andric if (!S.empty()) 2020b57cec5SDimitry Andric S = getContext().pImpl->Saver.save(S); 2030b57cec5SDimitry Andric getContext().pImpl->GlobalValuePartitions[this] = S; 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric // Update the HasPartition field. Setting the partition to the empty string 2060b57cec5SDimitry Andric // means this global no longer has a partition. 2070b57cec5SDimitry Andric HasPartition = !S.empty(); 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric StringRef GlobalObject::getSectionImpl() const { 2110b57cec5SDimitry Andric assert(hasSection()); 2120b57cec5SDimitry Andric return getContext().pImpl->GlobalObjectSections[this]; 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric void GlobalObject::setSection(StringRef S) { 2160b57cec5SDimitry Andric // Do nothing if we're clearing the section and it is already empty. 2170b57cec5SDimitry Andric if (!hasSection() && S.empty()) 2180b57cec5SDimitry Andric return; 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric // Get or create a stable section name string and put it in the table in the 2210b57cec5SDimitry Andric // context. 2220b57cec5SDimitry Andric if (!S.empty()) 2230b57cec5SDimitry Andric S = getContext().pImpl->Saver.save(S); 2240b57cec5SDimitry Andric getContext().pImpl->GlobalObjectSections[this] = S; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric // Update the HasSectionHashEntryBit. Setting the section to the empty string 2270b57cec5SDimitry Andric // means this global no longer has a section. 2280b57cec5SDimitry Andric setGlobalObjectFlag(HasSectionHashEntryBit, !S.empty()); 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric bool GlobalValue::isDeclaration() const { 2320b57cec5SDimitry Andric // Globals are definitions if they have an initializer. 2330b57cec5SDimitry Andric if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this)) 2340b57cec5SDimitry Andric return GV->getNumOperands() == 0; 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric // Functions are definitions if they have a body. 2370b57cec5SDimitry Andric if (const Function *F = dyn_cast<Function>(this)) 2380b57cec5SDimitry Andric return F->empty() && !F->isMaterializable(); 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric // Aliases and ifuncs are always definitions. 2410b57cec5SDimitry Andric assert(isa<GlobalIndirectSymbol>(this)); 2420b57cec5SDimitry Andric return false; 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric bool GlobalValue::canIncreaseAlignment() const { 2460b57cec5SDimitry Andric // Firstly, can only increase the alignment of a global if it 2470b57cec5SDimitry Andric // is a strong definition. 2480b57cec5SDimitry Andric if (!isStrongDefinitionForLinker()) 2490b57cec5SDimitry Andric return false; 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric // It also has to either not have a section defined, or, not have 2520b57cec5SDimitry Andric // alignment specified. (If it is assigned a section, the global 2530b57cec5SDimitry Andric // could be densely packed with other objects in the section, and 2540b57cec5SDimitry Andric // increasing the alignment could cause padding issues.) 2550b57cec5SDimitry Andric if (hasSection() && getAlignment() > 0) 2560b57cec5SDimitry Andric return false; 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric // On ELF platforms, we're further restricted in that we can't 2590b57cec5SDimitry Andric // increase the alignment of any variable which might be emitted 2600b57cec5SDimitry Andric // into a shared library, and which is exported. If the main 2610b57cec5SDimitry Andric // executable accesses a variable found in a shared-lib, the main 2620b57cec5SDimitry Andric // exe actually allocates memory for and exports the symbol ITSELF, 2630b57cec5SDimitry Andric // overriding the symbol found in the library. That is, at link 2640b57cec5SDimitry Andric // time, the observed alignment of the variable is copied into the 2650b57cec5SDimitry Andric // executable binary. (A COPY relocation is also generated, to copy 2660b57cec5SDimitry Andric // the initial data from the shadowed variable in the shared-lib 2670b57cec5SDimitry Andric // into the location in the main binary, before running code.) 2680b57cec5SDimitry Andric // 2690b57cec5SDimitry Andric // And thus, even though you might think you are defining the 2700b57cec5SDimitry Andric // global, and allocating the memory for the global in your object 2710b57cec5SDimitry Andric // file, and thus should be able to set the alignment arbitrarily, 2720b57cec5SDimitry Andric // that's not actually true. Doing so can cause an ABI breakage; an 2730b57cec5SDimitry Andric // executable might have already been built with the previous 2740b57cec5SDimitry Andric // alignment of the variable, and then assuming an increased 2750b57cec5SDimitry Andric // alignment will be incorrect. 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric // Conservatively assume ELF if there's no parent pointer. 2780b57cec5SDimitry Andric bool isELF = 2790b57cec5SDimitry Andric (!Parent || Triple(Parent->getTargetTriple()).isOSBinFormatELF()); 2800b57cec5SDimitry Andric if (isELF && !isDSOLocal()) 2810b57cec5SDimitry Andric return false; 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric return true; 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric const GlobalObject *GlobalValue::getBaseObject() const { 2870b57cec5SDimitry Andric if (auto *GO = dyn_cast<GlobalObject>(this)) 2880b57cec5SDimitry Andric return GO; 2890b57cec5SDimitry Andric if (auto *GA = dyn_cast<GlobalIndirectSymbol>(this)) 2900b57cec5SDimitry Andric return GA->getBaseObject(); 2910b57cec5SDimitry Andric return nullptr; 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric bool GlobalValue::isAbsoluteSymbolRef() const { 2950b57cec5SDimitry Andric auto *GO = dyn_cast<GlobalObject>(this); 2960b57cec5SDimitry Andric if (!GO) 2970b57cec5SDimitry Andric return false; 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric return GO->getMetadata(LLVMContext::MD_absolute_symbol); 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric Optional<ConstantRange> GlobalValue::getAbsoluteSymbolRange() const { 3030b57cec5SDimitry Andric auto *GO = dyn_cast<GlobalObject>(this); 3040b57cec5SDimitry Andric if (!GO) 3050b57cec5SDimitry Andric return None; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric MDNode *MD = GO->getMetadata(LLVMContext::MD_absolute_symbol); 3080b57cec5SDimitry Andric if (!MD) 3090b57cec5SDimitry Andric return None; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric return getConstantRangeFromMetadata(*MD); 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric bool GlobalValue::canBeOmittedFromSymbolTable() const { 3150b57cec5SDimitry Andric if (!hasLinkOnceODRLinkage()) 3160b57cec5SDimitry Andric return false; 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric // We assume that anyone who sets global unnamed_addr on a non-constant 3190b57cec5SDimitry Andric // knows what they're doing. 3200b57cec5SDimitry Andric if (hasGlobalUnnamedAddr()) 3210b57cec5SDimitry Andric return true; 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric // If it is a non constant variable, it needs to be uniqued across shared 3240b57cec5SDimitry Andric // objects. 3250b57cec5SDimitry Andric if (auto *Var = dyn_cast<GlobalVariable>(this)) 3260b57cec5SDimitry Andric if (!Var->isConstant()) 3270b57cec5SDimitry Andric return false; 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric return hasAtLeastLocalUnnamedAddr(); 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 3330b57cec5SDimitry Andric // GlobalVariable Implementation 3340b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link, 3370b57cec5SDimitry Andric Constant *InitVal, const Twine &Name, 3380b57cec5SDimitry Andric ThreadLocalMode TLMode, unsigned AddressSpace, 3390b57cec5SDimitry Andric bool isExternallyInitialized) 3400b57cec5SDimitry Andric : GlobalObject(Ty, Value::GlobalVariableVal, 3410b57cec5SDimitry Andric OperandTraits<GlobalVariable>::op_begin(this), 3420b57cec5SDimitry Andric InitVal != nullptr, Link, Name, AddressSpace), 3430b57cec5SDimitry Andric isConstantGlobal(constant), 3440b57cec5SDimitry Andric isExternallyInitializedConstant(isExternallyInitialized) { 3450b57cec5SDimitry Andric assert(!Ty->isFunctionTy() && PointerType::isValidElementType(Ty) && 3460b57cec5SDimitry Andric "invalid type for global variable"); 3470b57cec5SDimitry Andric setThreadLocalMode(TLMode); 3480b57cec5SDimitry Andric if (InitVal) { 3490b57cec5SDimitry Andric assert(InitVal->getType() == Ty && 3500b57cec5SDimitry Andric "Initializer should be the same type as the GlobalVariable!"); 3510b57cec5SDimitry Andric Op<0>() = InitVal; 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant, 3560b57cec5SDimitry Andric LinkageTypes Link, Constant *InitVal, 3570b57cec5SDimitry Andric const Twine &Name, GlobalVariable *Before, 3580b57cec5SDimitry Andric ThreadLocalMode TLMode, unsigned AddressSpace, 3590b57cec5SDimitry Andric bool isExternallyInitialized) 3600b57cec5SDimitry Andric : GlobalObject(Ty, Value::GlobalVariableVal, 3610b57cec5SDimitry Andric OperandTraits<GlobalVariable>::op_begin(this), 3620b57cec5SDimitry Andric InitVal != nullptr, Link, Name, AddressSpace), 3630b57cec5SDimitry Andric isConstantGlobal(constant), 3640b57cec5SDimitry Andric isExternallyInitializedConstant(isExternallyInitialized) { 3650b57cec5SDimitry Andric assert(!Ty->isFunctionTy() && PointerType::isValidElementType(Ty) && 3660b57cec5SDimitry Andric "invalid type for global variable"); 3670b57cec5SDimitry Andric setThreadLocalMode(TLMode); 3680b57cec5SDimitry Andric if (InitVal) { 3690b57cec5SDimitry Andric assert(InitVal->getType() == Ty && 3700b57cec5SDimitry Andric "Initializer should be the same type as the GlobalVariable!"); 3710b57cec5SDimitry Andric Op<0>() = InitVal; 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric if (Before) 3750b57cec5SDimitry Andric Before->getParent()->getGlobalList().insert(Before->getIterator(), this); 3760b57cec5SDimitry Andric else 3770b57cec5SDimitry Andric M.getGlobalList().push_back(this); 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric void GlobalVariable::removeFromParent() { 3810b57cec5SDimitry Andric getParent()->getGlobalList().remove(getIterator()); 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric void GlobalVariable::eraseFromParent() { 3850b57cec5SDimitry Andric getParent()->getGlobalList().erase(getIterator()); 3860b57cec5SDimitry Andric } 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric void GlobalVariable::setInitializer(Constant *InitVal) { 3890b57cec5SDimitry Andric if (!InitVal) { 3900b57cec5SDimitry Andric if (hasInitializer()) { 3910b57cec5SDimitry Andric // Note, the num operands is used to compute the offset of the operand, so 3920b57cec5SDimitry Andric // the order here matters. Clearing the operand then clearing the num 3930b57cec5SDimitry Andric // operands ensures we have the correct offset to the operand. 3940b57cec5SDimitry Andric Op<0>().set(nullptr); 3950b57cec5SDimitry Andric setGlobalVariableNumOperands(0); 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric } else { 3980b57cec5SDimitry Andric assert(InitVal->getType() == getValueType() && 3990b57cec5SDimitry Andric "Initializer type must match GlobalVariable type"); 4000b57cec5SDimitry Andric // Note, the num operands is used to compute the offset of the operand, so 4010b57cec5SDimitry Andric // the order here matters. We need to set num operands to 1 first so that 4020b57cec5SDimitry Andric // we get the correct offset to the first operand when we set it. 4030b57cec5SDimitry Andric if (!hasInitializer()) 4040b57cec5SDimitry Andric setGlobalVariableNumOperands(1); 4050b57cec5SDimitry Andric Op<0>().set(InitVal); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric /// Copy all additional attributes (those not needed to create a GlobalVariable) 4100b57cec5SDimitry Andric /// from the GlobalVariable Src to this one. 4110b57cec5SDimitry Andric void GlobalVariable::copyAttributesFrom(const GlobalVariable *Src) { 4120b57cec5SDimitry Andric GlobalObject::copyAttributesFrom(Src); 4130b57cec5SDimitry Andric setThreadLocalMode(Src->getThreadLocalMode()); 4140b57cec5SDimitry Andric setExternallyInitialized(Src->isExternallyInitialized()); 4150b57cec5SDimitry Andric setAttributes(Src->getAttributes()); 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric void GlobalVariable::dropAllReferences() { 4190b57cec5SDimitry Andric User::dropAllReferences(); 4200b57cec5SDimitry Andric clearMetadata(); 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4240b57cec5SDimitry Andric // GlobalIndirectSymbol Implementation 4250b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric GlobalIndirectSymbol::GlobalIndirectSymbol(Type *Ty, ValueTy VTy, 4280b57cec5SDimitry Andric unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, 4290b57cec5SDimitry Andric Constant *Symbol) 4300b57cec5SDimitry Andric : GlobalValue(Ty, VTy, &Op<0>(), 1, Linkage, Name, AddressSpace) { 4310b57cec5SDimitry Andric Op<0>() = Symbol; 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric 434*8bcb0991SDimitry Andric static const GlobalObject * 435*8bcb0991SDimitry Andric findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases) { 436*8bcb0991SDimitry Andric if (auto *GO = dyn_cast<GlobalObject>(C)) 437*8bcb0991SDimitry Andric return GO; 438*8bcb0991SDimitry Andric if (auto *GA = dyn_cast<GlobalAlias>(C)) 439*8bcb0991SDimitry Andric if (Aliases.insert(GA).second) 440*8bcb0991SDimitry Andric return findBaseObject(GA->getOperand(0), Aliases); 441*8bcb0991SDimitry Andric if (auto *CE = dyn_cast<ConstantExpr>(C)) { 442*8bcb0991SDimitry Andric switch (CE->getOpcode()) { 443*8bcb0991SDimitry Andric case Instruction::Add: { 444*8bcb0991SDimitry Andric auto *LHS = findBaseObject(CE->getOperand(0), Aliases); 445*8bcb0991SDimitry Andric auto *RHS = findBaseObject(CE->getOperand(1), Aliases); 446*8bcb0991SDimitry Andric if (LHS && RHS) 447*8bcb0991SDimitry Andric return nullptr; 448*8bcb0991SDimitry Andric return LHS ? LHS : RHS; 449*8bcb0991SDimitry Andric } 450*8bcb0991SDimitry Andric case Instruction::Sub: { 451*8bcb0991SDimitry Andric if (findBaseObject(CE->getOperand(1), Aliases)) 452*8bcb0991SDimitry Andric return nullptr; 453*8bcb0991SDimitry Andric return findBaseObject(CE->getOperand(0), Aliases); 454*8bcb0991SDimitry Andric } 455*8bcb0991SDimitry Andric case Instruction::IntToPtr: 456*8bcb0991SDimitry Andric case Instruction::PtrToInt: 457*8bcb0991SDimitry Andric case Instruction::BitCast: 458*8bcb0991SDimitry Andric case Instruction::GetElementPtr: 459*8bcb0991SDimitry Andric return findBaseObject(CE->getOperand(0), Aliases); 460*8bcb0991SDimitry Andric default: 461*8bcb0991SDimitry Andric break; 462*8bcb0991SDimitry Andric } 463*8bcb0991SDimitry Andric } 464*8bcb0991SDimitry Andric return nullptr; 465*8bcb0991SDimitry Andric } 466*8bcb0991SDimitry Andric 467*8bcb0991SDimitry Andric const GlobalObject *GlobalIndirectSymbol::getBaseObject() const { 468*8bcb0991SDimitry Andric DenseSet<const GlobalAlias *> Aliases; 469*8bcb0991SDimitry Andric return findBaseObject(getOperand(0), Aliases); 470*8bcb0991SDimitry Andric } 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4730b57cec5SDimitry Andric // GlobalAlias Implementation 4740b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link, 4770b57cec5SDimitry Andric const Twine &Name, Constant *Aliasee, 4780b57cec5SDimitry Andric Module *ParentModule) 4790b57cec5SDimitry Andric : GlobalIndirectSymbol(Ty, Value::GlobalAliasVal, AddressSpace, Link, Name, 4800b57cec5SDimitry Andric Aliasee) { 4810b57cec5SDimitry Andric if (ParentModule) 4820b57cec5SDimitry Andric ParentModule->getAliasList().push_back(this); 4830b57cec5SDimitry Andric } 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, 4860b57cec5SDimitry Andric LinkageTypes Link, const Twine &Name, 4870b57cec5SDimitry Andric Constant *Aliasee, Module *ParentModule) { 4880b57cec5SDimitry Andric return new GlobalAlias(Ty, AddressSpace, Link, Name, Aliasee, ParentModule); 4890b57cec5SDimitry Andric } 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, 4920b57cec5SDimitry Andric LinkageTypes Linkage, const Twine &Name, 4930b57cec5SDimitry Andric Module *Parent) { 4940b57cec5SDimitry Andric return create(Ty, AddressSpace, Linkage, Name, nullptr, Parent); 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, 4980b57cec5SDimitry Andric LinkageTypes Linkage, const Twine &Name, 4990b57cec5SDimitry Andric GlobalValue *Aliasee) { 5000b57cec5SDimitry Andric return create(Ty, AddressSpace, Linkage, Name, Aliasee, Aliasee->getParent()); 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric GlobalAlias *GlobalAlias::create(LinkageTypes Link, const Twine &Name, 5040b57cec5SDimitry Andric GlobalValue *Aliasee) { 5050b57cec5SDimitry Andric PointerType *PTy = Aliasee->getType(); 5060b57cec5SDimitry Andric return create(PTy->getElementType(), PTy->getAddressSpace(), Link, Name, 5070b57cec5SDimitry Andric Aliasee); 5080b57cec5SDimitry Andric } 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalValue *Aliasee) { 5110b57cec5SDimitry Andric return create(Aliasee->getLinkage(), Name, Aliasee); 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric void GlobalAlias::removeFromParent() { 5150b57cec5SDimitry Andric getParent()->getAliasList().remove(getIterator()); 5160b57cec5SDimitry Andric } 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric void GlobalAlias::eraseFromParent() { 5190b57cec5SDimitry Andric getParent()->getAliasList().erase(getIterator()); 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric void GlobalAlias::setAliasee(Constant *Aliasee) { 5230b57cec5SDimitry Andric assert((!Aliasee || Aliasee->getType() == getType()) && 5240b57cec5SDimitry Andric "Alias and aliasee types should match!"); 5250b57cec5SDimitry Andric setIndirectSymbol(Aliasee); 5260b57cec5SDimitry Andric } 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 5290b57cec5SDimitry Andric // GlobalIFunc Implementation 5300b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric GlobalIFunc::GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Link, 5330b57cec5SDimitry Andric const Twine &Name, Constant *Resolver, 5340b57cec5SDimitry Andric Module *ParentModule) 5350b57cec5SDimitry Andric : GlobalIndirectSymbol(Ty, Value::GlobalIFuncVal, AddressSpace, Link, Name, 5360b57cec5SDimitry Andric Resolver) { 5370b57cec5SDimitry Andric if (ParentModule) 5380b57cec5SDimitry Andric ParentModule->getIFuncList().push_back(this); 5390b57cec5SDimitry Andric } 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric GlobalIFunc *GlobalIFunc::create(Type *Ty, unsigned AddressSpace, 5420b57cec5SDimitry Andric LinkageTypes Link, const Twine &Name, 5430b57cec5SDimitry Andric Constant *Resolver, Module *ParentModule) { 5440b57cec5SDimitry Andric return new GlobalIFunc(Ty, AddressSpace, Link, Name, Resolver, ParentModule); 5450b57cec5SDimitry Andric } 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric void GlobalIFunc::removeFromParent() { 5480b57cec5SDimitry Andric getParent()->getIFuncList().remove(getIterator()); 5490b57cec5SDimitry Andric } 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric void GlobalIFunc::eraseFromParent() { 5520b57cec5SDimitry Andric getParent()->getIFuncList().erase(getIterator()); 5530b57cec5SDimitry Andric } 554