diff --git a/MPI_collectives.def b/MPI_collectives.def
new file mode 100644
index 0000000000000000000000000000000000000000..4a53fb1c1aff6065d5e88b65fd181cfce4a4f4d9
--- /dev/null
+++ b/MPI_collectives.def
@@ -0,0 +1,6 @@
+
+DEFMPICOLLECTIVES( MPI_INIT, "MPI_Init" )
+DEFMPICOLLECTIVES( MPI_FINALIZE, "MPI_Finalize" )
+DEFMPICOLLECTIVES( MPI_REDUCE, "MPI_Reduce" )
+DEFMPICOLLECTIVES( MPI_ALL_REDUCE, "MPI_AllReduce" )
+DEFMPICOLLECTIVES( MPI_BARRIER, "MPI_Barrier" )
diff --git a/Makefile b/Makefile
index 27d00b35f6751f4f0495f1df8e230cfd364840e7..d3924d02b4b1be3d92098ebe963064daa5cbf5b3 100755
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 all: plugin
 
 FILE=main.c prog_test.c
-
+PLUGIN=plugin.cpp
 CXX=g++_810
 CC=gcc_810
 
@@ -12,7 +12,7 @@ PLUGIN_FLAGS=-I`$(CC) -print-file-name=plugin`/include -g -Wall -fno-rtti -share
 CFLAGS=-g -O3
 
 
-libplugin.so: plugin.cpp
+libplugin.so: $(PLUGIN)
 	 $(CXX) $(PLUGIN_FLAGS) -o $@ $<
 
 plugin: libplugin.so prog_test.c
@@ -23,6 +23,7 @@ plugin: libplugin.so prog_test.c
 
 clean:
 	rm -rf *.pgr *.pdf plugin
+	rm -rf libplugin.so *.dot plugin
 
 clean_all: clean
 	rm -rf libplugin.so *.dot plugin
diff --git a/functions/MPI_functions.c b/functions/MPI_functions.c
new file mode 100644
index 0000000000000000000000000000000000000000..d2a44d5c33cbf446a8102df25f320c154f9943a4
--- /dev/null
+++ b/functions/MPI_functions.c
@@ -0,0 +1,158 @@
+#include "MPI_functions.h"
+
+void write_mpi_code(function * fun)
+{
+	basic_block bb;
+        gimple_stmt_iterator gsi;
+
+        FOR_EACH_BB_FN( bb,fun )
+        {
+                for (gsi = gsi_start_bb(bb); !gsi_end_p (gsi); gsi_next(&gsi))
+                {
+                        gimple *stmt = gsi_stmt(gsi);
+                        mpi_collective_code *current_enum = (mpi_collective_code*)xmalloc(sizeof (mpi_collective_code));
+
+                        *current_enum = get_mpi_code(stmt);
+                        if (*current_enum != LAST_AND_UNUSED_MPI_COLLECTIVE_CODE)
+                        {
+                                edit_aux_value(bb,(int*)current_enum);
+
+                        }
+                }
+
+        }
+}
+
+void detect_same_bb_mpi_call(function * fun)
+{
+        basic_block bb;
+        gimple_stmt_iterator gsi;
+        FOR_EACH_BB_FN(bb,fun)
+        {
+                int call_counter = 0;
+                for (gsi = gsi_start_bb(bb); !gsi_end_p (gsi); gsi_next(&gsi))
+                {
+                        gimple *stmt = gsi_stmt(gsi);
+                        mpi_collective_code *current_enum = (mpi_collective_code*)xmalloc(sizeof (mpi_collective_code));
+
+                        *current_enum = get_mpi_code(stmt);
+                        if (*current_enum != LAST_AND_UNUSED_MPI_COLLECTIVE_CODE)
+                        {
+                                //printf("Current mpi code : %i\n",(int)*current_enum);
+                                call_counter++;
+
+                        }
+                }
+                printf("number of MPI calls in current basic_block : %i\n",call_counter);
+        }
+}
+
+int are_there_several_mpi_call(function * fun)
+{
+        basic_block bb;
+        gimple_stmt_iterator gsi;
+        FOR_EACH_BB_FN(bb,fun)
+        {
+                int call_counter = 0;
+                for (gsi = gsi_start_bb(bb); !gsi_end_p (gsi); gsi_next(&gsi))
+                {
+                        gimple *stmt = gsi_stmt(gsi);
+                        mpi_collective_code *current_enum = (mpi_collective_code*)xmalloc(sizeof (mpi_collective_code));
+
+                        *current_enum = get_mpi_code(stmt);
+                        if (*current_enum != LAST_AND_UNUSED_MPI_COLLECTIVE_CODE)
+                        {
+                                call_counter++;
+
+                        }
+                }
+                if (call_counter >= 2)
+                {
+                        return 1;
+                }
+        }
+        return 0;
+}
+
+mpi_collective_code get_mpi_code(gimple * stmt)
+{
+        if (is_gimple_call(stmt))
+        {
+                tree t;
+                const char * callee_name;
+                t = gimple_call_fndecl(stmt);
+                callee_name = IDENTIFIER_POINTER(DECL_NAME(t));
+                for (int i = 0; i< LAST_AND_UNUSED_MPI_COLLECTIVE_CODE; i++)
+                {
+                        if (strcmp(callee_name,mpi_collective_name[i])==0)
+                        {
+                                return static_cast<mpi_collective_code>(i);
+                        }
+                }
+        }
+        return LAST_AND_UNUSED_MPI_COLLECTIVE_CODE;
+}
+
+void split_mpi_block(function * fun)
+{
+	if (are_there_several_mpi_call(fun) == 1)
+	{
+		basic_block bb;
+		gimple_stmt_iterator gsi;
+
+		FOR_EACH_BB_FN(bb,fun)
+		{
+
+			int call_counter = 0;
+			for (gsi = gsi_start_bb(bb); !gsi_end_p (gsi); gsi_next(&gsi))
+			{
+				gimple *stmt = gsi_stmt(gsi);
+				mpi_collective_code *current_enum = (mpi_collective_code*)xmalloc(sizeof (mpi_collective_code));
+				
+			 	*current_enum = get_mpi_code(stmt);
+				if (*current_enum != LAST_AND_UNUSED_MPI_COLLECTIVE_CODE)
+				{
+					call_counter++; 
+					
+				}
+				if (call_counter == 1 && *((int *)bb->aux)>=2)
+				{
+					split_block(bb, stmt);
+					int *edit_value = (int*)xmalloc(sizeof(int));
+					*edit_value = *((int *)bb->aux)-1; 
+					call_counter--;
+					edit_aux_value(bb,edit_value);
+					split_mpi_block(fun);
+					return;	
+					//free(edit_value);
+				}
+			}
+		}
+	}
+}
+
+void mark_number_of_calls(function * fun)
+{
+	basic_block bb;	
+	gimple_stmt_iterator gsi;
+	FOR_EACH_BB_FN(bb,fun)
+	{
+		int call_counter = 0;
+		int *aux_counter = (int*)xmalloc(sizeof(int));
+		for (gsi = gsi_start_bb(bb); !gsi_end_p (gsi); gsi_next(&gsi))
+		{
+			gimple *stmt = gsi_stmt(gsi);
+			mpi_collective_code *current_enum = (mpi_collective_code*)xmalloc(sizeof (mpi_collective_code));
+			
+		 	*current_enum = get_mpi_code(stmt);
+			if (*current_enum != LAST_AND_UNUSED_MPI_COLLECTIVE_CODE)
+			{
+				//printf("Current mpi code : %i\n",(int)*current_enum);
+				call_counter++; 
+				
+			}
+		}
+		*aux_counter = call_counter;
+		edit_aux_value(bb,aux_counter);
+	}
+}
diff --git a/functions/MPI_functions.h b/functions/MPI_functions.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b413b8a895355ef64045f611f4971b62f4fc771
--- /dev/null
+++ b/functions/MPI_functions.h
@@ -0,0 +1,11 @@
+#ifndef __MPIFUNDD__H
+#define __MPIFUNDD__H
+
+void write_mpi_code(function * fun);
+void detect_same_bb_mpi_call(function * fun);
+int are_there_several_mpi_call(function * fun);
+mpi_collective_code get_mpi_code(gimple * stmt);
+void split_mpi_block(function * fun);
+void mark_number_of_calls(function * fun);
+
+#endif
diff --git a/functions/MPI_types.h b/functions/MPI_types.h
new file mode 100644
index 0000000000000000000000000000000000000000..82162f970016f032772dc003e263d403e833d0af
--- /dev/null
+++ b/functions/MPI_types.h
@@ -0,0 +1,14 @@
+/* Enum to represent the collective operations */
+enum mpi_collective_code {
+#define DEFMPICOLLECTIVES( CODE, NAME ) CODE,
+#include "MPI_collectives.def"
+        LAST_AND_UNUSED_MPI_COLLECTIVE_CODE
+#undef DEFMPICOLLECTIVES
+} ;
+
+/* Name of each MPI collective operations */
+#define DEFMPICOLLECTIVES( CODE, NAME ) NAME,
+const char *const mpi_collective_name[] = {
+#include "MPI_collectives.def"
+} ;
+#undef DEFMPICOLLECTIVES
diff --git a/functions/aux_values.c b/functions/aux_values.c
new file mode 100644
index 0000000000000000000000000000000000000000..6c930489d8ad6ffcdcea9cae94510ae3f3a5e3ff
--- /dev/null
+++ b/functions/aux_values.c
@@ -0,0 +1,17 @@
+#include "aux_values.h"
+
+void edit_aux_value(basic_block bb, int *i)
+{
+        bb->aux = (int*)xmalloc(sizeof (int));
+        bb->aux = i;
+}
+
+void edit_all_aux_value(function * fun,int *i)
+{
+        basic_block bb;
+        FOR_ALL_BB_FN(bb,fun)
+        {
+                bb->aux = (int*)xmalloc(sizeof (int));
+                bb->aux = i;
+        }
+}
diff --git a/functions/aux_values.h b/functions/aux_values.h
new file mode 100644
index 0000000000000000000000000000000000000000..46de337fed7adab5f4941cbb3f3d2bf1cb859618
--- /dev/null
+++ b/functions/aux_values.h
@@ -0,0 +1,7 @@
+#ifndef __AUXVALUESDD__H
+#define __AUXVALUESDD__H
+
+void edit_aux_value(basic_block bb, int *i);
+void edit_all_aux_value(function * fun,int *i);
+
+#endif
diff --git a/functions/dominance.c b/functions/dominance.c
new file mode 100644
index 0000000000000000000000000000000000000000..91fffcf97ce59ca347ae4e11366ca7740693a16c
--- /dev/null
+++ b/functions/dominance.c
@@ -0,0 +1,86 @@
+#include "dominance.h"
+
+void print_dominance(function * fun)
+{
+        basic_block bb;
+        //gimple_stmt_iterator gsi;
+        calculate_dominance_info(CDI_DOMINATORS);
+        FOR_ALL_BB_FN(bb,fun)
+        {
+                vec<basic_block> bb_vector;
+                bb_vector = get_all_dominated_blocks(CDI_DOMINATORS,bb);
+                printf("Basic blocks dominated by bb %i\n",bb->index);
+                for (auto const & block : bb_vector)
+                {
+                        printf("%i ",block->index);
+                }
+                printf("\n");
+        }
+        free_dominance_info(fun, CDI_DOMINATORS);
+}
+
+void print_post_dominance(function * fun)
+{
+        basic_block bb;
+        //gimple_stmt_iterator gsi;
+        calculate_dominance_info(CDI_POST_DOMINATORS);
+        FOR_ALL_BB_FN(bb,fun)
+        {
+                vec<basic_block> bb_vector;
+                bb_vector = get_all_dominated_blocks(CDI_POST_DOMINATORS,bb);
+                printf("Basic blocks post dominated by bb %i\n",bb->index);
+                for (auto const & block : bb_vector)
+                {
+                        printf("%i ",block->index);
+                }
+                printf("\n");
+        }
+        free_dominance_info(fun, CDI_POST_DOMINATORS);
+}
+
+void print_strictly_dominated(function * fun)
+{
+        basic_block bb;
+        //gimple_stmt_iterator gsi;
+        calculate_dominance_info(CDI_DOMINATORS);
+        FOR_ALL_BB_FN(bb,fun)
+        {
+                vec<basic_block> bb_vector;
+                bb_vector = get_all_dominated_blocks(CDI_DOMINATORS,bb);
+                printf("Basic blocks strictly dominated by bb %i\n",bb->index);
+
+                for (auto const & block : bb_vector)
+                {
+                        if (bb->index != block->index)
+                        {
+                                printf("%i ",block->index);
+                        }
+                }
+                printf("\n");
+        }
+        free_dominance_info(fun, CDI_DOMINATORS);
+}
+
+void print_strictly_post_dominated(function * fun)
+{
+        basic_block bb;
+        //gimple_stmt_iterator gsi;
+        calculate_dominance_info(CDI_POST_DOMINATORS);
+        FOR_ALL_BB_FN(bb,fun)
+        {
+                vec<basic_block> bb_vector;
+                bb_vector = get_all_dominated_blocks(CDI_POST_DOMINATORS,bb);
+                printf("Basic blocks strictly post dominated by bb %i\n",bb->index);
+
+                for (auto const & block : bb_vector)
+                {
+                        if (bb->index != block->index)
+                        {
+                                printf("%i ",block->index);
+                        }
+                }
+                printf("\n");
+        }
+        free_dominance_info(fun, CDI_POST_DOMINATORS);
+}
+
diff --git a/functions/dominance.h b/functions/dominance.h
new file mode 100644
index 0000000000000000000000000000000000000000..8399a9a892c240774666d05c1d00d8c0dafef556
--- /dev/null
+++ b/functions/dominance.h
@@ -0,0 +1,9 @@
+#ifndef __DOMDD__H
+#define __DOMDD__H
+
+void print_dominance(function * fun);
+void print_post_dominance(function * fun);
+void print_strictly_dominated(function * fun);
+void print_strictly_post_dominated(function * fun);
+
+#endif
diff --git a/functions/graph.c b/functions/graph.c
new file mode 100644
index 0000000000000000000000000000000000000000..d24ab1b55c932794b63c97a9a74e59cd7f43a55a
--- /dev/null
+++ b/functions/graph.c
@@ -0,0 +1,109 @@
+#include "graph.h"
+
+/* Build a filename (as a string) based on function name */
+char * cfgviz_generate_filename( function * fun, const char * suffix )
+{
+        char * target_filename ;
+
+        target_filename = (char *)xmalloc( 1024 * sizeof( char ) ) ;
+
+        snprintf( target_filename, 1024, "%s_%s_%d_%s.dot",
+                        current_function_name(),
+                        LOCATION_FILE( fun->function_start_locus ),
+                        LOCATION_LINE( fun->function_start_locus ),
+                        suffix ) ;
+
+        return target_filename ;
+}
+
+/* Dump the graphviz representation of function 'fun' in file 'out' */
+void cfgviz_internal_dump( function * fun, FILE * out, int td )
+{
+        basic_block bb;
+
+        // Print the header line and open the main graph
+        fprintf(out, "Digraph G{\n");
+
+
+
+        /******************************/
+        /****   TD2 - QUESTION 7   ****/
+        /******************************/
+
+
+
+        FOR_ALL_BB_FN(bb,cfun)
+        {
+
+                //
+                // Print the basic block BB, with the MPI call if necessary
+                //
+
+                //printf("before test aux : %p\n",bb->aux);
+                //printf("now testing if MPI call...\n");
+		if ((bb->aux != NULL) && (*((int *)bb->aux) != LAST_AND_UNUSED_MPI_COLLECTIVE_CODE) && (*((int *)bb->aux) >= 0))
+                {
+                        //printf("Printing MPI function name\n");
+                        //printf("after test aux : %p\n",bb->aux);
+                        int code = *((int *)bb->aux);
+                        const char *name = mpi_collective_name[code];
+                        //printf("Function name to be added to graph : %s, code : %i\n",name,code);
+                        fprintf( out,
+                                        "%d [label=\"BB %d %s\" shape=ellipse]\n",
+                                        bb->index,
+                                        bb->index,
+                                        name
+                                   ) ;
+                } else {
+                        fprintf( out,
+                                        "%d [label=\"BB %d\" shape=ellipse]\n",
+                                        bb->index,
+                                        bb->index
+                                   ) ;
+                }
+                //
+                // Process output edges 
+                //
+                edge_iterator eit;
+		edge e;
+
+                FOR_EACH_EDGE( e, eit, bb->succs )
+                {
+                        const char *label = "";
+                        if( e->flags == EDGE_TRUE_VALUE )
+                                label = "true";
+                        else if( e->flags == EDGE_FALSE_VALUE )
+                                label = "false";
+
+                        fprintf( out, "%d -> %d [color=red label=\"%s\"]\n",
+                                        bb->index, e->dest->index, label ) ;
+
+                }
+        }
+        /******************************/
+        /**   TD2 - FIN QUESTION 7   **/
+        /******************************/
+
+
+        // Close the main graph
+        fprintf(out, "}\n");
+}
+
+void cfgviz_dump( function * fun, const char * suffix, int td )
+{
+        char * target_filename ;
+        FILE * out ;
+
+        target_filename = cfgviz_generate_filename( fun, suffix ) ;
+
+        printf( "[GRAPHVIZ] Generating CFG of function %s in file <%s>\n",
+                        current_function_name(), target_filename ) ;
+
+        out = fopen( target_filename, "w" ) ;
+
+        cfgviz_internal_dump( fun, out, td ) ;
+
+        fclose( out ) ;
+        free( target_filename ) ;
+}
+
diff --git a/functions/graph.h b/functions/graph.h
new file mode 100644
index 0000000000000000000000000000000000000000..4a2612a7d0294e82327c225bcc81481b625d01c8
--- /dev/null
+++ b/functions/graph.h
@@ -0,0 +1,7 @@
+#ifndef __GRAPHDD__H
+#define __GRAPHDD__H
+
+char * cfgviz_generate_filename(function * fun, const char * suffix);
+void cfgviz_internal_dump( function * fun, FILE * out, int td);
+void cfgviz_dump( function * fun, const char * suffix, int td);
+#endif
diff --git a/libplugin.so b/libplugin.so
deleted file mode 100755
index 97d39a670503e60fa206df47ea639a11afce5881..0000000000000000000000000000000000000000
Binary files a/libplugin.so and /dev/null differ
diff --git a/plugin b/plugin
deleted file mode 100755
index 62ebe8f26368633ec22acc9f138a7074fd8bdb65..0000000000000000000000000000000000000000
Binary files a/plugin and /dev/null differ
diff --git a/plugin.cpp b/plugin.cpp
index e1fa0228992337eb1377ba239178403638ed2c86..d87b34789f412dd0bb21aa3f1f8472ce53cdde4b 100755
--- a/plugin.cpp
+++ b/plugin.cpp
@@ -12,6 +12,17 @@
 #include "vec.h"
 #include <string.h>
 
+// Project headers
+#include "./functions/MPI_types.h"
+#include "./functions/aux_values.h"
+#include "./functions/aux_values.c"
+#include "./functions/dominance.h"
+#include "./functions/dominance.c"
+#include "./functions/graph.h"
+#include "./functions/graph.c"
+#include "./functions/MPI_functions.h"
+#include "./functions/MPI_functions.c"
+
 int plugin_is_GPL_compatible;
 
 const pass_data my_pass_data =
@@ -31,8 +42,8 @@ const pass_data my_pass_data =
 
 static void my_pragma_action(cpp_reader *ARG_UNUSED(dummy))
 {
-	printf("****** Pragam detected: ******\n");
-	printf("\n\n");
+	printf("****** Pragma detected: ******\n");
+	printf("\n");
 }
 
 
@@ -70,6 +81,7 @@ class my_pass : public gimple_opt_pass
                 unsigned int execute (function *fun)
                 {
                         printf("plugin: execute...\n");
+			edit_all_aux_value(fun,(int*)NULL);
 			return 0;
                 }
 };