コード例 #1
0
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Let's try to inject the equivalent of:
     void
     hello_world (const char *name)
     {
       // a test comment
       printf ("hello from %s\n", name);
     }
  */
  gcc_jit_type *void_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *const_char_ptr_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR);
  gcc_jit_param *param_name =
    gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name");
  gcc_jit_function *func =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  void_type,
				  "hello_world",
				  1, &param_name,
				  0);

  gcc_jit_param *param_format =
    gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format");
  gcc_jit_function *printf_func =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_IMPORTED,
				  gcc_jit_context_get_type (
				     ctxt, GCC_JIT_TYPE_INT),
				  "printf",
				  1, &param_format,
				  1);
  gcc_jit_rvalue *args[2];
  args[0] = gcc_jit_context_new_string_literal (ctxt, "hello from %s\n");
  args[1] = gcc_jit_param_as_rvalue (param_name);

  gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);

  gcc_jit_block_add_comment (
    block, NULL,
    "a test comment");

  gcc_jit_block_add_eval (
    block, NULL,
    gcc_jit_context_new_call (ctxt,
			      NULL,
			      printf_func,
			      2, args));
  gcc_jit_block_end_with_void_return (block, NULL);
}
コード例 #2
0
ファイル: test-nested-contexts.c プロジェクト: AlexMioMio/gcc
static void
make_test_quadratic (struct top_level *top_level,
		     struct middle_level *middle_level,
		     struct bottom_level *bottom_level)
{
  gcc_jit_param *a =
    gcc_jit_context_new_param (bottom_level->ctxt, NULL,
			       top_level->numeric_type, "a");
  gcc_jit_param *b =
    gcc_jit_context_new_param (bottom_level->ctxt, NULL,
			       top_level->numeric_type, "b");
  gcc_jit_param *c =
    gcc_jit_context_new_param (bottom_level->ctxt, NULL,
			       top_level->numeric_type, "c");
  gcc_jit_param *r1 =
    gcc_jit_context_new_param (bottom_level->ctxt, NULL,
			       top_level->numeric_type_ptr, "r1");
  gcc_jit_param *r2 =
    gcc_jit_context_new_param (bottom_level->ctxt, NULL,
			       top_level->numeric_type_ptr, "r2");
  gcc_jit_param *params[] = {a, b, c, r1, r2};
  gcc_jit_function *test_quadratic =
    gcc_jit_context_new_function (bottom_level->ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  top_level->int_type,
				  "test_quadratic",
				  5, params,
				  0);

  /* struct quadratic q; */
  gcc_jit_lvalue *q =
    gcc_jit_function_new_local (
      test_quadratic, NULL,
      top_level->struct_quadratic,
      "q");

  gcc_jit_block *initial =
    gcc_jit_function_new_block (test_quadratic,
				"initial");
  gcc_jit_block *on_positive_discriminant
    = gcc_jit_function_new_block (test_quadratic,
				  "positive_discriminant");

  gcc_jit_block *on_nonpositive_discriminant
    = gcc_jit_function_new_block (test_quadratic,
				  "nonpositive_discriminant");

  gcc_jit_block *on_zero_discriminant
    = gcc_jit_function_new_block (test_quadratic,
				  "zero_discriminant");

  gcc_jit_block *on_negative_discriminant
    = gcc_jit_function_new_block (test_quadratic,
				  "negative_discriminant");

  /* Initial block.  */
  /* q.a = a; */
  gcc_jit_block_add_assignment (
    initial, NULL,
    gcc_jit_lvalue_access_field (q, NULL, top_level->a),
    gcc_jit_param_as_rvalue (a));
  /* q.b = b; */
  gcc_jit_block_add_assignment (
    initial, NULL,
    gcc_jit_lvalue_access_field (q, NULL, top_level->b),
    gcc_jit_param_as_rvalue (b));
  /* q.c = c; */
  gcc_jit_block_add_assignment (
    initial, NULL,
    gcc_jit_lvalue_access_field (q, NULL, top_level->c),
    gcc_jit_param_as_rvalue (c));
  /* calc_discriminant (&q); */
  gcc_jit_rvalue *address_of_q = gcc_jit_lvalue_get_address (q, NULL);
  gcc_jit_block_add_eval (
    initial, NULL,
    gcc_jit_context_new_call (
      bottom_level->ctxt, NULL,
      middle_level->calc_discriminant,
      1, &address_of_q));

  gcc_jit_block_add_comment (
    initial, NULL,
    "if (q.discriminant > 0)");
  gcc_jit_block_end_with_conditional (
    initial, NULL,
    gcc_jit_context_new_comparison (
      bottom_level->ctxt, NULL,
      GCC_JIT_COMPARISON_GT,
      gcc_jit_rvalue_access_field (
	gcc_jit_lvalue_as_rvalue (q),
	NULL,
	top_level->discriminant),
      top_level->zero),
    on_positive_discriminant,
    on_nonpositive_discriminant);

  /* Block: "on_positive_discriminant" */
  /* double s = sqrt (q.discriminant); */
  gcc_jit_lvalue *s = gcc_jit_function_new_local (
    test_quadratic, NULL,
    top_level->numeric_type,
    "s");
  gcc_jit_rvalue *discriminant_of_q =
    gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (q),
				 NULL,
				 top_level->discriminant);
  gcc_jit_block_add_assignment (
    on_positive_discriminant, NULL,
    s,
    gcc_jit_context_new_call (
      bottom_level->ctxt, NULL,
      top_level->sqrt,
      1, &discriminant_of_q));

  gcc_jit_rvalue *minus_b =
    gcc_jit_context_new_unary_op (
      bottom_level->ctxt, NULL,
      GCC_JIT_UNARY_OP_MINUS,
      top_level->numeric_type,
      gcc_jit_param_as_rvalue (b));
  gcc_jit_rvalue *two_a =
    gcc_jit_context_new_binary_op (
      bottom_level->ctxt, NULL,
      GCC_JIT_BINARY_OP_MULT,
      top_level->numeric_type,
      gcc_jit_context_new_rvalue_from_int (
	bottom_level->ctxt,
	top_level->numeric_type,
	2),
      gcc_jit_param_as_rvalue (a));

  gcc_jit_block_add_comment (
    on_positive_discriminant, NULL,
    "*r1 = (-b + s) / (2 * a);");
  gcc_jit_block_add_assignment (
    on_positive_discriminant, NULL,

    /* "*r1 = ..." */
    gcc_jit_rvalue_dereference (
      gcc_jit_param_as_rvalue (r1), NULL),

    /* (-b + s) / (2 * a) */
    gcc_jit_context_new_binary_op (
      bottom_level->ctxt, NULL,
      GCC_JIT_BINARY_OP_DIVIDE,
      top_level->numeric_type,
      gcc_jit_context_new_binary_op (
	bottom_level->ctxt, NULL,
	GCC_JIT_BINARY_OP_PLUS,
	top_level->numeric_type,
	minus_b,
	gcc_jit_lvalue_as_rvalue (s)),
      two_a));

  gcc_jit_block_add_comment (
    on_positive_discriminant, NULL,
    "*r2 = (-b - s) / (2 * a)");
  gcc_jit_block_add_assignment (
    on_positive_discriminant, NULL,

    /* "*r2 = ..." */
    gcc_jit_rvalue_dereference (
      gcc_jit_param_as_rvalue (r2), NULL),

    /* (-b - s) / (2 * a) */
    gcc_jit_context_new_binary_op (
      bottom_level->ctxt, NULL,
      GCC_JIT_BINARY_OP_DIVIDE,
      top_level->numeric_type,
      gcc_jit_context_new_binary_op (
	bottom_level->ctxt, NULL,
	GCC_JIT_BINARY_OP_MINUS,
	top_level->numeric_type,
	minus_b,
	gcc_jit_lvalue_as_rvalue (s)),
      two_a));

  /* "return 2;" */
  gcc_jit_block_end_with_return (
    on_positive_discriminant, NULL,
    gcc_jit_context_new_rvalue_from_int (
      bottom_level->ctxt,
      top_level->int_type,
      2));

  /* Block: "on_nonpositive_discriminant" */
  gcc_jit_block_add_comment (
    on_nonpositive_discriminant, NULL,
    "else if (q.discriminant == 0)");
  gcc_jit_block_end_with_conditional (
    on_nonpositive_discriminant, NULL,
    gcc_jit_context_new_comparison (
      bottom_level->ctxt, NULL,
      GCC_JIT_COMPARISON_EQ,
      gcc_jit_rvalue_access_field (
	gcc_jit_lvalue_as_rvalue (q),
	NULL,
	top_level->discriminant),
      top_level->zero),
    on_zero_discriminant,
    on_negative_discriminant);

  /* Block: "on_zero_discriminant" */
  gcc_jit_block_add_comment (
    on_zero_discriminant, NULL,
    "*r1 = -b / (2 * a);");
  gcc_jit_block_add_assignment (
    on_zero_discriminant, NULL,

    /* "*r1 = ..." */
    gcc_jit_rvalue_dereference (
      gcc_jit_param_as_rvalue (r1), NULL),

    /* -b / (2 * a) */
    gcc_jit_context_new_binary_op (
      bottom_level->ctxt, NULL,
      GCC_JIT_BINARY_OP_DIVIDE,
      top_level->numeric_type,
      minus_b,
      two_a));

  /* "return 1;" */
  gcc_jit_block_end_with_return (
    on_zero_discriminant, NULL,
      gcc_jit_context_one (bottom_level->ctxt, top_level->int_type));

  /* Block: "on_negative_discriminant" */
  gcc_jit_block_end_with_return (
    /* else return 0; */
    on_negative_discriminant, NULL,
    gcc_jit_context_zero (bottom_level->ctxt, top_level->int_type));
}
コード例 #3
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;
}
コード例 #4
0
ファイル: test-nested-contexts.c プロジェクト: AlexMioMio/gcc
static void
make_calc_discriminant (struct top_level *top_level,
			struct middle_level *middle_level)
{
  /* Build "calc_discriminant".  */
  gcc_jit_param *param_q =
    gcc_jit_context_new_param (middle_level->ctxt, NULL,
			       top_level->quadratic_ptr, "q");
  middle_level->calc_discriminant =
    gcc_jit_context_new_function (middle_level->ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  top_level->void_type,
				  "calc_discriminant",
				  1, &param_q,
				  0);
  gcc_jit_block *blk =
    gcc_jit_function_new_block (middle_level->calc_discriminant, NULL);
  gcc_jit_block_add_comment (
    blk, NULL,
    "(b^2 - 4ac)");

  gcc_jit_rvalue *q_a =
    gcc_jit_lvalue_as_rvalue (
	gcc_jit_rvalue_dereference_field (
	  gcc_jit_param_as_rvalue (param_q),
	  NULL, top_level->a));
  gcc_jit_rvalue *q_b =
    gcc_jit_lvalue_as_rvalue (
	gcc_jit_rvalue_dereference_field (
	  gcc_jit_param_as_rvalue (param_q),
	  NULL, top_level->b));
  gcc_jit_rvalue *q_c =
    gcc_jit_lvalue_as_rvalue (
	gcc_jit_rvalue_dereference_field (
	  gcc_jit_param_as_rvalue (param_q),
	  NULL, top_level->c));

  gcc_jit_block_add_assignment (
    blk, NULL,

    /* q->discriminant =...  */
    gcc_jit_rvalue_dereference_field (
      gcc_jit_param_as_rvalue (param_q),
      NULL,
      top_level->discriminant),

    /* (q->b * q->b) - (4 * q->a * q->c) */
    gcc_jit_context_new_binary_op (
      middle_level->ctxt, NULL,
      GCC_JIT_BINARY_OP_MINUS,
      top_level->numeric_type,

      /* (q->b * q->b) */
      gcc_jit_context_new_binary_op (
	middle_level->ctxt, NULL,
	GCC_JIT_BINARY_OP_MULT,
	top_level->numeric_type,
	q_b, q_b),

      /* (4 * (q->a * q->c)) */
      gcc_jit_context_new_binary_op (
	middle_level->ctxt, NULL,
	GCC_JIT_BINARY_OP_MULT,
	top_level->numeric_type,
	/* 4.0 */
	gcc_jit_context_new_rvalue_from_int (
	  middle_level->ctxt,
	  top_level->numeric_type,
	  4),
	/* (q->a * q->c) */
	gcc_jit_context_new_binary_op (
	  middle_level->ctxt, NULL,
	  GCC_JIT_BINARY_OP_MULT,
	  top_level->numeric_type,
	  q_a, q_c)))); /* end of gcc_jit_function_add_assignment call.  */

  gcc_jit_block_end_with_void_return (blk, NULL);
}