+2009-06-13 Zoltan Varga <vargaz@gmail.com>
+
+ * mini.h (struct MonoBasicBlock): Add 'has_jump_table' and
+ 'has_call_handler' fields.
+
+ * method-to-ir.c (mono_method_to_ir): Set them if needed.
+
+ * branch-opts.c (mono_merge_basic_blocks): Avoid iterating through the
+ first bblock if not needed. Fixes #512790.
+
2009-06-11 Zoltan Varga <vargaz@gmail.com>
* aot-compiler.c (mono_compile_assembly): Fix a warning.
mono_unlink_bblock (cfg, bbn, bbn->out_bb [0]);
/* Handle the branch at the end of the bb */
- for (inst = bb->code; inst != NULL; inst = inst->next) {
- if (inst->opcode == OP_CALL_HANDLER) {
- g_assert (inst->inst_target_bb == bbn);
- NULLIFY_INS (inst);
+ if (bb->has_call_handler) {
+ for (inst = bb->code; inst != NULL; inst = inst->next) {
+ if (inst->opcode == OP_CALL_HANDLER) {
+ g_assert (inst->inst_target_bb == bbn);
+ NULLIFY_INS (inst);
+ }
}
- if (MONO_IS_JUMP_TABLE (inst)) {
- int i;
- MonoJumpInfoBBTable *table = MONO_JUMP_TABLE_FROM_INS (inst);
- for (i = 0; i < table->table_size; i++ ) {
- /* Might be already NULL from a previous merge */
- if (table->table [i])
- g_assert (table->table [i] == bbn);
- table->table [i] = NULL;
+ }
+ if (bb->has_jump_table) {
+ for (inst = bb->code; inst != NULL; inst = inst->next) {
+ if (MONO_IS_JUMP_TABLE (inst)) {
+ int i;
+ MonoJumpInfoBBTable *table = MONO_JUMP_TABLE_FROM_INS (inst);
+ for (i = 0; i < table->table_size; i++ ) {
+ /* Might be already NULL from a previous merge */
+ if (table->table [i])
+ g_assert (table->table [i] == bbn);
+ table->table [i] = NULL;
+ }
+ /* Can't nullify this as later instructions depend on it */
}
- /* Can't nullify this as later instructions depend on it */
}
}
if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins)) {
NULLIFY_INS (bb->last_ins);
}
+ bb->has_call_handler |= bbn->has_call_handler;
+ bb->has_jump_table |= bbn->has_jump_table;
+
if (bb->last_ins) {
if (bbn->code) {
bb->last_ins->next = bbn->code;
if (COMPILE_LLVM (cfg))
use_op_switch = TRUE;
+ cfg->cbb->has_jump_table = 1;
+
if (use_op_switch) {
MONO_INST_NEW (cfg, ins, OP_SWITCH);
ins->sreg1 = src1->dreg;
MONO_INST_NEW (cfg, ins, OP_CALL_HANDLER);
ins->inst_target_bb = tblock;
MONO_ADD_INS (bblock, ins);
+ bblock->has_call_handler = 1;
}
g_list_free (handlers);
}
guint has_array_access : 1;
/* Whenever this bblock is extended, ie. it has branches inside it */
guint extended : 1;
+ /* Whenever this bblock contains a OP_JUMP_TABLE instruction */
+ guint has_jump_table : 1;
+ /* Whenever this bblock contains an OP_CALL_HANDLER instruction */
+ guint has_call_handler : 1;
/* use for liveness analysis */
MonoBitSet *gen_set;