* [PATCH] Use a VEC for the list of conditional equivalences in DOM
@ 2010-08-17 9:56 Richard Guenther
0 siblings, 0 replies; only message in thread
From: Richard Guenther @ 2010-08-17 9:56 UTC (permalink / raw)
To: gcc-patches
This will make the code easier to understand and extend. I'm touching
it because of the cond-expr predicate stuff.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
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.
Index: gcc/tree-ssa-dom.c
===================================================================
*** gcc/tree-ssa-dom.c (revision 163281)
--- gcc/tree-ssa-dom.c (working copy)
*************** struct hashable_expr
*** 71,81 ****
/* Structure for recording known values of a conditional expression
at the exits from its block. */
! struct cond_equivalence
{
struct hashable_expr cond;
tree value;
! };
/* Structure for recording edge equivalences as well as any pending
edge redirections during the dominator optimizer.
--- 71,84 ----
/* Structure for recording known values of a conditional expression
at the exits from its block. */
! typedef struct cond_equivalence_s
{
struct hashable_expr cond;
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
edge redirections during the dominator optimizer.
*************** struct edge_info
*** 99,109 ****
tree rhs;
/* Traversing an edge may also indicate one or more particular conditions
! are true or false. The number of recorded conditions can vary, but
! can be determined by the condition's code. So we have an array
! 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.
--- 102,109 ----
tree rhs;
/* Traversing an edge may also indicate one or more particular conditions
! are true or false. */
! VEC(cond_equivalence, heap) *cond_equivalences;
};
/* Hash table with expressions made available during the renaming process.
*************** static hashval_t avail_expr_hash (const
*** 179,185 ****
static hashval_t real_avail_expr_hash (const void *);
static int avail_expr_eq (const void *, const void *);
static void htab_statistics (FILE *, htab_t);
! static void record_cond (struct cond_equivalence *);
static void record_const_or_copy (tree, tree);
static void record_equality (tree, tree);
static void record_equivalences_from_phis (basic_block);
--- 179,185 ----
static hashval_t real_avail_expr_hash (const void *);
static int avail_expr_eq (const void *, const void *);
static void htab_statistics (FILE *, htab_t);
! static void record_cond (cond_equivalence *);
static void record_const_or_copy (tree, tree);
static void record_equality (tree, tree);
static void record_equivalences_from_phis (basic_block);
*************** free_all_edge_infos (void)
*** 636,642 ****
if (edge_info)
{
if (edge_info->cond_equivalences)
! free (edge_info->cond_equivalences);
free (edge_info);
e->aux = NULL;
}
--- 636,642 ----
if (edge_info)
{
if (edge_info->cond_equivalences)
! VEC_free (cond_equivalence, heap, edge_info->cond_equivalences);
free (edge_info);
e->aux = NULL;
}
*************** record_equivalences_from_incoming_edge (
*** 1059,1072 ****
{
tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs;
! struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences;
if (lhs)
record_equality (lhs, rhs);
! if (cond_equivalences)
! for (i = 0; i < edge_info->max_cond_equivalences; i++)
! record_cond (&cond_equivalences[i]);
}
}
}
--- 1059,1072 ----
{
tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs;
! cond_equivalence *eq;
if (lhs)
record_equality (lhs, rhs);
! for (i = 0; VEC_iterate (cond_equivalence,
! edge_info->cond_equivalences, i, eq); ++i)
! record_cond (eq);
}
}
}
*************** htab_statistics (FILE *file, htab_t htab
*** 1114,1120 ****
boolean value. */
static void
! record_cond (struct cond_equivalence *p)
{
struct expr_hash_elt *element = XCNEW (struct expr_hash_elt);
void **slot;
--- 1114,1120 ----
boolean value. */
static void
! record_cond (cond_equivalence *p)
{
struct expr_hash_elt *element = XCNEW (struct expr_hash_elt);
void **slot;
*************** record_cond (struct cond_equivalence *p)
*** 1140,1153 ****
}
/* Build a cond_equivalence record indicating that the comparison
! CODE holds between operands OP0 and OP1. */
static void
build_and_record_new_cond (enum tree_code code,
tree op0, tree op1,
! struct cond_equivalence *p)
{
! struct hashable_expr *cond = &p->cond;
gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
--- 1140,1154 ----
}
/* Build a cond_equivalence record indicating that the comparison
! CODE holds between operands OP0 and OP1 and push it to **P. */
static void
build_and_record_new_cond (enum tree_code code,
tree op0, tree op1,
! VEC(cond_equivalence, heap) **p)
{
! cond_equivalence c;
! struct hashable_expr *cond = &c.cond;
gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
*************** build_and_record_new_cond (enum tree_cod
*** 1157,1163 ****
cond->ops.binary.opnd0 = op0;
cond->ops.binary.opnd1 = op1;
! p->value = boolean_true_node;
}
/* Record that COND is true and INVERTED is false into the edge information
--- 1158,1165 ----
cond->ops.binary.opnd0 = op0;
cond->ops.binary.opnd1 = op1;
! 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
*************** static void
*** 1170,1175 ****
--- 1172,1178 ----
record_conditions (struct edge_info *edge_info, tree cond, tree inverted)
{
tree op0, op1;
+ cond_equivalence c;
if (!COMPARISON_CLASS_P (cond))
return;
*************** record_conditions (struct edge_info *edg
*** 1183,1307 ****
case GT_EXPR:
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,
! &edge_info->cond_equivalences[4]);
build_and_record_new_cond (LTGT_EXPR, op0, op1,
! &edge_info->cond_equivalences[5]);
! }
! 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
? LE_EXPR : GE_EXPR),
! op0, op1, &edge_info->cond_equivalences[2]);
build_and_record_new_cond (NE_EXPR, op0, op1,
! &edge_info->cond_equivalences[3]);
break;
case GE_EXPR:
case LE_EXPR:
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,
! &edge_info->cond_equivalences[2]);
! }
! else
! {
! edge_info->max_cond_equivalences = 2;
! edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 2);
}
break;
case EQ_EXPR:
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,
! &edge_info->cond_equivalences[4]);
! }
! 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,
! &edge_info->cond_equivalences[2]);
build_and_record_new_cond (GE_EXPR, op0, op1,
! &edge_info->cond_equivalences[3]);
break;
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,
! &edge_info->cond_equivalences[2]);
build_and_record_new_cond (UNLE_EXPR, op0, op1,
! &edge_info->cond_equivalences[3]);
build_and_record_new_cond (UNGE_EXPR, op0, op1,
! &edge_info->cond_equivalences[4]);
build_and_record_new_cond (UNEQ_EXPR, op0, op1,
! &edge_info->cond_equivalences[5]);
build_and_record_new_cond (UNLT_EXPR, op0, op1,
! &edge_info->cond_equivalences[6]);
build_and_record_new_cond (UNGT_EXPR, op0, op1,
! &edge_info->cond_equivalences[7]);
break;
case UNLT_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
? UNLE_EXPR : UNGE_EXPR),
! op0, op1, &edge_info->cond_equivalences[2]);
build_and_record_new_cond (NE_EXPR, op0, op1,
! &edge_info->cond_equivalences[3]);
break;
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,
! &edge_info->cond_equivalences[2]);
build_and_record_new_cond (UNGE_EXPR, op0, op1,
! &edge_info->cond_equivalences[3]);
break;
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,
! &edge_info->cond_equivalences[2]);
build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! &edge_info->cond_equivalences[3]);
break;
default:
- edge_info->max_cond_equivalences = 2;
- edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 2);
break;
}
/* Now store the original true and false conditions into the first
two slots. */
! initialize_expr_from_cond (cond, &edge_info->cond_equivalences[0].cond);
! edge_info->cond_equivalences[0].value = boolean_true_node;
/* It is possible for INVERTED to be the negation of a comparison,
and not a valid RHS or GIMPLE_COND condition. This happens because
invert_truthvalue may return such an expression when asked to invert
a floating-point comparison. These comparisons are not assumed to
obey the trichotomy law. */
! initialize_expr_from_cond (inverted, &edge_info->cond_equivalences[1].cond);
! edge_info->cond_equivalences[1].value = boolean_false_node;
}
/* A helper function for record_const_or_copy and record_equality.
--- 1186,1281 ----
case GT_EXPR:
if (FLOAT_TYPE_P (TREE_TYPE (op0)))
{
build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! &edge_info->cond_equivalences);
build_and_record_new_cond (LTGT_EXPR, op0, op1,
! &edge_info->cond_equivalences);
}
build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR
? LE_EXPR : GE_EXPR),
! op0, op1, &edge_info->cond_equivalences);
build_and_record_new_cond (NE_EXPR, op0, op1,
! &edge_info->cond_equivalences);
break;
case GE_EXPR:
case LE_EXPR:
if (FLOAT_TYPE_P (TREE_TYPE (op0)))
{
build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! &edge_info->cond_equivalences);
}
break;
case EQ_EXPR:
if (FLOAT_TYPE_P (TREE_TYPE (op0)))
{
build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! &edge_info->cond_equivalences);
}
build_and_record_new_cond (LE_EXPR, op0, op1,
! &edge_info->cond_equivalences);
build_and_record_new_cond (GE_EXPR, op0, op1,
! &edge_info->cond_equivalences);
break;
case UNORDERED_EXPR:
build_and_record_new_cond (NE_EXPR, op0, op1,
! &edge_info->cond_equivalences);
build_and_record_new_cond (UNLE_EXPR, op0, op1,
! &edge_info->cond_equivalences);
build_and_record_new_cond (UNGE_EXPR, op0, op1,
! &edge_info->cond_equivalences);
build_and_record_new_cond (UNEQ_EXPR, op0, op1,
! &edge_info->cond_equivalences);
build_and_record_new_cond (UNLT_EXPR, op0, op1,
! &edge_info->cond_equivalences);
build_and_record_new_cond (UNGT_EXPR, op0, op1,
! &edge_info->cond_equivalences);
break;
case UNLT_EXPR:
case UNGT_EXPR:
build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR
? UNLE_EXPR : UNGE_EXPR),
! op0, op1, &edge_info->cond_equivalences);
build_and_record_new_cond (NE_EXPR, op0, op1,
! &edge_info->cond_equivalences);
break;
case UNEQ_EXPR:
build_and_record_new_cond (UNLE_EXPR, op0, op1,
! &edge_info->cond_equivalences);
build_and_record_new_cond (UNGE_EXPR, op0, op1,
! &edge_info->cond_equivalences);
break;
case LTGT_EXPR:
build_and_record_new_cond (NE_EXPR, op0, op1,
! &edge_info->cond_equivalences);
build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! &edge_info->cond_equivalences);
break;
default:
break;
}
/* Now store the original true and false conditions into the first
two slots. */
! initialize_expr_from_cond (cond, &c.cond);
! 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,
and not a valid RHS or GIMPLE_COND condition. This happens because
invert_truthvalue may return such an expression when asked to invert
a floating-point comparison. These comparisons are not assumed to
obey the trichotomy law. */
! initialize_expr_from_cond (inverted, &c.cond);
! 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.
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1749,1755 ****
our equivalence tables. */
if (edge_info)
{
! struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences;
tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs;
--- 1723,1729 ----
our equivalence tables. */
if (edge_info)
{
! cond_equivalence *eq;
tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs;
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1759,1767 ****
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
! if (cond_equivalences)
! for (i = 0; i < edge_info->max_cond_equivalences; i++)
! record_cond (&cond_equivalences[i]);
}
dom_thread_across_edge (walk_data, true_edge);
--- 1733,1741 ----
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
! for (i = 0; VEC_iterate (cond_equivalence,
! edge_info->cond_equivalences, i, eq); ++i)
! record_cond (eq);
}
dom_thread_across_edge (walk_data, true_edge);
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1784,1790 ****
our equivalence tables. */
if (edge_info)
{
! struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences;
tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs;
--- 1758,1764 ----
our equivalence tables. */
if (edge_info)
{
! cond_equivalence *eq;
tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs;
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1794,1802 ****
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
! if (cond_equivalences)
! for (i = 0; i < edge_info->max_cond_equivalences; i++)
! record_cond (&cond_equivalences[i]);
}
/* Now thread the edge. */
--- 1768,1776 ----
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
! for (i = 0; VEC_iterate (cond_equivalence,
! edge_info->cond_equivalences, i, eq); ++i)
! record_cond (eq);
}
/* Now thread the edge. */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-08-17 9:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-17 9:56 [PATCH] Use a VEC for the list of conditional equivalences in DOM Richard Guenther
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).