#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
-#include "ggc.h"
-#include "tree.h"
-#include "rtl.h"
-#include "basic-block.h"
-#include "diagnostic.h"
#include "tree-flow.h"
-#include "toplev.h"
-#include "tree-dump.h"
-#include "timevar.h"
#include "cfgloop.h"
#include "tree-chrec.h"
#include "tree-data-ref.h"
#include "tree-scalar-evolution.h"
#include "tree-pass.h"
-#include "domwalk.h"
-#include "value-prof.h"
-#include "pointer-set.h"
-#include "gimple.h"
#include "sese.h"
#ifdef HAVE_cloog
#include "ppl_c.h"
#include "graphite-ppl.h"
-#include "graphite.h"
#include "graphite-poly.h"
#include "graphite-scop-detection.h"
+/* Forward declarations. */
+static void make_close_phi_nodes_unique (basic_block);
+
/* The type of the analyzed basic block. */
typedef enum gbb_type {
bool res = true;
VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
- graphite_find_data_references_in_stmt (outermost_loop, stmt, &drs);
+ graphite_find_data_references_in_stmt (outermost_loop,
+ loop_containing_stmt (stmt),
+ stmt, &drs);
FOR_EACH_VEC_ELT (data_reference_p, drs, j, dr)
for (i = 0; i < DR_NUM_DIMENSIONS (dr); i++)
single edge pointing from outside into the loop. */
gcc_unreachable ();
-#ifdef ENABLE_CHECKING
- gcc_assert (find_single_entry_edge (region));
-#endif
+ gcc_checking_assert (find_single_entry_edge (region));
}
/* Check if the sd_region, mentioned in EDGE, has no exit bb. */
if (e->aux)
((sd_region *) e->aux)->exit = forwarder->dest;
-#ifdef ENABLE_CHECKING
- gcc_assert (find_single_exit_edge (region));
-#endif
+ gcc_checking_assert (find_single_exit_edge (region));
}
/* Unmark the exit edges of all REGIONS.
VEC_free (sd_region, heap, regions);
}
+/* Returns true when P1 and P2 are close phis with the same
+ argument. */
+
+static inline bool
+same_close_phi_node (gimple p1, gimple p2)
+{
+ return operand_equal_p (gimple_phi_arg_def (p1, 0),
+ gimple_phi_arg_def (p2, 0), 0);
+}
+
+/* Remove the close phi node at GSI and replace its rhs with the rhs
+ of PHI. */
+
+static void
+remove_duplicate_close_phi (gimple phi, gimple_stmt_iterator *gsi)
+{
+ gimple use_stmt;
+ use_operand_p use_p;
+ imm_use_iterator imm_iter;
+ tree res = gimple_phi_result (phi);
+ tree def = gimple_phi_result (gsi_stmt (*gsi));
+
+ gcc_assert (same_close_phi_node (phi, gsi_stmt (*gsi)));
+
+ FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
+ {
+ FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
+ SET_USE (use_p, res);
+
+ update_stmt (use_stmt);
+
+ /* It is possible that we just created a duplicate close-phi
+ for an already-processed containing loop. Check for this
+ case and clean it up. */
+ if (gimple_code (use_stmt) == GIMPLE_PHI
+ && gimple_phi_num_args (use_stmt) == 1)
+ make_close_phi_nodes_unique (gimple_bb (use_stmt));
+ }
+
+ remove_phi_node (gsi, true);
+}
+
+/* Removes all the close phi duplicates from BB. */
+
+static void
+make_close_phi_nodes_unique (basic_block bb)
+{
+ gimple_stmt_iterator psi;
+
+ for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
+ {
+ gimple_stmt_iterator gsi = psi;
+ gimple phi = gsi_stmt (psi);
+
+ /* At this point, PHI should be a close phi in normal form. */
+ gcc_assert (gimple_phi_num_args (phi) == 1);
+
+ /* Iterate over the next phis and remove duplicates. */
+ gsi_next (&gsi);
+ while (!gsi_end_p (gsi))
+ if (same_close_phi_node (phi, gsi_stmt (gsi)))
+ remove_duplicate_close_phi (phi, &gsi);
+ else
+ gsi_next (&gsi);
+ }
+}
+
/* Transforms LOOP to the canonical loop closed SSA form. */
static void
bb = e->dest;
if (VEC_length (edge, bb->preds) == 1)
- split_block_after_labels (bb);
+ {
+ e = split_block_after_labels (bb);
+ make_close_phi_nodes_unique (e->src);
+ }
else
{
gimple_stmt_iterator psi;
update_stmt (phi);
}
}
+
+ make_close_phi_nodes_unique (close);
}
+
+ /* The code above does not properly handle changes in the post dominance
+ information (yet). */
+ free_dominance_info (CDI_POST_DOMINATORS);
}
/* Converts the current loop closed SSA form to a canonical form
- the basic block containing the close phi nodes does not contain
other statements.
+
+ - there exist only one phi node per definition in the loop.
*/
static void