aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
authorJames Y Knight <jyknight@google.com>2016-01-13 23:59:19 +0000
committerJames Y Knight <jyknight@google.com>2016-01-13 23:59:19 +0000
commit9de6d7becc82f1e7f0d76b3124d52cd20a96d601 (patch)
tree5c010b6c451344cbeb3d8e1e2a00806d98afb1c0 /llvm/lib/Transforms/Utils/Local.cpp
parent578864007baa81366d2a98a307e016b78bed82af (diff)
downloadllvm-9de6d7becc82f1e7f0d76b3124d52cd20a96d601.zip
llvm-9de6d7becc82f1e7f0d76b3124d52cd20a96d601.tar.gz
llvm-9de6d7becc82f1e7f0d76b3124d52cd20a96d601.tar.bz2
Stop increasing alignment of externally-visible globals on ELF
platforms. With ELF, the alignment of a global variable in a shared library will get copied into an executables linked against it, if the executable even accesss the variable. So, it's not possible to implicitly increase alignment based on access patterns, or you'll break existing binaries. This happened to affect libc++'s std::cout symbol, for example. See thread: http://thread.gmane.org/gmane.comp.compilers.clang.devel/45311 llvm-svn: 257719
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp20
1 files changed, 7 insertions, 13 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index d2793e5..91b3499 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -944,37 +944,31 @@ 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->isStrongDefinitionForLinker())
+ if (!GO->canIncreaseAlignment())
return Align;
- 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();
+ GO->setAlignment(PrefAlign);
+ return PrefAlign;
}
return Align;