4

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.

7
  • 1
    I didn't get it. You want a shell script that uses LLVM tools to generate machine code without intermediate files, or you want to do it via LLVM API? Commented Jan 16, 2016 at 12:20
  • I admit, the wording of the question was ambiguous. Edited to clarify: I want to do it via the LLVM API. Commented Jan 16, 2016 at 12:26
  • I'm voting to close this question as off-topic because this is not a give-me-the-codez website. I'm afraid that, although I can answer your question with ease, I certainly won't. Do your own job. Commented Jan 16, 2016 at 12:27
  • 2
    Thanks, @Puppy, you are so very helpful, why are you even using stackoverflow? Commented Jan 16, 2016 at 12:30
  • There are many reasons, but to write code for lazy people to copy and paste is not one of them. Commented Jan 16, 2016 at 12:31

2 Answers 2

6

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!

Sign up to request clarification or add additional context in comments.

Comments

3

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.

2 Comments

Thanks, that really helped. As far as I can see, this way I can output a ".o" or ".obj" native object file, but there is no linking. Can linking be done directly via LLVM yet, or is that still in the works?
There is lld project, which performs linking and it is quite usable on some arches (OSX and Linux). But recently i saw a discussion on the mailing list regarding its architecture not allowing using it as library. It has been decided that lld should provide such API, but i suppose it's still a work-in-progress, yes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.