Exemplo n.º 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);
}
Exemplo n.º 2
0
void test_no_basic_block_when_offset_out_of_range(void)
{
	struct compilation_unit *cu = compilation_unit_alloc(&method);
	struct basic_block *block = alloc_basic_block(cu, 1, 2);

	list_add_tail(&block->bb_list_node, &cu->bb_list);
	assert_ptr_equals(NULL, find_bb(cu, 0));
	assert_ptr_equals(NULL, find_bb(cu, 2));

	free_compilation_unit(cu);
}
Exemplo n.º 3
0
void test_pqueue_returns_highest_priority_element_first(void)
{
	setup();

	pqueue_insert(pqueue, (void *) 2UL);
	pqueue_insert(pqueue, (void *) 1UL);
	pqueue_insert(pqueue, (void *) 0UL);

	assert_ptr_equals((void *) 0UL, pqueue_remove_top(pqueue));
	assert_ptr_equals((void *) 1UL, pqueue_remove_top(pqueue));
	assert_ptr_equals((void *) 2UL, pqueue_remove_top(pqueue));

	teardown();
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
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);
}
Exemplo n.º 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);
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
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);
}
Exemplo n.º 9
0
void test_find_basic_block(void)
{
	struct basic_block *b1;
	struct basic_block *b2;
	struct basic_block *b3;
	struct compilation_unit *cu = compilation_unit_alloc(&method);

	b1 = alloc_basic_block(cu, 0, 3);
	b2 = alloc_basic_block(cu, 3, 5);
	b3 = alloc_basic_block(cu, 5, 6);

	list_add_tail(&b1->bb_list_node, &cu->bb_list);
	list_add_tail(&b2->bb_list_node, &cu->bb_list);
	list_add_tail(&b3->bb_list_node, &cu->bb_list);

	assert_ptr_equals(b1, find_bb(cu, 2));
	assert_ptr_equals(b2, find_bb(cu, 3));
	assert_ptr_equals(b3, find_bb(cu, 5));

	free_compilation_unit(cu);
}
Exemplo n.º 10
0
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);
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
0
void test_empty_range_does_not_contain_anything(void)
{
	struct live_range range = { .start = 0, .end = 0 };

	assert_false(in_range(&range, 0));
	assert_false(in_range(&range, 1));
}

void test_empy_range_is_empty(void)
{
	struct live_range range = { .start = 0, .end = 0 };

	assert_true(range_is_empty(&range));
}

void test_range_length_treats_end_as_exclusive(void)
{
	struct live_range range = { .start = 0, .end = 2 };

	assert_int_equals(2, range_len(&range));
}

void test_in_range_treats_end_as_exclusive(void)
{
	struct live_range range = { .start = 0, .end = 2 };

	assert_true(in_range(&range, 0));
	assert_true(in_range(&range, 1));
	assert_false(in_range(&range, 2));
}

void test_range_that_is_within_another_range_intersects(void)
{
	struct live_range range1 = { .start = 0, .end = 3 };
	struct live_range range2 = { .start = 1, .end = 2 };

	assert_true(ranges_intersect(&range1, &range2));
	assert_true(ranges_intersect(&range2, &range1));
}

void test_ranges_that_intersect(void)
{
	struct live_range range1 = { .start = 0, .end = 2 };
	struct live_range range2 = { .start = 1, .end = 3 };

	assert_true(ranges_intersect(&range1, &range2));
	assert_true(ranges_intersect(&range2, &range1));
}

void test_ranges_that_do_not_intersect(void)
{
	struct live_range range1 = { .start = 0, .end = 2 };
	struct live_range range2 = { .start = 2, .end = 4 };

	assert_false(ranges_intersect(&range1, &range2));
	assert_false(ranges_intersect(&range2, &range1));
}

void test_interval_add_range(void)
{
#if 0
	struct live_interval it;
	struct live_range *r;

	INIT_LIST_HEAD(&it.range_list);

	interval_add_range(&it, 1, 3);
	r = interval_first_range(&it);
	assert_int_equals(1, r->start);
	assert_int_equals(3, r->end);
	assert_ptr_equals(NULL, next_range(&it.range_list, r));

	interval_add_range(&it, 5, 7);
	r = interval_first_range(&it);
	assert_int_equals(1, r->start);
	assert_int_equals(3, r->end);
	r = next_range(&it.range_list, r);
	assert_int_equals(5, r->start);
	assert_int_equals(7, r->end);
	assert_ptr_equals(NULL, next_range(&it.range_list, r));

	interval_add_range(&it, 3, 5);
	r = interval_first_range(&it);
	assert_int_equals(1, r->start);
	assert_int_equals(7, r->end);
	assert_ptr_equals(NULL, next_range(&it.range_list, r));

	interval_add_range(&it, 7, 8);
	r = interval_first_range(&it);
	assert_int_equals(1, r->start);
	assert_int_equals(8, r->end);
	assert_ptr_equals(NULL, next_range(&it.range_list, r));

	interval_add_range(&it, 10, 13);
	r = interval_first_range(&it);
	assert_int_equals(1, r->start);
	assert_int_equals(8, r->end);
	r = next_range(&it.range_list, r);
	assert_int_equals(10, r->start);
	assert_int_equals(13, r->end);
	assert_ptr_equals(NULL, next_range(&it.range_list, r));

	interval_add_range(&it, 0, 14);
	r = interval_first_range(&it);
	assert_int_equals(0, r->start);
	assert_int_equals(14, r->end);
	assert_ptr_equals(NULL, next_range(&it.range_list, r));
#endif
}
Exemplo n.º 13
0
static void assert_ld_insn(enum insn_type type, enum machine_reg reg, struct stack_slot *slot, struct insn *insn)
{
	assert_int_equals(type, insn->type);
	assert_int_equals(reg, mach_reg(&insn->x.reg));
	assert_ptr_equals(slot, insn->y.slot); 
}