/* Convert a program in SSA form into Normal form.
- Copyright (C) 2004-2013 Free Software Foundation, Inc.
+ Copyright (C) 2004-2015 Free Software Foundation, Inc.
Contributed by Andrew Macleod <amacleod@redhat.com>
This file is part of GCC.
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "alias.h"
+#include "symtab.h"
#include "tree.h"
-#include "ggc.h"
+#include "fold-const.h"
+#include "stor-layout.h"
+#include "predict.h"
+#include "hard-reg-set.h"
+#include "function.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "cfgrtl.h"
+#include "cfganal.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "bitmap.h"
#include "sbitmap.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
+#include "stringpool.h"
#include "tree-ssanames.h"
#include "dumpfile.h"
#include "diagnostic-core.h"
/* FIXME: A lot of code here deals with expanding to RTL. All that code
should be in cfgexpand.c. */
+#include "rtl.h"
+#include "flags.h"
+#include "insn-config.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "varasm.h"
+#include "stmt.h"
#include "expr.h"
/* Return TRUE if expression STMT is suitable for replacement. */
SRC/DEST might be BLKmode memory locations SIZEEXP is a tree from
which we deduce the size to copy in that case. */
-static inline rtx
+static inline rtx_insn *
emit_partition_copy (rtx dest, rtx src, int unsignedsrcp, tree sizeexp)
{
- rtx seq;
-
start_sequence ();
if (GET_MODE (src) != VOIDmode && GET_MODE (src) != GET_MODE (dest))
else
emit_move_insn (dest, src);
- seq = get_insns ();
+ rtx_insn *seq = get_insns ();
end_sequence ();
return seq;
insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus)
{
tree var;
- rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file,
set_curr_insn_location (locus);
var = partition_to_var (SA.map, src);
- seq = emit_partition_copy (SA.partition_to_pseudo[dest],
- SA.partition_to_pseudo[src],
- TYPE_UNSIGNED (TREE_TYPE (var)),
- var);
+ rtx_insn *seq = emit_partition_copy (copy_rtx (SA.partition_to_pseudo[dest]),
+ copy_rtx (SA.partition_to_pseudo[src]),
+ TYPE_UNSIGNED (TREE_TYPE (var)),
+ var);
insert_insn_on_edge (seq, e);
}
static void
insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus)
{
- rtx seq, x;
- enum machine_mode dest_mode, src_mode;
+ rtx dest_rtx, seq, x;
+ machine_mode dest_mode, src_mode;
int unsignedp;
tree var;
fprintf (dump_file, "\n");
}
- gcc_assert (SA.partition_to_pseudo[dest]);
+ dest_rtx = copy_rtx (SA.partition_to_pseudo[dest]);
+ gcc_assert (dest_rtx);
set_location_for_edge (e);
/* If a locus is provided, override the default. */
var = SSA_NAME_VAR (partition_to_var (SA.map, dest));
src_mode = TYPE_MODE (TREE_TYPE (src));
- dest_mode = GET_MODE (SA.partition_to_pseudo[dest]);
+ dest_mode = GET_MODE (dest_rtx);
gcc_assert (src_mode == TYPE_MODE (TREE_TYPE (var)));
- gcc_assert (!REG_P (SA.partition_to_pseudo[dest])
+ gcc_assert (!REG_P (dest_rtx)
|| dest_mode == promote_decl_mode (var, &unsignedp));
if (src_mode != dest_mode)
}
else if (src_mode == BLKmode)
{
- x = SA.partition_to_pseudo[dest];
+ x = dest_rtx;
store_expr (src, x, 0, false);
}
else
- x = expand_expr (src, SA.partition_to_pseudo[dest],
- dest_mode, EXPAND_NORMAL);
+ x = expand_expr (src, dest_rtx, dest_mode, EXPAND_NORMAL);
- if (x != SA.partition_to_pseudo[dest])
- emit_move_insn (SA.partition_to_pseudo[dest], x);
+ if (x != dest_rtx)
+ emit_move_insn (dest_rtx, x);
seq = get_insns ();
end_sequence ();
insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
source_location locus)
{
- rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file,
mems. Usually we give the source. As we result from SSA names
the left and right size should be the same (and no WITH_SIZE_EXPR
involved), so it doesn't matter. */
- seq = emit_partition_copy (SA.partition_to_pseudo[dest],
- src, unsignedsrcp,
- partition_to_var (SA.map, dest));
+ rtx_insn *seq = emit_partition_copy (copy_rtx (SA.partition_to_pseudo[dest]),
+ src, unsignedsrcp,
+ partition_to_var (SA.map, dest));
insert_insn_on_edge (seq, e);
}
insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
{
tree var;
- rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file,
set_curr_insn_location (locus);
var = partition_to_var (SA.map, src);
- seq = emit_partition_copy (dest,
- SA.partition_to_pseudo[src],
- TYPE_UNSIGNED (TREE_TYPE (var)),
- var);
+ rtx_insn *seq = emit_partition_copy (dest,
+ copy_rtx (SA.partition_to_pseudo[src]),
+ TYPE_UNSIGNED (TREE_TYPE (var)),
+ var);
insert_insn_on_edge (seq, e);
}
{
tree Ti;
int p0, pi;
- gimple_stmt_iterator gsi;
+ gphi_iterator gsi;
clear_elim_graph (g);
for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
{
- gimple phi = gsi_stmt (gsi);
+ gphi *phi = gsi.phi ();
source_location locus;
p0 = var_to_partition (g->map, gimple_phi_result (phi));
tree var = TREE_CODE (name) == SSA_NAME ? SSA_NAME_VAR (name) : name;
tree type = TREE_TYPE (var);
int unsignedp;
- enum machine_mode reg_mode = promote_decl_mode (var, &unsignedp);
+ machine_mode reg_mode = promote_decl_mode (var, &unsignedp);
rtx x = gen_reg_rtx (reg_mode);
if (POINTER_TYPE_P (type))
mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (var))));
check to see if this allows another PHI node to be removed. */
static void
-remove_gimple_phi_args (gimple phi)
+remove_gimple_phi_args (gphi *phi)
{
use_operand_p arg_p;
ssa_op_iter iter;
/* Also remove the def if it is a PHI node. */
if (gimple_code (stmt) == GIMPLE_PHI)
{
- remove_gimple_phi_args (stmt);
+ remove_gimple_phi_args (as_a <gphi *> (stmt));
gsi = gsi_for_stmt (stmt);
remove_phi_node (&gsi, true);
}
eliminate_useless_phis (void)
{
basic_block bb;
- gimple_stmt_iterator gsi;
+ gphi_iterator gsi;
tree result;
- FOR_EACH_BB (bb)
+ FOR_EACH_BB_FN (bb, cfun)
{
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
{
- gimple phi = gsi_stmt (gsi);
+ gphi *phi = gsi.phi ();
result = gimple_phi_result (phi);
if (virtual_operand_p (result))
{
/* Search for PHIs where the destination has no partition, but one
or more arguments has a partition. This should not happen and can
create incorrect code. */
- FOR_EACH_BB (bb)
+ FOR_EACH_BB_FN (bb, cfun)
{
- gimple_stmt_iterator gsi;
+ gphi_iterator gsi;
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- gimple phi = gsi_stmt (gsi);
+ gphi *phi = gsi.phi ();
tree T0 = var_to_partition_to_var (map, gimple_phi_result (phi));
if (T0 == NULL_TREE)
{
elim_graph g = new_elim_graph (sa->map->num_partitions);
g->map = sa->map;
- FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR, next_bb)
+ FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb,
+ EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
if (!gimple_seq_empty_p (phi_nodes (bb)))
{
edge e;
if (e->insns.r && (e->flags & EDGE_EH)
&& !single_pred_p (e->dest))
{
- rtx insns = e->insns.r;
+ rtx_insn *insns = e->insns.r;
basic_block bb;
- e->insns.r = NULL_RTX;
+ e->insns.r = NULL;
bb = split_edge (e);
single_pred_edge (bb)->insns.r = insns;
}
insert_backedge_copies (void)
{
basic_block bb;
- gimple_stmt_iterator gsi;
+ gphi_iterator gsi;
mark_dfs_back_edges ();
- FOR_EACH_BB (bb)
+ FOR_EACH_BB_FN (bb, cfun)
{
/* Mark block as possibly needing calculation of UIDs. */
bb->aux = &bb->aux;
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- gimple phi = gsi_stmt (gsi);
+ gphi *phi = gsi.phi ();
tree result = gimple_phi_result (phi);
size_t i;
|| trivially_conflicts_p (bb, result, arg)))
{
tree name;
- gimple stmt, last = NULL;
+ gassign *stmt;
+ gimple last = NULL;
gimple_stmt_iterator gsi2;
gsi2 = gsi_last_bb (gimple_phi_arg_edge (phi, i)->src);
/* Create a new instance of the underlying variable of the
PHI result. */
- name = copy_ssa_name (result, NULL);
+ name = copy_ssa_name (result);
stmt = gimple_build_assign (name,
gimple_phi_arg_def (phi, i));