コード例 #1
0
ファイル: compilation-unit-test.c プロジェクト: siam/jato
void test_instruction_positions_are_computed_in_basic_block_order(void)
{
	struct compilation_unit *cu = compilation_unit_alloc(&method);
	struct basic_block *b1, *b2;
	struct insn *insns[4];
	unsigned long i;

	for (i = 0; i < ARRAY_SIZE(insns); i++)
		insns[i] = alloc_insn(INSN_ADD);

	b1 = get_basic_block(cu, 0, ARRAY_SIZE(insns)/2);
	for (i = 0 ; i < ARRAY_SIZE(insns) / 2; i++)
		bb_add_insn(b1, insns[i]);

	b2 = get_basic_block(cu, ARRAY_SIZE(insns) / 2, ARRAY_SIZE(insns));
	for (i = ARRAY_SIZE(insns) / 2 ; i < ARRAY_SIZE(insns); i++)
		bb_add_insn(b2, insns[i]);

	compute_insn_positions(cu);

	for (i = 0; i < ARRAY_SIZE(insns); i++)
		assert_int_equals(i * 2, insns[i]->lir_pos);

	free_compilation_unit(cu);
}
コード例 #2
0
ファイル: spill-reload-test.c プロジェクト: siam/jato
void test_reload_insn_is_inserted_at_the_beginning_of_the_interval_if_necessary(void)
{
        struct compilation_unit *cu;
        struct insn *insn_array[2];
        struct var_info *r1, *r2;
        struct basic_block *bb;
	struct insn *insn;

        cu = compilation_unit_alloc(&method);
        r1 = get_var(cu, J_INT);
        r2 = get_var(cu, J_INT);

        insn_array[0] = arithmetic_insn(INSN_ADD, r1, r1, r1);
        insn_array[1] = arithmetic_insn(INSN_ADD, r2, r2, r2);

        bb = get_basic_block(cu, 0, 2);
        bb_add_insn(bb, insn_array[0]);
        bb_add_insn(bb, insn_array[1]);

	r1->interval->spill_reload_reg.interval = r1->interval;
	r2->interval->spill_reload_reg.interval = r2->interval;

	r2->interval->flags |= INTERVAL_FLAG_NEED_RELOAD;
	r2->interval->spill_parent = r1->interval;

	compute_insn_positions(cu);
	analyze_liveness(cu);
	insert_spill_reload_insns(cu);

	/*
	 * A reload instruction is inserted at the beginning.
	 */
	insn = list_first_entry(&bb->insn_list, struct insn, insn_list_node);
	assert_ld_insn(INSN_LD_LOCAL, r2->interval->reg, r1->interval->spill_slot, insn);

	/*
	 * Second instruction stays the same.
	 */
	insn = list_next_entry(&insn->insn_list_node, struct insn, insn_list_node);
	assert_ptr_equals(insn_array[0], insn);

	/*
	 * Last instruction stays the same. 
	 */
	insn = list_next_entry(&insn->insn_list_node, struct insn, insn_list_node);
	assert_ptr_equals(insn_array[1], insn);

	free_compilation_unit(cu);
}
コード例 #3
0
ファイル: liveness-test.c プロジェクト: vegard/jato
void test_variable_range_spans_two_basic_blocks(void)
{
	struct basic_block *bb1, *bb2;
	struct compilation_unit *cu;
	struct var_info *r1, *r2;
	struct insn *insn[4];

	cu = compilation_unit_alloc(&method);
	r1 = get_var(cu);
	r2 = get_var(cu);

	bb1 = get_basic_block(cu, 0, 2);
	bb2 = get_basic_block(cu, 2, 4);
	bb_add_successor(bb1, bb2);

	insn[2] = imm_insn(INSN_SETL, 0x02, r2);
	bb_add_insn(bb2, insn[2]);

	insn[3] = arithmetic_insn(INSN_ADD, r1, r2, r2);
	bb_add_insn(bb2, insn[3]);

	insn[0] = imm_insn(INSN_SETL, 0x01, r1);
	bb_add_insn(bb1, insn[0]);

	insn[1] = branch_insn(INSN_JMP, bb2);
	bb_add_insn(bb1, insn[1]);

	compute_insn_positions(cu);
	analyze_liveness(cu);

	assert_defines(bb1, r1);
	assert_defines(bb2, r2);
	assert_uses(bb2, r1);

	assert_live_range(r1->interval, 0, 4);
	assert_live_range(r2->interval, 2, 4);

	assert_ptr_equals(insn[0], r1->interval->insn_array[0]);
	assert_ptr_equals(insn[1], r1->interval->insn_array[1]);
	assert_ptr_equals(insn[2], r1->interval->insn_array[2]);
	assert_ptr_equals(insn[3], r1->interval->insn_array[3]);

	assert_ptr_equals(insn[2], r2->interval->insn_array[0]);
	assert_ptr_equals(insn[3], r2->interval->insn_array[1]);

	free_compilation_unit(cu);
}
コード例 #4
0
ファイル: spill-reload-test.c プロジェクト: vegard/jato
void test_spill_insn_is_inserted_at_the_end_of_the_interval_if_necessary(void)
{
        struct compilation_unit *cu;
        struct insn *insn_array[2];
        struct var_info *r1, *r2;
        struct basic_block *bb;
	struct insn *insn;

        cu = compilation_unit_alloc(&method);
        r1 = get_var(cu);
        r2 = get_var(cu);

        insn_array[0] = arithmetic_insn(INSN_ADD, r1, r1, r1);
        insn_array[1] = arithmetic_insn(INSN_ADD, r2, r2, r2);

        bb = get_basic_block(cu, 0, 2);
        bb_add_insn(bb, insn_array[0]);
        bb_add_insn(bb, insn_array[1]);

	r1->interval->need_spill = true;

	compute_insn_positions(cu);
	analyze_liveness(cu);
	insert_spill_reload_insns(cu);

	/*
	 * First instruction stays the same. 
	 */
	insn = list_first_entry(&bb->insn_list, struct insn, insn_list_node);
	assert_ptr_equals(insn_array[0], insn);

	/*
	 * Last instruction stays the same. 
	 */
	insn = list_next_entry(&insn->insn_list_node, struct insn, insn_list_node);
	assert_ptr_equals(insn_array[1], insn);

	/*
	 * A spill instruction is inserted after the interval end.
	 */ 
	insn = list_next_entry(&insn->insn_list_node, struct insn, insn_list_node);
	assert_st_insn(INSN_ST_LOCAL, r1->interval->spill_slot, r1->interval->reg, insn);

	free_compilation_unit(cu);
}
コード例 #5
0
ファイル: spill-reload-test.c プロジェクト: vegard/jato
void test_empty_interval_is_never_spilled(void)
{
	struct compilation_unit *cu;
	struct basic_block *bb;
	struct var_info *r1;

	cu = compilation_unit_alloc(&method);
	bb = get_basic_block(cu, 0, 2);

	r1 = get_var(cu);
	r1->interval->need_spill = true;

	compute_insn_positions(cu);
	analyze_liveness(cu);
	insert_spill_reload_insns(cu);

	free_compilation_unit(cu);
}
コード例 #6
0
ファイル: liveness-test.c プロジェクト: vegard/jato
void test_variable_range_limited_to_basic_block(void)
{
	struct compilation_unit *cu;
	struct var_info *r1, *r2;
	struct basic_block *bb;
	struct insn *insn[3];

	cu = compilation_unit_alloc(&method);
	r1 = get_var(cu);
	r2 = get_var(cu);

	bb = get_basic_block(cu, 0, 3);

	insn[0] = imm_insn(INSN_SETL, 0x01, r1);
	bb_add_insn(bb, insn[0]);

	insn[1] = imm_insn(INSN_SETL, 0x02, r2);
	bb_add_insn(bb, insn[1]);

	insn[2] = arithmetic_insn(INSN_ADD, r1, r2, r2);
	bb_add_insn(bb, insn[2]);

	compute_insn_positions(cu);
	analyze_liveness(cu);

	assert_defines(bb, r1);
	assert_defines(bb, r2);

	assert_live_range(r1->interval, 0, 3);
	assert_live_range(r2->interval, 1, 3);

	assert_ptr_equals(insn[0], r1->interval->insn_array[0]);
	assert_ptr_equals(insn[1], r1->interval->insn_array[1]);
	assert_ptr_equals(insn[2], r1->interval->insn_array[2]);

	assert_ptr_equals(insn[1], r2->interval->insn_array[0]);
	assert_ptr_equals(insn[2], r2->interval->insn_array[1]);

	free_compilation_unit(cu);
}
コード例 #7
0
ファイル: compiler.c プロジェクト: vegard/jato
int compile(struct compilation_unit *cu)
{
	int err;

	if (opt_trace_method)
		trace_method(cu);

	err = analyze_control_flow(cu);
	if (err)
		goto out;

	err = convert_to_ir(cu);
	if (err)
		goto out;

	err = sort_basic_blocks(cu);
	if (err)
		goto out;

	if (opt_trace_cfg)
		trace_cfg(cu);

	if (opt_trace_tree_ir)
		trace_tree_ir(cu);

	err = select_instructions(cu);
	if (err)
		goto out;

	compute_insn_positions(cu);

	if (opt_trace_lir)
		trace_lir(cu);

	err = analyze_liveness(cu);
	if (err)
		goto out;

	if (opt_trace_liveness)
		trace_liveness(cu);

	err = allocate_registers(cu);
	if (err)
		goto out;

	if (opt_trace_regalloc)
		trace_regalloc(cu);

	err = insert_spill_reload_insns(cu);
	if (err)
		goto out;

	assert(all_insn_have_bytecode_offset(cu));

	err = emit_machine_code(cu);
	if (err)
		goto out;

	if (opt_trace_machine_code)
		trace_machine_code(cu);

	cu->is_compiled = true;

	perf_append_cu(cu);
  out:
	if (err)
		compile_error(cu, err);

	return err;
}
コード例 #8
0
ファイル: compiler.c プロジェクト: abak/jato
static int do_compile(struct compilation_unit *cu)
{
	bool ssa_enable;
	int err;

	if (opt_print_compilation)
		print_compilation(cu->method);

	if (opt_trace_compile)
		trace_method(cu);

	err = inline_subroutines(cu->method);
	if (err)
		goto out;

	if (opt_trace_bytecode)
		trace_bytecode(cu->method);

	err = analyze_control_flow(cu);
	if (err)
		goto out;

	err = convert_to_ir(cu);
	if (err)
		goto out;

	ssa_enable = opt_ssa_enable && uses_array_ops(cu);

	if (ssa_enable) {
		err = compute_dfns(cu);
		if (err)
			goto out;
	}

	if (opt_trace_cfg)
		trace_cfg(cu);

	if (opt_trace_tree_ir)
		trace_tree_ir(cu);

	err = select_instructions(cu);
	if (err)
		goto out;

	compute_insn_positions(cu);

	if (opt_trace_lir)
		trace_lir(cu);

	if (ssa_enable) {
		err = compute_dom(cu);
		if (err)
			goto out;

		err = compute_dom_frontier(cu);
		if (err)
			goto out;

		err = lir_to_ssa(cu);
		if (err)
			goto out;

		if(opt_trace_ssa)
			trace_ssa(cu);

		imm_copy_propagation(cu);

		abc_removal(cu);

		err = dce(cu);
		if (err)
			goto out;

		err = ssa_to_lir(cu);
		if (err)
			goto out;
	}

	err = analyze_liveness(cu);
	if (err)
		goto out;

	if (opt_trace_liveness)
		trace_liveness(cu);

	err = allocate_registers(cu);
	if (err)
		goto out;

	err = mark_clobbers(cu);
	if (err)
		goto out;

	err = insert_spill_reload_insns(cu);
	if (err)
		goto out;

	if (opt_trace_regalloc)
		trace_regalloc(cu);

	err = convert_ic_calls(cu);
	if (err)
		goto out;

	assert(all_insn_have_bytecode_offset(cu));

	err = peephole_optimize(cu);
	if (err)
		goto out;

	err = emit_machine_code(cu);
	if (err)
		goto out;

	err = build_bc_offset_map(cu);
	if (err)
		goto out;

	if (opt_trace_machine_code)
		trace_machine_code(cu);

	resolve_fixup_offsets(cu);

	perf_append_cu(cu);
  out:
	if (opt_trace_compile)
		trace_flush();

	if (err && !exception_occurred())
		compile_error(cu, err);

	return err;
}