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, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
#include "config.h"
#include "system.h"
basic_block bb;
block_stmt_iterator bsi;
tree phi;
- bool saw_a_complex_value = false;
+ bool saw_a_complex_op = false;
FOR_EACH_BB (bb)
{
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{
- tree stmt = bsi_stmt (bsi);
- bool dsa = true;
+ tree orig_stmt, stmt, rhs = NULL;
+ bool dsa;
- if (TREE_CODE (stmt) == MODIFY_EXPR
- && is_complex_reg (TREE_OPERAND (stmt, 0)))
+ orig_stmt = stmt = bsi_stmt (bsi);
+
+ /* Most control-altering statements must be initially
+ simulated, else we won't cover the entire cfg. */
+ dsa = !stmt_ends_bb_p (stmt);
+
+ switch (TREE_CODE (stmt))
{
- dsa = false;
- saw_a_complex_value = true;
+ case RETURN_EXPR:
+ /* We don't care what the lattice value of <retval> is,
+ since it's never used as an input to another computation. */
+ dsa = true;
+ stmt = TREE_OPERAND (stmt, 0);
+ if (!stmt || TREE_CODE (stmt) != MODIFY_EXPR)
+ break;
+ /* FALLTHRU */
+
+ case MODIFY_EXPR:
+ dsa = !is_complex_reg (TREE_OPERAND (stmt, 0));
+ rhs = TREE_OPERAND (stmt, 1);
+ break;
+
+ case COND_EXPR:
+ rhs = TREE_OPERAND (stmt, 0);
+ break;
+
+ default:
+ break;
}
- DONT_SIMULATE_AGAIN (stmt) = dsa;
+ if (rhs)
+ switch (TREE_CODE (rhs))
+ {
+ case EQ_EXPR:
+ case NE_EXPR:
+ rhs = TREE_OPERAND (rhs, 0);
+ /* FALLTHRU */
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case RDIV_EXPR:
+ case NEGATE_EXPR:
+ case CONJ_EXPR:
+ if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE)
+ saw_a_complex_op = true;
+ break;
+
+ default:
+ break;
+ }
+
+ DONT_SIMULATE_AGAIN (orig_stmt) = dsa;
}
}
- return saw_a_complex_value;
+ return saw_a_complex_op;
}
unsigned int ver;
tree lhs, rhs;
- /* These conditions should be satisfied due to the initial filter
- set up in init_dont_simulate_again. */
- gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR);
+ if (TREE_CODE (stmt) != MODIFY_EXPR)
+ return SSA_PROP_VARYING;
lhs = TREE_OPERAND (stmt, 0);
rhs = TREE_OPERAND (stmt, 1);
+ /* These conditions should be satisfied due to the initial filter
+ set up in init_dont_simulate_again. */
gcc_assert (TREE_CODE (lhs) == SSA_NAME);
gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
size_t k, n;
n = num_referenced_vars;
+ if (n == 0)
+ return;
+
complex_variable_components = VEC_alloc (tree, heap, 2*n);
VEC_safe_grow (tree, heap, complex_variable_components, 2*n);
tree arg = PHI_ARG_DEF (phi, i);
tree r, i;
+ /* Avoid no-op assignments. This also prevents insertting stmts
+ onto abnormal edges, assuming the PHI isn't already broken. */
+ if (TREE_CODE (arg) == SSA_NAME
+ && SSA_NAME_VAR (arg) == SSA_NAME_VAR (lhs))
+ continue;
+
r = extract_component (NULL, arg, 0, false);
i = extract_component (NULL, arg, 1, false);
update_complex_components_on_edge (e, NULL, lhs, r, i);