From c2511ac51c9e6e6b8cd9900d6159d46718414012 Mon Sep 17 00:00:00 2001 From: Jing Yu Date: Sat, 24 Apr 2010 20:30:19 -0700 Subject: Fix a few divergence bugs and security problem. See README.google for details. Change-Id: Ifbee6d934426a60f34c7301a04fc442c6c75df22 --- gcc-4.4.0/README.google | 36 +++++ gcc-4.4.0/gcc/combine.c | 10 +- gcc-4.4.0/gcc/config/arm/eabi.h | 3 + gcc-4.4.0/gcc/configure | 21 ++- gcc-4.4.0/gcc/configure.ac | 19 ++- gcc-4.4.0/gcc/tree-ssa-lrs.c | 277 ++++++++++++++++++++++++++------------- gcc-4.4.0/gcc/tree-ssa-reassoc.c | 36 ++++- 7 files changed, 299 insertions(+), 103 deletions(-) (limited to 'gcc-4.4.0') diff --git a/gcc-4.4.0/README.google b/gcc-4.4.0/README.google index e2f11a2e3..82bc08ae5 100644 --- a/gcc-4.4.0/README.google +++ b/gcc-4.4.0/README.google @@ -2235,3 +2235,39 @@ gcc/combine.c in which a floating point mode RTX is unsafely optimized. Owner: dougkwan Status: backport of upstream rev 152443. + +gcc/configure.ac +gcc/configure + Fix a problem where the gcc configure script checks for particular + versions of ld for certain features when building with gold as the linker. + Owner: dougkwan + Status: Not yet upstream. + +gcc/tree-ssa-lrs.c + Port CL-39082 and CL-38762 from x86 gcc-4.4.0 to Android branch. + Owner: dougkwan + Status: Not yet upstream. + +gcc/tree-ssa-lrs.c + Port CL-39388 from x86 gcc-4.4.0 to Android branch to stabilize qsort + comparators. + Owner: dougkwan + Status: Not yet upstream. + +gcc/tree-ssa-lrs.c + Port CL-39443 from x86 gcc-4.4.0 to Android branch to stabilize qsort + comparators. + Owner: dougkwan + Status: Not yet upstream. + +gcc/tree-ssa-reassoc.c + Port CL-39465 from x86 gcc-4.4.0 to Android branch to stabilize qsort in + tree-ssa-reassoc.c + Owner: dougkwan + Status: Not yet upstream. + +gcc/config/arm/eabi.h + Add GNU-stack annotation to all Android code to fix a potential serious + security problem. http://b/issue?id=2623907. + Owner: jingyu + Status: google local diff --git a/gcc-4.4.0/gcc/combine.c b/gcc-4.4.0/gcc/combine.c index 48ec81c44..3b32ee757 100644 --- a/gcc-4.4.0/gcc/combine.c +++ b/gcc-4.4.0/gcc/combine.c @@ -8516,11 +8516,11 @@ distribute_and_simplify_rtx (rtx x, int n) enum rtx_code outer_code, inner_code; rtx decomposed, distributed, inner_op0, inner_op1, new_op0, new_op1, tmp; - /* Distributivity is not true for floating point as it can change the - value. So we don't do it unless -funsafe-math-optimizations. */ - if (FLOAT_MODE_P (GET_MODE (x)) - && ! flag_unsafe_math_optimizations) - return NULL_RTX; + /* Distributivity is not true for floating point as it can change the + value. So we don't do it unless -funsafe-math-optimizations. */ + if (FLOAT_MODE_P (GET_MODE (x)) + && ! flag_unsafe_math_optimizations) + return NULL_RTX; decomposed = XEXP (x, n); if (!ARITHMETIC_P (decomposed)) diff --git a/gcc-4.4.0/gcc/config/arm/eabi.h b/gcc-4.4.0/gcc/config/arm/eabi.h index 475ce7846..f398cddff 100644 --- a/gcc-4.4.0/gcc/config/arm/eabi.h +++ b/gcc-4.4.0/gcc/config/arm/eabi.h @@ -128,3 +128,6 @@ #define ENDFILE_SPEC \ "%{mandroid: %(endfile_android) ;" \ " : %(endfile_default)}" + +#undef NEED_INDICATE_EXEC_STACK +#define NEED_INDICATE_EXEC_STACK 1 diff --git a/gcc-4.4.0/gcc/configure b/gcc-4.4.0/gcc/configure index 299ff6915..170d4011f 100755 --- a/gcc-4.4.0/gcc/configure +++ b/gcc-4.4.0/gcc/configure @@ -20892,6 +20892,19 @@ fi fi +# Check to see if we are using gold instead of ld +echo "$as_me:$LINENO: checking whether we are using gold" >&5 +echo $ECHO_N "checking whether we are using gold... $ECHO_C" >&6 +ld_is_gold=no +if test x$gcc_cv_ld != x; then + ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q` + if echo "$ld_ver" | grep "GNU gold" > /dev/null; then + ld_is_gold=yes + fi +fi +echo "$as_me:$LINENO: result: $ld_is_gold" >&5 +echo "${ECHO_T}$ld_is_gold" >&6 + ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld case "$ORIGINAL_LD_FOR_TARGET" in @@ -21480,7 +21493,9 @@ else else gcc_cv_ld_hidden=yes ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q` - if echo "$ld_ver" | grep GNU > /dev/null; then + if test x"$ld_is_gold" == xyes; then + gcc_cv_ld_hidden=yes + elif echo "$ld_ver" | grep GNU > /dev/null; then ld_vers=`echo $ld_ver | sed -n \ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*.*\)$,\1,p'` ld_date=`echo $ld_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)[-]*\([01][0-9]\)[-]*\([0-3][0-9]\).*$,\1\2\3,p'` @@ -22016,7 +22031,9 @@ echo "$as_me:$LINENO: result: $gcc_cv_as_comdat_group_percent" >&5 echo "${ECHO_T}$gcc_cv_as_comdat_group_percent" >&6 fi -if test $in_tree_ld != yes && test x"$ld_vers" != x; then +if test x"$ld_is_gold" == xyes; then + comdat_group=yes +elif test $in_tree_ld != yes && test x"$ld_vers" != x; then comdat_group=yes if test 0"$ld_date" -lt 20050308; then if test -n "$ld_date"; then diff --git a/gcc-4.4.0/gcc/configure.ac b/gcc-4.4.0/gcc/configure.ac index 40052dab8..a2204be06 100644 --- a/gcc-4.4.0/gcc/configure.ac +++ b/gcc-4.4.0/gcc/configure.ac @@ -1969,6 +1969,17 @@ else AC_PATH_PROG(gcc_cv_ld, $LD_FOR_TARGET) fi]) +# Check to see if we are using gold instead of ld +AC_MSG_CHECKING(whether we are using gold) +ld_is_gold=no +if test x$gcc_cv_ld != x; then + ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q` + if echo "$ld_ver" | grep "GNU gold" > /dev/null; then + ld_is_gold=yes + fi +fi +AC_MSG_RESULT($ld_is_gold) + ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld AC_SUBST(ORIGINAL_LD_FOR_TARGET) case "$ORIGINAL_LD_FOR_TARGET" in @@ -2165,7 +2176,9 @@ else changequote(,)dnl gcc_cv_ld_hidden=yes ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q` - if echo "$ld_ver" | grep GNU > /dev/null; then + if test x"$ld_is_gold" == xyes; then + gcc_cv_ld_hidden=yes + elif echo "$ld_ver" | grep GNU > /dev/null; then ld_vers=`echo $ld_ver | sed -n \ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*.*\)$,\1,p'` ld_date=`echo $ld_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)[-]*\([01][0-9]\)[-]*\([0-3][0-9]\).*$,\1\2\3,p'` @@ -2448,7 +2461,9 @@ else [elf,2,16,0], [--fatal-warnings], [.section .text,"axG",%progbits,.foo,comdat]) fi -if test $in_tree_ld != yes && test x"$ld_vers" != x; then +if test x"$ld_is_gold" == xyes; then + comdat_group=yes +elif test $in_tree_ld != yes && test x"$ld_vers" != x; then comdat_group=yes if test 0"$ld_date" -lt 20050308; then if test -n "$ld_date"; then diff --git a/gcc-4.4.0/gcc/tree-ssa-lrs.c b/gcc-4.4.0/gcc/tree-ssa-lrs.c index bd5050a4e..2970520c6 100644 --- a/gcc-4.4.0/gcc/tree-ssa-lrs.c +++ b/gcc-4.4.0/gcc/tree-ssa-lrs.c @@ -211,6 +211,9 @@ typedef struct reg_alloc struct reg_alloc *parent; } *reg_alloc_p; +DEF_VEC_P(reg_alloc_p); +DEF_VEC_ALLOC_P(reg_alloc_p, heap); + /* This data structure is used to represent the code region that is selected for live range shrinking transformation. In this implementation, only two types of regions are @@ -235,7 +238,7 @@ typedef struct lrs_region size_t bitvec_width; /* The size (in the number of gimple statements) of the largest bb in the region. */ - size_t max_bb_size; + unsigned max_bb_size; /* The mapping from bb address to region index. */ struct pointer_map_t *bb_to_idx_map; @@ -302,11 +305,11 @@ typedef struct lrs_region /* The number of available registers for each register class. */ - size_t available_regs[lrc_num]; + unsigned available_regs[lrc_num]; /* Computed register pressure for this region. */ - size_t reg_pressure[lrc_num]; + unsigned reg_pressure[lrc_num]; /* Computed register pressure for each BB in the region. */ - size_t *bb_reg_pressures[lrc_num]; + unsigned *bb_reg_pressures[lrc_num]; } *lrs_region_p; @@ -324,8 +327,9 @@ static VEC(tree, heap) **reg_allocs = NULL; static size_t num_reg_allocs = 0; /* The map from ssa names to the associated reg allocs. */ static struct pointer_map_t *tmp_reg_alloc_map = NULL; +static VEC(reg_alloc_p, heap) *reg_alloc_vec = NULL; static alloc_pool tmp_reg_alloc_pool = NULL; -static size_t reg_pressure_control_min_bb_size = 0; +static unsigned reg_pressure_control_min_bb_size = 0; struct pending_negates { @@ -729,9 +733,9 @@ form_region (basic_block bb) if (dump_file) fprintf (dump_file, "region (Entry BB# %d) is skipped: " - "region max bb size = %d, min_size = %d!\n,", + "region max bb size = %u, min_size = %u!\n,", region->entry->index, region->max_bb_size, - (int)reg_pressure_control_min_bb_size); + reg_pressure_control_min_bb_size); destroy_region (region); return NULL; } @@ -998,6 +1002,7 @@ find_or_create_reg_alloc (tree nm) ra->parent = NULL; VEC_safe_push (tree, heap, ra->members, nm); *slot = ra; + VEC_safe_push (reg_alloc_p, heap, reg_alloc_vec, ra); return ra; } @@ -1050,78 +1055,81 @@ compute_reg_allocs (basic_block bb) } } -/* The function is used to move members (ssa names) of - a reg_alloc node to the root node of the union. The - member array of the transferred node is then destroyed. */ +/* The function is used to move members (ssa names) of + a reg_alloc node to the root node of the union. The + member array of the transferred node is then destroyed. + Returns the number of reg_alloc roots. */ -static bool -finalize_ra_mem (const void *key ATTRIBUTE_UNUSED, void **value, - void *data ) +static int +finalize_ra_mem (void) { reg_alloc_p ra = 0; - reg_alloc_p real_ra = 0; - size_t i, n; - int *c; - - c = (int *) data; + size_t r, c = 0; - gcc_assert (*value); - ra = (reg_alloc_p) *value; - if (!ra->members) - return true; - - real_ra = get_reg_alloc_root (ra); - if (real_ra == ra) + for (r = 0; + VEC_iterate (reg_alloc_p, reg_alloc_vec, r, ra); + r++) { - (*c)++ ; - return true; - } + size_t i; + tree nm; + reg_alloc_p real_ra = 0; - n = VEC_length (tree, ra->members); + real_ra = get_reg_alloc_root (ra); + if (real_ra == ra) + { + c++; + continue; + } - for (i = 0; i < n; i++) - VEC_safe_push (tree, heap, real_ra->members, - VEC_index (tree, ra->members, i)); + if (!ra->members) + continue; - VEC_free (tree, heap, ra->members); - ra->members = 0; + for (i = 0; + VEC_iterate (tree, ra->members, i, nm); + i++) + VEC_safe_push (tree, heap, real_ra->members, nm); - return true; + VEC_free (tree, heap, ra->members); + ra->members = 0; + } + + return c; } /* The function maps ssa names to their associated reg_alloc number. */ -static bool -finalize_ra_map (const void *key ATTRIBUTE_UNUSED, void **value, - void *data ATTRIBUTE_UNUSED) +static void +finalize_ra_map (void) { reg_alloc_p ra = 0; - reg_alloc_p real_ra = 0; - size_t i, n; - - gcc_assert (*value); - ra = (reg_alloc_p) *value; + size_t r; - real_ra = get_reg_alloc_root (ra); + for (r = 0; + VEC_iterate (reg_alloc_p, reg_alloc_vec, r, ra); + r++) + { + size_t i; + reg_alloc_p real_ra = 0; + tree nm; - if (!real_ra->members) - return true; + real_ra = get_reg_alloc_root (ra); + if (ra != real_ra) + continue; + if (!real_ra->members) + continue; - n = VEC_length (tree, real_ra->members); + for (i = 0; + VEC_iterate (tree, real_ra->members, i, nm); + i++) + { + void **slot = pointer_map_insert (reg_alloc_map, nm); + *slot = (void *)(size_t) num_reg_allocs; + } - for (i = 0; i < n; i++) - { - void **slot = pointer_map_insert (reg_alloc_map, - VEC_index (tree, real_ra->members, i)); - *slot = (void *)(size_t) num_reg_allocs; + reg_allocs[num_reg_allocs++] = real_ra->members; + real_ra->members = 0; } - - reg_allocs[num_reg_allocs++] = real_ra->members; - - real_ra->members = 0; - - return true; } /* The function returns the reg_alloc number/id for ssa @@ -1135,7 +1143,7 @@ get_reg_alloc_id (const tree nm) slot = pointer_map_contains (reg_alloc_map, nm); if (!slot) return -1; - return (int) *slot; + return (int) (long) *slot; } /* The function destroys the temporary reg_alloc map @@ -1148,6 +1156,8 @@ destroy_tmp_reg_alloc_map (void) free_alloc_pool (tmp_reg_alloc_pool); tmp_reg_alloc_map = 0; tmp_reg_alloc_pool = 0; + VEC_free (reg_alloc_p, heap, reg_alloc_vec); + reg_alloc_vec = NULL; } /* The function converts the temporary reg_alloc map @@ -1158,12 +1168,10 @@ static void finalize_reg_allocs (void) { int sz = 0; - pointer_map_traverse (tmp_reg_alloc_map, - finalize_ra_mem, &sz); + sz = finalize_ra_mem (); reg_allocs = XNEWVEC (VEC(tree, heap)*, sz); num_reg_allocs = 0; - pointer_map_traverse (tmp_reg_alloc_map, - finalize_ra_map, NULL); + finalize_ra_map (); destroy_tmp_reg_alloc_map (); } @@ -1261,7 +1269,7 @@ set_use_ref_bit_pos (tree *use, int pos, lrs_region_p region) void **slot; slot = pointer_map_insert (region->bit_pos_map, use); - *slot = (void*) pos; + *slot = (void *)(long) pos; } /* The function returns the bit position for use ref USE in REGION. */ @@ -1274,7 +1282,7 @@ get_use_ref_bit_pos (tree *use, lrs_region_p region) slot = pointer_map_contains (region->bit_pos_map, use); gcc_assert (slot); - return (int)*slot; + return (int)(long) *slot; } /* The function returns the live reference set at the program point @@ -1642,6 +1650,8 @@ get_vop_operands (lrs_stmt_p norm_stmt, } } +static struct pointer_map_t *orig_nm_order = NULL; + /* The comparison function used in quick sorting of SSA names. The names are sorted according to the register allocation ids, or if not mapped to registers, their ssa name versions. */ @@ -1655,8 +1665,18 @@ refed_nm_cmp (const void *p1, const void *p2) ra1 = get_reg_alloc_id (*n1); ra2 = get_reg_alloc_id (*n2); - if (ra1 == -1 && ra2 == -1) - return SSA_NAME_VERSION (*n2) - SSA_NAME_VERSION (*n1); + if (ra1 == ra2) + { + void **slot; + int o1, o2; + + slot = pointer_map_contains (orig_nm_order, *n1); + o1 = (int)(long) *slot; + slot = pointer_map_contains (orig_nm_order, *n2); + o2 = (int)(long) *slot; + gcc_assert (o2 != o1); + return o2 - o1; + } if (ra2 == -1) return 1; @@ -1718,6 +1738,17 @@ prepare_bitmaps (lrs_region_p region) region_live_out_nms = sbitmap_alloc (nr); sbitmap_zero (region_live_out_nms); + /* Now remember original name order. */ + orig_nm_order = pointer_map_create (); + for (i = 0; i < nr; i++) + { + void **slot; + + slot = pointer_map_insert (orig_nm_order, + VEC_index (tree, refed_names, i)); + *slot = (void *)(long)i; + } + /* Sort the refed names. */ qsort (VEC_address (tree, refed_names), VEC_length (tree, refed_names), sizeof (tree), refed_nm_cmp); @@ -1874,6 +1905,8 @@ prepare_bitmaps (lrs_region_p region) pointer_map_destroy (nm_to_use_ref_map); pointer_set_destroy (vvar_set); pointer_set_destroy (vvar_name_set); + pointer_map_destroy (orig_nm_order); + orig_nm_order = NULL; } /* From the solution set of the use ref data flow problem, this function @@ -2001,11 +2034,11 @@ is_lr_live (tree lr, sbitmap bitvec, lrs_region_p region) static void get_num_live_lrs (sbitmap bitvec, lrs_region_p region, - size_t *ngr, size_t *nfr) + unsigned *ngr, unsigned *nfr) { int i, n; - int gr_pressure = 0; - int fr_pressure = 0; + unsigned gr_pressure = 0; + unsigned fr_pressure = 0; n = VEC_length (tree, region->refed_names); @@ -2035,13 +2068,13 @@ compute_reg_pressure_bb (basic_block bb, int bb_ridx, lrs_region_p region) { gimple_stmt_iterator gsi; - size_t bb_gr_pressure = 0; - size_t bb_fr_pressure = 0; + unsigned bb_gr_pressure = 0; + unsigned bb_fr_pressure = 0; for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { int id; - size_t ngr, nfr; + unsigned ngr, nfr; gimple stmt = gsi_stmt (gsi); id = get_stmt_idx_in_region (stmt); @@ -2056,7 +2089,7 @@ compute_reg_pressure_bb (basic_block bb, int bb_ridx, lrs_region_p region) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { int id; - size_t ngr, nfr; + unsigned ngr, nfr; gimple stmt = gsi_stmt (gsi); id = get_stmt_idx_in_region (stmt); @@ -2131,7 +2164,7 @@ compute_reg_pressure (lrs_region_p region) region->available_regs[i]++; } region->reg_pressure[i] = 0; - region->bb_reg_pressures[i] = XNEWVEC (size_t, region->num_bbs); + region->bb_reg_pressures[i] = XNEWVEC (unsigned, region->num_bbs); } for (i = 0; i < region->num_bbs; i++) @@ -2250,7 +2283,7 @@ set_vnm_bit_pos (tree vnm, int pos, lrs_region_p region) void **slot; slot = pointer_map_insert (region->vname_bit_pos_map, vnm); - *slot = (void *) pos; + *slot = (void *)(long) pos; } /* The function returns the bit position of virtual name VNM. */ @@ -2278,7 +2311,7 @@ set_vvar_bit_range (int first, int last, slot = pointer_map_insert (region->vvar_bit_range_map, vvar); range = (first << 16) + last; - *slot = (void *)range; + *slot = (void *)(long) range; } /* The function gets the bit position range for virtual variable @@ -2986,6 +3019,9 @@ reassoc_tree_opnd_cmp (const void *p1, const void *p2) opnd1 = *(const tree *) p1; opnd2 = *(const tree *) p2; + if (opnd1 == opnd2) + return 0; + tc1 = TREE_CODE (opnd1); tc2 = TREE_CODE (opnd2); if (tc1 != SSA_NAME && tc2 == SSA_NAME) @@ -3004,6 +3040,18 @@ reassoc_tree_opnd_cmp (const void *p1, const void *p2) bb1 = gimple_bb (stmt1); bb2 = gimple_bb (stmt2); + /* Both statements are not in the current basic block, use SSA names' + DECL_UIDs and versions to determine order. */ + if (bb1 != cur_bb && bb2 != cur_bb) + { + tree v1 = SSA_NAME_VAR (opnd1); + tree v2 = SSA_NAME_VAR (opnd2); + if (v1 == v2) + return SSA_NAME_VERSION (opnd1) - SSA_NAME_VERSION (opnd2); + else + return DECL_UID (v1) - DECL_UID (v2); + } + if (bb1 != cur_bb) return -1; if (bb2 != cur_bb) @@ -4221,15 +4269,18 @@ use_stmt_pos_cmp (const void *p1, const void *p2) { basic_block b1, b2; gimple s1, s2, phi, s; - use_operand_p phi_use; + use_operand_p phi_use, use; enum gimple_code c1, c2; int idx; edge use_edge; const use_operand_p u1 = *(const use_operand_p *)p1; const use_operand_p u2 = *(const use_operand_p *)p2; + ssa_op_iter iter; - s1 = u1->loc.stmt; - s2 = u2->loc.stmt; + gcc_assert(u1 != u2); + + s1 = USE_STMT (u1); + s2 = USE_STMT (u2); c1 = gimple_code (s1); c2 = gimple_code (s2); @@ -4243,11 +4294,57 @@ use_stmt_pos_cmp (const void *p1, const void *p2) b1 = gimple_bb (s1); b2 = gimple_bb (s2); - return b2->index - b1->index; + if (b2->index != b1->index) + return b2->index - b1->index; + + /* Uses occur in the same basic block. */ + if (s1 == s2) + { + /* The uses appear in the same statement, use positions to + determine order. We cannot order by SSA names because they + can refer to the same SSA name. */ + FOR_EACH_SSA_USE_OPERAND (use, s1, iter, SSA_OP_USE) + { + if (use == u1) + return -1; + if (use == u2) + return 1; + } + gcc_unreachable(); + } + else + { + /* This cannot happen. */ + gcc_unreachable(); + } } if (c1 == GIMPLE_PHI && c2 == GIMPLE_PHI) - return gimple_bb (s2)->index - gimple_bb (s1)->index; + { + if (gimple_bb (s2)->index - gimple_bb (s1)->index) + return gimple_bb (s2)->index - gimple_bb (s1)->index; + + if (s1 == s2) + { + /* The uses appear in the same PHI, use positions to + determine order. We cannot order by SSA names because they + can refer to the same SSA name. */ + gcc_assert(PHI_ARG_INDEX_FROM_USE (u1) - PHI_ARG_INDEX_FROM_USE (u2)); + return PHI_ARG_INDEX_FROM_USE (u1) - PHI_ARG_INDEX_FROM_USE (u2); + } + else + { + tree result1 = gimple_phi_result (s1); + tree result2 = gimple_phi_result (s2); + tree var1 = SSA_NAME_VAR (result1); + tree var2 = SSA_NAME_VAR (result2); + + if (var1 == var2) + return SSA_NAME_VERSION (result2) - SSA_NAME_VERSION (result1); + else + return DECL_UID (var2) - DECL_UID (var1); + } + } if (c1 == GIMPLE_PHI) { @@ -5263,7 +5360,7 @@ dump_refed_vvars (FILE *dump_file, lrs_region_p region) static void dump_use_ref_set (FILE *file, sbitmap bitvec, tree *mapping) { - size_t i = 0; + unsigned i = 0; sbitmap_iterator bi; bool first = true; @@ -5290,12 +5387,12 @@ static void dump_register_pressure (FILE *file, sbitmap bitvec, lrs_region_p region) { - size_t gr_pressure = 0; - size_t fr_pressure = 0; + unsigned gr_pressure = 0; + unsigned fr_pressure = 0; get_num_live_lrs (bitvec, region, &gr_pressure, &fr_pressure); - fprintf (file, " \n\t[REG PRESSURE: gr = %d, fr = %d]", + fprintf (file, " \n\t[REG PRESSURE: gr = %u, fr = %u]", gr_pressure, fr_pressure); } @@ -5328,7 +5425,7 @@ dump_data_flow_bb (FILE *file, basic_block bb, int bb_ridx, mapping); fprintf (file, "\n"); - fprintf (file, "\tREG PRESSURE: gr = %d, fr = %d\n", + fprintf (file, "\tREG PRESSURE: gr = %u, fr = %u\n", region->bb_reg_pressures[lrc_gr][bb_ridx], region->bb_reg_pressures[lrc_fr][bb_ridx]); @@ -5384,11 +5481,11 @@ dump_data_flow_result (lrs_region_p region, const char* phase) dump_refed_names (dump_file, region); dump_refed_vvars (dump_file, region); - fprintf (dump_file, "\tREG PRESSURE: gr = %d, fr = %d\n", + fprintf (dump_file, "\tREG PRESSURE: gr = %u, fr = %u\n", region->reg_pressure[lrc_gr], region->reg_pressure[lrc_fr]); - fprintf (dump_file, "\tAVAIL REGS: gr = %d, fr = %d\n", + fprintf (dump_file, "\tAVAIL REGS: gr = %u, fr = %u\n", region->available_regs[lrc_gr], region->available_regs[lrc_fr]); @@ -5418,7 +5515,7 @@ static void dump_rd_set (FILE *file, sbitmap bitvec, VEC(tree, heap) *refed_vnames) { - size_t i = 0; + unsigned i = 0; sbitmap_iterator bi; bool first = true; diff --git a/gcc-4.4.0/gcc/tree-ssa-reassoc.c b/gcc-4.4.0/gcc/tree-ssa-reassoc.c index d28e1b620..bbc5c730b 100644 --- a/gcc-4.4.0/gcc/tree-ssa-reassoc.c +++ b/gcc-4.4.0/gcc/tree-ssa-reassoc.c @@ -171,11 +171,15 @@ static struct typedef struct operand_entry { unsigned int rank; + int id; tree op; } *operand_entry_t; static alloc_pool operand_entry_pool; +/* This is used to assign a unique ID to each struct operand_entry + so that qsort results are identical on different hosts. */ +static int next_operand_entry_id; /* Starting rank number for a given basic block, so that we can rank operations using unmovable instructions in that BB based on the bb @@ -327,16 +331,31 @@ sort_by_operand_rank (const void *pa, const void *pb) to fold when added/multiplied//whatever are put next to each other. Since all constants have rank 0, order them by type. */ if (oeb->rank == 0 && oea->rank == 0) - return constant_type (oeb->op) - constant_type (oea->op); + { + if (constant_type (oeb->op) != constant_type (oea->op)) + return constant_type (oeb->op) - constant_type (oea->op); + else + /* To make sorting result stable, we use unique IDs to determine + order. */ + return oeb->id - oea->id; + } /* Lastly, make sure the versions that are the same go next to each other. We use SSA_NAME_VERSION because it's stable. */ if ((oeb->rank - oea->rank == 0) && TREE_CODE (oea->op) == SSA_NAME && TREE_CODE (oeb->op) == SSA_NAME) - return SSA_NAME_VERSION (oeb->op) - SSA_NAME_VERSION (oea->op); + { + if (SSA_NAME_VERSION (oeb->op) != SSA_NAME_VERSION (oea->op)) + return SSA_NAME_VERSION (oeb->op) - SSA_NAME_VERSION (oea->op); + else + return oeb->id - oea->id; + } - return oeb->rank - oea->rank; + if (oeb->rank != oea->rank) + return oeb->rank - oea->rank; + else + return oeb->id - oea->id; } /* Add an operand entry to *OPS for the tree operand OP. */ @@ -348,6 +367,7 @@ add_to_ops_vec (VEC(operand_entry_t, heap) **ops, tree op) oe->op = op; oe->rank = get_rank (op); + oe->id = next_operand_entry_id++; VEC_safe_push (operand_entry_t, heap, *ops, oe); } @@ -733,6 +753,7 @@ static void linearize_expr_tree (VEC(operand_entry_t, heap) **, gimple, /* Structure for tracking and counting operands. */ typedef struct oecount_s { int cnt; + int id; enum tree_code oecode; tree op; } oecount; @@ -770,7 +791,11 @@ oecount_cmp (const void *p1, const void *p2) { const oecount *c1 = (const oecount *)p1; const oecount *c2 = (const oecount *)p2; - return c1->cnt - c2->cnt; + if (c1->cnt != c2->cnt) + return c1->cnt - c2->cnt; + else + /* If counts are identical, use unique IDs to stabilize qsort. */ + return c1->id - c2->id; } /* Walks the linear chain with result *DEF searching for an operation @@ -952,6 +977,7 @@ undistribute_ops_list (enum tree_code opcode, VEC (operand_entry_t, heap) **subops; htab_t ctable; bool changed = false; + int next_oecount_id = 0; if (length <= 1 || opcode != PLUS_EXPR) @@ -1019,6 +1045,7 @@ undistribute_ops_list (enum tree_code opcode, size_t idx; c.oecode = oecode; c.cnt = 1; + c.id = next_oecount_id++; c.op = oe1->op; VEC_safe_push (oecount, heap, cvec, &c); idx = VEC_length (oecount, cvec) + 41; @@ -1980,6 +2007,7 @@ init_reassoc (void) operand_entry_pool = create_alloc_pool ("operand entry pool", sizeof (struct operand_entry), 30); + next_operand_entry_id = 0; /* Reverse RPO (Reverse Post Order) will give us something where deeper loops come later. */ -- cgit v1.2.3