<div dir="ltr">Hi Rafael,<div><br></div><div>Sorry for any inconvenience caused! I'm OK if you want to revert this commit, and also thanks for your kindly help to port it to the new GlobalValue alias anyway.</div><div>
<br></div><div>Thanks,</div><div>-Jiangning</div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-05-16 11:43 GMT+08:00 Rafael Espíndola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Sorry I missed this, but this uses a aliases pointing to GEPs. That is<br>
not supported and is currently fully broken:<br>
<br>
$ cat test.ll<br>
@foo = global [1 x i32] zeroinitializer<br>
<br>
@bar = alias getelementptr ([1 x i32]* @foo, i32 1, i32 1)<br>
<br>
$ llvm-as test.ll -o - | llvm-dis -o -<br>
@foo = global [1 x i32] zeroinitializer<br>
<br>
@bar = alias getelementptr ([1 x i32]* @foo, i64 2, i32 0)<br>
<br>
<br>
The good news is that I found this while rebasing my fix for pr10367<br>
which just got LGTMed and should allow this to be correctly supported<br>
by adding and explicit offset for aliases.<br>
<br>
Since this is off by default anyway, I hope you don't mind If I revert<br>
this tomorrow morning. I volunteer to help you port it to the new<br>
alias :-)<br>
<br>
Cheers,<br>
Rafael<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
On 15 May 2014 19:45, Jiangning Liu <<a href="mailto:jiangning.liu@arm.com">jiangning.liu@arm.com</a>> wrote:<br>
> Author: jiangning<br>
> Date: Thu May 15 18:45:42 2014<br>
> New Revision: 208934<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=208934&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=208934&view=rev</a><br>
> Log:<br>
> Implement global merge optimization for global variables.<br>
><br>
> This commit implements two command line switches -global-merge-on-external<br>
> and -global-merge-aligned, and both of them are false by default, so this<br>
> optimization is disabled by default for all targets.<br>
><br>
> For ARM64, some back-end behaviors need to be tuned to get this optimization<br>
> further enabled.<br>
><br>
><br>
> Added:<br>
> llvm/trunk/test/CodeGen/AArch64/global-merge.ll<br>
> llvm/trunk/test/CodeGen/ARM/global-merge-1.ll<br>
> llvm/trunk/test/CodeGen/ARM64/global-merge.ll<br>
> llvm/trunk/test/Transforms/GlobalMerge/AArch64/<br>
> llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-1.ll<br>
> llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-2.ll<br>
> llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-3.ll<br>
> llvm/trunk/test/Transforms/GlobalMerge/AArch64/lit.local.cfg<br>
> Removed:<br>
> llvm/trunk/test/CodeGen/AArch64/global_merge_1.ll<br>
> Modified:<br>
> llvm/trunk/include/llvm/IR/GlobalAlias.h<br>
> llvm/trunk/include/llvm/Target/TargetLowering.h<br>
> llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp<br>
> llvm/trunk/lib/IR/Globals.cpp<br>
> llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp<br>
> llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h<br>
> llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp<br>
> llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.h<br>
> llvm/trunk/lib/Transforms/Scalar/GlobalMerge.cpp<br>
> llvm/trunk/lib/Transforms/Scalar/Scalar.cpp<br>
> llvm/trunk/test/Transforms/GlobalMerge/ARM/arm.ll<br>
> llvm/trunk/test/Transforms/GlobalMerge/ARM64/arm64.ll<br>
><br>
> Modified: llvm/trunk/include/llvm/IR/GlobalAlias.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalAlias.h?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalAlias.h?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/IR/GlobalAlias.h (original)<br>
> +++ llvm/trunk/include/llvm/IR/GlobalAlias.h Thu May 15 18:45:42 2014<br>
> @@ -82,6 +82,10 @@ public:<br>
> static inline bool classof(const Value *V) {<br>
> return V->getValueID() == Value::GlobalAliasVal;<br>
> }<br>
> +<br>
> + // return the constant offset of an expression, with which this global var<br>
> + // has alias.<br>
> + uint64_t calculateOffset(const DataLayout &DL) const;<br>
> };<br>
><br>
> template <><br>
><br>
> Modified: llvm/trunk/include/llvm/Target/TargetLowering.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/Target/TargetLowering.h (original)<br>
> +++ llvm/trunk/include/llvm/Target/TargetLowering.h Thu May 15 18:45:42 2014<br>
> @@ -32,6 +32,7 @@<br>
> #include "llvm/IR/CallingConv.h"<br>
> #include "llvm/IR/InlineAsm.h"<br>
> #include "llvm/IR/IRBuilder.h"<br>
> +#include "llvm/IR/GlobalVariable.h"<br>
> #include "llvm/MC/MCRegisterInfo.h"<br>
> #include "llvm/Target/TargetCallingConv.h"<br>
> #include "llvm/Target/TargetMachine.h"<br>
> @@ -883,6 +884,12 @@ public:<br>
> return 0;<br>
> }<br>
><br>
> + /// Returns the alignment required by global merge on external symbols.<br>
> + /// By default, returns the natural alignment of merged data structure.<br>
> + virtual unsigned getGlobalMergeAlignment(StructType *MergedTy) const {<br>
> + return getDataLayout()->getABITypeAlignment(MergedTy);<br>
> + }<br>
> +<br>
> /// Returns true if a cast between SrcAS and DestAS is a noop.<br>
> virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const {<br>
> return false;<br>
><br>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)<br>
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu May 15 18:45:42 2014<br>
> @@ -946,8 +946,11 @@ bool AsmPrinter::doFinalization(Module &<br>
> EmitVisibility(Name, Alias.getVisibility());<br>
><br>
> // Emit the directives as assignments aka .set:<br>
> - OutStreamer.EmitAssignment(Name,<br>
> - MCSymbolRefExpr::Create(Target, OutContext));<br>
> + const MCExpr *Expr = MCSymbolRefExpr::Create(Target, OutContext);<br>
> + if (uint64_t Offset = Alias.calculateOffset(*TM.getDataLayout()))<br>
> + Expr = MCBinaryExpr::CreateAdd(Expr,<br>
> + MCConstantExpr::Create(Offset, OutContext), OutContext);<br>
> + OutStreamer.EmitAssignment(Name, Expr);<br>
> }<br>
> }<br>
><br>
><br>
> Modified: llvm/trunk/lib/IR/Globals.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Globals.cpp?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Globals.cpp?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/IR/Globals.cpp (original)<br>
> +++ llvm/trunk/lib/IR/Globals.cpp Thu May 15 18:45:42 2014<br>
> @@ -15,6 +15,7 @@<br>
> #include "llvm/IR/GlobalValue.h"<br>
> #include "llvm/ADT/SmallPtrSet.h"<br>
> #include "llvm/IR/Constants.h"<br>
> +#include "llvm/IR/DataLayout.h"<br>
> #include "llvm/IR/DerivedTypes.h"<br>
> #include "llvm/IR/GlobalAlias.h"<br>
> #include "llvm/IR/GlobalVariable.h"<br>
> @@ -282,3 +283,27 @@ GlobalObject *GlobalAlias::getAliasedGlo<br>
> return cast<GlobalObject>(GV);<br>
> }<br>
> }<br>
> +<br>
> +uint64_t GlobalAlias::calculateOffset(const DataLayout &DL) const {<br>
> + uint64_t Offset = 0;<br>
> + const Constant *C = this;<br>
> + while (C) {<br>
> + if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(C)) {<br>
> + C = GA->getAliasee();<br>
> + } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {<br>
> + if (CE->getOpcode() == Instruction::GetElementPtr) {<br>
> + std::vector<Value*> Args;<br>
> + for (unsigned I = 1; I < CE->getNumOperands(); ++I)<br>
> + Args.push_back(CE->getOperand(I));<br>
> + Offset += DL.getIndexedOffset(CE->getOperand(0)->getType(), Args);<br>
> + }<br>
> + C = CE->getOperand(0);<br>
> + } else if (isa<GlobalValue>(C)) {<br>
> + return Offset;<br>
> + } else {<br>
> + assert(0 && "Unexpected type in alias chain!");<br>
> + return 0;<br>
> + }<br>
> + }<br>
> + return Offset;<br>
> +}<br>
><br>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)<br>
> +++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Thu May 15 18:45:42 2014<br>
> @@ -5560,3 +5560,17 @@ unsigned AArch64TargetLowering::getMaxim<br>
> return 4095;<br>
> }<br>
><br>
> +/// getGlobalMergeAlignment - Set alignment to be the max size of merged<br>
> +/// global variable data structure, and make it aligned up to power of 2.<br>
> +/// This way, we could guarantee the merged global variable data structure<br>
> +/// doesn't cross page boundary, because usually OS always allocates page at<br>
> +/// 4096-byte aligned boundary.<br>
> +unsigned AArch64TargetLowering::getGlobalMergeAlignment(<br>
> + StructType *MergedTy) const {<br>
> + unsigned Align = getDataLayout()->getTypeAllocSize(MergedTy);<br>
> + if (Align & (Align - 1))<br>
> + Align = llvm::NextPowerOf2(Align);<br>
> +<br>
> + return Align;<br>
> +}<br>
> +<br>
><br>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h (original)<br>
> +++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h Thu May 15 18:45:42 2014<br>
> @@ -386,6 +386,10 @@ public:<br>
> /// be used for loads / stores from the global.<br>
> unsigned getMaximalGlobalOffset() const override;<br>
><br>
> + /// getGlobalMergeAlignment - Set alignment to be the max size of merged<br>
> + /// global variable data structure, and make it aligned up to power of 2.<br>
> + unsigned getGlobalMergeAlignment(StructType *MergedTy) const override;<br>
> +<br>
> protected:<br>
> std::pair<const TargetRegisterClass*, uint8_t><br>
> findRepresentativeClass(MVT VT) const override;<br>
><br>
> Modified: llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp (original)<br>
> +++ llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp Thu May 15 18:45:42 2014<br>
> @@ -630,6 +630,20 @@ unsigned ARM64TargetLowering::getMaximal<br>
> return 4095;<br>
> }<br>
><br>
> +/// getGlobalMergeAlignment - Set alignment to be the max size of merged<br>
> +/// global variable data structure, and make it aligned up to power of 2.<br>
> +/// This way, we could guarantee the merged global variable data structure<br>
> +/// doesn't cross page boundary, because usually OS always allocates page at<br>
> +/// 4096-byte aligned boundary.<br>
> +unsigned ARM64TargetLowering::getGlobalMergeAlignment(<br>
> + StructType *MergedTy) const {<br>
> + unsigned Align = getDataLayout()->getTypeAllocSize(MergedTy);<br>
> + if (Align & (Align - 1))<br>
> + Align = llvm::NextPowerOf2(Align);<br>
> +<br>
> + return Align;<br>
> +}<br>
> +<br>
> FastISel *<br>
> ARM64TargetLowering::createFastISel(FunctionLoweringInfo &funcInfo,<br>
> const TargetLibraryInfo *libInfo) const {<br>
><br>
> Modified: llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.h?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.h?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.h (original)<br>
> +++ llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.h Thu May 15 18:45:42 2014<br>
> @@ -236,6 +236,10 @@ public:<br>
> /// be used for loads / stores from the global.<br>
> unsigned getMaximalGlobalOffset() const override;<br>
><br>
> + /// getGlobalMergeAlignment - Set alignment to be the max size of merged<br>
> + /// global variable data structure, and make it aligned up to power of 2.<br>
> + unsigned getGlobalMergeAlignment(StructType *MergedTy) const override;<br>
> +<br>
> /// Returns true if a cast between SrcAS and DestAS is a noop.<br>
> bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override {<br>
> // Addrspacecasts are always noops.<br>
><br>
> Modified: llvm/trunk/lib/Transforms/Scalar/GlobalMerge.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GlobalMerge.cpp?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GlobalMerge.cpp?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Transforms/Scalar/GlobalMerge.cpp (original)<br>
> +++ llvm/trunk/lib/Transforms/Scalar/GlobalMerge.cpp Thu May 15 18:45:42 2014<br>
> @@ -72,7 +72,7 @@ using namespace llvm;<br>
> #define DEBUG_TYPE "global-merge"<br>
><br>
> static cl::opt<bool><br>
> -EnableGlobalMerge("global-merge", cl::Hidden,<br>
> +EnableGlobalMerge("enable-global-merge", cl::NotHidden,<br>
> cl::desc("Enable global merge pass"),<br>
> cl::init(true));<br>
><br>
> @@ -81,6 +81,16 @@ EnableGlobalMergeOnConst("global-merge-o<br>
> cl::desc("Enable global merge pass on constants"),<br>
> cl::init(false));<br>
><br>
> +static cl::opt<bool><br>
> +EnableGlobalMergeOnExternal("global-merge-on-external", cl::Hidden,<br>
> + cl::desc("Enable global merge pass on external linkage"),<br>
> + cl::init(false));<br>
> +<br>
> +static cl::opt<bool><br>
> +EnableGlobalMergeAligned("global-merge-aligned", cl::Hidden,<br>
> + cl::desc("Set target specific alignment for global merge pass"),<br>
> + cl::init(false));<br>
> +<br>
> STATISTIC(NumMerged , "Number of globals merged");<br>
> namespace {<br>
> class GlobalMerge : public FunctionPass {<br>
> @@ -129,9 +139,21 @@ namespace {<br>
> } // end anonymous namespace<br>
><br>
> char GlobalMerge::ID = 0;<br>
> -INITIALIZE_PASS(GlobalMerge, "global-merge",<br>
> - "Global Merge", false, false)<br>
><br>
> +static void *initializeGlobalMergePassOnce(PassRegistry &Registry) {<br>
> + PassInfo *PI = new PassInfo(<br>
> + "Merge global variables",<br>
> + "global-merge", &GlobalMerge::ID,<br>
> + PassInfo::NormalCtor_t(callDefaultCtor<GlobalMerge>), false,<br>
> + false, PassInfo::TargetMachineCtor_t(<br>
> + callTargetMachineCtor<GlobalMerge>));<br>
> + Registry.registerPass(*PI, true);<br>
> + return PI;<br>
> +}<br>
> +<br>
> +void llvm::initializeGlobalMergePass(PassRegistry &Registry) {<br>
> + CALL_ONCE_INITIALIZATION(initializeGlobalMergePassOnce)<br>
> +}<br>
><br>
> bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,<br>
> Module &M, bool isConst, unsigned AddrSpace) const {<br>
> @@ -154,11 +176,16 @@ bool GlobalMerge::doMerge(SmallVectorImp<br>
><br>
> Type *Int32Ty = Type::getInt32Ty(M.getContext());<br>
><br>
> + assert (Globals.size() > 1);<br>
> +<br>
> for (size_t i = 0, e = Globals.size(); i != e; ) {<br>
> size_t j = 0;<br>
> uint64_t MergedSize = 0;<br>
> std::vector<Type*> Tys;<br>
> std::vector<Constant*> Inits;<br>
> +<br>
> + bool HasExternal = false;<br>
> + GlobalVariable *TheFirstExternal = 0;<br>
> for (j = i; j != e; ++j) {<br>
> Type *Ty = Globals[j]->getType()->getElementType();<br>
> MergedSize += DL->getTypeAllocSize(Ty);<br>
> @@ -167,17 +194,45 @@ bool GlobalMerge::doMerge(SmallVectorImp<br>
> }<br>
> Tys.push_back(Ty);<br>
> Inits.push_back(Globals[j]->getInitializer());<br>
> +<br>
> + if (Globals[j]->hasExternalLinkage() && !HasExternal) {<br>
> + HasExternal = true;<br>
> + TheFirstExternal = Globals[j];<br>
> + }<br>
> }<br>
><br>
> + // If merged variables doesn't have external linkage, we needn't to expose<br>
> + // the symbol after merging.<br>
> + GlobalValue::LinkageTypes Linkage = HasExternal ?<br>
> + GlobalValue::ExternalLinkage :<br>
> + GlobalValue::InternalLinkage ;<br>
> +<br>
> + // If merged variables have external linkage, we use symbol name of the<br>
> + // first variable merged as the suffix of global symbol name. This would<br>
> + // be able to avoid the link-time naming conflict for globalm symbols.<br>
> + Twine MergedGVName = HasExternal ?<br>
> + "_MergedGlobals_" + TheFirstExternal->getName() :<br>
> + "_MergedGlobals" ;<br>
> +<br>
> StructType *MergedTy = StructType::get(M.getContext(), Tys);<br>
> Constant *MergedInit = ConstantStruct::get(MergedTy, Inits);<br>
> +<br>
> GlobalVariable *MergedGV = new GlobalVariable(M, MergedTy, isConst,<br>
> - GlobalValue::InternalLinkage,<br>
> - MergedInit, "_MergedGlobals",<br>
> - nullptr,<br>
> - GlobalVariable::NotThreadLocal,<br>
> - AddrSpace);<br>
> + Linkage, MergedInit, MergedGVName,<br>
> + nullptr, GlobalVariable::NotThreadLocal,<br>
> + AddrSpace);<br>
> +<br>
> + if (EnableGlobalMergeAligned) {<br>
> + unsigned Align = TLI->getGlobalMergeAlignment(MergedTy);<br>
> + assert(((Align % DL->getABITypeAlignment(MergedTy)) == 0) &&<br>
> + "Specified alignment doesn't meet natural alignment requirement.");<br>
> + MergedGV->setAlignment(Align);<br>
> + }<br>
> +<br>
> for (size_t k = i; k < j; ++k) {<br>
> + GlobalValue::LinkageTypes Linkage = Globals[k]->getLinkage();<br>
> + std::string Name = Globals[k]->getName();<br>
> +<br>
> Constant *Idx[2] = {<br>
> ConstantInt::get(Int32Ty, 0),<br>
> ConstantInt::get(Int32Ty, k-i)<br>
> @@ -185,6 +240,12 @@ bool GlobalMerge::doMerge(SmallVectorImp<br>
> Constant *GEP = ConstantExpr::getInBoundsGetElementPtr(MergedGV, Idx);<br>
> Globals[k]->replaceAllUsesWith(GEP);<br>
> Globals[k]->eraseFromParent();<br>
> +<br>
> + if (Linkage != GlobalValue::InternalLinkage) {<br>
> + // Generate a new alias...<br>
> + new GlobalAlias(GEP->getType(), Linkage, Name, GEP, &M);<br>
> + }<br>
> +<br>
> NumMerged++;<br>
> }<br>
> i = j;<br>
> @@ -245,8 +306,12 @@ bool GlobalMerge::doInitialization(Modul<br>
> // Grab all non-const globals.<br>
> for (Module::global_iterator I = M.global_begin(),<br>
> E = M.global_end(); I != E; ++I) {<br>
> - // Merge is safe for "normal" internal globals only<br>
> - if (!I->hasLocalLinkage() || I->isThreadLocal() || I->hasSection())<br>
> + // Merge is safe for "normal" internal or external globals only<br>
> + if (I->isDeclaration() || I->isThreadLocal() || I->hasSection())<br>
> + continue;<br>
> +<br>
> + if (!(EnableGlobalMergeOnExternal && I->hasExternalLinkage())<br>
> + && !I->hasInternalLinkage())<br>
> continue;<br>
><br>
> PointerType *PT = dyn_cast<PointerType>(I->getType());<br>
><br>
> Modified: llvm/trunk/lib/Transforms/Scalar/Scalar.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Transforms/Scalar/Scalar.cpp (original)<br>
> +++ llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Thu May 15 18:45:42 2014<br>
> @@ -38,6 +38,7 @@ void llvm::initializeScalarOpts(PassRegi<br>
> initializeDSEPass(Registry);<br>
> initializeGVNPass(Registry);<br>
> initializeEarlyCSEPass(Registry);<br>
> + initializeGlobalMergePass(Registry);<br>
> initializeIndVarSimplifyPass(Registry);<br>
> initializeJumpThreadingPass(Registry);<br>
> initializeLICMPass(Registry);<br>
><br>
> Added: llvm/trunk/test/CodeGen/AArch64/global-merge.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/global-merge.ll?rev=208934&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/global-merge.ll?rev=208934&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/AArch64/global-merge.ll (added)<br>
> +++ llvm/trunk/test/CodeGen/AArch64/global-merge.ll Thu May 15 18:45:42 2014<br>
> @@ -0,0 +1,34 @@<br>
> +; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -O0 | FileCheck --check-prefix=NO-MERGE %s<br>
> +; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -O0 -global-merge-on-external=true -global-merge-aligned=true | FileCheck --check-prefix=NO-MERGE %s<br>
> +<br>
> +; RUN: llc < %s -mtriple=arm64-apple-ios -O0 | FileCheck %s --check-prefix=CHECK-APPLE-IOS-NO-MERGE<br>
> +; RUN: llc < %s -mtriple=arm64-apple-ios -O0 -global-merge-on-external=true -global-merge-aligned=false | FileCheck %s --check-prefix=CHECK-APPLE-IOS-NO-MERGE<br>
> +<br>
> +; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -O1 | FileCheck %s<br>
> +; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -O1 -global-merge-on-external=true -global-merge-aligned=true | FileCheck %s<br>
> +<br>
> +; RUN: llc < %s -mtriple=arm64-apple-ios -O1 | FileCheck %s --check-prefix=CHECK-APPLE-IOS<br>
> +; RUN: llc < %s -mtriple=arm64-apple-ios -O1 -global-merge-on-external=true -global-merge-aligned=false | FileCheck %s --check-prefix=CHECK-APPLE-IOS<br>
> +<br>
> +@m = internal global i32 0, align 4<br>
> +@n = internal global i32 0, align 4<br>
> +<br>
> +define void @f1(i32 %a1, i32 %a2) {<br>
> +; CHECK-LABEL: f1:<br>
> +; CHECK: adrp x{{[0-9]+}}, _MergedGlobals<br>
> +; CHECK-NOT: adrp<br>
> +<br>
> +; CHECK-APPLE-IOS-LABEL: f1:<br>
> +; CHECK-APPLE-IOS: adrp x{{[0-9]+}}, __MergedGlobals<br>
> +; CHECK-APPLE-IOS-NOT: adrp<br>
> + store i32 %a1, i32* @m, align 4<br>
> + store i32 %a2, i32* @n, align 4<br>
> + ret void<br>
> +}<br>
> +<br>
> +; CHECK: .local _MergedGlobals<br>
> +; CHECK: .comm _MergedGlobals,8,8<br>
> +; NO-MERGE-NOT: .local _MergedGlobals<br>
> +<br>
> +; CHECK-APPLE-IOS: .zerofill __DATA,__bss,__MergedGlobals,8,3<br>
> +; CHECK-APPLE-IOS-NO-MERGE-NOT: .zerofill __DATA,__bss,__MergedGlobals,8,3<br>
><br>
> Removed: llvm/trunk/test/CodeGen/AArch64/global_merge_1.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/global_merge_1.ll?rev=208933&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/global_merge_1.ll?rev=208933&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/AArch64/global_merge_1.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/AArch64/global_merge_1.ll (removed)<br>
> @@ -1,17 +0,0 @@<br>
> -; RUN: llc < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s<br>
> -<br>
> -@m = internal global i32 0, align 4<br>
> -@n = internal global i32 0, align 4<br>
> -<br>
> -define void @f1(i32 %a1, i32 %a2) {<br>
> -; CHECK-LABEL: f1:<br>
> -; CHECK: adrp x{{[0-9]+}}, _MergedGlobals<br>
> -; CHECK-NOT: adrp<br>
> - store i32 %a1, i32* @m, align 4<br>
> - store i32 %a2, i32* @n, align 4<br>
> - ret void<br>
> -}<br>
> -<br>
> -; CHECK: .local _MergedGlobals<br>
> -; CHECK: .comm _MergedGlobals,8,8<br>
> -<br>
><br>
> Added: llvm/trunk/test/CodeGen/ARM/global-merge-1.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/global-merge-1.ll?rev=208934&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/global-merge-1.ll?rev=208934&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/ARM/global-merge-1.ll (added)<br>
> +++ llvm/trunk/test/CodeGen/ARM/global-merge-1.ll Thu May 15 18:45:42 2014<br>
> @@ -0,0 +1,85 @@<br>
> +; RUN: llc %s -O0 -o - | FileCheck -check-prefix=NO-MERGE %s<br>
> +; RUN: llc %s -O0 -o - -enable-global-merge=false | FileCheck -check-prefix=NO-MERGE %s<br>
> +; RUN: llc %s -O0 -o - -enable-global-merge=true | FileCheck -check-prefix=NO-MERGE %s<br>
> +; RUN: llc %s -O1 -o - | FileCheck -check-prefix=MERGE %s<br>
> +; RUN: llc %s -O1 -o - -enable-global-merge=false | FileCheck -check-prefix=NO-MERGE %s<br>
> +; RUN: llc %s -O1 -o - -enable-global-merge=true | FileCheck -check-prefix=MERGE %s<br>
> +<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_bar,20,2<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_baz,20,2<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_foo,20,2<br>
> +; MERGE: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_bar,20,2<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_baz,20,2<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_foo,20,2<br>
> +<br>
> +; NO-MERGE-NOT: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> +; NO-MERGE: .zerofill __DATA,__bss,_bar,20,2<br>
> +; NO-MERGE: .zerofill __DATA,__bss,_baz,20,2<br>
> +; NO-MERGE: .zerofill __DATA,__bss,_foo,20,2<br>
> +; NO-MERGE-NOT: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> +<br>
> +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"<br>
> +target triple = "thumbv7-apple-ios3.0.0"<br>
> +<br>
> +@bar = internal global [5 x i32] zeroinitializer, align 4<br>
> +@baz = internal global [5 x i32] zeroinitializer, align 4<br>
> +@foo = internal global [5 x i32] zeroinitializer, align 4<br>
> +<br>
> +; Function Attrs: nounwind ssp<br>
> +define internal void @initialize() #0 {<br>
> + %1 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #3<br>
> + store i32 %1, i32* getelementptr inbounds ([5 x i32]* @bar, i32 0, i32 0), align 4, !tbaa !1<br>
> + %2 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #3<br>
> + store i32 %2, i32* getelementptr inbounds ([5 x i32]* @baz, i32 0, i32 0), align 4, !tbaa !1<br>
> + %3 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #3<br>
> + store i32 %3, i32* getelementptr inbounds ([5 x i32]* @bar, i32 0, i32 1), align 4, !tbaa !1<br>
> + %4 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #3<br>
> + store i32 %4, i32* getelementptr inbounds ([5 x i32]* @baz, i32 0, i32 1), align 4, !tbaa !1<br>
> + %5 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #3<br>
> + store i32 %5, i32* getelementptr inbounds ([5 x i32]* @bar, i32 0, i32 2), align 4, !tbaa !1<br>
> + %6 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #3<br>
> + store i32 %6, i32* getelementptr inbounds ([5 x i32]* @baz, i32 0, i32 2), align 4, !tbaa !1<br>
> + %7 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #3<br>
> + store i32 %7, i32* getelementptr inbounds ([5 x i32]* @bar, i32 0, i32 3), align 4, !tbaa !1<br>
> + %8 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #3<br>
> + store i32 %8, i32* getelementptr inbounds ([5 x i32]* @baz, i32 0, i32 3), align 4, !tbaa !1<br>
> + %9 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #3<br>
> + store i32 %9, i32* getelementptr inbounds ([5 x i32]* @bar, i32 0, i32 4), align 4, !tbaa !1<br>
> + %10 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #3<br>
> + store i32 %10, i32* getelementptr inbounds ([5 x i32]* @baz, i32 0, i32 4), align 4, !tbaa !1<br>
> + ret void<br>
> +}<br>
> +<br>
> +declare i32 @calc(...) #1<br>
> +<br>
> +; Function Attrs: nounwind ssp<br>
> +define internal void @calculate() #0 {<br>
> + %1 = load <4 x i32>* bitcast ([5 x i32]* @bar to <4 x i32>*), align 4<br>
> + %2 = load <4 x i32>* bitcast ([5 x i32]* @baz to <4 x i32>*), align 4<br>
> + %3 = mul <4 x i32> %2, %1<br>
> + store <4 x i32> %3, <4 x i32>* bitcast ([5 x i32]* @foo to <4 x i32>*), align 4<br>
> + %4 = load i32* getelementptr inbounds ([5 x i32]* @bar, i32 0, i32 4), align 4, !tbaa !1<br>
> + %5 = load i32* getelementptr inbounds ([5 x i32]* @baz, i32 0, i32 4), align 4, !tbaa !1<br>
> + %6 = mul nsw i32 %5, %4<br>
> + store i32 %6, i32* getelementptr inbounds ([5 x i32]* @foo, i32 0, i32 4), align 4, !tbaa !1<br>
> + ret void<br>
> +}<br>
> +<br>
> +; Function Attrs: nounwind readnone ssp<br>
> +define internal i32* @returnFoo() #2 {<br>
> + ret i32* getelementptr inbounds ([5 x i32]* @foo, i32 0, i32 0)<br>
> +}<br>
> +<br>
> +attributes #0 = { nounwind ssp "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +attributes #2 = { nounwind readnone ssp "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +attributes #3 = { nounwind }<br>
> +<br>
> +!llvm.ident = !{!0}<br>
> +<br>
> +!0 = metadata !{metadata !"LLVM version 3.4 "}<br>
> +!1 = metadata !{metadata !2, metadata !2, i64 0}<br>
> +!2 = metadata !{metadata !"int", metadata !3, i64 0}<br>
> +!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}<br>
> +!4 = metadata !{metadata !"Simple C/C++ TBAA"}<br>
><br>
> Added: llvm/trunk/test/CodeGen/ARM64/global-merge.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM64/global-merge.ll?rev=208934&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM64/global-merge.ll?rev=208934&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/ARM64/global-merge.ll (added)<br>
> +++ llvm/trunk/test/CodeGen/ARM64/global-merge.ll Thu May 15 18:45:42 2014<br>
> @@ -0,0 +1,88 @@<br>
> +; RUN: llc %s -O0 -o - | FileCheck -check-prefix=NO-MERGE %s<br>
> +; RUN: llc %s -O0 -o - -enable-global-merge=false | FileCheck -check-prefix=NO-MERGE %s<br>
> +; RUN: llc %s -O0 -o - -enable-global-merge=true | FileCheck -check-prefix=NO-MERGE %s<br>
> +; RUN: llc %s -O1 -o - | FileCheck -check-prefix=MERGE %s<br>
> +; RUN: llc %s -O1 -o - -enable-global-merge=false | FileCheck -check-prefix=NO-MERGE %s<br>
> +; RUN: llc %s -O1 -o - -enable-global-merge=true | FileCheck -check-prefix=MERGE %s<br>
> +<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_bar,20,2<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_baz,20,2<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_foo,20,2<br>
> +; MERGE: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_bar,20,2<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_baz,20,2<br>
> +; MERGE-NOT: .zerofill __DATA,__bss,_foo,20,2<br>
> +<br>
> +; NO-MERGE-NOT: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> +; NO-MERGE: .zerofill __DATA,__bss,_bar,20,2<br>
> +; NO-MERGE: .zerofill __DATA,__bss,_baz,20,2<br>
> +; NO-MERGE: .zerofill __DATA,__bss,_foo,20,2<br>
> +; NO-MERGE-NOT: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> +<br>
> +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32:64-S128"<br>
> +target triple = "arm64-apple-ios7.0.0"<br>
> +<br>
> +@bar = internal global [5 x i32] zeroinitializer, align 4<br>
> +@baz = internal global [5 x i32] zeroinitializer, align 4<br>
> +@foo = internal global [5 x i32] zeroinitializer, align 4<br>
> +<br>
> +; Function Attrs: nounwind ssp<br>
> +define internal void @initialize() #0 {<br>
> + %1 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #2<br>
> + store i32 %1, i32* getelementptr inbounds ([5 x i32]* @bar, i64 0, i64 0), align 4<br>
> + %2 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #2<br>
> + store i32 %2, i32* getelementptr inbounds ([5 x i32]* @baz, i64 0, i64 0), align 4<br>
> + %3 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #2<br>
> + store i32 %3, i32* getelementptr inbounds ([5 x i32]* @bar, i64 0, i64 1), align 4<br>
> + %4 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #2<br>
> + store i32 %4, i32* getelementptr inbounds ([5 x i32]* @baz, i64 0, i64 1), align 4<br>
> + %5 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #2<br>
> + store i32 %5, i32* getelementptr inbounds ([5 x i32]* @bar, i64 0, i64 2), align 4<br>
> + %6 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #2<br>
> + store i32 %6, i32* getelementptr inbounds ([5 x i32]* @baz, i64 0, i64 2), align 4<br>
> + %7 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #2<br>
> + store i32 %7, i32* getelementptr inbounds ([5 x i32]* @bar, i64 0, i64 3), align 4<br>
> + %8 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #2<br>
> + store i32 %8, i32* getelementptr inbounds ([5 x i32]* @baz, i64 0, i64 3), align 4<br>
> + %9 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #2<br>
> + store i32 %9, i32* getelementptr inbounds ([5 x i32]* @bar, i64 0, i64 4), align 4<br>
> + %10 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #2<br>
> + store i32 %10, i32* getelementptr inbounds ([5 x i32]* @baz, i64 0, i64 4), align 4<br>
> + ret void<br>
> +}<br>
> +<br>
> +declare i32 @calc(...)<br>
> +<br>
> +; Function Attrs: nounwind ssp<br>
> +define internal void @calculate() #0 {<br>
> + %1 = load i32* getelementptr inbounds ([5 x i32]* @bar, i64 0, i64 0), align 4<br>
> + %2 = load i32* getelementptr inbounds ([5 x i32]* @baz, i64 0, i64 0), align 4<br>
> + %3 = mul nsw i32 %2, %1<br>
> + store i32 %3, i32* getelementptr inbounds ([5 x i32]* @foo, i64 0, i64 0), align 4<br>
> + %4 = load i32* getelementptr inbounds ([5 x i32]* @bar, i64 0, i64 1), align 4<br>
> + %5 = load i32* getelementptr inbounds ([5 x i32]* @baz, i64 0, i64 1), align 4<br>
> + %6 = mul nsw i32 %5, %4<br>
> + store i32 %6, i32* getelementptr inbounds ([5 x i32]* @foo, i64 0, i64 1), align 4<br>
> + %7 = load i32* getelementptr inbounds ([5 x i32]* @bar, i64 0, i64 2), align 4<br>
> + %8 = load i32* getelementptr inbounds ([5 x i32]* @baz, i64 0, i64 2), align 4<br>
> + %9 = mul nsw i32 %8, %7<br>
> + store i32 %9, i32* getelementptr inbounds ([5 x i32]* @foo, i64 0, i64 2), align 4<br>
> + %10 = load i32* getelementptr inbounds ([5 x i32]* @bar, i64 0, i64 3), align 4<br>
> + %11 = load i32* getelementptr inbounds ([5 x i32]* @baz, i64 0, i64 3), align 4<br>
> + %12 = mul nsw i32 %11, %10<br>
> + store i32 %12, i32* getelementptr inbounds ([5 x i32]* @foo, i64 0, i64 3), align 4<br>
> + %13 = load i32* getelementptr inbounds ([5 x i32]* @bar, i64 0, i64 4), align 4<br>
> + %14 = load i32* getelementptr inbounds ([5 x i32]* @baz, i64 0, i64 4), align 4<br>
> + %15 = mul nsw i32 %14, %13<br>
> + store i32 %15, i32* getelementptr inbounds ([5 x i32]* @foo, i64 0, i64 4), align 4<br>
> + ret void<br>
> +}<br>
> +<br>
> +; Function Attrs: nounwind readnone ssp<br>
> +define internal i32* @returnFoo() #1 {<br>
> + ret i32* getelementptr inbounds ([5 x i32]* @foo, i64 0, i64 0)<br>
> +}<br>
> +<br>
> +attributes #0 = { nounwind ssp }<br>
> +attributes #1 = { nounwind readnone ssp }<br>
> +attributes #2 = { nounwind }<br>
><br>
> Added: llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-1.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-1.ll?rev=208934&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-1.ll?rev=208934&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-1.ll (added)<br>
> +++ llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-1.ll Thu May 15 18:45:42 2014<br>
> @@ -0,0 +1,22 @@<br>
> +; RUN: opt %s -mtriple=aarch64-none-linux-gnu -global-merge -S -o - | FileCheck %s<br>
> +; RUN: opt %s -mtriple=aarch64-none-linux-gnu -global-merge -global-merge-on-external -global-merge-aligned -S -o - | FileCheck %s<br>
> +<br>
> +; RUN: opt %s -mtriple=arm64-linux-gnuabi -global-merge -S -o - | FileCheck %s<br>
> +; RUN: opt %s -mtriple=arm64-linux-gnuabi -global-merge -global-merge-on-external -global-merge-aligned -S -o - | FileCheck %s<br>
> +<br>
> +; RUN: opt %s -mtriple=arm64-apple-ios -global-merge -S -o - | FileCheck %s<br>
> +; RUN: opt %s -mtriple=arm64-apple-ios -global-merge -global-merge-on-external -global-merge-aligned -S -o - | FileCheck %s<br>
> +<br>
> +@m = internal global i32 0, align 4<br>
> +@n = internal global i32 0, align 4<br>
> +<br>
> +; CHECK: @_MergedGlobals = internal global { i32, i32 } zeroinitializer<br>
> +<br>
> +define void @f1(i32 %a1, i32 %a2) {<br>
> +; CHECK-LABEL: @f1<br>
> +; CHECK: getelementptr inbounds ({ i32, i32 }* @_MergedGlobals, i32 0, i32 0)<br>
> +; CHECK: getelementptr inbounds ({ i32, i32 }* @_MergedGlobals, i32 0, i32 1)<br>
> + store i32 %a1, i32* @m, align 4<br>
> + store i32 %a2, i32* @n, align 4<br>
> + ret void<br>
> +}<br>
><br>
> Added: llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-2.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-2.ll?rev=208934&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-2.ll?rev=208934&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-2.ll (added)<br>
> +++ llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-2.ll Thu May 15 18:45:42 2014<br>
> @@ -0,0 +1,30 @@<br>
> +; RUN: opt %s -mtriple=aarch64-none-linux-gnu -global-merge -global-merge-on-external -global-merge-aligned -S -o - | FileCheck %s<br>
> +; RUN: opt %s -mtriple=arm64-linux-gnuabi -global-merge -global-merge-on-external -global-merge-aligned -S -o - | FileCheck %s<br>
> +; RUN: opt %s -mtriple=arm64-apple-ios -global-merge -global-merge-on-external -global-merge-aligned -S -o - | FileCheck %s<br>
> +<br>
> +@x = global i32 0, align 4<br>
> +@y = global i32 0, align 4<br>
> +@z = global i32 0, align 4<br>
> +<br>
> +; CHECK: @_MergedGlobals_x = global { i32, i32, i32 } zeroinitializer, align 16<br>
> +; CHECK: @x = alias getelementptr inbounds ({ i32, i32, i32 }* @_MergedGlobals_x, i32 0, i32 0)<br>
> +; CHECK: @y = alias getelementptr inbounds ({ i32, i32, i32 }* @_MergedGlobals_x, i32 0, i32 1)<br>
> +; CHECK: @z = alias getelementptr inbounds ({ i32, i32, i32 }* @_MergedGlobals_x, i32 0, i32 2)<br>
> +<br>
> +define void @f1(i32 %a1, i32 %a2) {<br>
> +; CHECK-LABEL: @f1<br>
> +; CHECK: getelementptr inbounds ({ i32, i32, i32 }* @_MergedGlobals_x, i32 0, i32 0)<br>
> +; CHECK: getelementptr inbounds ({ i32, i32, i32 }* @_MergedGlobals_x, i32 0, i32 1)<br>
> + store i32 %a1, i32* @x, align 4<br>
> + store i32 %a2, i32* @y, align 4<br>
> + ret void<br>
> +}<br>
> +<br>
> +define void @g1(i32 %a1, i32 %a2) {<br>
> +; CHECK-LABEL: @g1<br>
> +; CHECK: getelementptr inbounds ({ i32, i32, i32 }* @_MergedGlobals_x, i32 0, i32 1)<br>
> +; CHECK: getelementptr inbounds ({ i32, i32, i32 }* @_MergedGlobals_x, i32 0, i32 2)<br>
> + store i32 %a1, i32* @y, align 4<br>
> + store i32 %a2, i32* @z, align 4<br>
> + ret void<br>
> +}<br>
><br>
> Added: llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-3.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-3.ll?rev=208934&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-3.ll?rev=208934&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-3.ll (added)<br>
> +++ llvm/trunk/test/Transforms/GlobalMerge/AArch64/global-merge-3.ll Thu May 15 18:45:42 2014<br>
> @@ -0,0 +1,27 @@<br>
> +; RUN: opt %s -mtriple=aarch64-none-linux-gnu -global-merge -global-merge-on-external -global-merge-aligned -S -o - | FileCheck %s<br>
> +; RUN: opt %s -mtriple=arm64-linux-gnuabi -global-merge -global-merge-on-external -global-merge-aligned -S -o - | FileCheck %s<br>
> +; RUN: opt %s -mtriple=arm64-apple-ios -global-merge -global-merge-on-external -global-merge-aligned -S -o - | FileCheck %s<br>
> +<br>
> +@x = global [1000 x i32] zeroinitializer, align 1<br>
> +@y = global [1000 x i32] zeroinitializer, align 1<br>
> +@z = internal global i32 1, align 4<br>
> +<br>
> +; CHECK: @_MergedGlobals_x = global { i32, [1000 x i32] } { i32 1, [1000 x i32] zeroinitializer }, align 4096<br>
> +; CHECK: @_MergedGlobals_y = global { [1000 x i32] } zeroinitializer, align 4096<br>
> +<br>
> +; CHECK: @x = alias getelementptr inbounds ({ i32, [1000 x i32] }* @_MergedGlobals_x, i32 0, i32 1)<br>
> +; CHECK: @y = alias getelementptr inbounds ({ [1000 x i32] }* @_MergedGlobals_y, i32 0, i32 0)<br>
> +<br>
> +define void @f1(i32 %a1, i32 %a2, i32 %a3) {<br>
> +; CHECK-LABEL: @f1<br>
> +; CHECK: %x3 = getelementptr inbounds [1000 x i32]* getelementptr inbounds ({ i32, [1000 x i32] }* @_MergedGlobals_x, i32 0, i32 1), i32 0, i64 3<br>
> +; CHECK: %y3 = getelementptr inbounds [1000 x i32]* getelementptr inbounds ({ [1000 x i32] }* @_MergedGlobals_y, i32 0, i32 0), i32 0, i64 3<br>
> +; CHECK: store i32 %a3, i32* getelementptr inbounds ({ i32, [1000 x i32] }* @_MergedGlobals_x, i32 0, i32 0), align 4<br>
> +<br>
> + %x3 = getelementptr inbounds [1000 x i32]* @x, i32 0, i64 3<br>
> + %y3 = getelementptr inbounds [1000 x i32]* @y, i32 0, i64 3<br>
> + store i32 %a1, i32* %x3, align 4<br>
> + store i32 %a2, i32* %y3, align 4<br>
> + store i32 %a3, i32* @z, align 4<br>
> + ret void<br>
> +}<br>
><br>
> Added: llvm/trunk/test/Transforms/GlobalMerge/AArch64/lit.local.cfg<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/AArch64/lit.local.cfg?rev=208934&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/AArch64/lit.local.cfg?rev=208934&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/GlobalMerge/AArch64/lit.local.cfg (added)<br>
> +++ llvm/trunk/test/Transforms/GlobalMerge/AArch64/lit.local.cfg Thu May 15 18:45:42 2014<br>
> @@ -0,0 +1,4 @@<br>
> +targets = set(config.root.targets_to_build.split())<br>
> +if not 'AArch64' in targets:<br>
> + config.unsupported = True<br>
> +<br>
><br>
> Modified: llvm/trunk/test/Transforms/GlobalMerge/ARM/arm.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/ARM/arm.ll?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/ARM/arm.ll?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/GlobalMerge/ARM/arm.ll (original)<br>
> +++ llvm/trunk/test/Transforms/GlobalMerge/ARM/arm.ll Thu May 15 18:45:42 2014<br>
> @@ -1,23 +1,4 @@<br>
> -; RUN: llc %s -O0 -o - | FileCheck -check-prefix=NO-MERGE %s<br>
> -; RUN: llc %s -O0 -o - -global-merge=false | FileCheck -check-prefix=NO-MERGE %s<br>
> -; RUN: llc %s -O0 -o - -global-merge=true | FileCheck -check-prefix=NO-MERGE %s<br>
> -; RUN: llc %s -O1 -o - | FileCheck -check-prefix=MERGE %s<br>
> -; RUN: llc %s -O1 -o - -global-merge=false | FileCheck -check-prefix=NO-MERGE %s<br>
> -; RUN: llc %s -O1 -o - -global-merge=true | FileCheck -check-prefix=MERGE %s<br>
> -<br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_bar,20,2<br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_baz,20,2<br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_foo,20,2<br>
> -; MERGE: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_bar,20,2<br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_baz,20,2<br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_foo,20,2<br>
> -<br>
> -; NO-MERGE-NOT: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> -; NO-MERGE: .zerofill __DATA,__bss,_bar,20,2<br>
> -; NO-MERGE: .zerofill __DATA,__bss,_baz,20,2<br>
> -; NO-MERGE: .zerofill __DATA,__bss,_foo,20,2<br>
> -; NO-MERGE-NOT: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> +; RUN: opt %s -mtriple=arm-linux-gnuabi -global-merge -S -o - | FileCheck %s<br>
><br>
> target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"<br>
> target triple = "thumbv7-apple-ios3.0.0"<br>
> @@ -26,6 +7,8 @@ target triple = "thumbv7-apple-ios3.0.0"<br>
> @baz = internal global [5 x i32] zeroinitializer, align 4<br>
> @foo = internal global [5 x i32] zeroinitializer, align 4<br>
><br>
> +; CHECK: @_MergedGlobals = internal global { [5 x i32], [5 x i32], [5 x i32] } zeroinitializer<br>
> +<br>
> ; Function Attrs: nounwind ssp<br>
> define internal void @initialize() #0 {<br>
> %1 = tail call i32 bitcast (i32 (...)* @calc to i32 ()*)() #3<br>
><br>
> Modified: llvm/trunk/test/Transforms/GlobalMerge/ARM64/arm64.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/ARM64/arm64.ll?rev=208934&r1=208933&r2=208934&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalMerge/ARM64/arm64.ll?rev=208934&r1=208933&r2=208934&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/GlobalMerge/ARM64/arm64.ll (original)<br>
> +++ llvm/trunk/test/Transforms/GlobalMerge/ARM64/arm64.ll Thu May 15 18:45:42 2014<br>
> @@ -1,23 +1,6 @@<br>
> -; RUN: llc %s -O0 -o - | FileCheck -check-prefix=NO-MERGE %s<br>
> -; RUN: llc %s -O0 -o - -global-merge=false | FileCheck -check-prefix=NO-MERGE %s<br>
> -; RUN: llc %s -O0 -o - -global-merge=true | FileCheck -check-prefix=NO-MERGE %s<br>
> -; RUN: llc %s -O1 -o - | FileCheck -check-prefix=MERGE %s<br>
> -; RUN: llc %s -O1 -o - -global-merge=false | FileCheck -check-prefix=NO-MERGE %s<br>
> -; RUN: llc %s -O1 -o - -global-merge=true | FileCheck -check-prefix=MERGE %s<br>
> +; RUN: opt %s -mtriple=arm64-linux-gnuabi -global-merge -S -o - | FileCheck %s<br>
><br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_bar,20,2<br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_baz,20,2<br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_foo,20,2<br>
> -; MERGE: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_bar,20,2<br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_baz,20,2<br>
> -; MERGE-NOT: .zerofill __DATA,__bss,_foo,20,2<br>
> -<br>
> -; NO-MERGE-NOT: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> -; NO-MERGE: .zerofill __DATA,__bss,_bar,20,2<br>
> -; NO-MERGE: .zerofill __DATA,__bss,_baz,20,2<br>
> -; NO-MERGE: .zerofill __DATA,__bss,_foo,20,2<br>
> -; NO-MERGE-NOT: .zerofill __DATA,__bss,__MergedGlobals,60,4<br>
> +; CHECK: @_MergedGlobals = internal global { [5 x i32], [5 x i32], [5 x i32] } zeroinitializer<br>
><br>
> target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32:64-S128"<br>
> target triple = "arm64-apple-ios7.0.0"<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br></div>