Пример #1
0
static void assert_dup_x2_stack(unsigned char opc, struct expression *value1,
				struct expression *value2, struct expression *value3)
{
	struct basic_block *bb;
	struct statement *stmt;

	bb = alloc_simple_bb(&opc, 1);

	stack_push(bb->mimic_stack, expr_get(value3));
	stack_push(bb->mimic_stack, expr_get(value2));
	stack_push(bb->mimic_stack, expr_get(value1));

	convert_to_ir(bb->b_parent);
        stmt = stmt_entry(bb->stmt_list.next);

	assert_store_stmt(stmt);
	assert_ptr_equals(value1, to_expr(stmt->store_src));
	assert_temporary_expr(value1->vm_type, stmt->store_dest);

	assert_ptr_equals(to_expr(stmt->store_dest), pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value2, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value3, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value1, pop_and_put_expr(bb->mimic_stack));

	assert_true(stack_is_empty(bb->mimic_stack));

	free_simple_bb(bb);
}
Пример #2
0
static void __assert_convert_load(unsigned char *code,
                                  unsigned long code_size,
                                  enum vm_type expected_type,
                                  unsigned char expected_index)
{
    struct expression *expr;
    struct statement *stmt;
    struct basic_block *bb;

    bb = alloc_simple_bb(code, code_size);

    convert_to_ir(bb->b_parent);

    expr = stack_pop(bb->mimic_stack);
    assert_temporary_expr(expected_type, &expr->node);

    stmt = stmt_entry(bb->stmt_list.next);

    assert_store_stmt(stmt);
    assert_local_expr(expected_type, expected_index, stmt->store_src);
    assert_ptr_equals(&expr->node, stmt->store_dest);

    assert_true(stack_is_empty(bb->mimic_stack));

    expr_put(expr);
    free_simple_bb(bb);
}
Пример #3
0
void test_convert_tableswitch_bbs1(void)
{
	struct basic_block *bb0, *bb1, *bb2, *bb3, *bb4, *bb5, *bb6;
	struct compilation_unit *cu;

	struct cafebabe_method_info method_info;
	struct vm_method method = {
		.code_attribute.code = tableswitch1,
		.code_attribute.code_length = ARRAY_SIZE(tableswitch1),
		.method = &method_info,
	};

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

	cu = compilation_unit_alloc(&method);

	analyze_control_flow(cu);
	convert_to_ir(cu);
	assert_int_equals(7, nr_bblocks(cu));

	bb0 = bb_entry(cu->bb_list.next);
	bb1 = bb_entry(bb0->bb_list_node.next);
	bb2 = bb_entry(bb1->bb_list_node.next);
	bb3 = bb_entry(bb2->bb_list_node.next);
	bb4 = bb_entry(bb3->bb_list_node.next);
	bb5 = bb_entry(bb4->bb_list_node.next);
	bb6 = bb_entry(bb5->bb_list_node.next);

	assert_basic_block_successors((struct basic_block*[]){bb6, bb1}, 2, bb0);
	assert_basic_block_successors((struct basic_block*[]){bb6, bb2}, 2, bb1);
Пример #4
0
static void assert_dup2_x2_stack(unsigned char opc, struct expression *value1,
				struct expression *value2, struct expression *value3,
				struct expression *value4)
{
	struct statement *stmt, *stmt2;
	struct basic_block *bb;

	if (value1->vm_type == J_LONG || value1->vm_type == J_DOUBLE) {
		if (value2->vm_type == J_LONG || value2->vm_type == J_DOUBLE) {
			assert_dup_x1_stack(opc, value1, value2);
			return;
		} else {
			assert_dup_x2_stack(opc, value1, value2, value3);
			return;
		}
	} else {
		if (value3->vm_type == J_LONG || value3->vm_type == J_DOUBLE) {
			assert_dup2_x1_stack(opc, value1, value2, value3);
			return;
		}
	}

	bb = alloc_simple_bb(&opc, 1);

	stack_push(bb->mimic_stack, expr_get(value4));
	stack_push(bb->mimic_stack, expr_get(value3));
	stack_push(bb->mimic_stack, expr_get(value2));
	stack_push(bb->mimic_stack, expr_get(value1));

	convert_to_ir(bb->b_parent);
        stmt = stmt_entry(bb->stmt_list.next);
	stmt2 = stmt_entry(stmt->stmt_list_node.next);

	assert_store_stmt(stmt);
	assert_ptr_equals(value2, to_expr(stmt->store_src));
	assert_temporary_expr(value2->vm_type, stmt->store_dest);

	assert_store_stmt(stmt2);
	assert_ptr_equals(value1, to_expr(stmt2->store_src));
	assert_temporary_expr(value1->vm_type, stmt2->store_dest);

	assert_ptr_equals(to_expr(stmt2->store_dest), pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(to_expr(stmt->store_dest), pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value3, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value4, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value1, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value2, pop_and_put_expr(bb->mimic_stack));

	assert_true(stack_is_empty(bb->mimic_stack));

	free_simple_bb(bb);
}
Пример #5
0
static void assert_convert_fconst(enum vm_type expected_type,
                                  double expected_value, unsigned char opc)
{
    struct expression *expr;
    struct basic_block *bb;

    bb = alloc_simple_bb(&opc, 1);
    convert_to_ir(bb->b_parent);

    expr = stack_pop(bb->mimic_stack);
    assert_fvalue_expr(expected_type, expected_value, &expr->node);
    assert_true(stack_is_empty(bb->mimic_stack));

    expr_put(expr);
    free_simple_bb(bb);
}
Пример #6
0
static void
assert_swap_stack(unsigned char opc, void *value1, void *value2)
{
	struct basic_block *bb;

	bb = alloc_simple_bb(&opc, 1);

	stack_push(bb->mimic_stack, expr_get(value1));
	stack_push(bb->mimic_stack, expr_get(value2));

	convert_to_ir(bb->b_parent);
	assert_ptr_equals(value1, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value2, pop_and_put_expr(bb->mimic_stack));
	assert_true(stack_is_empty(bb->mimic_stack));

	free_simple_bb(bb);
}
Пример #7
0
static void __assert_convert_const(enum vm_type expected_type,
                                   long long expected_value,
                                   unsigned char *code,
                                   unsigned long code_size)
{
    struct expression *expr;
    struct basic_block *bb;

    bb = alloc_simple_bb(code, code_size);
    convert_to_ir(bb->b_parent);

    expr = stack_pop(bb->mimic_stack);
    assert_value_expr(expected_type, expected_value, &expr->node);
    assert_true(stack_is_empty(bb->mimic_stack));

    expr_put(expr);
    free_simple_bb(bb);
}
Пример #8
0
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;
}
Пример #9
0
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;
}