1249259Sdim//===-- Globals.cpp - Implement the GlobalValue & GlobalVariable class ----===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file implements the GlobalValue & GlobalVariable classes for the IR 11249259Sdim// library. 12249259Sdim// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim 15249259Sdim#include "llvm/IR/GlobalValue.h" 16249259Sdim#include "llvm/ADT/SmallPtrSet.h" 17249259Sdim#include "llvm/IR/Constants.h" 18249259Sdim#include "llvm/IR/DerivedTypes.h" 19249259Sdim#include "llvm/IR/GlobalAlias.h" 20249259Sdim#include "llvm/IR/GlobalVariable.h" 21249259Sdim#include "llvm/IR/Module.h" 22249259Sdim#include "llvm/Support/ErrorHandling.h" 23249259Sdim#include "llvm/Support/LeakDetector.h" 24249259Sdimusing namespace llvm; 25249259Sdim 26249259Sdim//===----------------------------------------------------------------------===// 27249259Sdim// GlobalValue Class 28249259Sdim//===----------------------------------------------------------------------===// 29249259Sdim 30249259Sdimbool GlobalValue::isMaterializable() const { 31249259Sdim return getParent() && getParent()->isMaterializable(this); 32249259Sdim} 33249259Sdimbool GlobalValue::isDematerializable() const { 34249259Sdim return getParent() && getParent()->isDematerializable(this); 35249259Sdim} 36249259Sdimbool GlobalValue::Materialize(std::string *ErrInfo) { 37249259Sdim return getParent()->Materialize(this, ErrInfo); 38249259Sdim} 39249259Sdimvoid GlobalValue::Dematerialize() { 40249259Sdim getParent()->Dematerialize(this); 41249259Sdim} 42249259Sdim 43249259Sdim/// Override destroyConstant to make sure it doesn't get called on 44249259Sdim/// GlobalValue's because they shouldn't be treated like other constants. 45249259Sdimvoid GlobalValue::destroyConstant() { 46249259Sdim llvm_unreachable("You can't GV->destroyConstant()!"); 47249259Sdim} 48249259Sdim 49249259Sdim/// copyAttributesFrom - copy all additional attributes (those not needed to 50249259Sdim/// create a GlobalValue) from the GlobalValue Src to this one. 51249259Sdimvoid GlobalValue::copyAttributesFrom(const GlobalValue *Src) { 52249259Sdim setAlignment(Src->getAlignment()); 53249259Sdim setSection(Src->getSection()); 54249259Sdim setVisibility(Src->getVisibility()); 55249259Sdim setUnnamedAddr(Src->hasUnnamedAddr()); 56249259Sdim} 57249259Sdim 58249259Sdimvoid GlobalValue::setAlignment(unsigned Align) { 59249259Sdim assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); 60249259Sdim assert(Align <= MaximumAlignment && 61249259Sdim "Alignment is greater than MaximumAlignment!"); 62249259Sdim Alignment = Log2_32(Align) + 1; 63249259Sdim assert(getAlignment() == Align && "Alignment representation error!"); 64249259Sdim} 65249259Sdim 66249259Sdimbool GlobalValue::isDeclaration() const { 67249259Sdim // Globals are definitions if they have an initializer. 68249259Sdim if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this)) 69249259Sdim return GV->getNumOperands() == 0; 70249259Sdim 71249259Sdim // Functions are definitions if they have a body. 72249259Sdim if (const Function *F = dyn_cast<Function>(this)) 73249259Sdim return F->empty(); 74249259Sdim 75249259Sdim // Aliases are always definitions. 76249259Sdim assert(isa<GlobalAlias>(this)); 77249259Sdim return false; 78249259Sdim} 79249259Sdim 80249259Sdim//===----------------------------------------------------------------------===// 81249259Sdim// GlobalVariable Implementation 82249259Sdim//===----------------------------------------------------------------------===// 83249259Sdim 84249259SdimGlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link, 85249259Sdim Constant *InitVal, 86249259Sdim const Twine &Name, ThreadLocalMode TLMode, 87249259Sdim unsigned AddressSpace, 88249259Sdim bool isExternallyInitialized) 89249259Sdim : GlobalValue(PointerType::get(Ty, AddressSpace), 90249259Sdim Value::GlobalVariableVal, 91249259Sdim OperandTraits<GlobalVariable>::op_begin(this), 92249259Sdim InitVal != 0, Link, Name), 93249259Sdim isConstantGlobal(constant), threadLocalMode(TLMode), 94249259Sdim isExternallyInitializedConstant(isExternallyInitialized) { 95249259Sdim if (InitVal) { 96249259Sdim assert(InitVal->getType() == Ty && 97249259Sdim "Initializer should be the same type as the GlobalVariable!"); 98249259Sdim Op<0>() = InitVal; 99249259Sdim } 100249259Sdim 101249259Sdim LeakDetector::addGarbageObject(this); 102249259Sdim} 103249259Sdim 104249259SdimGlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant, 105249259Sdim LinkageTypes Link, Constant *InitVal, 106249259Sdim const Twine &Name, 107249259Sdim GlobalVariable *Before, ThreadLocalMode TLMode, 108249259Sdim unsigned AddressSpace, 109249259Sdim bool isExternallyInitialized) 110249259Sdim : GlobalValue(PointerType::get(Ty, AddressSpace), 111249259Sdim Value::GlobalVariableVal, 112249259Sdim OperandTraits<GlobalVariable>::op_begin(this), 113249259Sdim InitVal != 0, Link, Name), 114249259Sdim isConstantGlobal(constant), threadLocalMode(TLMode), 115249259Sdim isExternallyInitializedConstant(isExternallyInitialized) { 116249259Sdim if (InitVal) { 117249259Sdim assert(InitVal->getType() == Ty && 118249259Sdim "Initializer should be the same type as the GlobalVariable!"); 119249259Sdim Op<0>() = InitVal; 120249259Sdim } 121249259Sdim 122249259Sdim LeakDetector::addGarbageObject(this); 123249259Sdim 124249259Sdim if (Before) 125249259Sdim Before->getParent()->getGlobalList().insert(Before, this); 126249259Sdim else 127249259Sdim M.getGlobalList().push_back(this); 128249259Sdim} 129249259Sdim 130249259Sdimvoid GlobalVariable::setParent(Module *parent) { 131249259Sdim if (getParent()) 132249259Sdim LeakDetector::addGarbageObject(this); 133249259Sdim Parent = parent; 134249259Sdim if (getParent()) 135249259Sdim LeakDetector::removeGarbageObject(this); 136249259Sdim} 137249259Sdim 138249259Sdimvoid GlobalVariable::removeFromParent() { 139249259Sdim getParent()->getGlobalList().remove(this); 140249259Sdim} 141249259Sdim 142249259Sdimvoid GlobalVariable::eraseFromParent() { 143249259Sdim getParent()->getGlobalList().erase(this); 144249259Sdim} 145249259Sdim 146249259Sdimvoid GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To, 147249259Sdim Use *U) { 148249259Sdim // If you call this, then you better know this GVar has a constant 149249259Sdim // initializer worth replacing. Enforce that here. 150249259Sdim assert(getNumOperands() == 1 && 151249259Sdim "Attempt to replace uses of Constants on a GVar with no initializer"); 152249259Sdim 153249259Sdim // And, since you know it has an initializer, the From value better be 154249259Sdim // the initializer :) 155249259Sdim assert(getOperand(0) == From && 156249259Sdim "Attempt to replace wrong constant initializer in GVar"); 157249259Sdim 158249259Sdim // And, you better have a constant for the replacement value 159249259Sdim assert(isa<Constant>(To) && 160249259Sdim "Attempt to replace GVar initializer with non-constant"); 161249259Sdim 162249259Sdim // Okay, preconditions out of the way, replace the constant initializer. 163249259Sdim this->setOperand(0, cast<Constant>(To)); 164249259Sdim} 165249259Sdim 166249259Sdimvoid GlobalVariable::setInitializer(Constant *InitVal) { 167249259Sdim if (InitVal == 0) { 168249259Sdim if (hasInitializer()) { 169249259Sdim Op<0>().set(0); 170249259Sdim NumOperands = 0; 171249259Sdim } 172249259Sdim } else { 173249259Sdim assert(InitVal->getType() == getType()->getElementType() && 174249259Sdim "Initializer type must match GlobalVariable type"); 175249259Sdim if (!hasInitializer()) 176249259Sdim NumOperands = 1; 177249259Sdim Op<0>().set(InitVal); 178249259Sdim } 179249259Sdim} 180249259Sdim 181249259Sdim/// copyAttributesFrom - copy all additional attributes (those not needed to 182249259Sdim/// create a GlobalVariable) from the GlobalVariable Src to this one. 183249259Sdimvoid GlobalVariable::copyAttributesFrom(const GlobalValue *Src) { 184249259Sdim assert(isa<GlobalVariable>(Src) && "Expected a GlobalVariable!"); 185249259Sdim GlobalValue::copyAttributesFrom(Src); 186249259Sdim const GlobalVariable *SrcVar = cast<GlobalVariable>(Src); 187249259Sdim setThreadLocal(SrcVar->isThreadLocal()); 188249259Sdim} 189249259Sdim 190249259Sdim 191249259Sdim//===----------------------------------------------------------------------===// 192249259Sdim// GlobalAlias Implementation 193249259Sdim//===----------------------------------------------------------------------===// 194249259Sdim 195249259SdimGlobalAlias::GlobalAlias(Type *Ty, LinkageTypes Link, 196249259Sdim const Twine &Name, Constant* aliasee, 197249259Sdim Module *ParentModule) 198249259Sdim : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) { 199249259Sdim LeakDetector::addGarbageObject(this); 200249259Sdim 201249259Sdim if (aliasee) 202249259Sdim assert(aliasee->getType() == Ty && "Alias and aliasee types should match!"); 203249259Sdim Op<0>() = aliasee; 204249259Sdim 205249259Sdim if (ParentModule) 206249259Sdim ParentModule->getAliasList().push_back(this); 207249259Sdim} 208249259Sdim 209249259Sdimvoid GlobalAlias::setParent(Module *parent) { 210249259Sdim if (getParent()) 211249259Sdim LeakDetector::addGarbageObject(this); 212249259Sdim Parent = parent; 213249259Sdim if (getParent()) 214249259Sdim LeakDetector::removeGarbageObject(this); 215249259Sdim} 216249259Sdim 217249259Sdimvoid GlobalAlias::removeFromParent() { 218249259Sdim getParent()->getAliasList().remove(this); 219249259Sdim} 220249259Sdim 221249259Sdimvoid GlobalAlias::eraseFromParent() { 222249259Sdim getParent()->getAliasList().erase(this); 223249259Sdim} 224249259Sdim 225249259Sdimvoid GlobalAlias::setAliasee(Constant *Aliasee) { 226249259Sdim assert((!Aliasee || Aliasee->getType() == getType()) && 227249259Sdim "Alias and aliasee types should match!"); 228249259Sdim 229249259Sdim setOperand(0, Aliasee); 230249259Sdim} 231249259Sdim 232263508SdimGlobalValue *GlobalAlias::getAliasedGlobal() { 233263508Sdim Constant *C = getAliasee(); 234249259Sdim if (C == 0) return 0; 235249259Sdim 236263508Sdim if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) 237249259Sdim return GV; 238249259Sdim 239263508Sdim ConstantExpr *CE = cast<ConstantExpr>(C); 240249259Sdim assert((CE->getOpcode() == Instruction::BitCast || 241249259Sdim CE->getOpcode() == Instruction::GetElementPtr) && 242249259Sdim "Unsupported aliasee"); 243249259Sdim 244249259Sdim return cast<GlobalValue>(CE->getOperand(0)); 245249259Sdim} 246249259Sdim 247263508SdimGlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) { 248263508Sdim SmallPtrSet<GlobalValue*, 3> Visited; 249249259Sdim 250249259Sdim // Check if we need to stop early. 251249259Sdim if (stopOnWeak && mayBeOverridden()) 252249259Sdim return this; 253249259Sdim 254263508Sdim GlobalValue *GV = getAliasedGlobal(); 255249259Sdim Visited.insert(GV); 256249259Sdim 257249259Sdim // Iterate over aliasing chain, stopping on weak alias if necessary. 258263508Sdim while (GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) { 259249259Sdim if (stopOnWeak && GA->mayBeOverridden()) 260249259Sdim break; 261249259Sdim 262249259Sdim GV = GA->getAliasedGlobal(); 263249259Sdim 264249259Sdim if (!Visited.insert(GV)) 265249259Sdim return 0; 266249259Sdim } 267249259Sdim 268249259Sdim return GV; 269249259Sdim} 270