summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2019-07-22 18:47:03 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2019-07-22 18:47:03 +0000
commitc3b8661df5478db2a83a213f36192dfdfa92cbe1 (patch)
tree0680b3ba5f637f8635b53d8a0095d640282c3d3a
parenta2748c74d68bd3748dcf626d828ee50a19cd1324 (diff)
downloadbcm5719-llvm-c3b8661df5478db2a83a213f36192dfdfa92cbe1.tar.gz
bcm5719-llvm-c3b8661df5478db2a83a213f36192dfdfa92cbe1.zip
LowerTypeTests: Teach the pass to respect global alignments.
We were previously ignoring alignment entirely when combining globals together in this pass. There are two main things that we need to do here: add additional padding before each global to meet the alignment requirements, and set the combined global's alignment to the maximum of all of the original globals' alignments. Since we now need to calculate layout as we go anyway, use the calculated layout to produce GlobalLayout instead of using StructLayout. Differential Revision: https://reviews.llvm.org/D65033 llvm-svn: 366722
-rw-r--r--llvm/lib/Transforms/IPO/LowerTypeTests.cpp45
-rw-r--r--llvm/test/Transforms/LowerTypeTests/align.ll16
2 files changed, 42 insertions, 19 deletions
diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index f7371284f47..716d4e8ede7 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -759,43 +759,50 @@ void LowerTypeTestsModule::buildBitSetsFromGlobalVariables(
// Build a new global with the combined contents of the referenced globals.
// This global is a struct whose even-indexed elements contain the original
// contents of the referenced globals and whose odd-indexed elements contain
- // any padding required to align the next element to the next power of 2.
+ // any padding required to align the next element to the next power of 2 plus
+ // any additional padding required to meet its alignment requirements.
std::vector<Constant *> GlobalInits;
const DataLayout &DL = M.getDataLayout();
+ DenseMap<GlobalTypeMember *, uint64_t> GlobalLayout;
+ uint64_t MaxAlign = 0;
+ uint64_t CurOffset = 0;
+ uint64_t DesiredPadding = 0;
for (GlobalTypeMember *G : Globals) {
- GlobalVariable *GV = cast<GlobalVariable>(G->getGlobal());
+ auto *GV = cast<GlobalVariable>(G->getGlobal());
+ uint64_t Align = GV->getAlignment();
+ if (Align == 0)
+ Align = DL.getABITypeAlignment(GV->getValueType());
+ MaxAlign = std::max(MaxAlign, Align);
+ uint64_t GVOffset = alignTo(CurOffset + DesiredPadding, Align);
+ GlobalLayout[G] = GVOffset;
+ if (GVOffset != 0) {
+ uint64_t Padding = GVOffset - CurOffset;
+ GlobalInits.push_back(
+ ConstantAggregateZero::get(ArrayType::get(Int8Ty, Padding)));
+ }
+
GlobalInits.push_back(GV->getInitializer());
uint64_t InitSize = DL.getTypeAllocSize(GV->getValueType());
+ CurOffset = GVOffset + InitSize;
- // Compute the amount of padding required.
- uint64_t Padding = NextPowerOf2(InitSize - 1) - InitSize;
+ // Compute the amount of padding that we'd like for the next element.
+ DesiredPadding = NextPowerOf2(InitSize - 1) - InitSize;
// Experiments of different caps with Chromium on both x64 and ARM64
// have shown that the 32-byte cap generates the smallest binary on
// both platforms while different caps yield similar performance.
// (see https://lists.llvm.org/pipermail/llvm-dev/2018-July/124694.html)
- if (Padding > 32)
- Padding = alignTo(InitSize, 32) - InitSize;
-
- GlobalInits.push_back(
- ConstantAggregateZero::get(ArrayType::get(Int8Ty, Padding)));
+ if (DesiredPadding > 32)
+ DesiredPadding = alignTo(InitSize, 32) - InitSize;
}
- if (!GlobalInits.empty())
- GlobalInits.pop_back();
+
Constant *NewInit = ConstantStruct::getAnon(M.getContext(), GlobalInits);
auto *CombinedGlobal =
new GlobalVariable(M, NewInit->getType(), /*isConstant=*/true,
GlobalValue::PrivateLinkage, NewInit);
+ CombinedGlobal->setAlignment(MaxAlign);
StructType *NewTy = cast<StructType>(NewInit->getType());
- const StructLayout *CombinedGlobalLayout = DL.getStructLayout(NewTy);
-
- // Compute the offsets of the original globals within the new global.
- DenseMap<GlobalTypeMember *, uint64_t> GlobalLayout;
- for (unsigned I = 0; I != Globals.size(); ++I)
- // Multiply by 2 to account for padding elements.
- GlobalLayout[Globals[I]] = CombinedGlobalLayout->getElementOffset(I * 2);
-
lowerTypeTestCalls(TypeIds, CombinedGlobal, GlobalLayout);
// Build aliases pointing to offsets into the combined global for each
diff --git a/llvm/test/Transforms/LowerTypeTests/align.ll b/llvm/test/Transforms/LowerTypeTests/align.ll
new file mode 100644
index 00000000000..ab06c46d950
--- /dev/null
+++ b/llvm/test/Transforms/LowerTypeTests/align.ll
@@ -0,0 +1,16 @@
+; RUN: opt -S -lowertypetests < %s | FileCheck %s
+
+target datalayout = "e-p:32:32"
+
+; CHECK: private constant { i32, [4 x i8], i32 } { i32 1, [4 x i8] zeroinitializer, i32 2 }, align 8
+@a = constant i32 1, !type !0
+@b = constant i32 2, align 8, !type !0
+
+!0 = !{i32 0, !"typeid1"}
+
+declare i1 @llvm.type.test(i8* %ptr, metadata %bitset) nounwind readnone
+
+define i1 @foo(i8* %p) {
+ %x = call i1 @llvm.type.test(i8* %p, metadata !"typeid1")
+ ret i1 %x
+}
OpenPOWER on IntegriCloud