X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FGlobals.cpp;h=94bf3dea9ab3ca05b275286d61dfc476709f6f05;hb=d865e02ea24e92f8fd1d2b49a26ea0676a879ce7;hp=229b0127a4a4dfd0d864b17f63b4deb60ee63e14;hpb=28c3cff8250b3fe2adc6479306fe7dbdb48a1bdb;p=oota-llvm.git diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp index 229b0127a4a..94bf3dea9ab 100644 --- a/lib/VMCore/Globals.cpp +++ b/lib/VMCore/Globals.cpp @@ -18,6 +18,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/LeakDetector.h" using namespace llvm; @@ -28,17 +29,17 @@ using namespace llvm; /// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove /// it. This involves recursively eliminating any dead users of the /// constantexpr. -static bool removeDeadUsersOfConstant(Constant *C) { +static bool removeDeadUsersOfConstant(const Constant *C) { if (isa(C)) return false; // Cannot remove this while (!C->use_empty()) { - Constant *User = dyn_cast(C->use_back()); + const Constant *User = dyn_cast(C->use_back()); if (!User) return false; // Non-constant usage; if (!removeDeadUsersOfConstant(User)) return false; // Constant wasn't dead } - C->destroyConstant(); + const_cast(C)->destroyConstant(); return true; } @@ -46,11 +47,11 @@ static bool removeDeadUsersOfConstant(Constant *C) { /// off of this global value, remove them. This method is useful for clients /// that want to check to see if a global is unused, but don't want to deal /// with potentially dead constants hanging off of the globals. -void GlobalValue::removeDeadConstantUsers() { - Value::use_iterator I = use_begin(), E = use_end(); - Value::use_iterator LastNonDeadUser = E; +void GlobalValue::removeDeadConstantUsers() const { + Value::use_const_iterator I = use_begin(), E = use_end(); + Value::use_const_iterator LastNonDeadUser = E; while (I != E) { - if (Constant *User = dyn_cast(*I)) { + if (const Constant *User = dyn_cast(*I)) { if (!removeDeadUsersOfConstant(User)) { // If the constant wasn't dead, remember that this was the last live use // and move on to the next constant. @@ -73,11 +74,11 @@ void GlobalValue::removeDeadConstantUsers() { } } + /// Override destroyConstant to make sure it doesn't get called on /// GlobalValue's because they shouldn't be treated like other constants. void GlobalValue::destroyConstant() { - assert(0 && "You can't GV->destroyConstant()!"); - abort(); + llvm_unreachable("You can't GV->destroyConstant()!"); } /// copyAttributesFrom - copy all additional attributes (those not needed to @@ -94,43 +95,44 @@ void GlobalValue::copyAttributesFrom(const GlobalValue *Src) { //===----------------------------------------------------------------------===// GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, - Constant *InitVal, const std::string &Name, - Module *ParentModule, bool ThreadLocal, - unsigned AddressSpace) - : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, + Constant *InitVal, const Twine &Name, + bool ThreadLocal, unsigned AddressSpace) + : GlobalValue(PointerType::get(Ty, AddressSpace), + Value::GlobalVariableVal, OperandTraits::op_begin(this), InitVal != 0, Link, Name), isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) { if (InitVal) { assert(InitVal->getType() == Ty && "Initializer should be the same type as the GlobalVariable!"); - Op<0>().init(InitVal, this); + Op<0>() = InitVal; } LeakDetector::addGarbageObject(this); - - if (ParentModule) - ParentModule->getGlobalList().push_back(this); } -GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, - Constant *InitVal, const std::string &Name, +GlobalVariable::GlobalVariable(Module &M, const Type *Ty, bool constant, + LinkageTypes Link, Constant *InitVal, + const Twine &Name, GlobalVariable *Before, bool ThreadLocal, unsigned AddressSpace) - : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, + : GlobalValue(PointerType::get(Ty, AddressSpace), + Value::GlobalVariableVal, OperandTraits::op_begin(this), InitVal != 0, Link, Name), isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) { if (InitVal) { assert(InitVal->getType() == Ty && "Initializer should be the same type as the GlobalVariable!"); - Op<0>().init(InitVal, this); + Op<0>() = InitVal; } LeakDetector::addGarbageObject(this); if (Before) Before->getParent()->getGlobalList().insert(Before, this); + else + M.getGlobalList().push_back(this); } void GlobalVariable::setParent(Module *parent) { @@ -169,6 +171,21 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To, this->setOperand(0, cast(To)); } +void GlobalVariable::setInitializer(Constant *InitVal) { + if (InitVal == 0) { + if (hasInitializer()) { + Op<0>().set(0); + NumOperands = 0; + } + } else { + assert(InitVal->getType() == getType()->getElementType() && + "Initializer type must match GlobalVariable type"); + if (!hasInitializer()) + NumOperands = 1; + Op<0>().set(InitVal); + } +} + /// copyAttributesFrom - copy all additional attributes (those not needed to /// create a GlobalVariable) from the GlobalVariable Src to this one. void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) { @@ -184,14 +201,14 @@ void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) { //===----------------------------------------------------------------------===// GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link, - const std::string &Name, Constant* aliasee, + const Twine &Name, Constant* aliasee, Module *ParentModule) : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) { LeakDetector::addGarbageObject(this); if (aliasee) assert(aliasee->getType() == Ty && "Alias and aliasee types should match!"); - Op<0>().init(aliasee, this); + Op<0>() = aliasee; if (ParentModule) ParentModule->getAliasList().push_back(this); @@ -242,19 +259,27 @@ const GlobalValue *GlobalAlias::getAliasedGlobal() const { CE->getOpcode() == Instruction::GetElementPtr)) return dyn_cast(CE->getOperand(0)); else - assert(0 && "Unsupported aliasee"); + llvm_unreachable("Unsupported aliasee"); } } return 0; } -const GlobalValue *GlobalAlias::resolveAliasedGlobal() const { +const GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) const { SmallPtrSet Visited; + // Check if we need to stop early. + if (stopOnWeak && mayBeOverridden()) + return this; + const GlobalValue *GV = getAliasedGlobal(); Visited.insert(GV); + // Iterate over aliasing chain, stopping on weak alias if necessary. while (const GlobalAlias *GA = dyn_cast(GV)) { + if (stopOnWeak && GA->mayBeOverridden()) + break; + GV = GA->getAliasedGlobal(); if (!Visited.insert(GV))