diff --git a/include/pass_mpi_collective.hpp b/include/pass_mpi_collective.hpp index 74f4feaee76d1e2ab0b3586683439ff61a010d93..a426be07ab4bfe3a43cc53c56418ef7f9daa196d 100644 --- a/include/pass_mpi_collective.hpp +++ b/include/pass_mpi_collective.hpp @@ -29,6 +29,15 @@ struct bb_data std::set<basic_block> post_dom; std::set<basic_block> dom_front; std::set<basic_block> post_dom_front; + int mark; // for graph parkour +}; + +struct edge_data +{ + // exclude adge that make loop + // excluding edge tag with loop remove all loop from the graph + // used to calculate collectives ranks + bool loop; }; class pass_mpi_collective : public opt_pass @@ -62,6 +71,13 @@ public: void label_dom_front(function *fun); void free_dom_data(); + //parkour de graph + void reset_bb_mark(function *fun); + void alloc_edge_aux(function *fun); + void free_edge_aux(function *fun); + void mark_edge(function *fun); + void mark_edge(basic_block bb, int mark); + private: // MPI function / collectives detections bool __is_mpi_func(gimple *stmt); diff --git a/src/pass_mpi_collective.cpp b/src/pass_mpi_collective.cpp index dad7621bfa60eb355baaa385301c44d452f497f0..8684874b88cdea16cf637c0c4e74215038caeb63 100644 --- a/src/pass_mpi_collective.cpp +++ b/src/pass_mpi_collective.cpp @@ -60,10 +60,17 @@ unsigned int pass_mpi_collective::execute(function *fun) label_collec(fun); label_dom(fun); label_dom_front(fun); + + alloc_edge_aux(fun); + + mark_edge(fun); + reset_bb_mark(fun); + cfgviz_dump(fun, "_split"); free_dom_data(); free_bb_aux(fun); + free_edge_aux(fun); return 0; } @@ -309,7 +316,6 @@ void pass_mpi_collective::label_dom_front(function *fun) } } - FOR_EACH_BB_FN(bb, fun) { if (EDGE_COUNT(bb->succs) < 2) @@ -338,18 +344,95 @@ void pass_mpi_collective::label_dom_front(function *fun) } } - void pass_mpi_collective::free_dom_data() { free_dominance_info(CDI_DOMINATORS); free_dominance_info(CDI_POST_DOMINATORS); } +// parkour de graph +void pass_mpi_collective::reset_bb_mark(function *fun) +{ + basic_block bb; + + FOR_ALL_BB_FN(bb, fun) + { + ((bb_data *) bb->aux)->mark = 0; + } +} + +void pass_mpi_collective::alloc_edge_aux(function *fun) +{ + basic_block bb; + edge e; + edge_iterator ei; + + FOR_ALL_BB_FN(bb, fun) + { + FOR_EACH_EDGE(e, ei, bb->succs) + { + e->aux = new edge_data(); + } + } +} + +void pass_mpi_collective::free_edge_aux(function *fun) +{ + basic_block bb; + edge e; + edge_iterator ei; + + FOR_ALL_BB_FN(bb, fun) + { + FOR_EACH_EDGE(e, ei, bb->succs) + { + if (e->aux != NULL) + { + delete (edge_data *) e->aux; + e->aux = NULL; + } + } + } +} + +void pass_mpi_collective::mark_edge(function *fun) +{ + mark_edge(ENTRY_BLOCK_PTR_FOR_FN(fun), 1); +} + +void pass_mpi_collective::mark_edge(basic_block bb, int mark) +{ + edge e; + edge_iterator ei; + basic_block bb_dest; + int dest_mark; + + ((bb_data *) bb->aux)->mark = mark; + FOR_EACH_EDGE(e, ei, bb->succs) + { + bb_dest = e->dest; + dest_mark = ((bb_data *) bb_dest->aux)->mark; + if (dest_mark > 0 && dest_mark < mark) + { + ((edge_data *) e->aux)->loop = true; + } + } + + FOR_EACH_EDGE(e, ei, bb->succs) + { + bb_dest = e->dest; + if (((bb_data *) bb_dest->aux)->mark == 0) + { + mark_edge(bb_dest, mark + 1); + } + } +} + //============================ GRAPHVIZ ===================================== /* Build a filename (as a string) based on function name */ char *pass_mpi_collective::cfgviz_generate_filename(function *fun, - const char *suffix) + const char *suffix) { char *target_filename; int line; @@ -443,6 +526,11 @@ void pass_mpi_collective::cfgviz_internal_dump(function *fun, FILE *out) label = "false"; } + if (((edge_data *) e->aux)->loop) + { + label = "remove_loop"; + } + fprintf(out, "%d -> %d [color=red label=\"%s\"]\n", bb->index, e->dest->index, label); }