Globals.cpp revision 19e861a4ffb896f16a691d5ac869e894df3cd464
1cc041ba03aed685400197fb938b7a583713d25afChris Lattner//===-- Globals.cpp - Implement the GlobalValue & GlobalVariable class ----===//
2fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman//
3e253cf60fde678c428d69327b1ed43232893079cReid Spencer//                     The LLVM Compiler Infrastructure
4e253cf60fde678c428d69327b1ed43232893079cReid Spencer//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman//
8e253cf60fde678c428d69327b1ed43232893079cReid Spencer//===----------------------------------------------------------------------===//
9e253cf60fde678c428d69327b1ed43232893079cReid Spencer//
10e253cf60fde678c428d69327b1ed43232893079cReid Spencer// This file implements the GlobalValue & GlobalVariable classes for the VMCore
11e253cf60fde678c428d69327b1ed43232893079cReid Spencer// library.
12e253cf60fde678c428d69327b1ed43232893079cReid Spencer//
13e253cf60fde678c428d69327b1ed43232893079cReid Spencer//===----------------------------------------------------------------------===//
14e253cf60fde678c428d69327b1ed43232893079cReid Spencer
15c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov#include "llvm/Constants.h"
16e253cf60fde678c428d69327b1ed43232893079cReid Spencer#include "llvm/GlobalVariable.h"
178b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov#include "llvm/GlobalAlias.h"
18cc041ba03aed685400197fb938b7a583713d25afChris Lattner#include "llvm/DerivedTypes.h"
19e253cf60fde678c428d69327b1ed43232893079cReid Spencer#include "llvm/Module.h"
20e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov#include "llvm/ADT/SmallPtrSet.h"
21551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/LeakDetector.h"
22e253cf60fde678c428d69327b1ed43232893079cReid Spencerusing namespace llvm;
23e253cf60fde678c428d69327b1ed43232893079cReid Spencer
24e253cf60fde678c428d69327b1ed43232893079cReid Spencer//===----------------------------------------------------------------------===//
25e253cf60fde678c428d69327b1ed43232893079cReid Spencer//                            GlobalValue Class
26e253cf60fde678c428d69327b1ed43232893079cReid Spencer//===----------------------------------------------------------------------===//
27e253cf60fde678c428d69327b1ed43232893079cReid Spencer
2800f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner/// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove
2900f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner/// it.  This involves recursively eliminating any dead users of the
3000f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner/// constantexpr.
3100f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattnerstatic bool removeDeadUsersOfConstant(Constant *C) {
32da6cdfa9e885ab8e1eb53b984c0ee77d0d64cd5eChris Lattner  if (isa<GlobalValue>(C)) return false; // Cannot remove this
33da6cdfa9e885ab8e1eb53b984c0ee77d0d64cd5eChris Lattner
3400f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner  while (!C->use_empty()) {
3500f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner    Constant *User = dyn_cast<Constant>(C->use_back());
3600f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner    if (!User) return false; // Non-constant usage;
3700f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner    if (!removeDeadUsersOfConstant(User))
3800f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner      return false; // Constant wasn't dead
3900f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner  }
40da6cdfa9e885ab8e1eb53b984c0ee77d0d64cd5eChris Lattner
41da6cdfa9e885ab8e1eb53b984c0ee77d0d64cd5eChris Lattner  C->destroyConstant();
42e253cf60fde678c428d69327b1ed43232893079cReid Spencer  return true;
43e253cf60fde678c428d69327b1ed43232893079cReid Spencer}
44e253cf60fde678c428d69327b1ed43232893079cReid Spencer
45e253cf60fde678c428d69327b1ed43232893079cReid Spencer/// removeDeadConstantUsers - If there are any dead constant users dangling
46e253cf60fde678c428d69327b1ed43232893079cReid Spencer/// off of this global value, remove them.  This method is useful for clients
47e253cf60fde678c428d69327b1ed43232893079cReid Spencer/// that want to check to see if a global is unused, but don't want to deal
48e253cf60fde678c428d69327b1ed43232893079cReid Spencer/// with potentially dead constants hanging off of the globals.
49f8083b7f20e0985b3c1848d25a56b1f527c0a255Chris Lattnervoid GlobalValue::removeDeadConstantUsers() {
5000f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner  Value::use_iterator I = use_begin(), E = use_end();
5100f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner  Value::use_iterator LastNonDeadUser = E;
5200f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner  while (I != E) {
5300f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner    if (Constant *User = dyn_cast<Constant>(*I)) {
5400f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner      if (!removeDeadUsersOfConstant(User)) {
5500f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner        // If the constant wasn't dead, remember that this was the last live use
5600f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner        // and move on to the next constant.
5700f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner        LastNonDeadUser = I;
5800f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner        ++I;
5900f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner      } else {
6000f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner        // If the constant was dead, then the iterator is invalidated.
6100f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner        if (LastNonDeadUser == E) {
6200f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner          I = use_begin();
6300f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner          if (I == E) break;
6400f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner        } else {
6500f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner          I = LastNonDeadUser;
6600f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner          ++I;
6700f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner        }
6800f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner      }
69e253cf60fde678c428d69327b1ed43232893079cReid Spencer    } else {
7000f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner      LastNonDeadUser = I;
7100f23ec5c2e0f4071b9720485ae63333149ee047Chris Lattner      ++I;
72e253cf60fde678c428d69327b1ed43232893079cReid Spencer    }
73e253cf60fde678c428d69327b1ed43232893079cReid Spencer  }
74e253cf60fde678c428d69327b1ed43232893079cReid Spencer}
75e253cf60fde678c428d69327b1ed43232893079cReid Spencer
76fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman/// Override destroyConstant to make sure it doesn't get called on
77e253cf60fde678c428d69327b1ed43232893079cReid Spencer/// GlobalValue's because they shouldn't be treated like other constants.
78e253cf60fde678c428d69327b1ed43232893079cReid Spencervoid GlobalValue::destroyConstant() {
79e253cf60fde678c428d69327b1ed43232893079cReid Spencer  assert(0 && "You can't GV->destroyConstant()!");
80e253cf60fde678c428d69327b1ed43232893079cReid Spencer  abort();
81e253cf60fde678c428d69327b1ed43232893079cReid Spencer}
8228c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands
8328c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands/// copyAttributesFrom - copy all additional attributes (those not needed to
8428c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands/// create a GlobalValue) from the GlobalValue Src to this one.
8528c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sandsvoid GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
8628c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands  setAlignment(Src->getAlignment());
8728c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands  setSection(Src->getSection());
8828c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands  setVisibility(Src->getVisibility());
8928c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands}
9028c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands
9128c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands
92e253cf60fde678c428d69327b1ed43232893079cReid Spencer//===----------------------------------------------------------------------===//
93e253cf60fde678c428d69327b1ed43232893079cReid Spencer// GlobalVariable Implementation
94e253cf60fde678c428d69327b1ed43232893079cReid Spencer//===----------------------------------------------------------------------===//
95e253cf60fde678c428d69327b1ed43232893079cReid Spencer
96e253cf60fde678c428d69327b1ed43232893079cReid SpencerGlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
97c763552299165b88d34a7d4f2d76ff413cbc7f67Lauro Ramos Venancio                               Constant *InitVal, const std::string &Name,
98fe63fb986dc9510c5d68f2442edab9574e9e50d0Christopher Lamb                               Module *ParentModule, bool ThreadLocal,
99fe63fb986dc9510c5d68f2442edab9574e9e50d0Christopher Lamb                               unsigned AddressSpace)
100fe63fb986dc9510c5d68f2442edab9574e9e50d0Christopher Lamb  : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
101efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif                OperandTraits<GlobalVariable>::op_begin(this),
102efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif                InitVal != 0, Link, Name),
103c763552299165b88d34a7d4f2d76ff413cbc7f67Lauro Ramos Venancio    isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
10496d83f63cdbb33c075901b1b84eb07622d86386fChris Lattner  if (InitVal) {
10596d83f63cdbb33c075901b1b84eb07622d86386fChris Lattner    assert(InitVal->getType() == Ty &&
1068243976b69aee92b26e67ef8a3ec505e924e408bAlkis Evlogimenos           "Initializer should be the same type as the GlobalVariable!");
1076c80c381601b17207b6b8f898cfe273a37584d52Gabor Greif    Op<0>() = InitVal;
1088243976b69aee92b26e67ef8a3ec505e924e408bAlkis Evlogimenos  }
109e253cf60fde678c428d69327b1ed43232893079cReid Spencer
110e253cf60fde678c428d69327b1ed43232893079cReid Spencer  LeakDetector::addGarbageObject(this);
111e253cf60fde678c428d69327b1ed43232893079cReid Spencer
112e253cf60fde678c428d69327b1ed43232893079cReid Spencer  if (ParentModule)
113e253cf60fde678c428d69327b1ed43232893079cReid Spencer    ParentModule->getGlobalList().push_back(this);
114e253cf60fde678c428d69327b1ed43232893079cReid Spencer}
115e253cf60fde678c428d69327b1ed43232893079cReid Spencer
116adc95467e41d6c46793f665168468cbf348c3638Chris LattnerGlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
117c763552299165b88d34a7d4f2d76ff413cbc7f67Lauro Ramos Venancio                               Constant *InitVal, const std::string &Name,
118fe63fb986dc9510c5d68f2442edab9574e9e50d0Christopher Lamb                               GlobalVariable *Before, bool ThreadLocal,
119fe63fb986dc9510c5d68f2442edab9574e9e50d0Christopher Lamb                               unsigned AddressSpace)
120fe63fb986dc9510c5d68f2442edab9574e9e50d0Christopher Lamb  : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
121efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif                OperandTraits<GlobalVariable>::op_begin(this),
122efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif                InitVal != 0, Link, Name),
123c763552299165b88d34a7d4f2d76ff413cbc7f67Lauro Ramos Venancio    isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
124adc95467e41d6c46793f665168468cbf348c3638Chris Lattner  if (InitVal) {
125adc95467e41d6c46793f665168468cbf348c3638Chris Lattner    assert(InitVal->getType() == Ty &&
126adc95467e41d6c46793f665168468cbf348c3638Chris Lattner           "Initializer should be the same type as the GlobalVariable!");
1276c80c381601b17207b6b8f898cfe273a37584d52Gabor Greif    Op<0>() = InitVal;
128adc95467e41d6c46793f665168468cbf348c3638Chris Lattner  }
129adc95467e41d6c46793f665168468cbf348c3638Chris Lattner
130adc95467e41d6c46793f665168468cbf348c3638Chris Lattner  LeakDetector::addGarbageObject(this);
131adc95467e41d6c46793f665168468cbf348c3638Chris Lattner
132adc95467e41d6c46793f665168468cbf348c3638Chris Lattner  if (Before)
133adc95467e41d6c46793f665168468cbf348c3638Chris Lattner    Before->getParent()->getGlobalList().insert(Before, this);
134adc95467e41d6c46793f665168468cbf348c3638Chris Lattner}
135adc95467e41d6c46793f665168468cbf348c3638Chris Lattner
136e253cf60fde678c428d69327b1ed43232893079cReid Spencervoid GlobalVariable::setParent(Module *parent) {
137e253cf60fde678c428d69327b1ed43232893079cReid Spencer  if (getParent())
138e253cf60fde678c428d69327b1ed43232893079cReid Spencer    LeakDetector::addGarbageObject(this);
139e253cf60fde678c428d69327b1ed43232893079cReid Spencer  Parent = parent;
140e253cf60fde678c428d69327b1ed43232893079cReid Spencer  if (getParent())
141e253cf60fde678c428d69327b1ed43232893079cReid Spencer    LeakDetector::removeGarbageObject(this);
142e253cf60fde678c428d69327b1ed43232893079cReid Spencer}
143e253cf60fde678c428d69327b1ed43232893079cReid Spencer
1444b83380f330b1c77bb9b4ad8f63bdcf1a596afd6Chris Lattnervoid GlobalVariable::removeFromParent() {
1454b83380f330b1c77bb9b4ad8f63bdcf1a596afd6Chris Lattner  getParent()->getGlobalList().remove(this);
1464b83380f330b1c77bb9b4ad8f63bdcf1a596afd6Chris Lattner}
1474b83380f330b1c77bb9b4ad8f63bdcf1a596afd6Chris Lattner
1484b83380f330b1c77bb9b4ad8f63bdcf1a596afd6Chris Lattnervoid GlobalVariable::eraseFromParent() {
1494b83380f330b1c77bb9b4ad8f63bdcf1a596afd6Chris Lattner  getParent()->getGlobalList().erase(this);
1504b83380f330b1c77bb9b4ad8f63bdcf1a596afd6Chris Lattner}
1514b83380f330b1c77bb9b4ad8f63bdcf1a596afd6Chris Lattner
152e253cf60fde678c428d69327b1ed43232893079cReid Spencervoid GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
153d0ff1adbdb4b7b565b7f8f191aac0731e80aa1efChris Lattner                                                 Use *U) {
154e253cf60fde678c428d69327b1ed43232893079cReid Spencer  // If you call this, then you better know this GVar has a constant
155e253cf60fde678c428d69327b1ed43232893079cReid Spencer  // initializer worth replacing. Enforce that here.
156fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman  assert(getNumOperands() == 1 &&
157e253cf60fde678c428d69327b1ed43232893079cReid Spencer         "Attempt to replace uses of Constants on a GVar with no initializer");
158e253cf60fde678c428d69327b1ed43232893079cReid Spencer
159e253cf60fde678c428d69327b1ed43232893079cReid Spencer  // And, since you know it has an initializer, the From value better be
160e253cf60fde678c428d69327b1ed43232893079cReid Spencer  // the initializer :)
161e253cf60fde678c428d69327b1ed43232893079cReid Spencer  assert(getOperand(0) == From &&
162e253cf60fde678c428d69327b1ed43232893079cReid Spencer         "Attempt to replace wrong constant initializer in GVar");
163e253cf60fde678c428d69327b1ed43232893079cReid Spencer
164e253cf60fde678c428d69327b1ed43232893079cReid Spencer  // And, you better have a constant for the replacement value
165e253cf60fde678c428d69327b1ed43232893079cReid Spencer  assert(isa<Constant>(To) &&
166e253cf60fde678c428d69327b1ed43232893079cReid Spencer         "Attempt to replace GVar initializer with non-constant");
167fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman
168e253cf60fde678c428d69327b1ed43232893079cReid Spencer  // Okay, preconditions out of the way, replace the constant initializer.
16907d7c9d9c508ec67a86ed572819d8cf9e3bdc422Chris Lattner  this->setOperand(0, cast<Constant>(To));
170e253cf60fde678c428d69327b1ed43232893079cReid Spencer}
1718b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov
17228c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands/// copyAttributesFrom - copy all additional attributes (those not needed to
17328c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands/// create a GlobalVariable) from the GlobalVariable Src to this one.
17428c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sandsvoid GlobalVariable::copyAttributesFrom(const GlobalValue *Src) {
17528c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands  assert(isa<GlobalVariable>(Src) && "Expected a GlobalVariable!");
17628c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands  GlobalValue::copyAttributesFrom(Src);
17728c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands  const GlobalVariable *SrcVar = cast<GlobalVariable>(Src);
17828c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands  setThreadLocal(SrcVar->isThreadLocal());
17928c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands}
18028c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands
18128c3cff8250b3fe2adc6479306fe7dbdb48a1bdbDuncan Sands
1828b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov//===----------------------------------------------------------------------===//
1838b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov// GlobalAlias Implementation
1848b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov//===----------------------------------------------------------------------===//
1858b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov
1868b0a8c84da2030ee8f4440d5b60a8033de691222Anton KorobeynikovGlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link,
187a80e1181b78183dc36ec6568559d38faa86981f0Anton Korobeynikov                         const std::string &Name, Constant* aliasee,
1888b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov                         Module *ParentModule)
189efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif  : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) {
1908b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov  LeakDetector::addGarbageObject(this);
1918b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov
192a80e1181b78183dc36ec6568559d38faa86981f0Anton Korobeynikov  if (aliasee)
193a80e1181b78183dc36ec6568559d38faa86981f0Anton Korobeynikov    assert(aliasee->getType() == Ty && "Alias and aliasee types should match!");
1946c80c381601b17207b6b8f898cfe273a37584d52Gabor Greif  Op<0>() = aliasee;
195a80e1181b78183dc36ec6568559d38faa86981f0Anton Korobeynikov
1968b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov  if (ParentModule)
1978b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov    ParentModule->getAliasList().push_back(this);
1988b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov}
1998b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov
2008b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikovvoid GlobalAlias::setParent(Module *parent) {
2018b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov  if (getParent())
2028b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov    LeakDetector::addGarbageObject(this);
2038b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov  Parent = parent;
2048b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov  if (getParent())
2058b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov    LeakDetector::removeGarbageObject(this);
2068b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov}
2078b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov
2088b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikovvoid GlobalAlias::removeFromParent() {
2098b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov  getParent()->getAliasList().remove(this);
2108b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov}
2118b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov
2128b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikovvoid GlobalAlias::eraseFromParent() {
2138b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov  getParent()->getAliasList().erase(this);
2148b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov}
2158b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov
2168b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikovbool GlobalAlias::isDeclaration() const {
217c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov  const GlobalValue* AV = getAliasedGlobal();
218c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov  if (AV)
219c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov    return AV->isDeclaration();
220c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov  else
221c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov    return false;
2228b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov}
2238b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov
224a80e1181b78183dc36ec6568559d38faa86981f0Anton Korobeynikovvoid GlobalAlias::setAliasee(Constant *Aliasee)
2258b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov{
226c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov  if (Aliasee)
227c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov    assert(Aliasee->getType() == getType() &&
228a80e1181b78183dc36ec6568559d38faa86981f0Anton Korobeynikov           "Alias and aliasee types should match!");
229c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov
230c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov  setOperand(0, Aliasee);
231c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov}
232c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov
2332bf6e6a632b445b363707f99aa35ca304e7a9176Chris Lattnerconst GlobalValue *GlobalAlias::getAliasedGlobal() const {
234c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov  const Constant *C = getAliasee();
235c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov  if (C) {
236c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov    if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
237c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov      return GV;
238c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov    else {
239c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov      const ConstantExpr *CE = 0;
240bb1f97cf87d8e3758d36d38499a8efe48ac28f91Anton Korobeynikov      if ((CE = dyn_cast<ConstantExpr>(C)) &&
2412bf6e6a632b445b363707f99aa35ca304e7a9176Chris Lattner          (CE->getOpcode() == Instruction::BitCast ||
2422bf6e6a632b445b363707f99aa35ca304e7a9176Chris Lattner           CE->getOpcode() == Instruction::GetElementPtr))
2432bf6e6a632b445b363707f99aa35ca304e7a9176Chris Lattner        return dyn_cast<GlobalValue>(CE->getOperand(0));
244c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov      else
245c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov        assert(0 && "Unsupported aliasee");
246c6c98af9e5814e8066c82f20ca11cf646a5fc289Anton Korobeynikov    }
247b4dbd9e243f9aef69f8edb1363788b2311a73506Jeff Cohen  }
248b4dbd9e243f9aef69f8edb1363788b2311a73506Jeff Cohen  return 0;
2498b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov}
2508b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov
25119e861a4ffb896f16a691d5ac869e894df3cd464Anton Korobeynikovconst GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) const {
25289a3d3f25cf58c940189d87356141d2610042d58Anton Korobeynikov  SmallPtrSet<const GlobalValue*, 3> Visited;
253e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov
254832b2a9cd8870211bf2d347d7b435beacbb06c8dAnton Korobeynikov  // Check if we need to stop early.
25519e861a4ffb896f16a691d5ac869e894df3cd464Anton Korobeynikov  if (stopOnWeak && hasWeakLinkage())
256832b2a9cd8870211bf2d347d7b435beacbb06c8dAnton Korobeynikov    return this;
257832b2a9cd8870211bf2d347d7b435beacbb06c8dAnton Korobeynikov
258e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov  const GlobalValue *GV = getAliasedGlobal();
259e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov  Visited.insert(GV);
260e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov
261832b2a9cd8870211bf2d347d7b435beacbb06c8dAnton Korobeynikov  // Iterate over aliasing chain, stopping on weak alias if necessary.
262e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov  while (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) {
26319e861a4ffb896f16a691d5ac869e894df3cd464Anton Korobeynikov    if (stopOnWeak && GA->hasWeakLinkage())
264832b2a9cd8870211bf2d347d7b435beacbb06c8dAnton Korobeynikov      break;
265832b2a9cd8870211bf2d347d7b435beacbb06c8dAnton Korobeynikov
266e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov    GV = GA->getAliasedGlobal();
267e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov
268e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov    if (!Visited.insert(GV))
269e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov      return NULL;
270e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov  }
271e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov
272e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov  return GV;
273e846dd89c173d462d197046b76d37588896623f3Anton Korobeynikov}
274