From f1665f5cd2038bf95e34e9ea577bd553c69b3563 Mon Sep 17 00:00:00 2001 From: Doug Kwan <dougkwan@google.com> Date: Fri, 16 Apr 2010 20:31:39 +0000 Subject: [PATCH] tree-ssa-reassoc.c (struct operand_entry): Add new field ID. 2010-04-16 Doug Kwan <dougkwan@google.com> * tree-ssa-reassoc.c (struct operand_entry): Add new field ID. (next_operand_entry_id): New static variable. (sort_by_operand_rank): Stabilize qsort comparator by using unique IDs. (add_to_ops_vec): Assigned unique ID to operand entry. (struct oecount_s): New field ID. (oecount_cmp): Stabilize qsort comparotor by using unique IDs. (undistribute_ops_list): Assign unique IDs to oecounts. (init_reassoc): reset next_operand_entry_id. From-SVN: r158449 --- gcc/ChangeLog | 11 +++++++++++ gcc/tree-ssa-reassoc.c | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8bf4532c71e3..66f0a9ed5dc8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2010-04-16 Doug Kwan <dougkwan@google.com> + + * tree-ssa-reassoc.c (struct operand_entry): Add new field ID. + (next_operand_entry_id): New static variable. + (sort_by_operand_rank): Stabilize qsort comparator by using unique IDs. + (add_to_ops_vec): Assigned unique ID to operand entry. + (struct oecount_s): New field ID. + (oecount_cmp): Stabilize qsort comparotor by using unique IDs. + (undistribute_ops_list): Assign unique IDs to oecounts. + (init_reassoc): reset next_operand_entry_id. + 2010-04-16 Doug Kwan <dougkwan@google.com> * config/i386/i386.md (*jcc_bt<mode>): Fix build breakage by adding diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 9a623bb3d59d..8d1c05c86e1e 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -172,11 +172,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 @@ -328,16 +332,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. */ @@ -349,6 +368,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); } @@ -740,6 +760,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; @@ -777,7 +798,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 @@ -959,6 +984,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) @@ -1026,6 +1052,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; @@ -2020,6 +2047,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. */ -- GitLab