void Function::comput_succ_pred_BB(){ list<Basic_block*>::iterator it, it2; Basic_block *current; Instruction *instr; Basic_block *succ=NULL; // IMPORTANT ne pas enlever la ligne ci-dessous if (BB_pred_succ) return; int size= (int) _myBB.size(); it=_myBB.begin(); current=*it; cout<<"debut comput succ pred bb"<<endl; for (int i=0; i<size; i++){ current=*it; it2 = it; instr = (Instruction*)current->get_branch(); if(instr != NULL) { if(instr->get_opcode() != j && instr->get_opcode() != jal && instr->get_opcode() != jalr && instr->get_opcode() != jr){ Basic_block* suc1 = find_label_BB(instr->get_op_label()); it2++; Basic_block *suc2 = *it2; current->set_link_succ_pred(suc1); current->set_link_succ_pred(suc2); } else{ if(instr->get_opcode() == j){ Basic_block *suc = find_label_BB(instr->get_op_label()); current->set_link_succ_pred(suc); } else { if(instr->is_call()){ it2++; Basic_block *suc = *it2; current->set_link_succ_pred(suc); } } } it++; } else { it++; Basic_block *tmp = *it; if(tmp != NULL) current->set_link_succ_pred(tmp); } } cout<<"fin comput succ pred bb"<<endl; // ne pas enlever la ligne ci-dessous BB_pred_succ = true; return; }
// NB : penser utiliser la méthode set_link_succ_pred(Basic_block *) de la classe Basic_block void Function::comput_succ_pred_BB(){ list<Basic_block*>::iterator it, it2; Basic_block *current; Instruction *instr; int nbi; Operand* op; Basic_block *succ=NULL; int size= (int) _myBB.size(); // nombre de BB it=_myBB.begin(); //1er BB //remarque : le dernier block n'a pas de successeurs for(int i=0; i<size-1; i++) { current = *it; instr = current->get_instruction_at_index(current->get_nb_inst()-2); // si saut if(instr->is_branch()) { // saut conditionnel if(instr->is_cond_branch()) { // ajout suivant current->set_link_succ_pred(*(++it)); // label = op3 op = instr->get_op3(); } else { // label = op1 op = instr->get_op1(); it++; } // ajout du label succ = find_label_BB((dynamic_cast<OPLabel * > (op))); current->set_link_succ_pred(succ); } else { // pas de saut, ajout suivant current->set_link_succ_pred(*(++it)); } } //A REMPLIR }
void Function::compute_live_var(){ int size=(int)_myBB.size(); list<Basic_block*> blocNoSucc; list<Basic_block*> workinglist; list<Basic_block*>::iterator it; Basic_block *current; it=_myBB.begin(); bool* reg=(bool*)malloc(sizeof(bool)*size); cout <<"debut compute_live_var"<< endl; //Trouver les blocs sans successeurs for(int i = 0; i < size; i++){ current = *it; reg[i] = false; if(current->get_nb_succ() == 0){ blocNoSucc.push_back(current); } it++; } //LiveIn = Use while(!blocNoSucc.empty()) { current = blocNoSucc.front(); blocNoSucc.pop_front(); reg[current->get_index()]=true; for(int j = 0;j<NB_REG;j++) { current->LiveIn[j] = current->Use[j]; } for(int p = 0;p<current->get_nb_pred();p++) { workinglist.push_back(current->get_predecessor(p)); } } while(!workinglist.empty()) { current = workinglist.front(); workinglist.pop_front(); if(reg[current->get_index()]) { continue; } else { reg[current->get_index()] = true; } //Calcul de LiveOut if(current->get_successor1() != NULL) { for(int k = 0;k<NB_REG;k++) { if(current->get_successor1()->LiveIn[k]){ current->LiveOut[k] = current->get_successor1()->LiveIn[k]; } } } if(current->get_successor2() != NULL) { for(int l = 0;l<NB_REG;l++) { if(current->get_successor2()->LiveIn[l]){ current->LiveOut[l] = current->get_successor2()->LiveIn[l]; } } } //Calcul de LiveIn for(int m = 0;m<NB_REG;m++) { if(current->Use[m]) { current->LiveIn[m] = current->Use[m]; } } for(int n = 0;n<NB_REG;n++) { if(!current->Def[n]) { if(current->LiveOut[n]) { current->LiveIn[n] = current->LiveOut[n]; } } } for(int q = 0;q<current->get_nb_pred();q++) { workinglist.push_back(current->get_predecessor(q)); } } cout <<"fin compute_live_var"<< endl; return; }
int main(int argc, char * argv[]){ if (argc < 2) { cout << "erreur : pas de fichier assembleur" << endl; } Program prog(argv[1]); Function* functmp; list <Function*> myfunc; list <Basic_block*> myBB; cout<<"Le programme a "<<prog.size()<<" lignes\n"<<endl; prog.comput_function(); cout<<"nombre de fonctions : "<<prog.nbr_func()<<endl; list<Function*>::iterator itfct; list<Basic_block*>::iterator itbb; Basic_block *bb; int i, j; list<int> frees; Dfg *d; Cfg *c; std::ostringstream *oss ; for(itfct=prog.function_list_begin(), i=0; itfct!=prog.function_list_end(); itfct++, i++){ functmp=*itfct; cout<<"------------Function DISPLAY----------\n" <<endl; functmp->display(); functmp->comput_basic_block(); functmp->comput_label(); functmp->comput_succ_pred_BB(); oss=new std::ostringstream; (*oss)<<"./tmp/func_"<<i<<".dot"; c=new Cfg(functmp->get_BB(0), functmp->nbr_BB()); c->restitution(NULL, oss->str()); cout<<"========== Function "<<i<<"==========="<<endl; cout<<"============================"<<endl; functmp ->compute_live_var(); j=0; int total1 = 0, total2 = 0, total3 = 0, total4 = 0; for(itbb=functmp->bb_list_begin(); itbb!=functmp->bb_list_end(); itbb++, j++){ bb=*itbb; bb->link_instructions(); bb->comput_pred_succ_dep(); total1 += bb->nb_cycles(); d = new Dfg(bb); d->scheduling(false); d->apply_scheduling(); total2 += bb->nb_cycles(); bb->reg_rename(); // il faut annuler le calcul des dépendances et le refaire bb->reset_pred_succ_dep(); bb->comput_pred_succ_dep(); total3 += bb->nb_cycles(); d= new Dfg(bb); d->scheduling(false); d->apply_scheduling(); total4 += bb->nb_cycles(); //return 0; } printf("Nombres de cycles : \n"); printf(" BASIC | SCHEDULED | RENAMED | RE-SCHEDULED\n"); printf(" %d | %d | %d | %d \n", total1, total2, total3, total4); } }
void Function::comput_succ_pred_BB(){ list <Basic_block*> BBtmp; Basic_block * BB = new Basic_block(); /*Calcul des successeurs*/ for(int i=0; i<_myBB.size(); i++){ BB = get_BB(i); if(get_BB(i)->get_end()->get_line()->type_line()==line_Instru){ //si l'instru n'est pas un br alors 1 successeur le BB suivant if(get_BB(i)->get_branch()==NULL && ((i+1) < _myBB.size()) || dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_opcode()==jal || dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_opcode()==jalr ){ BB->set_successor1( get_BB(i+1)); } //si l'instru est un BR inconditiennel 1 successeur le BB pointé par le label else if(dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_opcode()==j){ if(find_label_BB(dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_op1())->get_head()){ //cout<<"coucou1"<<endl; BB->set_successor1(find_label_BB( dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_op1())); } }//cout<<"here too\n";} //si l'instru est un BR conditionnel 2 successeur le BB pointé et le BB suivant else if((dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_opcode()==beq || dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_opcode()==bne) && ((i+1)< _myBB.size())){ if(find_label_BB( dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_op3())->get_head()){ BB->set_successor1(find_label_BB( dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_op3())); } BB->set_successor2(get_BB(i+1)); //cout<<"here too too\n"; } else if(dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_opcode()!=jr && ((i+1)< _myBB.size())){ if(find_label_BB( dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_op2())->get_head()){ BB->set_successor1(find_label_BB( dynamic_cast< Instruction *> (get_BB(i)->get_branch()->get_line())->get_op2())); } BB->set_successor2(get_BB(i+1)); //cout<<"and finaly here too\n"; } //sinon pas de successeur else ; BBtmp.push_back(BB); BB = new Basic_block(); } } _myBB.clear(); list<Basic_block*>::iterator it; it=BBtmp.begin(); for (int i=0; i< BBtmp.size();i++ ){ _myBB.push_back(*it); it++; } /*Calcul des predecesseur*/ for(int i=0;i<_myBB.size(); i++){ for(int j=0; j<_myBB.size(); j++){ //cout<<"nbr de succ de BB"<<j<<" "<<get_BB(j)->get_nbr_succ()<<endl; if(get_BB(j)->get_nbr_succ()){ if(get_BB(i)->get_index() == get_BB(j)->get_successor1()->get_index()){ get_BB(i)->set_predecessor(get_BB(j)); } } if(get_BB(j)->get_nbr_succ()==2){ if(get_BB(i)->get_index() == get_BB(j)->get_successor2()->get_index()){ get_BB(i)->set_predecessor(get_BB(j)); } } } } }
void Function::comput_basic_block(){ Basic_block * BB = new Basic_block(); int i=0; int begin=0; Node* element = _head; //cout<<"entré"<<endl; /*supprime les directives precedent le premier BB*/ while(!begin){ if(element->get_line()->type_line()!=line_Direct){ //cout<<"tete1 "<<element->get_line()->get_content() <<endl; BB->set_head(element); //cout<<BB->get_head()->get_line()->get_content()<<endl; begin=1; } else element= element->get_next(); } while(element != _end) { /*si l'instruction est un branchement alors on prend le delay sot comme dernier element du BB et comme tete l'element qui suit*/ if(element->get_line()->type_line()==line_Instru && element->get_next()->get_line()->type_line()==line_Instru){ if(element->get_line()->get_type()==BR){ //cout<<"fin1 "<<element->get_next()->get_line()->get_content() <<endl; BB->set_branch(element); BB->set_end(element->get_next()); BB->set_index(i); i++; _myBB.push_back(BB); BB = new Basic_block(); BB->set_branch(NULL); if(element->get_next()->get_next()!=_end && element->get_next()!=_end){ //cout<<"tête2 "<<element->get_next()->get_next()->get_line()->get_content() <<endl; BB->set_head(element->get_next()->get_next()); element = element->get_next(); } else break; } } /*si l'instruction suivante est un label alors on prend l'instruction courante comme fin du BB et on prens le suivant comme tete du prochain BB*/ else if(element->get_next()->get_line()->type_line()==line_Lab){ //cout<<"fin3 "<<element->get_line()->get_content() <<endl; BB->set_end(element); BB->set_index(i); i++; _myBB.push_back(BB); //cout<<"tête3 "<<element->get_next()->get_line()->get_content() <<endl; BB = new Basic_block(); BB->set_head(element->get_next()); } if(element->get_next()==_end){ BB->set_end(element); BB->set_index(i); i++; //cout<<"fin4"<<element->get_line()->get_content() <<endl; _myBB.push_back(BB); break; } else element = element->get_next(); } }