Commit 0bb7a8cb authored by Matthias Braun's avatar Matthias Braun
Browse files

- Don't perform memory operands merging too early

- Extend spillslot verifier to detect "lonely" spills
- Make ia32 backend display warnings when emitting unknown nodes
parent cb9fc172
......@@ -246,7 +246,9 @@ static void be_ra_chordal_register_options(lc_opt_entry_t *grp)
co_register_options(chordal_grp);
be_java_coal_register_options(chordal_grp);
#ifdef WITH_ILP
be_spill_remat_register_options(chordal_grp);
#endif
}
#endif /* WITH_LIBCORE */
......@@ -484,8 +486,7 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi)
);
dump(BE_CH_DUMP_SPILL, irg, chordal_env.cls, "-spill", dump_ir_block_graph_sched);
check_for_memory_operands(&chordal_env);
be_abi_fix_stack_nodes(bi->abi, chordal_env.lv);
be_abi_fix_stack_nodes(bi->abi, chordal_env.lv);
BE_TIMER_PUSH(ra_timer.t_verify);
......@@ -597,6 +598,8 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi)
}
BE_TIMER_POP(ra_timer.t_verify);
check_for_memory_operands(&chordal_env);
BE_TIMER_PUSH(ra_timer.t_epilog);
dump(BE_CH_DUMP_LOWER, irg, NULL, "-spilloff", dump_ir_block_graph_sched);
......
......@@ -3092,7 +3092,6 @@ connect_all_remats_with_keep(spill_ilp_t * si)
obstack_free(si->obst, ins);
}
}
#endif
static void
connect_all_spills_with_keep(spill_ilp_t * si)
......
......@@ -274,6 +274,13 @@ static int cmp_spill(const void* d1, const void* d2, size_t size) {
return s1->spill != s2->spill;
}
static spill_t *find_spill(be_verify_spillslots_env_t *env, ir_node *node) {
spill_t spill;
spill.spill = node;
return set_find(env->spills, &spill, sizeof(spill), HASH_PTR(node));
}
static spill_t *get_spill(be_verify_spillslots_env_t *env, ir_node *node, entity *ent) {
spill_t spill, *res;
int hash = HASH_PTR(node);
......@@ -291,8 +298,16 @@ static spill_t *get_spill(be_verify_spillslots_env_t *env, ir_node *node, entity
static void collect(be_verify_spillslots_env_t *env, ir_node *node, ir_node *reload, entity* ent);
static void check_entity(be_verify_spillslots_env_t *env, ir_node *node, entity *ent) {
if(ent == NULL) {
ir_fprintf(stderr, "Verify warning: Node %+F in block %+F(%s) should have an entity assigned\n",
node, get_nodes_block(node), get_irg_dump_name(env->irg));
}
}
static void collect_spill(be_verify_spillslots_env_t *env, ir_node *node, ir_node *reload, entity* ent) {
entity *spillent = be_get_frame_entity(node);
check_entity(env, node, spillent);
get_spill(env, node, ent);
if(spillent != ent) {
......@@ -316,6 +331,7 @@ static void collect_memperm(be_verify_spillslots_env_t *env, ir_node *node, ir_n
out = get_Proj_proj(node);
spillent = be_get_MemPerm_out_entity(memperm, out);
check_entity(env, memperm, spillent);
if(spillent != ent) {
ir_fprintf(stderr, "Verify warning: MemPerm %+F has different entity than reload %+F in block %+F(%s)\n",
node, reload, get_nodes_block(node), get_irg_dump_name(env->irg));
......@@ -386,6 +402,7 @@ static void collect_spills_walker(ir_node *node, void *data) {
if(be_is_Reload(node)) {
ir_node *spill = get_irn_n(node, be_pos_Reload_mem);
entity* ent = be_get_frame_entity(node);
check_entity(env, node, ent);
collect(env, spill, node, ent);
ARR_APP1(ir_node*, env->reloads, node);
......@@ -424,6 +441,23 @@ static void check_spillslot_interference(be_verify_spillslots_env_t *env) {
}
}
static void check_lonely_spills(ir_node *node, void *data) {
be_verify_spillslots_env_t *env = data;
if(be_is_Spill(node) || (is_Proj(node) && be_is_MemPerm(get_Proj_pred(node)))) {
spill_t *spill = find_spill(env, node);
if(be_is_Spill(node)) {
entity *ent = be_get_frame_entity(node);
check_entity(env, node, ent);
}
if(spill == NULL) {
ir_fprintf(stderr, "Verify warning: Node %+F in block %+F(%s) not connected to a reaload\n",
node, get_nodes_block(node), get_irg_dump_name(env->irg));
}
}
}
int be_verify_spillslots(ir_graph *irg)
{
be_verify_spillslots_env_t env;
......@@ -435,6 +469,7 @@ int be_verify_spillslots(ir_graph *irg)
env.lv = be_liveness(irg);
irg_walk_graph(irg, collect_spills_walker, NULL, &env);
irg_walk_graph(irg, check_lonely_spills, NULL, &env);
check_spillslot_interference(&env);
......
......@@ -70,6 +70,10 @@ void ia32_switch_section(FILE *F, section_t sec) {
case SECTION_RODATA:
case SECTION_COMMON:
fprintf(F, "\t%s\n", text[asm_flavour][sec]);
break;
default:
break;
}
}
......@@ -82,6 +86,8 @@ static void ia32_dump_function_object(FILE *F, const char *name)
case ASM_MINGW_GAS:
fprintf(F, "\t.def\t%s;\t.scl\t2;\t.type\t32;\t.endef\n", name);
break;
default:
break;
}
}
......@@ -91,6 +97,8 @@ static void ia32_dump_function_size(FILE *F, const char *name)
case ASM_LINUX_GAS:
fprintf(F, "\t.size\t%s, .-%s\n", name, name);
break;
default:
break;
}
}
......@@ -1744,6 +1752,11 @@ static void emit_be_Return(const ir_node *n, ia32_emit_env_t *env) {
lc_efprintf(arg_env, F, "\t%-35s %-60s /* %+F (%+G) */\n", "ret", "/* be_Return */", n, n);
}
static void emit_Nothing(const ir_node *n, ia32_emit_env_t *env) {
FILE *F = env->out;
ir_fprintf(F, "\t%35s /* %+F (%+G) */\n", " ", n, n);
}
/***********************************************************************************
......@@ -1765,7 +1778,9 @@ static void ia32_register_emitters(void) {
#define IA32_EMIT2(a,b) op_ia32_##a->ops.generic = (op_func)emit_ia32_##b
#define IA32_EMIT(a) IA32_EMIT2(a,a)
#define EMIT(a) op_##a->ops.generic = (op_func)emit_##a
#define IGN(a) op_##a->ops.generic = (op_func)emit_Nothing
#define BE_EMIT(a) op_be_##a->ops.generic = (op_func)emit_be_##a
#define BE_IGN(a) op_be_##a->ops.generic = (op_func)emit_Nothing
/* first clear the generic function pointer for all ops */
clear_irp_opcodes_generic_func();
......@@ -1811,12 +1826,19 @@ static void ia32_register_emitters(void) {
BE_EMIT(Perm);
BE_EMIT(Return);
BE_IGN(RegParams);
BE_IGN(Barrier);
BE_IGN(Keep);
/* firm emitter */
EMIT(Jmp);
EMIT(Proj);
IGN(Phi);
IGN(Start);
#undef BE_EMIT
#undef EMIT
#undef IGN
#undef IA32_EMIT2
#undef IA32_EMIT
}
......@@ -1826,7 +1848,6 @@ static void ia32_register_emitters(void) {
*/
static void ia32_emit_node(const ir_node *irn, void *env) {
ia32_emit_env_t *emit_env = env;
FILE *F = emit_env->out;
ir_op *op = get_irn_op(irn);
DEBUG_ONLY(firm_dbg_module_t *mod = emit_env->mod;)
......@@ -1837,7 +1858,8 @@ static void ia32_emit_node(const ir_node *irn, void *env) {
(*emit)(irn, env);
}
else {
ir_fprintf(F, "\t%35s /* %+F (%+G) */\n", " ", irn, irn);
emit_Nothing(irn, env);
ir_fprintf(stderr, "Warning: No emit handler for node %+F (%+G)\n", irn, irn);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment