Skip to content
Extraits de code Groupes Projets
Non vérifiée Valider d0e7bdf5 rédigé par Nicolas MARIE's avatar Nicolas MARIE
Parcourir les fichiers

first commit, start project

parent
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
CC=mpicc
CXX=mpicxx
FLAGS=-Wall -Wextra -Werror -fPIC -fno-rtti
TEST_FLAGS=-Wall -Wextra -Werror -fPIC
LDFLAGS=-shared
INCLUDE=-I ./include
PLUGIN_INCLUDE=$(INCLUDE) -I $(shell $(CC) -print-file-name=plugin)/include
PLUGIN_FLAGS=-fplugin=$(LIBD)/libplugin.so
# Options dependant flags
OPTI_FLAGS=-O2
DEBUG_FLAGS=-g -Og
DEBUG_TEST_FLAGS=-fdump-tree-all -fdump-tree-all-graph
# Comment to disable debug
FLAGS+=$(DEBUG_FLAGS)
TEST_FLAGS+=$(DEBUG_TEST_FLAGS)
# Directories
SRCD=src
OBJD=obj
LIBD=lib
TARGETD=bin
TESTD=test
TESTSRCD=$(SRCD)/test
# Files
SRCS=$(notdir $(wildcard ($(SRCD)/*.cpp))
OBJS=$(addprefix $(OBJD)/, $(SRCS:cpp=o))
.PHONY: plugin
plugin:
mkdir -p $(OBJD)
mkdir -p $(LIBD)
$(MAKE) $(LIBD)/libplugin.so
.PHONY: test
test: $(TESTD)/test2
$(TESTD)/%: $(TESTSRCD)/%.c
$(CC) $(FLAGS) $(PLUGIN_FLAGS) $^ -o $@
$(OBJD)/%.o: $(SRCD)/%.cpp
$(CXX) $(FLAGS) $(PLUGIN_INCLUDE) -c $^ -o $@
$(LIBD)/libplugin.so: $(OBJD)/plugin.o $(OBJD)/pass_mpi_collective.o
$(CXX) $(FLAGS) $(LDFLAGS) $^ -o $@
# removing test scince plugin was rebuild
rm -rf $(TESTD)
.PHONY: clean
clean:
rm -rf $(OBJD)
rm -rf $(TARGETD)
rm -rf $(LIBD)
rm -rf $(TESTD)
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" )
// dependance de tree-pass.H
#include <gcc-plugin.h>
// declare opt_pass
#include <tree-pass.h>
/* 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
class pass_mpi_collective : public opt_pass {
public:
pass_mpi_collective(gcc::context *ctxt);
pass_mpi_collective* clone();
bool gate(function *fun);
unsigned int execute(function *fun);
void print_tree(function *fun);
bool is_func(gimple *stmt);
bool is_mpi_func(gimple *stmt);
mpi_collective_code is_mpi_collec(gimple *stmt);
void split_blocks(function *fun);
private:
bool __is_mpi_func(gimple *stmt);
mpi_collective_code __is_mpi_collec(gimple *stmt);
char *cfgviz_generate_filename(function *fun,
const char *suffix);
void cfgviz_internal_dump(function *fun, FILE *out);
void cfgviz_dump(function *fun, const char *suffix);
};
// dependance of context.h
#include <gcc-plugin.h>
// 'g' global variable
#include <context.h>
// dependance of gimple.h
#include <tree.h>
// dependance of gimple-iterator.h
#include <gimple.h>
// gsi
#include <gimple-iterator.h>
// our pass
#include "pass_mpi_collective.hpp"
// Definitions
const pass_data my_pass_data = {
GIMPLE_PASS, /* type */
"my new ppass", /* name */
OPTGROUP_NONE, /* optinfo_flags */
TV_OPTIMIZE, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
// Class functions
pass_mpi_collective::pass_mpi_collective(gcc::context *ctxt)
: opt_pass(my_pass_data, ctxt){}
pass_mpi_collective* pass_mpi_collective::clone(){
return new pass_mpi_collective(g);
}
bool pass_mpi_collective::gate(function *fun){
//printf("In gate of: %s\n", fndecl_name(fun->decl));
printf("In gate of: %s\n", function_name(fun));
//printf("In gate of: %s\n", current_function_name());
return true;
}
unsigned int pass_mpi_collective::execute(function *fun){
printf("In execute of: %s\n", function_name(fun));
print_tree(fun);
split_blocks(fun);
print_tree(fun);
return 0;
}
void pass_mpi_collective::print_tree(function *fun){
basic_block bb;
gimple_stmt_iterator gsi;
gimple *stmt;
//size_t line;
FOR_EACH_BB_FN(bb, fun){
printf("\tBasic block: %d\n", bb->index);
for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)){
stmt = gsi_stmt(gsi);
//line = gimple_lineno(stmt);
//printf("\tstatement at line = %lu\n", line);
if(is_func(stmt)){
printf("\t\tStatement is a function call (%s)\n", fndecl_name(gimple_call_fndecl(stmt)));
if(__is_mpi_func(stmt)){
printf("\t\t\tStatement is a MPI function call (%s)\n", fndecl_name(gimple_call_fndecl(stmt)));
if(__is_mpi_collec(stmt)){
printf("\t\t\t\tStatement is a MPI statement (%s)\n", fndecl_name(gimple_call_fndecl(stmt)));
}
}
}
}
}
}
bool pass_mpi_collective::is_func(gimple *stmt){
return is_gimple_call(stmt);
}
bool pass_mpi_collective::__is_mpi_func(gimple *stmt){
return strncmp(fndecl_name(gimple_call_fndecl(stmt)), "MPI_", 4) == 0;
}
bool pass_mpi_collective::is_mpi_func(gimple *stmt){
return is_func(stmt) && __is_mpi_func(stmt);
}
mpi_collective_code pass_mpi_collective::__is_mpi_collec(gimple *stmt){
size_t i;
const char * callee_name;
i = 0;
callee_name = fndecl_name(gimple_call_fndecl(stmt));
while(i < LAST_AND_UNUSED_MPI_COLLECTIVE_CODE){
if(strcmp(mpi_collective_name[i], callee_name) == 0)
return (enum mpi_collective_code) i;
++i;
}
return LAST_AND_UNUSED_MPI_COLLECTIVE_CODE;
}
mpi_collective_code pass_mpi_collective::is_mpi_collec(gimple *stmt){
if(!is_mpi_func(stmt))
return LAST_AND_UNUSED_MPI_COLLECTIVE_CODE;
return __is_mpi_collec(stmt);
}
// TODO tag blocks and set bb->data
//void pass_mpi_collective::tag_blocks(){
//}
// TODO clear blocks TAGs
//void pass_mpi_collective::clear_blocks_tag(){
//}
void pass_mpi_collective::split_blocks(function *fun){
basic_block bb;
gimple_stmt_iterator gsi;
gimple *stmt;
size_t nb_collective;
FOR_EACH_BB_FN(bb, fun){
nb_collective = 0;
for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)){
stmt = gsi_stmt(gsi);
if(is_mpi_collec(stmt) != LAST_AND_UNUSED_MPI_COLLECTIVE_CODE)
++nb_collective;
if(nb_collective >= 2)
split_block(bb, stmt);
}
}
}
/* Build a filename (as a string) based on function name */
char *pass_mpi_collective::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 pass_mpi_collective::cfgviz_internal_dump(
function *fun, FILE *out)
{
basic_block bb;
mpi_collective_code code;
edge_iterator eit;
edge e;
fprintf(out, "Digraph G{\n");
FOR_ALL_BB_FN(bb, fun)
{
code = LAST_AND_UNUSED_MPI_COLLECTIVE_CODE;
if(bb->aux != NULL)
code = *((mpi_collective_code*) bb->aux);
fprintf(out, "%d [label=\"BB %d %s\" shape=ellipse]\n",
bb->index, bb->index,
(code == LAST_AND_UNUSED_MPI_COLLECTIVE_CODE ? "" :
mpi_collective_name[code]));
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);
}
}
fprintf(out, "}\n");
}
void pass_mpi_collective::cfgviz_dump(function *fun,
const char *suffix)
{
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);
fclose(out);
free(target_filename);
}
// c printf
#include <cstdio>
// plugin_name_args & plugin_info
#include <gcc-plugin.h>
// pass_data
#include <tree-pass.h>
// 'g' global variable
#include <context.h>
// our pass
#include "pass_mpi_collective.hpp"
/* Global variable required for plugin to execute */
int plugin_is_GPL_compatible;
/* Main entry point for plugin */
int
plugin_init(struct plugin_name_args *plugin_info,
struct plugin_gcc_version *version)
{
printf("plugin_init: Entering...\n");
printf("\tbasever = %s\n", version->basever);
printf("\tdatestamp = %s\n", version->datestamp);
printf("\tdevphase = %s\n", version->devphase);
printf("\trevision = %s\n", version->revision);
printf("\tconfig = %s\n", version->configuration_arguments);
printf("\tbase_name = %s\n", plugin_info->base_name);
printf("\tfull_name = %s\n", plugin_info->full_name);
for(int i = 0; i < plugin_info->argc; ++i)
printf("\t\targ %d: %s = %s\n", i, plugin_info->argv[i].key,
plugin_info->argv[i].value);
printf("\tversion = %s\n", plugin_info->version);
printf("\thelp = %s\n", plugin_info->help);
printf("\n\n");
pass_mpi_collective p(g);
struct register_pass_info pass_info;
pass_info.pass = &p;
pass_info.reference_pass_name = "cfg";
pass_info.ref_pass_instance_number = 0;
pass_info.pos_op = PASS_POS_INSERT_AFTER;
register_callback( plugin_info->base_name,
PLUGIN_PASS_MANAGER_SETUP,
NULL,
&pass_info);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
void mpi_call(int c)
{
MPI_Barrier(MPI_COMM_WORLD);
if(c<10)
{
printf("je suis dans le if (c=%d)\n", c);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
}
else
{
printf("je suis dans le else (c=%d)\n", c);
MPI_Barrier(MPI_COMM_WORLD);
}
}
int main(int argc, char * argv[])
{
MPI_Init(&argc, &argv);
int i;
int a = 2;
int b = 3;
int c=0;
for(i=0; i<10; i++)
{
mpi_call(c);
c+= (a+b);
}
printf("c=%d\n", c);
MPI_Finalize();
return 1;
}
Fichier ajouté
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter