54 #define DEBUG_TYPE "global-merge"
75 cl::desc(
"Enable global merge pass on constants"),
78 STATISTIC(NumMerged ,
"Number of globals merged");
84 Module &M,
bool isConst,
unsigned AddrSpace)
const;
90 return MustKeepGlobalVariables.count(GV);
95 void setMustKeepGlobalVariables(
Module &M);
110 virtual bool doInitialization(
Module &M);
112 virtual bool doFinalization(
Module &M);
114 const char *getPassName()
const {
115 return "Merge internal globals";
129 Type *Ty1 = cast<PointerType>(GV1->
getType())->getElementType();
130 Type *Ty2 = cast<PointerType>(GV2->
getType())->getElementType();
132 return (
TD->getTypeAllocSize(Ty1) <
TD->getTypeAllocSize(Ty2));
140 "Global Merge",
false,
false)
144 Module &M,
bool isConst,
unsigned AddrSpace)
const {
154 std::stable_sort(Globals.begin(), Globals.end(), GlobalCmp(TD));
158 for (
size_t i = 0, e = Globals.size(); i != e; ) {
160 uint64_t MergedSize = 0;
161 std::vector<Type*> Tys;
162 std::vector<Constant*> Inits;
163 for (j = i; j != e; ++j) {
164 Type *Ty = Globals[j]->getType()->getElementType();
166 if (MergedSize > MaxOffset) {
170 Inits.push_back(Globals[j]->getInitializer());
177 MergedInit,
"_MergedGlobals",
180 for (
size_t k = i; k < j; ++k) {
186 Globals[k]->replaceAllUsesWith(GEP);
187 Globals[k]->eraseFromParent();
207 MustKeepGlobalVariables.insert(
G);
210 void GlobalMerge::setMustKeepGlobalVariables(
Module &M) {
216 IBB != IEndBB; ++IBB) {
224 Idx != NumClauses; ++Idx)
226 dyn_cast<GlobalVariable>(LPInst->
getClause(Idx)
228 MustKeepGlobalVariables.insert(GV);
233 bool GlobalMerge::doInitialization(
Module &M) {
239 bool Changed =
false;
240 setMustKeepGlobalVariables(M);
246 if (!
I->hasLocalLinkage() ||
I->isThreadLocal() ||
I->hasSection())
250 assert(PT &&
"Global variable is not a pointer!");
256 Type *Ty =
I->getType()->getElementType();
261 if (
I->getName().startswith(
"llvm.") ||
262 I->getName().startswith(
".llvm."))
266 if (isMustKeepGlobalVariable(
I))
272 BSSGlobals[AddressSpace].push_back(
I);
273 else if (
I->isConstant())
274 ConstGlobals[AddressSpace].push_back(
I);
281 I = Globals.
begin(), E = Globals.
end();
I != E; ++
I)
282 if (
I->second.size() > 1)
283 Changed |= doMerge(
I->second, M,
false,
I->first);
286 I = BSSGlobals.
begin(), E = BSSGlobals.
end();
I != E; ++
I)
287 if (
I->second.size() > 1)
288 Changed |= doMerge(
I->second, M,
false,
I->first);
292 I = ConstGlobals.
begin(), E = ConstGlobals.
end();
I != E; ++
I)
293 if (
I->second.size() > 1)
294 Changed |= doMerge(
I->second, M,
true,
I->first);
299 bool GlobalMerge::runOnFunction(
Function &
F) {
303 bool GlobalMerge::doFinalization(
Module &M) {
304 MustKeepGlobalVariables.clear();
309 return new GlobalMerge(TM);
static SectionKind getKindForGlobal(const GlobalValue *GV, const TargetMachine &TM)
static PassRegistry * getPassRegistry()
The main container class for the LLVM Intermediate Representation.
const TargetMachine & getTargetMachine() const
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getNumOperands() const
virtual void getAnalysisUsage(AnalysisUsage &) const
unsigned getAddressSpace() const
Return the address space of the Pointer type.
const Constant * getInitializer() const
const GlobalVariable * getGlobalVariable(StringRef Name, bool AllowInternal=false) const
This file contains the simple types necessary to represent the attributes associated with functions a...
ID
LLVM Calling Convention Representation.
global_iterator global_begin()
unsigned getNumClauses() const
getNumClauses - Get the number of clauses for this landing pad.
virtual unsigned getMaximalGlobalOffset() const
Pass * createGlobalMergePass(const TargetMachine *TM=0)
STATISTIC(NumMerged,"Number of globals merged")
Value * getClause(unsigned Idx) const
initializer< Ty > init(const Ty &Val)
LLVM Constant Representation.
LandingPadInst * getLandingPadInst()
Return the landingpad instruction associated with the landing pad.
const DataLayout * getDataLayout() const
Value * getOperand(unsigned i) const
static Constant * get(StructType *T, ArrayRef< Constant * > V)
unsigned getPreferredAlignment(const GlobalVariable *GV) const
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
global_iterator global_end()
unsigned getABITypeAlignment(Type *Ty) const
BasicBlock * getUnwindDest() const
uint64_t getTypeAllocSize(Type *Ty) const
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
Value * stripPointerCasts()
Strips off any unneeded pointer casts, all-zero GEPs and aliases from the specified value...
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
bool hasInitializer() const
PointerType * getType() const
getType - Global values are always pointers.
static Constant * getInBoundsGetElementPtr(Constant *C, ArrayRef< Constant * > IdxList)
static IntegerType * getInt32Ty(LLVMContext &C)
Rename collisions when linking (static functions).
static cl::opt< bool > EnableGlobalMergeOnConst("global-merge-on-const", cl::Hidden, cl::desc("Enable global merge pass on constants"), cl::init(false))
void initializeGlobalMergePass(PassRegistry &)
GlobalVariable * collectUsedGlobalVariables(Module &M, SmallPtrSet< GlobalValue *, 8 > &Set, bool CompilerUsed)
Given "llvm.used" or "llvm.compiler.used" as a global name, collect the initializer elements of that ...
INITIALIZE_PASS(GlobalMerge,"global-merge","Global Merge", false, false) bool GlobalMerge const DataLayout * TD