[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