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 >
Apparently Analagous 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