diff options
Diffstat (limited to 'unittests/Transforms')
-rw-r--r-- | unittests/Transforms/CMakeLists.txt | 1 | ||||
-rw-r--r-- | unittests/Transforms/IPO/CMakeLists.txt | 9 | ||||
-rw-r--r-- | unittests/Transforms/IPO/LowerBitSets.cpp | 155 | ||||
-rw-r--r-- | unittests/Transforms/IPO/Makefile | 15 | ||||
-rw-r--r-- | unittests/Transforms/Makefile | 2 | ||||
-rw-r--r-- | unittests/Transforms/Utils/CMakeLists.txt | 1 | ||||
-rw-r--r-- | unittests/Transforms/Utils/Cloning.cpp | 109 | ||||
-rw-r--r-- | unittests/Transforms/Utils/ValueMapperTest.cpp | 27 |
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)); +} + +} |