[llvm-branch-commits] [llvm-branch] r96832 - in /llvm/branches/Apple/Hermes: include/llvm/Bitcode/ReaderWriter.h include/llvm/ExecutionEngine/ExecutionEngine.h include/llvm/ModuleProvider.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Reader/BitcodeReader.h lib/ExecutionEngine/JIT/JIT.cpp lib/VMCore/ModuleProvider.cpp
Evan Cheng
evan.cheng at apple.com
Mon Feb 22 15:51:25 PST 2010
Author: evancheng
Date: Mon Feb 22 17:51:24 2010
New Revision: 96832
URL: http://llvm.org/viewvc/llvm-project?rev=96832&view=rev
Log:
Bring back ModuleProvider. Make BitcodeReader inherit and implement ModuleProvider and add ModuleProvider variant createJIT() to provide backward compatibility.
Added:
llvm/branches/Apple/Hermes/include/llvm/ModuleProvider.h
llvm/branches/Apple/Hermes/lib/VMCore/ModuleProvider.cpp
Modified:
llvm/branches/Apple/Hermes/include/llvm/Bitcode/ReaderWriter.h
llvm/branches/Apple/Hermes/include/llvm/ExecutionEngine/ExecutionEngine.h
llvm/branches/Apple/Hermes/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/branches/Apple/Hermes/lib/Bitcode/Reader/BitcodeReader.h
llvm/branches/Apple/Hermes/lib/ExecutionEngine/JIT/JIT.cpp
Modified: llvm/branches/Apple/Hermes/include/llvm/Bitcode/ReaderWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/include/llvm/Bitcode/ReaderWriter.h?rev=96832&r1=96831&r2=96832&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/include/llvm/Bitcode/ReaderWriter.h (original)
+++ llvm/branches/Apple/Hermes/include/llvm/Bitcode/ReaderWriter.h Mon Feb 22 17:51:24 2010
@@ -18,12 +18,22 @@
namespace llvm {
class Module;
+ class ModuleProvider;
class MemoryBuffer;
class ModulePass;
class BitstreamWriter;
class LLVMContext;
class raw_ostream;
+ /// getBitcodeModuleProvider - Read the header of the specified bitcode buffer
+ /// and prepare for lazy deserialization of function bodies. If successful,
+ /// this takes ownership of 'buffer' and returns a non-null pointer. On
+ /// error, this returns null, *does not* take ownership of Buffer, and fills
+ /// in *ErrMsg with an error description if ErrMsg is non-null.
+ ModuleProvider *getBitcodeModuleProvider(MemoryBuffer *Buffer,
+ LLVMContext& Context,
+ std::string *ErrMsg = 0);
+
/// getLazyBitcodeModule - Read the header of the specified bitcode buffer
/// and prepare for lazy deserialization of function bodies. If successful,
/// this takes ownership of 'buffer' and returns a non-null pointer. On
Modified: llvm/branches/Apple/Hermes/include/llvm/ExecutionEngine/ExecutionEngine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=96832&r1=96831&r2=96832&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/include/llvm/ExecutionEngine/ExecutionEngine.h (original)
+++ llvm/branches/Apple/Hermes/include/llvm/ExecutionEngine/ExecutionEngine.h Mon Feb 22 17:51:24 2010
@@ -37,6 +37,7 @@
class JITMemoryManager;
class MachineCodeInfo;
class Module;
+class ModuleProvider;
class MutexGuard;
class TargetData;
class Type;
@@ -168,6 +169,15 @@
///
/// Clients should make sure to initialize targets prior to calling this
/// function.
+ static ExecutionEngine *createJIT(ModuleProvider *MP,
+ std::string *ErrorStr = 0,
+ JITMemoryManager *JMM = 0,
+ CodeGenOpt::Level OptLevel =
+ CodeGenOpt::Default,
+ bool GVsWithCode = true,
+ CodeModel::Model CMM =
+ CodeModel::Default);
+
static ExecutionEngine *createJIT(Module *M,
std::string *ErrorStr = 0,
JITMemoryManager *JMM = 0,
Added: llvm/branches/Apple/Hermes/include/llvm/ModuleProvider.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/include/llvm/ModuleProvider.h?rev=96832&view=auto
==============================================================================
--- llvm/branches/Apple/Hermes/include/llvm/ModuleProvider.h (added)
+++ llvm/branches/Apple/Hermes/include/llvm/ModuleProvider.h Mon Feb 22 17:51:24 2010
@@ -0,0 +1,88 @@
+//===-- llvm/ModuleProvider.h - Interface for module providers --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides an abstract interface for loading a module from some
+// place. This interface allows incremental or random access loading of
+// functions from the file. This is useful for applications like JIT compilers
+// or interprocedural optimizers that do not need the entire program in memory
+// at the same time.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MODULEPROVIDER_H
+#define MODULEPROVIDER_H
+
+#include <string>
+
+namespace llvm {
+
+class Function;
+class Module;
+
+class ModuleProvider {
+protected:
+ Module *TheModule;
+ ModuleProvider();
+
+public:
+ virtual ~ModuleProvider();
+
+ /// getModule - returns the module this provider is encapsulating.
+ ///
+ Module* getModule() { return TheModule; }
+
+ /// materializeFunction - make sure the given function is fully read. If the
+ /// module is corrupt, this returns true and fills in the optional string
+ /// with information about the problem. If successful, this returns false.
+ ///
+ virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0) = 0;
+
+ /// dematerializeFunction - If the given function is read in, and if the
+ /// module provider supports it, release the memory for the function, and set
+ /// it up to be materialized lazily. If the provider doesn't support this
+ /// capability, this method is a noop.
+ ///
+ virtual void dematerializeFunction(Function *) {}
+
+ /// materializeModule - make sure the entire Module has been completely read.
+ /// On error, return null and fill in the error string if specified.
+ ///
+ virtual Module* materializeModule(std::string *ErrInfo = 0) = 0;
+
+ /// releaseModule - no longer delete the Module* when provider is destroyed.
+ /// On error, return null and fill in the error string if specified.
+ ///
+ virtual Module* releaseModule(std::string *ErrInfo = 0) {
+ // Since we're losing control of this Module, we must hand it back complete
+ if (!materializeModule(ErrInfo))
+ return 0;
+ Module *tempM = TheModule;
+ TheModule = 0;
+ return tempM;
+ }
+};
+
+
+/// ExistingModuleProvider - Allow conversion from a fully materialized Module
+/// into a ModuleProvider, allowing code that expects a ModuleProvider to work
+/// if we just have a Module. Note that the ModuleProvider takes ownership of
+/// the Module specified.
+struct ExistingModuleProvider : public ModuleProvider {
+ explicit ExistingModuleProvider(Module *M) {
+ TheModule = M;
+ }
+ bool materializeFunction(Function *, std::string * = 0) {
+ return false;
+ }
+ Module* materializeModule(std::string * = 0) { return TheModule; }
+};
+
+} // End llvm namespace
+
+#endif
Modified: llvm/branches/Apple/Hermes/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Bitcode/Reader/BitcodeReader.cpp?rev=96832&r1=96831&r2=96832&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/Bitcode/Reader/BitcodeReader.cpp Mon Feb 22 17:51:24 2010
@@ -18,6 +18,7 @@
#include "llvm/InlineAsm.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
#include "llvm/Operator.h"
#include "llvm/AutoUpgrade.h"
#include "llvm/ADT/SmallString.h"
@@ -2394,9 +2395,121 @@
//===----------------------------------------------------------------------===//
+// ModuleProvider implementation
+//===----------------------------------------------------------------------===//
+
+
+bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) {
+ // If it already is material, ignore the request.
+ if (!F || !F->isMaterializable()) return false;
+
+ DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F);
+ assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
+
+ // Move the bit stream to the saved position of the deferred function body.
+ Stream.JumpToBit(DFII->second);
+
+ if (ParseFunctionBody(F)) {
+ if (ErrInfo) *ErrInfo = ErrorString;
+ return true;
+ }
+
+ // Upgrade any old intrinsic calls in the function.
+ for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(),
+ E = UpgradedIntrinsics.end(); I != E; ++I) {
+ if (I->first != I->second) {
+ for (Value::use_iterator UI = I->first->use_begin(),
+ UE = I->first->use_end(); UI != UE; ) {
+ if (CallInst* CI = dyn_cast<CallInst>(*UI++))
+ UpgradeIntrinsicCall(CI, I->second);
+ }
+ }
+ }
+
+ return false;
+}
+
+void BitcodeReader::dematerializeFunction(Function *F) {
+ // If this function isn't dematerializable, this is a noop.
+ if (!F || !isDematerializable(F))
+ return;
+
+ assert(DeferredFunctionInfo.count(F) && "No info to read function later?");
+
+ // Just forget the function body, we can remat it later.
+ F->deleteBody();
+}
+
+
+Module *BitcodeReader::materializeModule(std::string *ErrInfo) {
+ // Iterate over the module, deserializing any functions that are still on
+ // disk.
+ for (Module::iterator F = TheModule->begin(), E = TheModule->end();
+ F != E; ++F)
+ if (F->isMaterializable() &&
+ Materialize(F, ErrInfo))
+ return 0;
+
+ // Upgrade any intrinsic calls that slipped through (should not happen!) and
+ // delete the old functions to clean up. We can't do this unless the entire
+ // module is materialized because there could always be another function body
+ // with calls to the old function.
+ for (std::vector<std::pair<Function*, Function*> >::iterator I =
+ UpgradedIntrinsics.begin(), E = UpgradedIntrinsics.end(); I != E; ++I) {
+ if (I->first != I->second) {
+ for (Value::use_iterator UI = I->first->use_begin(),
+ UE = I->first->use_end(); UI != UE; ) {
+ if (CallInst* CI = dyn_cast<CallInst>(*UI++))
+ UpgradeIntrinsicCall(CI, I->second);
+ }
+ if (!I->first->use_empty())
+ I->first->replaceAllUsesWith(I->second);
+ I->first->eraseFromParent();
+ }
+ }
+ std::vector<std::pair<Function*, Function*> >().swap(UpgradedIntrinsics);
+
+ // Check debug info intrinsics.
+ CheckDebugInfoIntrinsics(TheModule);
+
+ return false;
+}
+
+
+/// This method is provided by the parent ModuleProvde class and overriden
+/// here. It simply releases the module from its provided and frees up our
+/// state.
+/// @brief Release our hold on the generated module
+Module *BitcodeReader::releaseModule(std::string *ErrInfo) {
+ // Since we're losing control of this Module, we must hand it back complete
+ Module *M = ModuleProvider::releaseModule(ErrInfo);
+ FreeState();
+ return M;
+}
+
+
+//===----------------------------------------------------------------------===//
// External interface
//===----------------------------------------------------------------------===//
+/// getBitcodeModuleProvider - lazy function-at-a-time loading from a file.
+///
+ModuleProvider *llvm::getBitcodeModuleProvider(MemoryBuffer *Buffer,
+ LLVMContext& Context,
+ std::string *ErrMsg) {
+ BitcodeReader *R = new BitcodeReader(Buffer, Context);
+ if (R->ParseBitcodeInto(0)) {
+ if (ErrMsg)
+ *ErrMsg = R->getErrorString();
+
+ // Don't let the BitcodeReader dtor delete 'Buffer'.
+ R->releaseMemoryBuffer();
+ delete R;
+ return 0;
+ }
+ return R;
+}
+
/// getLazyBitcodeModule - lazy function-at-a-time loading from a file.
///
Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
Modified: llvm/branches/Apple/Hermes/lib/Bitcode/Reader/BitcodeReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Bitcode/Reader/BitcodeReader.h?rev=96832&r1=96831&r2=96832&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Bitcode/Reader/BitcodeReader.h (original)
+++ llvm/branches/Apple/Hermes/lib/Bitcode/Reader/BitcodeReader.h Mon Feb 22 17:51:24 2010
@@ -14,6 +14,7 @@
#ifndef BITCODE_READER_H
#define BITCODE_READER_H
+#include "llvm/ModuleProvider.h"
#include "llvm/GVMaterializer.h"
#include "llvm/Attributes.h"
#include "llvm/Type.h"
@@ -121,7 +122,7 @@
void AssignValue(Value *V, unsigned Idx);
};
-class BitcodeReader : public GVMaterializer {
+class BitcodeReader : public GVMaterializer, public ModuleProvider {
LLVMContext &Context;
Module *TheModule;
MemoryBuffer *Buffer;
@@ -183,10 +184,22 @@
void FreeState();
+ /// releaseMemoryBuffer - This causes the reader to completely forget about
+ /// the memory buffer it contains, which prevents the buffer from being
+ /// destroyed when it is deleted.
+ void releaseMemoryBuffer() {
+ Buffer = 0;
+ }
+
/// setBufferOwned - If this is true, the reader will destroy the MemoryBuffer
/// when the reader is destroyed.
void setBufferOwned(bool Owned) { BufferOwned = Owned; }
+ virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0);
+ virtual Module *materializeModule(std::string *ErrInfo = 0);
+ virtual void dematerializeFunction(Function *F);
+ virtual Module *releaseModule(std::string *ErrInfo = 0);
+
virtual bool isMaterializable(const GlobalValue *GV) const;
virtual bool isDematerializable(const GlobalValue *GV) const;
virtual bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0);
Modified: llvm/branches/Apple/Hermes/lib/ExecutionEngine/JIT/JIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/ExecutionEngine/JIT/JIT.cpp?rev=96832&r1=96831&r2=96832&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/ExecutionEngine/JIT/JIT.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/ExecutionEngine/JIT/JIT.cpp Mon Feb 22 17:51:24 2010
@@ -18,6 +18,7 @@
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Instructions.h"
+#include "llvm/ModuleProvider.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
#include "llvm/CodeGen/MachineCodeInfo.h"
#include "llvm/ExecutionEngine/GenericValue.h"
@@ -190,6 +191,15 @@
#endif // __APPLE__
#endif // __GNUC__
+ExecutionEngine *ExecutionEngine::createJIT(ModuleProvider *MP,
+ std::string *ErrorStr,
+ JITMemoryManager *JMM,
+ CodeGenOpt::Level OptLevel,
+ bool GVsWithCode,
+ CodeModel::Model CMM) {
+ return createJIT(MP->getModule(), ErrorStr, JMM, OptLevel, GVsWithCode, CMM);
+}
+
/// createJIT - This is the factory method for creating a JIT for the current
/// machine, it does not fall back to the interpreter. This takes ownership
/// of the module.
Added: llvm/branches/Apple/Hermes/lib/VMCore/ModuleProvider.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/VMCore/ModuleProvider.cpp?rev=96832&view=auto
==============================================================================
--- llvm/branches/Apple/Hermes/lib/VMCore/ModuleProvider.cpp (added)
+++ llvm/branches/Apple/Hermes/lib/VMCore/ModuleProvider.cpp Mon Feb 22 17:51:24 2010
@@ -0,0 +1,26 @@
+//===-- ModuleProvider.cpp - Base implementation for module providers -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Minimal implementation of the abstract interface for providing a module.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ModuleProvider.h"
+#include "llvm/Module.h"
+using namespace llvm;
+
+/// ctor - always have a valid Module
+///
+ModuleProvider::ModuleProvider() : TheModule(0) { }
+
+/// dtor - when we leave, we take our Module with us
+///
+ModuleProvider::~ModuleProvider() {
+ delete TheModule;
+}
More information about the llvm-branch-commits
mailing list