Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

cfg.cpp

Go to the documentation of this file.
00001 /*
00002         Copyright (C) 1997 CFU Corporation
00003 
00004         Author: Chao-yinig Fu
00005         Date: Oct. 21 1997
00006 
00007         ^..^
00008         (00)
00009 
00010          $__$
00011         <~00~>
00012          (oo)
00013           ||
00014 
00015         ```````
00016         C ^|^ D
00017          \ O /
00018 */
00019 
00020 #include "cfg.h"
00021 #include "util.h"
00022 #include "lego_util.h"
00023 #include <assert.h>
00024 #include "mst.h"
00025 
00026 //#define CFGDEBUG
00027 #ifdef CFGDEBUG
00028 #define CFGLEVEL 2
00029 #define Cdb(level,format,args...) (CFGLEVEL>=level)?emit_message(format,##args):NULL
00030 #define Cdb_call(level,args...) (CFGLEVEL>=level)?args:NULL
00031 #else
00032 #define Cdb(level,format,args...)
00033 #define Cdb_call(level,args...)
00034 #endif  // CFGDEBUG
00035 
00036 void CFG::build(legoProc *proc_ptr)
00037 {
00038         char *proc_name=proc_ptr->GetProcName();
00039         set_proc_name(proc_name);
00040         int region_count=proc_ptr->GetCount();
00041         Cdb(1,"Proc: %s has %d regions",proc_name,region_count);
00042 
00043         //
00044         // Step 0. Create an exit node and put this node to root
00045         //
00046         Node *a_node=new Node(ExitNodeId);
00047         _exit=new Node_List();
00048         _exit->set_node(a_node);
00049         _root=_exit;    
00050         _node_count++;
00051 
00052         //
00053         // Step 1. build nodes and edges
00054         //
00055         recursive_build(proc_ptr,proc_ptr);
00056 
00057         //
00058         // Step 2. add edge from exit to entry
00059         //
00060         add_edge_from_exit_to_entry();
00061 
00062         Cdb(2,"_in_edge_count=%d _out_edge_count=%d",_in_edge_count,_out_edge_count);
00063         assert(_in_edge_count==_out_edge_count);
00064 }
00065 
00066 //
00067 // This function will recursively call until reach the basic block rgeion
00068 //
00069 void CFG::recursive_build(legoProc *proc_ptr,legoRegion *region_ptr)
00070 {
00071         int sub_region_count;
00072         legoRegion *sub_region_ptr;
00073 
00074         regionTypes region_type=region_ptr->GetRegionType();
00075         
00076         switch(region_type)
00077         {
00078                 case RT_PROC:
00079                 case RT_LOOP:
00080                 case RT_LOOPBODY:
00081                 case RT_TRACE:
00082                 case RT_TREE:
00083                         sub_region_count=region_ptr->GetCount();
00084                         for(int i=0;i<sub_region_count;i++)
00085                         {
00086                                 sub_region_ptr=(legoRegion *)region_ptr->GetItem(i);
00087                                 recursive_build(proc_ptr,sub_region_ptr);
00088                         }
00089                         break;
00090 
00091                 case RT_SB:
00092                 case RT_HB:
00093                 case RT_BB:
00094                         build_one_block(proc_ptr,region_ptr);
00095                         break;
00096 
00097                 default:
00098                         fprintf(stderr,"ERROR region_type\n");
00099                         assert(0);
00100                         break;
00101 
00102         }
00103 }
00104 
00105 //
00106 // build one block (SB, HB or BB)
00107 //
00108 void CFG::build_one_block(legoProc *proc_ptr,legoRegion *region_ptr)
00109 {
00110         regionTypes region_type=region_ptr->GetRegionType();
00111 
00112         assert(region_type==RT_SB || region_type==RT_HB || region_type==RT_BB);
00113 
00114         //
00115         // Step 1. increment _node_count
00116         //
00117         _node_count++;
00118 
00119         //
00120         // Step 2. Create new Node and new Node_List
00121         //
00122         Node *current_node=new Node(region_ptr->GetRegionId());
00123         Node_List *nl=new Node_List();
00124         nl->set_node(current_node);
00125 
00126         //
00127         // Step 3. add to the head of _root
00128         //
00129         if(_root==NULL)
00130         {
00131                 _root=nl;
00132         }
00133         else
00134         {
00135                 nl->set_next_node_list(_root);
00136                 _root=nl;
00137         }
00138 
00139         //
00140         // Step 4. Iterate in_edge to increment _in_edge_count
00141         //
00142         edgeList *edge,*in_edge,*out_edge;
00143         in_edge=region_ptr->GetInEdgesPtr();
00144         out_edge=region_ptr->GetOutEdgesPtr();
00145 
00146         for(edge=in_edge;edge!=NULL;edge=edge->GetNextListPtr())
00147         {
00148                 Cdb(3,">>> in_edge >>> valid=%d",edge->GetValid());
00149 
00150                 if(edge->GetValid()==0)
00151                 {
00152                         //
00153                         // This node is an entry node.
00154                         // Set _entry to it
00155                         //
00156                         if(_entry!=NULL)
00157                                 assert(0);
00158 
00159                         _entry=nl;
00160                 }
00161                 else
00162                 {
00163                         if(edge->GetEdgeId()>_max_edge_id)
00164                                 _max_edge_id=edge->GetEdgeId();
00165 
00166                         _in_edge_count++;
00167 
00169                         //opEdges *an_op_edge=edge->GetEdgePtr();
00170                         //int now_op_id=an_op_edge->GetFromOpId();
00171                         //int now_region_id=find_legoRegion_with_op_id(proc_ptr,now_op_id)->GetRegionId();
00172                         //Node *a_node=new Node(now_region_id);
00173                         //int edge_weight=an_op_edge->GetEdgeAttrListPtr()->GetAttrValPtr()->GetAttrValue();
00174                         //a_node->set_weight(edge_weight);
00175                         //a_node->set_next_node(current_node->next_node());
00176                         //a_node->set_direction(0);     // In
00177                         //a_node->set_edge_id(edge->GetEdgeId());
00178                         //current_node->set_next_node(a_node);
00180                 }
00181         }
00182 
00183         //
00184         // Step 4. Iterate out_edge to increment _out_edge_count and create edge
00185         //
00186         for(edge=out_edge;edge!=NULL;edge=edge->GetNextListPtr())
00187         {
00188                 Cdb(3,">>> out_edge >>> valid=%d",edge->GetValid());
00189 
00190                 if(edge->GetValid()==0)
00191                 {
00192                         //
00193                         // This node is a last node.
00194                         // Create an edge from this node to _exit
00195                         //
00196                         assert(_exit!=NULL);
00197 
00198                         Node *a_node=new Node(ExitNodeId);
00199                         int edge_weight=(int)region_ptr->GetWeight();
00200                         a_node->set_weight(edge_weight);
00201                         a_node->set_next_node(current_node->next_node());
00202                         a_node->set_direction(1);       // Out 
00203                         a_node->set_edge_id(_last_to_exit_edge_id--);
00204                         current_node->set_next_node(a_node);
00205 
00206                         // update _out_edge_count and _in_edge_count
00207                         _out_edge_count++;
00208                         _in_edge_count++;
00209                 }
00210                 else
00211                 {
00212                         if(edge->GetEdgeId()>_max_edge_id)
00213                                 _max_edge_id=edge->GetEdgeId();
00214 
00215                         _out_edge_count++;
00216 
00217                         opEdges *an_op_edge=edge->GetEdgePtr();
00218                         int now_op_id=an_op_edge->GetToOpId();
00219                         legoRegion *lego_block=find_lego_block_with_op_id(proc_ptr,now_op_id);
00220                         assert(lego_block!=NULL);
00221                         int now_region_id=lego_block->GetRegionId();
00222                         Node *a_node=new Node(now_region_id);
00223                         int edge_weight=an_op_edge->GetEdgeAttrListPtr()->GetAttrValPtr()->GetAttrValue();
00224                         a_node->set_weight(edge_weight);
00225                         a_node->set_next_node(current_node->next_node());
00226                         a_node->set_direction(1);       // Out 
00227                         a_node->set_edge_id(edge->GetEdgeId());
00228                         current_node->set_next_node(a_node);
00229                 }
00230         }
00231 }
00232 
00233 //
00234 // Add one edge from _exit to _entry
00235 //
00236 void CFG::add_edge_from_exit_to_entry()
00237 {
00238         // For _entry adjacency list
00239         //Node *n=new Node(_exit->node()->node_id());
00240         //n->set_edge_id(ExitToEntryEdgeId);
00241         //n->set_direction(0);
00242         //n->set_next_node(_entry->node()->next_node());
00243 
00244         int edge_weight=0;
00245         assert(_entry!=NULL);
00246         assert(_exit!=NULL);
00247 
00248         for(Node *adj_list=_entry->node()->next_node();adj_list!=NULL;adj_list=adj_list->next_node())
00249         {
00250                 if(adj_list->direction()==1)
00251                         edge_weight+=adj_list->weight();
00252         }
00253         //n->set_weight(edge_weight);
00254         //_entry->node()->set_next_node(n);
00255         
00256         _in_edge_count++;
00257 
00258         // For _exit adjacency list
00259         Node *n=new Node(_entry->node()->node_id());
00260         n->set_edge_id(ExitToEntryEdgeId);
00261         n->set_direction(1);
00262         n->set_next_node(_exit->node()->next_node());
00263         n->set_weight(edge_weight);
00264         _exit->node()->set_next_node(n);
00265         _out_edge_count++;
00266 }
00267 
00268 void CFG::print(FILE *f)
00269 {
00270         Node_List *nl;
00271         Node *n;
00272 
00273         fprintf(f,"\nCFG-------------------------------------\nProc: %s has %d nodes\n",_proc_name,_node_count);
00274         fprintf(f,"in_edge_count=%d out_edge_count=%d\n",_in_edge_count,_out_edge_count);
00275 
00276         if(_entry!=NULL)
00277         {
00278                 fprintf(f,"Entry node is: %d\n",_entry->node()->node_id());
00279         }
00280         if(_exit!=NULL)
00281         {
00282                 fprintf(f,"Exit node is: %d\n",_exit->node()->node_id());
00283         }
00284 
00285         for(nl=root();nl!=NULL;nl=nl->next_node_list())
00286         {
00287                 n=nl->node();
00288                 fprintf(f,"\nnode_id=%d visit=%d\n",n->node_id(),nl->visit());
00289 
00290                 for(n=n->next_node();n!=NULL;n=n->next_node())
00291                 {
00292                         fprintf(f,"\tnode_id=%d weight=%d edge_id=%d direction=%d\n",n->node_id(),n->weight(),n->edge_id(),n->direction());     
00293                 }
00294         }
00295 }
00296 
00297 Node_List *CFG::find_node(int node_id)
00298 {
00299         Node_List *current_nl;
00300 
00301         for(current_nl=root();current_nl!=NULL;current_nl=current_nl->next_node_list())
00302         {
00303                 Node *node=current_nl->node();
00304                 if(node->node_id()==node_id)
00305                         return current_nl;
00306         }
00307         
00308         // Cannot find_node with node_id
00309         fprintf(stderr,"!!! Cannot find node_id=%d\n",node_id);
00310         assert(0);
00311         return(NULL);
00312 }
00313 
00314 //
00315 // If option=1, set edge_type
00316 // If option=0, don't set edge_type
00317 //
00318 void CFG::dfs(int option)
00319 {
00320         Cdb(1,"CFG::dfs()");
00321 
00322         // Initialization
00323         for(Node_List *nl=_root;nl!=NULL;nl=nl->next_node_list())
00324         {
00325                 nl->set_color(WHITE);
00326                 nl->set_predecessor(NULL);
00327         }
00328 
00329         // Reset time
00330         _time=0;
00331 
00332         //
00333         // Initial topological list
00334         //
00335         _topological_list=new int[_node_count];
00336         _index_of_topological_list=0;
00337 
00338         // Visit from the _entry node of CFG
00339         dfs_visit(_entry,option);
00340 
00341         Cdb(2,"_entry is done");
00342 
00343         // Visit the remainder nodes
00344         for(Node_List *nl=_root;nl!=NULL;nl=nl->next_node_list())
00345         {
00346                 if(nl->color()==WHITE)
00347                 {
00348                         assert(0);
00349                         dfs_visit(nl,option);
00350                 }
00351         }
00352 }
00353 
00354 //
00355 // If option=1, set edge_type
00356 // If option=0, don't set edge_type
00357 //
00358 void CFG::dfs_visit(Node_List *nl,int option)
00359 {
00360         Cdb(1,"CFG::dfs_visit()");
00361         Cdb(2,"Examine start node_id=%d",nl->node()->node_id());
00362 
00363         nl->set_color(GRAY);
00364 
00365         _time++;
00366         nl->set_start_time(_time);
00367 
00368         for(Node *n=nl->node()->next_node();n!=NULL;n=n->next_node())
00369         {
00370                 Cdb(2,"[%d]'s Adjacency list: hidden=%d edge_id=%d direction=%d node_id=%d",nl->node()->node_id(),n->hidden(),n->edge_id(),n->direction(),n->node_id());
00371 
00372                 //
00373                 // Search outgoing edges
00374                 //
00375                 if(n->direction()==1 && n->hidden()==0)
00376                 {
00377                         Cdb(2,"[%d]'s Adjacency list: edge_id=%d (to %d)",nl->node()->node_id(),n->edge_id(),n->node_id());
00378 
00379                         //if(n->edge_type()!=ET_UNDEFINED)
00380                                 //assert(0);
00381 
00382                         Node_List *to_nl=find_node(n->node_id());
00383 
00384                         Color to_nl_color=to_nl->color();
00385                         if(to_nl_color==WHITE)
00386                         {
00387                                 Cdb(2,"Its color is WHITE");
00388 
00389                                 if(option==1)
00390                                 {
00391                                         n->set_edge_type(ET_TREE);
00392                                         Cdb(2,"Its egde type is TREE");
00393                                 }
00394 
00395                                 to_nl->set_predecessor(nl);
00396                                 dfs_visit(to_nl,option);
00397                         }
00398                         else if(to_nl_color==GRAY && option==1)
00399                         {
00400                                 Cdb(2,"Its color is GRAY");
00401                                 if(to_nl!=nl)
00402                                 {
00403                                         n->set_edge_type(ET_BACK);
00404                                         Cdb(2,"Its egde type is BACK");
00405                                 }
00406                                 else
00407                                 {
00408                                         n->set_edge_type(ET_SELFLOOP);
00409                                         Cdb(2,"Its egde type is SELFLOOP");
00410                                 }
00411                         }
00412                         else if(to_nl_color==BLACK && option==1)
00413                         {
00414                                 Cdb(2,"Its color is BLACK");
00415                                 if(nl->start_time() < to_nl->start_time())
00416                                 {
00417                                         n->set_edge_type(ET_FORWARD);
00418                                         Cdb(2,"Its egde type is FORWARD");
00419                                 }
00420                                 else
00421                                 {
00422                                         n->set_edge_type(ET_CROSS);
00423                                         Cdb(2,"Its egde type is CROSS");
00424                                 }
00425                         }
00426                         else if(option==1)
00427                                 assert(0);
00428                 }
00429         }
00430 
00431         nl->set_color(BLACK);
00432 
00433         _time++;
00434         nl->set_finish_time(_time);
00435 
00436         assert(_index_of_topological_list<=_node_count);
00437         _topological_list[_index_of_topological_list]=nl->node()->node_id();
00438         _index_of_topological_list++;
00439 }
00440 
00441 void CFG::print_topological_list()
00442 {
00443         fprintf(stderr,"Topological List\n");
00444 
00445         for(int i=0;i<_index_of_topological_list;i++)
00446         {
00447                 fprintf(stderr,"[%d] %d\n",i,_topological_list[i]);
00448         }
00449 }
00450 
00451 void CFG::print_dfs_tree()
00452 {
00453         Node_List *nl;
00454         Node *n;
00455 
00456         fprintf(stderr,"\nCFG::print_dfs_tree()\n");
00457         fprintf(stderr,"Proc: %s has %d nodes\n",_proc_name,_node_count);
00458         fprintf(stderr,"_in_edge_count=%d _out_edge_count=%d\n",_in_edge_count,_out_edge_count);
00459         fprintf(stderr,"_entry: %d\n",_entry->node()->node_id());
00460         fprintf(stderr,"_exit: %d\n",_exit->node()->node_id());
00461         fprintf(stderr,"_max_edge_id: %d\n",_max_edge_id);
00462 
00463         for(nl=root();nl!=NULL;nl=nl->next_node_list())
00464         {
00465                 n=nl->node();
00466                 fprintf(stderr,"\n_node_id=%d _num_paths=%d _color=",n->node_id(),nl->num_paths());
00467                 print_color(nl->color());
00468 
00469                 for(n=n->next_node();n!=NULL;n=n->next_node())
00470                 {
00471                         //if(n->direction()==1)
00472                         //{
00473                                 fprintf(stderr,"_hidden=%d _node_id=%d _weight=%d _edge_id=%d _direction=%d _num_paths=%d _edge_type=",n->hidden(),n->node_id(),n->weight(),n->edge_id(),n->direction(),n->num_paths());        
00474                                 print_edge_type(n->edge_type());
00475                         //}
00476                 }
00477         }
00478 }
00479 
00480 void CFG::print_edge_type(Edge_Type et)
00481 {
00482         if(et==ET_UNDEFINED)
00483                 fprintf(stderr,"ET_UNDEFINED\n");
00484         else if(et==ET_TREE)
00485                 fprintf(stderr,"ET_TREE\n");
00486         else if(et==ET_BACK)
00487                 fprintf(stderr,"ET_BACK\n");
00488         else if(et==ET_FORWARD)
00489                 fprintf(stderr,"ET_FORWARD\n");
00490         else if(et==ET_CROSS)
00491                 fprintf(stderr,"ET_CROSS\n");
00492         else if(et==ET_NEW)
00493                 fprintf(stderr,"ET_NEW\n");
00494         else if(et==ET_SELFLOOP)
00495                 fprintf(stderr,"ET_SELFLOOP\n");
00496         else
00497                 assert(0);
00498 }
00499 
00500 void CFG::print_color(Color c)
00501 {
00502         if(c==WHITE)
00503                 fprintf(stderr,"WHITE\n");
00504         else if(c==GRAY)
00505                 fprintf(stderr,"GRAY\n");
00506         else if(c==BLACK)
00507                 fprintf(stderr,"BLACK\n");
00508         else
00509                 assert(0);
00510 }
00511 
00512 // 
00513 //  When see a back edge (u->v),
00514 //  Add two edges (_entry->v), and (u->_exit) in CFG
00515 //  The edge type of these two edges are ET_NEW
00516 //
00517 void CFG::process_back_edge()
00518 {
00519         Cdb(1,"CFG::process_back_edge()");
00520 
00521         Cdb(2,"Proc: %s has %d nodes",_proc_name,_node_count);
00522         Cdb(2,"in_edge_count=%d out_edge_count=%d",_in_edge_count,_out_edge_count);
00523         Cdb(2,"Entry node is: %d",_entry->node()->node_id());
00524         Cdb(2,"Exit node is: %d",_exit->node()->node_id());
00525 
00526         for(Node_List *nl=root();nl!=NULL;nl=nl->next_node_list())
00527         {
00528                 Node *n=nl->node();
00529                 Cdb(2,"\nnode_id=%d",n->node_id());
00530 
00531                 for(n=n->next_node();n!=NULL;n=n->next_node())
00532                 {
00533                         if(n->direction()==1)
00534                         {
00535                                 Cdb(2,"hidden=%d node_id=%d edge_id=%d direction=%d edge_type=",n->hidden(),n->node_id(),n->edge_id(),n->direction());  
00536                                 Cdb(2,print_edge_type(n->edge_type()));
00537 
00538                                 //
00539                                 // If the edge is to ExitToEntryEdgeId
00540                                 // set this edge hidden=1
00541                                 // Continue to next adj list
00542                                 //
00543                                 if(n->edge_id()==ExitToEntryEdgeId)
00544                                 {
00545                                         n->set_hidden(1);
00546                                         continue;
00547                                 }
00548 
00549                                 if(n->edge_type()==ET_BACK || n->edge_type()==ET_SELFLOOP)
00550                                 {
00551                                         //
00552                                         // This edge becomes hidden
00553                                         //
00554                                         n->set_hidden(1);
00555 
00556                                         Node_List *sink=find_node(n->node_id());
00557 
00558                                         //
00559                                         // If self loop, don't add new edges
00560                                         //
00561                                         if(n->edge_type()==ET_SELFLOOP)
00562                                         {
00563                                                 Cdb(2,"Self Loop");
00564                                         }
00565                                         else
00566                                         {
00567                                                 _max_edge_id++;
00568                                                 Node *new_node=add_edge(_entry,sink,_max_edge_id);
00569                                                 n->set_entry_to_dest(new_node);
00570                                                 Cdb(2,"new_node _edge_id=%d",new_node->edge_id());
00571 
00572                                                 _max_edge_id++;
00573                                                 new_node=add_edge(nl,_exit,_max_edge_id);
00574                                                 n->set_src_to_exit(new_node);
00575                                                 Cdb(2,"new_node _edge_id=%d",new_node->edge_id());
00576                                         }
00577                                         Cdb_call(3,getchar());
00578                                 }
00579                         }
00580                 }
00581         }
00582 }
00583 
00584 //
00585 // Create an edge from source to dest with edge_id
00586 // Retrun this new Node (adjacency-list)
00587 //
00588 Node *CFG::add_edge(Node_List *source,Node_List *dest,int edge_id)
00589 {
00590         //Node *n=source->node();
00591 
00592         // 
00593         // Edge out of source node
00594         //
00595         Node *new_node=new Node(dest->node()->node_id());
00596         new_node->set_direction(1);
00597         new_node->set_edge_id(edge_id);
00598         new_node->set_edge_type(ET_NEW);
00599 
00600         new_node->set_next_node(source->node()->next_node());
00601         source->node()->set_next_node(new_node);
00602 
00603         Cdb(2,"Add _edge_id=%d from %d to %d",edge_id,source->node()->node_id(),dest->node()->node_id());
00604 
00605         // 
00606         // Edge into dest node
00607         //
00608         Node *other_node=new Node(source->node()->node_id());
00609         other_node->set_direction(0);
00610         other_node->set_edge_id(edge_id);
00611         other_node->set_edge_type(ET_NEW);
00612 
00613         other_node->set_next_node(dest->node()->next_node());
00614         dest->node()->set_next_node(other_node);
00615 
00616         //
00617         // Update edge counts
00618         //
00619         _in_edge_count++;
00620         _out_edge_count++;
00621 
00622         return new_node;
00623 }
00624 
00625 //
00626 // Return 1, if the number of paths is less than 2^20
00627 // Return 0, if the number of paths is greater than 2^20, we stop profiling
00628 //
00629 int CFG::assign_value()
00630 {
00631         Cdb(1,"CFG::assign_value()");
00632 
00633         for(int i=0;i<_index_of_topological_list;i++)
00634         {
00635                 Node_List *nl=find_node(_topological_list[i]);
00636                 Cdb(2,"This node is %d",nl->node()->node_id());
00637 
00638                 //
00639                 // We only have one leaf node, which is _exit.
00640                 //
00641                 if(i==0)
00642                 {
00643                         assert(nl==_exit);
00644                         nl->set_num_paths(1);
00645                 }
00646                 else
00647                 {
00648                         nl->set_num_paths(0);
00649 
00650                         for(Node *n=nl->node()->next_node();n!=NULL;n=n->next_node())
00651                         {
00652                                 if(n->direction()==1 && n->hidden()==0)
00653                                 {
00654                                         n->set_num_paths(nl->num_paths());
00655                                         Cdb(2,"_edge_id=%d _num_paths=%d",n->edge_id(),n->num_paths());
00656                                         Node_List *to_nl=find_node(n->node_id());
00657                                         int new_num_paths=nl->num_paths()+to_nl->num_paths();
00658                                         nl->set_num_paths(new_num_paths);
00659                                         if(new_num_paths>(1<<20))
00660                                                 return 0;
00661                                 }
00662                         }
00663                 }
00664 
00665                 Cdb(2,"_node_id=%d _num_paths=%d",nl->node()->node_id(),nl->num_paths());
00666                 Cdb_call(3,getchar());
00667         }
00668         return 1;
00669 }
00670 
00671 void CFG::read_file()
00672 {
00673         FILE *ifp=fopen("my.cfg","r");
00674 
00675         assert(ifp!=NULL);
00676 
00677         int node_count,edge_count;
00678         fscanf(ifp,"node_count=%d edge_count=%d\n",&node_count,&edge_count);
00679         fprintf(stderr,"node_count=%d edge_count\n",node_count,edge_count);
00680         _node_count=node_count;
00681         _in_edge_count=edge_count;
00682         _out_edge_count=edge_count;
00683 
00684         int entry_node,exit_node;
00685         fscanf(ifp,"entry_node=%d exit_node=%d\n",&entry_node,&exit_node);
00686         fprintf(stderr,"entry_node=%d exit_node=%d\n",entry_node,exit_node);
00687 
00688         Node_List *nl,*prev_nl;
00689         Node *n;
00690         for(int i=0;i<node_count;i++)
00691         {
00692                 int node_id;
00693                 int edge_count;
00694                 fscanf(ifp,"%d (%d)\t",&node_id,&edge_count);
00695                 fprintf(stderr,"%d (%d)\t",node_id,edge_count);
00696 
00697                 nl=new Node_List();
00698                 n=new Node(node_id);
00699                 nl->set_node(n);
00700 
00701                 if(_root==NULL)
00702                 {
00703                         _root=nl;
00704                 }
00705                 else
00706                 {
00707                         prev_nl->set_next_node_list(nl);
00708                 }
00709 
00710                 for(int j=0;j<edge_count;j++)
00711                 {
00712                         fscanf(ifp,"%d ",&node_id);
00713                         fprintf(stderr,"%d ",node_id);
00714 
00715                         Node *adj_node=new Node(node_id);
00716                         _max_edge_id++;
00717                         adj_node->set_edge_id(_max_edge_id);
00718                         n->set_next_node(adj_node);
00719                         n=adj_node;
00720                 }
00721                 fscanf(ifp,"\n");
00722                 fprintf(stderr,"\n");
00723 
00724                 prev_nl=nl;
00725         }
00726 
00727         _entry=find_node(entry_node);
00728         _exit=find_node(exit_node);
00729         set_proc_name("my.cfg");
00730         add_edge_from_exit_to_entry();
00731 }
00732 
00733 //
00734 // Un-hide this edge ExitToEntryEdgeId
00735 //
00736 void CFG::unhide_EXIT_edge()
00737 {
00738         Cdb(1,"CFG::unhide_EXIT_edge()");
00739 
00740         Node_List *nl;
00741         Node *n;
00742 
00743         for(nl=root();nl!=NULL;nl=nl->next_node_list())
00744         {
00745                 n=nl->node();
00746                 for(n=n->next_node();n!=NULL;n=n->next_node())
00747                 {
00748                         //if(n->direction()==1)
00749                         //{
00750 
00751                                 if(n->edge_id()==ExitToEntryEdgeId)
00752                                         n->set_hidden(0);
00753                         //}
00754                 }
00755         }
00756 }
00757 
00758 //
00759 // hide ET_NEW edge
00760 //
00761 void CFG::hide_ET_NEW_edge()
00762 {
00763         Cdb(1,"CFG::hide_ET_NEW_edge()");
00764 
00765         Node_List *nl;
00766         Node *n;
00767 
00768         for(nl=root();nl!=NULL;nl=nl->next_node_list())
00769         {
00770                 n=nl->node();
00771                 for(n=n->next_node();n!=NULL;n=n->next_node())
00772                 {
00773                         //if(n->direction()==1)
00774                         //{
00775                                 if(n->edge_type()==ET_NEW)
00776                                         n->set_hidden(1);
00777 
00778                         //}
00779                 }
00780         }
00781 }
00782 
00783 
00784 //
00785 // Efficiently Computing Program Events (from paper)
00786 //
00787 void CFG::event_counting(MST *mst)
00788 {
00789         Cdb(1,"CFG::event_counting()");
00790 
00791         event_dfs(0,_entry,NULL,NULL,mst);
00792 
00793         //
00794         // Find edges: not in MST
00795         //
00796         for(Node_List *nl=root();nl!=NULL;nl=nl->next_node_list())
00797         {
00798                 Node *n=nl->node();
00799                 for(n=n->next_node();n!=NULL;n=n->next_node())
00800                 {
00801                         //
00802                         // Check edges with out direction and hidden=0 
00803                         // The current edge is n
00804                         //
00805                         if(n->direction()==1 && n->hidden()==0)
00806                         {
00807                                 if(mst->is_mst(n->edge_id())==0)
00808                                 {
00809                                         int new_eff_sum=n->eff_sum()+n->num_paths();
00810                                         n->set_eff_sum(new_eff_sum);
00811                                         Cdb(2,"new_eff_sum=%d",n->eff_sum());
00812                                 }
00813                         }
00814                 }
00815         }
00816 }
00817 
00818 void CFG::print_eff_sum(MST *mst)
00819 {
00820         Cdb(1,"CFG::print_eff_sum()");
00821         //
00822         // Find edges: not in MST
00823         //
00824         for(Node_List *nl=root();nl!=NULL;nl=nl->next_node_list())
00825         {
00826                 Node *n=nl->node();
00827                 for(n=n->next_node();n!=NULL;n=n->next_node())
00828                 {
00829                         //
00830                         // Check edges with out direction and hidden=0 
00831                         // The current edge is n
00832                         //
00833                         if(n->direction()==1 && n->hidden()==0)
00834                         {
00835                                 if(mst->is_mst(n->edge_id())==0)
00836                                 {
00837                                         fprintf(stderr,"_edge_id=%d (from %d to %d) new_eff_sum=%d\n",n->edge_id(),nl->node()->node_id(),n->node_id(),n->eff_sum());
00838                                 }
00839                         }
00840                 }
00841         }
00842 }
00843 void CFG::event_dfs(int events,Node_List *v,Node_List *e_nl,Node *e,MST *mst)
00844 {
00845         Cdb(1,"CFG::event_dfs()");
00846         Cdb(2,"events=%d Node_List=%d",events,v->node()->node_id());
00847         if(e!=NULL)
00848         {
00849                 Cdb(2,"_edge_id=%d from %d to %d",e->edge_id(),e_nl->node()->node_id(),e->node_id());
00850         }
00851         Cdb(1,"Start search (_node_id=%d)",v->node()->node_id());
00852 
00853         //
00854         // Find edge: in MST & edges!=e & edges's target==v
00855         //
00856         for(Node_List *nl=root();nl!=NULL;nl=nl->next_node_list())
00857         {
00858                 Node *n=nl->node();
00859                 for(n=n->next_node();n!=NULL;n=n->next_node())
00860                 {
00861                         //
00862                         // Check edges with out direction and hidden=0 
00863                         // The current edge is "n"
00864                         //
00865                         if(n->direction()==1 && n->hidden()==0)
00866                         {
00867                                 if(mst->is_mst(n->edge_id()) && n!=e && n->node_id()==v->node()->node_id())
00868                                 {
00869                                         Cdb(2,"Find _edge_id=%d from %d to %d",n->edge_id(),nl->node()->node_id(),n->node_id());
00870 
00871                                         int dir=event_dir(e_nl,e,nl,n);
00872                                         Cdb(2,"Find dir=%d",dir);
00873                                         Cdb(2,"Find num_paths=%d",n->num_paths());
00874                                         int new_event=dir*events+n->num_paths();
00875                                         Cdb(2,"new_event=%d",new_event);
00876 
00877                                         Cdb_call(3,getchar());
00878                                         event_dfs(new_event,nl,nl,n,mst);
00879                                 }
00880                         }
00881                 }
00882         }
00883         Cdb(2,"Finish with first search (_node_id=%d)",v->node()->node_id());
00884         Cdb_call(3,getchar());
00885 
00886         //
00887         // Find edge: in MST & edges!=e & edges's source==v
00888         //
00889         for(Node_List *nl=root();nl!=NULL;nl=nl->next_node_list())
00890         {
00891                 //
00892                 // check if source!=v
00893                 // go to next iteration
00894                 //
00895                 if(nl!=v)
00896                         continue;
00897 
00898                 Node *n=nl->node();
00899 
00900                 for(n=n->next_node();n!=NULL;n=n->next_node())
00901                 {
00902                         //
00903                         // Check edges with out direction and hidden=0 
00904                         //
00905                         if(n->direction()==1 && n->hidden()==0)
00906                         {
00907                                 if(mst->is_mst(n->edge_id()) && n!=e)
00908                                 {
00909                                         Cdb(2,"Find _edge_id=%d from %d to %d",n->edge_id(),nl->node()->node_id(),n->node_id());
00910 
00911                                         int dir=event_dir(e_nl,e,nl,n);
00912                                         Cdb(2,"Find dir=%d",dir);
00913                                         Cdb(2,"Find num_paths=%d",n->num_paths());
00914                                         Node_List *target=find_node(n->node_id());
00915                                         int new_event=dir*events+n->num_paths();
00916                                         Cdb(2,"new_event=%d",new_event);
00917                                         Cdb_call(3,getchar());
00918                                         event_dfs(new_event,target,nl,n,mst);
00919                                 }
00920                         }
00921                 }
00922         }
00923         Cdb(2,"Finish with second search (_node_id=%d)",v->node()->node_id());
00924         Cdb_call(3,getchar());
00925 
00926         //
00927         // Find edge: isnot in MST & edges!=e & 
00928         //            edges's target==v or edges' source==v
00929         //
00930         for(Node_List *nl=root();nl!=NULL;nl=nl->next_node_list())
00931         {
00932                 Node *n=nl->node();
00933                 for(n=n->next_node();n!=NULL;n=n->next_node())
00934                 {
00935                         //
00936                         // Check edges with out direction and hidden=0 
00937                         // The current edge is n
00938                         //
00939                         if(n->direction()==1 && n->hidden()==0)
00940                         {
00941                                 if(mst->is_mst(n->edge_id())==0 && n!=e )
00942                                 {
00943                                         if(n->node_id()==v->node()->node_id() ||nl==v)
00944                                         {
00945                                                 Cdb(2,"Find _edge_id=%d from %d to %d",n->edge_id(),nl->node()->node_id(),n->node_id());
00946 
00947                                                 int dir=event_dir(e_nl,e,nl,n);
00948                                                 Cdb(2,"Find dir=%d",dir);
00949                                                 Cdb(2,"Find num_paths=%d",n->num_paths());
00950                                                 Cdb(2,"Find eff_sum=%d",n->eff_sum());
00951 
00952                                                 int total_eff_sum=n->eff_sum()+dir*events;
00953                                                 n->set_eff_sum(total_eff_sum);
00954                                                 Cdb(2,"new eff_sum=%d",n->eff_sum());
00955                                                 Cdb_call(3,getchar());
00956                                         }
00957                                 }
00958                         }
00959                 }
00960         }
00961         Cdb(2,"Finish with Third search (_node_id=%d)",v->node()->node_id());
00962 
00963         Cdb_call(3,getchar());
00964 }
00965 
00966 //
00967 // First edge: e_nl -> e_n
00968 // Second edge: f_nl -> f_n
00969 //
00970 // Return 1: same direction
00971 //        0: opposite direction
00972 //
00973 int CFG::event_dir(Node_List *e_nl,Node *e_n,Node_List *f_nl,Node *f_n)
00974 {
00975         if(e_n==NULL)
00976                 return 1;
00977         else if(e_nl->node()->node_id()==f_n->node_id() ||
00978                 e_n->node_id()==f_nl->node()->node_id())
00979         {
00980                 return 1;       // same direction
00981         }
00982         else if(e_nl->node()->node_id()==f_nl->node()->node_id() ||
00983                 e_n->node_id()==f_n->node_id())
00984         {
00985                 return -1;      // opposite direction
00986         }
00987         else
00988                 assert(0);
00989 }
00990 
00991 void CFG::find_type_of_instrumentation(MST *mst)
00992 {
00993         Cdb(1,"CFG::find_type_of_instrumentation");
00994 
00995         Node_List *queue[_node_count];
00996         int iq=0;       // index of queue
00997 
00998         //
00999         // Register initialization code
01000         //
01001         queue[iq]=_entry;
01002         iq++;
01003 
01004         while(iq!=0)
01005         {
01006                 Node_List *v=queue[0];
01007                 Cdb(2,"Check node_id=%d",v->node()->node_id());
01008 
01009                 for(int i=1;i<iq;i++)
01010                 {
01011                         queue[i-1]=queue[i];
01012                 }
01013                 iq--;
01014         
01015                 for(Node *e=v->node()->next_node();e!=NULL;e=e->next_node())
01016                 {
01017                         if(e->direction()==1 && e->hidden()==0)
01018                         {
01019                                 Cdb(2,"edge_id=%d (from %d to %d)",e->edge_id(),v->node()->node_id(),e->node_id());
01020                                 if(mst->is_mst(e->edge_id())==0)
01021                                 {
01022                                         // Type r=inc(e)
01023                                         Cdb(2,"Type r=inc(e)");
01024                                         Cdb_call(2,getchar());
01025                                 }
01026                                 else if(num_of_incoming_edge(find_node(e->node_id()))==1)
01027                                 {
01028                                         Cdb(2,"Add node_id=%d to queue",e->node_id());
01029                                         Cdb_call(2,getchar());
01030                                         queue[iq]=find_node(e->node_id());
01031                                         iq++;
01032                                 }
01033                                 else
01034                                 {
01035                                         // Type r=0;
01036                                         Cdb(2,"Type r=0");
01037                                         Cdb_call(2,getchar());
01038                                 }
01039                         }
01040                 }
01041         }
01042 }
01043 
01044 int CFG::num_of_incoming_edge(Node_List *vertex)
01045 {
01046         int num=0;
01047 
01048         for(Node_List *nl=_root;nl!=NULL;nl=nl->next_node_list())
01049         {
01050                 Node *n=nl->node();
01051                 for(n=n->next_node();n!=NULL;n=n->next_node())
01052                 {
01053                         if(n->direction()==1 && n->hidden()==0 && n->node_id()==vertex->node()->node_id())
01054                         {
01055                                 num++;
01056                         }
01057                 }
01058         }
01059         return num;
01060 }
01061 
01062 //
01063 // Regenerate paths
01064 //
01065 void CFG::regenerate_path(FILE *ifp)
01066 {
01067         Cdb(1,"CFG::regenerate_path");
01068 
01069         for(int i=0;i<_entry->num_paths();i++)
01070         {
01071                 int path_value=i;
01072 
01073                 fprintf(ifp,"sum=%d: %d",i,_entry->node()->node_id());
01074                 
01075                 Node_List *nl=_entry;
01076                 do
01077                 {
01078                         Node *max_v=NULL;
01079 
01080                         for(Node *v=nl->node()->next_node();v!=NULL;v=v->next_node())
01081                         {
01082                                 if(v->direction()==0 || v->edge_type()==ET_BACK || v->edge_type()==ET_SELFLOOP)
01083                                         continue;
01084 
01085                                 int value;
01086 
01087                                 if(max_v==NULL)
01088                                         max_v=v;
01089 
01090                                 value=v->num_paths();
01091                                 if(value<=path_value && value>max_v->num_paths())
01092                                         max_v=v;
01093                         }
01094 
01095                         //fprintf(ifp,"_(%d)_%d",max_v->edge_id(),max_v->node_id());
01096                         fprintf(ifp," %d",max_v->node_id());
01097                         nl=find_node(max_v->node_id());
01098                         path_value=path_value-max_v->num_paths();
01099                 }
01100                 while(nl!=_exit);
01101 
01102                 fprintf(ifp,"\n");
01103         }
01104 }

Generated on Mon Jul 21 20:24:04 2003 for TINKER LEGO DOC by doxygen 1.3.2