diff options
Diffstat (limited to 'gcc-4.4.0/gcc/tree-ssa-reassoc.c')
-rw-r--r-- | gcc-4.4.0/gcc/tree-ssa-reassoc.c | 36 |
1 files changed, 32 insertions, 4 deletions
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. */ |