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 } -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140901/52547f6a/attachment.html>
Reed Kotler
2014-Sep-02 22:33 UTC
[LLVMdev] Problem linking and JITing code through C++-API
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 >
Yes. It appears that a bad reference to DataLayout was passed to MachineJumpTableInfo::getEntrySize. I'm using LLVM as a pre-compiled Ubuntu package for this work, so I can't do much more in GDB without building from source. Program received signal SIGSEGV, Segmentation fault. 0x00000000007565f0 in llvm::MachineJumpTableInfo::getEntrySize(llvm::DataLayout const&) const () (gdb) where #0 0x00000000007565f0 in llvm::MachineJumpTableInfo::getEntrySize(llvm::DataLayout const&) const () #1 0x0000000000704313 in (anonymous namespace)::JITEmitter::getJumpTableEntryAddress(unsigned int) const () #2 0x000000000070bce1 in (anonymous namespace)::JITEmitter::finishFunction(llvm::MachineFunction&) () #3 0x0000000000474430 in (anonymous namespace)::Emitter<llvm::JITCodeEmitter>::runOnMachineFunction(llvm::MachineFunction&) () #4 0x0000000000b214dc in llvm::FPPassManager::runOnFunction(llvm::Function&) () #5 0x0000000000b21610 in llvm::FunctionPassManagerImpl::run(llvm::Function&) () #6 0x0000000000b216f4 in llvm::FunctionPassManager::run(llvm::Function&) () #7 0x00000000006fe26e in llvm::JIT::jitTheFunction(llvm::Function*, llvm::MutexGuard const&) () #8 0x00000000006fe8cf in llvm::JIT::runJITOnFunctionUnlocked(llvm::Function*, llvm::MutexGuard const&) () #9 0x00000000006fead2 in llvm::JIT::getPointerToFunction(llvm::Function*) () #10 0x00000000006fd63f in llvm::JIT::getPointerToBasicBlock(llvm::BasicBlock*) () #11 0x00000000009e14ee in llvm::ExecutionEngine::getConstantValue(llvm::Constant const*) () #12 0x00000000009e265f in llvm::ExecutionEngine::InitializeMemory(llvm::Constant const*, void*) () #13 0x00000000009e27e3 in llvm::ExecutionEngine::InitializeMemory(llvm::Constant const*, void*) () #14 0x00000000009e3628 in llvm::ExecutionEngine::EmitGlobalVariable(llvm::GlobalVariable const*) () #15 0x00000000006fd559 in llvm::JIT::getOrEmitGlobalVariable(llvm::GlobalVariable const*) () #16 0x000000000070b8cd in (anonymous namespace)::JITEmitter::getPointerToGlobal(llvm::GlobalValue*, void*, bool) [clone .isra.439] () #17 0x000000000070c505 in (anonymous namespace)::JITEmitter::finishFunction(llvm::MachineFunction&) () #18 0x0000000000474430 in (anonymous namespace)::Emitter<llvm::JITCodeEmitter>::runOnMachineFunction(llvm::MachineFunction&) () #19 0x0000000000b214dc in llvm::FPPassManager::runOnFunction(llvm::Function&) () #20 0x0000000000b21610 in llvm::FunctionPassManagerImpl::run(llvm::Function&) () #21 0x0000000000b216f4 in llvm::FunctionPassManager::run(llvm::Function&) () #22 0x00000000006fe26e in llvm::JIT::jitTheFunction(llvm::Function*, llvm::MutexGuard const&) () #23 0x00000000006fe8fa in llvm::JIT::runJITOnFunctionUnlocked(llvm::Function*, llvm::MutexGuard const&) () #24 0x00000000006fead2 in llvm::JIT::getPointerToFunction(llvm::Function*) () #25 0x00000000004285e7 in main () at sprite.cpp:172 (gdb) x/10i $pc => 0x7565f0 <_ZNK4llvm20MachineJumpTableInfo12getEntrySizeERKNS_10DataLayoutE>: cmpl $0x5,(%rdi) 0x7565f3 <_ZNK4llvm20MachineJumpTableInfo12getEntrySizeERKNS_10DataLayoutE+3>: mov (%rdi),%edx 0x7565f5 <_ZNK4llvm20MachineJumpTableInfo12getEntrySizeERKNS_10DataLayoutE+5>: lea 0x4ccc5c(%rip),%rax # 0xc23258 0x7565fc <_ZNK4llvm20MachineJumpTableInfo12getEntrySizeERKNS_10DataLayoutE+12>: movslq (%rax,%rdx,4),%rdx 0x756600 <_ZNK4llvm20MachineJumpTableInfo12getEntrySizeERKNS_10DataLayoutE+16>: add %rdx,%rax 0x756603 <_ZNK4llvm20MachineJumpTableInfo12getEntrySizeERKNS_10DataLayoutE+19>: jmpq *%rax 0x756605 <_ZNK4llvm20MachineJumpTableInfo12getEntrySizeERKNS_10DataLayoutE+21>: nopl (%rax) 0x756608 <_ZNK4llvm20MachineJumpTableInfo12getEntrySizeERKNS_10DataLayoutE+24>: mov $0x4,%eax 0x75660d <_ZNK4llvm20MachineJumpTableInfo12getEntrySizeERKNS_10DataLayoutE+29>: retq 0x75660e <_ZNK4llvm20MachineJumpTableInfo12getEntrySizeERKNS_10DataLayoutE+30>: xchg %ax,%ax (gdb) x $rdi 0x3eb000003ec: Cannot access memory at address 0x3eb000003ec -----Original Message----- From: Reed Kotler [mailto:rkotler at mips.com] Sent: Tuesday, September 02, 2014 3:33 PM To: Andy Jost; LLVMdev at cs.uiuc.edu Subject: Re: Problem linking and JITing code through C++-API 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 >
Seemingly Similar Threads
- [LLVMdev] Problem linking and JITing code through C++-API
- [LLVMdev] Problem linking and JITing code through C++-API
- A rails plugin to generate css sprite image automatically
- My SCSS compiled CSS lacks "/assets" in the generated urls
- Rgl and plotmath symbols (via sprites): a trial