summaryrefslogtreecommitdiff
path: root/unittests/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Transforms')
-rw-r--r--unittests/Transforms/CMakeLists.txt1
-rw-r--r--unittests/Transforms/IPO/CMakeLists.txt9
-rw-r--r--unittests/Transforms/IPO/LowerBitSets.cpp155
-rw-r--r--unittests/Transforms/IPO/Makefile15
-rw-r--r--unittests/Transforms/Makefile2
-rw-r--r--unittests/Transforms/Utils/CMakeLists.txt1
-rw-r--r--unittests/Transforms/Utils/Cloning.cpp109
-rw-r--r--unittests/Transforms/Utils/ValueMapperTest.cpp27
8 files changed, 268 insertions, 51 deletions
diff --git a/unittests/Transforms/CMakeLists.txt b/unittests/Transforms/CMakeLists.txt
index e3ce185e0d5b4..5d3b29c94d72e 100644
--- a/unittests/Transforms/CMakeLists.txt
+++ b/unittests/Transforms/CMakeLists.txt
@@ -1 +1,2 @@
+add_subdirectory(IPO)
add_subdirectory(Utils)
diff --git a/unittests/Transforms/IPO/CMakeLists.txt b/unittests/Transforms/IPO/CMakeLists.txt
new file mode 100644
index 0000000000000..58b71b2bce03f
--- /dev/null
+++ b/unittests/Transforms/IPO/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(LLVM_LINK_COMPONENTS
+ Core
+ Support
+ IPO
+ )
+
+add_llvm_unittest(IPOTests
+ LowerBitSets.cpp
+ )
diff --git a/unittests/Transforms/IPO/LowerBitSets.cpp b/unittests/Transforms/IPO/LowerBitSets.cpp
new file mode 100644
index 0000000000000..49a42cd20d7a9
--- /dev/null
+++ b/unittests/Transforms/IPO/LowerBitSets.cpp
@@ -0,0 +1,155 @@
+//===- LowerBitSets.cpp - Unit tests for bitset 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/LowerBitSets.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(LowerBitSets, 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(LowerBitSets, 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(LowerBitSets, 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);
+ }
+}
diff --git a/unittests/Transforms/IPO/Makefile b/unittests/Transforms/IPO/Makefile
new file mode 100644
index 0000000000000..f807879c2b5f6
--- /dev/null
+++ b/unittests/Transforms/IPO/Makefile
@@ -0,0 +1,15 @@
+##===- unittests/Transforms/IPO/Makefile -------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+TESTNAME = IPO
+LINK_COMPONENTS := IPO
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Transforms/Makefile b/unittests/Transforms/Makefile
index 599b18a057dcf..3a2cdfc2c74a0 100644
--- a/unittests/Transforms/Makefile
+++ b/unittests/Transforms/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
-PARALLEL_DIRS = Utils
+PARALLEL_DIRS = IPO Utils
include $(LEVEL)/Makefile.common
diff --git a/unittests/Transforms/Utils/CMakeLists.txt b/unittests/Transforms/Utils/CMakeLists.txt
index ffa1d49d380bd..517ff99ea46bc 100644
--- a/unittests/Transforms/Utils/CMakeLists.txt
+++ b/unittests/Transforms/Utils/CMakeLists.txt
@@ -9,4 +9,5 @@ add_llvm_unittest(UtilsTests
Cloning.cpp
IntegerDivision.cpp
Local.cpp
+ ValueMapperTest.cpp
)
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
index 1d22d5b15c9ba..18d3ca6267535 100644
--- a/unittests/Transforms/Utils/Cloning.cpp
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -22,6 +22,7 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -30,9 +31,7 @@ namespace {
class CloneInstruction : public ::testing::Test {
protected:
- virtual void SetUp() {
- V = nullptr;
- }
+ void SetUp() override { V = nullptr; }
template <typename T>
T *clone(T *V1) {
@@ -46,7 +45,7 @@ protected:
DeleteContainerPointers(Clones);
}
- virtual void TearDown() {
+ void TearDown() override {
eraseClones();
DeleteContainerPointers(Orig);
delete V;
@@ -135,7 +134,8 @@ TEST_F(CloneInstruction, Inbounds) {
Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
std::vector<Value *> ops;
ops.push_back(Z);
- GetElementPtrInst *GEP = GetElementPtrInst::Create(V, ops);
+ GetElementPtrInst *GEP =
+ GetElementPtrInst::Create(Type::getInt32Ty(context), V, ops);
EXPECT_FALSE(this->clone(GEP)->isInBounds());
GEP->setIsInBounds();
@@ -204,16 +204,14 @@ TEST_F(CloneInstruction, CallingConvention) {
class CloneFunc : public ::testing::Test {
protected:
- virtual void SetUp() {
+ void SetUp() override {
SetupModule();
CreateOldFunc();
CreateNewFunc();
SetupFinder();
}
- virtual void TearDown() {
- delete Finder;
- }
+ void TearDown() override { delete Finder; }
void SetupModule() {
M = new Module("", C);
@@ -230,14 +228,16 @@ protected:
IRBuilder<> IBuilder(C);
// Function DI
- DIFile File = DBuilder.createFile("filename.c", "/file/dir/");
- DITypeArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
- DICompositeType FuncType = DBuilder.createSubroutineType(File, ParamTypes);
- DICompileUnit CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
- "filename.c", "/file/dir", "CloneFunc", false, "", 0);
+ auto *File = DBuilder.createFile("filename.c", "/file/dir/");
+ DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
+ DISubroutineType *FuncType =
+ DBuilder.createSubroutineType(File, ParamTypes);
+ auto *CU =
+ DBuilder.createCompileUnit(dwarf::DW_LANG_C99, "filename.c",
+ "/file/dir", "CloneFunc", false, "", 0);
- DISubprogram Subprogram = DBuilder.createFunction(CU, "f", "f", File, 4,
- FuncType, true, true, 3, 0, false, OldFunc);
+ auto *Subprogram = DBuilder.createFunction(
+ CU, "f", "f", File, 4, FuncType, true, true, 3, 0, false, OldFunc);
// Function body
BasicBlock* Entry = BasicBlock::Create(C, "", OldFunc);
@@ -252,13 +252,15 @@ protected:
Instruction* Terminator = IBuilder.CreateRetVoid();
// Create a local variable around the alloca
- DIType IntType = DBuilder.createBasicType("int", 32, 0,
- dwarf::DW_ATE_signed);
- DIExpression E = DBuilder.createExpression();
- DIVariable Variable = DBuilder.createLocalVariable(
- dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
- DBuilder.insertDeclare(Alloca, Variable, E, Store);
- DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, Terminator);
+ auto *IntType =
+ DBuilder.createBasicType("int", 32, 0, dwarf::DW_ATE_signed);
+ auto *E = DBuilder.createExpression();
+ auto *Variable = DBuilder.createLocalVariable(
+ dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
+ auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram);
+ DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
+ DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL,
+ Terminator);
// Finalize the debug info
DBuilder.finalize();
@@ -296,38 +298,41 @@ TEST_F(CloneFunc, NewFunctionCreated) {
// Test that a new subprogram entry was added and is pointing to the new
// function, while the original subprogram still points to the old one.
TEST_F(CloneFunc, Subprogram) {
+ EXPECT_FALSE(verifyModule(*M));
+
unsigned SubprogramCount = Finder->subprogram_count();
EXPECT_EQ(2U, SubprogramCount);
auto Iter = Finder->subprograms().begin();
- DISubprogram Sub1(*Iter);
- EXPECT_TRUE(Sub1.Verify());
+ auto *Sub1 = cast<DISubprogram>(*Iter);
Iter++;
- DISubprogram Sub2(*Iter);
- EXPECT_TRUE(Sub2.Verify());
+ auto *Sub2 = cast<DISubprogram>(*Iter);
- EXPECT_TRUE((Sub1.getFunction() == OldFunc && Sub2.getFunction() == NewFunc)
- || (Sub1.getFunction() == NewFunc && Sub2.getFunction() == OldFunc));
+ EXPECT_TRUE(
+ (Sub1->getFunction() == OldFunc && Sub2->getFunction() == NewFunc) ||
+ (Sub1->getFunction() == NewFunc && Sub2->getFunction() == OldFunc));
}
// Test that the new subprogram entry was not added to the CU which doesn't
// contain the old subprogram entry.
TEST_F(CloneFunc, SubprogramInRightCU) {
+ EXPECT_FALSE(verifyModule(*M));
+
EXPECT_EQ(2U, Finder->compile_unit_count());
auto Iter = Finder->compile_units().begin();
- DICompileUnit CU1(*Iter);
- EXPECT_TRUE(CU1.Verify());
+ auto *CU1 = cast<DICompileUnit>(*Iter);
Iter++;
- DICompileUnit CU2(*Iter);
- EXPECT_TRUE(CU2.Verify());
- EXPECT_TRUE(CU1.getSubprograms().getNumElements() == 0
- || CU2.getSubprograms().getNumElements() == 0);
+ auto *CU2 = cast<DICompileUnit>(*Iter);
+ EXPECT_TRUE(CU1->getSubprograms().size() == 0 ||
+ CU2->getSubprograms().size() == 0);
}
// Test that instructions in the old function still belong to it in the
// metadata, while instruction in the new function belong to the new one.
TEST_F(CloneFunc, InstructionOwnership) {
+ EXPECT_FALSE(verifyModule(*M));
+
inst_iterator OldIter = inst_begin(OldFunc);
inst_iterator OldEnd = inst_end(OldFunc);
inst_iterator NewIter = inst_begin(NewFunc);
@@ -345,14 +350,12 @@ TEST_F(CloneFunc, InstructionOwnership) {
// Verify that the debug location data is the same
EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
-
+
// But that they belong to different functions
- DISubprogram OldSubprogram(OldDL.getScope(C));
- DISubprogram NewSubprogram(NewDL.getScope(C));
- EXPECT_TRUE(OldSubprogram.Verify());
- EXPECT_TRUE(NewSubprogram.Verify());
- EXPECT_EQ(OldFunc, OldSubprogram.getFunction());
- EXPECT_EQ(NewFunc, NewSubprogram.getFunction());
+ auto *OldSubprogram = cast<DISubprogram>(OldDL.getScope());
+ auto *NewSubprogram = cast<DISubprogram>(NewDL.getScope());
+ EXPECT_EQ(OldFunc, OldSubprogram->getFunction());
+ EXPECT_EQ(NewFunc, NewSubprogram->getFunction());
}
++OldIter;
@@ -365,6 +368,8 @@ TEST_F(CloneFunc, InstructionOwnership) {
// Test that the arguments for debug intrinsics in the new function were
// properly cloned
TEST_F(CloneFunc, DebugIntrinsics) {
+ EXPECT_FALSE(verifyModule(*M));
+
inst_iterator OldIter = inst_begin(OldFunc);
inst_iterator OldEnd = inst_end(OldFunc);
inst_iterator NewIter = inst_begin(NewFunc);
@@ -384,21 +389,25 @@ TEST_F(CloneFunc, DebugIntrinsics) {
getParent()->getParent());
// Old variable must belong to the old function
- EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
- .getContext()).getFunction());
+ EXPECT_EQ(OldFunc,
+ cast<DISubprogram>(OldIntrin->getVariable()->getScope())
+ ->getFunction());
// New variable must belong to the New function
- EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
- .getContext()).getFunction());
+ EXPECT_EQ(NewFunc,
+ cast<DISubprogram>(NewIntrin->getVariable()->getScope())
+ ->getFunction());
} else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
EXPECT_TRUE(NewIntrin);
// Old variable must belong to the old function
- EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
- .getContext()).getFunction());
+ EXPECT_EQ(OldFunc,
+ cast<DISubprogram>(OldIntrin->getVariable()->getScope())
+ ->getFunction());
// New variable must belong to the New function
- EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
- .getContext()).getFunction());
+ EXPECT_EQ(NewFunc,
+ cast<DISubprogram>(NewIntrin->getVariable()->getScope())
+ ->getFunction());
}
++OldIter;
diff --git a/unittests/Transforms/Utils/ValueMapperTest.cpp b/unittests/Transforms/Utils/ValueMapperTest.cpp
new file mode 100644
index 0000000000000..137a2607c848b
--- /dev/null
+++ b/unittests/Transforms/Utils/ValueMapperTest.cpp
@@ -0,0 +1,27 @@
+//===- ValueMapper.cpp - Unit tests for ValueMapper -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(ValueMapperTest, MapMetadataUnresolved) {
+ LLVMContext Context;
+ TempMDTuple T = MDTuple::getTemporary(Context, None);
+
+ ValueToValueMapTy VM;
+ EXPECT_EQ(T.get(), MapMetadata(T.get(), VM, RF_NoModuleLevelChanges));
+}
+
+}