libLTO: Allow LTOModule to own a context
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Tue, 11 Nov 2014 23:08:05 +0000 (23:08 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Tue, 11 Nov 2014 23:08:05 +0000 (23:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221728 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/LTO/LTOCodeGenerator.h
include/llvm/LTO/LTOModule.h
lib/LTO/LTOModule.cpp

index f93f013b7c608a5a333cd51062f09a7c0919a152..0c9ce4a54f02a7dc95008cffe3068e1d32063374 100644 (file)
@@ -119,6 +119,8 @@ struct LTOCodeGenerator {
 
   void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
 
+  LLVMContext &getContext() { return Context; }
+
 private:
   void initializeLTOPasses();
 
index fc583a20f6829f1eddb8b4f9ec2514066b619ffc..23b1fce435b96ec2a5c1d96dce2f9ff2f18dc7d4 100644 (file)
@@ -46,6 +46,8 @@ private:
     const GlobalValue *symbol;
   };
 
+  std::unique_ptr<LLVMContext> OwnedContext;
+
   std::unique_ptr<object::IRObjectFile> IRFile;
   std::unique_ptr<TargetMachine> _target;
   StringSet                               _linkeropt_strings;
@@ -59,8 +61,12 @@ private:
   std::vector<const char*>                _asm_undefines;
 
   LTOModule(std::unique_ptr<object::IRObjectFile> Obj, TargetMachine *TM);
+  LTOModule(std::unique_ptr<object::IRObjectFile> Obj, TargetMachine *TM,
+            std::unique_ptr<LLVMContext> Context);
 
 public:
+  ~LTOModule();
+
   /// Returns 'true' if the file or memory contents is LLVM bitcode.
   static bool isBitcodeFile(const void *mem, size_t length);
   static bool isBitcodeFile(const char *path);
@@ -95,6 +101,13 @@ public:
                                      TargetOptions options, std::string &errMsg,
                                      StringRef path = "");
 
+  static LTOModule *createInLocalContext(const void *mem, size_t length,
+                                         TargetOptions options,
+                                         std::string &errMsg, StringRef path);
+  static LTOModule *createInContext(const void *mem, size_t length,
+                                    TargetOptions options, std::string &errMsg,
+                                    StringRef path, LLVMContext *Context);
+
   const Module &getModule() const {
     return const_cast<LTOModule*>(this)->getModule();
   }
@@ -204,7 +217,7 @@ private:
 
   /// Create an LTOModule (private version).
   static LTOModule *makeLTOModule(MemoryBufferRef Buffer, TargetOptions options,
-                                  std::string &errMsg);
+                                  std::string &errMsg, LLVMContext *Context);
 };
 }
 #endif
index b9320d24cc3ae5159fb37ab41c0242c20e309a8c..34e7f51c7bfb5202aaf68bce7015404f0278f60e 100644 (file)
@@ -52,6 +52,13 @@ LTOModule::LTOModule(std::unique_ptr<object::IRObjectFile> Obj,
                      llvm::TargetMachine *TM)
     : IRFile(std::move(Obj)), _target(TM) {}
 
+LTOModule::LTOModule(std::unique_ptr<object::IRObjectFile> Obj,
+                     llvm::TargetMachine *TM,
+                     std::unique_ptr<LLVMContext> Context)
+    : OwnedContext(std::move(Context)), IRFile(std::move(Obj)), _target(TM) {}
+
+LTOModule::~LTOModule() {}
+
 /// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
 /// bitcode.
 bool LTOModule::isBitcodeFile(const void *Mem, size_t Length) {
@@ -77,7 +84,8 @@ bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer,
       IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef());
   if (!BCOrErr)
     return false;
-  std::string Triple = getBitcodeTargetTriple(*BCOrErr, getGlobalContext());
+  LLVMContext Context;
+  std::string Triple = getBitcodeTargetTriple(*BCOrErr, Context);
   return StringRef(Triple).startswith(TriplePrefix);
 }
 
@@ -90,7 +98,8 @@ LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options,
     return nullptr;
   }
   std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
-  return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg);
+  return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg,
+                       &getGlobalContext());
 }
 
 LTOModule *LTOModule::createFromOpenFile(int fd, const char *path, size_t size,
@@ -110,27 +119,49 @@ LTOModule *LTOModule::createFromOpenFileSlice(int fd, const char *path,
     return nullptr;
   }
   std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
-  return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg);
+  return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg,
+                       &getGlobalContext());
 }
 
 LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length,
                                        TargetOptions options,
                                        std::string &errMsg, StringRef path) {
+  return createInContext(mem, length, options, errMsg, path,
+                         &getGlobalContext());
+}
+
+LTOModule *LTOModule::createInLocalContext(const void *mem, size_t length,
+                                           TargetOptions options,
+                                           std::string &errMsg,
+                                           StringRef path) {
+  return createInContext(mem, length, options, errMsg, path, nullptr);
+}
+
+LTOModule *LTOModule::createInContext(const void *mem, size_t length,
+                                      TargetOptions options,
+                                      std::string &errMsg, StringRef path,
+                                      LLVMContext *Context) {
   StringRef Data((const char *)mem, length);
   MemoryBufferRef Buffer(Data, path);
-  return makeLTOModule(Buffer, options, errMsg);
+  return makeLTOModule(Buffer, options, errMsg, Context);
 }
 
 LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer,
-                                    TargetOptions options,
-                                    std::string &errMsg) {
+                                    TargetOptions options, std::string &errMsg,
+                                    LLVMContext *Context) {
+  std::unique_ptr<LLVMContext> OwnedContext;
+  if (!Context) {
+    OwnedContext = llvm::make_unique<LLVMContext>();
+    Context = OwnedContext.get();
+  }
+
   ErrorOr<MemoryBufferRef> MBOrErr =
       IRObjectFile::findBitcodeInMemBuffer(Buffer);
   if (std::error_code EC = MBOrErr.getError()) {
     errMsg = EC.message();
     return nullptr;
   }
-  ErrorOr<Module *> MOrErr = parseBitcodeFile(*MBOrErr, getGlobalContext());
+  ErrorOr<Module *> MOrErr = parseBitcodeFile(*MBOrErr, *Context);
   if (std::error_code EC = MOrErr.getError()) {
     errMsg = EC.message();
     return nullptr;
@@ -169,7 +200,11 @@ LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer,
   std::unique_ptr<object::IRObjectFile> IRObj(
       new object::IRObjectFile(Buffer, std::move(M)));
 
-  LTOModule *Ret = new LTOModule(std::move(IRObj), target);
+  LTOModule *Ret;
+  if (OwnedContext)
+    Ret = new LTOModule(std::move(IRObj), target, std::move(OwnedContext));
+  else
+    Ret = new LTOModule(std::move(IRObj), target);
 
   if (Ret->parseSymbols(errMsg)) {
     delete Ret;