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;
 }