From: Rafael Espindola Date: Tue, 13 May 2014 18:45:48 +0000 (+0000) Subject: Split GlobalValue into GlobalValue and GlobalObject. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=834384bf5bd3c104e352d3ef4956541f5932529c;p=oota-llvm.git Split GlobalValue into GlobalValue and GlobalObject. This allows code to statically accept a Function or a GlobalVariable, but not an alias. This is already a cleanup by itself IMHO, but the main reason for it is that it gives a lot more confidence that the refactoring to fix the design of GlobalAlias is correct. That will be a followup patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208716 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index f7121a5c61a..cd9263d4914 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -1173,9 +1173,10 @@ LLVMTypeRef LLVMX86MMXType(void); macro(ConstantStruct) \ macro(ConstantVector) \ macro(GlobalValue) \ - macro(Function) \ macro(GlobalAlias) \ - macro(GlobalVariable) \ + macro(GlobalObject) \ + macro(Function) \ + macro(GlobalVariable) \ macro(UndefValue) \ macro(Instruction) \ macro(BinaryOperator) \ diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index d5c3e721b09..b53fb423d82 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -233,7 +233,7 @@ public: /// requested, it will override the alignment request if required for /// correctness. /// - void EmitAlignment(unsigned NumBits, const GlobalValue *GV = nullptr) const; + void EmitAlignment(unsigned NumBits, const GlobalObject *GO = nullptr) const; /// This method prints the label for the specified MachineBasicBlock, an /// alignment (if present) and a comment describing it if appropriate. diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index 3566002ae1d..22444bd3000 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -23,7 +23,7 @@ #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallingConv.h" -#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/GlobalObject.h" #include "llvm/Support/Compiler.h" namespace llvm { @@ -68,7 +68,7 @@ private: mutable ilist_half_node Sentinel; }; -class Function : public GlobalValue, public ilist_node { +class Function : public GlobalObject, public ilist_node { public: typedef iplist ArgumentListType; typedef iplist BasicBlockListType; diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h index ad02996e2dc..5aa42612562 100644 --- a/include/llvm/IR/GlobalAlias.h +++ b/include/llvm/IR/GlobalAlias.h @@ -68,8 +68,8 @@ public: /// This method tries to ultimately resolve the alias by going through the /// aliasing chain and trying to find the very last global. Returns NULL if a /// cycle was found. - GlobalValue *getAliasedGlobal(); - const GlobalValue *getAliasedGlobal() const { + GlobalObject *getAliasedGlobal(); + const GlobalObject *getAliasedGlobal() const { return const_cast(this)->getAliasedGlobal(); } diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h new file mode 100644 index 00000000000..3bc8b8531dd --- /dev/null +++ b/include/llvm/IR/GlobalObject.h @@ -0,0 +1,58 @@ +//===-- llvm/GlobalObject.h - Class to represent a global object *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This represents an independent object. That is, a function or a global +// variable, but not an alias. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_GLOBALOBJECT_H +#define LLVM_IR_GLOBALOBJECT_H + +#include "llvm/IR/Constant.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/GlobalValue.h" + +namespace llvm { + +class Module; + +class GlobalObject : public GlobalValue { + GlobalObject(const GlobalObject &) LLVM_DELETED_FUNCTION; + +protected: + GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, + LinkageTypes Linkage, const Twine &Name) + : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name) { + setGlobalValueSubClassData(0); + } + + std::string Section; // Section to emit this into, empty means default +public: + unsigned getAlignment() const { + return (1u << getGlobalValueSubClassData()) >> 1; + } + void setAlignment(unsigned Align); + + bool hasSection() const { return !getSection().empty(); } + const std::string &getSection() const { return Section; } + void setSection(StringRef S); + + void copyAttributesFrom(const GlobalValue *Src) override; + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Value *V) { + return V->getValueID() == Value::FunctionVal || + V->getValueID() == Value::GlobalVariableVal; + } +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index 4d0d5e181f8..0ed302cdb4b 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -62,7 +62,7 @@ protected: GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, LinkageTypes Linkage, const Twine &Name) : Constant(Ty, VTy, Ops, NumOps), Linkage(Linkage), - Visibility(DefaultVisibility), Alignment(0), UnnamedAddr(0), + Visibility(DefaultVisibility), UnnamedAddr(0), DllStorageClass(DefaultStorageClass), Parent(nullptr) { setName(Name); } @@ -71,18 +71,29 @@ protected: // Linkage and Visibility from turning into negative values. LinkageTypes Linkage : 5; // The linkage of this global unsigned Visibility : 2; // The visibility style of this global - unsigned Alignment : 16; // Alignment of this symbol, must be power of two unsigned UnnamedAddr : 1; // This value's address is not significant unsigned DllStorageClass : 2; // DLL storage class + +private: + // Give subclasses access to what otherwise would be wasted padding. + // (22 + 2 + 1 + 2 + 5) == 32. + unsigned SubClassData : 22; +protected: + unsigned getGlobalValueSubClassData() const { + return SubClassData; + } + void setGlobalValueSubClassData(unsigned V) { + assert(V < (1 << 22) && "It will not fit"); + SubClassData = V; + } + Module *Parent; // The containing module. - std::string Section; // Section to emit this into, empty mean default public: ~GlobalValue() { removeDeadConstantUsers(); // remove any dead constants using this. } unsigned getAlignment() const; - void setAlignment(unsigned Align); bool hasUnnamedAddr() const { return UnnamedAddr; } void setUnnamedAddr(bool Val) { UnnamedAddr = Val; } @@ -112,7 +123,6 @@ public: bool hasSection() const { return !getSection().empty(); } const std::string &getSection() const; - void setSection(StringRef S); /// Global values are always pointers. inline PointerType *getType() const { diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h index d73e8262258..8cd4332b1ad 100644 --- a/include/llvm/IR/GlobalVariable.h +++ b/include/llvm/IR/GlobalVariable.h @@ -22,7 +22,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/ADT/ilist_node.h" -#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/GlobalObject.h" #include "llvm/IR/OperandTraits.h" namespace llvm { @@ -32,7 +32,7 @@ class Constant; template class SymbolTableListTraits; -class GlobalVariable : public GlobalValue, public ilist_node { +class GlobalVariable : public GlobalObject, public ilist_node { friend class SymbolTableListTraits; void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; void operator=(const GlobalVariable &) LLVM_DELETED_FUNCTION; diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index 7108af564f8..01586831bc4 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -31,6 +31,7 @@ class Constant; class DataLayout; class Function; class GlobalAlias; +class GlobalObject; class GlobalValue; class GlobalVariable; class InlineAsm; @@ -526,8 +527,13 @@ template <> struct isa_impl { template <> struct isa_impl { static inline bool doit(const Value &Val) { - return isa(Val) || isa(Val) || - isa(Val); + return isa(Val) || isa(Val); + } +}; + +template <> struct isa_impl { + static inline bool doit(const Value &Val) { + return isa(Val) || isa(Val); } }; diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 331381b0273..37a2c3220cb 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1458,7 +1458,7 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, // an explicit alignment requested, it will override the alignment request // if required for correctness. // -void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const { +void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalObject *GV) const { if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getDataLayout(), NumBits); if (NumBits == 0) return; // 1-byte aligned: no need to emit alignment. diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index e5b98b89db6..e3a445800c7 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -1307,7 +1307,7 @@ const char *LLVMGetSection(LLVMValueRef Global) { } void LLVMSetSection(LLVMValueRef Global, const char *Section) { - unwrap(Global)->setSection(Section); + unwrap(Global)->setSection(Section); } LLVMVisibility LLVMGetVisibility(LLVMValueRef Global) { @@ -1357,7 +1357,7 @@ unsigned LLVMGetAlignment(LLVMValueRef V) { void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) { Value *P = unwrap(V); - if (GlobalValue *GV = dyn_cast(P)) + if (GlobalObject *GV = dyn_cast(P)) GV->setAlignment(Bytes); else if (AllocaInst *AI = dyn_cast(P)) AI->setAlignment(Bytes); diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index c1a09686b02..de8e66f1bca 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -209,7 +209,7 @@ void Function::eraseFromParent() { Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name, Module *ParentModule) - : GlobalValue(PointerType::getUnqual(Ty), + : GlobalObject(PointerType::getUnqual(Ty), Value::FunctionVal, nullptr, 0, Linkage, name) { assert(FunctionType::isValidReturnType(getReturnType()) && "invalid return type"); @@ -361,7 +361,7 @@ void Function::clearGC() { /// create a Function) from the Function Src to this one. void Function::copyAttributesFrom(const GlobalValue *Src) { assert(isa(Src) && "Expected a Function!"); - GlobalValue::copyAttributesFrom(Src); + GlobalObject::copyAttributesFrom(Src); const Function *SrcF = cast(Src); setCallingConv(SrcF->getCallingConv()); setAttributes(SrcF->getAttributes()); diff --git a/lib/IR/Globals.cpp b/lib/IR/Globals.cpp index 0138a223817..0ec54fe3c08 100644 --- a/lib/IR/Globals.cpp +++ b/lib/IR/Globals.cpp @@ -53,11 +53,6 @@ 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) { - if (!isa(this)) { - setAlignment(Src->getAlignment()); - setSection(Src->getSection()); - } - setVisibility(Src->getVisibility()); setUnnamedAddr(Src->hasUnnamedAddr()); setDLLStorageClass(Src->getDLLStorageClass()); @@ -67,29 +62,31 @@ unsigned GlobalValue::getAlignment() const { if (auto *GA = dyn_cast(this)) return GA->getAliasedGlobal()->getAlignment(); - return (1u << Alignment) >> 1; + return cast(this)->getAlignment(); } -void GlobalValue::setAlignment(unsigned Align) { - assert((!isa(this)) && - "GlobalAlias should not have an alignment!"); +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; + setGlobalValueSubClassData(Log2_32(Align) + 1); assert(getAlignment() == Align && "Alignment representation error!"); } +void GlobalObject::copyAttributesFrom(const GlobalValue *Src) { + const auto *GV = cast(Src); + GlobalValue::copyAttributesFrom(GV); + setAlignment(GV->getAlignment()); + setSection(GV->getSection()); +} + const std::string &GlobalValue::getSection() const { if (auto *GA = dyn_cast(this)) return GA->getAliasedGlobal()->getSection(); - return Section; + return cast(this)->getSection(); } -void GlobalValue::setSection(StringRef S) { - assert(!isa(this) && "GlobalAlias should not have a section!"); - Section = S; -} +void GlobalObject::setSection(StringRef S) { Section = S; } bool GlobalValue::isDeclaration() const { // Globals are definitions if they have an initializer. @@ -113,9 +110,9 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link, Constant *InitVal, const Twine &Name, ThreadLocalMode TLMode, unsigned AddressSpace, bool isExternallyInitialized) - : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, - OperandTraits::op_begin(this), - InitVal != nullptr, Link, Name), + : GlobalObject(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, + OperandTraits::op_begin(this), + InitVal != nullptr, Link, Name), isConstantGlobal(constant), threadLocalMode(TLMode), isExternallyInitializedConstant(isExternallyInitialized) { if (InitVal) { @@ -132,9 +129,9 @@ GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant, const Twine &Name, GlobalVariable *Before, ThreadLocalMode TLMode, unsigned AddressSpace, bool isExternallyInitialized) - : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, - OperandTraits::op_begin(this), - InitVal != nullptr, Link, Name), + : GlobalObject(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, + OperandTraits::op_begin(this), + InitVal != nullptr, Link, Name), isConstantGlobal(constant), threadLocalMode(TLMode), isExternallyInitializedConstant(isExternallyInitialized) { if (InitVal) { @@ -206,7 +203,7 @@ 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); setThreadLocalMode(SrcVar->getThreadLocalMode()); } @@ -269,7 +266,7 @@ static GlobalValue *getAliaseeGV(GlobalAlias *GA) { return cast(CE->getOperand(0)); } -GlobalValue *GlobalAlias::getAliasedGlobal() { +GlobalObject *GlobalAlias::getAliasedGlobal() { SmallPtrSet Visited; GlobalAlias *GA = this; @@ -282,6 +279,6 @@ GlobalValue *GlobalAlias::getAliasedGlobal() { // Iterate over aliasing chain. GA = dyn_cast(GV); if (!GA) - return GV; + return cast(GV); } } diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index b742492da0e..820f3acacef 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -495,15 +495,15 @@ static void forceRenaming(GlobalValue *GV, StringRef Name) { /// a GlobalValue) from the SrcGV to the DestGV. static void copyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) { // Use the maximum alignment, rather than just copying the alignment of SrcGV. + auto *DestGO = dyn_cast(DestGV); unsigned Alignment; - bool IsAlias = isa(DestGV); - if (!IsAlias) - Alignment = std::max(DestGV->getAlignment(), SrcGV->getAlignment()); + if (DestGO) + Alignment = std::max(DestGO->getAlignment(), SrcGV->getAlignment()); DestGV->copyAttributesFrom(SrcGV); - if (!IsAlias) - DestGV->setAlignment(Alignment); + if (DestGO) + DestGO->setAlignment(Alignment); forceRenaming(DestGV, SrcGV->getName()); } diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index d6db61b6759..4bda885f22c 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -896,26 +896,26 @@ static unsigned enforceKnownAlignment(Value *V, unsigned Align, return PrefAlign; } - if (auto *GV = dyn_cast(V)) { + if (auto *GO = dyn_cast(V)) { // If there is a large requested alignment and we can, bump up the alignment // of the global. - if (GV->isDeclaration()) + if (GO->isDeclaration()) return Align; // If the memory we set aside for the global may not be the memory used by // the final program then it is impossible for us to reliably enforce the // preferred alignment. - if (GV->isWeakForLinker()) + if (GO->isWeakForLinker()) return Align; - if (GV->getAlignment() >= PrefAlign) - return GV->getAlignment(); + if (GO->getAlignment() >= PrefAlign) + return GO->getAlignment(); // We can only increase the alignment of the global if it has no alignment // specified or if it is not assigned a section. If it is assigned a // section, the global could be densely packed with other objects in the // section, increasing the alignment could cause padding issues. - if (!GV->hasSection() || GV->getAlignment() == 0) - GV->setAlignment(PrefAlign); - return GV->getAlignment(); + if (!GO->hasSection() || GO->getAlignment() == 0) + GO->setAlignment(PrefAlign); + return GO->getAlignment(); } return Align;