// Calcul flot de données (defs, uses, def_uses) // Attention !! Pour que l'algo fonctionne, il faut que : // les noms des instructions soient des entiers encodés en chaines, // les instructions dans le GFC soient rangées séquentiellement (ou en ordre croissant au-moins) // à l'intérieur d'un bloc (et dans l'ordre des blocs). #include #include #include #define NB_MAX_BLOCKS_CFG 30 #define MAX_LENGTH_NAME_VAR 50 #define MAX_LENGTH_NAME_BLOCK 50 #define MAX_NB_USED_VAR_STATEMENT 10 #define MAX_NB_STATEMENTS_BLOCK 10 #define MAX_NB_NEXT_NODES_STATEMENT 10 #define MAX_NB_PREVIOUS_NODES_STATEMENT 10 #define MAX_DEF (MAX_NB_STATEMENTS_BLOCK*NB_MAX_BLOCKS_CFG) #define MAX_USE (MAX_NB_USED_VAR_STATEMENT*MAX_NB_STATEMENTS_BLOCK) #define MAX_DEF_USE (MAX_USE*MAX_DEF*NB_MAX_BLOCKS_CFG) typedef enum {start_node, middle_node, terminate_node} cfg_graph_type; typedef struct { char name[MAX_LENGTH_NAME_VAR]; } variable; typedef struct { char name[MAX_LENGTH_NAME_VAR]; variable *defined_variable; variable *used_variables[MAX_NB_USED_VAR_STATEMENT]; } statement; typedef struct st_basic_block { char name[MAX_LENGTH_NAME_BLOCK]; statement *statements[MAX_NB_STATEMENTS_BLOCK]; struct st_basic_block *next_nodes[MAX_NB_NEXT_NODES_STATEMENT]; struct st_basic_block *previous_nodes[MAX_NB_PREVIOUS_NODES_STATEMENT]; cfg_graph_type node_type; } basic_block; typedef struct { basic_block *blocks[NB_MAX_BLOCKS_CFG]; int nb_blocks; } cfg_type; // rajout VA typedef struct { variable *var; statement *def_statement; statement *use_statement; } def_use_association; typedef struct { variable *var; statement *statement; } var_association; // rajout VA typedef struct { var_association *def_in[MAX_DEF]; var_association *def_out[MAX_DEF]; var_association *use_out[MAX_USE]; def_use_association *def_use_asso[MAX_DEF_USE]; } def_use_info; // rajout VA typedef def_use_info *info_out_cfg[NB_MAX_BLOCKS_CFG]; statement* create_statement(char name_statement[MAX_LENGTH_NAME_VAR], variable *def_var, variable *used_vars[MAX_NB_USED_VAR_STATEMENT]) { statement *stmt; int i; stmt =(statement*) malloc(sizeof(statement)); strcpy(stmt->name,name_statement); stmt->defined_variable=def_var; if (used_vars != NULL) for(i=0;iused_variables[i]=used_vars[i]; else for(i=0;iused_variables[i]=NULL; return stmt; } void print_statement(statement *stmt) { printf("---------- Statement : %s\n",stmt->name); printf(" with def_var : "); if (stmt->defined_variable != NULL) printf("%s",stmt->defined_variable->name); printf("\n with used_vars : "); int i=0; if (stmt->used_variables != NULL) while ((iused_variables[i]) != NULL)) { printf("%s ",stmt->used_variables[i]->name); i++; } printf("\n\n"); } basic_block* create_block(char name_block[MAX_LENGTH_NAME_BLOCK], statement *stmt_block[MAX_NB_STATEMENTS_BLOCK], basic_block *n_nodes[MAX_NB_NEXT_NODES_STATEMENT], basic_block *p_nodes[MAX_NB_PREVIOUS_NODES_STATEMENT], cfg_graph_type b_type) { basic_block *b; int i; b = (basic_block*) malloc(sizeof(basic_block)); strcpy(b-> name,name_block); b->node_type = b_type; for(i=0;istatements[i] = stmt_block[i]; if (n_nodes != NULL) for(i=0;inext_nodes[i] = n_nodes[i]; else for(i=0;inext_nodes[i] = NULL; if (p_nodes != NULL) for(i=0;iprevious_nodes[i] = p_nodes[i]; else for(i=0;iprevious_nodes[i] = NULL; return b; } void print_block(basic_block *b) { printf("** Block : %s of type : ",b->name); switch (b->node_type) { case start_node : printf("start_node \n"); break; case middle_node : printf("middle_node \n"); break; case terminate_node : printf("terminate_node \n"); break; default : printf("\n"); } printf(" with statements : \n"); int i=0; while ((istatements[i] != NULL)) { print_statement(b->statements[i]); i++; } printf(" with previous nodes : "); i=0; if (b->previous_nodes != NULL) while ((iprevious_nodes[i] != NULL)) { printf("%s ",b->previous_nodes[i]->name); i++; } printf("\n"); printf(" with next nodes : "); i=0; if (b->next_nodes != NULL) while ((inext_nodes[i] != NULL)) { printf("%s ",b->next_nodes[i]->name); i++; } printf("\n\n\n"); } void print_def_use_asso(def_use_association * du) { printf("(%s,%s,%s) ",du->var->name,du->def_statement->name,du->use_statement->name); } void print_var_asso(var_association * du) { printf("(%s,%s) ",du->var->name,du->statement->name); } void print_info_def_uses(cfg_type *cfg,info_out_cfg tab) { int i,j; printf("\n!!!!!!!!!!!!! INFO DEF USES :\n\n"); for(i=0;inb_blocks;i++) { printf("\nInfo def_uses block %d :",i+1); j=0; printf("\n Def_in : "); while((jdef_in[j]!=NULL)) { print_var_asso(tab[i]->def_in[j]); j++; } j=0; printf("\n Def_out : "); while((jdef_out[j]!=NULL)) { print_var_asso(tab[i]->def_out[j]); j++; } j=0; printf("\n Use_out : "); while((juse_out[j]!=NULL)) { print_var_asso(tab[i]->use_out[j]); j++; } j=0; printf("\n Def_use_assos : "); while((jdef_use_asso[j]!=NULL)) { print_def_use_asso(tab[i]->def_use_asso[j]); j++; } printf("\n\n"); } } void print_file_def_use_asso(FILE* f,def_use_association * du) { fprintf(f,"(%s,%s,%s) ",du->var->name,du->def_statement->name,du->use_statement->name); } void print_file_var_asso(FILE* f,var_association * du) { fprintf(f,"(%s,%s) ",du->var->name,du->statement->name); } void print_file_info_def_uses(int n,cfg_type *cfg,info_out_cfg tab) { int i,j; char nom[10]; printf("\n Veuillez donner le nom du fichier de sauvegarde des résultats : "); scanf("%s",nom); FILE *f = fopen(nom, "w"); fprintf(f,"INFO DEF USES pour le programme de choix numéro : %d\n\n",n); for(i=0;inb_blocks;i++) { fprintf(f,"\nInfo def_uses block %d :",i+1); j=0; fprintf(f,"\n Def_in : "); while((jdef_in[j]!=NULL)) { print_file_var_asso(f,tab[i]->def_in[j]); j++; } j=0; fprintf(f,"\n Def_out : "); while((jdef_out[j]!=NULL)) { print_file_var_asso(f,tab[i]->def_out[j]); j++; } j=0; fprintf(f,"\n Use_out : "); while((juse_out[j]!=NULL)) { print_file_var_asso(f,tab[i]->use_out[j]); j++; } j=0; fprintf(f,"\n Def_use_assos : "); while((jdef_use_asso[j]!=NULL)) { print_file_def_use_asso(f,tab[i]->def_use_asso[j]); j++; } } fclose(f); } void print_cfg(cfg_type *cfg) { printf("\nCFG with %d blocks :\n\n",cfg->nb_blocks); int i; for(i=0;i<(cfg->nb_blocks);i++) print_block(cfg->blocks[i]); } /**********************************************************************/ // modèle de l'exemple cfg_type* create_cfg_exemple(void) { cfg_type *cfg; basic_block *b1,*b2,*b3,*b4,*b5,*b6,*b7,*b8; statement *st1,*st2,*st3,*st4,*st5,*st6,*st7,*st8,*st9,*st10,*st11; variable *va,*vb,*vc,*vd; variable *used_vars3[MAX_NB_USED_VAR_STATEMENT], *used_vars4[MAX_NB_USED_VAR_STATEMENT],*used_vars5[MAX_NB_USED_VAR_STATEMENT], *used_vars6[MAX_NB_USED_VAR_STATEMENT],*used_vars7[MAX_NB_USED_VAR_STATEMENT], *used_vars8[MAX_NB_USED_VAR_STATEMENT],*used_vars9[MAX_NB_USED_VAR_STATEMENT], *used_vars10[MAX_NB_USED_VAR_STATEMENT],*used_vars11[MAX_NB_USED_VAR_STATEMENT]; statement *stmt_block1[MAX_NB_STATEMENTS_BLOCK],*stmt_block2[MAX_NB_STATEMENTS_BLOCK], *stmt_block3[MAX_NB_STATEMENTS_BLOCK],*stmt_block4[MAX_NB_STATEMENTS_BLOCK], *stmt_block5[MAX_NB_STATEMENTS_BLOCK],*stmt_block6[MAX_NB_STATEMENTS_BLOCK], *stmt_block7[MAX_NB_STATEMENTS_BLOCK],*stmt_block8[MAX_NB_STATEMENTS_BLOCK]; basic_block *n_nodes1[MAX_NB_NEXT_NODES_STATEMENT],*n_nodes2[MAX_NB_NEXT_NODES_STATEMENT], *n_nodes3[MAX_NB_NEXT_NODES_STATEMENT],*n_nodes4[MAX_NB_NEXT_NODES_STATEMENT], *n_nodes5[MAX_NB_NEXT_NODES_STATEMENT],*n_nodes6[MAX_NB_NEXT_NODES_STATEMENT], *n_nodes7[MAX_NB_NEXT_NODES_STATEMENT]; basic_block *p_nodes2[MAX_NB_PREVIOUS_NODES_STATEMENT],*p_nodes3[MAX_NB_PREVIOUS_NODES_STATEMENT], *p_nodes4[MAX_NB_PREVIOUS_NODES_STATEMENT],*p_nodes5[MAX_NB_PREVIOUS_NODES_STATEMENT], *p_nodes6[MAX_NB_PREVIOUS_NODES_STATEMENT],*p_nodes7[MAX_NB_PREVIOUS_NODES_STATEMENT], *p_nodes8[MAX_NB_PREVIOUS_NODES_STATEMENT]; int i; cfg = (cfg_type*) malloc(sizeof(cfg_type)); cfg->nb_blocks = 8; va = (variable*) malloc(sizeof(variable)); strcpy(va->name,"a"); vb = (variable*) malloc(sizeof(variable)); strcpy(vb->name,"b"); vc = (variable*) malloc(sizeof(variable)); strcpy(vc->name,"c"); vd = (variable*) malloc(sizeof(variable)); strcpy(vd->name,"d"); used_vars3[0]=va; for(i=1;iblocks[0]=create_block("1",stmt_block1,n_nodes1,NULL,start_node); cfg->blocks[1]=create_block("2",stmt_block2,n_nodes2,p_nodes2,middle_node); cfg->blocks[2]=create_block("3",stmt_block3,n_nodes3,p_nodes3,middle_node); cfg->blocks[3]=create_block("4",stmt_block4,n_nodes4,p_nodes4,middle_node); cfg->blocks[4]=create_block("5",stmt_block5,n_nodes5,p_nodes5,middle_node); cfg->blocks[5]=create_block("6",stmt_block6,n_nodes6,p_nodes6,middle_node); cfg->blocks[6]=create_block("7",stmt_block7,n_nodes7,p_nodes7,middle_node); cfg->blocks[7]=create_block("8",stmt_block8,NULL,p_nodes8,terminate_node); return cfg; } // modèle de l'exo4_5 TD8 cfg_type* create_cfg_exo4_5TD8(void) { cfg_type *cfg; basic_block *b1,*b2,*b3,*b4; statement *st1,*st2,*st3,*st4,*st5,*st6,*st7,*st8,*st9,*st10,*st11,*st12,*st13,*st14,*st15,*st16,*st17; variable *vt1,*vt2,*vm,*vn,*vk,*va,*vu1,*vu2,*ve,*vb,*vc,*vd; variable *used_vars1[MAX_NB_USED_VAR_STATEMENT],*used_vars2[MAX_NB_USED_VAR_STATEMENT], *used_vars3[MAX_NB_USED_VAR_STATEMENT], *used_vars4[MAX_NB_USED_VAR_STATEMENT],*used_vars5[MAX_NB_USED_VAR_STATEMENT], *used_vars6[MAX_NB_USED_VAR_STATEMENT],*used_vars7[MAX_NB_USED_VAR_STATEMENT], *used_vars8[MAX_NB_USED_VAR_STATEMENT],*used_vars9[MAX_NB_USED_VAR_STATEMENT], *used_vars10[MAX_NB_USED_VAR_STATEMENT],*used_vars11[MAX_NB_USED_VAR_STATEMENT], *used_vars12[MAX_NB_USED_VAR_STATEMENT],*used_vars13[MAX_NB_USED_VAR_STATEMENT], *used_vars15[MAX_NB_USED_VAR_STATEMENT], *used_vars16[MAX_NB_USED_VAR_STATEMENT],*used_vars17[MAX_NB_USED_VAR_STATEMENT]; statement *stmt_block1[MAX_NB_STATEMENTS_BLOCK],*stmt_block2[MAX_NB_STATEMENTS_BLOCK], *stmt_block3[MAX_NB_STATEMENTS_BLOCK],*stmt_block4[MAX_NB_STATEMENTS_BLOCK]; basic_block *n_nodes1[MAX_NB_NEXT_NODES_STATEMENT],*n_nodes2[MAX_NB_NEXT_NODES_STATEMENT], *n_nodes3[MAX_NB_NEXT_NODES_STATEMENT]; basic_block *p_nodes2[MAX_NB_PREVIOUS_NODES_STATEMENT],*p_nodes3[MAX_NB_PREVIOUS_NODES_STATEMENT], *p_nodes4[MAX_NB_PREVIOUS_NODES_STATEMENT]; int i; cfg = (cfg_type*) malloc(sizeof(cfg_type)); cfg->nb_blocks = 4; vt1 = (variable*) malloc(sizeof(variable)); strcpy(vt1->name,"t1"); vt2 = (variable*) malloc(sizeof(variable)); strcpy(vt2->name,"t2"); vm = (variable*) malloc(sizeof(variable)); strcpy(vm->name,"m"); vn = (variable*) malloc(sizeof(variable)); strcpy(vn->name,"n"); vk = (variable*) malloc(sizeof(variable)); strcpy(vk->name,"k"); va = (variable*) malloc(sizeof(variable)); strcpy(va->name,"a"); vu1 = (variable*) malloc(sizeof(variable)); strcpy(vu1->name,"u1"); vu2 = (variable*) malloc(sizeof(variable)); strcpy(vu2->name,"u2"); ve = (variable*) malloc(sizeof(variable)); strcpy(ve->name,"e"); vb = (variable*) malloc(sizeof(variable)); strcpy(vb->name,"b"); vc = (variable*) malloc(sizeof(variable)); strcpy(vc->name,"c"); vd = (variable*) malloc(sizeof(variable)); strcpy(vd->name,"d"); used_vars1[0]=vm; for(i=1;iblocks[0]=create_block("1",stmt_block1,n_nodes1,NULL,start_node); cfg->blocks[1]=create_block("2",stmt_block2,n_nodes2,p_nodes2,middle_node); cfg->blocks[2]=create_block("3",stmt_block3,n_nodes3,p_nodes3,middle_node); cfg->blocks[3]=create_block("4",stmt_block4,NULL,p_nodes4,terminate_node); return cfg; } // modèle de l'exo6 TD8 cfg_type* create_cfg_exo6TD8(void) { cfg_type *cfg; basic_block *b1,*b2,*b3,*b4,*b5,*b6,*b7; statement *st1,*st2,*st3,*st4,*st5,*st6,*st7,*st8,*st9,*st10,*st11,*st12,*st13,*st14,*st15; variable *va,*vm,*vb,*vn,*vx,*vy,*vt,*vu,*vv,*vz; variable *used_vars1[MAX_NB_USED_VAR_STATEMENT],*used_vars2[MAX_NB_USED_VAR_STATEMENT], *used_vars3[MAX_NB_USED_VAR_STATEMENT], *used_vars4[MAX_NB_USED_VAR_STATEMENT],*used_vars5[MAX_NB_USED_VAR_STATEMENT], *used_vars6[MAX_NB_USED_VAR_STATEMENT],*used_vars7[MAX_NB_USED_VAR_STATEMENT], *used_vars9[MAX_NB_USED_VAR_STATEMENT],*used_vars10[MAX_NB_USED_VAR_STATEMENT], *used_vars12[MAX_NB_USED_VAR_STATEMENT],*used_vars13[MAX_NB_USED_VAR_STATEMENT], *used_vars14[MAX_NB_USED_VAR_STATEMENT],*used_vars15[MAX_NB_USED_VAR_STATEMENT]; statement *stmt_block1[MAX_NB_STATEMENTS_BLOCK],*stmt_block2[MAX_NB_STATEMENTS_BLOCK], *stmt_block3[MAX_NB_STATEMENTS_BLOCK],*stmt_block4[MAX_NB_STATEMENTS_BLOCK], *stmt_block5[MAX_NB_STATEMENTS_BLOCK],*stmt_block6[MAX_NB_STATEMENTS_BLOCK], *stmt_block7[MAX_NB_STATEMENTS_BLOCK]; basic_block *n_nodes1[MAX_NB_NEXT_NODES_STATEMENT],*n_nodes2[MAX_NB_NEXT_NODES_STATEMENT], *n_nodes3[MAX_NB_NEXT_NODES_STATEMENT],*n_nodes4[MAX_NB_NEXT_NODES_STATEMENT], *n_nodes5[MAX_NB_NEXT_NODES_STATEMENT],*n_nodes6[MAX_NB_NEXT_NODES_STATEMENT]; basic_block *p_nodes2[MAX_NB_PREVIOUS_NODES_STATEMENT],*p_nodes3[MAX_NB_PREVIOUS_NODES_STATEMENT], *p_nodes4[MAX_NB_PREVIOUS_NODES_STATEMENT],*p_nodes5[MAX_NB_PREVIOUS_NODES_STATEMENT], *p_nodes6[MAX_NB_PREVIOUS_NODES_STATEMENT],*p_nodes7[MAX_NB_PREVIOUS_NODES_STATEMENT]; int i; cfg = (cfg_type*) malloc(sizeof(cfg_type)); cfg->nb_blocks = 7; va = (variable*) malloc(sizeof(variable)); strcpy(va->name,"a"); vm = (variable*) malloc(sizeof(variable)); strcpy(vm->name,"m"); vb = (variable*) malloc(sizeof(variable)); strcpy(vb->name,"b"); vn = (variable*) malloc(sizeof(variable)); strcpy(vn->name,"n"); vx = (variable*) malloc(sizeof(variable)); strcpy(vx->name,"x"); vy = (variable*) malloc(sizeof(variable)); strcpy(vy->name,"y"); vt = (variable*) malloc(sizeof(variable)); strcpy(vt->name,"t"); vu = (variable*) malloc(sizeof(variable)); strcpy(vu->name,"u"); vv = (variable*) malloc(sizeof(variable)); strcpy(vv->name,"v"); vz = (variable*) malloc(sizeof(variable)); strcpy(vz->name,"z"); used_vars1[0]=vm; for(i=1;iblocks[0]=create_block("1",stmt_block1,n_nodes1,NULL,start_node); cfg->blocks[1]=create_block("2",stmt_block2,n_nodes2,p_nodes2,middle_node); cfg->blocks[2]=create_block("3",stmt_block3,n_nodes3,p_nodes3,middle_node); cfg->blocks[3]=create_block("4",stmt_block4,n_nodes4,p_nodes4,middle_node); cfg->blocks[4]=create_block("5",stmt_block5,n_nodes5,p_nodes5,middle_node); cfg->blocks[5]=create_block("6",stmt_block6,n_nodes6,p_nodes6,middle_node); cfg->blocks[6]=create_block("7",stmt_block7,NULL,p_nodes7,terminate_node); return cfg; } // modèle de l'exo7 TD8 cfg_type* create_cfg_exo7TD8(void) { cfg_type *cfg; basic_block *b1,*b2,*b3,*b4,*b5,*b6; statement *st1,*st2,*st3,*st4,*st5,*st6,*st7,*st8,*st9,*st10,*st11,*st12,*st13,*st14,*st15, *st16,*st17,*st18,*st19,*st20,*st21,*st22,*st23; variable *va,*vb,*vx,*vy,*vi,*vd,*ve,*vz,*vc; variable *used_vars1[MAX_NB_USED_VAR_STATEMENT],*used_vars2[MAX_NB_USED_VAR_STATEMENT], *used_vars3[MAX_NB_USED_VAR_STATEMENT],*used_vars4[MAX_NB_USED_VAR_STATEMENT], *used_vars5[MAX_NB_USED_VAR_STATEMENT],*used_vars6[MAX_NB_USED_VAR_STATEMENT], *used_vars8[MAX_NB_USED_VAR_STATEMENT], *used_vars9[MAX_NB_USED_VAR_STATEMENT],*used_vars10[MAX_NB_USED_VAR_STATEMENT], *used_vars11[MAX_NB_USED_VAR_STATEMENT],*used_vars12[MAX_NB_USED_VAR_STATEMENT], *used_vars13[MAX_NB_USED_VAR_STATEMENT],*used_vars14[MAX_NB_USED_VAR_STATEMENT], *used_vars15[MAX_NB_USED_VAR_STATEMENT],*used_vars16[MAX_NB_USED_VAR_STATEMENT], *used_vars18[MAX_NB_USED_VAR_STATEMENT], *used_vars19[MAX_NB_USED_VAR_STATEMENT],*used_vars20[MAX_NB_USED_VAR_STATEMENT], *used_vars21[MAX_NB_USED_VAR_STATEMENT],*used_vars22[MAX_NB_USED_VAR_STATEMENT], *used_vars23[MAX_NB_USED_VAR_STATEMENT]; statement *stmt_block1[MAX_NB_STATEMENTS_BLOCK],*stmt_block2[MAX_NB_STATEMENTS_BLOCK], *stmt_block3[MAX_NB_STATEMENTS_BLOCK],*stmt_block4[MAX_NB_STATEMENTS_BLOCK], *stmt_block5[MAX_NB_STATEMENTS_BLOCK],*stmt_block6[MAX_NB_STATEMENTS_BLOCK]; basic_block *n_nodes1[MAX_NB_NEXT_NODES_STATEMENT],*n_nodes2[MAX_NB_NEXT_NODES_STATEMENT], *n_nodes3[MAX_NB_NEXT_NODES_STATEMENT],*n_nodes4[MAX_NB_NEXT_NODES_STATEMENT], *n_nodes5[MAX_NB_NEXT_NODES_STATEMENT]; basic_block *p_nodes2[MAX_NB_PREVIOUS_NODES_STATEMENT],*p_nodes3[MAX_NB_PREVIOUS_NODES_STATEMENT], *p_nodes4[MAX_NB_PREVIOUS_NODES_STATEMENT],*p_nodes5[MAX_NB_PREVIOUS_NODES_STATEMENT], *p_nodes6[MAX_NB_PREVIOUS_NODES_STATEMENT]; int i; cfg = (cfg_type*) malloc(sizeof(cfg_type)); cfg->nb_blocks = 6; va = (variable*) malloc(sizeof(variable)); strcpy(va->name,"a"); vb = (variable*) malloc(sizeof(variable)); strcpy(vb->name,"b"); vx = (variable*) malloc(sizeof(variable)); strcpy(vx->name,"x"); vy = (variable*) malloc(sizeof(variable)); strcpy(vy->name,"y"); vi = (variable*) malloc(sizeof(variable)); strcpy(vi->name,"i"); vd = (variable*) malloc(sizeof(variable)); strcpy(vd->name,"d"); ve = (variable*) malloc(sizeof(variable)); strcpy(ve->name,"e"); vc = (variable*) malloc(sizeof(variable)); strcpy(vc->name,"c"); vz = (variable*) malloc(sizeof(variable)); strcpy(vz->name,"z"); used_vars1[0]=va; for(i=1;iblocks[0]=create_block("1",stmt_block1,n_nodes1,NULL,start_node); cfg->blocks[1]=create_block("2",stmt_block2,n_nodes2,p_nodes2,middle_node); cfg->blocks[2]=create_block("3",stmt_block3,n_nodes3,p_nodes3,middle_node); cfg->blocks[3]=create_block("4",stmt_block4,n_nodes4,p_nodes4,middle_node); cfg->blocks[4]=create_block("5",stmt_block5,n_nodes5,p_nodes5,middle_node); cfg->blocks[5]=create_block("6",stmt_block6,NULL,p_nodes6,terminate_node); return cfg; } /**********************************************************************/ // Data flow analysis code /**********************************************************************/ // rend l'indice dans cfg->blocks du bloc b (à partir de son nom) ou -1 int search_block_in_cfg(cfg_type* cfg, basic_block* b) { int i=0, res=-1; while((inb_blocks)&&(strcmp(cfg->blocks[i]->name,b->name))) i++; if (inb_blocks) res=i; return res; } // recherche une def de var dans le bloc b (rend 0 ou 1) int present_def_stmt_block(variable* var, basic_block* b) { int i=0; while ((istatements[i] != NULL)) { if ((b->statements[i]->defined_variable != NULL)&&(!strcmp(b->statements[i]->defined_variable->name, var->name))) return 1; else i++; } return 0; } // recherche une def de var dans un ens de defs, à partir de la def d'indice begin (inclue) // rend -1 ou l'indice dans defs int present_def_block(variable* var, var_association* defs[MAX_DEF], int begin) { int i=begin,res=-1; while((ivar->name,var->name)) { res = i; i = MAX_DEF; } i++; } return res; } // recherche une def de var dans la totalité d'un ens de defs // rend -1 ou l'indice dans defs int present_def_all_block(variable* var, var_association* defs[MAX_DEF]) { int i=0,res=-1; while((ivar->name,var->name)) { res = i; i = MAX_DEF; } i++; } return res; } // rend -1 ou l'indice de l'instruction, dans le bloc d'indice ind_block (dans cfg), avec la dernière def de var // strictement avant stmt // rend -1 ou l'indice dans le bloc int last_def_block(cfg_type* cfg, int ind_block, variable* var, statement* stmt) { int i=0,res=-1,end; basic_block * b = cfg->blocks[ind_block]; end = atoi(stmt->name); while((istatements[i]!=NULL)) { if ((b->statements[i]->defined_variable != NULL) && !strcmp(b->statements[i]->defined_variable->name,var->name) &&(atoi(b->statements[i]->name) < end)) if (res == -1) res = i; else if (atoi(b->statements[i]->name) > atoi(b->statements[res]->name)) res = i; i++; } return res; } // supprime dans defs toutes les defs de var strictement postérieures à l'instruction begin void delete_def_info_block(variable* var, var_association* defs[MAX_DEF], statement* begin) { int i=0,last=MAX_DEF-1; while ((last>=0)&&(defs[last]==NULL)) last--; if (last==-1) return; while((ivar->name,var->name) && strcmp(defs[i]->statement->name,begin->name)) { defs[i]=defs[last]; defs[last]=NULL; last--; } else i++; } // rend l'indice du bloc dans cfg contenant l'instruction stmt, ou NULL basic_block* get_block_of_inst(cfg_type* cfg, statement* stmt) { int i,j; for(i=0;inb_blocks;i++) { j=0; while((jblocks[i]->statements[j] != NULL)) { if (!strcmp(stmt->name,cfg->blocks[i]->statements[j]->name)) return cfg->blocks[i]; j++; } } return NULL; } // rend l'indice dans le bloc b de l'instruction stmt, ou -1 int get_indice_in_block_of_inst(basic_block* b, statement* stmt) { int i=0; while((istatements[i] != NULL)) { if (stmt == b->statements[i]) return i; i++; } return -1; } // teste l'égalité de 2 vars_assos : même nom, même instruction int are_equals_vars_assos(var_association* asso1, var_association* asso2) { return !strcmp(asso1->var->name,asso2->var->name)&&!strcmp(asso1->statement->name,asso2->statement->name); } // teste si la def asso est dans l'ens de defs defs int search_var_asso(var_association* asso, var_association* defs[MAX_DEF]) { int i=0; while((ivar->name,asso2->var->name)&&!strcmp(asso1->def_statement->name,asso2->def_statement->name) &&!strcmp(asso1->use_statement->name,asso2->use_statement->name); } // teste si la def_use_asso asso est dans l'ens de def_uses_assos du int search_def_use_asso(def_use_association* asso, def_use_association* du[MAX_DEF_USE]) { int i=0; while((iname); intuse = atoi(use_stmt->name); while ((istatements[i] != NULL)) { if ((b->statements[i]->defined_variable != NULL) && !strcmp(b->statements[i]->defined_variable->name, var->name) && atoi(b->statements[i]->name)>intdef && atoi(b->statements[i]->name)name); while ((istatements[i] != NULL)) { if ((b->statements[i]->defined_variable != NULL) && !strcmp(b->statements[i]->defined_variable->name, var->name) && atoi(b->statements[i]->name)name); // we check until the last statement (included) while((istatements[i] != NULL)) { if ((b->statements[i]->defined_variable != NULL) && !strcmp(b->statements[i]->defined_variable->name, var->name) && atoi(b->statements[i]->name)>intdef) return 0; i++; } return 1; } // teste s'il existe un chemin sans def de var dans les blocs entre def_block et use_block // already_seen contient les blocs déjà parcourus pour ne pas risquer de suivre des chemins en cycle int cfg_path_without_redef(cfg_type* cfg, variable* var, basic_block* def_block, basic_block* use_block, info_out_cfg info_out, basic_block* already_seen[NB_MAX_BLOCKS_CFG]) { int i=0,ib,j,absent=1,res; basic_block* b; // cas chemin direct def-use : cfg-path terminé while((iprevious_nodes[i] != NULL)) if (!strcmp(def_block->name,use_block->previous_nodes[i]->name)) return 1; else i++; i=0; while((iprevious_nodes[i] != NULL)) { b = use_block->previous_nodes[i]; ib = search_block_in_cfg(cfg,b); if (ib==-1) printf("\n\nError predecessor block not find in cfg !!\n\n"); else { // on recharge b à partir de cfg->blocks car les blocks pointés par previous_nodes ne sont pas // complétement à jour (cf. fcts create-cfg...) b = cfg->blocks[ib]; // verif si bloc pred b pas déjà parcouru j=0; while ((jname,b->name)) absent = 0; else j++; if (absent) { if (jstatements[i] != NULL)) { //parcours des instructions rangées en ordre séquentiel // ecl : algo statement local(b->statements[i],du_info); stmt = b->statements[i]; j=0; if (stmt->used_variables != NULL) while ((jused_variables[j] != NULL)) { // ecl : add use(stmt->used_variables[j],stmt); // ecl : add def_use(stmt->used_variables[j],stmt_def,stmt); var_asso = (var_association*) malloc(sizeof(var_association)); var_asso->var = stmt->used_variables[j]; var_asso->statement = stmt; du_info->use_out[nb_uses] = var_asso; // ajout d'une use dans use_out nb_uses++; ind_def_stmt = present_def_all_block(var_asso->var,du_info->def_out); if ((ind_def_stmt != -1) && block_path_without_redef(var_asso->var,b,du_info->def_out[ind_def_stmt]->statement,stmt)) { du_asso = (def_use_association*) malloc(sizeof(def_use_association)); du_asso->var = var_asso->var; du_asso->def_statement = du_info->def_out[ind_def_stmt]->statement; du_asso->use_statement = stmt; du_info->def_use_asso[nb_def_uses] = du_asso; // ajout d'une asso def_use nb_def_uses++; } j++; } // ecl : add def(stmt->defined_variable,stmt); if (stmt->defined_variable != NULL) { pres_def = present_def_all_block(stmt->defined_variable,du_info->def_out); if (pres_def == -1) { var_asso = (var_association*) malloc(sizeof(var_association)); var_asso->var = stmt->defined_variable; var_asso->statement = stmt; du_info->def_out[nb_defs] = var_asso; // ajout d'une def dans def_out nb_defs++; } else du_info->def_out[pres_def]->statement = stmt; // maj/écrasement de la def précédente (de la même var) dans def_out } i++; } } // calcule l'info def_use au niveau local pour tout le cfg void algo_def_uses_local(cfg_type* cfg, info_out_cfg info_out) { int i,j; def_use_info* dui; printf("\n\n -> local algo \n"); // init info_out à vide for(i=0;i<(cfg->nb_blocks);i++) { dui = (def_use_info*) malloc(sizeof(def_use_info)); info_out[i] = dui; for(j=0;jdef_in[j]=NULL; info_out[i]->def_out[j]=NULL; } for(j=0;juse_out[j]=NULL; for(j=0;jdef_use_asso[j]=NULL; } for(i=cfg->nb_blocks;inb_blocks);i++) algo_block_local(cfg->blocks[i],info_out[i]); } // Mise à jour des def_in du bloc d'indice b (dans cfg) avec les def_out de son prédécesseur d'indice p dans cfg void info_add_defs_in(info_out_cfg info_temp, int b, int p) { int ib=0,ip=0; if (info_temp[p]->def_out == NULL) return; if (info_temp[b]->def_in != NULL) while((ibdef_in[ib] != NULL)) ib++; if (ib == MAX_DEF) { printf("\n\nError ! Block %d def_in full. Need to increase MAX_DEF value.\n\n",b); return; } while((ipdef_out[ip] != NULL)) { if (!(search_var_asso(info_temp[p]->def_out[ip],info_temp[b]->def_in))) { info_temp[b]->def_in[ib] = info_temp[p]->def_out[ip]; ib++; } ip++; } } // teste si le point fixe est atteint, i.e. si tous les blocs ont même def_in et def_out dans info_out_new et info_out int point_fixe(cfg_type* cfg, info_out_cfg info_out_new,info_out_cfg info_out) { int i,j,idem=1; for(i=0;i<(cfg->nb_blocks);i++) { j=0; while(idem&&(jdef_in[j] != NULL)&&(info_out[i]->def_in[j] != NULL)) { idem = idem && are_equals_vars_assos(info_out_new[i]->def_in[j],info_out[i]->def_in[j]); j++; } if (!idem) return 0; if (jdef_in[j] == NULL)&&(info_out[i]->def_in[j] == NULL); if (!idem) return 0; j=0; while(idem&&(jdef_out[j] != NULL)&&(info_out[i]->def_out[j] != NULL)) { idem = idem && are_equals_vars_assos(info_out_new[i]->def_out[j],info_out[i]->def_out[j]); j++; } if (!idem) return 0; if (jdef_out[j] == NULL)&&(info_out[i]->def_out[j] == NULL); if (!idem) return 0; } return idem; } // calcule une itération de l'info def_use au niveau global pour le bloc d'indice ind_block dans cfg void algo_block_global(cfg_type* cfg, info_out_cfg info_out, int ind_block) { int i=0,j=0,k,nb_defs=0,nb_uses=0,nb_def_uses=0,pres_def,ind_def_stmt,ind_use_stmt; basic_block* b = cfg->blocks[ind_block]; int ib = search_block_in_cfg(cfg,b); def_use_info* du_info = info_out[ind_block]; statement* stmt, *def_stmt; basic_block* def_block; var_association* var_asso; def_use_association* du_asso; // init/maj de def_out à partir de def_in while((jdef_out[j]!=NULL)) j++; while((idef_in[i]!=NULL)) { if (!(search_var_asso(du_info->def_in[i],du_info->def_out))) { du_info->def_out[j] = du_info->def_in[i]; j++; } i++; } i=0; while ((istatements[i] != NULL)) { //parcours des instructions rangées en ordre séquentiel // ecl : algo statement global(b->statements[i],du_info); partie uses et defs stmt = b->statements[i]; j=0; if (stmt->used_variables != NULL) while ((jused_variables[j] != NULL)) { // ecl : add use(stmt->used_variables[j],stmt); var_asso = (var_association*) malloc(sizeof(var_association)); var_asso->var = stmt->used_variables[j]; var_asso->statement = stmt; du_info->use_out[nb_uses] = var_asso; // ajout d'une use dans use_out nb_uses++; j++; } // ecl : add def(stmt->defined_variable,stmt); if (stmt->defined_variable != NULL) { pres_def = present_def_all_block(stmt->defined_variable,du_info->def_out); if (pres_def == -1) { var_asso = (var_association*) malloc(sizeof(var_association)); var_asso->var = stmt->defined_variable; var_asso->statement = stmt; du_info->def_out[nb_defs] = var_asso; // ajout d'une def dans def_out nb_defs++; } else { du_info->def_out[pres_def]->statement = stmt; // maj/écrasement de la première def de la (même) var delete_def_info_block(stmt->defined_variable,du_info->def_out,stmt); } } i++; } i=0; while (iuse_out[i]; stmt = var_asso->statement; ind_use_stmt = get_indice_in_block_of_inst(b,stmt); ind_def_stmt = present_def_all_block(var_asso->var,du_info->def_in); while (ind_def_stmt != -1) { // ecl : add def_use(var_asso->var,stmt_def,stmt); def_stmt = du_info->def_in[ind_def_stmt]->statement; def_block = get_block_of_inst(cfg,def_stmt); if (def_block != NULL) if (!strcmp(b->name,def_block->name)&&(atoi(def_stmt->name) < atoi(stmt->name))) { if (block_path_without_redef(var_asso->var,b,def_stmt,stmt)) { du_asso = (def_use_association*) malloc(sizeof(def_use_association)); du_asso->var = var_asso->var; du_asso->def_statement = def_stmt; du_asso->use_statement = stmt; du_info->def_use_asso[nb_def_uses] = du_asso; nb_def_uses++; // ajout d'une asso def_use intra-bloc } } else { basic_block* already_seen[NB_MAX_BLOCKS_CFG]; already_seen[0] = b; for(k=1;kvar,def_block,def_stmt); int clear_path2=cfg_path_without_redef(cfg,var_asso->var,def_block,b,info_out,already_seen); int clear_path3=block_path_without_redef_start(var_asso->var,b,stmt); if (clear_path1 && clear_path2 && clear_path3) { du_asso = (def_use_association*) malloc(sizeof(def_use_association)); du_asso->var = var_asso->var; du_asso->def_statement = def_stmt; du_asso->use_statement = stmt; du_info->def_use_asso[nb_def_uses] = du_asso; nb_def_uses++; // ajout d'une asso def_use inter blocs ou intra-bloc avec boucle } } else printf("\n\nError block not find with def_stmt->name !!\n\n"); ind_def_stmt = present_def_block(var_asso->var,du_info->def_in,ind_def_stmt+1); } //code utile pour (re)calculer les def-uses locales ind_def_stmt = last_def_block(cfg,ib,var_asso->var,stmt); if (ind_def_stmt != -1) { def_stmt = b->statements[ind_def_stmt]; du_asso = (def_use_association*) malloc(sizeof(def_use_association)); du_asso->var = var_asso->var; du_asso->def_statement = def_stmt; du_asso->use_statement = stmt; if (!search_def_use_asso(du_asso,du_info->def_use_asso)) { du_info->def_use_asso[nb_def_uses] = du_asso; nb_def_uses++; } } i++; } } // calcule une itération de l'info def_use au niveau global pour tout le cfg void algo_def_uses_global(cfg_type* cfg, info_out_cfg info_out) { int i; for(i=0;i<(cfg->nb_blocks);i++) algo_block_global(cfg,info_out,i); } // calcule l'info def_use complète au niveau global pour tout le cfg void algo_global(cfg_type* cfg, info_out_cfg info_out) { int i,j,p,boucle=1,num_iter=1,v; def_use_info* dui; info_out_cfg info_sauv; printf("\n\n-> global algo \n"); // init info_out à vide for(i=0;i<(cfg->nb_blocks);i++) { dui = (def_use_info*) malloc(sizeof(def_use_info)); info_out[i] = dui; for(j=0;jdef_in[j]=NULL; info_out[i]->def_out[j]=NULL; } for(j=0;juse_out[j]=NULL; for(j=0;jdef_use_asso[j]=NULL; } for(i=cfg->nb_blocks;inb_blocks);i++) for(j=0;jdef_in[j] = info_sauv[i]->def_in[j]; info_out[i]->def_out[j] = info_sauv[i]->def_out[j]; } while (boucle) { // maj des def_in avec blocs prédécesseurs for(i=0;i<(cfg->nb_blocks);i++) { j=0; while ((jblocks[i]->previous_nodes[j] != NULL)) { p=search_block_in_cfg(cfg,cfg->blocks[i]->previous_nodes[j]); if (p != -1) info_add_defs_in(info_out,i,p); j++; }} algo_def_uses_global(cfg,info_out); printf("\n\n -> global algo - iteration %d \n",num_iter); num_iter++; print_info_def_uses(cfg,info_out); printf("One touch please...\n"); char c=getchar(); boucle = !point_fixe(cfg,info_out,info_sauv); // sauvegarde uniquement des defs (in et out) for(i=0;i<(cfg->nb_blocks);i++) { for(j=0;jdef_in[j] = info_out[i]->def_in[j]; info_sauv[i]->def_out[j] = info_out[i]->def_out[j]; } } } } int main(void) { cfg_type *cfg; info_out_cfg tab_def_use_assos; char c; int n=0; while ((n<=0)||(n>4)) { printf("Program to analyse: \n"); printf(" - example program: 1\n"); printf(" - exo4_5 TD8 program: 2\n"); printf(" - exo6 TD8 program: 3\n"); printf(" - exo7 TD8 program: 4\n"); scanf("%d",&n); c=getchar(); } switch (n) { case 1 : printf("\nCase of the example program\n\n"); cfg = create_cfg_exemple(); break; case 2 : printf("\nCase of the exo4_5 TD8 program\n\n"); cfg = create_cfg_exo4_5TD8(); break; case 3 : printf("\nCase of the exo6 TD8 program\n\n"); cfg = create_cfg_exo6TD8(); break; case 4 : printf("\nCase of the exo7 TD8 program\n\n"); cfg = create_cfg_exo7TD8(); } print_cfg(cfg); printf("CFG creation finished\n\n"); printf("One touch please...\n"); c=getchar(); algo_global(cfg,tab_def_use_assos); printf("\n\nGlobal analysis finished\n\n"); print_info_def_uses(cfg,tab_def_use_assos); print_file_info_def_uses(n,cfg,tab_def_use_assos); printf("Program finished\n"); c=getchar(); return 0; }