Commit fd4a760e by Richard Guenther Committed by Richard Biener

tree-ssa-dom.c (struct edge_info): Use a VEC for the list of conditional equivalences.

2010-08-17  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-dom.c (struct edge_info): Use a VEC for the
	list of conditional equivalences.
	(free_all_edge_infos): Adjust.
	(record_equivalences_from_incoming_edge): Likewise.
	(record_cond): Likewise.
	(build_and_record_new_cond): Likewise.
	(record_conditions): Likewise.
	(dom_opt_leave_block): Likewise.

From-SVN: r163302
parent b17b584f
2010-08-17 Richard Guenther <rguenther@suse.de>
* tree-ssa-dom.c (struct edge_info): Use a VEC for the
list of conditional equivalences.
(free_all_edge_infos): Adjust.
(record_equivalences_from_incoming_edge): Likewise.
(record_cond): Likewise.
(build_and_record_new_cond): Likewise.
(record_conditions): Likewise.
(dom_opt_leave_block): Likewise.
2010-08-17 Kai Tietz <kai.tietz@onevision.com> 2010-08-17 Kai Tietz <kai.tietz@onevision.com>
* doc/invoke.texi (ms-extension): Add documentation. * doc/invoke.texi (ms-extension): Add documentation.
......
...@@ -71,11 +71,14 @@ struct hashable_expr ...@@ -71,11 +71,14 @@ struct hashable_expr
/* Structure for recording known values of a conditional expression /* Structure for recording known values of a conditional expression
at the exits from its block. */ at the exits from its block. */
struct cond_equivalence typedef struct cond_equivalence_s
{ {
struct hashable_expr cond; struct hashable_expr cond;
tree value; tree value;
}; } cond_equivalence;
DEF_VEC_O(cond_equivalence);
DEF_VEC_ALLOC_O(cond_equivalence,heap);
/* Structure for recording edge equivalences as well as any pending /* Structure for recording edge equivalences as well as any pending
edge redirections during the dominator optimizer. edge redirections during the dominator optimizer.
...@@ -99,11 +102,8 @@ struct edge_info ...@@ -99,11 +102,8 @@ struct edge_info
tree rhs; tree rhs;
/* Traversing an edge may also indicate one or more particular conditions /* Traversing an edge may also indicate one or more particular conditions
are true or false. The number of recorded conditions can vary, but are true or false. */
can be determined by the condition's code. So we have an array VEC(cond_equivalence, heap) *cond_equivalences;
and its maximum index rather than use a varray. */
struct cond_equivalence *cond_equivalences;
unsigned int max_cond_equivalences;
}; };
/* Hash table with expressions made available during the renaming process. /* Hash table with expressions made available during the renaming process.
...@@ -179,7 +179,7 @@ static hashval_t avail_expr_hash (const void *); ...@@ -179,7 +179,7 @@ static hashval_t avail_expr_hash (const void *);
static hashval_t real_avail_expr_hash (const void *); static hashval_t real_avail_expr_hash (const void *);
static int avail_expr_eq (const void *, const void *); static int avail_expr_eq (const void *, const void *);
static void htab_statistics (FILE *, htab_t); static void htab_statistics (FILE *, htab_t);
static void record_cond (struct cond_equivalence *); static void record_cond (cond_equivalence *);
static void record_const_or_copy (tree, tree); static void record_const_or_copy (tree, tree);
static void record_equality (tree, tree); static void record_equality (tree, tree);
static void record_equivalences_from_phis (basic_block); static void record_equivalences_from_phis (basic_block);
...@@ -636,7 +636,7 @@ free_all_edge_infos (void) ...@@ -636,7 +636,7 @@ free_all_edge_infos (void)
if (edge_info) if (edge_info)
{ {
if (edge_info->cond_equivalences) if (edge_info->cond_equivalences)
free (edge_info->cond_equivalences); VEC_free (cond_equivalence, heap, edge_info->cond_equivalences);
free (edge_info); free (edge_info);
e->aux = NULL; e->aux = NULL;
} }
...@@ -1059,14 +1059,14 @@ record_equivalences_from_incoming_edge (basic_block bb) ...@@ -1059,14 +1059,14 @@ record_equivalences_from_incoming_edge (basic_block bb)
{ {
tree lhs = edge_info->lhs; tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs; tree rhs = edge_info->rhs;
struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences; cond_equivalence *eq;
if (lhs) if (lhs)
record_equality (lhs, rhs); record_equality (lhs, rhs);
if (cond_equivalences) for (i = 0; VEC_iterate (cond_equivalence,
for (i = 0; i < edge_info->max_cond_equivalences; i++) edge_info->cond_equivalences, i, eq); ++i)
record_cond (&cond_equivalences[i]); record_cond (eq);
} }
} }
} }
...@@ -1114,7 +1114,7 @@ htab_statistics (FILE *file, htab_t htab) ...@@ -1114,7 +1114,7 @@ htab_statistics (FILE *file, htab_t htab)
boolean value. */ boolean value. */
static void static void
record_cond (struct cond_equivalence *p) record_cond (cond_equivalence *p)
{ {
struct expr_hash_elt *element = XCNEW (struct expr_hash_elt); struct expr_hash_elt *element = XCNEW (struct expr_hash_elt);
void **slot; void **slot;
...@@ -1140,14 +1140,15 @@ record_cond (struct cond_equivalence *p) ...@@ -1140,14 +1140,15 @@ record_cond (struct cond_equivalence *p)
} }
/* Build a cond_equivalence record indicating that the comparison /* Build a cond_equivalence record indicating that the comparison
CODE holds between operands OP0 and OP1. */ CODE holds between operands OP0 and OP1 and push it to **P. */
static void static void
build_and_record_new_cond (enum tree_code code, build_and_record_new_cond (enum tree_code code,
tree op0, tree op1, tree op0, tree op1,
struct cond_equivalence *p) VEC(cond_equivalence, heap) **p)
{ {
struct hashable_expr *cond = &p->cond; cond_equivalence c;
struct hashable_expr *cond = &c.cond;
gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison); gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
...@@ -1157,7 +1158,8 @@ build_and_record_new_cond (enum tree_code code, ...@@ -1157,7 +1158,8 @@ build_and_record_new_cond (enum tree_code code,
cond->ops.binary.opnd0 = op0; cond->ops.binary.opnd0 = op0;
cond->ops.binary.opnd1 = op1; cond->ops.binary.opnd1 = op1;
p->value = boolean_true_node; c.value = boolean_true_node;
VEC_safe_push (cond_equivalence, heap, *p, &c);
} }
/* Record that COND is true and INVERTED is false into the edge information /* Record that COND is true and INVERTED is false into the edge information
...@@ -1170,6 +1172,7 @@ static void ...@@ -1170,6 +1172,7 @@ static void
record_conditions (struct edge_info *edge_info, tree cond, tree inverted) record_conditions (struct edge_info *edge_info, tree cond, tree inverted)
{ {
tree op0, op1; tree op0, op1;
cond_equivalence c;
if (!COMPARISON_CLASS_P (cond)) if (!COMPARISON_CLASS_P (cond))
return; return;
...@@ -1183,125 +1186,96 @@ record_conditions (struct edge_info *edge_info, tree cond, tree inverted) ...@@ -1183,125 +1186,96 @@ record_conditions (struct edge_info *edge_info, tree cond, tree inverted)
case GT_EXPR: case GT_EXPR:
if (FLOAT_TYPE_P (TREE_TYPE (op0))) if (FLOAT_TYPE_P (TREE_TYPE (op0)))
{ {
edge_info->max_cond_equivalences = 6;
edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 6);
build_and_record_new_cond (ORDERED_EXPR, op0, op1, build_and_record_new_cond (ORDERED_EXPR, op0, op1,
&edge_info->cond_equivalences[4]); &edge_info->cond_equivalences);
build_and_record_new_cond (LTGT_EXPR, op0, op1, build_and_record_new_cond (LTGT_EXPR, op0, op1,
&edge_info->cond_equivalences[5]); &edge_info->cond_equivalences);
}
else
{
edge_info->max_cond_equivalences = 4;
edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
} }
build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR
? LE_EXPR : GE_EXPR), ? LE_EXPR : GE_EXPR),
op0, op1, &edge_info->cond_equivalences[2]); op0, op1, &edge_info->cond_equivalences);
build_and_record_new_cond (NE_EXPR, op0, op1, build_and_record_new_cond (NE_EXPR, op0, op1,
&edge_info->cond_equivalences[3]); &edge_info->cond_equivalences);
break; break;
case GE_EXPR: case GE_EXPR:
case LE_EXPR: case LE_EXPR:
if (FLOAT_TYPE_P (TREE_TYPE (op0))) if (FLOAT_TYPE_P (TREE_TYPE (op0)))
{ {
edge_info->max_cond_equivalences = 3;
edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 3);
build_and_record_new_cond (ORDERED_EXPR, op0, op1, build_and_record_new_cond (ORDERED_EXPR, op0, op1,
&edge_info->cond_equivalences[2]); &edge_info->cond_equivalences);
}
else
{
edge_info->max_cond_equivalences = 2;
edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 2);
} }
break; break;
case EQ_EXPR: case EQ_EXPR:
if (FLOAT_TYPE_P (TREE_TYPE (op0))) if (FLOAT_TYPE_P (TREE_TYPE (op0)))
{ {
edge_info->max_cond_equivalences = 5;
edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 5);
build_and_record_new_cond (ORDERED_EXPR, op0, op1, build_and_record_new_cond (ORDERED_EXPR, op0, op1,
&edge_info->cond_equivalences[4]); &edge_info->cond_equivalences);
}
else
{
edge_info->max_cond_equivalences = 4;
edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
} }
build_and_record_new_cond (LE_EXPR, op0, op1, build_and_record_new_cond (LE_EXPR, op0, op1,
&edge_info->cond_equivalences[2]); &edge_info->cond_equivalences);
build_and_record_new_cond (GE_EXPR, op0, op1, build_and_record_new_cond (GE_EXPR, op0, op1,
&edge_info->cond_equivalences[3]); &edge_info->cond_equivalences);
break; break;
case UNORDERED_EXPR: case UNORDERED_EXPR:
edge_info->max_cond_equivalences = 8;
edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 8);
build_and_record_new_cond (NE_EXPR, op0, op1, build_and_record_new_cond (NE_EXPR, op0, op1,
&edge_info->cond_equivalences[2]); &edge_info->cond_equivalences);
build_and_record_new_cond (UNLE_EXPR, op0, op1, build_and_record_new_cond (UNLE_EXPR, op0, op1,
&edge_info->cond_equivalences[3]); &edge_info->cond_equivalences);
build_and_record_new_cond (UNGE_EXPR, op0, op1, build_and_record_new_cond (UNGE_EXPR, op0, op1,
&edge_info->cond_equivalences[4]); &edge_info->cond_equivalences);
build_and_record_new_cond (UNEQ_EXPR, op0, op1, build_and_record_new_cond (UNEQ_EXPR, op0, op1,
&edge_info->cond_equivalences[5]); &edge_info->cond_equivalences);
build_and_record_new_cond (UNLT_EXPR, op0, op1, build_and_record_new_cond (UNLT_EXPR, op0, op1,
&edge_info->cond_equivalences[6]); &edge_info->cond_equivalences);
build_and_record_new_cond (UNGT_EXPR, op0, op1, build_and_record_new_cond (UNGT_EXPR, op0, op1,
&edge_info->cond_equivalences[7]); &edge_info->cond_equivalences);
break; break;
case UNLT_EXPR: case UNLT_EXPR:
case UNGT_EXPR: case UNGT_EXPR:
edge_info->max_cond_equivalences = 4;
edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR
? UNLE_EXPR : UNGE_EXPR), ? UNLE_EXPR : UNGE_EXPR),
op0, op1, &edge_info->cond_equivalences[2]); op0, op1, &edge_info->cond_equivalences);
build_and_record_new_cond (NE_EXPR, op0, op1, build_and_record_new_cond (NE_EXPR, op0, op1,
&edge_info->cond_equivalences[3]); &edge_info->cond_equivalences);
break; break;
case UNEQ_EXPR: case UNEQ_EXPR:
edge_info->max_cond_equivalences = 4;
edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
build_and_record_new_cond (UNLE_EXPR, op0, op1, build_and_record_new_cond (UNLE_EXPR, op0, op1,
&edge_info->cond_equivalences[2]); &edge_info->cond_equivalences);
build_and_record_new_cond (UNGE_EXPR, op0, op1, build_and_record_new_cond (UNGE_EXPR, op0, op1,
&edge_info->cond_equivalences[3]); &edge_info->cond_equivalences);
break; break;
case LTGT_EXPR: case LTGT_EXPR:
edge_info->max_cond_equivalences = 4;
edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
build_and_record_new_cond (NE_EXPR, op0, op1, build_and_record_new_cond (NE_EXPR, op0, op1,
&edge_info->cond_equivalences[2]); &edge_info->cond_equivalences);
build_and_record_new_cond (ORDERED_EXPR, op0, op1, build_and_record_new_cond (ORDERED_EXPR, op0, op1,
&edge_info->cond_equivalences[3]); &edge_info->cond_equivalences);
break; break;
default: default:
edge_info->max_cond_equivalences = 2;
edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 2);
break; break;
} }
/* Now store the original true and false conditions into the first /* Now store the original true and false conditions into the first
two slots. */ two slots. */
initialize_expr_from_cond (cond, &edge_info->cond_equivalences[0].cond); initialize_expr_from_cond (cond, &c.cond);
edge_info->cond_equivalences[0].value = boolean_true_node; c.value = boolean_true_node;
VEC_safe_push (cond_equivalence, heap, edge_info->cond_equivalences, &c);
/* It is possible for INVERTED to be the negation of a comparison, /* It is possible for INVERTED to be the negation of a comparison,
and not a valid RHS or GIMPLE_COND condition. This happens because and not a valid RHS or GIMPLE_COND condition. This happens because
invert_truthvalue may return such an expression when asked to invert invert_truthvalue may return such an expression when asked to invert
a floating-point comparison. These comparisons are not assumed to a floating-point comparison. These comparisons are not assumed to
obey the trichotomy law. */ obey the trichotomy law. */
initialize_expr_from_cond (inverted, &edge_info->cond_equivalences[1].cond); initialize_expr_from_cond (inverted, &c.cond);
edge_info->cond_equivalences[1].value = boolean_false_node; c.value = boolean_false_node;
VEC_safe_push (cond_equivalence, heap, edge_info->cond_equivalences, &c);
} }
/* A helper function for record_const_or_copy and record_equality. /* A helper function for record_const_or_copy and record_equality.
...@@ -1749,7 +1723,7 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb) ...@@ -1749,7 +1723,7 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
our equivalence tables. */ our equivalence tables. */
if (edge_info) if (edge_info)
{ {
struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences; cond_equivalence *eq;
tree lhs = edge_info->lhs; tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs; tree rhs = edge_info->rhs;
...@@ -1759,9 +1733,9 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb) ...@@ -1759,9 +1733,9 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
/* If we have 0 = COND or 1 = COND equivalences, record them /* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */ into our expression hash tables. */
if (cond_equivalences) for (i = 0; VEC_iterate (cond_equivalence,
for (i = 0; i < edge_info->max_cond_equivalences; i++) edge_info->cond_equivalences, i, eq); ++i)
record_cond (&cond_equivalences[i]); record_cond (eq);
} }
dom_thread_across_edge (walk_data, true_edge); dom_thread_across_edge (walk_data, true_edge);
...@@ -1784,7 +1758,7 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb) ...@@ -1784,7 +1758,7 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
our equivalence tables. */ our equivalence tables. */
if (edge_info) if (edge_info)
{ {
struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences; cond_equivalence *eq;
tree lhs = edge_info->lhs; tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs; tree rhs = edge_info->rhs;
...@@ -1794,9 +1768,9 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb) ...@@ -1794,9 +1768,9 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
/* If we have 0 = COND or 1 = COND equivalences, record them /* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */ into our expression hash tables. */
if (cond_equivalences) for (i = 0; VEC_iterate (cond_equivalence,
for (i = 0; i < edge_info->max_cond_equivalences; i++) edge_info->cond_equivalences, i, eq); ++i)
record_cond (&cond_equivalences[i]); record_cond (eq);
} }
/* Now thread the edge. */ /* Now thread the edge. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment