Revert "Stop increasing alignment of externally-visible globals on ELF platforms."

This reverts commit r257719, due to PR26144.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257775 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
James Y Knight 2016-01-14 16:33:21 +00:00
parent def08208bf
commit ee7d060ab8
5 changed files with 25 additions and 65 deletions

View File

@ -346,10 +346,6 @@ public:
return !(isDeclarationForLinker() || isWeakForLinker());
}
// Returns true if the alignment of the value can be unilaterally
// increased.
bool canIncreaseAlignment() const;
/// This method unlinks 'this' from the containing module, but does not delete
/// it.
virtual void removeFromParent() = 0;

View File

@ -1742,8 +1742,8 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool& ModifiedDT) {
// over-aligning global variables that have an explicit section is
// forbidden.
GlobalVariable *GV;
if ((GV = dyn_cast<GlobalVariable>(Val)) && GV->canIncreaseAlignment() &&
GV->getAlignment() < PrefAlign &&
if ((GV = dyn_cast<GlobalVariable>(Val)) && GV->hasUniqueInitializer() &&
!GV->hasSection() && GV->getAlignment() < PrefAlign &&
DL->getTypeAllocSize(GV->getType()->getElementType()) >=
MinSize + Offset2)
GV->setAlignment(PrefAlign);

View File

@ -12,12 +12,11 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/IR/GlobalValue.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
@ -135,47 +134,6 @@ bool GlobalValue::isDeclaration() const {
return false;
}
bool GlobalValue::canIncreaseAlignment() const {
// Firstly, can only increase the alignment of a global if it
// is a strong definition.
if (!isStrongDefinitionForLinker())
return false;
// It also has to either not have a section defined, or, not have
// alignment specified. (If it is assigned a section, the global
// could be densely packed with other objects in the section, and
// increasing the alignment could cause padding issues.)
if (hasSection() && getAlignment() > 0)
return false;
// On ELF platforms, we're further restricted in that we can't
// increase the alignment of any variable which might be emitted
// into a shared library, and which is exported. If the main
// executable accesses a variable found in a shared-lib, the main
// exe actually allocates memory for and exports the symbol ITSELF,
// overriding the symbol found in the library. That is, at link
// time, the observed alignment of the variable is copied into the
// executable binary. (A COPY relocation is also generated, to copy
// the initial data from the shadowed variable in the shared-lib
// into the location in the main binary, before running code.)
//
// And thus, even though you might think you are defining the
// global, and allocating the memory for the global in your object
// file, and thus should be able to set the alignment arbitrarily,
// that's not actually true. Doing so can cause an ABI breakage; an
// executable might have already been built with the previous
// alignment of the variable, and then assuming an increased
// alignment will be incorrect.
// Conservatively assume ELF if there's no parent pointer.
bool isELF =
(!Parent || Triple(Parent->getTargetTriple()).isOSBinFormatELF());
if (isELF && hasDefaultVisibility() && !hasLocalLinkage())
return false;
return true;
}
//===----------------------------------------------------------------------===//
// GlobalVariable Implementation
//===----------------------------------------------------------------------===//

View File

@ -944,31 +944,37 @@ bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
static unsigned enforceKnownAlignment(Value *V, unsigned Align,
unsigned PrefAlign,
const DataLayout &DL) {
assert(PrefAlign > Align);
V = V->stripPointerCasts();
if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
assert(AI->getAlignment() <= Align);
// If the preferred alignment is greater than the natural stack alignment
// then don't round up. This avoids dynamic stack realignment.
if (DL.exceedsNaturalStackAlignment(PrefAlign))
return Align;
// If there is a requested alignment and if this is an alloca, round up.
if (AI->getAlignment() >= PrefAlign)
return AI->getAlignment();
AI->setAlignment(PrefAlign);
return PrefAlign;
}
if (auto *GO = dyn_cast<GlobalObject>(V)) {
assert(GO->getAlignment() <= Align);
// If there is a large requested alignment and we can, bump up the alignment
// of the global. 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 (!GO->canIncreaseAlignment())
if (!GO->isStrongDefinitionForLinker())
return Align;
GO->setAlignment(PrefAlign);
return PrefAlign;
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 (!GO->hasSection() || GO->getAlignment() == 0)
GO->setAlignment(PrefAlign);
return GO->getAlignment();
}
return Align;

View File

@ -1,10 +1,10 @@
; RUN: llc < %s -mtriple=armv7-apple-ios -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-IOS --check-prefix=CHECK
; RUN: llc < %s -mtriple=thumbv7m-none-macho -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-DARWIN --check-prefix=CHECK
; RUN: llc < %s -mtriple=arm-none-eabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
; RUN: llc < %s -mtriple=arm-none-eabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
; RUN: llc < %s -mtriple=arm-none-androideabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
; RUN: llc < %s -mtriple=arm-none-gnueabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
; RUN: llc < %s -mtriple=arm-none-gnueabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
; RUN: llc < %s -mtriple=armv7-apple-ios -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-IOS
; RUN: llc < %s -mtriple=thumbv7m-none-macho -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-DARWIN
; RUN: llc < %s -mtriple=arm-none-eabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-eabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-androideabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-gnueabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
; RUN: llc < %s -mtriple=arm-none-gnueabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
define void @f1(i8* %dest, i8* %src) {
entry:
@ -402,8 +402,8 @@ entry:
; CHECK: arr1:
; CHECK-IOS: .align 3
; CHECK-DARWIN: .align 2
; CHECK-EABI-NOT: .align
; CHECK-GNUEABI-NOT: .align
; CHECK-EABI: .align 2
; CHECK-GNUEABI: .align 2
; CHECK: arr2:
; CHECK: {{\.section.+foo,bar}}
; CHECK-NOT: .align