summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-05-16 13:02:18 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-05-16 13:02:18 +0000
commit21cfedee056a1e0789bbe6cafa23549d0ff16f24 (patch)
treeec91a01c03827b063b817116a403ec039408b40d /lib
parent2b3ef615cab1134cda3c41d448b470124705d734 (diff)
downloadllvm-21cfedee056a1e0789bbe6cafa23549d0ff16f24.tar.gz
llvm-21cfedee056a1e0789bbe6cafa23549d0ff16f24.tar.bz2
llvm-21cfedee056a1e0789bbe6cafa23549d0ff16f24.tar.xz
Revert "Implement global merge optimization for global variables."
This reverts commit r208934. The patch depends on aliases to GEPs with non zero offsets. That is not supported and fairly broken. The good news is that GlobalAlias is being redesigned and will have support for offsets, so this patch should be a nice match for it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208978 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp7
-rw-r--r--lib/IR/Globals.cpp25
-rw-r--r--lib/Target/AArch64/AArch64ISelLowering.cpp14
-rw-r--r--lib/Target/AArch64/AArch64ISelLowering.h4
-rw-r--r--lib/Target/ARM64/ARM64ISelLowering.cpp14
-rw-r--r--lib/Target/ARM64/ARM64ISelLowering.h4
-rw-r--r--lib/Transforms/Scalar/GlobalMerge.cpp85
-rw-r--r--lib/Transforms/Scalar/Scalar.cpp1
8 files changed, 12 insertions, 142 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 0c4865f2f2..37a2c3220c 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -946,11 +946,8 @@ bool AsmPrinter::doFinalization(Module &M) {
EmitVisibility(Name, Alias.getVisibility());
// Emit the directives as assignments aka .set:
- const MCExpr *Expr = MCSymbolRefExpr::Create(Target, OutContext);
- if (uint64_t Offset = Alias.calculateOffset(*TM.getDataLayout()))
- Expr = MCBinaryExpr::CreateAdd(Expr,
- MCConstantExpr::Create(Offset, OutContext), OutContext);
- OutStreamer.EmitAssignment(Name, Expr);
+ OutStreamer.EmitAssignment(Name,
+ MCSymbolRefExpr::Create(Target, OutContext));
}
}
diff --git a/lib/IR/Globals.cpp b/lib/IR/Globals.cpp
index d64046a7bf..0ec54fe3c0 100644
--- a/lib/IR/Globals.cpp
+++ b/lib/IR/Globals.cpp
@@ -15,7 +15,6 @@
#include "llvm/IR/GlobalValue.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
@@ -283,27 +282,3 @@ GlobalObject *GlobalAlias::getAliasedGlobal() {
return cast<GlobalObject>(GV);
}
}
-
-uint64_t GlobalAlias::calculateOffset(const DataLayout &DL) const {
- uint64_t Offset = 0;
- const Constant *C = this;
- while (C) {
- if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(C)) {
- C = GA->getAliasee();
- } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
- if (CE->getOpcode() == Instruction::GetElementPtr) {
- std::vector<Value*> Args;
- for (unsigned I = 1; I < CE->getNumOperands(); ++I)
- Args.push_back(CE->getOperand(I));
- Offset += DL.getIndexedOffset(CE->getOperand(0)->getType(), Args);
- }
- C = CE->getOperand(0);
- } else if (isa<GlobalValue>(C)) {
- return Offset;
- } else {
- assert(0 && "Unexpected type in alias chain!");
- return 0;
- }
- }
- return Offset;
-}
diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp
index a676600e5d..852d324476 100644
--- a/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -5560,17 +5560,3 @@ unsigned AArch64TargetLowering::getMaximalGlobalOffset() const {
return 4095;
}
-/// getGlobalMergeAlignment - Set alignment to be the max size of merged
-/// global variable data structure, and make it aligned up to power of 2.
-/// This way, we could guarantee the merged global variable data structure
-/// doesn't cross page boundary, because usually OS always allocates page at
-/// 4096-byte aligned boundary.
-unsigned AArch64TargetLowering::getGlobalMergeAlignment(
- StructType *MergedTy) const {
- unsigned Align = getDataLayout()->getTypeAllocSize(MergedTy);
- if (Align & (Align - 1))
- Align = llvm::NextPowerOf2(Align);
-
- return Align;
-}
-
diff --git a/lib/Target/AArch64/AArch64ISelLowering.h b/lib/Target/AArch64/AArch64ISelLowering.h
index 9818b7a2dc..070db94808 100644
--- a/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/lib/Target/AArch64/AArch64ISelLowering.h
@@ -386,10 +386,6 @@ public:
/// be used for loads / stores from the global.
unsigned getMaximalGlobalOffset() const override;
- /// getGlobalMergeAlignment - Set alignment to be the max size of merged
- /// global variable data structure, and make it aligned up to power of 2.
- unsigned getGlobalMergeAlignment(StructType *MergedTy) const override;
-
protected:
std::pair<const TargetRegisterClass*, uint8_t>
findRepresentativeClass(MVT VT) const override;
diff --git a/lib/Target/ARM64/ARM64ISelLowering.cpp b/lib/Target/ARM64/ARM64ISelLowering.cpp
index cb91185d26..3554fff28a 100644
--- a/lib/Target/ARM64/ARM64ISelLowering.cpp
+++ b/lib/Target/ARM64/ARM64ISelLowering.cpp
@@ -631,20 +631,6 @@ unsigned ARM64TargetLowering::getMaximalGlobalOffset() const {
return 4095;
}
-/// getGlobalMergeAlignment - Set alignment to be the max size of merged
-/// global variable data structure, and make it aligned up to power of 2.
-/// This way, we could guarantee the merged global variable data structure
-/// doesn't cross page boundary, because usually OS always allocates page at
-/// 4096-byte aligned boundary.
-unsigned ARM64TargetLowering::getGlobalMergeAlignment(
- StructType *MergedTy) const {
- unsigned Align = getDataLayout()->getTypeAllocSize(MergedTy);
- if (Align & (Align - 1))
- Align = llvm::NextPowerOf2(Align);
-
- return Align;
-}
-
FastISel *
ARM64TargetLowering::createFastISel(FunctionLoweringInfo &funcInfo,
const TargetLibraryInfo *libInfo) const {
diff --git a/lib/Target/ARM64/ARM64ISelLowering.h b/lib/Target/ARM64/ARM64ISelLowering.h
index f026e35b15..b2402c9791 100644
--- a/lib/Target/ARM64/ARM64ISelLowering.h
+++ b/lib/Target/ARM64/ARM64ISelLowering.h
@@ -238,10 +238,6 @@ public:
/// be used for loads / stores from the global.
unsigned getMaximalGlobalOffset() const override;
- /// getGlobalMergeAlignment - Set alignment to be the max size of merged
- /// global variable data structure, and make it aligned up to power of 2.
- unsigned getGlobalMergeAlignment(StructType *MergedTy) const override;
-
/// Returns true if a cast between SrcAS and DestAS is a noop.
bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override {
// Addrspacecasts are always noops.
diff --git a/lib/Transforms/Scalar/GlobalMerge.cpp b/lib/Transforms/Scalar/GlobalMerge.cpp
index 98061f5b9a..dd9c3784cc 100644
--- a/lib/Transforms/Scalar/GlobalMerge.cpp
+++ b/lib/Transforms/Scalar/GlobalMerge.cpp
@@ -72,7 +72,7 @@ using namespace llvm;
#define DEBUG_TYPE "global-merge"
static cl::opt<bool>
-EnableGlobalMerge("enable-global-merge", cl::NotHidden,
+EnableGlobalMerge("global-merge", cl::Hidden,
cl::desc("Enable global merge pass"),
cl::init(true));
@@ -81,16 +81,6 @@ EnableGlobalMergeOnConst("global-merge-on-const", cl::Hidden,
cl::desc("Enable global merge pass on constants"),
cl::init(false));
-static cl::opt<bool>
-EnableGlobalMergeOnExternal("global-merge-on-external", cl::Hidden,
- cl::desc("Enable global merge pass on external linkage"),
- cl::init(false));
-
-static cl::opt<bool>
-EnableGlobalMergeAligned("global-merge-aligned", cl::Hidden,
- cl::desc("Set target specific alignment for global merge pass"),
- cl::init(false));
-
STATISTIC(NumMerged , "Number of globals merged");
namespace {
class GlobalMerge : public FunctionPass {
@@ -139,21 +129,9 @@ namespace {
} // end anonymous namespace
char GlobalMerge::ID = 0;
+INITIALIZE_PASS(GlobalMerge, "global-merge",
+ "Global Merge", false, false)
-static void *initializeGlobalMergePassOnce(PassRegistry &Registry) {
- PassInfo *PI = new PassInfo(
- "Merge global variables",
- "global-merge", &GlobalMerge::ID,
- PassInfo::NormalCtor_t(callDefaultCtor<GlobalMerge>), false,
- false, PassInfo::TargetMachineCtor_t(
- callTargetMachineCtor<GlobalMerge>));
- Registry.registerPass(*PI, true);
- return PI;
-}
-
-void llvm::initializeGlobalMergePass(PassRegistry &Registry) {
- CALL_ONCE_INITIALIZATION(initializeGlobalMergePassOnce)
-}
bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
Module &M, bool isConst, unsigned AddrSpace) const {
@@ -176,16 +154,11 @@ bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
Type *Int32Ty = Type::getInt32Ty(M.getContext());
- assert (Globals.size() > 1);
-
for (size_t i = 0, e = Globals.size(); i != e; ) {
size_t j = 0;
uint64_t MergedSize = 0;
std::vector<Type*> Tys;
std::vector<Constant*> Inits;
-
- bool HasExternal = false;
- GlobalVariable *TheFirstExternal = 0;
for (j = i; j != e; ++j) {
Type *Ty = Globals[j]->getType()->getElementType();
MergedSize += DL->getTypeAllocSize(Ty);
@@ -194,45 +167,17 @@ bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
}
Tys.push_back(Ty);
Inits.push_back(Globals[j]->getInitializer());
-
- if (Globals[j]->hasExternalLinkage() && !HasExternal) {
- HasExternal = true;
- TheFirstExternal = Globals[j];
- }
}
- // If merged variables doesn't have external linkage, we needn't to expose
- // the symbol after merging.
- GlobalValue::LinkageTypes Linkage = HasExternal ?
- GlobalValue::ExternalLinkage :
- GlobalValue::InternalLinkage ;
-
- // If merged variables have external linkage, we use symbol name of the
- // first variable merged as the suffix of global symbol name. This would
- // be able to avoid the link-time naming conflict for globalm symbols.
- Twine MergedGVName = HasExternal ?
- "_MergedGlobals_" + TheFirstExternal->getName() :
- "_MergedGlobals" ;
-
StructType *MergedTy = StructType::get(M.getContext(), Tys);
Constant *MergedInit = ConstantStruct::get(MergedTy, Inits);
-
GlobalVariable *MergedGV = new GlobalVariable(M, MergedTy, isConst,
- Linkage, MergedInit, MergedGVName,
- nullptr, GlobalVariable::NotThreadLocal,
- AddrSpace);
-
- if (EnableGlobalMergeAligned) {
- unsigned Align = TLI->getGlobalMergeAlignment(MergedTy);
- assert(((Align % DL->getABITypeAlignment(MergedTy)) == 0) &&
- "Specified alignment doesn't meet natural alignment requirement.");
- MergedGV->setAlignment(Align);
- }
-
+ GlobalValue::InternalLinkage,
+ MergedInit, "_MergedGlobals",
+ nullptr,
+ GlobalVariable::NotThreadLocal,
+ AddrSpace);
for (size_t k = i; k < j; ++k) {
- GlobalValue::LinkageTypes Linkage = Globals[k]->getLinkage();
- std::string Name = Globals[k]->getName();
-
Constant *Idx[2] = {
ConstantInt::get(Int32Ty, 0),
ConstantInt::get(Int32Ty, k-i)
@@ -240,12 +185,6 @@ bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
Constant *GEP = ConstantExpr::getInBoundsGetElementPtr(MergedGV, Idx);
Globals[k]->replaceAllUsesWith(GEP);
Globals[k]->eraseFromParent();
-
- if (Linkage != GlobalValue::InternalLinkage) {
- // Generate a new alias...
- new GlobalAlias(GEP->getType(), Linkage, Name, GEP, &M);
- }
-
NumMerged++;
}
i = j;
@@ -306,12 +245,8 @@ bool GlobalMerge::doInitialization(Module &M) {
// Grab all non-const globals.
for (Module::global_iterator I = M.global_begin(),
E = M.global_end(); I != E; ++I) {
- // Merge is safe for "normal" internal or external globals only
- if (I->isDeclaration() || I->isThreadLocal() || I->hasSection())
- continue;
-
- if (!(EnableGlobalMergeOnExternal && I->hasExternalLinkage())
- && !I->hasInternalLinkage())
+ // Merge is safe for "normal" internal globals only
+ if (!I->hasLocalLinkage() || I->isThreadLocal() || I->hasSection())
continue;
PointerType *PT = dyn_cast<PointerType>(I->getType());
diff --git a/lib/Transforms/Scalar/Scalar.cpp b/lib/Transforms/Scalar/Scalar.cpp
index 2cca725480..f8f828c840 100644
--- a/lib/Transforms/Scalar/Scalar.cpp
+++ b/lib/Transforms/Scalar/Scalar.cpp
@@ -38,7 +38,6 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
initializeDSEPass(Registry);
initializeGVNPass(Registry);
initializeEarlyCSEPass(Registry);
- initializeGlobalMergePass(Registry);
initializeIndVarSimplifyPass(Registry);
initializeJumpThreadingPass(Registry);
initializeLICMPass(Registry);