[LLVMdev] Problem linking and JITing code through C++-API
Reed Kotler
rkotler at mips.com
Tue Sep 2 15:33:23 PDT 2014
Have you tried running this under gdb and looking at where the
segmentation fault occurs?
On 09/01/2014 04:41 PM, Andy Jost wrote:
> I have a frontend that generates some LLVM bitcode that needs to be
> linked with other bitcode (its runtime library), which I generate from
> C++ source using Clang.
>
> If I write the output of my program to disk, link it with llvm-link, and
> then run it with lli, everything works perfectly. But if I try to
> perform the linking and running steps in my main program, I get this
> error during llvm::ExecutionEngine::getPointerToFunction:
>
> Stack dump:
>
> 0. Running pass 'X86 Machine Code Emitter' on function
> '@.step.myappend'
>
> 1. Running pass 'X86 Machine Code Emitter' on function
> '@.step.myappend'
>
> Segmentation fault (core dumped)
>
> There are no other messages. Any idea what I’m doing wrong? I’ll copy
> the source of my main C++ file and the bitcode for .step.myappend
> below. I can send the full bitcode file, too, if someone asks for it,
> but it is around 800 lines.
>
> ####################
>
> #include <fstream>
>
> #include <iostream>
>
> #include "llvm/Bitcode/ReaderWriter.h"
>
> #include "llvm/ExecutionEngine/JIT.h"
>
> #include "llvm/IR/DataLayout.h"
>
> #include "llvm/Linker.h"
>
> #include "llvm/PassManager.h"
>
> #include "llvm/Support/MemoryBuffer.h"
>
> #include "llvm/Support/raw_ostream.h"
>
> #include "llvm/Support/system_error.h"
>
> #include "llvm/Support/TargetSelect.h"
>
> #include "llvm/Transforms/IPO.h"
>
> #include "llvm/Transforms/Scalar.h"
>
> #include "sprite/compiler.hpp"
>
> #include "sprite/config.hpp"
>
> #include "sprite/curryinput.hpp"
>
> #include "sprite/icurry_parser.hpp"
>
> namespace
>
> {
>
> std::string dirname(std::string const & path)
>
> {
>
> size_t const pos = path.find_last_of("/");
>
> return path.substr(0, pos == std::string::npos ? 0 : pos);
>
> }
>
> std::string basename(std::string const & path)
>
> {
>
> size_t const pos = path.find_last_of("/");
>
> return path.substr(pos == std::string::npos ? 0 : pos + 1);
>
> }
>
> std::string remove_extension(std::string const & path)
>
> {
>
> size_t const pos = path.find_last_of(".");
>
> return pos == std::string::npos ? path : path.substr(0, pos);
>
> }
>
> std::string joinpath(std::string const & dirname, std::string const &
> path)
>
> {
>
> if(!path.empty() && path.front() == '/')
>
> return path;
>
> if(dirname.empty())
>
> return path;
>
> return dirname.back() == '/' ? dirname + path : dirname + "/" + path;
>
> }
>
> }
>
> int main(int argc, char const *argv[])
>
> {
>
> if(argc != 2)
>
> {
>
> std::cerr << "Usage: " << argv[0] << " <file.curry>" << std::endl;
>
> return 1;
>
> }
>
> std::string const curry2read =
>
> std::string(SPRITE_LIBINSTALL) + "/cmc/translator/bin/curry2read";
>
> std::string const curryfile(argv[1]);
>
> std::string const readablefile = joinpath(
>
> dirname(curryfile)
>
> , ".curry/" + remove_extension(basename(curryfile)) + ".read"
>
> );
>
> // Generate the readable Curry file.
>
> int ok = std::system((curry2read + " -q " + curryfile).c_str());
>
> if(ok != 0) return 1;
>
> std::ifstream input(readablefile);
>
> if(!input)
>
> {
>
> std::cerr << "Could not open \"" << readablefile << "\"" << std::endl;
>
> return 1;
>
> }
>
> // Parse the input program.
>
> sprite::curry::Library lib;
>
> input >> lib;
>
> std::string topmodule = lib.modules.front().name;
>
> // sprite::compiler::prettyprint(lib);
>
> // Compile the program.
>
> sprite::compiler::LibrarySTab stab;
>
> sprite::compiler::compile(lib, stab);
>
> // Declare the main function.
>
> namespace tgt = sprite::backend;
>
> auto & module_stab = stab.modules.at(topmodule);
>
> auto & compiler = *module_stab.compiler;
>
> tgt::scope _ = module_stab.module_ir;
>
> tgt::extern_(
>
> tgt::types::int_(32)(), "main", {}
>
> , [&]{
>
> // Construct the root expression (just the "main" symbol).
>
> tgt::value root_p = compiler.node_alloc();
>
> sprite::curry::Qname const main_{topmodule, "main"};
>
> root_p = construct(compiler, root_p, {main_, {}});
>
> // Evaluate and then print the root expression.
>
> compiler.rt.normalize(root_p);
>
> compiler.rt.printexpr(root_p, "\n");
>
> tgt::return_(0);
>
> }
>
> );
>
> // module_stab.module_ir->dump();
>
> // Load the runtime library.
>
> llvm::OwningPtr<llvm::MemoryBuffer> buffer;
>
> llvm::error_code err = llvm::MemoryBuffer::getFile(
>
> SPRITE_LIBINSTALL "/sprite-rt.bc", buffer
>
> );
>
> if(err)
>
> {
>
> std::cerr << err.message() << std::endl;
>
> return EXIT_FAILURE;
>
> }
>
> // Make the runtime library into a module.
>
> std::string errmsg;
>
> llvm::Module *rtlib = llvm::ParseBitcodeFile(
>
> buffer.get(), module_stab.module_ir.context(), &errmsg
>
> );
>
> if(!rtlib)
>
> {
>
> std::cerr << errmsg << std::endl;
>
> return EXIT_FAILURE;
>
> }
>
> // Link the compiled program code into the runtime module.
>
> bool failed = llvm::Linker::LinkModules(
>
> rtlib, module_stab.module_ir.ptr(), llvm::Linker::PreserveSource,
> &errmsg
>
> );
>
> if(failed)
>
> {
>
> std::cerr << errmsg << std::endl;
>
> return EXIT_FAILURE;
>
> }
>
> std::cout << "Linking done..." << std::endl;
>
> rtlib->dump();
>
> // Run optimization passes.
>
> // std::vector<const char *> exportList;
>
> // llvm::PassManager Passes;
>
> // Passes.add(new llvm::DataLayout(rtlib));
>
> // Passes.add(llvm::createDemoteRegisterToMemoryPass());
>
> // Passes.add(llvm::createInternalizePass(exportList));
>
> // Passes.add(llvm::createScalarReplAggregatesPass());
>
> // Passes.add(llvm::createInstructionCombiningPass());
>
> // Passes.add(llvm::createGlobalOptimizerPass());
>
> // Passes.add(llvm::createFunctionInliningPass());
>
> // Passes.run(*rtlib);
>
> // Create the JIT
>
> llvm::InitializeNativeTarget();
>
> llvm::ExecutionEngine * jit = llvm::EngineBuilder(rtlib)
>
> .setErrorStr(&errmsg)
>
> .setEngineKind(llvm::EngineKind::JIT)
>
> .create();
>
> if(!jit)
>
> {
>
> std::cerr << "Failed to create JIT compiler: " << errmsg << std::endl;
>
> return EXIT_FAILURE;
>
> }
>
> // Execute the program.
>
> std::cout << "Begin Execution..." << std::endl;
>
> // rtlib->dump();
>
> void * main_fp = jit->getPointerToFunction(rtlib->getFunction("main"));
>
> int32_t (*target_program)() = (int32_t(*)())(intptr_t)(main_fp);
>
> std::cout << "Ready..." << std::endl;
>
> return target_program();
>
> #if 0
>
> // Write a bitcode file and interpret it.
>
> {
>
> std::string err;
>
> llvm::raw_fd_ostream fout("sprite-out.bc", err,
> llvm::raw_fd_ostream::F_Binary);
>
> llvm::WriteBitcodeToFile(module_stab.module_ir.ptr(), fout);
>
> }
>
> std::system("llvm-link-3.3 sprite-out.bc " SPRITE_LIBINSTALL
> "/sprite-rt.bc > tmp.bc");
>
> std::system("mv tmp.bc sprite-out.bc");
>
> int const status = std::system("lli-3.3 sprite-out.bc");
>
> return WEXITSTATUS(status);
>
> #endif
>
> }
>
> ####################
>
> define linkonce void @.step.myappend(%"struct.sprite::compiler::node"*
> %root_p) {
>
> .entry:
>
> %0 = alloca %"struct.sprite::compiler::node"*
>
> %1 = alloca %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %root_p,
> %"struct.sprite::compiler::node"** %0
>
> %2 = load %"struct.sprite::compiler::node"** %0
>
> %3 = getelementptr %"struct.sprite::compiler::node"* %2, i32 0, i32 2
>
> %4 = load i8** %3
>
> %5 = bitcast i8* %4 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %5,
> %"struct.sprite::compiler::node"** %0
>
> br label %11
>
> ; <label>:6 ; preds = %11
>
> %7 = load %"struct.sprite::compiler::node"** %0
>
> %8 = getelementptr %"struct.sprite::compiler::node"* %7, i32 0, i32 2
>
> %9 = load i8** %8
>
> %10 = bitcast i8* %9 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %10,
> %"struct.sprite::compiler::node"** %0
>
> br label %11, !sprite.implied !0
>
> ; <label>:11 ; preds = %6, %.entry
>
> %12 = load %"struct.sprite::compiler::node"** %0
>
> %13 = getelementptr %"struct.sprite::compiler::node"* %12, i32 0, i32 1
>
> %14 = load i64* %13
>
> %15 = load i64* %13
>
> %16 = icmp eq i64 %15, -3
>
> br i1 %16, label %6, label %17
>
> ; <label>:17 ; preds = %11
>
> %18 = load %"struct.sprite::compiler::node"** %0
>
> store %"struct.sprite::compiler::node"* %18,
> %"struct.sprite::compiler::node"** %1
>
> %19 = getelementptr %"struct.sprite::compiler::node"* %18, i32 0, i32 1
>
> %20 = load i64* %19
>
> %21 = add i64 %20, 4
>
> %22 = getelementptr [6 x i8*]* @.jtable, i32 0, i64 %21
>
> %23 = load i8** %22
>
> indirectbr i8* %23, [label %24, label %26, label %36, label %38,
> label %44, label %66]
>
> ; <label>:24 ; preds = %26, %17
>
> %25 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 x
> i8]* @.str21, i32 0, i32 0))
>
> ret void, !case...FAIL !1
>
> ; <label>:26 ; preds = %26, %17
>
> %27 = load %"struct.sprite::compiler::node"** %1
>
> %28 = getelementptr %"struct.sprite::compiler::node"* %27, i32 0, i32 2
>
> %29 = load i8** %28
>
> %30 = bitcast i8* %29 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %30,
> %"struct.sprite::compiler::node"** %1
>
> %31 = getelementptr %"struct.sprite::compiler::node"* %30, i32 0, i32 1
>
> %32 = load i64* %31
>
> %33 = add i64 %32, 4
>
> %34 = getelementptr [6 x i8*]* @.jtable, i32 0, i64 %33
>
> %35 = load i8** %34
>
> indirectbr i8* %35, [label %24, label %26, label %36, label %38,
> label %44, label %66]
>
> ; <label>:36 ; preds = %26, %17
>
> %37 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x
> i8]* @.str22, i32 0, i32 0))
>
> ret void, !case...CHOICE !1
>
> ; <label>:38 ; preds = %26, %17
>
> %39 = load %"struct.sprite::compiler::node"** %1
>
> %40 = getelementptr %"struct.sprite::compiler::node"* %39, i32 0, i32 0
>
> %41 = load %"struct.sprite::compiler::vtable"** %40
>
> %42 = getelementptr %"struct.sprite::compiler::vtable"* %41, i32 0, i32 4
>
> %43 = load void (%"struct.sprite::compiler::node"*)** %42
>
> tail call void %43(%"struct.sprite::compiler::node"* %39)
>
> ret void
>
> ; <label>:44 ; preds = %26, %17
>
> store %"struct.sprite::compiler::node"* %root_p,
> %"struct.sprite::compiler::node"** %0
>
> %45 = load %"struct.sprite::compiler::node"** %0
>
> %46 = getelementptr %"struct.sprite::compiler::node"* %45, i32 0, i32 3
>
> %47 = load i8** %46
>
> %48 = bitcast i8* %47 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %48,
> %"struct.sprite::compiler::node"** %0
>
> br label %54
>
> ; <label>:49 ; preds = %54
>
> %50 = load %"struct.sprite::compiler::node"** %0
>
> %51 = getelementptr %"struct.sprite::compiler::node"* %50, i32 0, i32 2
>
> %52 = load i8** %51
>
> %53 = bitcast i8* %52 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %53,
> %"struct.sprite::compiler::node"** %0
>
> br label %54, !sprite.implied !0
>
> ; <label>:54 ; preds = %49, %44
>
> %55 = load %"struct.sprite::compiler::node"** %0
>
> %56 = getelementptr %"struct.sprite::compiler::node"* %55, i32 0, i32 1
>
> %57 = load i64* %56
>
> %58 = load i64* %56
>
> %59 = icmp eq i64 %58, -3
>
> br i1 %59, label %49, label %60
>
> ; <label>:60 ; preds = %54
>
> %61 = load %"struct.sprite::compiler::node"** %0
>
> %62 = bitcast %"struct.sprite::compiler::node"* %61 to i8*
>
> %63 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0,
> i32 0
>
> store %"struct.sprite::compiler::vtable"* @.fwd.vt,
> %"struct.sprite::compiler::vtable"** %63
>
> %64 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0,
> i32 1
>
> store i64 -3, i64* %64
>
> %65 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0,
> i32 2
>
> store i8* %62, i8** %65
>
> ret void
>
> ; <label>:66 ; preds = %26, %17
>
> store %"struct.sprite::compiler::node"* %root_p,
> %"struct.sprite::compiler::node"** %0
>
> %67 = load %"struct.sprite::compiler::node"** %0
>
> %68 = getelementptr %"struct.sprite::compiler::node"* %67, i32 0, i32 2
>
> %69 = load i8** %68
>
> %70 = bitcast i8* %69 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %70,
> %"struct.sprite::compiler::node"** %0
>
> br label %76
>
> ; <label>:71 ; preds = %76
>
> %72 = load %"struct.sprite::compiler::node"** %0
>
> %73 = getelementptr %"struct.sprite::compiler::node"* %72, i32 0, i32 2
>
> %74 = load i8** %73
>
> %75 = bitcast i8* %74 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %75,
> %"struct.sprite::compiler::node"** %0
>
> br label %76, !sprite.implied !0
>
> ; <label>:76 ; preds = %71, %66
>
> %77 = load %"struct.sprite::compiler::node"** %0
>
> %78 = getelementptr %"struct.sprite::compiler::node"* %77, i32 0, i32 1
>
> %79 = load i64* %78
>
> %80 = load i64* %78
>
> %81 = icmp eq i64 %80, -3
>
> br i1 %81, label %71, label %82
>
> ; <label>:82 ; preds = %76
>
> %83 = load %"struct.sprite::compiler::node"** %0
>
> %84 = getelementptr %"struct.sprite::compiler::node"* %83, i32 0, i32 2
>
> %85 = load i8** %84
>
> %86 = bitcast i8* %85 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %86,
> %"struct.sprite::compiler::node"** %0
>
> br label %92
>
> ; <label>:87 ; preds = %92
>
> %88 = load %"struct.sprite::compiler::node"** %0
>
> %89 = getelementptr %"struct.sprite::compiler::node"* %88, i32 0, i32 2
>
> %90 = load i8** %89
>
> %91 = bitcast i8* %90 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %91,
> %"struct.sprite::compiler::node"** %0
>
> br label %92, !sprite.implied !0
>
> ; <label>:92 ; preds = %87, %82
>
> %93 = load %"struct.sprite::compiler::node"** %0
>
> %94 = getelementptr %"struct.sprite::compiler::node"* %93, i32 0, i32 1
>
> %95 = load i64* %94
>
> %96 = load i64* %94
>
> %97 = icmp eq i64 %96, -3
>
> br i1 %97, label %87, label %98
>
> ; <label>:98 ; preds = %92
>
> %99 = load %"struct.sprite::compiler::node"** %0
>
> %100 = bitcast %"struct.sprite::compiler::node"* %99 to i8*
>
> %101 = call i8* @malloc(i64 32)
>
> %102 = bitcast i8* %101 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %root_p,
> %"struct.sprite::compiler::node"** %0
>
> %103 = load %"struct.sprite::compiler::node"** %0
>
> %104 = getelementptr %"struct.sprite::compiler::node"* %103, i32 0, i32 2
>
> %105 = load i8** %104
>
> %106 = bitcast i8* %105 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %106,
> %"struct.sprite::compiler::node"** %0
>
> br label %112
>
> ; <label>:107 ; preds = %112
>
> %108 = load %"struct.sprite::compiler::node"** %0
>
> %109 = getelementptr %"struct.sprite::compiler::node"* %108, i32 0, i32 2
>
> %110 = load i8** %109
>
> %111 = bitcast i8* %110 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %111,
> %"struct.sprite::compiler::node"** %0
>
> br label %112, !sprite.implied !0
>
> ; <label>:112 ; preds = %107, %98
>
> %113 = load %"struct.sprite::compiler::node"** %0
>
> %114 = getelementptr %"struct.sprite::compiler::node"* %113, i32 0, i32 1
>
> %115 = load i64* %114
>
> %116 = load i64* %114
>
> %117 = icmp eq i64 %116, -3
>
> br i1 %117, label %107, label %118
>
> ; <label>:118 ; preds = %112
>
> %119 = load %"struct.sprite::compiler::node"** %0
>
> %120 = getelementptr %"struct.sprite::compiler::node"* %119, i32 0, i32 3
>
> %121 = load i8** %120
>
> %122 = bitcast i8* %121 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %122,
> %"struct.sprite::compiler::node"** %0
>
> br label %128
>
> ; <label>:123 ; preds = %128
>
> %124 = load %"struct.sprite::compiler::node"** %0
>
> %125 = getelementptr %"struct.sprite::compiler::node"* %124, i32 0, i32 2
>
> %126 = load i8** %125
>
> %127 = bitcast i8* %126 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %127,
> %"struct.sprite::compiler::node"** %0
>
> br label %128, !sprite.implied !0
>
> ; <label>:128 ; preds = %123, %118
>
> %129 = load %"struct.sprite::compiler::node"** %0
>
> %130 = getelementptr %"struct.sprite::compiler::node"* %129, i32 0, i32 1
>
> %131 = load i64* %130
>
> %132 = load i64* %130
>
> %133 = icmp eq i64 %132, -3
>
> br i1 %133, label %123, label %134
>
> ; <label>:134 ; preds = %128
>
> %135 = load %"struct.sprite::compiler::node"** %0
>
> %136 = bitcast %"struct.sprite::compiler::node"* %135 to i8*
>
> store %"struct.sprite::compiler::node"* %root_p,
> %"struct.sprite::compiler::node"** %0
>
> %137 = load %"struct.sprite::compiler::node"** %0
>
> %138 = getelementptr %"struct.sprite::compiler::node"* %137, i32 0, i32 3
>
> %139 = load i8** %138
>
> %140 = bitcast i8* %139 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %140,
> %"struct.sprite::compiler::node"** %0
>
> br label %146
>
> ; <label>:141 ; preds = %146
>
> %142 = load %"struct.sprite::compiler::node"** %0
>
> %143 = getelementptr %"struct.sprite::compiler::node"* %142, i32 0, i32 2
>
> %144 = load i8** %143
>
> %145 = bitcast i8* %144 to %"struct.sprite::compiler::node"*
>
> store %"struct.sprite::compiler::node"* %145,
> %"struct.sprite::compiler::node"** %0
>
> br label %146, !sprite.implied !0
>
> ; <label>:146 ; preds = %141, %134
>
> %147 = load %"struct.sprite::compiler::node"** %0
>
> %148 = getelementptr %"struct.sprite::compiler::node"* %147, i32 0, i32 1
>
> %149 = load i64* %148
>
> %150 = load i64* %148
>
> %151 = icmp eq i64 %150, -3
>
> br i1 %151, label %141, label %152
>
> ; <label>:152 ; preds = %146
>
> %153 = load %"struct.sprite::compiler::node"** %0
>
> %154 = bitcast %"struct.sprite::compiler::node"* %153 to i8*
>
> %155 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 0
>
> store %"struct.sprite::compiler::vtable"* @.vtable.for.myappend,
> %"struct.sprite::compiler::vtable"** %155
>
> %156 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 1
>
> store i64 -1, i64* %156
>
> %157 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 2
>
> store i8* %136, i8** %157
>
> %158 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 3
>
> store i8* %154, i8** %158
>
> %159 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32
> 0, i32 0
>
> store %"struct.sprite::compiler::vtable"* @.vt.CTOR.MyCons,
> %"struct.sprite::compiler::vtable"** %159
>
> %160 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32
> 0, i32 1
>
> store i64 1, i64* %160
>
> %161 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32
> 0, i32 2
>
> store i8* %100, i8** %161
>
> %162 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32
> 0, i32 3
>
> store i8* %101, i8** %162
>
> ret void
>
> }
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
More information about the llvm-dev
mailing list