From f3a89dbfed24dfe2bf9a0f35dca3aac253299e06 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sun, 21 Feb 2010 23:03:20 +0000 Subject: [PATCH] 4.4.3-7 --- .cvsignore | 2 +- gcc.spec | 28 +- gcc44-max-vartrack-size.patch | 229 ------- gcc44-pr42233.patch | 973 +++++++++++++++++++++++++++++ gcc44-pr43051.patch | 331 ++++++++++ gcc44-sparc-config-detection.patch | 4 +- import.log | 1 + sources | 2 +- 8 files changed, 1329 insertions(+), 241 deletions(-) delete mode 100644 gcc44-max-vartrack-size.patch create mode 100644 gcc44-pr42233.patch create mode 100644 gcc44-pr43051.patch diff --git a/.cvsignore b/.cvsignore index 4e1ffc9..a36c3e4 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,2 +1,2 @@ fastjar-0.97.tar.gz -gcc-4.4.3-20100211.tar.bz2 +gcc-4.4.3-20100221.tar.bz2 diff --git a/gcc.spec b/gcc.spec index 864f8f1..8849bd6 100644 --- a/gcc.spec +++ b/gcc.spec @@ -1,9 +1,9 @@ -%global DATE 20100211 -%global SVNREV 156726 +%global DATE 20100221 +%global SVNREV 156936 %global gcc_version 4.4.3 # Note, gcc_release must be integer, if you want to add suffixes to # %{release}, append them after %{gcc_release} on Release: line. -%global gcc_release 6 +%global gcc_release 7 %global _unpackaged_files_terminate_build 0 %global multilib_64_archs sparc64 ppc64 s390x x86_64 %if 0%{?fedora} >= 13 @@ -175,8 +175,9 @@ Patch16: gcc44-unwind-debug-hook.patch Patch17: gcc44-pr38757.patch Patch18: gcc44-libstdc++-docs.patch Patch19: gcc44-ppc64-aixdesc.patch -Patch20: gcc44-max-vartrack-size.patch -Patch21: gcc44-no-add-needed.patch +Patch20: gcc44-no-add-needed.patch +Patch21: gcc44-pr42233.patch +Patch22: gcc44-pr43051.patch Patch1000: fastjar-0.97-segfault.patch Patch1001: fastjar-0.97-len1.patch @@ -485,10 +486,11 @@ which are required to compile with the GNAT. %patch18 -p0 -b .libstdc++-docs~ %endif %patch19 -p0 -b .ppc64-aixdesc~ -%patch20 -p0 -b .max-vartrack-size~ %if 0%{?fedora} >= 13 -%patch21 -p0 -b .no-add-needed~ +%patch20 -p0 -b .no-add-needed~ %endif +%patch21 -p0 -b .pr42233~ +#%patch22 -p0 -b .pr43051~ # This testcase doesn't compile. rm libjava/testsuite/libjava.lang/PR35020* @@ -686,7 +688,7 @@ CC="$CC" CFLAGS="$OPT_FLAGS" CXXFLAGS="`echo $OPT_FLAGS | sed 's/ -Wall / /g'`" --with-arch_32=i686 \ %endif %ifarch s390 s390x - --with-arch=z9-109 --with-tune=z10 \ + --with-arch=z9-109 --with-tune=z10 --enable-decimal-float \ %endif %ifnarch sparc sparcv9 ppc --build=%{gcc_target_platform} @@ -1878,6 +1880,16 @@ fi %doc rpm.doc/changelogs/libmudflap/ChangeLog* %changelog +* Sun Feb 21 2010 Jakub Jelinek 4.4.3-7 +- update from gcc-4_4-branch + - PRs c++/43024, c++/43033, fortran/41869, target/40887, + tree-optimization/42871, tree-optimization/43074 +- VTA backports (PRs debug/42918, debug/43084) +- --enable-decimal-float on s390{,x} (#565871) +- improve __builtin_expect handling, propagate branch probabilities + during expansion even for sequences with more than one jump + (PR middle-end/42233) + * Thu Feb 11 2010 Jakub Jelinek 4.4.3-6 - update from gcc-4_4-branch - PR tree-optimization/42705 diff --git a/gcc44-max-vartrack-size.patch b/gcc44-max-vartrack-size.patch deleted file mode 100644 index 70bcd75..0000000 --- a/gcc44-max-vartrack-size.patch +++ /dev/null @@ -1,229 +0,0 @@ -2010-01-05 Alexandre Oliva - - * params.def (PARAM_MAX_VARTRACK_SIZE): New. - * doc/invoke.texi: Document it. - * var-tracking.c: Include toplev.h and params.h. - (vt_find_locations): Return bool indicating success. Compute - hash sizes unconditionally. Check new parameter, report. - (variable_tracking_main_1): Check vt_find_locations results and - retry. Renamed from... - (variable_tracking_main): ... this. New wrapper to preserve - flag_var_tracking_assignments. - * Makefile.in (var-tracking.o): Adjust dependencies. - ---- gcc/doc/invoke.texi.jj 2010-01-09 20:39:58.000000000 +0100 -+++ gcc/doc/invoke.texi 2010-01-21 10:00:15.979730377 +0100 -@@ -7937,6 +7937,15 @@ with more basic blocks than this paramet - motion optimization performed on them. The default value of the - parameter is 1000 for -O1 and 10000 for -O2 and above. - -+@item max-vartrack-size -+Sets a maximum number of hash table slots to use during variable -+tracking dataflow analysis of any function. If this limit is exceeded -+with variable tracking at assignments enabled, analysis for that -+function is retried without it, after removing all debug insns from -+the function. If the limit is exceeded even without debug insns, var -+tracking analysis is completely disabled for the function. Setting -+the parameter to zero makes it unlimited. -+ - @item min-nondebug-insn-uid - Use uids starting at this parameter for nondebug insns. The range below - the parameter is reserved exclusively for debug insns created by ---- gcc/params.def.jj 2010-01-09 20:39:58.000000000 +0100 -+++ gcc/params.def 2010-01-21 10:00:15.980730943 +0100 -@@ -771,6 +771,13 @@ DEFPARAM (PARAM_LOOP_INVARIANT_MAX_BBS_I - "max basic blocks number in loop for loop invariant motion", - 10000, 0, 0) - -+/* Set maximum hash table size for var tracking. */ -+ -+DEFPARAM (PARAM_MAX_VARTRACK_SIZE, -+ "max-vartrack-size", -+ "Max. size of var tracking hash tables", -+ 50000000, 0, 0) -+ - /* Set minimum insn uid for non-debug insns. */ - - DEFPARAM (PARAM_MIN_NONDEBUG_INSN_UID, ---- gcc/var-tracking.c.jj 2010-01-21 09:10:37.000000000 +0100 -+++ gcc/var-tracking.c 2010-01-21 10:00:15.983740989 +0100 -@@ -109,6 +109,8 @@ - #include "tree-flow.h" - #include "cselib.h" - #include "target.h" -+#include "toplev.h" -+#include "params.h" - - /* var-tracking.c assumes that tree code with the same value as VALUE rtx code - has no chance to appear in REG_EXPR/MEM_EXPRs and isn't a decl. -@@ -451,7 +453,7 @@ static int add_uses (rtx *, void *); - static void add_uses_1 (rtx *, void *); - static void add_stores (rtx, const_rtx, void *); - static bool compute_bb_dataflow (basic_block); --static void vt_find_locations (void); -+static bool vt_find_locations (void); - - static void dump_attrs_list (attrs); - static int dump_var_slot (void **, void *); -@@ -5511,7 +5513,7 @@ compute_bb_dataflow (basic_block bb) - - /* Find the locations of variables in the whole function. */ - --static void -+static bool - vt_find_locations (void) - { - fibheap_t worklist, pending, fibheap_swap; -@@ -5522,6 +5524,8 @@ vt_find_locations (void) - int *rc_order; - int i; - int htabsz = 0; -+ int htabmax = PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE); -+ bool success = true; - - /* Compute reverse completion order of depth first search of the CFG - so that the data-flow runs faster. */ -@@ -5543,7 +5547,7 @@ vt_find_locations (void) - fibheap_insert (pending, bb_order[bb->index], bb); - sbitmap_ones (in_pending); - -- while (!fibheap_empty (pending)) -+ while (success && !fibheap_empty (pending)) - { - fibheap_swap = pending; - pending = worklist; -@@ -5566,11 +5570,11 @@ vt_find_locations (void) - - SET_BIT (visited, bb->index); - -- if (dump_file && VTI (bb)->in.vars) -+ if (VTI (bb)->in.vars) - { - htabsz -- -= htab_size (shared_hash_htab (VTI (bb)->in.vars)) -- + htab_size (shared_hash_htab (VTI (bb)->out.vars)); -+ -= (htab_size (shared_hash_htab (VTI (bb)->in.vars)) -+ + htab_size (shared_hash_htab (VTI (bb)->out.vars))); - oldinsz - = htab_elements (shared_hash_htab (VTI (bb)->in.vars)); - oldoutsz -@@ -5634,9 +5638,20 @@ vt_find_locations (void) - } - - changed = compute_bb_dataflow (bb); -- if (dump_file) -- htabsz += htab_size (shared_hash_htab (VTI (bb)->in.vars)) -- + htab_size (shared_hash_htab (VTI (bb)->out.vars)); -+ htabsz += (htab_size (shared_hash_htab (VTI (bb)->in.vars)) -+ + htab_size (shared_hash_htab (VTI (bb)->out.vars))); -+ -+ if (htabmax && htabsz > htabmax) -+ { -+ if (MAY_HAVE_DEBUG_INSNS) -+ inform (DECL_SOURCE_LOCATION (cfun->decl), -+ "variable tracking size limit exceeded with debug insns, retrying without"); -+ else -+ inform (DECL_SOURCE_LOCATION (cfun->decl), -+ "variable tracking size limit exceeded"); -+ success = false; -+ break; -+ } - - if (changed) - { -@@ -5687,7 +5702,7 @@ vt_find_locations (void) - } - } - -- if (MAY_HAVE_DEBUG_INSNS) -+ if (success && MAY_HAVE_DEBUG_INSNS) - FOR_EACH_BB (bb) - gcc_assert (VTI (bb)->flooded); - -@@ -5698,6 +5713,8 @@ vt_find_locations (void) - sbitmap_free (visited); - sbitmap_free (in_worklist); - sbitmap_free (in_pending); -+ -+ return success; - } - - /* Print the content of the LIST to dump file. */ -@@ -7600,9 +7617,11 @@ vt_finalize (void) - - /* The entry point to variable tracking pass. */ - --unsigned int --variable_tracking_main (void) -+static inline unsigned int -+variable_tracking_main_1 (void) - { -+ bool success; -+ - if (flag_var_tracking_assignments < 0) - { - delete_debug_insns (); -@@ -7627,7 +7646,31 @@ variable_tracking_main (void) - } - } - -- vt_find_locations (); -+ success = vt_find_locations (); -+ -+ if (!success && flag_var_tracking_assignments > 0) -+ { -+ vt_finalize (); -+ -+ delete_debug_insns (); -+ -+ /* This is later restored by our caller. */ -+ flag_var_tracking_assignments = 0; -+ -+ vt_initialize (); -+ -+ if (!frame_pointer_needed && !vt_stack_adjustments ()) -+ gcc_unreachable (); -+ -+ success = vt_find_locations (); -+ } -+ -+ if (!success) -+ { -+ vt_finalize (); -+ vt_debug_insns_local (false); -+ return 0; -+ } - - if (dump_file && (dump_flags & TDF_DETAILS)) - { -@@ -7641,6 +7684,19 @@ variable_tracking_main (void) - vt_debug_insns_local (false); - return 0; - } -+ -+unsigned int -+variable_tracking_main (void) -+{ -+ unsigned int ret; -+ int save = flag_var_tracking_assignments; -+ -+ ret = variable_tracking_main_1 (); -+ -+ flag_var_tracking_assignments = save; -+ -+ return ret; -+} - - static bool - gate_handle_var_tracking (void) ---- gcc/Makefile.in.jj 2010-01-21 08:58:12.000000000 +0100 -+++ gcc/Makefile.in 2010-01-21 10:00:45.555730868 +0100 -@@ -2751,7 +2751,7 @@ var-tracking.o : var-tracking.c $(CONFIG - $(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \ - $(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \ - $(REGS_H) $(EXPR_H) $(TIMEVAR_H) tree-pass.h cselib.h $(TARGET_H) \ -- $(TREE_FLOW_H) -+ $(TREE_FLOW_H) $(TOPLEV_H) $(PARAMS_H) - profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ - $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) $(FUNCTION_H) \ - $(TOPLEV_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \ diff --git a/gcc44-pr42233.patch b/gcc44-pr42233.patch new file mode 100644 index 0000000..0be6d6f --- /dev/null +++ b/gcc44-pr42233.patch @@ -0,0 +1,973 @@ +2010-02-19 Jakub Jelinek + + PR middle-end/42233 + * dojump.c (do_jump) : Invert priority. + + PR bootstrap/43121 + * except.c (sjlj_emit_function_enter): Don't call + add_reg_br_prob_note, instead add REG_BR_PROB note to the last insn + directly. + * rtl.h (add_reg_br_prob_note): Remove prototype. + + PR middle-end/42233 + * loop-doloop.c (add_test): Adjust do_compare_rtx_and_jump caller. + + PR middle-end/42233 + * expr.h (jumpifnot, jumpifnot_1, jumpif, jumpif_1, do_jump, + do_jump_1, do_compare_rtx_and_jump): Add PROB argument. + * dojump.c: Include output.h. + (inv): New inline function. + (jumpifnot, jumpifnot_1, jumpif, jumpif_1, do_jump_1, do_jump, + do_jump_by_parts_greater_rtx, do_jump_by_parts_greater, + do_jump_by_parts_zero_rtx, do_jump_by_parts_equality_rtx, + do_jump_by_parts_equality, do_compare_and_jump): Add PROB + argument, pass it down to other calls. + (do_compare_rtx_and_jump): Likewise. If PROB is not -1, + add REG_BR_PROB note to the conditional jump. + * cfgexpand.c (add_reg_br_prob_note): Removed. + (expand_gimple_cond): Don't call it, add the probability + as last argument to jumpif_1/jumpifnot_1. + * Makefile.in (dojump.o): Depend on output.h. + * builtins.c (expand_errno_check): Adjust do_compare_rtx_and_jump + callers. + * expmed.c (emit_store_flag_force, do_cmp_and_jump): Likewise. + * stmt.c (do_jump_if_equal): Likewise. + * cfgrtl.c (rtl_lv_add_condition_to_bb): Likewise. + * loop-unswitch.c (compare_and_jump_seq): Likewise. + * config/rs6000/rs6000.c (rs6000_aix_emit_builtin_unwind_init): + Likewise. + * optabs.c (expand_doubleword_shift, expand_abs): Likewise. + * expr.c (expand_expr_real_1): Adjust do_jump, jumpifnot and + jumpifnot_1 callers. + (expand_expr_real_2): Adjust jumpifnot_1 and do_compare_rtx_and_jump + callers. + (store_expr): Adjust jumpifnot caller. + (store_constructor): Adjust jumpif caller. + + PR middle-end/42233 + * gimplify.c (gimple_boolify): For __builtin_expect call + gimple_boolify also on its first argument. + +--- gcc/expmed.c.jj 2009-12-31 11:53:14.000000000 +0100 ++++ gcc/expmed.c 2010-02-19 18:27:13.000000000 +0100 +@@ -5608,7 +5608,7 @@ emit_store_flag_force (rtx target, enum + emit_move_insn (target, const1_rtx); + label = gen_label_rtx (); + do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, NULL_RTX, +- NULL_RTX, label); ++ NULL_RTX, label, -1); + + emit_move_insn (target, const0_rtx); + emit_label (label); +@@ -5626,5 +5626,5 @@ do_cmp_and_jump (rtx arg1, rtx arg2, enu + { + int unsignedp = (op == LTU || op == LEU || op == GTU || op == GEU); + do_compare_rtx_and_jump (arg1, arg2, op, unsignedp, mode, +- NULL_RTX, NULL_RTX, label); ++ NULL_RTX, NULL_RTX, label, -1); + } +--- gcc/loop-unswitch.c.jj 2009-04-24 21:41:23.000000000 +0200 ++++ gcc/loop-unswitch.c 2010-02-19 18:27:10.000000000 +0100 +@@ -121,7 +121,7 @@ compare_and_jump_seq (rtx op0, rtx op1, + op0 = force_operand (op0, NULL_RTX); + op1 = force_operand (op1, NULL_RTX); + do_compare_rtx_and_jump (op0, op1, comp, 0, +- mode, NULL_RTX, NULL_RTX, label); ++ mode, NULL_RTX, NULL_RTX, label, -1); + jump = get_last_insn (); + JUMP_LABEL (jump) = label; + LABEL_NUSES (label)++; +--- gcc/dojump.c.jj 2009-06-03 16:08:37.000000000 +0200 ++++ gcc/dojump.c 2010-02-19 18:53:16.000000000 +0100 +@@ -35,12 +35,21 @@ along with GCC; see the file COPYING3. + #include "langhooks.h" + #include "ggc.h" + #include "basic-block.h" ++#include "output.h" + + static bool prefer_and_bit_test (enum machine_mode, int); +-static void do_jump_by_parts_greater (tree, int, rtx, rtx); +-static void do_jump_by_parts_equality (tree, rtx, rtx); ++static void do_jump_by_parts_greater (tree, int, rtx, rtx, int); ++static void do_jump_by_parts_equality (tree, rtx, rtx, int); + static void do_compare_and_jump (tree, enum rtx_code, enum rtx_code, rtx, +- rtx); ++ rtx, int); ++ ++/* Invert probability if there is any. -1 stands for unknown. */ ++ ++static inline int ++inv (int prob) ++{ ++ return prob == -1 ? -1 : REG_BR_PROB_BASE - prob; ++} + + /* At the start of a function, record that we have no previously-pushed + arguments waiting to be popped. */ +@@ -96,17 +105,17 @@ do_pending_stack_adjust (void) + functions here. */ + + void +-jumpifnot (tree exp, rtx label) ++jumpifnot (tree exp, rtx label, int prob) + { +- do_jump (exp, label, NULL_RTX); ++ do_jump (exp, label, NULL_RTX, inv (prob)); + } + + /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */ + + void +-jumpif (tree exp, rtx label) ++jumpif (tree exp, rtx label, int prob) + { +- do_jump (exp, NULL_RTX, label); ++ do_jump (exp, NULL_RTX, label, prob); + } + + /* Used internally by prefer_and_bit_test. */ +@@ -156,10 +165,12 @@ prefer_and_bit_test (enum machine_mode m + + do_jump always does any pending stack adjust except when it does not + actually perform a jump. An example where there is no jump +- is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null. */ ++ is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null. ++ ++ PROB is probability of jump to if_true_label, or -1 if unknown. */ + + void +-do_jump (tree exp, rtx if_false_label, rtx if_true_label) ++do_jump (tree exp, rtx if_false_label, rtx if_true_label, int prob) + { + enum tree_code code = TREE_CODE (exp); + rtx temp; +@@ -206,11 +217,12 @@ do_jump (tree exp, rtx if_false_label, r + case LROTATE_EXPR: + case RROTATE_EXPR: + /* These cannot change zero->nonzero or vice versa. */ +- do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label); ++ do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob); + break; + + case TRUTH_NOT_EXPR: +- do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label); ++ do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label, ++ inv (prob)); + break; + + case COND_EXPR: +@@ -226,10 +238,10 @@ do_jump (tree exp, rtx if_false_label, r + } + + do_pending_stack_adjust (); +- do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX); +- do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label); ++ do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX, -1); ++ do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob); + emit_label (label1); +- do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label); ++ do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob); + break; + } + +@@ -261,7 +273,8 @@ do_jump (tree exp, rtx if_false_label, r + && (optab_handler (cmp_optab, TYPE_MODE (type))->insn_code + != CODE_FOR_nothing)) + { +- do_jump (fold_convert (type, exp), if_false_label, if_true_label); ++ do_jump (fold_convert (type, exp), if_false_label, if_true_label, ++ prob); + break; + } + goto normal; +@@ -277,12 +290,14 @@ do_jump (tree exp, rtx if_false_label, r + != MODE_COMPLEX_INT); + + if (integer_zerop (TREE_OPERAND (exp, 1))) +- do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label); ++ do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label, ++ inv (prob)); + else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT + && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump)) +- do_jump_by_parts_equality (exp, if_false_label, if_true_label); ++ do_jump_by_parts_equality (exp, if_false_label, if_true_label, prob); + else +- do_compare_and_jump (exp, EQ, EQ, if_false_label, if_true_label); ++ do_compare_and_jump (exp, EQ, EQ, if_false_label, if_true_label, ++ prob); + break; + } + +@@ -302,12 +317,14 @@ do_jump (tree exp, rtx if_false_label, r + != MODE_COMPLEX_INT); + + if (integer_zerop (TREE_OPERAND (exp, 1))) +- do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label); ++ do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob); + else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT + && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump)) +- do_jump_by_parts_equality (exp, if_true_label, if_false_label); ++ do_jump_by_parts_equality (exp, if_true_label, if_false_label, ++ inv (prob)); + else +- do_compare_and_jump (exp, NE, NE, if_false_label, if_true_label); ++ do_compare_and_jump (exp, NE, NE, if_false_label, if_true_label, ++ prob); + break; + } + +@@ -315,36 +332,43 @@ do_jump (tree exp, rtx if_false_label, r + mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))); + if (GET_MODE_CLASS (mode) == MODE_INT + && ! can_compare_p (LT, mode, ccp_jump)) +- do_jump_by_parts_greater (exp, 1, if_false_label, if_true_label); ++ do_jump_by_parts_greater (exp, 1, if_false_label, if_true_label, prob); + else +- do_compare_and_jump (exp, LT, LTU, if_false_label, if_true_label); ++ do_compare_and_jump (exp, LT, LTU, if_false_label, if_true_label, ++ prob); + break; + + case LE_EXPR: + mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))); + if (GET_MODE_CLASS (mode) == MODE_INT + && ! can_compare_p (LE, mode, ccp_jump)) +- do_jump_by_parts_greater (exp, 0, if_true_label, if_false_label); ++ do_jump_by_parts_greater (exp, 0, if_true_label, if_false_label, ++ inv (prob)); + else +- do_compare_and_jump (exp, LE, LEU, if_false_label, if_true_label); ++ do_compare_and_jump (exp, LE, LEU, if_false_label, if_true_label, ++ prob); + break; + + case GT_EXPR: + mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))); + if (GET_MODE_CLASS (mode) == MODE_INT + && ! can_compare_p (GT, mode, ccp_jump)) +- do_jump_by_parts_greater (exp, 0, if_false_label, if_true_label); ++ do_jump_by_parts_greater (exp, 0, if_false_label, if_true_label, ++ prob); + else +- do_compare_and_jump (exp, GT, GTU, if_false_label, if_true_label); ++ do_compare_and_jump (exp, GT, GTU, if_false_label, if_true_label, ++ prob); + break; + + case GE_EXPR: + mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))); + if (GET_MODE_CLASS (mode) == MODE_INT + && ! can_compare_p (GE, mode, ccp_jump)) +- do_jump_by_parts_greater (exp, 1, if_true_label, if_false_label); ++ do_jump_by_parts_greater (exp, 1, if_true_label, if_false_label, ++ inv (prob)); + else +- do_compare_and_jump (exp, GE, GEU, if_false_label, if_true_label); ++ do_compare_and_jump (exp, GE, GEU, if_false_label, if_true_label, ++ prob); + break; + + case UNORDERED_EXPR: +@@ -368,9 +392,10 @@ do_jump (tree exp, rtx if_false_label, r + do_rev = 1; + + if (! do_rev) +- do_compare_and_jump (exp, cmp, cmp, if_false_label, if_true_label); ++ do_compare_and_jump (exp, cmp, cmp, if_false_label, if_true_label, prob); + else +- do_compare_and_jump (exp, rcmp, rcmp, if_true_label, if_false_label); ++ do_compare_and_jump (exp, rcmp, rcmp, if_true_label, if_false_label, ++ inv (prob)); + } + break; + +@@ -415,7 +440,7 @@ do_jump (tree exp, rtx if_false_label, r + mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))); + if (can_compare_p (rcode1, mode, ccp_jump)) + do_compare_and_jump (exp, rcode1, rcode1, if_false_label, +- if_true_label); ++ if_true_label, prob); + else + { + tree op0 = save_expr (TREE_OPERAND (exp, 0)); +@@ -429,8 +454,8 @@ do_jump (tree exp, rtx if_false_label, r + + cmp0 = fold_build2 (tcode1, TREE_TYPE (exp), op0, op1); + cmp1 = fold_build2 (tcode2, TREE_TYPE (exp), op0, op1); +- do_jump (cmp0, 0, if_true_label); +- do_jump (cmp1, if_false_label, if_true_label); ++ do_jump (cmp0, 0, if_true_label, prob); ++ do_jump (cmp1, if_false_label, if_true_label, prob); + } + break; + } +@@ -443,6 +468,7 @@ do_jump (tree exp, rtx if_false_label, r + { + tree exp0 = TREE_OPERAND (exp, 0); + rtx set_label, clr_label; ++ int setclr_prob = prob; + + /* Strip narrowing integral type conversions. */ + while (CONVERT_EXPR_P (exp0) +@@ -458,6 +484,7 @@ do_jump (tree exp, rtx if_false_label, r + exp0 = TREE_OPERAND (exp0, 0); + clr_label = if_true_label; + set_label = if_false_label; ++ setclr_prob = inv (prob); + } + else + { +@@ -480,7 +507,7 @@ do_jump (tree exp, rtx if_false_label, r + = (unsigned HOST_WIDE_INT) 1 << TREE_INT_CST_LOW (shift); + do_jump (build2 (BIT_AND_EXPR, argtype, arg, + build_int_cst_wide_type (argtype, mask, 0)), +- clr_label, set_label); ++ clr_label, set_label, setclr_prob); + break; + } + } +@@ -503,7 +530,8 @@ do_jump (tree exp, rtx if_false_label, r + && (optab_handler (cmp_optab, TYPE_MODE (type))->insn_code + != CODE_FOR_nothing)) + { +- do_jump (fold_convert (type, exp), if_false_label, if_true_label); ++ do_jump (fold_convert (type, exp), if_false_label, if_true_label, ++ prob); + break; + } + +@@ -526,13 +554,13 @@ do_jump (tree exp, rtx if_false_label, r + if (if_false_label == NULL_RTX) + { + drop_through_label = gen_label_rtx (); +- do_jump (TREE_OPERAND (exp, 0), drop_through_label, NULL_RTX); +- do_jump (TREE_OPERAND (exp, 1), NULL_RTX, if_true_label); ++ do_jump (TREE_OPERAND (exp, 0), drop_through_label, NULL_RTX, prob); ++ do_jump (TREE_OPERAND (exp, 1), NULL_RTX, if_true_label, prob); + } + else + { +- do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX); +- do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label); ++ do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX, prob); ++ do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob); + } + break; + +@@ -541,7 +569,7 @@ do_jump (tree exp, rtx if_false_label, r + /* High branch cost, expand as the bitwise OR of the conditions. + Do the same if the RHS has side effects, because we're effectively + turning a TRUTH_OR_EXPR into a TRUTH_ORIF_EXPR. */ +- if (BRANCH_COST (optimize_insn_for_speed_p (), false)>= 4 ++ if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4 + || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1))) + goto normal; + +@@ -549,13 +577,13 @@ do_jump (tree exp, rtx if_false_label, r + if (if_true_label == NULL_RTX) + { + drop_through_label = gen_label_rtx (); +- do_jump (TREE_OPERAND (exp, 0), NULL_RTX, drop_through_label); +- do_jump (TREE_OPERAND (exp, 1), if_false_label, NULL_RTX); ++ do_jump (TREE_OPERAND (exp, 0), NULL_RTX, drop_through_label, prob); ++ do_jump (TREE_OPERAND (exp, 1), if_false_label, NULL_RTX, prob); + } + else + { +- do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label); +- do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label); ++ do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label, prob); ++ do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob); + } + break; + +@@ -577,7 +605,7 @@ do_jump (tree exp, rtx if_false_label, r + do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)), + NE, TYPE_UNSIGNED (TREE_TYPE (exp)), + GET_MODE (temp), NULL_RTX, +- if_false_label, if_true_label); ++ if_false_label, if_true_label, prob); + } + + if (drop_through_label) +@@ -593,7 +621,8 @@ do_jump (tree exp, rtx if_false_label, r + + static void + do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0, +- rtx op1, rtx if_false_label, rtx if_true_label) ++ rtx op1, rtx if_false_label, rtx if_true_label, ++ int prob) + { + int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD); + rtx drop_through_label = 0; +@@ -625,11 +654,12 @@ do_jump_by_parts_greater_rtx (enum machi + /* All but high-order word must be compared as unsigned. */ + do_compare_rtx_and_jump (op0_word, op1_word, GT, + (unsignedp || i > 0), word_mode, NULL_RTX, +- NULL_RTX, if_true_label); ++ NULL_RTX, if_true_label, prob); + + /* Consider lower words only if these are equal. */ + do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode, +- NULL_RTX, NULL_RTX, if_false_label); ++ NULL_RTX, NULL_RTX, if_false_label, ++ inv (prob)); + } + + if (if_false_label) +@@ -645,7 +675,7 @@ do_jump_by_parts_greater_rtx (enum machi + + static void + do_jump_by_parts_greater (tree exp, int swap, rtx if_false_label, +- rtx if_true_label) ++ rtx if_true_label, int prob) + { + rtx op0 = expand_normal (TREE_OPERAND (exp, swap)); + rtx op1 = expand_normal (TREE_OPERAND (exp, !swap)); +@@ -653,7 +683,7 @@ do_jump_by_parts_greater (tree exp, int + int unsignedp = TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))); + + do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, +- if_true_label); ++ if_true_label, prob); + } + + /* Jump according to whether OP0 is 0. We assume that OP0 has an integer +@@ -663,7 +693,7 @@ do_jump_by_parts_greater (tree exp, int + + static void + do_jump_by_parts_zero_rtx (enum machine_mode mode, rtx op0, +- rtx if_false_label, rtx if_true_label) ++ rtx if_false_label, rtx if_true_label, int prob) + { + int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD; + rtx part; +@@ -685,8 +715,7 @@ do_jump_by_parts_zero_rtx (enum machine_ + if (part != 0) + { + do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode, +- NULL_RTX, if_false_label, if_true_label); +- ++ NULL_RTX, if_false_label, if_true_label, prob); + return; + } + +@@ -697,7 +726,7 @@ do_jump_by_parts_zero_rtx (enum machine_ + for (i = 0; i < nwords; i++) + do_compare_rtx_and_jump (operand_subword_force (op0, i, mode), + const0_rtx, EQ, 1, word_mode, NULL_RTX, +- if_false_label, NULL_RTX); ++ if_false_label, NULL_RTX, prob); + + if (if_true_label) + emit_jump (if_true_label); +@@ -713,7 +742,7 @@ do_jump_by_parts_zero_rtx (enum machine_ + + static void + do_jump_by_parts_equality_rtx (enum machine_mode mode, rtx op0, rtx op1, +- rtx if_false_label, rtx if_true_label) ++ rtx if_false_label, rtx if_true_label, int prob) + { + int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD); + rtx drop_through_label = 0; +@@ -721,12 +750,14 @@ do_jump_by_parts_equality_rtx (enum mach + + if (op1 == const0_rtx) + { +- do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label); ++ do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label, ++ prob); + return; + } + else if (op0 == const0_rtx) + { +- do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label); ++ do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label, ++ prob); + return; + } + +@@ -737,7 +768,7 @@ do_jump_by_parts_equality_rtx (enum mach + do_compare_rtx_and_jump (operand_subword_force (op0, i, mode), + operand_subword_force (op1, i, mode), + EQ, 0, word_mode, NULL_RTX, +- if_false_label, NULL_RTX); ++ if_false_label, NULL_RTX, prob); + + if (if_true_label) + emit_jump (if_true_label); +@@ -749,13 +780,14 @@ do_jump_by_parts_equality_rtx (enum mach + with one insn, test the comparison and jump to the appropriate label. */ + + static void +-do_jump_by_parts_equality (tree exp, rtx if_false_label, rtx if_true_label) ++do_jump_by_parts_equality (tree exp, rtx if_false_label, rtx if_true_label, ++ int prob) + { + rtx op0 = expand_normal (TREE_OPERAND (exp, 0)); + rtx op1 = expand_normal (TREE_OPERAND (exp, 1)); + enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))); + do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label, +- if_true_label); ++ if_true_label, prob); + } + + /* Generate code for a comparison of OP0 and OP1 with rtx code CODE. +@@ -825,7 +857,7 @@ compare_from_rtx (rtx op0, rtx op1, enum + void + do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, + enum machine_mode mode, rtx size, rtx if_false_label, +- rtx if_true_label) ++ rtx if_true_label, int prob) + { + rtx tem; + int dummy_true_label = 0; +@@ -837,6 +869,7 @@ do_compare_rtx_and_jump (rtx op0, rtx op + if_true_label = if_false_label; + if_false_label = 0; + code = reverse_condition (code); ++ prob = inv (prob); + } + + /* If one operand is constant, make it the second one. Only do this +@@ -886,52 +919,56 @@ do_compare_rtx_and_jump (rtx op0, rtx op + { + case LTU: + do_jump_by_parts_greater_rtx (mode, 1, op1, op0, +- if_false_label, if_true_label); ++ if_false_label, if_true_label, prob); + break; + + case LEU: + do_jump_by_parts_greater_rtx (mode, 1, op0, op1, +- if_true_label, if_false_label); ++ if_true_label, if_false_label, ++ inv (prob)); + break; + + case GTU: + do_jump_by_parts_greater_rtx (mode, 1, op0, op1, +- if_false_label, if_true_label); ++ if_false_label, if_true_label, prob); + break; + + case GEU: + do_jump_by_parts_greater_rtx (mode, 1, op1, op0, +- if_true_label, if_false_label); ++ if_true_label, if_false_label, ++ inv (prob)); + break; + + case LT: + do_jump_by_parts_greater_rtx (mode, 0, op1, op0, +- if_false_label, if_true_label); ++ if_false_label, if_true_label, prob); + break; + + case LE: + do_jump_by_parts_greater_rtx (mode, 0, op0, op1, +- if_true_label, if_false_label); ++ if_true_label, if_false_label, ++ inv (prob)); + break; + + case GT: + do_jump_by_parts_greater_rtx (mode, 0, op0, op1, +- if_false_label, if_true_label); ++ if_false_label, if_true_label, prob); + break; + + case GE: + do_jump_by_parts_greater_rtx (mode, 0, op1, op0, +- if_true_label, if_false_label); ++ if_true_label, if_false_label, ++ inv (prob)); + break; + + case EQ: + do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label, +- if_true_label); ++ if_true_label, prob); + break; + + case NE: + do_jump_by_parts_equality_rtx (mode, op0, op1, if_true_label, +- if_false_label); ++ if_false_label, inv (prob)); + break; + + default: +@@ -939,8 +976,32 @@ do_compare_rtx_and_jump (rtx op0, rtx op + } + } + else +- emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, +- if_true_label); ++ { ++ rtx last = get_last_insn (); ++ emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, ++ if_true_label); ++ if (prob != -1 && profile_status != PROFILE_ABSENT) ++ { ++ for (last = NEXT_INSN (last); ++ last && NEXT_INSN (last); ++ last = NEXT_INSN (last)) ++ if (JUMP_P (last)) ++ break; ++ if (!last ++ || !JUMP_P (last) ++ || NEXT_INSN (last) ++ || !any_condjump_p (last)) ++ { ++ if (dump_file) ++ fprintf (dump_file, "Failed to add probability note\n"); ++ } ++ else ++ { ++ gcc_assert (!find_reg_note (last, REG_BR_PROB, 0)); ++ add_reg_note (last, REG_BR_PROB, GEN_INT (prob)); ++ } ++ } ++ } + + if (if_false_label) + emit_jump (if_false_label); +@@ -961,7 +1022,7 @@ do_compare_rtx_and_jump (rtx op0, rtx op + static void + do_compare_and_jump (tree exp, enum rtx_code signed_code, + enum rtx_code unsigned_code, rtx if_false_label, +- rtx if_true_label) ++ rtx if_true_label, int prob) + { + rtx op0, op1; + tree type; +@@ -1022,7 +1083,7 @@ do_compare_and_jump (tree exp, enum rtx_ + do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, + ((mode == BLKmode) + ? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX), +- if_false_label, if_true_label); ++ if_false_label, if_true_label, prob); + } + + #include "gt-dojump.h" +--- gcc/expr.h.jj 2009-04-24 21:41:31.000000000 +0200 ++++ gcc/expr.h 2010-02-19 18:31:34.000000000 +0100 +@@ -564,20 +564,20 @@ extern void do_pending_stack_adjust (voi + extern tree string_constant (tree, tree *); + + /* Generate code to evaluate EXP and jump to LABEL if the value is zero. */ +-extern void jumpifnot (tree, rtx); ++extern void jumpifnot (tree, rtx, int); + + /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */ +-extern void jumpif (tree, rtx); ++extern void jumpif (tree, rtx, int); + + /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if + the result is zero, or IF_TRUE_LABEL if the result is one. */ +-extern void do_jump (tree, rtx, rtx); ++extern void do_jump (tree, rtx, rtx, int); + + /* Generate rtl to compare two rtx's, will call emit_cmp_insn. */ + extern rtx compare_from_rtx (rtx, rtx, enum rtx_code, int, enum machine_mode, + rtx); + extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int, +- enum machine_mode, rtx, rtx, rtx); ++ enum machine_mode, rtx, rtx, rtx, int); + + /* Two different ways of generating switch statements. */ + extern int try_casesi (tree, tree, tree, tree, rtx, rtx, rtx); +--- gcc/cfgrtl.c.jj 2009-05-28 12:50:54.000000000 +0200 ++++ gcc/cfgrtl.c 2010-02-19 18:27:14.000000000 +0100 +@@ -2951,7 +2951,7 @@ rtl_lv_add_condition_to_bb (basic_block + op0 = force_operand (op0, NULL_RTX); + op1 = force_operand (op1, NULL_RTX); + do_compare_rtx_and_jump (op0, op1, comp, 0, +- mode, NULL_RTX, NULL_RTX, label); ++ mode, NULL_RTX, NULL_RTX, label, -1); + jump = get_last_insn (); + JUMP_LABEL (jump) = label; + LABEL_NUSES (label)++; +--- gcc/except.c.jj 2009-04-24 21:41:34.000000000 +0200 ++++ gcc/except.c 2010-02-19 18:27:14.000000000 +0100 +@@ -1834,7 +1834,7 @@ sjlj_emit_function_enter (rtx dispatch_l + + #ifdef DONT_USE_BUILTIN_SETJMP + { +- rtx x; ++ rtx x, last; + x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE, + TYPE_MODE (integer_type_node), 1, + plus_constant (XEXP (fc, 0), +@@ -1842,7 +1842,12 @@ sjlj_emit_function_enter (rtx dispatch_l + + emit_cmp_and_jump_insns (x, const0_rtx, NE, 0, + TYPE_MODE (integer_type_node), 0, dispatch_label); +- add_reg_br_prob_note (get_insns (), REG_BR_PROB_BASE/100); ++ last = get_last_insn (); ++ if (JUMP_P (last) && any_condjump_p (last)) ++ { ++ gcc_assert (!find_reg_note (last, REG_BR_PROB, 0)); ++ add_reg_note (last, REG_BR_PROB, GEN_INT (REG_BR_PROB_BASE / 100)); ++ } + } + #else + expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs), +--- gcc/config/rs6000/rs6000.c.jj 2009-09-29 17:58:03.000000000 +0200 ++++ gcc/config/rs6000/rs6000.c 2010-02-19 18:27:13.000000000 +0100 +@@ -15534,7 +15534,7 @@ rs6000_aix_emit_builtin_unwind_init (voi + + do_compare_rtx_and_jump (opcode, tocompare, EQ, 1, + SImode, NULL_RTX, NULL_RTX, +- no_toc_save_needed); ++ no_toc_save_needed, -1); + + mem = gen_frame_mem (Pmode, + gen_rtx_PLUS (Pmode, stack_top, +--- gcc/stmt.c.jj 2009-04-27 13:45:10.000000000 +0200 ++++ gcc/stmt.c 2010-02-19 18:27:14.000000000 +0100 +@@ -2472,7 +2472,7 @@ do_jump_if_equal (enum machine_mode mode + int unsignedp) + { + do_compare_rtx_and_jump (op0, op1, EQ, unsignedp, mode, +- NULL_RTX, NULL_RTX, label); ++ NULL_RTX, NULL_RTX, label, -1); + } + + /* Not all case values are encountered equally. This function +--- gcc/Makefile.in.jj 2009-07-28 18:00:54.000000000 +0200 ++++ gcc/Makefile.in 2010-02-19 18:27:13.000000000 +0100 +@@ -2514,7 +2514,7 @@ expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) + tree-pass.h $(DF_H) $(DIAGNOSTIC_H) vecprim.h + dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ + $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) $(INSN_ATTR_H) insn-config.h \ +- langhooks.h $(GGC_H) gt-dojump.h vecprim.h $(BASIC_BLOCK_H) ++ langhooks.h $(GGC_H) gt-dojump.h vecprim.h $(BASIC_BLOCK_H) output.h + builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(GIMPLE_H) $(FLAGS_H) $(TARGET_H) $(FUNCTION_H) $(REGS_H) \ + $(EXPR_H) $(OPTABS_H) insn-config.h $(RECOG_H) output.h typeclass.h \ +--- gcc/cfgexpand.c.jj 2010-01-05 09:56:05.000000000 +0100 ++++ gcc/cfgexpand.c 2010-02-19 18:34:14.000000000 +0100 +@@ -379,46 +379,6 @@ release_stmt_tree (gimple stmt, tree stm + } + + +-/* Verify that there is exactly single jump instruction since last and attach +- REG_BR_PROB note specifying probability. +- ??? We really ought to pass the probability down to RTL expanders and let it +- re-distribute it when the conditional expands into multiple conditionals. +- This is however difficult to do. */ +-void +-add_reg_br_prob_note (rtx last, int probability) +-{ +- if (profile_status == PROFILE_ABSENT) +- return; +- for (last = NEXT_INSN (last); last && NEXT_INSN (last); last = NEXT_INSN (last)) +- if (JUMP_P (last)) +- { +- /* It is common to emit condjump-around-jump sequence when we don't know +- how to reverse the conditional. Special case this. */ +- if (!any_condjump_p (last) +- || !JUMP_P (NEXT_INSN (last)) +- || !simplejump_p (NEXT_INSN (last)) +- || !NEXT_INSN (NEXT_INSN (last)) +- || !BARRIER_P (NEXT_INSN (NEXT_INSN (last))) +- || !NEXT_INSN (NEXT_INSN (NEXT_INSN (last))) +- || !LABEL_P (NEXT_INSN (NEXT_INSN (NEXT_INSN (last)))) +- || NEXT_INSN (NEXT_INSN (NEXT_INSN (NEXT_INSN (last))))) +- goto failed; +- gcc_assert (!find_reg_note (last, REG_BR_PROB, 0)); +- add_reg_note (last, REG_BR_PROB, +- GEN_INT (REG_BR_PROB_BASE - probability)); +- return; +- } +- if (!last || !JUMP_P (last) || !any_condjump_p (last)) +- goto failed; +- gcc_assert (!find_reg_note (last, REG_BR_PROB, 0)); +- add_reg_note (last, REG_BR_PROB, GEN_INT (probability)); +- return; +-failed: +- if (dump_file) +- fprintf (dump_file, "Failed to add probability note\n"); +-} +- +- + #ifndef STACK_ALIGNMENT_NEEDED + #define STACK_ALIGNMENT_NEEDED 1 + #endif +@@ -1669,8 +1629,8 @@ expand_gimple_cond (basic_block bb, gimp + two-way jump that needs to be decomposed into two basic blocks. */ + if (false_edge->dest == bb->next_bb) + { +- jumpif (pred, label_rtx_for_bb (true_edge->dest)); +- add_reg_br_prob_note (last, true_edge->probability); ++ jumpif (pred, label_rtx_for_bb (true_edge->dest), ++ true_edge->probability); + maybe_dump_rtl_for_gimple_stmt (stmt, last); + if (true_edge->goto_locus) + { +@@ -1685,8 +1645,8 @@ expand_gimple_cond (basic_block bb, gimp + } + if (true_edge->dest == bb->next_bb) + { +- jumpifnot (pred, label_rtx_for_bb (false_edge->dest)); +- add_reg_br_prob_note (last, false_edge->probability); ++ jumpifnot (pred, label_rtx_for_bb (false_edge->dest), ++ false_edge->probability); + maybe_dump_rtl_for_gimple_stmt (stmt, last); + if (false_edge->goto_locus) + { +@@ -1700,8 +1660,7 @@ expand_gimple_cond (basic_block bb, gimp + return NULL; + } + +- jumpif (pred, label_rtx_for_bb (true_edge->dest)); +- add_reg_br_prob_note (last, true_edge->probability); ++ jumpif (pred, label_rtx_for_bb (true_edge->dest), true_edge->probability); + last = get_last_insn (); + if (false_edge->goto_locus) + { +--- gcc/gimplify.c.jj 2010-02-08 13:15:22.000000000 +0100 ++++ gcc/gimplify.c 2010-02-19 19:19:54.000000000 +0100 +@@ -2762,6 +2762,32 @@ gimple_boolify (tree expr) + { + tree type = TREE_TYPE (expr); + ++ if (TREE_CODE (expr) == NE_EXPR ++ && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR ++ && integer_zerop (TREE_OPERAND (expr, 1))) ++ { ++ tree call = TREE_OPERAND (expr, 0); ++ tree fn = get_callee_fndecl (call); ++ ++ /* For __builtin_expect ((long) (x), y) recurse into x as well. */ ++ if (fn ++ && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL ++ && DECL_FUNCTION_CODE (fn) == BUILT_IN_EXPECT ++ && call_expr_nargs (call) == 2) ++ { ++ tree arg = CALL_EXPR_ARG (call, 0); ++ if (arg) ++ { ++ if (TREE_CODE (arg) == NOP_EXPR ++ && TREE_TYPE (arg) == TREE_TYPE (call)) ++ arg = TREE_OPERAND (arg, 0); ++ arg = gimple_boolify (arg); ++ CALL_EXPR_ARG (call, 0) ++ = fold_convert (TREE_TYPE (call), arg); ++ } ++ } ++ } ++ + if (TREE_CODE (type) == BOOLEAN_TYPE) + return expr; + +--- gcc/expr.c.jj 2010-01-16 10:44:34.000000000 +0100 ++++ gcc/expr.c 2010-02-19 18:32:25.000000000 +0100 +@@ -4483,7 +4483,7 @@ store_expr (tree exp, rtx target, int ca + + do_pending_stack_adjust (); + NO_DEFER_POP; +- jumpifnot (TREE_OPERAND (exp, 0), lab1); ++ jumpifnot (TREE_OPERAND (exp, 0), lab1, -1); + store_expr (TREE_OPERAND (exp, 1), target, call_param_p, + nontemporal); + emit_jump_insn (gen_jump (lab2)); +@@ -5503,7 +5503,7 @@ store_constructor (tree exp, rtx target, + /* Generate a conditional jump to exit the loop. */ + exit_cond = build2 (LT_EXPR, integer_type_node, + index, hi_index); +- jumpif (exit_cond, loop_end); ++ jumpif (exit_cond, loop_end, -1); + + /* Update the loop counter, and jump to the head of + the loop. */ +@@ -8974,7 +8974,8 @@ expand_expr_real_1 (tree exp, rtx target + + temp = gen_label_rtx (); + do_compare_rtx_and_jump (target, cmpop1, comparison_code, +- unsignedp, mode, NULL_RTX, NULL_RTX, temp); ++ unsignedp, mode, NULL_RTX, NULL_RTX, temp, ++ -1); + } + emit_move_insn (target, op1); + emit_label (temp); +@@ -9125,7 +9126,7 @@ expand_expr_real_1 (tree exp, rtx target + emit_move_insn (target, const0_rtx); + + op1 = gen_label_rtx (); +- jumpifnot (exp, op1); ++ jumpifnot (exp, op1, -1); + + if (target) + emit_move_insn (target, const1_rtx); +@@ -9194,7 +9195,7 @@ expand_expr_real_1 (tree exp, rtx target + NO_DEFER_POP; + op0 = gen_label_rtx (); + op1 = gen_label_rtx (); +- jumpifnot (TREE_OPERAND (exp, 0), op0); ++ jumpifnot (TREE_OPERAND (exp, 0), op0, -1); + store_expr (TREE_OPERAND (exp, 1), temp, + modifier == EXPAND_STACK_PARM, + false); +@@ -9240,7 +9241,7 @@ expand_expr_real_1 (tree exp, rtx target + int value = TREE_CODE (rhs) == BIT_IOR_EXPR; + do_jump (TREE_OPERAND (rhs, 1), + value ? label : 0, +- value ? 0 : label); ++ value ? 0 : label, -1); + expand_assignment (lhs, build_int_cst (TREE_TYPE (rhs), value), + MOVE_NONTEMPORAL (exp)); + do_pending_stack_adjust (); +@@ -9924,7 +9925,7 @@ do_store_flag (tree exp, rtx target, enu + emit_move_insn (target, invert ? const0_rtx : const1_rtx); + label = gen_label_rtx (); + do_compare_rtx_and_jump (op0, op1, code, unsignedp, operand_mode, NULL_RTX, +- NULL_RTX, label); ++ NULL_RTX, label, -1); + + emit_move_insn (target, invert ? const1_rtx : const0_rtx); + emit_label (label); +--- gcc/optabs.c.jj 2009-04-24 21:41:23.000000000 +0200 ++++ gcc/optabs.c 2010-02-19 18:27:10.000000000 +0100 +@@ -1149,7 +1149,7 @@ expand_doubleword_shift (enum machine_mo + + NO_DEFER_POP; + do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode, +- 0, 0, subword_label); ++ 0, 0, subword_label, -1); + OK_DEFER_POP; + + if (!expand_superword_shift (binoptab, outof_input, superword_op1, +@@ -3498,7 +3498,7 @@ expand_abs (enum machine_mode mode, rtx + NO_DEFER_POP; + + do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode, +- NULL_RTX, NULL_RTX, op1); ++ NULL_RTX, NULL_RTX, op1, -1); + + op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab, + target, target, 0); +--- gcc/rtl.h.jj 2009-04-27 16:47:34.000000000 +0200 ++++ gcc/rtl.h 2010-02-19 18:27:14.000000000 +0100 +@@ -2305,8 +2305,6 @@ extern GTY(()) rtx stack_limit_rtx; + /* In predict.c */ + extern void invert_br_probabilities (rtx); + extern bool expensive_function_p (int); +-/* In cfgexpand.c */ +-extern void add_reg_br_prob_note (rtx last, int probability); + + /* In var-tracking.c */ + extern unsigned int variable_tracking_main (void); +--- gcc/loop-doloop.c.jj 2009-04-24 21:41:33.000000000 +0200 ++++ gcc/loop-doloop.c 2010-02-19 18:27:14.000000000 +0100 +@@ -291,7 +291,8 @@ add_test (rtx cond, edge *e, basic_block + op0 = force_operand (op0, NULL_RTX); + op1 = force_operand (op1, NULL_RTX); + label = block_label (dest); +- do_compare_rtx_and_jump (op0, op1, code, 0, mode, NULL_RTX, NULL_RTX, label); ++ do_compare_rtx_and_jump (op0, op1, code, 0, mode, NULL_RTX, ++ NULL_RTX, label, -1); + + jump = get_last_insn (); + if (!jump || !JUMP_P (jump)) diff --git a/gcc44-pr43051.patch b/gcc44-pr43051.patch new file mode 100644 index 0000000..c4425ae --- /dev/null +++ b/gcc44-pr43051.patch @@ -0,0 +1,331 @@ +2010-02-17 Alexandre Oliva + + * var-tracking.c (dataflow_set_preserve_mem_locs): Update cur_loc. + +2010-02-17 Jakub Jelinek + + PR debug/43051 + * var-tracking.c (struct dfset_merge): Move definition earlier. + (value_pair): New variable. + (ignore_first_value_pair): New function. + (find_loc_in_1pdv_1): Change last argument to struct dfset_merge *. + If node->loc is VALUE, don't call rtx_equal_p at all, instead just + compare pointers and then recurse. For other rtxes, call + rtx_equal_p_cb instead of rtx_equal_p and ignore first VALUE pair + during comparison, if some has been found, compare those VALUEs + recursively. + (find_loc_in_1pdv): Change last argument to struct dfset_merge *. + (intersect_loc_chains, variable_post_merge_perm_vals): Adjust callers. + + * gcc.dg/guality/pr43051-1.c: New test. + +--- gcc/var-tracking.c.jj 2010-02-07 11:53:22.000000000 +0100 ++++ gcc/var-tracking.c 2010-02-15 12:37:00.000000000 +0100 +@@ -428,7 +428,8 @@ static int variable_union_info_cmp_pos ( + static int variable_union (void **, void *); + static int variable_canonicalize (void **, void *); + static void dataflow_set_union (dataflow_set *, dataflow_set *); +-static location_chain find_loc_in_1pdv (rtx, variable, htab_t); ++struct dfset_merge; ++static location_chain find_loc_in_1pdv (rtx, variable, struct dfset_merge *); + static bool canon_value_cmp (rtx, rtx); + static int loc_cmp (rtx, rtx); + static bool variable_part_different_p (variable_part *, variable_part *); +@@ -2234,6 +2235,53 @@ dv_changed_p (decl_or_value dv) + : DECL_CHANGED (dv_as_decl (dv))); + } + ++/* Hash table iteration argument passed to variable_merge. */ ++struct dfset_merge ++{ ++ /* The set in which the merge is to be inserted. */ ++ dataflow_set *dst; ++ /* The set that we're iterating in. */ ++ dataflow_set *cur; ++ /* The set that may contain the other dv we are to merge with. */ ++ dataflow_set *src; ++ /* Number of onepart dvs in src. */ ++ int src_onepart_cnt; ++}; ++ ++/* First encountered differing VALUE pair remembered by ++ ignore_first_value_pair hook. */ ++ ++static rtx value_pair[2]; ++ ++/* Helper for rtx_equal_p_cb. Pretend the first encountered VALUE pair ++ is the same and remember it. */ ++ ++static int ++ignore_first_value_pair (const_rtx *px, const_rtx *py, rtx *nx, rtx *ny) ++{ ++ const_rtx x = *px, y; ++ ++ if (GET_CODE (x) != VALUE) ++ return 0; ++ y = *py; ++ if (GET_CODE (y) != VALUE) ++ return 0; ++ if (x == y) ++ return 0; ++ if (GET_MODE (x) != GET_MODE (y)) ++ return 0; ++ /* If this isn't the first encountered VALUE pair, fail. */ ++ if (value_pair[0]) ++ return 0; ++ /* Remember the first encountered VALUE pair and pretend the VALUEs are the ++ same. */ ++ value_pair[0] = CONST_CAST_RTX (x); ++ value_pair[1] = CONST_CAST_RTX (y); ++ *nx = CONST_CAST_RTX (x); ++ *ny = CONST_CAST_RTX (x); ++ return 1; ++} ++ + /* Vector of VALUEs that should have VALUE_RECURSED_INTO bit cleared + at the end of find_loc_in_1pdv. Not a static variable in find_loc_in_1pdv + to avoid constant allocation/freeing of it. */ +@@ -2245,7 +2293,7 @@ static VEC(rtx, heap) *values_to_unmark; + any values recursively mentioned in the location lists. */ + + static location_chain +-find_loc_in_1pdv_1 (rtx loc, variable var, htab_t vars) ++find_loc_in_1pdv_1 (rtx loc, variable var, struct dfset_merge *dsm) + { + location_chain node; + +@@ -2260,22 +2308,65 @@ find_loc_in_1pdv_1 (rtx loc, variable va + gcc_assert (var->var_part[0].offset == 0); + + for (node = var->var_part[0].loc_chain; node; node = node->next) +- if (rtx_equal_p (loc, node->loc)) +- return node; +- else if (GET_CODE (node->loc) == VALUE +- && !VALUE_RECURSED_INTO (node->loc)) ++ if (GET_CODE (node->loc) == VALUE) + { +- decl_or_value dv = dv_from_value (node->loc); +- variable var = (variable) +- htab_find_with_hash (vars, dv, dv_htab_hash (dv)); ++ if (loc == node->loc) ++ return node; ++ if (!VALUE_RECURSED_INTO (node->loc)) ++ { ++ decl_or_value dv = dv_from_value (node->loc); ++ htab_t vars = shared_hash_htab (dsm->src->vars); ++ variable var ++ = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv)); + +- if (var) ++ if (var) ++ { ++ location_chain where; ++ VALUE_RECURSED_INTO (node->loc) = true; ++ VEC_safe_push (rtx, heap, values_to_unmark, node->loc); ++ if ((where = find_loc_in_1pdv_1 (loc, var, dsm))) ++ return where; ++ } ++ } ++ } ++ else if (GET_CODE (node->loc) == GET_CODE (loc)) ++ { ++ rtx val1, val2; ++ if (!rtx_equal_p_cb (loc, node->loc, ignore_first_value_pair)) + { +- location_chain where; +- VALUE_RECURSED_INTO (node->loc) = true; +- VEC_safe_push (rtx, heap, values_to_unmark, node->loc); +- if ((where = find_loc_in_1pdv_1 (loc, var, vars))) +- return where; ++ value_pair[0] = NULL; ++ value_pair[1] = NULL; ++ continue; ++ } ++ if (!value_pair[0]) ++ return node; ++ val1 = value_pair[0]; ++ val2 = value_pair[1]; ++ value_pair[0] = NULL; ++ value_pair[1] = NULL; ++ if (dsm->cur) ++ { ++ decl_or_value dv; ++ htab_t vars; ++ variable var1, var2; ++ dv = dv_from_value (val1); ++ vars = shared_hash_htab (dsm->cur->vars); ++ var1 = (variable) htab_find_with_hash (vars, dv, ++ dv_htab_hash (dv)); ++ if (var1) ++ { ++ dv = dv_from_value (val2); ++ vars = shared_hash_htab (dsm->src->vars); ++ var2 = (variable) htab_find_with_hash (vars, dv, ++ dv_htab_hash (dv)); ++ if (var2) ++ { ++ location_chain s1node = var1->var_part[0].loc_chain; ++ for (; s1node; s1node = s1node->next) ++ if (find_loc_in_1pdv_1 (s1node->loc, var2, dsm)) ++ return node; ++ } ++ } + } + } + +@@ -2287,32 +2378,19 @@ find_loc_in_1pdv_1 (rtx loc, variable va + any values recursively mentioned in the location lists. */ + + static location_chain +-find_loc_in_1pdv (rtx loc, variable var, htab_t vars) ++find_loc_in_1pdv (rtx loc, variable var, struct dfset_merge *dsm) + { + location_chain ret; + unsigned int i; + rtx value; + +- ret = find_loc_in_1pdv_1 (loc, var, vars); ++ ret = find_loc_in_1pdv_1 (loc, var, dsm); + for (i = 0; VEC_iterate (rtx, values_to_unmark, i, value); i++) + VALUE_RECURSED_INTO (value) = false; + VEC_truncate (rtx, values_to_unmark, 0); + return ret; + } + +-/* Hash table iteration argument passed to variable_merge. */ +-struct dfset_merge +-{ +- /* The set in which the merge is to be inserted. */ +- dataflow_set *dst; +- /* The set that we're iterating in. */ +- dataflow_set *cur; +- /* The set that may contain the other dv we are to merge with. */ +- dataflow_set *src; +- /* Number of onepart dvs in src. */ +- int src_onepart_cnt; +-}; +- + /* Insert LOC in *DNODE, if it's not there yet. The list must be in + loc_cmp order, and it is maintained as such. */ + +@@ -2351,7 +2429,6 @@ intersect_loc_chains (rtx val, location_ + location_chain s1node, variable s2var) + { + dataflow_set *s1set = dsm->cur; +- dataflow_set *s2set = dsm->src; + location_chain found; + + for (; s1node; s1node = s1node->next) +@@ -2359,8 +2436,7 @@ intersect_loc_chains (rtx val, location_ + if (s1node->loc == val) + continue; + +- if ((found = find_loc_in_1pdv (s1node->loc, s2var, +- shared_hash_htab (s2set->vars)))) ++ if ((found = find_loc_in_1pdv (s1node->loc, s2var, dsm))) + { + insert_into_intersection (dest, s1node->loc, + MIN (s1node->init, found->init)); +@@ -3592,7 +3668,10 @@ variable_post_merge_perm_vals (void **ps + var = shared_hash_find (set->vars, dv); + if (var) + { +- if (find_loc_in_1pdv (pnode->loc, var, shared_hash_htab (set->vars))) ++ struct dfset_merge dsm; ++ memset (&dsm, '\0', sizeof (dsm)); ++ dsm.src = set; ++ if (find_loc_in_1pdv (pnode->loc, var, &dsm)) + return 1; + val_reset (set, dv); + } +@@ -3808,6 +3808,7 @@ dataflow_set_preserve_mem_locs (void **s + { + tree decl = dv_as_decl (var->dv); + location_chain loc, *locp; ++ bool changed = false; + + if (!var->n_var_parts) + return 1; +@@ -3881,6 +3882,9 @@ dataflow_set_preserve_mem_locs (void **s + if (emit_notes) + remove_value_chains (var->dv, old_loc); + *locp = loc->next; ++ if (var->var_part[0].cur_loc ++ && rtx_equal_p (loc->loc, var->var_part[0].cur_loc)) ++ changed = true; + pool_free (loc_chain_pool, loc); + } + +@@ -3889,6 +3893,12 @@ dataflow_set_preserve_mem_locs (void **s + var->n_var_parts--; + if (emit_notes && dv_is_value_p (var->dv)) + remove_cselib_value_chains (var->dv); ++ gcc_assert (changed); ++ } ++ if (changed) ++ { ++ if (var->n_var_parts && var->var_part[0].loc_chain) ++ var->var_part[0].cur_loc = var->var_part[0].loc_chain->loc; + variable_was_changed (var, set); + } + } +--- gcc/testsuite/gcc.dg/guality/pr43051-1.c.jj 2010-02-17 10:17:12.000000000 +0100 ++++ gcc/testsuite/gcc.dg/guality/pr43051-1.c 2010-02-17 10:41:43.000000000 +0100 +@@ -0,0 +1,57 @@ ++/* PR debug/43051 */ ++/* { dg-do run } */ ++/* { dg-options "-g" } */ ++ ++extern void abort (void); ++ ++static void __attribute__ ((noinline)) ++foo (const char *x, long long y, int z) ++{ ++ asm volatile ("" : : "r" (x), "r" ((int) y), "r" (z) : "memory"); ++} ++ ++struct S ++{ ++ struct S *n; ++ int v; ++}; ++ ++struct S a[10]; ++ ++struct S * __attribute__ ((noinline)) ++bar (struct S *c, int v, struct S *e) ++{ ++#ifdef __i386__ ++ register int si asm ("esi"), di asm ("edi"), bx ++# if !defined (__pic__) && !defined (__APPLE__) ++ asm ("ebx") ++# endif ++ ; ++ asm volatile ("" : "=r" (si), "=r" (di), "=r" (bx)); ++#endif ++ while (c < e) ++ { ++ foo ("c", (unsigned long) c, 0); /* { dg-final { gdb-test 34 "c" "\&a\[0\]" } } */ ++ foo ("v", v, 1); /* { dg-final { gdb-test 35 "v" "1" } } */ ++ foo ("e", (unsigned long) e, 2); /* { dg-final { gdb-test 36 "e" "\&a\[1\]" } } */ ++ if (c->v == v) ++ return c; ++ foo ("c", (unsigned long) c, 3); /* { dg-final { gdb-test 39 "c" "\&a\[0\]" } } */ ++ foo ("v", v, 4); /* { dg-final { gdb-test 40 "v" "1" } } */ ++ foo ("e", (unsigned long) e, 5); /* { dg-final { gdb-test 41 "e" "\&a\[1\]" } } */ ++ c++; ++ } ++#ifdef __i386__ ++ asm volatile ("" : : "r" (si), "r" (di), "r" (bx)); ++#endif ++ return 0; ++} ++ ++int ++main () ++{ ++ asm volatile ("" : : "r" (&a[0]) : "memory"); ++ if (bar (&a[a[0].v], a[0].v + 1, &a[a[0].v + 1])) ++ abort (); ++ return 0; ++} diff --git a/gcc44-sparc-config-detection.patch b/gcc44-sparc-config-detection.patch index cc3cb41..9c6b57e 100644 --- a/gcc44-sparc-config-detection.patch +++ b/gcc44-sparc-config-detection.patch @@ -6,7 +6,7 @@ ;; -sparc-*-linux*) # SPARC's running GNU/Linux, libc6 +sparc-*-linux* | sparcv9*-*-linux*) # SPARC's running GNU/Linux, libc6 - tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h linux.h" + tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/gas.h linux.h" extra_options="${extra_options} sparc/long-double-switch.opt" tmake_file="${tmake_file} sparc/t-linux" @@ -2287,7 +2287,7 @@ sparc64-*-freebsd*|ultrasparc-*-freebsd* @@ -15,7 +15,7 @@ ;; -sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux +sparc64*-*-linux*) # 64-bit SPARC's running GNU/Linux - tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h linux.h sparc/linux64.h" + tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/gas.h linux.h sparc/linux64.h" extra_options="${extra_options} sparc/long-double-switch.opt" tmake_file="${tmake_file} sparc/t-linux sparc/t-linux64 sparc/t-crtfm" --- libgcc/config.host.jj 2008-04-24 15:46:19.000000000 -0500 diff --git a/import.log b/import.log index dca725e..2664ddd 100644 --- a/import.log +++ b/import.log @@ -7,3 +7,4 @@ gcc-4_4_3-1_fc13:HEAD:gcc-4.4.3-1.fc13.src.rpm:1264094717 gcc-4_4_3-4_fc13:HEAD:gcc-4.4.3-4.fc13.src.rpm:1264621537 gcc-4_4_3-5_fc13:HEAD:gcc-4.4.3-5.fc13.src.rpm:1265659730 gcc-4_4_3-6_fc13:HEAD:gcc-4.4.3-6.fc13.src.rpm:1265925505 +gcc-4_4_3-7_fc13:F-13:gcc-4.4.3-7.fc13.src.rpm:1266793373 diff --git a/sources b/sources index b9841eb..82bd137 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ 2659f09c2e43ef8b7d4406321753f1b2 fastjar-0.97.tar.gz -080254256e618fa9f8f28e03698b016a gcc-4.4.3-20100211.tar.bz2 +ca2561a74af23f1de6218cc7e3bb2606 gcc-4.4.3-20100221.tar.bz2