return jump;
}
+ return NULL;
+ } else {
+ /* Branching to an outer clause could skip inner clauses */
return NULL;
}
} else {
mono_handle_global_vregs (cfg);
if (cfg->opt & (MONO_OPT_CONSPROP | MONO_OPT_COPYPROP))
mono_local_cprop (cfg);
- mono_local_deadce (cfg);
+ if (cfg->opt & MONO_OPT_DEADCE)
+ mono_local_deadce (cfg);
}
#endif
}
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;
bb->next_bb = bbn->next_bb;
}
mono_nullify_basic_block (bbn);
+
+ /*
+ * If bbn fell through to its next bblock, have to add a branch, since bb
+ * will not fall though to the same bblock (#513931).
+ */
+ if (bb->last_ins && bb->out_count == 1 && bb->out_bb [0] != bb->next_bb && !MONO_IS_BRANCH_OP (bb->last_ins)) {
+ MONO_INST_NEW (cfg, inst, OP_BR);
+ inst->inst_target_bb = bb->out_bb [0];
+ MONO_ADD_INS (bb, inst);
+ }
}
static void
}
if (bb->last_ins && MONO_IS_COND_BRANCH_NOFP (bb->last_ins)) {
- if (bb->last_ins->inst_false_bb && bb->last_ins->inst_false_bb->out_of_line && (bb->region == bb->last_ins->inst_false_bb->region)) {
+ if (bb->last_ins->inst_false_bb && bb->last_ins->inst_false_bb->out_of_line && (bb->region == bb->last_ins->inst_false_bb->region) && !cfg->disable_out_of_line_bblocks) {
/* Reverse the branch */
bb->last_ins->opcode = mono_reverse_branch_op (bb->last_ins->opcode);
bbn = bb->last_ins->inst_false_bb;