4

I am trying to see how to avoid LLVM JIT compilation every time and use the cached copy. I see that LLVM has ObjectCache support for code generation from module, but to get module from a file or code string, it needs to be compiled and go through different optimization passes. What is the best way to go about it?

  1. Cache the final image object to some file and first lookup the file, and try to parse and try to create ExecutionEngine with the image so that one can execute (get pointer to function and call it)

  2. Save the intermediate output of code compilation and optimization - i.e. write a module to some file (e.g., using dump) and try to read it (parse IR). then use ObjectCache support for code generation from this module.

Option (2) seems two steps and likely worse than (1), but is (1) the right way to go about it?

Aana
  • 71
  • 6
  • Could you please clarify a bit more what exactly are you trying to achieve? In the first option you are mixing object code and bitcode, which are different things. What do you try to cache? Object files (machine code) or bitcode files (LLVM IR)? – AlexDenisov Jan 03 '18 at 23:35
  • ideally object files (machine code), so that we don't need to do compile as well as generate machine code. so first option does not seem valid - or are there apis available to dump object code as well (would dump useful here)? – Aana Jan 04 '18 at 00:35

1 Answers1

3

Given that you have an instance of ObjectFile you can write it to the disk:

std::string cacheName("some_name.o");
std::error_code EC;
raw_fd_ostream outfile(cacheName, EC, sys::fs::F_None);
outfile.write(object.getBinary()->getMemoryBufferRef().getBufferStart(),
              object.getBinary()->getMemoryBufferRef().getBufferSize());
outfile.close();

Then you can read it back from disk:

std::string cacheName("some_name.o");

ErrorOr<std::unique_ptr<MemoryBuffer>> buffer =
  MemoryBuffer::getFile(cacheName.c_str());

if (!buffer) {
  // handle error
}

Expected<std::unique_ptr<ObjectFile>> objectOrError =
  ObjectFile::createObjectFile(buffer.get()->getMemBufferRef());

if (!objectOrError) {
  // handle error
}

std::unique_ptr<ObjectFile> objectFile(std::move(objectOrError.get()));

auto owningObject = OwningBinary<ObjectFile>(std::move(objectFile),
                                             std::move(buffer.get()));
auto object = owningObject.getBinary();

You can take this code and plug it in your custom ObjectCache, then feed the object cache to the JIT engine.

I hope it helps.

AlexDenisov
  • 4,022
  • 25
  • 31