[llvm] r239871 - Handle forward referenced function when streaming bitcode.
Rafael Espindola
rafael.espindola at gmail.com
Tue Jun 16 18:15:47 PDT 2015
Author: rafael
Date: Tue Jun 16 20:15:47 2015
New Revision: 239871
URL: http://llvm.org/viewvc/llvm-project?rev=239871&view=rev
Log:
Handle forward referenced function when streaming bitcode.
Without this the included unit test would assert in
assert(BasicBlockFwdRefs.empty() && "Unresolved blockaddress fwd references");
Modified:
llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/trunk/unittests/Bitcode/BitReaderTest.cpp
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=239871&r1=239870&r2=239871&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Jun 16 20:15:47 2015
@@ -4597,23 +4597,11 @@ const std::error_category &llvm::Bitcode
// External interface
//===----------------------------------------------------------------------===//
-/// \brief Get a lazy one-at-time loading module from bitcode.
-///
-/// This isn't always used in a lazy context. In particular, it's also used by
-/// \a parseBitcodeFile(). If this is truly lazy, then we need to eagerly pull
-/// in forward-referenced functions from block address references.
-///
-/// \param[in] MaterializeAll Set to \c true if we should materialize
-/// everything.
static ErrorOr<std::unique_ptr<Module>>
-getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
- LLVMContext &Context, bool MaterializeAll,
- DiagnosticHandlerFunction DiagnosticHandler,
- bool ShouldLazyLoadMetadata = false) {
- std::unique_ptr<Module> M =
- make_unique<Module>(Buffer->getBufferIdentifier(), Context);
- BitcodeReader *R =
- new BitcodeReader(Buffer.get(), Context, DiagnosticHandler);
+getBitcodeModuleImpl(std::unique_ptr<DataStreamer> Streamer, StringRef Name,
+ BitcodeReader *R, LLVMContext &Context,
+ bool MaterializeAll, bool ShouldLazyLoadMetadata) {
+ std::unique_ptr<Module> M = make_unique<Module>(Name, Context);
M->setMaterializer(R);
auto cleanupOnError = [&](std::error_code EC) {
@@ -4622,22 +4610,46 @@ getLazyBitcodeModuleImpl(std::unique_ptr
};
// Delay parsing Metadata if ShouldLazyLoadMetadata is true.
- if (std::error_code EC =
- R->parseBitcodeInto(nullptr, M.get(), ShouldLazyLoadMetadata))
+ if (std::error_code EC = R->parseBitcodeInto(std::move(Streamer), M.get(),
+ ShouldLazyLoadMetadata))
return cleanupOnError(EC);
if (MaterializeAll) {
// Read in the entire module, and destroy the BitcodeReader.
if (std::error_code EC = M->materializeAllPermanently())
- return EC;
+ return cleanupOnError(EC);
} else {
// Resolve forward references from blockaddresses.
if (std::error_code EC = R->materializeForwardReferencedFunctions())
return cleanupOnError(EC);
}
+ return std::move(M);
+}
+
+/// \brief Get a lazy one-at-time loading module from bitcode.
+///
+/// This isn't always used in a lazy context. In particular, it's also used by
+/// \a parseBitcodeFile(). If this is truly lazy, then we need to eagerly pull
+/// in forward-referenced functions from block address references.
+///
+/// \param[in] MaterializeAll Set to \c true if we should materialize
+/// everything.
+static ErrorOr<std::unique_ptr<Module>>
+getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
+ LLVMContext &Context, bool MaterializeAll,
+ DiagnosticHandlerFunction DiagnosticHandler,
+ bool ShouldLazyLoadMetadata = false) {
+ BitcodeReader *R =
+ new BitcodeReader(Buffer.get(), Context, DiagnosticHandler);
+
+ ErrorOr<std::unique_ptr<Module>> Ret =
+ getBitcodeModuleImpl(nullptr, Buffer->getBufferIdentifier(), R, Context,
+ MaterializeAll, ShouldLazyLoadMetadata);
+ if (!Ret)
+ return Ret;
Buffer.release(); // The BitcodeReader owns it now.
- return std::move(M);
+ return Ret;
}
ErrorOr<std::unique_ptr<Module>> llvm::getLazyBitcodeModule(
@@ -4652,10 +4664,9 @@ ErrorOr<std::unique_ptr<Module>> llvm::g
LLVMContext &Context, DiagnosticHandlerFunction DiagnosticHandler) {
std::unique_ptr<Module> M = make_unique<Module>(Name, Context);
BitcodeReader *R = new BitcodeReader(Context, DiagnosticHandler);
- M->setMaterializer(R);
- if (std::error_code EC = R->parseBitcodeInto(std::move(Streamer), M.get()))
- return EC;
- return std::move(M);
+
+ return getBitcodeModuleImpl(std::move(Streamer), Name, R, Context, false,
+ false);
}
ErrorOr<std::unique_ptr<Module>>
Modified: llvm/trunk/unittests/Bitcode/BitReaderTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Bitcode/BitReaderTest.cpp?rev=239871&r1=239870&r2=239871&view=diff
==============================================================================
--- llvm/trunk/unittests/Bitcode/BitReaderTest.cpp (original)
+++ llvm/trunk/unittests/Bitcode/BitReaderTest.cpp Tue Jun 16 20:15:47 2015
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#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"
@@ -16,6 +17,7 @@
#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"
@@ -58,6 +60,49 @@ static std::unique_ptr<Module> getLazyMo
return std::move(ModuleOrErr.get());
}
+class BufferDataStreamer : public DataStreamer {
+ std::unique_ptr<MemoryBuffer> 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<MemoryBuffer> Buffer)
+ : Buffer(std::move(Buffer)) {}
+};
+
+static std::unique_ptr<Module>
+getStreamedModuleFromAssembly(LLVMContext &Context, SmallString<1024> &Mem,
+ const char *Assembly) {
+ writeModuleToBuffer(parseAssembly(Assembly), Mem);
+ std::unique_ptr<MemoryBuffer> Buffer =
+ MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
+ auto Streamer = make_unique<BufferDataStreamer>(std::move(Buffer));
+ ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
+ getStreamedBitcodeModule("test", std::move(Streamer), Context);
+ return std::move(ModuleOrErr.get());
+}
+
+TEST(BitReaderTest, MateralizeForwardRefWithStream) {
+ SmallString<1024> Mem;
+
+ LLVMContext Context;
+ std::unique_ptr<Module> 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;
More information about the llvm-commits
mailing list