X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FIR%2FGlobals.cpp;h=cecd999657e3c3dfb7406a0748f4bd05a57cd376;hb=9ed44978efe98a42df1cbf9c3737e29c556b9885;hp=6d547f3edf3f61bfdf7768590d98908e35ae00c2;hpb=af2f494c2d87a77c46efb85856f235ddd7f3c6ab;p=oota-llvm.git diff --git a/lib/IR/Globals.cpp b/lib/IR/Globals.cpp index 6d547f3edf3..cecd999657e 100644 --- a/lib/IR/Globals.cpp +++ b/lib/IR/Globals.cpp @@ -18,9 +18,10 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/LeakDetector.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/LeakDetector.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -28,18 +29,24 @@ using namespace llvm; //===----------------------------------------------------------------------===// bool GlobalValue::isMaterializable() const { - return getParent() && getParent()->isMaterializable(this); + if (const Function *F = dyn_cast(this)) + return F->isMaterializable(); + return false; } bool GlobalValue::isDematerializable() const { return getParent() && getParent()->isDematerializable(this); } -bool GlobalValue::Materialize(std::string *ErrInfo) { - return getParent()->Materialize(this, ErrInfo); +std::error_code GlobalValue::materialize() { + return getParent()->materialize(this); } void GlobalValue::Dematerialize() { getParent()->Dematerialize(this); } +const DataLayout *GlobalValue::getDataLayout() const { + return getParent()->getDataLayout(); +} + /// 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() { @@ -49,20 +56,76 @@ void GlobalValue::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()); + setDLLStorageClass(Src->getDLLStorageClass()); +} + +unsigned GlobalValue::getAlignment() const { + if (auto *GA = dyn_cast(this)) { + // In general we cannot compute this at the IR level, but we try. + if (const GlobalObject *GO = GA->getBaseObject()) + return GO->getAlignment(); + + // FIXME: we should also be able to handle: + // Alias = Global + Offset + // Alias = Absolute + return 0; + } + return cast(this)->getAlignment(); } -void GlobalValue::setAlignment(unsigned Align) { +void GlobalObject::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; + unsigned AlignmentData = Log2_32(Align) + 1; + unsigned OldData = getGlobalValueSubClassData(); + setGlobalValueSubClassData((OldData & ~AlignmentMask) | AlignmentData); assert(getAlignment() == Align && "Alignment representation error!"); } +unsigned GlobalObject::getGlobalObjectSubClassData() const { + unsigned ValueData = getGlobalValueSubClassData(); + return ValueData >> AlignmentBits; +} + +void GlobalObject::setGlobalObjectSubClassData(unsigned Val) { + unsigned OldData = getGlobalValueSubClassData(); + setGlobalValueSubClassData((OldData & AlignmentMask) | + (Val << AlignmentBits)); + assert(getGlobalObjectSubClassData() == Val && "representation error"); +} + +void GlobalObject::copyAttributesFrom(const GlobalValue *Src) { + const auto *GV = cast(Src); + GlobalValue::copyAttributesFrom(GV); + setAlignment(GV->getAlignment()); + setSection(GV->getSection()); +} + +const char *GlobalValue::getSection() const { + if (auto *GA = dyn_cast(this)) { + // In general we cannot compute this at the IR level, but we try. + if (const GlobalObject *GO = GA->getBaseObject()) + return GO->getSection(); + return ""; + } + return cast(this)->getSection(); +} + +Comdat *GlobalValue::getComdat() { + if (auto *GA = dyn_cast(this)) { + // In general we cannot compute this at the IR level, but we try. + if (const GlobalObject *GO = GA->getBaseObject()) + return const_cast(GO)->getComdat(); + return nullptr; + } + return cast(this)->getComdat(); +} + +void GlobalObject::setSection(StringRef S) { Section = S; } + bool GlobalValue::isDeclaration() const { // Globals are definitions if they have an initializer. if (const GlobalVariable *GV = dyn_cast(this)) @@ -70,28 +133,27 @@ bool GlobalValue::isDeclaration() const { // Functions are definitions if they have a body. if (const Function *F = dyn_cast(this)) - return F->empty(); + return F->empty() && !F->isMaterializable(); // Aliases are always definitions. assert(isa(this)); return false; } - + //===----------------------------------------------------------------------===// // GlobalVariable Implementation //===----------------------------------------------------------------------===// GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link, - Constant *InitVal, - const Twine &Name, ThreadLocalMode TLMode, - unsigned AddressSpace, + Constant *InitVal, const Twine &Name, + ThreadLocalMode TLMode, unsigned AddressSpace, bool isExternallyInitialized) - : GlobalValue(PointerType::get(Ty, AddressSpace), - Value::GlobalVariableVal, - OperandTraits::op_begin(this), - InitVal != 0, Link, Name), - isConstantGlobal(constant), threadLocalMode(TLMode), - isExternallyInitializedConstant(isExternallyInitialized) { + : GlobalObject(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, + OperandTraits::op_begin(this), + InitVal != nullptr, Link, Name), + isConstantGlobal(constant), + isExternallyInitializedConstant(isExternallyInitialized) { + setThreadLocalMode(TLMode); if (InitVal) { assert(InitVal->getType() == Ty && "Initializer should be the same type as the GlobalVariable!"); @@ -103,24 +165,23 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link, GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant, LinkageTypes Link, Constant *InitVal, - const Twine &Name, - GlobalVariable *Before, ThreadLocalMode TLMode, - unsigned AddressSpace, + const Twine &Name, GlobalVariable *Before, + ThreadLocalMode TLMode, unsigned AddressSpace, bool isExternallyInitialized) - : GlobalValue(PointerType::get(Ty, AddressSpace), - Value::GlobalVariableVal, - OperandTraits::op_begin(this), - InitVal != 0, Link, Name), - isConstantGlobal(constant), threadLocalMode(TLMode), - isExternallyInitializedConstant(isExternallyInitialized) { + : GlobalObject(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, + OperandTraits::op_begin(this), + InitVal != nullptr, Link, Name), + isConstantGlobal(constant), + isExternallyInitializedConstant(isExternallyInitialized) { + setThreadLocalMode(TLMode); if (InitVal) { assert(InitVal->getType() == Ty && "Initializer should be the same type as the GlobalVariable!"); Op<0>() = InitVal; } - + LeakDetector::addGarbageObject(this); - + if (Before) Before->getParent()->getGlobalList().insert(Before, this); else @@ -164,9 +225,9 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To, } void GlobalVariable::setInitializer(Constant *InitVal) { - if (InitVal == 0) { + if (!InitVal) { if (hasInitializer()) { - Op<0>().set(0); + Op<0>().set(nullptr); NumOperands = 0; } } else { @@ -182,9 +243,9 @@ void GlobalVariable::setInitializer(Constant *InitVal) { /// 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); + GlobalObject::copyAttributesFrom(Src); const GlobalVariable *SrcVar = cast(Src); - setThreadLocal(SrcVar->isThreadLocal()); + setThreadLocalMode(SrcVar->getThreadLocalMode()); } @@ -192,20 +253,47 @@ void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) { // GlobalAlias Implementation //===----------------------------------------------------------------------===// -GlobalAlias::GlobalAlias(Type *Ty, LinkageTypes Link, - const Twine &Name, Constant* aliasee, +GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link, + const Twine &Name, Constant *Aliasee, Module *ParentModule) - : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) { + : GlobalValue(PointerType::get(Ty, AddressSpace), 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; + Op<0>() = Aliasee; if (ParentModule) ParentModule->getAliasList().push_back(this); } +GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, + LinkageTypes Link, const Twine &Name, + Constant *Aliasee, Module *ParentModule) { + return new GlobalAlias(Ty, AddressSpace, Link, Name, Aliasee, ParentModule); +} + +GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, + LinkageTypes Linkage, const Twine &Name, + Module *Parent) { + return create(Ty, AddressSpace, Linkage, Name, nullptr, Parent); +} + +GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, + LinkageTypes Linkage, const Twine &Name, + GlobalValue *Aliasee) { + return create(Ty, AddressSpace, Linkage, Name, Aliasee, Aliasee->getParent()); +} + +GlobalAlias *GlobalAlias::create(LinkageTypes Link, const Twine &Name, + GlobalValue *Aliasee) { + PointerType *PTy = Aliasee->getType(); + return create(PTy->getElementType(), PTy->getAddressSpace(), Link, Name, + Aliasee); +} + +GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalValue *Aliasee) { + return create(Aliasee->getLinkage(), Name, Aliasee); +} + void GlobalAlias::setParent(Module *parent) { if (getParent()) LeakDetector::addGarbageObject(this); @@ -225,45 +313,5 @@ void GlobalAlias::eraseFromParent() { 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; -}