1//===-- Globals.cpp - Implement the GlobalValue & GlobalVariable class ----===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the GlobalValue & GlobalVariable classes for the VMCore
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/Constants.h"
16#include "llvm/GlobalVariable.h"
17#include "llvm/GlobalAlias.h"
18#include "llvm/DerivedTypes.h"
19#include "llvm/Module.h"
20#include "llvm/ADT/SmallPtrSet.h"
21#include "llvm/Support/ErrorHandling.h"
22#include "llvm/Support/LeakDetector.h"
23using namespace llvm;
24
25//===----------------------------------------------------------------------===//
26//                            GlobalValue Class
27//===----------------------------------------------------------------------===//
28
29bool GlobalValue::isMaterializable() const {
30  return getParent() && getParent()->isMaterializable(this);
31}
32bool GlobalValue::isDematerializable() const {
33  return getParent() && getParent()->isDematerializable(this);
34}
35bool GlobalValue::Materialize(std::string *ErrInfo) {
36  return getParent()->Materialize(this, ErrInfo);
37}
38void GlobalValue::Dematerialize() {
39  getParent()->Dematerialize(this);
40}
41
42/// Override destroyConstant to make sure it doesn't get called on
43/// GlobalValue's because they shouldn't be treated like other constants.
44void GlobalValue::destroyConstant() {
45  llvm_unreachable("You can't GV->destroyConstant()!");
46}
47
48/// copyAttributesFrom - copy all additional attributes (those not needed to
49/// create a GlobalValue) from the GlobalValue Src to this one.
50void GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
51  setAlignment(Src->getAlignment());
52  setSection(Src->getSection());
53  setVisibility(Src->getVisibility());
54  setUnnamedAddr(Src->hasUnnamedAddr());
55}
56
57void GlobalValue::setAlignment(unsigned Align) {
58  assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
59  assert(Align <= MaximumAlignment &&
60         "Alignment is greater than MaximumAlignment!");
61  Alignment = Log2_32(Align) + 1;
62  assert(getAlignment() == Align && "Alignment representation error!");
63}
64
65bool GlobalValue::isDeclaration() const {
66  // Globals are definitions if they have an initializer.
67  if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this))
68    return GV->getNumOperands() == 0;
69
70  // Functions are definitions if they have a body.
71  if (const Function *F = dyn_cast<Function>(this))
72    return F->empty();
73
74  // Aliases are always definitions.
75  assert(isa<GlobalAlias>(this));
76  return false;
77}
78
79//===----------------------------------------------------------------------===//
80// GlobalVariable Implementation
81//===----------------------------------------------------------------------===//
82
83GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
84                               Constant *InitVal, const Twine &Name,
85                               bool ThreadLocal, unsigned AddressSpace)
86  : GlobalValue(PointerType::get(Ty, AddressSpace),
87                Value::GlobalVariableVal,
88                OperandTraits<GlobalVariable>::op_begin(this),
89                InitVal != 0, Link, Name),
90    isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
91  if (InitVal) {
92    assert(InitVal->getType() == Ty &&
93           "Initializer should be the same type as the GlobalVariable!");
94    Op<0>() = InitVal;
95  }
96
97  LeakDetector::addGarbageObject(this);
98}
99
100GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
101                               LinkageTypes Link, Constant *InitVal,
102                               const Twine &Name,
103                               GlobalVariable *Before, bool ThreadLocal,
104                               unsigned AddressSpace)
105  : GlobalValue(PointerType::get(Ty, AddressSpace),
106                Value::GlobalVariableVal,
107                OperandTraits<GlobalVariable>::op_begin(this),
108                InitVal != 0, Link, Name),
109    isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
110  if (InitVal) {
111    assert(InitVal->getType() == Ty &&
112           "Initializer should be the same type as the GlobalVariable!");
113    Op<0>() = InitVal;
114  }
115
116  LeakDetector::addGarbageObject(this);
117
118  if (Before)
119    Before->getParent()->getGlobalList().insert(Before, this);
120  else
121    M.getGlobalList().push_back(this);
122}
123
124void GlobalVariable::setParent(Module *parent) {
125  if (getParent())
126    LeakDetector::addGarbageObject(this);
127  Parent = parent;
128  if (getParent())
129    LeakDetector::removeGarbageObject(this);
130}
131
132void GlobalVariable::removeFromParent() {
133  getParent()->getGlobalList().remove(this);
134}
135
136void GlobalVariable::eraseFromParent() {
137  getParent()->getGlobalList().erase(this);
138}
139
140void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
141                                                 Use *U) {
142  // If you call this, then you better know this GVar has a constant
143  // initializer worth replacing. Enforce that here.
144  assert(getNumOperands() == 1 &&
145         "Attempt to replace uses of Constants on a GVar with no initializer");
146
147  // And, since you know it has an initializer, the From value better be
148  // the initializer :)
149  assert(getOperand(0) == From &&
150         "Attempt to replace wrong constant initializer in GVar");
151
152  // And, you better have a constant for the replacement value
153  assert(isa<Constant>(To) &&
154         "Attempt to replace GVar initializer with non-constant");
155
156  // Okay, preconditions out of the way, replace the constant initializer.
157  this->setOperand(0, cast<Constant>(To));
158}
159
160void GlobalVariable::setInitializer(Constant *InitVal) {
161  if (InitVal == 0) {
162    if (hasInitializer()) {
163      Op<0>().set(0);
164      NumOperands = 0;
165    }
166  } else {
167    assert(InitVal->getType() == getType()->getElementType() &&
168           "Initializer type must match GlobalVariable type");
169    if (!hasInitializer())
170      NumOperands = 1;
171    Op<0>().set(InitVal);
172  }
173}
174
175/// copyAttributesFrom - copy all additional attributes (those not needed to
176/// create a GlobalVariable) from the GlobalVariable Src to this one.
177void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) {
178  assert(isa<GlobalVariable>(Src) && "Expected a GlobalVariable!");
179  GlobalValue::copyAttributesFrom(Src);
180  const GlobalVariable *SrcVar = cast<GlobalVariable>(Src);
181  setThreadLocal(SrcVar->isThreadLocal());
182}
183
184
185//===----------------------------------------------------------------------===//
186// GlobalAlias Implementation
187//===----------------------------------------------------------------------===//
188
189GlobalAlias::GlobalAlias(Type *Ty, LinkageTypes Link,
190                         const Twine &Name, Constant* aliasee,
191                         Module *ParentModule)
192  : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) {
193  LeakDetector::addGarbageObject(this);
194
195  if (aliasee)
196    assert(aliasee->getType() == Ty && "Alias and aliasee types should match!");
197  Op<0>() = aliasee;
198
199  if (ParentModule)
200    ParentModule->getAliasList().push_back(this);
201}
202
203void GlobalAlias::setParent(Module *parent) {
204  if (getParent())
205    LeakDetector::addGarbageObject(this);
206  Parent = parent;
207  if (getParent())
208    LeakDetector::removeGarbageObject(this);
209}
210
211void GlobalAlias::removeFromParent() {
212  getParent()->getAliasList().remove(this);
213}
214
215void GlobalAlias::eraseFromParent() {
216  getParent()->getAliasList().erase(this);
217}
218
219void GlobalAlias::setAliasee(Constant *Aliasee) {
220  assert((!Aliasee || Aliasee->getType() == getType()) &&
221         "Alias and aliasee types should match!");
222
223  setOperand(0, Aliasee);
224}
225
226const GlobalValue *GlobalAlias::getAliasedGlobal() const {
227  const Constant *C = getAliasee();
228  if (C == 0) return 0;
229
230  if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
231    return GV;
232
233  const ConstantExpr *CE = cast<ConstantExpr>(C);
234  assert((CE->getOpcode() == Instruction::BitCast ||
235          CE->getOpcode() == Instruction::GetElementPtr) &&
236         "Unsupported aliasee");
237
238  return cast<GlobalValue>(CE->getOperand(0));
239}
240
241const GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) const {
242  SmallPtrSet<const GlobalValue*, 3> Visited;
243
244  // Check if we need to stop early.
245  if (stopOnWeak && mayBeOverridden())
246    return this;
247
248  const GlobalValue *GV = getAliasedGlobal();
249  Visited.insert(GV);
250
251  // Iterate over aliasing chain, stopping on weak alias if necessary.
252  while (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) {
253    if (stopOnWeak && GA->mayBeOverridden())
254      break;
255
256    GV = GA->getAliasedGlobal();
257
258    if (!Visited.insert(GV))
259      return 0;
260  }
261
262  return GV;
263}
264