示例#1
0
static void* concurrent_jit_run(void *info)
{
    gcc_jit_context *ctx;
    ctx = gcc_jit_context_acquire ();
    if (ctx == NULL)
    {
        fprintf(stderr, "acquired JIT context is NULL");
        return NULL;
    }

    gcc_jit_context_set_int_option(ctx, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2);

#if EXTRAE_SUPPORT
    Extrae_event(JIT_EVENT_TYPE, JIT_CODE_GENERATION);
#endif

    generate_code_regexp(ctx, regexp);

#if EXTRAE_SUPPORT
    Extrae_event(JIT_EVENT_TYPE, 0);

    Extrae_event(JIT_EVENT_TYPE, JIT_COMPILATION);
#endif
    gcc_jit_result *result = gcc_jit_context_compile(ctx);
#if EXTRAE_SUPPORT
    Extrae_event(JIT_EVENT_TYPE, 0);
#endif
    if (result == NULL)
    {
        fprintf(stderr, "compilation failed");
        return NULL;
    }

#if EXTRAE_SUPPORT
    Extrae_event(JIT_EVENT_TYPE, JIT_GET_CODE);
#endif

    match_fun_t function_addr = (match_fun_t)gcc_jit_result_get_code(result, "match");

#if EXTRAE_SUPPORT
    Extrae_event(JIT_EVENT_TYPE, 0);
#endif

#if EXTRAE_SUPPORT
    if (function_addr == NULL)
    {
        fprintf(stderr, "error getting 'match'");
        return NULL;
    }
#endif

    atomic_store(&match_fun, function_addr);

    return NULL;
}
示例#2
0
文件: toyvm.c 项目: KangDroid/gcc
static toyvm_compiled_function *
toyvm_function_compile (toyvm_function *fn)
{
  compilation_state state;
  int pc;
  char *funcname;

  memset (&state, 0, sizeof (state));

  funcname = get_function_name (fn->fn_filename);

  state.ctxt = gcc_jit_context_acquire ();

  gcc_jit_context_set_bool_option (state.ctxt,
				   GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
				   0);
  gcc_jit_context_set_bool_option (state.ctxt,
				   GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
				   0);
  gcc_jit_context_set_int_option (state.ctxt,
				  GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
				  3);
  gcc_jit_context_set_bool_option (state.ctxt,
				   GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES,
				   0);
  gcc_jit_context_set_bool_option (state.ctxt,
				   GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING,
				   0);
  gcc_jit_context_set_bool_option (state.ctxt,
				   GCC_JIT_BOOL_OPTION_DEBUGINFO,
				   1);

  /* Create types.  */
  state.int_type =
    gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_INT);
  state.bool_type =
    gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_BOOL);
  state.stack_type =
    gcc_jit_context_new_array_type (state.ctxt, NULL,
				    state.int_type, MAX_STACK_DEPTH);

  /* The constant value 1.  */
  state.const_one = gcc_jit_context_one (state.ctxt, state.int_type);

  /* Create locations.  */
  for (pc = 0; pc < fn->fn_num_ops; pc++)
    {
      toyvm_op *op = &fn->fn_ops[pc];

      state.op_locs[pc] = gcc_jit_context_new_location (state.ctxt,
							fn->fn_filename,
							op->op_linenum,
							0); /* column */
    }

  /* Creating the function.  */
  state.param_arg =
    gcc_jit_context_new_param (state.ctxt, state.op_locs[0],
			       state.int_type, "arg");
  state.fn =
    gcc_jit_context_new_function (state.ctxt,
				  state.op_locs[0],
				  GCC_JIT_FUNCTION_EXPORTED,
				  state.int_type,
				  funcname,
				  1, &state.param_arg, 0);

  /* Create stack lvalues.  */
  state.stack =
    gcc_jit_function_new_local (state.fn, NULL,
				state.stack_type, "stack");
  state.stack_depth =
    gcc_jit_function_new_local (state.fn, NULL,
				state.int_type, "stack_depth");
  state.x =
    gcc_jit_function_new_local (state.fn, NULL,
				state.int_type, "x");
  state.y =
    gcc_jit_function_new_local (state.fn, NULL,
				state.int_type, "y");

  /* 1st pass: create blocks, one per opcode. */

  /* We need an entry block to do one-time initialization, so create that
     first.  */
  state.initial_block = gcc_jit_function_new_block (state.fn, "initial");

  /* Create a block per operation.  */
  for (pc = 0; pc < fn->fn_num_ops; pc++)
    {
      char buf[16];
      sprintf (buf, "instr%i", pc);
      state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf);
    }

  /* Populate the initial block.  */

  /* "stack_depth = 0;".  */
  gcc_jit_block_add_assignment (
    state.initial_block,
    state.op_locs[0],
    state.stack_depth,
    gcc_jit_context_zero (state.ctxt, state.int_type));

  /* "PUSH (arg);".  */
  add_push (&state,
	    state.initial_block,
	    gcc_jit_param_as_rvalue (state.param_arg),
	    state.op_locs[0]);

  /* ...and jump to insn 0.  */
  gcc_jit_block_end_with_jump (state.initial_block,
			       state.op_locs[0],
			       state.op_blocks[0]);

  /* 2nd pass: fill in instructions.  */
  for (pc = 0; pc < fn->fn_num_ops; pc++)
    {
      gcc_jit_location *loc = state.op_locs[pc];

      gcc_jit_block *block = state.op_blocks[pc];
      gcc_jit_block *next_block = (pc < fn->fn_num_ops
				   ? state.op_blocks[pc + 1]
				   : NULL);

      toyvm_op *op;
      op = &fn->fn_ops[pc];

      /* Helper macros.  */

#define X_EQUALS_POP()\
      add_pop (&state, block, state.x, loc)
#define Y_EQUALS_POP()\
      add_pop (&state, block, state.y, loc)
#define PUSH_RVALUE(RVALUE)\
      add_push (&state, block, (RVALUE), loc)
#define PUSH_X()\
      PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.x))
#define PUSH_Y() \
      PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.y))

      gcc_jit_block_add_comment (block, loc, opcode_names[op->op_opcode]);

      /* Handle the individual opcodes.  */

      switch (op->op_opcode)
	{
	case DUP:
	  X_EQUALS_POP ();
	  PUSH_X ();
	  PUSH_X ();
	  break;

	case ROT:
	  Y_EQUALS_POP ();
	  X_EQUALS_POP ();
	  PUSH_Y ();
	  PUSH_X ();
	  break;

	case BINARY_ADD:
	  Y_EQUALS_POP ();
	  X_EQUALS_POP ();
	  PUSH_RVALUE (
	   gcc_jit_context_new_binary_op (
	     state.ctxt,
	     loc,
	     GCC_JIT_BINARY_OP_PLUS,
	     state.int_type,
	     gcc_jit_lvalue_as_rvalue (state.x),
	     gcc_jit_lvalue_as_rvalue (state.y)));
	  break;

	case BINARY_SUBTRACT:
	  Y_EQUALS_POP ();
	  X_EQUALS_POP ();
	  PUSH_RVALUE (
	   gcc_jit_context_new_binary_op (
	     state.ctxt,
	     loc,
	     GCC_JIT_BINARY_OP_MINUS,
	     state.int_type,
	     gcc_jit_lvalue_as_rvalue (state.x),
	     gcc_jit_lvalue_as_rvalue (state.y)));
	  break;

	case BINARY_MULT:
	  Y_EQUALS_POP ();
	  X_EQUALS_POP ();
	  PUSH_RVALUE (
	   gcc_jit_context_new_binary_op (
	     state.ctxt,
	     loc,
	     GCC_JIT_BINARY_OP_MULT,
	     state.int_type,
	     gcc_jit_lvalue_as_rvalue (state.x),
	     gcc_jit_lvalue_as_rvalue (state.y)));
	  break;

	case BINARY_COMPARE_LT:
	  Y_EQUALS_POP ();
	  X_EQUALS_POP ();
	  PUSH_RVALUE (
	     /* cast of bool to int */
	     gcc_jit_context_new_cast (
	       state.ctxt,
	       loc,
	       /* (x < y) as a bool */
	       gcc_jit_context_new_comparison (
		 state.ctxt,
		 loc,
		 GCC_JIT_COMPARISON_LT,
		 gcc_jit_lvalue_as_rvalue (state.x),
		 gcc_jit_lvalue_as_rvalue (state.y)),
	       state.int_type));
	  break;

	case RECURSE:
	  {
	    X_EQUALS_POP ();
	    gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (state.x);
	    PUSH_RVALUE (
	      gcc_jit_context_new_call (
		state.ctxt,
		loc,
		state.fn,
		1, &arg));
	    break;
	  }

	case RETURN:
	  X_EQUALS_POP ();
	  gcc_jit_block_end_with_return (
	    block,
	    loc,
	    gcc_jit_lvalue_as_rvalue (state.x));
	  break;

	  /* Ops taking an operand.  */
	case PUSH_CONST:
	  PUSH_RVALUE (
	    gcc_jit_context_new_rvalue_from_int (
	      state.ctxt,
	      state.int_type,
	      op->op_operand));
	  break;

	case JUMP_ABS_IF_TRUE:
	  X_EQUALS_POP ();
	  gcc_jit_block_end_with_conditional (
	    block,
	    loc,
	    /* "(bool)x".  */
	    gcc_jit_context_new_cast (
	      state.ctxt,
	      loc,
	      gcc_jit_lvalue_as_rvalue (state.x),
	      state.bool_type),
	    state.op_blocks[op->op_operand], /* on_true */
	    next_block); /* on_false */
	  break;

	default:
	  assert(0);
	} /* end of switch on opcode */

      /* Go to the next block.  */
      if (op->op_opcode != JUMP_ABS_IF_TRUE
	  && op->op_opcode != RETURN)
	gcc_jit_block_end_with_jump (
	  block,
	  loc,
	  next_block);

    } /* end of loop on PC locations.  */

  /* We've now finished populating the context.  Compile it.  */
  gcc_jit_result *jit_result = gcc_jit_context_compile (state.ctxt);
  gcc_jit_context_release (state.ctxt);

  toyvm_compiled_function *toyvm_result =
    (toyvm_compiled_function *)calloc (1, sizeof (toyvm_compiled_function));
  if (!toyvm_result)
    {
      fprintf (stderr, "out of memory allocating toyvm_compiled_function\n");
      gcc_jit_result_release (jit_result);
      return NULL;
    }

  toyvm_result->cf_jit_result = jit_result;
  toyvm_result->cf_code =
    (toyvm_compiled_code)gcc_jit_result_get_code (jit_result,
						  funcname);

  free (funcname);

  return toyvm_result;
}