summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSilviu Baranga <silviu.baranga@arm.com>2013-01-07 12:31:25 +0000
committerSilviu Baranga <silviu.baranga@arm.com>2013-01-07 12:31:25 +0000
commite97165901ee51216b22b808041b10febbb4afa5e (patch)
treec8fa4a5bb21e8d3a6279e44647b012f6771f6d7e
parenta1e7530bb4a7aa8626f36a77be77fccade1d0b34 (diff)
downloadllvm-e97165901ee51216b22b808041b10febbb4afa5e.tar.gz
llvm-e97165901ee51216b22b808041b10febbb4afa5e.tar.bz2
llvm-e97165901ee51216b22b808041b10febbb4afa5e.tar.xz
Make the MergeGlobals pass correctly handle the address space qualifiers of the global variables. We partition the set of globals by their address space, and apply the same the trasnformation as before to merge them.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171730 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/GlobalMerge.cpp35
-rw-r--r--test/CodeGen/ARM/global-merge-addrspace.ll12
2 files changed, 36 insertions, 11 deletions
diff --git a/lib/Transforms/Scalar/GlobalMerge.cpp b/lib/Transforms/Scalar/GlobalMerge.cpp
index d9ce74eb54..1601a8d646 100644
--- a/lib/Transforms/Scalar/GlobalMerge.cpp
+++ b/lib/Transforms/Scalar/GlobalMerge.cpp
@@ -76,7 +76,7 @@ namespace {
const TargetLowering *TLI;
bool doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
- Module &M, bool isConst) const;
+ Module &M, bool isConst, unsigned AddrSpace) const;
public:
static char ID; // Pass identification, replacement for typeid.
@@ -118,7 +118,7 @@ INITIALIZE_PASS(GlobalMerge, "global-merge",
bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
- Module &M, bool isConst) const {
+ Module &M, bool isConst, unsigned AddrSpace) const {
const DataLayout *TD = TLI->getDataLayout();
// FIXME: Infer the maximum possible offset depending on the actual users
@@ -150,7 +150,9 @@ bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
Constant *MergedInit = ConstantStruct::get(MergedTy, Inits);
GlobalVariable *MergedGV = new GlobalVariable(M, MergedTy, isConst,
GlobalValue::InternalLinkage,
- MergedInit, "_MergedGlobals");
+ MergedInit, "_MergedGlobals",
+ 0, GlobalVariable::NotThreadLocal,
+ AddrSpace);
for (size_t k = i; k < j; ++k) {
Constant *Idx[2] = {
ConstantInt::get(Int32Ty, 0),
@@ -169,7 +171,8 @@ bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
bool GlobalMerge::doInitialization(Module &M) {
- SmallVector<GlobalVariable*, 16> Globals, ConstGlobals, BSSGlobals;
+ DenseMap<unsigned, SmallVector<GlobalVariable*, 16> > Globals, ConstGlobals,
+ BSSGlobals;
const DataLayout *TD = TLI->getDataLayout();
unsigned MaxOffset = TLI->getMaximalGlobalOffset();
bool Changed = false;
@@ -181,6 +184,11 @@ bool GlobalMerge::doInitialization(Module &M) {
if (!I->hasLocalLinkage() || I->isThreadLocal() || I->hasSection())
continue;
+ PointerType *PT = dyn_cast<PointerType>(I->getType());
+ assert(PT && "Global variable is not a pointer!");
+
+ unsigned AddressSpace = PT->getAddressSpace();
+
// Ignore fancy-aligned globals for now.
unsigned Alignment = TD->getPreferredAlignment(I);
Type *Ty = I->getType()->getElementType();
@@ -195,18 +203,23 @@ bool GlobalMerge::doInitialization(Module &M) {
if (TD->getTypeAllocSize(Ty) < MaxOffset) {
if (TargetLoweringObjectFile::getKindForGlobal(I, TLI->getTargetMachine())
.isBSSLocal())
- BSSGlobals.push_back(I);
+ BSSGlobals[AddressSpace].push_back(I);
else if (I->isConstant())
- ConstGlobals.push_back(I);
+ ConstGlobals[AddressSpace].push_back(I);
else
- Globals.push_back(I);
+ Globals[AddressSpace].push_back(I);
}
}
- if (Globals.size() > 1)
- Changed |= doMerge(Globals, M, false);
- if (BSSGlobals.size() > 1)
- Changed |= doMerge(BSSGlobals, M, false);
+ for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator
+ I = Globals.begin(), E = Globals.end(); I != E; ++I)
+ if (I->second.size() > 1)
+ Changed |= doMerge(I->second, M, false, I->first);
+
+ for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator
+ I = BSSGlobals.begin(), E = BSSGlobals.end(); I != E; ++I)
+ if (I->second.size() > 1)
+ Changed |= doMerge(I->second, M, false, I->first);
// FIXME: This currently breaks the EH processing due to way how the
// typeinfo detection works. We might want to detect the TIs and ignore
diff --git a/test/CodeGen/ARM/global-merge-addrspace.ll b/test/CodeGen/ARM/global-merge-addrspace.ll
new file mode 100644
index 0000000000..0efa690bde
--- /dev/null
+++ b/test/CodeGen/ARM/global-merge-addrspace.ll
@@ -0,0 +1,12 @@
+; RUN: llc < %s -mtriple=thumb-apple-darwin | FileCheck %s
+; Test the GlobalMerge pass. Check that the pass does not crash when using
+; multiple address spaces.
+
+; CHECK: _MergedGlobals:
+@g1 = internal addrspace(1) global i32 1
+@g2 = internal addrspace(1) global i32 2
+
+
+; CHECK: _MergedGlobals1:
+@g3 = internal addrspace(2) global i32 3
+@g4 = internal addrspace(2) global i32 4