Is there a way to output an llvm jit module into file? - c++

I'd like to save a llvm module into file xxx.ll
maybe the code just like
llvm::module M;
...
ofstream << M;
Is there given function in llvm? or we need do some transformation for M then we can use ofstream
I'm using llvm 14

There is a llvm::Module::print method. You'll also need to construct llvm::raw_os_ostream.

Related

Get textual representation of LLVM IR from module obejct

I'm currently working on a compiler for a C/C++ like language. I have reached the compiling phase of code generation. I'm using the LLVM C++ api to create an LLVM IR from the input file.
As far as I understood it my module object (I'm working with just one module) should contain all information I need for getting the textual representation of the LLVM IR as a string.
But I really don't know how to do that.
If you wish to get the LLVM IR of your llvm::Module you can use the llvm::Module::print function. Use this in combination with the LLVM standard streams like this:
llvm::Module module = ...
module.print(llvm::errs()); // for stderr, llvm::outs() for stdout
See also dump():
module.dump(); // print to stderr
Or use raw_ostream
llvm::outs() << module;
// or
llvm::errs() << module;
// or
llvm::dbgs() << module;

LLVM JIT support for caching compiled output

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?
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)
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?
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.

generate machine code directly via LLVM API

With the following code, I can generate an LLVM bitcode file from a module:
llvm::Module * module;
// fill module with code
module = ...;
std::error_code ec;
llvm::raw_fd_ostream out("anonymous.bc", ec, llvm::sys::fs::F_None);
llvm::WriteBitcodeToFile(module, out);
I can then use that bitcode file to generate an executable machine code file, e.g.:
clang -o anonymous anonymous.bc
Alternatively:
llc anonymous.bc
gcc -o anonymous anonymous.s
My question now is: Can I generate the machine code directly in C++ with the LLVM API without first needing to write the bitcode file?
I am looking for either a code example or at least some starting points in the LLVM API, e.g. which classes to use, nudging me in the right direction might even be enough.
I was also looking for the code for this, and #arrowd's suggestion worked.
To save the trouble for the next person, this is what I came up with.
Given a Module, it generates assembly code on stdout for your native target:
void printASM(Module *M) {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
auto TargetTriple = sys::getDefaultTargetTriple();
M->setTargetTriple(TargetTriple);
std::string Error;
const Target *target = TargetRegistry::lookupTarget(TargetTriple, Error);
auto cpu = sys::getHostCPUName();
SubtargetFeatures Features;
StringMap<bool> HostFeatures;
if (sys::getHostCPUFeatures(HostFeatures))
for (auto &F : HostFeatures)
Features.AddFeature(F.first(), F.second);
auto features = Features.getString();
TargetOptions Options;
std::unique_ptr<TargetMachine> TM{
target->createTargetMachine(
TargetTriple, cpu, features, Options,
Reloc::PIC_, None, CodeGenOpt::None)
};
legacy::PassManager PM;
M->setDataLayout(TM->createDataLayout());
TM->addPassesToEmitFile(PM, (raw_pwrite_stream &) outs(), (raw_pwrite_stream *) (&outs()),
TargetMachine::CodeGenFileType::CGFT_AssemblyFile, true, nullptr);
PM.run(*M);
}
If anyone knows a shorter way to write this code, feel free to correct me!
Take a look at llc tool source, spcifically compileModule() function. In short, it creates Target, sets some options for it via TargetOptions, then uses it to addPassesToEmitFile() and finally asks PassManager to perform all planned tasks.

How to intercept LLVM lli tool input?

I'd like to use LLVM lli tool as static library (rename main() to lli() and export it in libLLi.a) - to create rich UI for it. How can i modify it (or use without modifications) in order to intercept stdin?
Assume i know how to generate LLVM assembly file (using clang -S -emit-llvm .. -o output.ll) and how to execute it using lli tool (lli output.ll).
Common use case:
Source code of simple app to be interpreted by lli:
#include <iostream>
using namespace std;
int main() {
char name[128];
cout << "type your name: ";
cin.getline(name, sizeof(name));
cout << "hi, " << name << endl;
return 0;
}
I need to interpret LLVM assembly for it and to show InputBox when cin.getline invoked and show TextBox when cout << invoked (InputBox and TextBox are rich UI controls).
PS. I can't fork process and forward stdin/stdout of the whole child process.
lli is already a thin wrapper around llvm library functions, just use those instead. The main() function in tools/lli/lli.cpp is long only because it supports tons of flags to control every possible setting. After you strip it down it should be less than 10 lines to create an ExecutionEngine using an EngineBuilder and use it to run a llvm::Function.
You might also find chapter 4 of the Kaleidoscope tutorial helpful, where they add JIT support to the language. This also demonstrates how to use an EngineBuilder, though the ExecutionEngine they choose to build is a JIT instead of an Interpreter, you can customize it for your use case.
Now for the other part of your question, how do you trap stdin and stdout? LLVM is not a VM, the code is running in your process and using your stdin and stdout. My first suggestion is that since you already have the function in LLVM IR format, just run a transformation pass that replaces standard I/O functions with your own I/O functions. A simpler way to do that if you can get the ABI to line up, is to do the remapping with the ExecutionEngine. Call EE->updateGlobalMapping(functionDeclInIR, &replacementFunctionInNativeCode) to tell the ExecutionEngine that the Function* for functionDeclInIR is represented in native code by replacementFunctionInNativeCode. You would need to provide your own implementation of _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc (aka. ostream::operator<<) which uses your GUI.

How to execute a bitcode file with LLVM 3.3?

I'm starting to program with LLVM, and trying to execute a bitcode.
I came up to this code, adapted from old examples (my doubt is in the creation of the MemoryBuffer, getFile(string) does not exist anymore):
string *errorString = new string;
LLVMContext context;
OwningPtr<MemoryBuffer> *mb = new OwningPtr<MemoryBuffer>;
MemoryBuffer::getFileOrSTDIN(argv[1], *mb);
Module *m = ParseBitcodeFile(mb->take(), context, errorString);
ExecutionEngine *ee = EngineBuilder(m).create();
Function *main = m->getFunction("main");
From this line on nothing works (segmentation fault)
1 - "standard" approach?
void * f = ee->getPointerToFunction(main);
void (*FP)() = (void (*)()) f;
2 - lli's approach, not sure about the '0' for envp
vector<string> *argList = new vector<string>;
ee->runFunctionAsMain(main, *argList, 0);
3 - a generalization of 2.
vector<struct GenericValue> *argList = new vector<struct GenericValue>;
ee->runFunction(main, *argList);
The lli tool is your reference here. As an official LLVM tool and part of the repository and releases, it is always up to date with the latest LLVM APIs. The file tools/lli/lli.cpp is just ~500 lines of code, much of it header files, option definitions and comments. The main function contains the exact flow of execution and is cleanly structured and commented.
You can pick one of two approaches:
Start with lli.cpp as is, gradually stripping things you don't need.
Take the relevant parts from lli.cpp into your own main file.
If the problem is rather with your main, you can always find examples of bitcode files that actually run with lli within the LLVM tests - test/ExecutionEngine - most tests there are bitcode files on which lli is invoked and runs successfully.
After running into the same problem as you, I searched through lli.cpp for all non-optional invocations to modules, enginebuilders etc...
I believe what you are missing is a call to "ee->runStaticConstructorDestructors(false)"
Atleast, this fixed the issue for me
Note: This is under llvm3.4, but I have verified that the same instruction also exists in llvm3.1, indicating it propably exists in 3.3 aswell.