LLVM JIT对缓存编译输出的支持

LLVM JIT对缓存编译输出的支持,llvm,jit,llvm-clang,llvm-4.0,Llvm,Jit,Llvm Clang,Llvm 4.0,我试图了解如何避免每次LLVM JIT编译并使用缓存副本。我看到LLVM支持从模块生成代码,但要从文件或代码字符串中获取模块,需要对其进行编译并经过不同的优化过程。最好的办法是什么 将最终图像对象缓存到某个文件中,首先查找该文件,然后尝试解析并尝试使用该图像创建ExecutionEngine,以便执行(获取指向函数的指针并调用它) 保存代码编译和优化的中间输出-即,将模块写入某个文件(例如,使用dump)并尝试读取(parse IR)。然后使用ObjectCache支持从此模块生成代码 选项(2

我试图了解如何避免每次LLVM JIT编译并使用缓存副本。我看到LLVM支持从模块生成代码,但要从文件或代码字符串中获取模块,需要对其进行编译并经过不同的优化过程。最好的办法是什么

  • 将最终图像对象缓存到某个文件中,首先查找该文件,然后尝试解析并尝试使用该图像创建
    ExecutionEngine
    ,以便执行(获取指向函数的指针并调用它)

  • 保存代码编译和优化的中间输出-即,将模块写入某个文件(例如,使用dump)并尝试读取(parse IR)。然后使用
    ObjectCache
    支持从此模块生成代码


  • 选项(2)似乎有两个步骤,可能比(1)更糟,但(1)是正确的方法吗?

    如果您有
    ObjectFile
    的实例,您可以将其写入磁盘:

    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();
    
    然后您可以从磁盘读回它:

    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();
    
    std::string cacheName(“some_name.o”);
    错误缓冲区=
    MemoryBuffer::getFile(cacheName.c_str());
    如果(!缓冲区){
    //处理错误
    }
    预期对象错误=
    ObjectFile::createObjectFile(buffer.get()->getMemBufferRef());
    如果(!objectOrError){
    //处理错误
    }
    std::unique_ptr objectFile(std::move(objectOrError.get());
    auto-owningObject=OwningBinary(std::move(objectFile),
    std::move(buffer.get());
    auto object=owningObject.getBinary();
    
    您可以获取此代码并将其插入自定义的
    ObjectCache
    ,然后将对象缓存提供给JIT引擎


    我希望这能有所帮助。

    请你再澄清一点,你到底想实现什么目标?在第一个选项中,您混合了目标代码和位代码,它们是不同的东西。你试图缓存什么?目标文件(机器代码)或位代码文件(LLVM IR)?理想情况下是目标文件(机器代码),因此我们不需要编译和生成机器代码。所以第一个选项似乎无效——或者是否也有API可用于转储对象代码(此处转储有用)?