Imported Upstream version 5.18.0.167

Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-10-20 08:25:10 +00:00
parent e19d552987
commit b084638f15
28489 changed files with 184 additions and 3866856 deletions

View File

@ -1,10 +0,0 @@
set(LLVM_LINK_COMPONENTS
Core
Support
IPO
)
add_llvm_unittest(IPOTests
LowerTypeTests.cpp
WholeProgramDevirt.cpp
)

View File

@ -1,156 +0,0 @@
//===- LowerTypeTests.cpp - Unit tests for type test lowering -------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/IPO/LowerTypeTests.h"
#include "gtest/gtest.h"
using namespace llvm;
using namespace lowertypetests;
TEST(LowerTypeTests, BitSetBuilder) {
struct {
std::vector<uint64_t> Offsets;
std::set<uint64_t> Bits;
uint64_t ByteOffset;
uint64_t BitSize;
unsigned AlignLog2;
bool IsSingleOffset;
bool IsAllOnes;
} BSBTests[] = {
{{}, std::set<uint64_t>{}, 0, 1, 0, false, false},
{{0}, {0}, 0, 1, 0, true, true},
{{4}, {0}, 4, 1, 0, true, true},
{{37}, {0}, 37, 1, 0, true, true},
{{0, 1}, {0, 1}, 0, 2, 0, false, true},
{{0, 4}, {0, 1}, 0, 2, 2, false, true},
{{0, uint64_t(1) << 33}, {0, 1}, 0, 2, 33, false, true},
{{3, 7}, {0, 1}, 3, 2, 2, false, true},
{{0, 1, 7}, {0, 1, 7}, 0, 8, 0, false, false},
{{0, 2, 14}, {0, 1, 7}, 0, 8, 1, false, false},
{{0, 1, 8}, {0, 1, 8}, 0, 9, 0, false, false},
{{0, 2, 16}, {0, 1, 8}, 0, 9, 1, false, false},
{{0, 1, 2, 3, 4, 5, 6, 7},
{0, 1, 2, 3, 4, 5, 6, 7},
0,
8,
0,
false,
true},
{{0, 1, 2, 3, 4, 5, 6, 7, 8},
{0, 1, 2, 3, 4, 5, 6, 7, 8},
0,
9,
0,
false,
true},
};
for (auto &&T : BSBTests) {
BitSetBuilder BSB;
for (auto Offset : T.Offsets)
BSB.addOffset(Offset);
BitSetInfo BSI = BSB.build();
EXPECT_EQ(T.Bits, BSI.Bits);
EXPECT_EQ(T.ByteOffset, BSI.ByteOffset);
EXPECT_EQ(T.BitSize, BSI.BitSize);
EXPECT_EQ(T.AlignLog2, BSI.AlignLog2);
EXPECT_EQ(T.IsSingleOffset, BSI.isSingleOffset());
EXPECT_EQ(T.IsAllOnes, BSI.isAllOnes());
for (auto Offset : T.Offsets)
EXPECT_TRUE(BSI.containsGlobalOffset(Offset));
auto I = T.Offsets.begin();
for (uint64_t NonOffset = 0; NonOffset != 256; ++NonOffset) {
if (I != T.Offsets.end() && *I == NonOffset) {
++I;
continue;
}
EXPECT_FALSE(BSI.containsGlobalOffset(NonOffset));
}
}
}
TEST(LowerTypeTests, GlobalLayoutBuilder) {
struct {
uint64_t NumObjects;
std::vector<std::set<uint64_t>> Fragments;
std::vector<uint64_t> WantLayout;
} GLBTests[] = {
{0, {}, {}},
{4, {{0, 1}, {2, 3}}, {0, 1, 2, 3}},
{3, {{0, 1}, {1, 2}}, {0, 1, 2}},
{4, {{0, 1}, {1, 2}, {2, 3}}, {0, 1, 2, 3}},
{4, {{0, 1}, {2, 3}, {1, 2}}, {0, 1, 2, 3}},
{6, {{2, 5}, {0, 1, 2, 3, 4, 5}}, {0, 1, 2, 5, 3, 4}},
};
for (auto &&T : GLBTests) {
GlobalLayoutBuilder GLB(T.NumObjects);
for (auto &&F : T.Fragments)
GLB.addFragment(F);
std::vector<uint64_t> ComputedLayout;
for (auto &&F : GLB.Fragments)
ComputedLayout.insert(ComputedLayout.end(), F.begin(), F.end());
EXPECT_EQ(T.WantLayout, ComputedLayout);
}
}
TEST(LowerTypeTests, ByteArrayBuilder) {
struct BABAlloc {
std::set<uint64_t> Bits;
uint64_t BitSize;
uint64_t WantByteOffset;
uint8_t WantMask;
};
struct {
std::vector<BABAlloc> Allocs;
std::vector<uint8_t> WantBytes;
} BABTests[] = {
{{{{0}, 1, 0, 1}, {{0}, 1, 0, 2}}, {3}},
{{{{0}, 16, 0, 1},
{{1}, 15, 0, 2},
{{2}, 14, 0, 4},
{{3}, 13, 0, 8},
{{4}, 12, 0, 0x10},
{{5}, 11, 0, 0x20},
{{6}, 10, 0, 0x40},
{{7}, 9, 0, 0x80},
{{0}, 7, 9, 0x80},
{{0}, 6, 10, 0x40},
{{0}, 5, 11, 0x20},
{{0}, 4, 12, 0x10},
{{0}, 3, 13, 8},
{{0}, 2, 14, 4},
{{0}, 1, 15, 2}},
{1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0, 0x80, 0x40, 0x20, 0x10, 8, 4,
2}},
};
for (auto &&T : BABTests) {
ByteArrayBuilder BABuilder;
for (auto &&A : T.Allocs) {
uint64_t GotByteOffset;
uint8_t GotMask;
BABuilder.allocate(A.Bits, A.BitSize, GotByteOffset, GotMask);
EXPECT_EQ(A.WantByteOffset, GotByteOffset);
EXPECT_EQ(A.WantMask, GotMask);
}
EXPECT_EQ(T.WantBytes, BABuilder.Bytes);
}
}

View File

@ -1,165 +0,0 @@
//===- WholeProgramDevirt.cpp - Unit tests for whole-program devirt -------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/IPO/WholeProgramDevirt.h"
#include "llvm/ADT/ArrayRef.h"
#include "gtest/gtest.h"
using namespace llvm;
using namespace wholeprogramdevirt;
TEST(WholeProgramDevirt, findLowestOffset) {
VTableBits VT1;
VT1.ObjectSize = 8;
VT1.Before.BytesUsed = {1 << 0};
VT1.After.BytesUsed = {1 << 1};
VTableBits VT2;
VT2.ObjectSize = 8;
VT2.Before.BytesUsed = {1 << 1};
VT2.After.BytesUsed = {1 << 0};
TypeMemberInfo TM1{&VT1, 0};
TypeMemberInfo TM2{&VT2, 0};
VirtualCallTarget Targets[] = {
{&TM1, /*IsBigEndian=*/false},
{&TM2, /*IsBigEndian=*/false},
};
EXPECT_EQ(2ull, findLowestOffset(Targets, /*IsAfter=*/false, 1));
EXPECT_EQ(66ull, findLowestOffset(Targets, /*IsAfter=*/true, 1));
EXPECT_EQ(8ull, findLowestOffset(Targets, /*IsAfter=*/false, 8));
EXPECT_EQ(72ull, findLowestOffset(Targets, /*IsAfter=*/true, 8));
TM1.Offset = 4;
EXPECT_EQ(33ull, findLowestOffset(Targets, /*IsAfter=*/false, 1));
EXPECT_EQ(65ull, findLowestOffset(Targets, /*IsAfter=*/true, 1));
EXPECT_EQ(40ull, findLowestOffset(Targets, /*IsAfter=*/false, 8));
EXPECT_EQ(72ull, findLowestOffset(Targets, /*IsAfter=*/true, 8));
TM1.Offset = 8;
TM2.Offset = 8;
EXPECT_EQ(66ull, findLowestOffset(Targets, /*IsAfter=*/false, 1));
EXPECT_EQ(2ull, findLowestOffset(Targets, /*IsAfter=*/true, 1));
EXPECT_EQ(72ull, findLowestOffset(Targets, /*IsAfter=*/false, 8));
EXPECT_EQ(8ull, findLowestOffset(Targets, /*IsAfter=*/true, 8));
VT1.After.BytesUsed = {0xff, 0, 0, 0, 0xff};
VT2.After.BytesUsed = {0xff, 1, 0, 0, 0};
EXPECT_EQ(16ull, findLowestOffset(Targets, /*IsAfter=*/true, 16));
EXPECT_EQ(40ull, findLowestOffset(Targets, /*IsAfter=*/true, 32));
}
TEST(WholeProgramDevirt, setReturnValues) {
VTableBits VT1;
VT1.ObjectSize = 8;
VTableBits VT2;
VT2.ObjectSize = 8;
TypeMemberInfo TM1{&VT1, 0};
TypeMemberInfo TM2{&VT2, 0};
VirtualCallTarget Targets[] = {
{&TM1, /*IsBigEndian=*/false},
{&TM2, /*IsBigEndian=*/false},
};
TM1.Offset = 4;
TM2.Offset = 4;
int64_t OffsetByte;
uint64_t OffsetBit;
Targets[0].RetVal = 1;
Targets[1].RetVal = 0;
setBeforeReturnValues(Targets, 32, 1, OffsetByte, OffsetBit);
EXPECT_EQ(-5ll, OffsetByte);
EXPECT_EQ(0ull, OffsetBit);
EXPECT_EQ(std::vector<uint8_t>{1}, VT1.Before.Bytes);
EXPECT_EQ(std::vector<uint8_t>{1}, VT1.Before.BytesUsed);
EXPECT_EQ(std::vector<uint8_t>{0}, VT2.Before.Bytes);
EXPECT_EQ(std::vector<uint8_t>{1}, VT2.Before.BytesUsed);
Targets[0].RetVal = 0;
Targets[1].RetVal = 1;
setBeforeReturnValues(Targets, 39, 1, OffsetByte, OffsetBit);
EXPECT_EQ(-5ll, OffsetByte);
EXPECT_EQ(7ull, OffsetBit);
EXPECT_EQ(std::vector<uint8_t>{1}, VT1.Before.Bytes);
EXPECT_EQ(std::vector<uint8_t>{0x81}, VT1.Before.BytesUsed);
EXPECT_EQ(std::vector<uint8_t>{0x80}, VT2.Before.Bytes);
EXPECT_EQ(std::vector<uint8_t>{0x81}, VT2.Before.BytesUsed);
Targets[0].RetVal = 12;
Targets[1].RetVal = 34;
setBeforeReturnValues(Targets, 40, 8, OffsetByte, OffsetBit);
EXPECT_EQ(-6ll, OffsetByte);
EXPECT_EQ(0ull, OffsetBit);
EXPECT_EQ((std::vector<uint8_t>{1, 12}), VT1.Before.Bytes);
EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT1.Before.BytesUsed);
EXPECT_EQ((std::vector<uint8_t>{0x80, 34}), VT2.Before.Bytes);
EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT2.Before.BytesUsed);
Targets[0].RetVal = 56;
Targets[1].RetVal = 78;
setBeforeReturnValues(Targets, 48, 16, OffsetByte, OffsetBit);
EXPECT_EQ(-8ll, OffsetByte);
EXPECT_EQ(0ull, OffsetBit);
EXPECT_EQ((std::vector<uint8_t>{1, 12, 0, 56}), VT1.Before.Bytes);
EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}),
VT1.Before.BytesUsed);
EXPECT_EQ((std::vector<uint8_t>{0x80, 34, 0, 78}), VT2.Before.Bytes);
EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}),
VT2.Before.BytesUsed);
Targets[0].RetVal = 1;
Targets[1].RetVal = 0;
setAfterReturnValues(Targets, 32, 1, OffsetByte, OffsetBit);
EXPECT_EQ(4ll, OffsetByte);
EXPECT_EQ(0ull, OffsetBit);
EXPECT_EQ(std::vector<uint8_t>{1}, VT1.After.Bytes);
EXPECT_EQ(std::vector<uint8_t>{1}, VT1.After.BytesUsed);
EXPECT_EQ(std::vector<uint8_t>{0}, VT2.After.Bytes);
EXPECT_EQ(std::vector<uint8_t>{1}, VT2.After.BytesUsed);
Targets[0].RetVal = 0;
Targets[1].RetVal = 1;
setAfterReturnValues(Targets, 39, 1, OffsetByte, OffsetBit);
EXPECT_EQ(4ll, OffsetByte);
EXPECT_EQ(7ull, OffsetBit);
EXPECT_EQ(std::vector<uint8_t>{1}, VT1.After.Bytes);
EXPECT_EQ(std::vector<uint8_t>{0x81}, VT1.After.BytesUsed);
EXPECT_EQ(std::vector<uint8_t>{0x80}, VT2.After.Bytes);
EXPECT_EQ(std::vector<uint8_t>{0x81}, VT2.After.BytesUsed);
Targets[0].RetVal = 12;
Targets[1].RetVal = 34;
setAfterReturnValues(Targets, 40, 8, OffsetByte, OffsetBit);
EXPECT_EQ(5ll, OffsetByte);
EXPECT_EQ(0ull, OffsetBit);
EXPECT_EQ((std::vector<uint8_t>{1, 12}), VT1.After.Bytes);
EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT1.After.BytesUsed);
EXPECT_EQ((std::vector<uint8_t>{0x80, 34}), VT2.After.Bytes);
EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT2.After.BytesUsed);
Targets[0].RetVal = 56;
Targets[1].RetVal = 78;
setAfterReturnValues(Targets, 48, 16, OffsetByte, OffsetBit);
EXPECT_EQ(6ll, OffsetByte);
EXPECT_EQ(0ull, OffsetBit);
EXPECT_EQ((std::vector<uint8_t>{1, 12, 56, 0}), VT1.After.Bytes);
EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}),
VT1.After.BytesUsed);
EXPECT_EQ((std::vector<uint8_t>{0x80, 34, 78, 0}), VT2.After.Bytes);
EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}),
VT2.After.BytesUsed);
}