X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgraphite-scop-detection.c;h=0a3680b1fa1268d4f22ef5738a103ab24e440dc0;hb=b0b9387e93c5723fd748754dfb436bca8a267e47;hp=5647d2e0b39444bc9cb72c197e8c74d8489abe85;hpb=e313585005607d7ad7202f9d5b639ec86c968f1f;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c index 5647d2e0b39..0a3680b1fa1 100644 --- a/gcc/graphite-scop-detection.c +++ b/gcc/graphite-scop-detection.c @@ -22,34 +22,23 @@ along with GCC; see the file COPYING3. If not see #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 { @@ -269,23 +258,33 @@ graphite_can_represent_expr (basic_block scop_entry, loop_p loop, Graphite. */ static bool -stmt_has_simple_data_refs_p (loop_p outermost_loop, gimple stmt) +stmt_has_simple_data_refs_p (loop_p outermost_loop ATTRIBUTE_UNUSED, + gimple stmt) { data_reference_p dr; unsigned i; int j; bool res = true; - VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5); + VEC (data_reference_p, heap) *drs = NULL; + loop_p outer; - graphite_find_data_references_in_stmt (outermost_loop, stmt, &drs); + for (outer = loop_containing_stmt (stmt); outer; outer = loop_outer (outer)) + { + graphite_find_data_references_in_stmt (outer, + 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++) - if (!graphite_can_represent_scev (DR_ACCESS_FN (dr, i))) - { - res = false; - goto done; - } + FOR_EACH_VEC_ELT (data_reference_p, drs, j, dr) + for (i = 0; i < DR_NUM_DIMENSIONS (dr); i++) + if (!graphite_can_represent_scev (DR_ACCESS_FN (dr, i))) + { + res = false; + goto done; + } + + free_data_refs (drs); + drs = NULL; + } done: free_data_refs (drs); @@ -383,24 +382,24 @@ harmful_stmt_in_bb (basic_block scop_entry, loop_p outer_loop, basic_block bb) return NULL; } -/* Return true when it is not possible to represent LOOP in the - polyhedral representation. This is evaluated taking SCOP_ENTRY - in mind. */ +/* Return true if LOOP can be represented in the polyhedral + representation. This is evaluated taking SCOP_ENTRY and + OUTERMOST_LOOP in mind. */ static bool graphite_can_represent_loop (basic_block scop_entry, loop_p loop) { - tree niter = number_of_latch_executions (loop); - - /* Number of iterations unknown. */ - if (chrec_contains_undetermined (niter)) - return false; + tree niter; + struct tree_niter_desc niter_desc; - /* Number of iterations not affine. */ - if (!graphite_can_represent_expr (scop_entry, loop, niter)) - return false; + /* FIXME: For the moment, graphite cannot be used on loops that + iterate using induction variables that wrap. */ - return true; + return number_of_iterations_exit (loop, single_exit (loop), &niter_desc, false) + && niter_desc.control.no_overflow + && (niter = number_of_latch_executions (loop)) + && !chrec_contains_undetermined (niter) + && graphite_can_represent_expr (scop_entry, loop, niter); } /* Store information needed by scopdet_* functions. */ @@ -899,9 +898,7 @@ create_single_entry_edge (sd_region *region) 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. */ @@ -967,9 +964,7 @@ create_single_exit_edge (sd_region *region) 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. @@ -1217,6 +1212,73 @@ limit_scops (VEC (scop_p, heap) **scops) 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 @@ -1231,7 +1293,10 @@ canonicalize_loop_closed_ssa (loop_p loop) 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; @@ -1266,7 +1331,13 @@ canonicalize_loop_closed_ssa (loop_p loop) 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 @@ -1286,6 +1357,8 @@ canonicalize_loop_closed_ssa (loop_p loop) - 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