aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJing Yu <jingyu@google.com>2010-04-24 20:30:19 -0700
committerJing Yu <jingyu@google.com>2010-04-24 20:30:19 -0700
commitc2511ac51c9e6e6b8cd9900d6159d46718414012 (patch)
tree4f2d2810af6bf0b726c6f375258aab47ea9d8233
parent2c20a1914acb75c3c654893a490b96b2df2edc7a (diff)
downloadtoolchain_gcc-c2511ac51c9e6e6b8cd9900d6159d46718414012.tar.gz
toolchain_gcc-c2511ac51c9e6e6b8cd9900d6159d46718414012.tar.bz2
toolchain_gcc-c2511ac51c9e6e6b8cd9900d6159d46718414012.zip
Fix a few divergence bugs and security problem.
See README.google for details. Change-Id: Ifbee6d934426a60f34c7301a04fc442c6c75df22
-rw-r--r--gcc-4.4.0/README.google36
-rw-r--r--gcc-4.4.0/gcc/combine.c10
-rw-r--r--gcc-4.4.0/gcc/config/arm/eabi.h3
-rwxr-xr-xgcc-4.4.0/gcc/configure21
-rw-r--r--gcc-4.4.0/gcc/configure.ac19
-rw-r--r--gcc-4.4.0/gcc/tree-ssa-lrs.c277
-rw-r--r--gcc-4.4.0/gcc/tree-ssa-reassoc.c36
7 files changed, 299 insertions, 103 deletions
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. */