1 //=== - unittest/Support/OptimizedStructLayoutTest.cpp - Layout tests -----===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/OptimizedStructLayout.h"
10 #include "gtest/gtest.h"
20 uint64_t ForcedOffset
;
21 uint64_t ExpectedOffset
;
24 SmallVector
<Field
, 16> Fields
;
25 bool Verified
= false;
29 LayoutTest(const LayoutTest
&) = delete;
30 LayoutTest
&operator=(const LayoutTest
&) = delete;
31 ~LayoutTest() { assert(Verified
); }
33 LayoutTest
&flexible(uint64_t Size
, uint64_t Alignment
,
34 uint64_t ExpectedOffset
) {
35 Fields
.push_back({Size
, Align(Alignment
),
36 OptimizedStructLayoutField::FlexibleOffset
, ExpectedOffset
});
40 LayoutTest
&fixed(uint64_t Size
, uint64_t Alignment
, uint64_t Offset
) {
41 Fields
.push_back({Size
, Align(Alignment
), Offset
, Offset
});
45 void verify(uint64_t ExpectedSize
, uint64_t ExpectedAlignment
) {
46 SmallVector
<OptimizedStructLayoutField
, 8> LayoutFields
;
47 LayoutFields
.reserve(Fields
.size());
48 for (auto &F
: Fields
)
49 LayoutFields
.emplace_back(&F
, F
.Size
, F
.Alignment
, F
.ForcedOffset
);
51 auto SizeAndAlign
= performOptimizedStructLayout(LayoutFields
);
53 EXPECT_EQ(SizeAndAlign
.first
, ExpectedSize
);
54 EXPECT_EQ(SizeAndAlign
.second
, Align(ExpectedAlignment
));
56 for (auto &LF
: LayoutFields
) {
57 auto &F
= *static_cast<const Field
*>(LF
.Id
);
58 EXPECT_EQ(LF
.Offset
, F
.ExpectedOffset
);
67 TEST(OptimizedStructLayoutTest
, Basic
) {
75 TEST(OptimizedStructLayoutTest
, OddSize
) {
84 TEST(OptimizedStructLayoutTest
, Gaps
) {
95 TEST(OptimizedStructLayoutTest
, Greed
) {
96 // The greedy algorithm doesn't find the optimal layout here, which
97 // would be to put the 5-byte field at the end.
107 TEST(OptimizedStructLayoutTest
, Jagged
) {
115 TEST(OptimizedStructLayoutTest
, GardenPath
) {
116 // The 4-byte-aligned field is our highest priority, but the less-aligned
117 // fields keep leaving the end offset mis-aligned.
135 TEST(OptimizedStructLayoutTest
, HighAlignment
) {
136 // Handle the case where a flexible field has such a high alignment
137 // requirement that aligning LastEnd to it gives an offset past the
138 // end of the gap before the next fixed-alignment field.
145 .flexible(4, 128, 128)