diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index c62b5bc..341ea9e 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1572,6 +1572,11 @@ rtl_tidy_fallthru_edge (edge e) if (INSN_P (q)) return; + /* If the two blocks are in different partitions we do not want to mark + this as a fallthru edge. */ + if (BB_PARTITION (b) != BB_PARTITION (c)) + return; + /* Remove what will soon cease being the jump insn from the source block. If block B consisted only of this single jump, turn it into a deleted note. */ diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 2805b7c..21d2213 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -1989,16 +1989,6 @@ arm_option_override (void) else max_insns_skipped = current_tune->max_insns_skipped; - /* Hot/Cold partitioning is not currently supported, since we can't - handle literal pool placement in that case. */ - if (flag_reorder_blocks_and_partition) - { - inform (input_location, - "-freorder-blocks-and-partition not supported on this architecture"); - flag_reorder_blocks_and_partition = 0; - flag_reorder_blocks = 1; - } - if (flag_pic) /* Hoisting PIC address calculations more aggressively provides a small, but measurable, size reduction for PIC code. Therefore, we decrease @@ -13479,9 +13469,19 @@ arm_reorg (void) minipool_pad = 0; /* Scan all the insns and record the operands that will need fixing. */ - for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn)) + for (insn = next_nondebug_insn (insn); insn; insn = next_nondebug_insn (insn)) { - if (GET_CODE (insn) == BARRIER) + if (NOTE_P (insn)) + { + if (NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS) + { + /* Given we can't address a range greater than 4MB go ahead + and increase the address sky high to force all pools before + this note to be dumped. */ + address += 0x400000; + } + } + else if (GET_CODE (insn) == BARRIER) push_minipool_barrier (insn, address); else if (INSN_P (insn)) { diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 8acde0e..9ccc283 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1922,20 +1922,25 @@ enum arm_auto_incmodes || (TARGET_THUMB1 \ && (optimize_size || flag_pic))) +/* TODO: When partitioning we cannot use tbh/tbb or other short forms as the + branches may be in different sections. We could improve this by looking + at the labels in BODY and determining whether we cross HOT/COLD boundaries. */ #define CASE_VECTOR_SHORTEN_MODE(min, max, body) \ - (TARGET_THUMB1 \ - ? (min >= 0 && max < 512 \ - ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 1, QImode) \ - : min >= -256 && max < 256 \ - ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, QImode) \ - : min >= 0 && max < 8192 \ - ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 1, HImode) \ - : min >= -4096 && max < 4096 \ - ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, HImode) \ - : SImode) \ - : ((min < 0 || max >= 0x20000 || !TARGET_THUMB2) ? SImode \ - : (max >= 0x200) ? HImode \ - : QImode)) + (flag_reorder_blocks_and_partition \ + ? SImode \ + : (TARGET_THUMB1 \ + ? (min >= 0 && max < 512 \ + ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 1, QImode) \ + : min >= -256 && max < 256 \ + ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, QImode) \ + : min >= 0 && max < 8192 \ + ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 1, HImode) \ + : min >= -4096 && max < 4096 \ + ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, HImode) \ + : SImode) \ + : ((min < 0 || max >= 0x20000 || !TARGET_THUMB2) ? SImode \ + : (max >= 0x200) ? HImode \ + : QImode))) /* signed 'char' is most compatible, but RISC OS wants it unsigned. unsigned is probably best, but may break some code. */ diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index b9e9f25..300d7df 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -1051,6 +1051,13 @@ eliminate_partially_redundant_load (basic_block bb, rtx insn, /* Adding a load on a critical edge will cause a split. */ if (EDGE_CRITICAL_P (pred)) critical_edge_split = true; + + /* If the destination register is used at the BB end we can not + insert the load. */ + if (reg_used_between_p (dest, PREV_INSN (BB_END (pred_bb)), + next_pred_bb_end)) + goto cleanup; + not_ok_count += pred->count; unoccr = (struct unoccr *) obstack_alloc (&unoccr_obstack, sizeof (struct unoccr));