Lang Hames
2014-Sep-08 21:18 UTC
[LLVMdev] Problem linking and JITing code through C++-API
Hi Andy, It looks like you're using LLVM's old JIT, rather than MCJIT? The old JIT has been removed from the mainline, and is no longer supported. I'd recommend building your own copy of LLVM from the development branch (as Reed suggested) where MCJIT is used by default - this may fix your issue. If you want to stick with the precompiled binaries, then you should change: #include "llvm/ExecutionEngine/JIT.h" to #include "llvm/ExecutionEngine/MCJIT.h" and add: .setUseMCJIT(true) to your EngineBuilder invocation. And finally change: jit->getPointerToFunction(rtlib->getFunction("main")); to jit->getFunctionAddress("main"); Cheers, Lang. On Tue, Sep 2, 2014 at 4:28 PM, Reed Kotler <Reed.Kotler at imgtec.com> wrote:> It's really easy to build LLVM from source on any linux environment. > > ________________________________________ > From: Andy Jost [Andrew.Jost at synopsys.com] > Sent: Tuesday, September 02, 2014 4:00 PM > To: Reed Kotler; Andy Jost; LLVMdev at cs.uiuc.edu > Subject: RE: Problem linking and JITing code through C++-API > > 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 > > > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140908/3a76f3b5/attachment.html>
Thank you for the suggestions, Lang. I was able to make each change except the last one. There is no getFunctionAddress is the version of LLVM I have (3.3). If I run without that last change, I get (on x86_64): LLVM ERROR: Target does not support MC emission! I suppose there’s no reason to debug the original issue any further, since the old JIT has been removed. When I have the time, I’ll see if my project works with a newer version of LLVM. -Andy From: Lang Hames [mailto:lhames at gmail.com] Sent: Monday, September 08, 2014 2:18 PM To: Reed Kotler Cc: Andy Jost; LLVMdev at cs.uiuc.edu Subject: Re: [LLVMdev] Problem linking and JITing code through C++-API Hi Andy, It looks like you're using LLVM's old JIT, rather than MCJIT? The old JIT has been removed from the mainline, and is no longer supported. I'd recommend building your own copy of LLVM from the development branch (as Reed suggested) where MCJIT is used by default - this may fix your issue. If you want to stick with the precompiled binaries, then you should change: #include "llvm/ExecutionEngine/JIT.h" to #include "llvm/ExecutionEngine/MCJIT.h" and add: .setUseMCJIT(true) to your EngineBuilder invocation. And finally change: jit->getPointerToFunction(rtlib->getFunction("main")); to jit->getFunctionAddress("main"); Cheers, Lang. On Tue, Sep 2, 2014 at 4:28 PM, Reed Kotler <Reed.Kotler at imgtec.com<mailto:Reed.Kotler at imgtec.com>> wrote: It's really easy to build LLVM from source on any linux environment. ________________________________________ From: Andy Jost [Andrew.Jost at synopsys.com<mailto:Andrew.Jost at synopsys.com>] Sent: Tuesday, September 02, 2014 4:00 PM To: Reed Kotler; Andy Jost; LLVMdev at cs.uiuc.edu<mailto:LLVMdev at cs.uiuc.edu> Subject: RE: Problem linking and JITing code through C++-API 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<mailto:rkotler at mips.com>] Sent: Tuesday, September 02, 2014 3:33 PM To: Andy Jost; LLVMdev at cs.uiuc.edu<mailto: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<http://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<mailto:LLVMdev at cs.uiuc.edu> http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >_______________________________________________ LLVM Developers mailing list LLVMdev at cs.uiuc.edu<mailto:LLVMdev at cs.uiuc.edu> http://llvm.cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140910/65a4b960/attachment.html>
Lang Hames
2014-Sep-10 18:24 UTC
[LLVMdev] Problem linking and JITing code through C++-API
Hi Andy, Sure thing. Regarding the error you saw, I think you'll also need to add a call to InitializeNativeTargetAsmPrinter() after your call to InitializeNativeTarget(). This is required on newer versions of LLVM as well. Cheers, Lang. On Tue, Sep 9, 2014 at 8:09 PM, Andy Jost <Andrew.Jost at synopsys.com> wrote:> Thank you for the suggestions, Lang. I was able to make each change > except the last one. There is no getFunctionAddress is the version of LLVM > I have (3.3). > > > > If I run without that last change, I get (on x86_64): > > > > LLVM ERROR: Target does not support MC emission! > > > > I suppose there’s no reason to debug the original issue any further, since > the old JIT has been removed. When I have the time, I’ll see if my project > works with a newer version of LLVM. > > > > -Andy > > > > *From:* Lang Hames [mailto:lhames at gmail.com] > *Sent:* Monday, September 08, 2014 2:18 PM > *To:* Reed Kotler > *Cc:* Andy Jost; LLVMdev at cs.uiuc.edu > *Subject:* Re: [LLVMdev] Problem linking and JITing code through C++-API > > > > Hi Andy, > > It looks like you're using LLVM's old JIT, rather than MCJIT? The old JIT > has been removed from the mainline, and is no longer supported. I'd > recommend building your own copy of LLVM from the development branch (as > Reed suggested) where MCJIT is used by default - this may fix your issue. > > > > If you want to stick with the precompiled binaries, then you should change: > > #include "llvm/ExecutionEngine/JIT.h" > > to > > #include "llvm/ExecutionEngine/MCJIT.h" > > and add: > > .setUseMCJIT(true) > > to your EngineBuilder invocation. > > And finally change: > > jit->getPointerToFunction(rtlib->getFunction("main")); > > to > > jit->getFunctionAddress("main"); > > Cheers, > Lang. > > > > On Tue, Sep 2, 2014 at 4:28 PM, Reed Kotler <Reed.Kotler at imgtec.com> > wrote: > > It's really easy to build LLVM from source on any linux environment. > > ________________________________________ > From: Andy Jost [Andrew.Jost at synopsys.com] > Sent: Tuesday, September 02, 2014 4:00 PM > To: Reed Kotler; Andy Jost; LLVMdev at cs.uiuc.edu > Subject: RE: Problem linking and JITing code through C++-API > > > 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 > > > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140910/76c5dc2d/attachment.html>