X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FVMCore%2FGlobals.cpp;h=c428b889c3ec84381ab0147271c6906cec4eb111;hb=b21d9aebba7e45ddcbce61dd501000049cefb335;hp=ab1118dd0b1906800ee14e2271f5d6a8f9e39503;hpb=00f23ec5c2e0f4071b9720485ae63333149ee047;p=oota-llvm.git diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp index ab1118dd0b1..c428b889c3e 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. // //===----------------------------------------------------------------------===// // @@ -12,9 +12,13 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Constants.h" #include "llvm/GlobalVariable.h" +#include "llvm/GlobalAlias.h" #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; @@ -22,105 +26,101 @@ using namespace llvm; // GlobalValue Class //===----------------------------------------------------------------------===// -/// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove -/// it. This involves recursively eliminating any dead users of the -/// constantexpr. -static bool removeDeadUsersOfConstant(Constant *C) { - if (isa(C)) return false; // Cannot remove this - - while (!C->use_empty()) { - 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(); - return true; -} - -/// removeDeadConstantUsers - If there are any dead constant users dangling -/// 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; - while (I != E) { - if (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. - LastNonDeadUser = I; - ++I; - } else { - // If the constant was dead, then the iterator is invalidated. - if (LastNonDeadUser == E) { - I = use_begin(); - if (I == E) break; - } else { - I = LastNonDeadUser; - ++I; - } - } - } else { - LastNonDeadUser = I; - ++I; - } - } +bool GlobalValue::isMaterializable() const { + return getParent() && getParent()->isMaterializable(this); +} +bool GlobalValue::isDematerializable() const { + return getParent() && getParent()->isDematerializable(this); +} +bool GlobalValue::Materialize(std::string *ErrInfo) { + return getParent()->Materialize(this, ErrInfo); +} +void GlobalValue::Dematerialize() { + getParent()->Dematerialize(this); } /// 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 +/// 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()); + setUnnamedAddr(Src->hasUnnamedAddr()); } + +void GlobalValue::setAlignment(unsigned Align) { + assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); + assert(Align <= MaximumAlignment && + "Alignment is greater than MaximumAlignment!"); + Alignment = Log2_32(Align) + 1; + assert(getAlignment() == Align && "Alignment representation error!"); +} + +bool GlobalValue::isDeclaration() const { + // Globals are definitions if they have an initializer. + if (const GlobalVariable *GV = dyn_cast(this)) + return GV->getNumOperands() == 0; + + // Functions are definitions if they have a body. + if (const Function *F = dyn_cast(this)) + return F->empty(); + + // Aliases are always definitions. + assert(isa(this)); + return false; +} + //===----------------------------------------------------------------------===// // GlobalVariable Implementation //===----------------------------------------------------------------------===// -GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, - Constant *InitVal, - const std::string &Name, Module *ParentModule) - : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, - &Initializer, InitVal != 0, Link, Name), - isConstantGlobal(constant) { +GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link, + Constant *InitVal, const Twine &Name, + ThreadLocalMode TLMode, unsigned AddressSpace) + : GlobalValue(PointerType::get(Ty, AddressSpace), + Value::GlobalVariableVal, + OperandTraits::op_begin(this), + InitVal != 0, Link, Name), + isConstantGlobal(constant), threadLocalMode(TLMode) { 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); - - if (ParentModule) - ParentModule->getGlobalList().push_back(this); } -GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, - Constant *InitVal, - const std::string &Name, GlobalVariable *Before) - : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, - &Initializer, InitVal != 0, Link, Name), - isConstantGlobal(constant) { +GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant, + LinkageTypes Link, Constant *InitVal, + const Twine &Name, + GlobalVariable *Before, ThreadLocalMode TLMode, + unsigned AddressSpace) + : GlobalValue(PointerType::get(Ty, AddressSpace), + Value::GlobalVariableVal, + OperandTraits::op_begin(this), + InitVal != 0, Link, Name), + isConstantGlobal(constant), threadLocalMode(TLMode) { 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); if (Before) Before->getParent()->getGlobalList().insert(Before, this); + else + M.getGlobalList().push_back(this); } - void GlobalVariable::setParent(Module *parent) { if (getParent()) LeakDetector::addGarbageObject(this); @@ -156,3 +156,108 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To, // Okay, preconditions out of the way, replace the constant initializer. 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) { + assert(isa(Src) && "Expected a GlobalVariable!"); + GlobalValue::copyAttributesFrom(Src); + const GlobalVariable *SrcVar = cast(Src); + setThreadLocal(SrcVar->isThreadLocal()); +} + + +//===----------------------------------------------------------------------===// +// GlobalAlias Implementation +//===----------------------------------------------------------------------===// + +GlobalAlias::GlobalAlias(Type *Ty, LinkageTypes Link, + 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>() = aliasee; + + if (ParentModule) + ParentModule->getAliasList().push_back(this); +} + +void GlobalAlias::setParent(Module *parent) { + if (getParent()) + LeakDetector::addGarbageObject(this); + Parent = parent; + if (getParent()) + LeakDetector::removeGarbageObject(this); +} + +void GlobalAlias::removeFromParent() { + getParent()->getAliasList().remove(this); +} + +void GlobalAlias::eraseFromParent() { + getParent()->getAliasList().erase(this); +} + +void GlobalAlias::setAliasee(Constant *Aliasee) { + assert((!Aliasee || Aliasee->getType() == getType()) && + "Alias and aliasee types should match!"); + + setOperand(0, Aliasee); +} + +const GlobalValue *GlobalAlias::getAliasedGlobal() const { + const Constant *C = getAliasee(); + if (C == 0) return 0; + + if (const GlobalValue *GV = dyn_cast(C)) + return GV; + + const ConstantExpr *CE = cast(C); + assert((CE->getOpcode() == Instruction::BitCast || + CE->getOpcode() == Instruction::GetElementPtr) && + "Unsupported aliasee"); + + return cast(CE->getOperand(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 0; + } + + return GV; +}