diff options
Diffstat (limited to 'gcc/tree-phinodes.c')
-rw-r--r-- | gcc/tree-phinodes.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c index 0bd5085ba99..f96dafa476c 100644 --- a/gcc/tree-phinodes.c +++ b/gcc/tree-phinodes.c @@ -464,4 +464,41 @@ remove_phi_nodes (basic_block bb) set_phi_nodes (bb, NULL); } +/* Given PHI, return its RHS if the PHI is a degenerate, otherwise return + NULL. */ + +tree +degenerate_phi_result (gimple phi) +{ + tree lhs = gimple_phi_result (phi); + tree val = NULL; + size_t i; + + /* Ignoring arguments which are the same as LHS, if all the remaining + arguments are the same, then the PHI is a degenerate and has the + value of that common argument. */ + for (i = 0; i < gimple_phi_num_args (phi); i++) + { + tree arg = gimple_phi_arg_def (phi, i); + + if (arg == lhs) + continue; + else if (!arg) + break; + else if (!val) + val = arg; + else if (arg == val) + continue; + /* We bring in some of operand_equal_p not only to speed things + up, but also to avoid crashing when dereferencing the type of + a released SSA name. */ + else if (TREE_CODE (val) != TREE_CODE (arg) + || TREE_CODE (val) == SSA_NAME + || !operand_equal_p (arg, val, 0)) + break; + } + return (i == gimple_phi_num_args (phi) ? val : NULL); +} + + #include "gt-tree-phinodes.h" |