X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FGlobals.cpp;h=c31b7b5e76cd44f2a661010dfa15dca8c902db16;hb=3d29df3e8a203b167d8071ea6f805b21db18a5af;hp=aeb34f43715d46aed6d8afe3286b33a63a5de72b;hpb=c6c98af9e5814e8066c82f20ca11cf646a5fc289;p=oota-llvm.git diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp index aeb34f43715..c31b7b5e76c 100644 --- a/lib/VMCore/Globals.cpp +++ b/lib/VMCore/Globals.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -16,7 +16,9 @@ #include "llvm/GlobalVariable.h" #include "llvm/GlobalAlias.h" #include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" #include "llvm/Module.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/LeakDetector.h" using namespace llvm; @@ -27,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; } @@ -45,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. @@ -78,23 +80,34 @@ void GlobalValue::destroyConstant() { assert(0 && "You can't GV->destroyConstant()!"); abort(); } - + +/// copyAttributesFrom - copy all additional attributes (those not needed to +/// create a GlobalValue) from the GlobalValue Src to this one. +void GlobalValue::copyAttributesFrom(const GlobalValue *Src) { + setAlignment(Src->getAlignment()); + setSection(Src->getSection()); + setVisibility(Src->getVisibility()); +} + + //===----------------------------------------------------------------------===// // GlobalVariable Implementation //===----------------------------------------------------------------------===// -GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, +GlobalVariable::GlobalVariable(LLVMContext &Context, const Type *Ty, + bool constant, LinkageTypes Link, Constant *InitVal, const std::string &Name, - Module *ParentModule, bool ThreadLocal) - : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, - &Initializer, InitVal != 0, Link, Name), + Module *ParentModule, bool ThreadLocal, + unsigned AddressSpace) + : GlobalValue(Context.getPointerType(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!"); - Initializer.init(InitVal, this); - } else { - Initializer.init(0, this); + Op<0>() = InitVal; } LeakDetector::addGarbageObject(this); @@ -103,18 +116,20 @@ GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, ParentModule->getGlobalList().push_back(this); } -GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, +GlobalVariable::GlobalVariable(LLVMContext &Context, const Type *Ty, + bool constant, LinkageTypes Link, Constant *InitVal, const std::string &Name, - GlobalVariable *Before, bool ThreadLocal) - : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, - &Initializer, InitVal != 0, Link, Name), + GlobalVariable *Before, bool ThreadLocal, + unsigned AddressSpace) + : GlobalValue(Context.getPointerType(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!"); - Initializer.init(InitVal, this); - } else { - Initializer.init(0, this); + Op<0>() = InitVal; } LeakDetector::addGarbageObject(this); @@ -159,6 +174,16 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To, this->setOperand(0, cast(To)); } +/// 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) { + assert(isa(Src) && "Expected a GlobalVariable!"); + GlobalValue::copyAttributesFrom(Src); + const GlobalVariable *SrcVar = cast(Src); + setThreadLocal(SrcVar->isThreadLocal()); +} + + //===----------------------------------------------------------------------===// // GlobalAlias Implementation //===----------------------------------------------------------------------===// @@ -166,12 +191,12 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To, GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link, const std::string &Name, Constant* aliasee, Module *ParentModule) - : GlobalValue(Ty, Value::GlobalAliasVal, &Aliasee, 1, Link, Name) { + : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) { LeakDetector::addGarbageObject(this); if (aliasee) assert(aliasee->getType() == Ty && "Alias and aliasee types should match!"); - Aliasee.init(aliasee, this); + Op<0>() = aliasee; if (ParentModule) ParentModule->getAliasList().push_back(this); @@ -210,20 +235,44 @@ void GlobalAlias::setAliasee(Constant *Aliasee) setOperand(0, Aliasee); } -const GlobalValue *GlobalAlias::getAliasedGlobal() const { +const GlobalValue *GlobalAlias::getAliasedGlobal() const { const Constant *C = getAliasee(); if (C) { if (const GlobalValue *GV = dyn_cast(C)) return GV; else { const ConstantExpr *CE = 0; - if ((CE = dyn_cast(Aliasee)) && - (CE->getOpcode() == Instruction::BitCast)) - return cast(CE->getOperand(0)); + if ((CE = dyn_cast(C)) && + (CE->getOpcode() == Instruction::BitCast || + CE->getOpcode() == Instruction::GetElementPtr)) + return dyn_cast(CE->getOperand(0)); else assert(0 && "Unsupported aliasee"); } - } else - return 0; + } + return 0; } +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)) + return NULL; + } + + return GV; +}