static boolean
init_gallivm_engine(struct gallivm_state *gallivm)
{
   if (1) {
      /* We can only create one LLVMExecutionEngine (w/ LLVM 2.6 anyway) */
      enum LLVM_CodeGenOpt_Level optlevel;
      char *error = NULL;
      int ret;

      if (gallivm_debug & GALLIVM_DEBUG_NO_OPT) {
         optlevel = None;
      }
      else {
         optlevel = Default;
      }

#if USE_MCJIT
      ret = lp_build_create_mcjit_compiler_for_module(&gallivm->engine,
                                                      gallivm->module,
                                                      (unsigned) optlevel,
                                                      &error);
#else
      ret = LLVMCreateJITCompiler(&gallivm->engine, gallivm->provider,
                                  (unsigned) optlevel, &error);
#endif
      if (ret) {
         _debug_printf("%s\n", error);
         LLVMDisposeMessage(error);
         goto fail;
      }

#if defined(DEBUG) || defined(PROFILE)
      lp_register_oprofile_jit_event_listener(gallivm->engine);
#endif
   }

   LLVMAddModuleProvider(gallivm->engine, gallivm->provider);//new

#if !USE_MCJIT
   gallivm->target = LLVMGetExecutionEngineTargetData(gallivm->engine);
   if (!gallivm->target)
      goto fail;
#else
   if (0) {
       /*
        * Dump the data layout strings.
        */

       LLVMTargetDataRef target = LLVMGetExecutionEngineTargetData(gallivm->engine);
       char *data_layout;
       char *engine_data_layout;

       data_layout = LLVMCopyStringRepOfTargetData(gallivm->target);
       engine_data_layout = LLVMCopyStringRepOfTargetData(target);

       if (1) {
          debug_printf("module target data = %s\n", data_layout);
          debug_printf("engine target data = %s\n", engine_data_layout);
       }

       free(data_layout);
       free(engine_data_layout);
   }
#endif

   return TRUE;

fail:
   return FALSE;
}
Exemplo n.º 2
0
/**
 * Allocate gallivm LLVM objects.
 * \return  TRUE for success, FALSE for failure
 */
static boolean
init_gallivm_state(struct gallivm_state *gallivm)
{
   assert(!gallivm->context);
   assert(!gallivm->module);
   assert(!gallivm->provider);

   lp_build_init();

   gallivm->context = LLVMContextCreate();
   if (!gallivm->context)
      goto fail;

   gallivm->module = LLVMModuleCreateWithNameInContext("gallivm",
                                                       gallivm->context);
   if (!gallivm->module)
      goto fail;

   gallivm->provider =
      LLVMCreateModuleProviderForExistingModule(gallivm->module);
   if (!gallivm->provider)
      goto fail;

   if (!GlobalEngine) {
      /* We can only create one LLVMExecutionEngine (w/ LLVM 2.6 anyway) */
      enum LLVM_CodeGenOpt_Level optlevel;
      char *error = NULL;

      if (gallivm_debug & GALLIVM_DEBUG_NO_OPT) {
         optlevel = None;
      }
      else {
         optlevel = Default;
      }

      if (LLVMCreateJITCompiler(&GlobalEngine, gallivm->provider,
                                (unsigned) optlevel, &error)) {
         _debug_printf("%s\n", error);
         LLVMDisposeMessage(error);
         goto fail;
      }

#if defined(DEBUG) || defined(PROFILE)
      lp_register_oprofile_jit_event_listener(GlobalEngine);
#endif
   }

   gallivm->engine = GlobalEngine;

   LLVMAddModuleProvider(gallivm->engine, gallivm->provider);//new

   gallivm->target = LLVMGetExecutionEngineTargetData(gallivm->engine);
   if (!gallivm->target)
      goto fail;

   if (!create_pass_manager(gallivm))
      goto fail;

   gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
   if (!gallivm->builder)
      goto fail;

   return TRUE;

fail:
   free_gallivm_state(gallivm);
   return FALSE;
}
Exemplo n.º 3
0
void
lp_build_init(void)
{
#ifdef DEBUG
   gallivm_debug = debug_get_option_gallivm_debug();
#endif

   lp_set_target_options();

   LLVMInitializeNativeTarget();

   LLVMLinkInJIT();

   if (!lp_build_module)
      lp_build_module = LLVMModuleCreateWithName("gallivm");

   if (!lp_build_provider)
      lp_build_provider = LLVMCreateModuleProviderForExistingModule(lp_build_module);

   if (!lp_build_engine) {
      enum LLVM_CodeGenOpt_Level optlevel;
      char *error = NULL;

      if (gallivm_debug & GALLIVM_DEBUG_NO_OPT) {
         optlevel = None;
      }
      else {
         optlevel = Default;
      }

      if (LLVMCreateJITCompiler(&lp_build_engine, lp_build_provider,
                                (unsigned)optlevel, &error)) {
         _debug_printf("%s\n", error);
         LLVMDisposeMessage(error);
         assert(0);
      }

#if defined(DEBUG) || defined(PROFILE)
      lp_register_oprofile_jit_event_listener(lp_build_engine);
#endif
   }

   if (!lp_build_target)
      lp_build_target = LLVMGetExecutionEngineTargetData(lp_build_engine);

   if (!lp_build_pass) {
      lp_build_pass = LLVMCreateFunctionPassManager(lp_build_provider);
      LLVMAddTargetData(lp_build_target, lp_build_pass);

      if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) {
         /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
          * but there are more on SVN. */
         /* TODO: Add more passes */
         LLVMAddCFGSimplificationPass(lp_build_pass);
         LLVMAddPromoteMemoryToRegisterPass(lp_build_pass);
         LLVMAddConstantPropagationPass(lp_build_pass);
         if(util_cpu_caps.has_sse4_1) {
            /* FIXME: There is a bug in this pass, whereby the combination of fptosi
             * and sitofp (necessary for trunc/floor/ceil/round implementation)
             * somehow becomes invalid code.
             */
            LLVMAddInstructionCombiningPass(lp_build_pass);
         }
         LLVMAddGVNPass(lp_build_pass);
      } else {
         /* We need at least this pass to prevent the backends to fail in
          * unexpected ways.
          */
         LLVMAddPromoteMemoryToRegisterPass(lp_build_pass);
      }
   }

   util_cpu_detect();

#if 0
   /* For simulating less capable machines */
   util_cpu_caps.has_sse3 = 0;
   util_cpu_caps.has_ssse3 = 0;
   util_cpu_caps.has_sse4_1 = 0;
#endif
}