X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=unittests%2FBitcode%2FBitReaderTest.cpp;h=3c56ea04c744fbe215773dd7ea042ce1ec302c12;hb=00552e3875ee5f382db6c98286a241a7d0efe1b8;hp=adc8851f279d8b256b961422030c001042c0d885;hpb=9b29ff99c0443ec0c038adafc8d5c782a8624e17;p=oota-llvm.git diff --git a/unittests/Bitcode/BitReaderTest.cpp b/unittests/Bitcode/BitReaderTest.cpp index adc8851f279..3c56ea04c74 100644 --- a/unittests/Bitcode/BitReaderTest.cpp +++ b/unittests/Bitcode/BitReaderTest.cpp @@ -8,14 +8,16 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/AsmParser/Parser.h" #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/AsmParser/Parser.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" +#include "llvm/Support/DataStream.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" @@ -51,9 +53,142 @@ static std::unique_ptr getLazyModuleFromAssembly(LLVMContext &Context, SmallString<1024> &Mem, const char *Assembly) { writeModuleToBuffer(parseAssembly(Assembly), Mem); - MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Mem.str(), "test", false); - ErrorOr ModuleOrErr = getLazyBitcodeModule(Buffer, Context); - return std::unique_ptr(ModuleOrErr.get()); + std::unique_ptr Buffer = + MemoryBuffer::getMemBuffer(Mem.str(), "test", false); + ErrorOr> ModuleOrErr = + getLazyBitcodeModule(std::move(Buffer), Context); + return std::move(ModuleOrErr.get()); +} + +class BufferDataStreamer : public DataStreamer { + std::unique_ptr Buffer; + unsigned Pos = 0; + size_t GetBytes(unsigned char *Out, size_t Len) override { + StringRef Buf = Buffer->getBuffer(); + size_t Left = Buf.size() - Pos; + Len = std::min(Left, Len); + memcpy(Out, Buffer->getBuffer().substr(Pos).data(), Len); + Pos += Len; + return Len; + } + +public: + BufferDataStreamer(std::unique_ptr Buffer) + : Buffer(std::move(Buffer)) {} +}; + +static std::unique_ptr +getStreamedModuleFromAssembly(LLVMContext &Context, SmallString<1024> &Mem, + const char *Assembly) { + writeModuleToBuffer(parseAssembly(Assembly), Mem); + std::unique_ptr Buffer = + MemoryBuffer::getMemBuffer(Mem.str(), "test", false); + auto Streamer = llvm::make_unique(std::move(Buffer)); + ErrorOr> ModuleOrErr = + getStreamedBitcodeModule("test", std::move(Streamer), Context); + return std::move(ModuleOrErr.get()); +} + +TEST(BitReaderTest, MateralizeForwardRefWithStream) { + SmallString<1024> Mem; + + LLVMContext Context; + std::unique_ptr M = getStreamedModuleFromAssembly( + Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n" + "define void @func() {\n" + " unreachable\n" + "bb:\n" + " unreachable\n" + "}\n"); + EXPECT_FALSE(M->getFunction("func")->empty()); +} + +TEST(BitReaderTest, DematerializeFunctionPreservesLinkageType) { + SmallString<1024> Mem; + + LLVMContext Context; + std::unique_ptr M = getLazyModuleFromAssembly( + Context, Mem, "define internal i32 @func() {\n" + "ret i32 0\n" + "}\n"); + + EXPECT_FALSE(verifyModule(*M, &dbgs())); + + M->getFunction("func")->materialize(); + EXPECT_FALSE(M->getFunction("func")->empty()); + EXPECT_TRUE(M->getFunction("func")->getLinkage() == + GlobalValue::InternalLinkage); + + // Check that the linkage type is preserved after dematerialization. + M->getFunction("func")->dematerialize(); + EXPECT_TRUE(M->getFunction("func")->empty()); + EXPECT_TRUE(M->getFunction("func")->getLinkage() == + GlobalValue::InternalLinkage); + EXPECT_FALSE(verifyModule(*M, &dbgs())); +} + +// Tests that lazy evaluation can parse functions out of order. +TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) { + SmallString<1024> Mem; + LLVMContext Context; + std::unique_ptr M = getLazyModuleFromAssembly( + Context, Mem, "define void @f() {\n" + " unreachable\n" + "}\n" + "define void @g() {\n" + " unreachable\n" + "}\n" + "define void @h() {\n" + " unreachable\n" + "}\n" + "define void @j() {\n" + " unreachable\n" + "}\n"); + EXPECT_FALSE(verifyModule(*M, &dbgs())); + + Function *F = M->getFunction("f"); + Function *G = M->getFunction("g"); + Function *H = M->getFunction("h"); + Function *J = M->getFunction("j"); + + // Initially all functions are not materialized (no basic blocks). + EXPECT_TRUE(F->empty()); + EXPECT_TRUE(G->empty()); + EXPECT_TRUE(H->empty()); + EXPECT_TRUE(J->empty()); + EXPECT_FALSE(verifyModule(*M, &dbgs())); + + // Materialize h. + H->materialize(); + EXPECT_TRUE(F->empty()); + EXPECT_TRUE(G->empty()); + EXPECT_FALSE(H->empty()); + EXPECT_TRUE(J->empty()); + EXPECT_FALSE(verifyModule(*M, &dbgs())); + + // Materialize g. + G->materialize(); + EXPECT_TRUE(F->empty()); + EXPECT_FALSE(G->empty()); + EXPECT_FALSE(H->empty()); + EXPECT_TRUE(J->empty()); + EXPECT_FALSE(verifyModule(*M, &dbgs())); + + // Materialize j. + J->materialize(); + EXPECT_TRUE(F->empty()); + EXPECT_FALSE(G->empty()); + EXPECT_FALSE(H->empty()); + EXPECT_FALSE(J->empty()); + EXPECT_FALSE(verifyModule(*M, &dbgs())); + + // Materialize f. + F->materialize(); + EXPECT_FALSE(F->empty()); + EXPECT_FALSE(G->empty()); + EXPECT_FALSE(H->empty()); + EXPECT_FALSE(J->empty()); + EXPECT_FALSE(verifyModule(*M, &dbgs())); } TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677 @@ -70,7 +205,7 @@ TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677 EXPECT_FALSE(verifyModule(*M, &dbgs())); // Try (and fail) to dematerialize @func. - M->getFunction("func")->Dematerialize(); + M->getFunction("func")->dematerialize(); EXPECT_FALSE(M->getFunction("func")->empty()); } @@ -95,13 +230,13 @@ TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) { EXPECT_FALSE(verifyModule(*M, &dbgs())); // Materialize @before, pulling in @func. - EXPECT_FALSE(M->getFunction("before")->Materialize()); + EXPECT_FALSE(M->getFunction("before")->materialize()); EXPECT_FALSE(M->getFunction("func")->empty()); EXPECT_TRUE(M->getFunction("other")->empty()); EXPECT_FALSE(verifyModule(*M, &dbgs())); // Try (and fail) to dematerialize @func. - M->getFunction("func")->Dematerialize(); + M->getFunction("func")->dematerialize(); EXPECT_FALSE(M->getFunction("func")->empty()); EXPECT_FALSE(verifyModule(*M, &dbgs())); } @@ -127,13 +262,13 @@ TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) { EXPECT_FALSE(verifyModule(*M, &dbgs())); // Materialize @after, pulling in @func. - EXPECT_FALSE(M->getFunction("after")->Materialize()); + EXPECT_FALSE(M->getFunction("after")->materialize()); EXPECT_FALSE(M->getFunction("func")->empty()); EXPECT_TRUE(M->getFunction("other")->empty()); EXPECT_FALSE(verifyModule(*M, &dbgs())); // Try (and fail) to dematerialize @func. - M->getFunction("func")->Dematerialize(); + M->getFunction("func")->dematerialize(); EXPECT_FALSE(M->getFunction("func")->empty()); EXPECT_FALSE(verifyModule(*M, &dbgs())); }