diff --git a/include/pass_mpi_collective.hpp b/include/pass_mpi_collective.hpp index 44d96f7bcc1aa996854072ce785c7ecbd89df2d6..8bea3b348ef7818284acc3da387605ba11056e07 100644 --- a/include/pass_mpi_collective.hpp +++ b/include/pass_mpi_collective.hpp @@ -29,7 +29,8 @@ 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 + int mark1; // for graph parkour + int mark2; int collective_rank; }; @@ -76,13 +77,14 @@ public: void reset_bb_mark(function *fun); void alloc_edge_aux(function *fun); void free_edge_aux(function *fun); + + // loop detection void mark_edge(function *fun); - void mark_edge(basic_block bb); // rank definition void rank_collective(function *fun); - int rank_collective(basic_block bb, - mpi_collective_code mpi_code, int rank); + int __rank_collective(basic_block bb, + mpi_collective_code mpi_code, int rank); private: // MPI function / collectives detections diff --git a/src/pass_mpi_collective.cpp b/src/pass_mpi_collective.cpp index 3e8640e365ed0861fd71663def7c8482f1d62def..e605fda7dee02a444fa6caedea9de9e2472368e0 100644 --- a/src/pass_mpi_collective.cpp +++ b/src/pass_mpi_collective.cpp @@ -12,6 +12,8 @@ #include <filesystem> // set #include <set> +// list +#include <list> // our pass #include "pass_mpi_collective.hpp" @@ -259,12 +261,6 @@ void pass_mpi_collective::label_dom(function *fun) } } - //for (basic_block bb2 : *dom) - //{ - // printf("%d dom %d\n", bb->index, bb2->index); - //} - //((bb_data *) bb->aux)->dom = dominated; - post_dom_gccvec = get_all_dominated_blocks(CDI_POST_DOMINATORS, bb); size_post_dom = post_dom_gccvec.length(); for (size_t i = 0; i < size_post_dom; ++i) @@ -274,11 +270,6 @@ void pass_mpi_collective::label_dom(function *fun) data->post_dom.insert(post_dom_gccvec[i]); } } - //for (basic_block bb2 : *post_dom) - //{ - // printf("%d post dom %d\n", bb->index, bb2->index); - //} - //((bb_data *) bb->aux)->post_dom = post_dominated; } } @@ -359,7 +350,8 @@ void pass_mpi_collective::reset_bb_mark(function *fun) FOR_ALL_BB_FN(bb, fun) { - ((bb_data *) bb->aux)->mark = 0; + ((bb_data *) bb->aux)->mark1 = 0; + ((bb_data *) bb->aux)->mark2 = 0; } } @@ -397,27 +389,101 @@ void pass_mpi_collective::free_edge_aux(function *fun) } } +// naive version of mark_edge (work but Omax(2^n)) +//void pass_mpi_collective::mark_edge(function *fun) +//{ +// mark_edge(ENTRY_BLOCK_PTR_FOR_FN(fun)); +//} +// +//void pass_mpi_collective::mark_edge(basic_block bb) +//{ +// edge e; +// edge_iterator ei; +// +// ((bb_data *) bb->aux)->mark = 1; +// FOR_EACH_EDGE(e, ei, bb->succs) +// { +// if (((bb_data *) e->dest->aux)->mark) +// { +// ((edge_data *) e->aux)->loop = true; +// } else { +// mark_edge(e->dest); +// } +// } +// ((bb_data *) bb->aux)->mark = 0; +//} + void pass_mpi_collective::mark_edge(function *fun) { - mark_edge(ENTRY_BLOCK_PTR_FOR_FN(fun)); -} -void pass_mpi_collective::mark_edge(basic_block bb) -{ - edge e; - edge_iterator ei; + edge e1; + edge_iterator ei1; + std::list<basic_block> nodes1; + basic_block bb; + + edge e2; + edge_iterator ei2; + std::list<basic_block> nodes2; + basic_block cursor; + + int index; - ((bb_data *) bb->aux)->mark = 1; - FOR_EACH_EDGE(e, ei, bb->succs) + index = 0; + + nodes1.push_back(ENTRY_BLOCK_PTR_FOR_FN(fun)); + ((bb_data *) ENTRY_BLOCK_PTR_FOR_FN(fun)->aux)->mark1 = 1; + + while (!nodes1.empty()) { - if (((bb_data *) e->dest->aux)->mark) + bb = nodes1.front(); + nodes1.pop_front(); + + FOR_EACH_EDGE(e1, ei1, bb->succs) { - ((edge_data *) e->aux)->loop = true; - } else { - mark_edge(e->dest); + if (((bb_data *) e1->dest->aux)->mark1) + { + continue; + } + ((bb_data *) bb->aux)->mark1 = 1; + nodes1.push_back(e1->dest); + } + + if (EDGE_COUNT(bb->preds) < 2) + { + continue; + } + + ++index; + nodes2.clear(); + nodes2.push_back(bb); + ((bb_data *) bb->aux)->mark2 = index; + + while (!nodes2.empty()) + { + cursor = nodes2.front(); + nodes2.pop_front(); + + FOR_EACH_EDGE(e2, ei2, cursor->succs) + { + if (e2->dest == bb) + { + ((edge_data *) e2->aux)->loop = true; + } + if (((edge_data *) e2->aux)->loop) + { + continue; + } + + if (((bb_data *) e2->dest->aux)->mark2 >= index) + { + continue; + } + ((bb_data *) cursor->aux)->mark2 = index; + nodes2.push_back(e2->dest); + } } } - ((bb_data *) bb->aux)->mark = 0; + reset_bb_mark(fun); } void pass_mpi_collective::rank_collective(function *fun) @@ -427,13 +493,13 @@ void pass_mpi_collective::rank_collective(function *fun) for (i = 0; i < LAST_AND_UNUSED_MPI_COLLECTIVE_CODE; ++i) { - next_rank = rank_collective(EXIT_BLOCK_PTR_FOR_FN(fun), - (enum mpi_collective_code) i, next_rank); + next_rank = __rank_collective(EXIT_BLOCK_PTR_FOR_FN(fun), + (enum mpi_collective_code) i, next_rank); reset_bb_mark(fun); } } -int pass_mpi_collective::rank_collective(basic_block bb, +int pass_mpi_collective::__rank_collective(basic_block bb, mpi_collective_code mpi_code, int rank) { edge e; @@ -447,25 +513,27 @@ int pass_mpi_collective::rank_collective(basic_block bb, { continue; } - if (((bb_data *) e->src->aux)->mark) + + // cache or travell + if (((bb_data *) e->src->aux)->mark1) { - //printf("caching from %d to %d\n", e->src->index, bb->index); next_rank = std::max(next_rank, - ((bb_data *) e->src->aux)->mark); + ((bb_data *) e->src->aux)->mark1); } else { - //printf("going from %d to %d\n", e->src->index, bb->index); next_rank = std::max(next_rank, - rank_collective(e->src, mpi_code, rank)); + __rank_collective(e->src, mpi_code, rank)); } } + // set mpi code if (((bb_data *) bb->aux)->mpi_code == mpi_code) { ((bb_data *) bb->aux)->collective_rank = next_rank; next_rank++; } - ((bb_data *) bb->aux)->mark = next_rank; + // set mark before recusion + ((bb_data *) bb->aux)->mark1 = next_rank; return next_rank; }