summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm-c/Core.h5
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h2
-rw-r--r--include/llvm/IR/Function.h4
-rw-r--r--include/llvm/IR/GlobalAlias.h4
-rw-r--r--include/llvm/IR/GlobalObject.h58
-rw-r--r--include/llvm/IR/GlobalValue.h20
-rw-r--r--include/llvm/IR/GlobalVariable.h4
-rw-r--r--include/llvm/IR/Value.h10
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp2
-rw-r--r--lib/IR/Core.cpp4
-rw-r--r--lib/IR/Function.cpp4
-rw-r--r--lib/IR/Globals.cpp45
-rw-r--r--lib/Linker/LinkModules.cpp10
-rw-r--r--lib/Transforms/Utils/Local.cpp16
14 files changed, 130 insertions, 58 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index f7121a5c61..cd9263d491 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 d5c3e721b0..b53fb423d8 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 3566002ae1..22444bd300 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<Argument> Sentinel;
};
-class Function : public GlobalValue, public ilist_node<Function> {
+class Function : public GlobalObject, public ilist_node<Function> {
public:
typedef iplist<Argument> ArgumentListType;
typedef iplist<BasicBlock> BasicBlockListType;
diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h
index ad02996e2d..5aa4261256 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<GlobalAlias *>(this)->getAliasedGlobal();
}
diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h
new file mode 100644
index 0000000000..3bc8b8531d
--- /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 4d0d5e181f..0ed302cdb4 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 d73e826225..8cd4332b1a 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<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
-class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable> {
+class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
friend class SymbolTableListTraits<GlobalVariable, Module>;
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 7108af564f..01586831bc 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<GlobalAlias, Value> {
template <> struct isa_impl<GlobalValue, Value> {
static inline bool doit(const Value &Val) {
- return isa<GlobalVariable>(Val) || isa<Function>(Val) ||
- isa<GlobalAlias>(Val);
+ return isa<GlobalObject>(Val) || isa<GlobalAlias>(Val);
+ }
+};
+
+template <> struct isa_impl<GlobalObject, Value> {
+ static inline bool doit(const Value &Val) {
+ return isa<GlobalVariable>(Val) || isa<Function>(Val);
}
};
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 331381b027..37a2c3220c 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 e5b98b89db..e3a445800c 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<GlobalValue>(Global)->setSection(Section);
+ unwrap<GlobalObject>(Global)->setSection(Section);
}
LLVMVisibility LLVMGetVisibility(LLVMValueRef Global) {
@@ -1357,7 +1357,7 @@ unsigned LLVMGetAlignment(LLVMValueRef V) {
void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) {
Value *P = unwrap<Value>(V);
- if (GlobalValue *GV = dyn_cast<GlobalValue>(P))
+ if (GlobalObject *GV = dyn_cast<GlobalObject>(P))
GV->setAlignment(Bytes);
else if (AllocaInst *AI = dyn_cast<AllocaInst>(P))
AI->setAlignment(Bytes);
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp
index c1a09686b0..de8e66f1bc 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<Function>(Src) && "Expected a Function!");
- GlobalValue::copyAttributesFrom(Src);
+ GlobalObject::copyAttributesFrom(Src);
const Function *SrcF = cast<Function>(Src);
setCallingConv(SrcF->getCallingConv());
setAttributes(SrcF->getAttributes());
diff --git a/lib/IR/Globals.cpp b/lib/IR/Globals.cpp
index 0138a22381..0ec54fe3c0 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<GlobalAlias>(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<GlobalAlias>(this))
return GA->getAliasedGlobal()->getAlignment();
- return (1u << Alignment) >> 1;
+ return cast<GlobalObject>(this)->getAlignment();
}
-void GlobalValue::setAlignment(unsigned Align) {
- assert((!isa<GlobalAlias>(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<GlobalObject>(Src);
+ GlobalValue::copyAttributesFrom(GV);
+ setAlignment(GV->getAlignment());
+ setSection(GV->getSection());
+}
+
const std::string &GlobalValue::getSection() const {
if (auto *GA = dyn_cast<GlobalAlias>(this))
return GA->getAliasedGlobal()->getSection();
- return Section;
+ return cast<GlobalObject>(this)->getSection();
}
-void GlobalValue::setSection(StringRef S) {
- assert(!isa<GlobalAlias>(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<GlobalVariable>::op_begin(this),
- InitVal != nullptr, Link, Name),
+ : GlobalObject(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
+ OperandTraits<GlobalVariable>::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<GlobalVariable>::op_begin(this),
- InitVal != nullptr, Link, Name),
+ : GlobalObject(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
+ OperandTraits<GlobalVariable>::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<GlobalVariable>(Src) && "Expected a GlobalVariable!");
- GlobalValue::copyAttributesFrom(Src);
+ GlobalObject::copyAttributesFrom(Src);
const GlobalVariable *SrcVar = cast<GlobalVariable>(Src);
setThreadLocalMode(SrcVar->getThreadLocalMode());
}
@@ -269,7 +266,7 @@ static GlobalValue *getAliaseeGV(GlobalAlias *GA) {
return cast<GlobalValue>(CE->getOperand(0));
}
-GlobalValue *GlobalAlias::getAliasedGlobal() {
+GlobalObject *GlobalAlias::getAliasedGlobal() {
SmallPtrSet<GlobalValue*, 3> Visited;
GlobalAlias *GA = this;
@@ -282,6 +279,6 @@ GlobalValue *GlobalAlias::getAliasedGlobal() {
// Iterate over aliasing chain.
GA = dyn_cast<GlobalAlias>(GV);
if (!GA)
- return GV;
+ return cast<GlobalObject>(GV);
}
}
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index b742492da0..820f3acace 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<GlobalObject>(DestGV);
unsigned Alignment;
- bool IsAlias = isa<GlobalAlias>(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 d6db61b675..4bda885f22 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<GlobalValue>(V)) {
+ if (auto *GO = dyn_cast<GlobalObject>(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;