/* Routines for discovering and unpropagating edge equivalences.
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2007 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
/* If the conditional is a single variable 'X', record 'X = 1'
for the true edge and 'X = 0' on the false edge. */
- if (TREE_CODE (cond) == SSA_NAME)
+ if (TREE_CODE (cond) == SSA_NAME
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (cond))
{
- equivalency = xmalloc (sizeof (struct edge_equivalency));
+ equivalency = XNEW (struct edge_equivalency);
equivalency->rhs = constant_boolean_node (1, TREE_TYPE (cond));
equivalency->lhs = cond;
true_edge->aux = equivalency;
- equivalency = xmalloc (sizeof (struct edge_equivalency));
+ equivalency = XNEW (struct edge_equivalency);
equivalency->rhs = constant_boolean_node (0, TREE_TYPE (cond));
equivalency->lhs = cond;
false_edge->aux = equivalency;
know the value of OP0 on both arms of the branch. i.e., we
can record an equivalence for OP0 rather than COND. */
if (TREE_CODE (op0) == SSA_NAME
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0)
&& TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
&& is_gimple_min_invariant (op1))
{
if (TREE_CODE (cond) == EQ_EXPR)
{
- equivalency = xmalloc (sizeof (struct edge_equivalency));
+ equivalency = XNEW (struct edge_equivalency);
equivalency->lhs = op0;
equivalency->rhs = (integer_zerop (op1)
? boolean_false_node
: boolean_true_node);
true_edge->aux = equivalency;
- equivalency = xmalloc (sizeof (struct edge_equivalency));
+ equivalency = XNEW (struct edge_equivalency);
equivalency->lhs = op0;
equivalency->rhs = (integer_zerop (op1)
? boolean_true_node
}
else
{
- equivalency = xmalloc (sizeof (struct edge_equivalency));
+ equivalency = XNEW (struct edge_equivalency);
equivalency->lhs = op0;
equivalency->rhs = (integer_zerop (op1)
? boolean_true_node
: boolean_false_node);
true_edge->aux = equivalency;
- equivalency = xmalloc (sizeof (struct edge_equivalency));
+ equivalency = XNEW (struct edge_equivalency);
equivalency->lhs = op0;
equivalency->rhs = (integer_zerop (op1)
? boolean_false_node
}
if (TREE_CODE (op0) == SSA_NAME
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0)
&& (is_gimple_min_invariant (op1)
- || TREE_CODE (op1) == SSA_NAME))
+ || (TREE_CODE (op1) == SSA_NAME
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op1))))
{
/* For IEEE, -0.0 == 0.0, so we don't necessarily know
the sign of a variable compared against zero. If
|| REAL_VALUES_EQUAL (dconst0, TREE_REAL_CST (op1))))
continue;
- equivalency = xmalloc (sizeof (struct edge_equivalency));
+ equivalency = XNEW (struct edge_equivalency);
equivalency->lhs = op0;
equivalency->rhs = op1;
if (TREE_CODE (cond) == EQ_EXPR)
{
tree cond = SWITCH_COND (stmt);
- if (TREE_CODE (cond) == SSA_NAME)
+ if (TREE_CODE (cond) == SSA_NAME
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (cond))
{
tree labels = SWITCH_LABELS (stmt);
int i, n_labels = TREE_VEC_LENGTH (labels);
- tree *info = xcalloc (n_basic_blocks, sizeof (tree));
+ tree *info = XCNEWVEC (tree, n_basic_blocks);
/* Walk over the case label vector. Record blocks
which are reached by a single case label which represents
/* Record an equivalency on the edge from BB to basic
block I. */
- equivalency = xmalloc (sizeof (struct edge_equivalency));
+ equivalency = XNEW (struct edge_equivalency);
equivalency->rhs = x;
equivalency->lhs = cond;
find_edge (bb, BASIC_BLOCK (i))->aux = equivalency;
static hashval_t
equiv_hash (const void *p)
{
- tree value = ((struct equiv_hash_elt *)p)->value;
+ tree const value = ((const struct equiv_hash_elt *)p)->value;
return iterative_hash_expr (value, 0);
}
static int
equiv_eq (const void *p1, const void *p2)
{
- tree value1 = ((struct equiv_hash_elt *)p1)->value;
- tree value2 = ((struct equiv_hash_elt *)p2)->value;
+ tree value1 = ((const struct equiv_hash_elt *)p1)->value;
+ tree value2 = ((const struct equiv_hash_elt *)p2)->value;
return operand_equal_p (value1, value2, 0);
}
struct equiv_hash_elt *equiv_hash_elt;
void **slot;
- equiv_hash_elt = xmalloc (sizeof (struct equiv_hash_elt));
+ equiv_hash_elt = XNEW (struct equiv_hash_elt);
equiv_hash_elt->value = value;
equiv_hash_elt->equivalences = NULL;
/* Main driver for un-cprop. */
-static void
+static unsigned int
tree_ssa_uncprop (void)
{
struct dom_walk_data walk_data;
}
}
}
-
+ return 0;
}
/* Record any equivalency associated with E. */
if (e->aux)
{
- struct edge_equivalency *equiv = e->aux;
+ struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux;
record_equiv (equiv->rhs, equiv->lhs);
}
if (slot)
{
- struct equiv_hash_elt *elt = *slot;
+ struct equiv_hash_elt *elt = (struct equiv_hash_elt *) *slot;
int j;
/* Walk every equivalence with the same value. If we find
/* If we had an equivalence associated with this edge, remove it. */
if (e->aux)
{
- struct edge_equivalency *equiv = e->aux;
+ struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux;
remove_equivalence (equiv->rhs);
}
}
if (e && e->src == parent && e->aux)
{
- struct edge_equivalency *equiv = e->aux;
+ struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux;
record_equiv (equiv->rhs, equiv->lhs);
VEC_safe_push (tree, heap, equiv_stack, equiv->rhs);