yann@1393: diff -durN gcc-4.4.0.orig/gcc/Makefile.in gcc-4.4.0/gcc/Makefile.in yann@1393: --- gcc-4.4.0.orig/gcc/Makefile.in 2009-03-25 13:00:32.000000000 +0100 yann@1393: +++ gcc-4.4.0/gcc/Makefile.in 2009-05-27 21:38:50.000000000 +0200 yann@1393: @@ -2785,7 +2785,8 @@ yann@1393: value-prof.h $(TREE_INLINE_H) $(TARGET_H) yann@1393: cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ yann@1393: $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \ yann@1393: - output.h $(TOPLEV_H) $(FUNCTION_H) except.h $(TM_P_H) insn-config.h $(EXPR_H) \ yann@1393: + output.h $(TOPLEV_H) $(FUNCTION_H) except.h $(TM_P_H) $(INSN_ATTR_H) \ yann@1393: + insn-config.h $(EXPR_H) \ yann@1393: $(CFGLAYOUT_H) $(CFGLOOP_H) $(OBSTACK_H) $(TARGET_H) $(TREE_H) \ yann@1393: tree-pass.h $(DF_H) $(GGC_H) yann@1393: cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ yann@1393: diff -durN gcc-4.4.0.orig/gcc/cfgrtl.c gcc-4.4.0/gcc/cfgrtl.c yann@1393: --- gcc-4.4.0.orig/gcc/cfgrtl.c 2008-12-12 22:16:09.000000000 +0100 yann@1393: +++ gcc-4.4.0/gcc/cfgrtl.c 2009-05-27 21:38:50.000000000 +0200 yann@1393: @@ -53,6 +53,7 @@ yann@1393: #include "toplev.h" yann@1393: #include "tm_p.h" yann@1393: #include "obstack.h" yann@1393: +#include "insn-attr.h" yann@1393: #include "insn-config.h" yann@1393: #include "cfglayout.h" yann@1393: #include "expr.h" yann@1393: @@ -427,13 +428,27 @@ yann@1393: return 0; yann@1393: } yann@1393: yann@1393: +static unsigned int yann@1393: +rest_of_pass_free_cfg (void) yann@1393: +{ yann@1393: +#ifdef DELAY_SLOTS yann@1393: + /* The resource.c machinery uses DF but the CFG isn't guaranteed to be yann@1393: + valid at that point so it would be too late to call df_analyze. */ yann@1393: + if (optimize > 0 && flag_delayed_branch) yann@1393: + df_analyze (); yann@1393: +#endif yann@1393: + yann@1393: + free_bb_for_insn (); yann@1393: + return 0; yann@1393: +} yann@1393: + yann@1393: struct rtl_opt_pass pass_free_cfg = yann@1393: { yann@1393: { yann@1393: RTL_PASS, yann@1393: NULL, /* name */ yann@1393: NULL, /* gate */ yann@1393: - free_bb_for_insn, /* execute */ yann@1393: + rest_of_pass_free_cfg, /* execute */ yann@1393: NULL, /* sub */ yann@1393: NULL, /* next */ yann@1393: 0, /* static_pass_number */ yann@1393: diff -durN gcc-4.4.0.orig/gcc/resource.c gcc-4.4.0/gcc/resource.c yann@1393: --- gcc-4.4.0.orig/gcc/resource.c 2009-02-20 16:20:38.000000000 +0100 yann@1393: +++ gcc-4.4.0/gcc/resource.c 2009-05-27 21:38:50.000000000 +0200 yann@1393: @@ -135,8 +135,6 @@ yann@1393: static int yann@1393: find_basic_block (rtx insn, int search_limit) yann@1393: { yann@1393: - basic_block bb; yann@1393: - yann@1393: /* Scan backwards to the previous BARRIER. Then see if we can find a yann@1393: label that starts a basic block. Return the basic block number. */ yann@1393: for (insn = prev_nonnote_insn (insn); yann@1393: @@ -157,11 +155,8 @@ yann@1393: for (insn = next_nonnote_insn (insn); yann@1393: insn && LABEL_P (insn); yann@1393: insn = next_nonnote_insn (insn)) yann@1393: - { yann@1393: - FOR_EACH_BB (bb) yann@1393: - if (insn == BB_HEAD (bb)) yann@1393: - return bb->index; yann@1393: - } yann@1393: + if (BLOCK_FOR_INSN (insn)) yann@1393: + return BLOCK_FOR_INSN (insn)->index; yann@1393: yann@1393: return -1; yann@1393: } yann@1393: @@ -848,13 +843,12 @@ yann@1393: (with no intervening active insns) to see if any of them start a basic yann@1393: block. If we hit the start of the function first, we use block 0. yann@1393: yann@1393: - Once we have found a basic block and a corresponding first insns, we can yann@1393: - accurately compute the live status from basic_block_live_regs and yann@1393: - reg_renumber. (By starting at a label following a BARRIER, we are immune yann@1393: - to actions taken by reload and jump.) Then we scan all insns between yann@1393: - that point and our target. For each CLOBBER (or for call-clobbered regs yann@1393: - when we pass a CALL_INSN), mark the appropriate registers are dead. For yann@1393: - a SET, mark them as live. yann@1393: + Once we have found a basic block and a corresponding first insn, we can yann@1393: + accurately compute the live status (by starting at a label following a yann@1393: + BARRIER, we are immune to actions taken by reload and jump.) Then we yann@1393: + scan all insns between that point and our target. For each CLOBBER (or yann@1393: + for call-clobbered regs when we pass a CALL_INSN), mark the appropriate yann@1393: + registers are dead. For a SET, mark them as live. yann@1393: yann@1393: We have to be careful when using REG_DEAD notes because they are not yann@1393: updated by such things as find_equiv_reg. So keep track of registers yann@1393: @@ -954,13 +948,10 @@ yann@1393: TARGET. Otherwise, we must assume everything is live. */ yann@1393: if (b != -1) yann@1393: { yann@1393: - regset regs_live = DF_LR_IN (BASIC_BLOCK (b)); yann@1393: + regset regs_live = df_get_live_in (BASIC_BLOCK (b)); yann@1393: rtx start_insn, stop_insn; yann@1393: yann@1393: - /* Compute hard regs live at start of block -- this is the real hard regs yann@1393: - marked live, plus live pseudo regs that have been renumbered to yann@1393: - hard regs. */ yann@1393: - yann@1393: + /* Compute hard regs live at start of block. */ yann@1393: REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live); yann@1393: yann@1393: /* Get starting and ending insn, handling the case where each might yann@1393: @@ -1046,10 +1037,24 @@ yann@1393: yann@1393: else if (LABEL_P (real_insn)) yann@1393: { yann@1393: + basic_block bb; yann@1393: + yann@1393: /* A label clobbers the pending dead registers since neither yann@1393: reload nor jump will propagate a value across a label. */ yann@1393: AND_COMPL_HARD_REG_SET (current_live_regs, pending_dead_regs); yann@1393: CLEAR_HARD_REG_SET (pending_dead_regs); yann@1393: + yann@1393: + /* We must conservatively assume that all registers that used yann@1393: + to be live here still are. The fallthrough edge may have yann@1393: + left a live register uninitialized. */ yann@1393: + bb = BLOCK_FOR_INSN (real_insn); yann@1393: + if (bb) yann@1393: + { yann@1393: + HARD_REG_SET extra_live; yann@1393: + yann@1393: + REG_SET_TO_HARD_REG_SET (extra_live, df_get_live_in (bb)); yann@1393: + IOR_HARD_REG_SET (current_live_regs, extra_live); yann@1393: + } yann@1393: } yann@1393: yann@1393: /* The beginning of the epilogue corresponds to the end of the yann@1393: @@ -1121,6 +1126,7 @@ yann@1393: init_resource_info (rtx epilogue_insn) yann@1393: { yann@1393: int i; yann@1393: + basic_block bb; yann@1393: yann@1393: /* Indicate what resources are required to be valid at the end of the current yann@1393: function. The condition code never is and memory always is. If the yann@1393: @@ -1189,6 +1195,11 @@ yann@1393: /* Allocate and initialize the tables used by mark_target_live_regs. */ yann@1393: target_hash_table = XCNEWVEC (struct target_info *, TARGET_HASH_PRIME); yann@1393: bb_ticks = XCNEWVEC (int, last_basic_block); yann@1393: + yann@1393: + /* Set the BLOCK_FOR_INSN of each label that starts a basic block. */ yann@1393: + FOR_EACH_BB (bb) yann@1393: + if (LABEL_P (BB_HEAD (bb))) yann@1393: + BLOCK_FOR_INSN (BB_HEAD (bb)) = bb; yann@1393: } yann@1393: yann@1393: /* Free up the resources allocated to mark_target_live_regs (). This yann@1393: @@ -1197,6 +1208,8 @@ yann@1393: void yann@1393: free_resource_info (void) yann@1393: { yann@1393: + basic_block bb; yann@1393: + yann@1393: if (target_hash_table != NULL) yann@1393: { yann@1393: int i; yann@1393: @@ -1222,6 +1235,10 @@ yann@1393: free (bb_ticks); yann@1393: bb_ticks = NULL; yann@1393: } yann@1393: + yann@1393: + FOR_EACH_BB (bb) yann@1393: + if (LABEL_P (BB_HEAD (bb))) yann@1393: + BLOCK_FOR_INSN (BB_HEAD (bb)) = NULL; yann@1393: } yann@1393: yann@1393: /* Clear any hashed information that we have stored for INSN. */