Pass a MemoryBufferRef when we can avoid taking ownership.

The attached patch simplifies a few interfaces that don't need to take
ownership of a buffer.

For example, both parseAssembly and parseBitcodeFile will parse the
entire buffer before returning. There is no need to take ownership.

Using a MemoryBufferRef makes it obvious in the type signature that
there is no ownership transfer.

llvm-svn: 216488
This commit is contained in:
Rafael Espindola 2014-08-26 21:49:01 +00:00
parent 59953f0dbe
commit d96d553d76
16 changed files with 58 additions and 71 deletions

View File

@ -14,13 +14,11 @@
#ifndef LLVM_ASMPARSER_PARSER_H #ifndef LLVM_ASMPARSER_PARSER_H
#define LLVM_ASMPARSER_PARSER_H #define LLVM_ASMPARSER_PARSER_H
#include "llvm/ADT/StringRef.h" #include "llvm/Support/MemoryBuffer.h"
#include <memory>
namespace llvm { namespace llvm {
class Module; class Module;
class MemoryBuffer;
class SMDiagnostic; class SMDiagnostic;
class LLVMContext; class LLVMContext;
@ -55,8 +53,8 @@ std::unique_ptr<Module> parseAssemblyString(StringRef AsmString,
/// @param F The MemoryBuffer containing assembly /// @param F The MemoryBuffer containing assembly
/// @param Err Error result info. /// @param Err Error result info.
/// @param Context Context in which to allocate globals info. /// @param Context Context in which to allocate globals info.
std::unique_ptr<Module> parseAssembly(std::unique_ptr<MemoryBuffer> F, std::unique_ptr<Module> parseAssembly(MemoryBufferRef F, SMDiagnostic &Err,
SMDiagnostic &Err, LLVMContext &Context); LLVMContext &Context);
/// This function is the low-level interface to the LLVM Assembly Parser. /// This function is the low-level interface to the LLVM Assembly Parser.
/// This is kept as an independent function instead of being inlined into /// This is kept as an independent function instead of being inlined into
@ -67,8 +65,7 @@ std::unique_ptr<Module> parseAssembly(std::unique_ptr<MemoryBuffer> F,
/// @param M The module to add data to. /// @param M The module to add data to.
/// @param Err Error result info. /// @param Err Error result info.
/// @return true on error. /// @return true on error.
bool parseAssemblyInto(std::unique_ptr<MemoryBuffer> F, Module &M, bool parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err);
SMDiagnostic &Err);
} // End llvm namespace } // End llvm namespace

View File

@ -15,11 +15,11 @@
#define LLVM_BITCODE_READERWRITER_H #define LLVM_BITCODE_READERWRITER_H
#include "llvm/Support/ErrorOr.h" #include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MemoryBuffer.h"
#include <string> #include <string>
namespace llvm { namespace llvm {
class BitstreamWriter; class BitstreamWriter;
class MemoryBuffer;
class DataStreamer; class DataStreamer;
class LLVMContext; class LLVMContext;
class Module; class Module;
@ -42,14 +42,13 @@ namespace llvm {
std::string *ErrMsg = nullptr); std::string *ErrMsg = nullptr);
/// Read the header of the specified bitcode buffer and extract just the /// Read the header of the specified bitcode buffer and extract just the
/// triple information. If successful, this returns a string and *does not* /// triple information. If successful, this returns a string. On error, this
/// take ownership of 'buffer'. On error, this returns "". /// returns "".
std::string getBitcodeTargetTriple(MemoryBuffer *Buffer, std::string getBitcodeTargetTriple(MemoryBufferRef Buffer,
LLVMContext &Context); LLVMContext &Context);
/// Read the specified bitcode file, returning the module. /// Read the specified bitcode file, returning the module.
/// This method *never* takes ownership of Buffer. ErrorOr<Module *> parseBitcodeFile(MemoryBufferRef Buffer,
ErrorOr<Module *> parseBitcodeFile(MemoryBuffer *Buffer,
LLVMContext &Context); LLVMContext &Context);
/// WriteBitcodeToFile - Write the specified module to the specified /// WriteBitcodeToFile - Write the specified module to the specified

View File

@ -54,8 +54,6 @@ public:
/// Make sure the entire Module has been completely read. /// Make sure the entire Module has been completely read.
/// ///
virtual std::error_code MaterializeModule(Module *M) = 0; virtual std::error_code MaterializeModule(Module *M) = 0;
virtual void releaseBuffer() = 0;
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -483,7 +483,7 @@ public:
/// Make sure all GlobalValues in this Module are fully read and clear the /// Make sure all GlobalValues in this Module are fully read and clear the
/// Materializer. If the module is corrupt, this DOES NOT clear the old /// Materializer. If the module is corrupt, this DOES NOT clear the old
/// Materializer. /// Materializer.
std::error_code materializeAllPermanently(bool ReleaseBuffer = false); std::error_code materializeAllPermanently();
/// @} /// @}
/// @name Direct access to the globals list, functions list, and symbol table /// @name Direct access to the globals list, functions list, and symbol table

View File

@ -15,14 +15,12 @@
#ifndef LLVM_IRREADER_IRREADER_H #ifndef LLVM_IRREADER_IRREADER_H
#define LLVM_IRREADER_IRREADER_H #define LLVM_IRREADER_IRREADER_H
#include "llvm/ADT/StringRef.h" #include "llvm/Support/MemoryBuffer.h"
#include <memory>
#include <string> #include <string>
namespace llvm { namespace llvm {
class Module; class Module;
class MemoryBuffer;
class SMDiagnostic; class SMDiagnostic;
class LLVMContext; class LLVMContext;
@ -36,8 +34,8 @@ std::unique_ptr<Module> getLazyIRFileModule(StringRef Filename,
/// If the given MemoryBuffer holds a bitcode image, return a Module /// If the given MemoryBuffer holds a bitcode image, return a Module
/// for it. Otherwise, attempt to parse it as LLVM Assembly and return /// for it. Otherwise, attempt to parse it as LLVM Assembly and return
/// a Module for it. This function *never* takes ownership of Buffer. /// a Module for it.
std::unique_ptr<Module> parseIR(MemoryBuffer *Buffer, SMDiagnostic &Err, std::unique_ptr<Module> parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err,
LLVMContext &Context); LLVMContext &Context);
/// If the given file holds a bitcode image, return a Module for it. /// If the given file holds a bitcode image, return a Module for it.

View File

@ -102,6 +102,9 @@ public:
StringRef BufferName = "", StringRef BufferName = "",
bool RequiresNullTerminator = true); bool RequiresNullTerminator = true);
static std::unique_ptr<MemoryBuffer>
getMemBuffer(MemoryBufferRef Ref, bool RequiresNullTerminator = true);
/// Open the specified memory range as a MemoryBuffer, copying the contents /// Open the specified memory range as a MemoryBuffer, copying the contents
/// and taking ownership of it. InputData does not have to be null terminated. /// and taking ownership of it. InputData does not have to be null terminated.
static MemoryBuffer *getMemBufferCopy(StringRef InputData, static MemoryBuffer *getMemBufferCopy(StringRef InputData,

View File

@ -21,22 +21,21 @@
#include <system_error> #include <system_error>
using namespace llvm; using namespace llvm;
bool llvm::parseAssemblyInto(std::unique_ptr<MemoryBuffer> F, Module &M, bool llvm::parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err) {
SMDiagnostic &Err) {
SourceMgr SM; SourceMgr SM;
StringRef Buf = F->getBuffer(); std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F, false);
SM.AddNewSourceBuffer(std::move(F), SMLoc()); SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
return LLParser(Buf, SM, Err, &M).Run(); return LLParser(F.getBuffer(), SM, Err, &M).Run();
} }
std::unique_ptr<Module> llvm::parseAssembly(std::unique_ptr<MemoryBuffer> F, std::unique_ptr<Module> llvm::parseAssembly(MemoryBufferRef F,
SMDiagnostic &Err, SMDiagnostic &Err,
LLVMContext &Context) { LLVMContext &Context) {
std::unique_ptr<Module> M = std::unique_ptr<Module> M =
make_unique<Module>(F->getBufferIdentifier(), Context); make_unique<Module>(F.getBufferIdentifier(), Context);
if (parseAssemblyInto(std::move(F), *M, Err)) if (parseAssemblyInto(F, *M, Err))
return nullptr; return nullptr;
return std::move(M); return std::move(M);
@ -53,14 +52,12 @@ std::unique_ptr<Module> llvm::parseAssemblyFile(StringRef Filename,
return nullptr; return nullptr;
} }
return parseAssembly(std::move(FileOrErr.get()), Err, Context); return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context);
} }
std::unique_ptr<Module> llvm::parseAssemblyString(StringRef AsmString, std::unique_ptr<Module> llvm::parseAssemblyString(StringRef AsmString,
SMDiagnostic &Err, SMDiagnostic &Err,
LLVMContext &Context) { LLVMContext &Context) {
std::unique_ptr<MemoryBuffer> F( MemoryBufferRef F(AsmString, "<string>");
MemoryBuffer::getMemBuffer(AsmString, "<string>")); return parseAssembly(F, Err, Context);
return parseAssembly(std::move(F), Err, Context);
} }

View File

@ -31,7 +31,7 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
LLVMModuleRef *OutModule, LLVMModuleRef *OutModule,
char **OutMessage) { char **OutMessage) {
ErrorOr<Module *> ModuleOrErr = ErrorOr<Module *> ModuleOrErr =
parseBitcodeFile(unwrap(MemBuf), *unwrap(ContextRef)); parseBitcodeFile(unwrap(MemBuf)->getMemBufferRef(), *unwrap(ContextRef));
if (std::error_code EC = ModuleOrErr.getError()) { if (std::error_code EC = ModuleOrErr.getError()) {
if (OutMessage) if (OutMessage)
*OutMessage = strdup(EC.message().c_str()); *OutMessage = strdup(EC.message().c_str());

View File

@ -3564,15 +3564,17 @@ Module *llvm::getStreamedBitcodeModule(const std::string &name,
return M; return M;
} }
ErrorOr<Module *> llvm::parseBitcodeFile(MemoryBuffer *Buffer, ErrorOr<Module *> llvm::parseBitcodeFile(MemoryBufferRef Buffer,
LLVMContext &Context) { LLVMContext &Context) {
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
ErrorOr<Module *> ModuleOrErr = ErrorOr<Module *> ModuleOrErr =
getLazyBitcodeModuleImpl(Buffer, Context, true); getLazyBitcodeModuleImpl(Buf.get(), Context, true);
if (!ModuleOrErr) if (!ModuleOrErr)
return ModuleOrErr; return ModuleOrErr;
Buf.release(); // The BitcodeReader owns it now.
Module *M = ModuleOrErr.get(); Module *M = ModuleOrErr.get();
// Read in the entire module, and destroy the BitcodeReader. // Read in the entire module, and destroy the BitcodeReader.
if (std::error_code EC = M->materializeAllPermanently(true)) { if (std::error_code EC = M->materializeAllPermanently()) {
delete M; delete M;
return EC; return EC;
} }
@ -3583,12 +3585,11 @@ ErrorOr<Module *> llvm::parseBitcodeFile(MemoryBuffer *Buffer,
return M; return M;
} }
std::string llvm::getBitcodeTargetTriple(MemoryBuffer *Buffer, std::string llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer,
LLVMContext &Context) { LLVMContext &Context) {
BitcodeReader *R = new BitcodeReader(Buffer, Context); std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
auto R = llvm::make_unique<BitcodeReader>(Buf.get(), Context);
ErrorOr<std::string> Triple = R->parseTriple(); ErrorOr<std::string> Triple = R->parseTriple();
R->releaseBuffer();
delete R;
if (Triple.getError()) if (Triple.getError())
return ""; return "";
return Triple.get(); return Triple.get();

View File

@ -221,7 +221,7 @@ public:
void FreeState(); void FreeState();
void releaseBuffer() override; void releaseBuffer();
bool isMaterializable(const GlobalValue *GV) const override; bool isMaterializable(const GlobalValue *GV) const override;
bool isDematerializable(const GlobalValue *GV) const override; bool isDematerializable(const GlobalValue *GV) const override;

View File

@ -413,13 +413,10 @@ std::error_code Module::materializeAll() {
return Materializer->MaterializeModule(this); return Materializer->MaterializeModule(this);
} }
std::error_code Module::materializeAllPermanently(bool ReleaseBuffer) { std::error_code Module::materializeAllPermanently() {
if (std::error_code EC = materializeAll()) if (std::error_code EC = materializeAll())
return EC; return EC;
if (ReleaseBuffer)
Materializer->releaseBuffer();
Materializer.reset(); Materializer.reset();
return std::error_code(); return std::error_code();
} }

View File

@ -46,7 +46,7 @@ getLazyIRModule(std::unique_ptr<MemoryBuffer> Buffer, SMDiagnostic &Err,
return std::unique_ptr<Module>(ModuleOrErr.get()); return std::unique_ptr<Module>(ModuleOrErr.get());
} }
return parseAssembly(std::move(Buffer), Err, Context); return parseAssembly(Buffer->getMemBufferRef(), Err, Context);
} }
std::unique_ptr<Module> llvm::getLazyIRFileModule(StringRef Filename, std::unique_ptr<Module> llvm::getLazyIRFileModule(StringRef Filename,
@ -63,24 +63,22 @@ std::unique_ptr<Module> llvm::getLazyIRFileModule(StringRef Filename,
return getLazyIRModule(std::move(FileOrErr.get()), Err, Context); return getLazyIRModule(std::move(FileOrErr.get()), Err, Context);
} }
std::unique_ptr<Module> llvm::parseIR(MemoryBuffer *Buffer, SMDiagnostic &Err, std::unique_ptr<Module> llvm::parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err,
LLVMContext &Context) { LLVMContext &Context) {
NamedRegionTimer T(TimeIRParsingName, TimeIRParsingGroupName, NamedRegionTimer T(TimeIRParsingName, TimeIRParsingGroupName,
TimePassesIsEnabled); TimePassesIsEnabled);
if (isBitcode((const unsigned char *)Buffer->getBufferStart(), if (isBitcode((const unsigned char *)Buffer.getBufferStart(),
(const unsigned char *)Buffer->getBufferEnd())) { (const unsigned char *)Buffer.getBufferEnd())) {
ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(Buffer, Context); ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(Buffer, Context);
if (std::error_code EC = ModuleOrErr.getError()) { if (std::error_code EC = ModuleOrErr.getError()) {
Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error, Err = SMDiagnostic(Buffer.getBufferIdentifier(), SourceMgr::DK_Error,
EC.message()); EC.message());
return nullptr; return nullptr;
} }
return std::unique_ptr<Module>(ModuleOrErr.get()); return std::unique_ptr<Module>(ModuleOrErr.get());
} }
return parseAssembly(std::unique_ptr<MemoryBuffer>(MemoryBuffer::getMemBuffer( return parseAssembly(Buffer, Err, Context);
Buffer->getBuffer(), Buffer->getBufferIdentifier())),
Err, Context);
} }
std::unique_ptr<Module> llvm::parseIRFile(StringRef Filename, SMDiagnostic &Err, std::unique_ptr<Module> llvm::parseIRFile(StringRef Filename, SMDiagnostic &Err,
@ -93,7 +91,7 @@ std::unique_ptr<Module> llvm::parseIRFile(StringRef Filename, SMDiagnostic &Err,
return nullptr; return nullptr;
} }
return parseIR(FileOrErr.get().get(), Err, Context); return parseIR(FileOrErr.get()->getMemBufferRef(), Err, Context);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -106,7 +104,8 @@ LLVMBool LLVMParseIRInContext(LLVMContextRef ContextRef,
SMDiagnostic Diag; SMDiagnostic Diag;
std::unique_ptr<MemoryBuffer> MB(unwrap(MemBuf)); std::unique_ptr<MemoryBuffer> MB(unwrap(MemBuf));
*OutM = wrap(parseIR(MB.get(), Diag, *unwrap(ContextRef)).release()); *OutM =
wrap(parseIR(MB->getMemBufferRef(), Diag, *unwrap(ContextRef)).release());
if(!*OutM) { if(!*OutM) {
if (OutMessage) { if (OutMessage) {

View File

@ -65,7 +65,8 @@ bool LTOModule::isBitcodeFile(const char *path) {
bool LTOModule::isBitcodeForTarget(MemoryBuffer *buffer, bool LTOModule::isBitcodeForTarget(MemoryBuffer *buffer,
StringRef triplePrefix) { StringRef triplePrefix) {
std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext()); std::string Triple =
getBitcodeTargetTriple(buffer->getMemBufferRef(), getGlobalContext());
return StringRef(Triple).startswith(triplePrefix); return StringRef(Triple).startswith(triplePrefix);
} }
@ -112,14 +113,7 @@ LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length,
LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer,
TargetOptions options, TargetOptions options,
std::string &errMsg) { std::string &errMsg) {
StringRef Data = Buffer.getBuffer(); ErrorOr<Module *> MOrErr = parseBitcodeFile(Buffer, getGlobalContext());
StringRef FileName = Buffer.getBufferIdentifier();
std::unique_ptr<MemoryBuffer> MemBuf(
makeBuffer(Data.begin(), Data.size(), FileName));
if (!MemBuf)
return nullptr;
ErrorOr<Module *> MOrErr = parseBitcodeFile(MemBuf.get(), getGlobalContext());
if (std::error_code EC = MOrErr.getError()) { if (std::error_code EC = MOrErr.getError()) {
errMsg = EC.message(); errMsg = EC.message();
return nullptr; return nullptr;

View File

@ -268,10 +268,7 @@ ErrorOr<IRObjectFile *>
llvm::object::IRObjectFile::createIRObjectFile(MemoryBufferRef Object, llvm::object::IRObjectFile::createIRObjectFile(MemoryBufferRef Object,
LLVMContext &Context) { LLVMContext &Context) {
StringRef Data = Object.getBuffer(); std::unique_ptr<MemoryBuffer> Buff(MemoryBuffer::getMemBuffer(Object, false));
StringRef FileName = Object.getBufferIdentifier();
std::unique_ptr<MemoryBuffer> Buff(
MemoryBuffer::getMemBuffer(Data, FileName, false));
ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Buff.get(), Context); ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Buff.get(), Context);
if (std::error_code EC = MOrErr.getError()) if (std::error_code EC = MOrErr.getError())

View File

@ -103,6 +103,12 @@ MemoryBuffer *MemoryBuffer::getMemBuffer(StringRef InputData,
MemoryBufferMem(InputData, RequiresNullTerminator); MemoryBufferMem(InputData, RequiresNullTerminator);
} }
std::unique_ptr<MemoryBuffer>
MemoryBuffer::getMemBuffer(MemoryBufferRef Ref, bool RequiresNullTerminator) {
return std::unique_ptr<MemoryBuffer>(getMemBuffer(
Ref.getBuffer(), Ref.getBufferIdentifier(), RequiresNullTerminator));
}
/// getMemBufferCopy - Open the specified memory range as a MemoryBuffer, /// getMemBufferCopy - Open the specified memory range as a MemoryBuffer,
/// copying the contents and taking ownership of it. This has no requirements /// copying the contents and taking ownership of it. This has no requirements
/// on EndPtr[0]. /// on EndPtr[0].

View File

@ -157,7 +157,8 @@ std::unique_ptr<Module> TempFile::readBitcode(LLVMContext &Context) const {
} }
MemoryBuffer *Buffer = BufferOr.get().get(); MemoryBuffer *Buffer = BufferOr.get().get();
ErrorOr<Module *> ModuleOr = parseBitcodeFile(Buffer, Context); ErrorOr<Module *> ModuleOr =
parseBitcodeFile(Buffer->getMemBufferRef(), Context);
if (!ModuleOr) { if (!ModuleOr) {
DEBUG(dbgs() << "error: " << ModuleOr.getError().message() << "\n"); DEBUG(dbgs() << "error: " << ModuleOr.getError().message() << "\n");
return nullptr; return nullptr;