diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c9e621740f0..f75bbe4862b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2010-10-08 Nathan Froyd + + * tree-ssa-sccvn.c (init_vn_nary_op_from_pieces): New function. + (init_vn_nary_op_from_op): New function. + (init_vn_nary_op_from_stmt): New function. + (vn_nary_op_lookup_1): New function. + (sizeof_vn_nary_op): New function. + (alloc_vn_nary_op_noinit): New function. + (alloc_vn_nary_op): New function. + (vn_nary_op_insert_into): New function. + (vn_nary_op_lookup_pieces): Rewrite to use new helper functions. + (vn_nary_op_lookup): Likewise. + (vn_nary_op_lookup_stmt): Likewise. + (vn_nary_op_insert_pieces): Likewise. + (vn_nary_op_insert): Likewise. + (vn_nary_op_insert_stmt): Likewise. + (copy_nary): Likewise. + (set_value_id_for_result): New function. + (set_hashtable_value_ids): Call it. + 2010-10-08 Nathan Froyd * config/fr30/fr30.c (TARGET_EXCEPT_UNWIND_INFO): Define. diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index b055a43e56e..ed56d1de673 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1698,6 +1698,81 @@ vn_nary_op_eq (const void *p1, const void *p2) return true; } +/* Initialize VNO from the pieces provided. */ + +static void +init_vn_nary_op_from_pieces (vn_nary_op_t vno, unsigned int length, + enum tree_code code, tree type, tree op0, + tree op1, tree op2, tree op3) +{ + vno->opcode = code; + vno->length = length; + vno->type = type; + vno->op[0] = op0; + vno->op[1] = op1; + vno->op[2] = op2; + vno->op[3] = op3; +} + +/* Initialize VNO from OP. */ + +static void +init_vn_nary_op_from_op (vn_nary_op_t vno, tree op) +{ + unsigned i; + + vno->opcode = TREE_CODE (op); + vno->length = TREE_CODE_LENGTH (TREE_CODE (op)); + vno->type = TREE_TYPE (op); + for (i = 0; i < vno->length; ++i) + vno->op[i] = TREE_OPERAND (op, i); +} + +/* Initialize VNO from STMT. */ + +static void +init_vn_nary_op_from_stmt (vn_nary_op_t vno, gimple stmt) +{ + unsigned i; + + vno->opcode = gimple_assign_rhs_code (stmt); + vno->length = gimple_num_ops (stmt) - 1; + vno->type = gimple_expr_type (stmt); + for (i = 0; i < vno->length; ++i) + vno->op[i] = gimple_op (stmt, i + 1); + if (vno->opcode == REALPART_EXPR + || vno->opcode == IMAGPART_EXPR + || vno->opcode == VIEW_CONVERT_EXPR) + vno->op[0] = TREE_OPERAND (vno->op[0], 0); +} + +/* Compute the hashcode for VNO and look for it in the hash table; + return the resulting value number if it exists in the hash table. + Return NULL_TREE if it does not exist in the hash table or if the + result field of the operation is NULL. VNRESULT will contain the + vn_nary_op_t from the hashtable if it exists. */ + +static tree +vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult) +{ + void **slot; + + if (vnresult) + *vnresult = NULL; + + vno->hashcode = vn_nary_op_compute_hash (vno); + slot = htab_find_slot_with_hash (current_info->nary, vno, vno->hashcode, + NO_INSERT); + if (!slot && current_info == optimistic_info) + slot = htab_find_slot_with_hash (valid_info->nary, vno, vno->hashcode, + NO_INSERT); + if (!slot) + return NULL_TREE; + if (vnresult) + *vnresult = (vn_nary_op_t)*slot; + return ((vn_nary_op_t)*slot)->result; +} + /* Lookup a n-ary operation by its pieces and return the resulting value number if it exists in the hash table. Return NULL_TREE if it does not exist in the hash table or if the result field of the operation @@ -1709,28 +1784,9 @@ vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code, tree type, tree op0, tree op1, tree op2, tree op3, vn_nary_op_t *vnresult) { - void **slot; struct vn_nary_op_s vno1; - if (vnresult) - *vnresult = NULL; - vno1.opcode = code; - vno1.length = length; - vno1.type = type; - vno1.op[0] = op0; - vno1.op[1] = op1; - vno1.op[2] = op2; - vno1.op[3] = op3; - vno1.hashcode = vn_nary_op_compute_hash (&vno1); - slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode, - NO_INSERT); - if (!slot && current_info == optimistic_info) - slot = htab_find_slot_with_hash (valid_info->nary, &vno1, vno1.hashcode, - NO_INSERT); - if (!slot) - return NULL_TREE; - if (vnresult) - *vnresult = (vn_nary_op_t)*slot; - return ((vn_nary_op_t)*slot)->result; + init_vn_nary_op_from_pieces (&vno1, length, code, type, op0, op1, op2, op3); + return vn_nary_op_lookup_1 (&vno1, vnresult); } /* Lookup OP in the current hash table, and return the resulting value @@ -1742,28 +1798,9 @@ vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code, tree vn_nary_op_lookup (tree op, vn_nary_op_t *vnresult) { - void **slot; struct vn_nary_op_s vno1; - unsigned i; - - if (vnresult) - *vnresult = NULL; - vno1.opcode = TREE_CODE (op); - vno1.length = TREE_CODE_LENGTH (TREE_CODE (op)); - vno1.type = TREE_TYPE (op); - for (i = 0; i < vno1.length; ++i) - vno1.op[i] = TREE_OPERAND (op, i); - vno1.hashcode = vn_nary_op_compute_hash (&vno1); - slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode, - NO_INSERT); - if (!slot && current_info == optimistic_info) - slot = htab_find_slot_with_hash (valid_info->nary, &vno1, vno1.hashcode, - NO_INSERT); - if (!slot) - return NULL_TREE; - if (vnresult) - *vnresult = (vn_nary_op_t)*slot; - return ((vn_nary_op_t)*slot)->result; + init_vn_nary_op_from_op (&vno1, op); + return vn_nary_op_lookup_1 (&vno1, vnresult); } /* Lookup the rhs of STMT in the current hash table, and return the resulting @@ -1774,32 +1811,59 @@ vn_nary_op_lookup (tree op, vn_nary_op_t *vnresult) tree vn_nary_op_lookup_stmt (gimple stmt, vn_nary_op_t *vnresult) { - void **slot; struct vn_nary_op_s vno1; - unsigned i; + init_vn_nary_op_from_stmt (&vno1, stmt); + return vn_nary_op_lookup_1 (&vno1, vnresult); +} - if (vnresult) - *vnresult = NULL; - vno1.opcode = gimple_assign_rhs_code (stmt); - vno1.length = gimple_num_ops (stmt) - 1; - vno1.type = gimple_expr_type (stmt); - for (i = 0; i < vno1.length; ++i) - vno1.op[i] = gimple_op (stmt, i + 1); - if (vno1.opcode == REALPART_EXPR - || vno1.opcode == IMAGPART_EXPR - || vno1.opcode == VIEW_CONVERT_EXPR) - vno1.op[0] = TREE_OPERAND (vno1.op[0], 0); - vno1.hashcode = vn_nary_op_compute_hash (&vno1); - slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode, - NO_INSERT); - if (!slot && current_info == optimistic_info) - slot = htab_find_slot_with_hash (valid_info->nary, &vno1, vno1.hashcode, - NO_INSERT); - if (!slot) - return NULL_TREE; - if (vnresult) - *vnresult = (vn_nary_op_t)*slot; - return ((vn_nary_op_t)*slot)->result; +/* Return the size of a vn_nary_op_t with LENGTH operands. */ + +static size_t +sizeof_vn_nary_op (unsigned int length) +{ + return sizeof (struct vn_nary_op_s) - sizeof (tree) * (4 - length); +} + +/* Allocate a vn_nary_op_t with LENGTH operands on STACK. */ + +static vn_nary_op_t +alloc_vn_nary_op_noinit (unsigned int length, struct obstack *stack) +{ + return (vn_nary_op_t) obstack_alloc (stack, sizeof_vn_nary_op (length)); +} + +/* Allocate and initialize a vn_nary_op_t on CURRENT_INFO's + obstack. */ + +static vn_nary_op_t +alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id) +{ + vn_nary_op_t vno1 = alloc_vn_nary_op_noinit (length, + ¤t_info->nary_obstack); + + vno1->value_id = value_id; + vno1->length = length; + vno1->result = result; + + return vno1; +} + +/* Insert VNO into TABLE. If COMPUTE_HASH is true, then compute + VNO->HASHCODE first. */ + +static vn_nary_op_t +vn_nary_op_insert_into (vn_nary_op_t vno, htab_t table, bool compute_hash) +{ + void **slot; + + if (compute_hash) + vno->hashcode = vn_nary_op_compute_hash (vno); + + slot = htab_find_slot_with_hash (table, vno, vno->hashcode, INSERT); + gcc_assert (!*slot); + + *slot = vno; + return vno; } /* Insert a n-ary operation into the current hash table using it's @@ -1813,33 +1877,11 @@ vn_nary_op_insert_pieces (unsigned int length, enum tree_code code, tree result, unsigned int value_id) { - void **slot; vn_nary_op_t vno1; - vno1 = (vn_nary_op_t) obstack_alloc (¤t_info->nary_obstack, - (sizeof (struct vn_nary_op_s) - - sizeof (tree) * (4 - length))); - vno1->value_id = value_id; - vno1->opcode = code; - vno1->length = length; - vno1->type = type; - if (length >= 1) - vno1->op[0] = op0; - if (length >= 2) - vno1->op[1] = op1; - if (length >= 3) - vno1->op[2] = op2; - if (length >= 4) - vno1->op[3] = op3; - vno1->result = result; - vno1->hashcode = vn_nary_op_compute_hash (vno1); - slot = htab_find_slot_with_hash (current_info->nary, vno1, vno1->hashcode, - INSERT); - gcc_assert (!*slot); - - *slot = vno1; - return vno1; - + vno1 = alloc_vn_nary_op (length, result, value_id); + init_vn_nary_op_from_pieces (vno1, length, code, type, op0, op1, op2, op3); + return vn_nary_op_insert_into (vno1, current_info->nary, true); } /* Insert OP into the current hash table with a value number of @@ -1850,27 +1892,11 @@ vn_nary_op_t vn_nary_op_insert (tree op, tree result) { unsigned length = TREE_CODE_LENGTH (TREE_CODE (op)); - void **slot; vn_nary_op_t vno1; - unsigned i; - vno1 = (vn_nary_op_t) obstack_alloc (¤t_info->nary_obstack, - (sizeof (struct vn_nary_op_s) - - sizeof (tree) * (4 - length))); - vno1->value_id = VN_INFO (result)->value_id; - vno1->opcode = TREE_CODE (op); - vno1->length = length; - vno1->type = TREE_TYPE (op); - for (i = 0; i < vno1->length; ++i) - vno1->op[i] = TREE_OPERAND (op, i); - vno1->result = result; - vno1->hashcode = vn_nary_op_compute_hash (vno1); - slot = htab_find_slot_with_hash (current_info->nary, vno1, vno1->hashcode, - INSERT); - gcc_assert (!*slot); - - *slot = vno1; - return vno1; + vno1 = alloc_vn_nary_op (length, result, VN_INFO (result)->value_id); + init_vn_nary_op_from_op (vno1, op); + return vn_nary_op_insert_into (vno1, current_info->nary, true); } /* Insert the rhs of STMT into the current hash table with a value number of @@ -1880,31 +1906,11 @@ vn_nary_op_t vn_nary_op_insert_stmt (gimple stmt, tree result) { unsigned length = gimple_num_ops (stmt) - 1; - void **slot; vn_nary_op_t vno1; - unsigned i; - vno1 = (vn_nary_op_t) obstack_alloc (¤t_info->nary_obstack, - (sizeof (struct vn_nary_op_s) - - sizeof (tree) * (4 - length))); - vno1->value_id = VN_INFO (result)->value_id; - vno1->opcode = gimple_assign_rhs_code (stmt); - vno1->length = length; - vno1->type = gimple_expr_type (stmt); - for (i = 0; i < vno1->length; ++i) - vno1->op[i] = gimple_op (stmt, i + 1); - if (vno1->opcode == REALPART_EXPR - || vno1->opcode == IMAGPART_EXPR - || vno1->opcode == VIEW_CONVERT_EXPR) - vno1->op[0] = TREE_OPERAND (vno1->op[0], 0); - vno1->result = result; - vno1->hashcode = vn_nary_op_compute_hash (vno1); - slot = htab_find_slot_with_hash (current_info->nary, vno1, vno1->hashcode, - INSERT); - gcc_assert (!*slot); - - *slot = vno1; - return vno1; + vno1 = alloc_vn_nary_op (length, result, VN_INFO (result)->value_id); + init_vn_nary_op_from_stmt (vno1, stmt); + return vn_nary_op_insert_into (vno1, current_info->nary, true); } /* Compute a hashcode for PHI operation VP1 and return it. */ @@ -3043,14 +3049,11 @@ sort_scc (VEC (tree, heap) *scc) static void copy_nary (vn_nary_op_t onary, vn_tables_t info) { - size_t size = (sizeof (struct vn_nary_op_s) - - sizeof (tree) * (4 - onary->length)); - vn_nary_op_t nary = (vn_nary_op_t) obstack_alloc (&info->nary_obstack, size); - void **slot; + size_t size = sizeof_vn_nary_op (onary->length); + vn_nary_op_t nary = alloc_vn_nary_op_noinit (onary->length, + &info->nary_obstack); memcpy (nary, onary, size); - slot = htab_find_slot_with_hash (info->nary, nary, nary->hashcode, INSERT); - gcc_assert (!*slot); - *slot = nary; + vn_nary_op_insert_into (nary, info->nary, false); } /* Insert the no longer used phi OPHI to the hash INFO. */ @@ -3414,6 +3417,20 @@ free_scc_vn (void) XDELETE (optimistic_info); } +/* Set *ID if we computed something useful in RESULT. */ + +static void +set_value_id_for_result (tree result, unsigned int *id) +{ + if (result) + { + if (TREE_CODE (result) == SSA_NAME) + *id = VN_INFO (result)->value_id; + else if (is_gimple_min_invariant (result)) + *id = get_or_alloc_constant_value_id (result); + } +} + /* Set the value ids in the valid hash tables. */ static void @@ -3429,39 +3446,15 @@ set_hashtable_value_ids (void) FOR_EACH_HTAB_ELEMENT (valid_info->nary, vno, vn_nary_op_t, hi) - { - if (vno->result) - { - if (TREE_CODE (vno->result) == SSA_NAME) - vno->value_id = VN_INFO (vno->result)->value_id; - else if (is_gimple_min_invariant (vno->result)) - vno->value_id = get_or_alloc_constant_value_id (vno->result); - } - } + set_value_id_for_result (vno->result, &vno->value_id); FOR_EACH_HTAB_ELEMENT (valid_info->phis, vp, vn_phi_t, hi) - { - if (vp->result) - { - if (TREE_CODE (vp->result) == SSA_NAME) - vp->value_id = VN_INFO (vp->result)->value_id; - else if (is_gimple_min_invariant (vp->result)) - vp->value_id = get_or_alloc_constant_value_id (vp->result); - } - } + set_value_id_for_result (vp->result, &vp->value_id); FOR_EACH_HTAB_ELEMENT (valid_info->references, vr, vn_reference_t, hi) - { - if (vr->result) - { - if (TREE_CODE (vr->result) == SSA_NAME) - vr->value_id = VN_INFO (vr->result)->value_id; - else if (is_gimple_min_invariant (vr->result)) - vr->value_id = get_or_alloc_constant_value_id (vr->result); - } - } + set_value_id_for_result (vr->result, &vr->value_id); } /* Do SCCVN. Returns true if it finished, false if we bailed out