diff options
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99486.patch')
-rw-r--r-- | toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99486.patch | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99486.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99486.patch new file mode 100644 index 0000000000..e6b58ac872 --- /dev/null +++ b/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99486.patch @@ -0,0 +1,230 @@ +2011-03-09 Bernd Schmidt <bernds@codesourcery.com> + + Issue #10649 + gcc/ + * dwarf2out.c (dwarf2out_begin_epilogue): Accept simplejumps + as well as returnjumps. + * cfganal.c (set_edge_can_fallthru_flag): Revert previous change + that tried to keep epilogue blocks adjacent. + +2011-02-03 Bernd Schmidt <bernds@codesourcery.com> + + gcc/ + * function.c (prepare_shrink_wrap): New function. + (thread_prologue_and_epilogue_insns): Call it. + +=== modified file 'gcc/cfganal.c' +--- old/gcc/cfganal.c 2011-02-08 10:51:58 +0000 ++++ new/gcc/cfganal.c 2011-03-10 14:55:10 +0000 +@@ -271,37 +271,6 @@ + EDGE_SUCC (bb, 0)->flags |= EDGE_CAN_FALLTHRU; + EDGE_SUCC (bb, 1)->flags |= EDGE_CAN_FALLTHRU; + } +- /* dwarf2out expects that a NOTE_INSN_EPILOGUE_BEGIN is always paired +- with a return or a sibcall. Ensure that this remains the case if +- they are in different basic blocks. */ +- FOR_EACH_BB (bb) +- { +- edge e; +- edge_iterator ei; +- rtx insn, end; +- +- end = BB_END (bb); +- FOR_BB_INSNS (bb, insn) +- if (GET_CODE (insn) == NOTE +- && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG +- && !(CALL_P (end) && SIBLING_CALL_P (end)) +- && !returnjump_p (end)) +- { +- basic_block other_bb = NULL; +- FOR_EACH_EDGE (e, ei, bb->succs) +- { +- if (e->flags & EDGE_FALLTHRU) +- other_bb = e->dest; +- else +- e->flags &= ~EDGE_CAN_FALLTHRU; +- } +- FOR_EACH_EDGE (e, ei, other_bb->preds) +- { +- if (!(e->flags & EDGE_FALLTHRU)) +- e->flags &= ~EDGE_CAN_FALLTHRU; +- } +- } +- } + } + + /* Find unreachable blocks. An unreachable block will have 0 in + +=== modified file 'gcc/dwarf2out.c' +--- old/gcc/dwarf2out.c 2011-02-08 10:51:58 +0000 ++++ new/gcc/dwarf2out.c 2011-03-10 14:55:10 +0000 +@@ -2782,10 +2782,10 @@ + dwarf2out_frame_debug_expr (insn, label); + } + +-/* Determine if we need to save and restore CFI information around this +- epilogue. If SIBCALL is true, then this is a sibcall epilogue. If +- we do need to save/restore, then emit the save now, and insert a +- NOTE_INSN_CFA_RESTORE_STATE at the appropriate place in the stream. */ ++/* Determine if we need to save and restore CFI information around ++ this epilogue. If we do need to save/restore, then emit the save ++ now, and insert a NOTE_INSN_CFA_RESTORE_STATE at the appropriate ++ place in the stream. */ + + void + dwarf2out_begin_epilogue (rtx insn) +@@ -2800,8 +2800,10 @@ + if (!INSN_P (i)) + continue; + +- /* Look for both regular and sibcalls to end the block. */ +- if (returnjump_p (i)) ++ /* Look for both regular and sibcalls to end the block. Various ++ optimization passes may cause us to jump to a common epilogue ++ tail, so we also accept simplejumps. */ ++ if (returnjump_p (i) || simplejump_p (i)) + break; + if (CALL_P (i) && SIBLING_CALL_P (i)) + break; + +=== modified file 'gcc/function.c' +--- old/gcc/function.c 2011-02-08 10:51:58 +0000 ++++ new/gcc/function.c 2011-03-10 14:55:10 +0000 +@@ -5038,6 +5038,127 @@ + return true; + return false; + } ++ ++/* Look for sets of call-saved registers in the first block of the ++ function, and move them down into successor blocks if the register ++ is used only on one path. This exposes more opportunities for ++ shrink-wrapping. ++ These kinds of sets often occur when incoming argument registers are ++ moved to call-saved registers because their values are live across ++ one or more calls during the function. */ ++ ++static void ++prepare_shrink_wrap (basic_block entry_block) ++{ ++ rtx insn, curr; ++ FOR_BB_INSNS_SAFE (entry_block, insn, curr) ++ { ++ basic_block next_bb; ++ edge e, live_edge; ++ edge_iterator ei; ++ rtx set, scan; ++ unsigned destreg, srcreg; ++ ++ if (!NONDEBUG_INSN_P (insn)) ++ continue; ++ set = single_set (insn); ++ if (!set) ++ continue; ++ ++ if (!REG_P (SET_SRC (set)) || !REG_P (SET_DEST (set))) ++ continue; ++ srcreg = REGNO (SET_SRC (set)); ++ destreg = REGNO (SET_DEST (set)); ++ if (hard_regno_nregs[srcreg][GET_MODE (SET_SRC (set))] > 1 ++ || hard_regno_nregs[destreg][GET_MODE (SET_DEST (set))] > 1) ++ continue; ++ ++ next_bb = entry_block; ++ scan = insn; ++ ++ for (;;) ++ { ++ live_edge = NULL; ++ FOR_EACH_EDGE (e, ei, next_bb->succs) ++ { ++ if (REGNO_REG_SET_P (df_get_live_in (e->dest), destreg)) ++ { ++ if (live_edge) ++ { ++ live_edge = NULL; ++ break; ++ } ++ live_edge = e; ++ } ++ } ++ if (!live_edge) ++ break; ++ /* We can sometimes encounter dead code. Don't try to move it ++ into the exit block. */ ++ if (live_edge->dest == EXIT_BLOCK_PTR) ++ break; ++ if (EDGE_COUNT (live_edge->dest->preds) > 1) ++ break; ++ while (scan != BB_END (next_bb)) ++ { ++ scan = NEXT_INSN (scan); ++ if (NONDEBUG_INSN_P (scan)) ++ { ++ rtx link; ++ HARD_REG_SET set_regs; ++ ++ CLEAR_HARD_REG_SET (set_regs); ++ note_stores (PATTERN (scan), record_hard_reg_sets, ++ &set_regs); ++ if (CALL_P (scan)) ++ IOR_HARD_REG_SET (set_regs, call_used_reg_set); ++ for (link = REG_NOTES (scan); link; link = XEXP (link, 1)) ++ if (REG_NOTE_KIND (link) == REG_INC) ++ record_hard_reg_sets (XEXP (link, 0), NULL, &set_regs); ++ ++ if (TEST_HARD_REG_BIT (set_regs, srcreg) ++ || reg_referenced_p (SET_DEST (set), ++ PATTERN (scan))) ++ { ++ scan = NULL_RTX; ++ break; ++ } ++ if (CALL_P (scan)) ++ { ++ rtx link = CALL_INSN_FUNCTION_USAGE (scan); ++ while (link) ++ { ++ rtx tmp = XEXP (link, 0); ++ if (GET_CODE (tmp) == USE ++ && reg_referenced_p (SET_DEST (set), tmp)) ++ break; ++ link = XEXP (link, 1); ++ } ++ if (link) ++ { ++ scan = NULL_RTX; ++ break; ++ } ++ } ++ } ++ } ++ if (!scan) ++ break; ++ next_bb = live_edge->dest; ++ } ++ ++ if (next_bb != entry_block) ++ { ++ rtx after = BB_HEAD (next_bb); ++ while (!NOTE_P (after) ++ || NOTE_KIND (after) != NOTE_INSN_BASIC_BLOCK) ++ after = NEXT_INSN (after); ++ emit_insn_after (PATTERN (insn), after); ++ delete_insn (insn); ++ } ++ } ++} ++ + #endif + + #ifdef HAVE_return +@@ -5215,6 +5336,8 @@ + bitmap_head bb_antic_flags; + bitmap_head bb_on_list; + ++ prepare_shrink_wrap (entry_edge->dest); ++ + bitmap_initialize (&bb_antic_flags, &bitmap_default_obstack); + bitmap_initialize (&bb_on_list, &bitmap_default_obstack); + + |