static int avail_expr_eq (const void *, const void *);
static void htab_statistics (FILE *, htab_t);
static void record_cond (tree, tree, varray_type *);
+static void record_dominating_conditions (tree, varray_type *);
static void record_const_or_copy (tree, tree, varray_type *);
static void record_equality (tree, tree, varray_type *);
static tree update_rhs_and_lookup_avail_expr (tree, tree, varray_type *,
if (TREE_CODE_CLASS (cond_code) == '<')
{
record_cond (cond, boolean_true_node, &bd->avail_exprs);
+ record_dominating_conditions (cond, &bd->avail_exprs);
record_cond (inverted, boolean_false_node, &bd->avail_exprs);
}
else if (cond_code == SSA_NAME)
{
record_cond (cond, boolean_false_node, &bd->avail_exprs);
record_cond (inverted, boolean_true_node, &bd->avail_exprs);
+ record_dominating_conditions (inverted, &bd->avail_exprs);
}
else if (cond_code == SSA_NAME)
record_const_or_copy (cond, boolean_false_node,
free (element);
}
+/* COND is a condition which is known to be true. Record variants of
+ COND which must also be true.
+
+ For example, if a < b is true, then a <= b must also be true. */
+
+static void
+record_dominating_conditions (tree cond, varray_type *block_avail_exprs_p)
+{
+ switch (TREE_CODE (cond))
+ {
+ case LT_EXPR:
+ record_cond (build2 (LE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (ORDERED_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (LTGT_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case GT_EXPR:
+ record_cond (build2 (GE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (ORDERED_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (LTGT_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case GE_EXPR:
+ case LE_EXPR:
+ record_cond (build2 (ORDERED_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case EQ_EXPR:
+ record_cond (build2 (ORDERED_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (LE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (GE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case UNORDERED_EXPR:
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNLE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNGE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNEQ_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNLT_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNGT_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case UNLT_EXPR:
+ record_cond (build2 (UNLE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case UNGT_EXPR:
+ record_cond (build2 (UNGE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case UNEQ_EXPR:
+ record_cond (build2 (UNLE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNGE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case LTGT_EXPR:
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (ORDERED_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+
+ default:
+ break;
+ }
+}
+
/* A helper function for record_const_or_copy and record_equality.
Do the work of recording the value and undo info. */
if (true_arm)
{
record_cond (cond, boolean_true_node, block_avail_exprs_p);
+ record_dominating_conditions (cond, block_avail_exprs_p);
record_cond (inverted, boolean_false_node, block_avail_exprs_p);
if (TREE_CONSTANT (op1))
{
record_cond (inverted, boolean_true_node, block_avail_exprs_p);
+ record_dominating_conditions (inverted, block_avail_exprs_p);
record_cond (cond, boolean_false_node, block_avail_exprs_p);
if (TREE_CONSTANT (op1))