X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FIR%2FGlobals.cpp;h=5a6adb3f304555324e9c6510b29ef75d19970258;hb=a716c07147b6c2674a3c0a8008f13abec4055baa;hp=2e52aa302867bf321a4f803d68b49c41b4219391;hpb=0b8c9a80f20772c3793201ab5b251d3520b9cea3;p=oota-llvm.git diff --git a/lib/IR/Globals.cpp b/lib/IR/Globals.cpp index 2e52aa30286..5a6adb3f304 100644 --- a/lib/IR/Globals.cpp +++ b/lib/IR/Globals.cpp @@ -19,8 +19,8 @@ #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.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,13 +28,15 @@ 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); @@ -49,20 +51,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,52 +128,51 @@ 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) - : GlobalValue(PointerType::get(Ty, AddressSpace), - Value::GlobalVariableVal, - OperandTraits::op_begin(this), - InitVal != 0, Link, Name), - isConstantGlobal(constant), threadLocalMode(TLMode) { + ThreadLocalMode TLMode, unsigned AddressSpace, + bool 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); } 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) { + const Twine &Name, GlobalVariable *Before, + ThreadLocalMode TLMode, unsigned AddressSpace, + bool 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 @@ -123,11 +180,7 @@ GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant, } void GlobalVariable::setParent(Module *parent) { - if (getParent()) - LeakDetector::addGarbageObject(this); Parent = parent; - if (getParent()) - LeakDetector::removeGarbageObject(this); } void GlobalVariable::removeFromParent() { @@ -159,9 +212,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 { @@ -177,9 +230,10 @@ 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()); + setExternallyInitialized(SrcVar->isExternallyInitialized()); } @@ -187,26 +241,48 @@ 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) { - LeakDetector::addGarbageObject(this); - - if (aliasee) - assert(aliasee->getType() == Ty && "Alias and aliasee types should match!"); - Op<0>() = aliasee; + : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalAliasVal, + &Op<0>(), 1, Link, Name) { + 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); Parent = parent; - if (getParent()) - LeakDetector::removeGarbageObject(this); } void GlobalAlias::removeFromParent() { @@ -220,45 +296,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; -}