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