Example #1
0
int run(unique_ptr<Module> module, Chars_const fnName, const vector<string> args) {
  
  check(module, "no module");
  
  Function* entryFn = module->getFunction(fnName);
  check(entryFn, "Source file does not contain a function of the given name");
  
  // Use an EngineBuilder to configure and construct an MCJIT ExecutionEngine.
#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR <= 5
  EngineBuilder builder(module.release());
  builder.setUseMCJIT(true);
#else
  const EngineBuilder builder(move(module));
  const SectionMemoryManager mm;
  builder.setMCJITMemoryManager(&mm);
#endif
  string errorStr;
  builder.setErrorStr(&errorStr);
  builder.setEngineKind(EngineKind::JIT);
  builder.setOptLevel(CodeGenOpt::None);
  
  ExecutionEngine* engine = builder.create();
  
  // Call 'finalizeObject' to notify the JIT that we're ready to execute the jitted code,
  // then run the static constructors.
  engine->finalizeObject();
  engine->runStaticConstructorsDestructors(false);
  
  // Pass the args to the jitted function, and capture the result.
  const int result = engine->runFunctionAsMain(entryFn, args, nullptr);
  engine->runStaticConstructorsDestructors(true); // Run the static destructors.
  return result;
}
Example #2
0
casefoldFunctionType caseFoldCodeGen(void) {
                            
    Module * M = new Module("casefold", getGlobalContext());
    
    IDISA::IDISA_Builder * idb = GetIDISA_Builder(M);

    kernel::PipelineBuilder pipelineBuilder(M, idb);

    Encoding encoding(Encoding::Type::UTF_8, 8);
    
    pablo::PabloFunction * function = casefold2pablo(encoding);
    

    pipelineBuilder.CreateKernels(function);

    pipelineBuilder.ExecuteKernels();

    //std::cerr << "ExecuteKernels(); done\n";
    llvm::Function * main_IR = M->getFunction("Main");
    ExecutionEngine * mEngine = JIT_to_ExecutionEngine(M);
    
    mEngine->finalizeObject();
    //std::cerr << "finalizeObject(); done\n";

    delete idb;

    return reinterpret_cast<casefoldFunctionType>(mEngine->getPointerToFunction(main_IR));
}
Example #3
0
void * compile(llvm::Module * m) {
    ExecutionEngine * engine =
      EngineBuilder(std::unique_ptr<Module>(m))
      .create();
    engine->finalizeObject();

    return engine->getPointerToFunction(
        m->getFunction("aFun"));
}
Example #4
0
ExecutionEngine *MCJITHelper::compileModule(Module *M) {
  if (M == OpenModule)
    closeCurrentModule();

  std::string ErrStr;
  ExecutionEngine *NewEngine = EngineBuilder(M)
                                            .setErrorStr(&ErrStr)
                                            .setMCJITMemoryManager(new HelpingMemoryManager(this))
                                            .create();
  if (!NewEngine) {
    fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
    exit(1);
  }

  // Create a function pass manager for this engine
  FunctionPassManager *FPM = new FunctionPassManager(M);

  // Set up the optimizer pipeline.  Start with registering info about how the
  // target lays out data structures.
  FPM->add(new DataLayout(*NewEngine->getDataLayout()));
  // Provide basic AliasAnalysis support for GVN.
  FPM->add(createBasicAliasAnalysisPass());
  // Promote allocas to registers.
  FPM->add(createPromoteMemoryToRegisterPass());
  // Do simple "peephole" optimizations and bit-twiddling optzns.
  FPM->add(createInstructionCombiningPass());
  // Reassociate expressions.
  FPM->add(createReassociatePass());
  // Eliminate Common SubExpressions.
  FPM->add(createGVNPass());
  // Simplify the control flow graph (deleting unreachable blocks, etc).
  FPM->add(createCFGSimplificationPass());
  FPM->doInitialization();

  // For each function in the module
  Module::iterator it;
  Module::iterator end = M->end();
  for (it = M->begin(); it != end; ++it) {
    // Run the FPM on this function
    FPM->run(*it);
  }

  // We don't need this anymore
  delete FPM;

  // Store this engine
  EngineMap[M] = NewEngine;
  NewEngine->finalizeObject();

  return NewEngine;
}
Example #5
0
	void initEE(std::unique_ptr<Module> Owner) {
		string ErrStr;
		if (EE == NULL) {
			RTDyldMM = new SectionMemoryManager();
			EE = EngineBuilder(std::move(Owner))
				.setEngineKind(EngineKind::JIT)
				.setErrorStr(&ErrStr)
				.setVerifyModules(true)
				.setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager>(RTDyldMM))
				.setOptLevel(CodeGenOpt::Default)
				.create();

		} else
			EE->addModule(std::move(Owner));
		if (ErrStr.length() != 0)
			cerr << "Create Engine Error" << endl << ErrStr << endl;
		EE->finalizeObject();
	}
Example #6
0
ExecutionEngine* codegen::compile() {
    if(compiled) {
        cerr << "Module has already been compiled, cannot compile again!"
            << "\nExiting..." << endl;
        exit(-1);
    }

    builder->CreateRet(ConstantInt::get(int32Type, 0));

    // This is for debugging
    if(llvmoutput)
        module->dump();

    string error;
    ExecutionEngine *executionEngine = EngineBuilder(module).
            setErrorStr(&error).
            setUseMCJIT(true).
            create();

    executionEngine->finalizeObject();

    compiled = true;
    return executionEngine;
}
Example #7
0
void JITCompiledModule::compile_module(CodeGen *cg, llvm::Module *m, const string &function_name) {

    // Make the execution engine
    debug(2) << "Creating new execution engine\n";
    string error_string;

    TargetOptions options;
    options.LessPreciseFPMADOption = true;
    options.NoFramePointerElim = false;
    options.AllowFPOpFusion = FPOpFusion::Fast;
    options.UnsafeFPMath = true;
    options.NoInfsFPMath = true;
    options.NoNaNsFPMath = true;
    options.HonorSignDependentRoundingFPMathOption = false;
    options.UseSoftFloat = false;
    options.FloatABIType =
        cg->use_soft_float_abi() ? FloatABI::Soft : FloatABI::Hard;
    options.NoZerosInBSS = false;
    options.GuaranteedTailCallOpt = false;
    options.DisableTailCalls = false;
    options.StackAlignmentOverride = 0;
    options.TrapFuncName = "";
    options.PositionIndependentExecutable = true;
    options.UseInitArray = false;

    EngineBuilder engine_builder(m);
    engine_builder.setTargetOptions(options);
    engine_builder.setErrorStr(&error_string);
    engine_builder.setEngineKind(EngineKind::JIT);
    #ifdef USE_MCJIT
    engine_builder.setUseMCJIT(true);
    JITMemoryManager *memory_manager = JITMemoryManager::CreateDefaultMemManager();
    engine_builder.setJITMemoryManager(memory_manager);
    #else
    engine_builder.setUseMCJIT(false);
    #endif
    engine_builder.setOptLevel(CodeGenOpt::Aggressive);
    engine_builder.setMCPU(cg->mcpu());
    engine_builder.setMAttrs(vec<string>(cg->mattrs()));
    ExecutionEngine *ee = engine_builder.create();
    if (!ee) std::cerr << error_string << "\n";
    internal_assert(ee) << "Couldn't create execution engine\n";

    #ifdef __arm__
    start = end = NULL;
    #endif

    // Do any target-specific initialization
    cg->jit_init(ee, m);

    // Retrieve function pointers from the compiled module (which also
    // triggers compilation)
    debug(1) << "JIT compiling...\n";

    hook_up_function_pointer(ee, m, function_name, true, &function);

    void *function_address = reinterpret_bits<void *>(function);
    debug(1) << "JIT compiled function pointer " << function_address << "\n";

    hook_up_function_pointer(ee, m, function_name + "_jit_wrapper", true, &wrapped_function);
    hook_up_function_pointer(ee, m, "halide_copy_to_host", false, &copy_to_host);
    hook_up_function_pointer(ee, m, "halide_copy_to_dev", false, &copy_to_dev);
    hook_up_function_pointer(ee, m, "halide_dev_free", false, &free_dev_buffer);
    hook_up_function_pointer(ee, m, "halide_set_error_handler", true, &set_error_handler);
    hook_up_function_pointer(ee, m, "halide_set_custom_allocator", true, &set_custom_allocator);
    hook_up_function_pointer(ee, m, "halide_set_custom_do_par_for", true, &set_custom_do_par_for);
    hook_up_function_pointer(ee, m, "halide_set_custom_do_task", true, &set_custom_do_task);
    hook_up_function_pointer(ee, m, "halide_set_custom_trace", true, &set_custom_trace);
    hook_up_function_pointer(ee, m, "halide_shutdown_thread_pool", true, &shutdown_thread_pool);

    debug(2) << "Finalizing object\n";
    ee->finalizeObject();

    // Stash the various objects that need to stay alive behind a reference-counted pointer.
    module = new JITModuleHolder(ee, m, shutdown_thread_pool);

    // Do any target-specific post-compilation module meddling
    cg->jit_finalize(ee, m, &module.ptr->cleanup_routines);

    #ifdef __arm__
    // Flush each function from the dcache so that it gets pulled into
    // the icache correctly.

    // finalizeMemory should have done the trick, but as of Aug 28
    // 2013, it doesn't work unless we also manually flush the
    // cache. Otherwise the icache's view of the code is missing the
    // relocations, which gets really confusing to debug, because
    // gdb's view of the code uses the dcache, so the disassembly
    // isn't right.
    debug(2) << "Flushing cache from " << (void *)start
             << " to " << (void *)end << "\n";
    __builtin___clear_cache(start, end);
    #endif

    // TODO: I don't think this is necessary, we shouldn't have any static constructors
    // ee->runStaticConstructorsDestructors(false);

}
Example #8
0
extern "C" void LLVMExecutionEngineFinalizeObject(LLVMExecutionEngineRef eeref)
{
    ExecutionEngine *ee = unwrap(eeref);

    ee->finalizeObject();
}
Example #9
0
ExecutionEngine *MCJITHelper::compileModule(Module *M) {
    assert(EngineMap.find(M) == EngineMap.end());

    if (M == CurrentModule)
        closeCurrentModule();

    std::string ErrStr;
    ExecutionEngine *EE = EngineBuilder(M)
                          .setErrorStr(&ErrStr)
                          .setMCJITMemoryManager(new HelpingMemoryManager(this))
                          .create();
    if (!EE) {
        fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
        exit(1);
    }

    if (UseObjectCache)
        EE->setObjectCache(&OurObjectCache);
    // Get the ModuleID so we can identify IR input files
    const std::string ModuleID = M->getModuleIdentifier();

    // If we've flagged this as an IR file, it doesn't need function passes run.
    if (0 != ModuleID.compare(0, 3, "IR:")) {
        FunctionPassManager *FPM = 0;

        // Create a FPM for this module
        FPM = new FunctionPassManager(M);

        // Set up the optimizer pipeline.  Start with registering info about how the
        // target lays out data structures.
        FPM->add(new DataLayout(*EE->getDataLayout()));
        // Provide basic AliasAnalysis support for GVN.
        FPM->add(createBasicAliasAnalysisPass());
        // Promote allocas to registers.
        FPM->add(createPromoteMemoryToRegisterPass());
        // Do simple "peephole" optimizations and bit-twiddling optzns.
        FPM->add(createInstructionCombiningPass());
        // Reassociate expressions.
        FPM->add(createReassociatePass());
        // Eliminate Common SubExpressions.
        FPM->add(createGVNPass());
        // Simplify the control flow graph (deleting unreachable blocks, etc).
        FPM->add(createCFGSimplificationPass());

        FPM->doInitialization();

        // For each function in the module
        Module::iterator it;
        Module::iterator end = M->end();
        for (it = M->begin(); it != end; ++it) {
            // Run the FPM on this function
            FPM->run(*it);
        }

        delete FPM;
    }

    EE->finalizeObject();

    // Store this engine
    EngineMap[M] = EE;

    return EE;
}
Example #10
0
int main() {
    ygt_print("Hello!\n");
    InitializeNativeTarget();
    InitializeNativeTargetAsmPrinter();
    InitializeNativeTargetAsmParser();
    InitializeNativeTargetDisassembler();

    ygt_print("Creating LLVM context and module...\n");
    LLVMContext ctx;
    auto m = make_unique<Module>("the_module", ctx);

    ygt_print("Creating StackMapHelper...\n");
    StackMapHelper smhelper;

    ygt_print("Declaring yg_stack_swap as an LLVM-level function...\n");
    declare_ss(ctx, *m);

    ygt_print("Constructing bar, the ss leaf...\n");
    Function *bar;
    smid_t bar_smid;
    tie(bar, bar_smid) = make_ss_leaf("barss", &main_stack, &coro_stack, smhelper, ctx, *m);

    verifyFunction(*bar);

    ygt_print("Constructing foo, the caller...\n");
    Function *foo;
    smid_t foo_smid;
    tie(foo, foo_smid) = make_caller("foo", bar, smhelper, ctx, *m);

    verifyFunction(*foo);

    m->dump();

    Function *ss_func = m->getFunction("yg_stack_swap");

    ygt_print("Creating execution engine...\n");
    ExecutionEngine *ee = EngineBuilder(move(m)).setEngineKind(EngineKind::JIT).create();
    ygt_print("Execution engine created.\n");

    StackMapSectionRecorder smsr;
    ygt_print("Registering JIT event listener...\n");
    ee->RegisterJITEventListener(&smsr);

    EHFrameSectionRegisterer reg;
    ygt_print("Registering EHFrame registerer...\n");
    ee->RegisterJITEventListener(&reg);

    ygt_print("Adding global mapping yg_stack_swap...\n");
    ee->addGlobalMapping(ss_func, reinterpret_cast<void*>(yg_stack_swap));

    ygt_print("JIT compiling...\n");
    ee->finalizeObject();

    ygt_print("Adding stack map sections...\n");
    smhelper.add_stackmap_sections(smsr, *ee);

    ygt_print("Registering EH frames...\n");
    reg.registerEHFrameSections();

    uintptr_t yg_stack_swap_addr = ee->getFunctionAddress("yg_stack_swap");
    ygt_print("yg_stack_swap_addr=%" PRIxPTR ", yg_stack_swap=%p\n", yg_stack_swap_addr, yg_stack_swap);
    assert(yg_stack_swap_addr == reinterpret_cast<uintptr_t>(yg_stack_swap));

    ygt_print("Getting foo...\n");
    void (*the_real_foo)(int32_t, int64_t, float, double) = (void(*)(int32_t, int64_t, float, double))
            ee->getFunctionAddress("foo");
    ygt_print("the_real_foo == %p\n", the_real_foo);

    ygt_print("Prepare corotine for introspection...\n");
    coro_stack = YGStack::alloc(8*1024*1024);
    coro_stack.init(reinterpret_cast<uintptr_t>(coro));

    MyCtx my_ctx = { foo_smid, bar_smid, &smhelper };

    ygt_print("Swap-stack to prepare the coroutine...\n");
    yg_stack_swap(&main_stack, &coro_stack, reinterpret_cast<uintptr_t>(&my_ctx));

    ygt_print("Back from coro.\n");

    ygt_print("Calling the_real_foo...\n");

    the_real_foo(100, 200, 300.0f, 400.0);

    ygt_print("Returned from foo.\n");

    return 0;
}
Example #11
0
void *MCJITHelper::getPointerToFunction(Function* F) {
  // See if an existing instance of MCJIT has this function.
  EngineVector::iterator begin = Engines.begin();
  EngineVector::iterator end = Engines.end();
  EngineVector::iterator it;
  for (it = begin; it != end; ++it) {
    void *P = (*it)->getPointerToFunction(F);
    if (P)
      return P;
  }

  // If we didn't find the function, see if we can generate it.
  if (OpenModule) {
    std::string ErrStr;
    ExecutionEngine *NewEngine = EngineBuilder(OpenModule)
                                              .setErrorStr(&ErrStr)
                                              .setMCJITMemoryManager(new HelpingMemoryManager(this))
                                              .create();
    if (!NewEngine) {
      fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
      exit(1);
    }

    // Create a function pass manager for this engine
    FunctionPassManager *FPM = new FunctionPassManager(OpenModule);

    // Set up the optimizer pipeline.  Start with registering info about how the
    // target lays out data structures.
    FPM->add(new DataLayout(*NewEngine->getDataLayout()));
    // Provide basic AliasAnalysis support for GVN.
    FPM->add(createBasicAliasAnalysisPass());
    // Promote allocas to registers.
    FPM->add(createPromoteMemoryToRegisterPass());
    // Do simple "peephole" optimizations and bit-twiddling optzns.
    FPM->add(createInstructionCombiningPass());
    // Reassociate expressions.
    FPM->add(createReassociatePass());
    // Eliminate Common SubExpressions.
    FPM->add(createGVNPass());
    // Simplify the control flow graph (deleting unreachable blocks, etc).
    FPM->add(createCFGSimplificationPass());
    FPM->doInitialization();

    // For each function in the module
    Module::iterator it;
    Module::iterator end = OpenModule->end();
    for (it = OpenModule->begin(); it != end; ++it) {
      // Run the FPM on this function
      FPM->run(*it);
    }

    // We don't need this anymore
    delete FPM;

    OpenModule = NULL;
    Engines.push_back(NewEngine);
    NewEngine->finalizeObject();
    return NewEngine->getPointerToFunction(F);
  }
  return NULL;
}