88a8c0b2a7ad7d4484456cfc524735a6d282321b
[oota-llvm.git] / lib / VMCore / Globals.cpp
1 //===-- Globals.cpp - Implement the GlobalValue & GlobalVariable class ----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source 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/GlobalVariable.h"
16 #include "llvm/GlobalAlias.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/Module.h"
19 #include "llvm/Support/LeakDetector.h"
20 using namespace llvm;
21
22 //===----------------------------------------------------------------------===//
23 //                            GlobalValue Class
24 //===----------------------------------------------------------------------===//
25
26 /// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove
27 /// it.  This involves recursively eliminating any dead users of the
28 /// constantexpr.
29 static bool removeDeadUsersOfConstant(Constant *C) {
30   if (isa<GlobalValue>(C)) return false; // Cannot remove this
31
32   while (!C->use_empty()) {
33     Constant *User = dyn_cast<Constant>(C->use_back());
34     if (!User) return false; // Non-constant usage;
35     if (!removeDeadUsersOfConstant(User))
36       return false; // Constant wasn't dead
37   }
38
39   C->destroyConstant();
40   return true;
41 }
42
43 /// removeDeadConstantUsers - If there are any dead constant users dangling
44 /// off of this global value, remove them.  This method is useful for clients
45 /// that want to check to see if a global is unused, but don't want to deal
46 /// with potentially dead constants hanging off of the globals.
47 void GlobalValue::removeDeadConstantUsers() {
48   Value::use_iterator I = use_begin(), E = use_end();
49   Value::use_iterator LastNonDeadUser = E;
50   while (I != E) {
51     if (Constant *User = dyn_cast<Constant>(*I)) {
52       if (!removeDeadUsersOfConstant(User)) {
53         // If the constant wasn't dead, remember that this was the last live use
54         // and move on to the next constant.
55         LastNonDeadUser = I;
56         ++I;
57       } else {
58         // If the constant was dead, then the iterator is invalidated.
59         if (LastNonDeadUser == E) {
60           I = use_begin();
61           if (I == E) break;
62         } else {
63           I = LastNonDeadUser;
64           ++I;
65         }
66       }
67     } else {
68       LastNonDeadUser = I;
69       ++I;
70     }
71   }
72 }
73
74 /// Override destroyConstant to make sure it doesn't get called on
75 /// GlobalValue's because they shouldn't be treated like other constants.
76 void GlobalValue::destroyConstant() {
77   assert(0 && "You can't GV->destroyConstant()!");
78   abort();
79 }
80   
81 //===----------------------------------------------------------------------===//
82 // GlobalVariable Implementation
83 //===----------------------------------------------------------------------===//
84
85 GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
86                                Constant *InitVal, const std::string &Name,
87                                Module *ParentModule, bool ThreadLocal)
88   : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
89                 &Initializer, 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     Initializer.init(InitVal, this);
95   } else {
96     Initializer.init(0, this);
97   }
98
99   LeakDetector::addGarbageObject(this);
100
101   if (ParentModule)
102     ParentModule->getGlobalList().push_back(this);
103 }
104
105 GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
106                                Constant *InitVal, const std::string &Name,
107                                GlobalVariable *Before, bool ThreadLocal)
108   : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
109                 &Initializer, InitVal != 0, Link, Name), 
110     isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
111   if (InitVal) {
112     assert(InitVal->getType() == Ty &&
113            "Initializer should be the same type as the GlobalVariable!");
114     Initializer.init(InitVal, this);
115   } else {
116     Initializer.init(0, this);
117   }
118   
119   LeakDetector::addGarbageObject(this);
120   
121   if (Before)
122     Before->getParent()->getGlobalList().insert(Before, this);
123 }
124
125 void GlobalVariable::setParent(Module *parent) {
126   if (getParent())
127     LeakDetector::addGarbageObject(this);
128   Parent = parent;
129   if (getParent())
130     LeakDetector::removeGarbageObject(this);
131 }
132
133 void GlobalVariable::removeFromParent() {
134   getParent()->getGlobalList().remove(this);
135 }
136
137 void GlobalVariable::eraseFromParent() {
138   getParent()->getGlobalList().erase(this);
139 }
140
141 void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
142                                                  Use *U) {
143   // If you call this, then you better know this GVar has a constant
144   // initializer worth replacing. Enforce that here.
145   assert(getNumOperands() == 1 &&
146          "Attempt to replace uses of Constants on a GVar with no initializer");
147
148   // And, since you know it has an initializer, the From value better be
149   // the initializer :)
150   assert(getOperand(0) == From &&
151          "Attempt to replace wrong constant initializer in GVar");
152
153   // And, you better have a constant for the replacement value
154   assert(isa<Constant>(To) &&
155          "Attempt to replace GVar initializer with non-constant");
156
157   // Okay, preconditions out of the way, replace the constant initializer.
158   this->setOperand(0, cast<Constant>(To));
159 }
160
161 //===----------------------------------------------------------------------===//
162 // GlobalAlias Implementation
163 //===----------------------------------------------------------------------===//
164
165 GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link,
166                          const std::string &Name, Constant* aliasee,
167                          Module *ParentModule)
168   : GlobalValue(Ty, Value::GlobalAliasVal, &Aliasee, 1, Link, Name) {
169   LeakDetector::addGarbageObject(this);
170
171   if (aliasee)
172     assert(aliasee->getType() == Ty && "Alias and aliasee types should match!");
173   Aliasee.init(aliasee, this);
174
175   if (ParentModule)
176     ParentModule->getAliasList().push_back(this);
177 }
178
179 void GlobalAlias::setParent(Module *parent) {
180   if (getParent())
181     LeakDetector::addGarbageObject(this);
182   Parent = parent;
183   if (getParent())
184     LeakDetector::removeGarbageObject(this);
185 }
186
187 void GlobalAlias::removeFromParent() {
188   getParent()->getAliasList().remove(this);
189 }
190
191 void GlobalAlias::eraseFromParent() {
192   getParent()->getAliasList().erase(this);
193 }
194
195 bool GlobalAlias::isDeclaration() const {
196   const GlobalValue* AV = dyn_cast_or_null<const GlobalValue>(getAliasee());
197   return (AV && AV->isDeclaration());
198 }
199
200 void GlobalAlias::setAliasee(Constant *Aliasee) 
201 {
202   if (Aliasee) {
203     assert(Aliasee->getType() == getType() && 
204            "Alias and aliasee types should match!");
205     setOperand(0, Aliasee);
206   }
207 }
208