00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "bb.h"
00042 #include <stack>
00043 #include <vector>
00044 #include <list>
00045 #include "defs.h"
00046 #include "cxx_memory.h"
00047 #include "region.h"
00048 #include "region_bb_util.h"
00049 #include "region_verify.h"
00050 #include "interval_processor.h"
00051 #include "vt_region.h"
00052 #include "ipfec_defs.h"
00053 #include "tracing.h"
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 void Verify_Node(REGIONAL_CFG_NODE *node, REGION *rgn){
00064
00065 REGION *home_rgn = node->Home_Region();
00066 if(node->Is_Region())
00067 Is_True(home_rgn==rgn, ("regional cfg node (rgn_id:%d) should be in region_id:%d",
00068 node->Region_Node()->Id(), rgn->Id()));
00069 else
00070 Is_True(home_rgn==rgn, ("regional cfg node (bb_id:%d) should be in region_id:%d",
00071 BB_id(node->BB_Node()), rgn->Id()));
00072
00073
00074 if(node->Is_Region()){
00075 REGION *rgn = node->Region_Node();
00076 Is_True(rgn->Parent()==home_rgn,
00077 ("home region:%d of regional cfg node:%d should be its parent region%d",
00078 home_rgn->Id(), node->Id(), rgn->Parent()->Id()));
00079 }else{
00080 BB *bb = node->BB_Node();
00081 Is_True(Regional_Cfg_Node(bb)==node,
00082 ("bb:%d should get its corresponding regional cfg node", BB_id(bb)));
00083 }
00084
00085
00086 for(CFG_SUCC_EDGE_ITER iter(node); iter!=0; ++iter){
00087 REGIONAL_CFG_NODE *dest = (*iter)->Dest();
00088 Is_True(dest->Find_Pred_Edge(node), ("node is the pred of its succ"));
00089 }
00090
00091
00092 INT32 succ_num = 0;
00093 for(CFG_SUCC_EDGE_ITER iter(node); iter!=0; ++iter)
00094 succ_num++;
00095 Is_True(node->Succ_Num()==succ_num, ("_succ_num=%d, succ_num=%d", node->Succ_Num(),succ_num));
00096 INT32 pred_num = 0;
00097 for(CFG_PRED_EDGE_ITER iter(node); iter!=0; ++iter)
00098 pred_num++;
00099 Is_True(node->Pred_Num()==pred_num, ("_pred_num=%d, pred_num=%d", node->Pred_Num(),pred_num));
00100
00101
00102 BB_ALLOC alloc(&(home_rgn->Regional_Cfg()->_m));
00103 if(node->Is_Entry()){
00104 BOOL find_entry_edge = FALSE;
00105 BB_VECTOR bbs(alloc);
00106 if(node->Is_Region())
00107 Collect_Entry_BBs(node->Region_Node(), &bbs);
00108 else
00109 bbs.push_back(node->BB_Node());
00110 Is_True(!bbs.empty(), ("#entry_bbs is %d", bbs.size()));
00111 for(BB_VECTOR_ITER iter=bbs.begin(); iter!=bbs.end(); iter++){
00112 if(BB_preds_len(*iter)==0)
00113 find_entry_edge = TRUE;
00114 BBLIST *pred_list;
00115 FOR_ALL_BB_PREDS(*iter, pred_list) {
00116 BB *pred = BBLIST_item(pred_list);
00117 if(!Region_Contains_BB(home_rgn, pred)){
00118 find_entry_edge = TRUE;
00119 break;
00120 }
00121 }
00122 if(find_entry_edge) break;
00123 }
00124 bbs.clear();
00125
00126 Is_True(find_entry_edge,
00127 ("entry node (id:%d) should has one incoming edge which src is not in region (id:%d)",
00128 node->Id(),home_rgn->Id()));
00129 }
00130
00131 if(node->Is_Exit()){
00132 INT32 find_exit_edge = 0;
00133 BB_VECTOR bbs(alloc);
00134 if(node->Is_Region())
00135 Collect_Exit_BBs(node->Region_Node(), &bbs);
00136 else
00137 bbs.push_back(node->BB_Node());
00138 Is_True(!bbs.empty(), ("#exit_bbs is %d", bbs.size()));
00139 for(BB_VECTOR_ITER iter=bbs.begin(); iter!=bbs.end(); iter++){
00140 if(BB_succs_len(*iter)==0)
00141 find_exit_edge = TRUE;
00142 BBLIST *succ_list;
00143 FOR_ALL_BB_SUCCS(*iter, succ_list) {
00144 BB *succ = BBLIST_item(succ_list);
00145 if(!Region_Contains_BB(home_rgn, succ)){
00146 find_exit_edge = TRUE;
00147 break;
00148 }
00149 if(find_exit_edge) break;
00150 }
00151 }
00152 bbs.clear();
00153
00154 #ifdef Is_True_On
00155 if(node->Is_Region())
00156 Is_True(find_exit_edge,
00157 ("verify exit node (rgn_id:%d) should has one outcoming edge which dest is not in region (id:%d)",
00158 node->Region_Node()->Id(), home_rgn->Id()));
00159 else
00160 Is_True(find_exit_edge,
00161 ("verify exit node (bb_id:%d) should has one outcoming edge which dest is not in region (id:%d)",
00162 BB_id(node->BB_Node()), home_rgn->Id()));
00163 #endif
00164 }
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 void Verify_Cfg(REGIONAL_CFG *cfg){
00176
00177 INT32 entry_num = 0;
00178 INT32 exit_num = 0;
00179 for(SEQ_REGIONAL_CFG_ITER iter(cfg); iter!=0; ++iter){
00180 REGIONAL_CFG_NODE *node = *iter;
00181
00182
00183 Verify_Node(node, cfg->_r);
00184
00185 if(node->Is_Entry())
00186 entry_num++;
00187 else{
00188
00189
00190 if(cfg->_r->Region_Type()==SEME)
00191 Is_True(node->First_Pred(),
00192 ("node_id:%d of region_id:%d has no pred ", node->Id(), cfg->_r->Id()));
00193 }
00194 if(node->Is_Exit())
00195 exit_num++;
00196
00197
00198 Is_True(node->Home_Region()==cfg->_r, ("verify Home_Region"));
00199
00200
00201 for(CFG_SUCC_NODE_ITER succ_iter(node); succ_iter!=0; ++succ_iter)
00202 Is_True(Edge_Counter(node, *succ_iter, cfg)>=1,("verify regional cfg edge"));
00203 }
00204
00205 Is_True(entry_num == cfg->Num_Of_Entries(),
00206 ("verify entries of regional_cfg: region_id: %d, entry_num=%d, cfg->_entries.size()=%d",
00207 cfg->_r->Id(), entry_num, cfg->Num_Of_Entries()));
00208 Is_True(exit_num == cfg->Num_Of_Exits(),
00209 ("verify exits of regional_cfg: region_id: %d, exit_num=%d, cfg->_exits.size()=%d",
00210 cfg->_r->Id(),exit_num, cfg->Num_Of_Exits()));
00211
00212 if(cfg->_r->Region_Type()==IMPROPER) return;
00213
00214
00215 NODE_ALLOC alloc(&(cfg->_m));
00216 NODE_VECTOR nodes(alloc);
00217 for(TOPOLOGICAL_REGIONAL_CFG_ITER iter(cfg); iter!=0; ++iter){
00218 REGIONAL_CFG_NODE *node = *iter;
00219 for(CFG_PRED_NODE_ITER pred_iter(node); pred_iter!=0; ++pred_iter)
00220 Is_True(Find_In_Vector(*pred_iter, nodes) != (NODE_VECTOR_ITER)0,
00221 ("verify topological_cfg_iter"));
00222 nodes.push_back(node);
00223 }
00224
00225 nodes.clear();
00226
00227
00228 for(REVERSE_TOPO_REGIONAL_CFG_ITER iter(cfg); iter!=0; ++iter){
00229 REGIONAL_CFG_NODE *node = *iter;
00230 for(CFG_SUCC_NODE_ITER succ_iter(node); succ_iter!=0; ++succ_iter)
00231 Is_True (Find_In_Vector(*succ_iter, nodes) != (NODE_VECTOR_ITER)0,
00232 ("verify topological_cfg_iter"));
00233 nodes.push_back(node);
00234 }
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 void Verify_SEME_Region(REGION *region){
00246 Is_True(region->Region_Type()==SEME,
00247 ("verify SEME region's Region_Type should be SEME_REGION"));
00248
00249 REGIONAL_CFG *cfg = region->Regional_Cfg();
00250 Is_True(cfg->Num_Of_Entries() == 1,
00251 ("SEME REGION id:%d has more than one entries", region->Id()));
00252
00253
00254 INTERVAL_PROCESSOR inter(region);
00255 inter.Find_Cycles();
00256 Is_True(inter._cycles.empty(), ("seme should have no cycles"));
00257
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 static BOOL Find_Regional_Cfg_Edge(REGIONAL_CFG_NODE *src,
00270 REGIONAL_CFG_NODE *dest,
00271 REGION *rgn){
00272 if(rgn->Region_Type() == LOOP){
00273 LOOP_REGION *loop = (LOOP_REGION *)rgn;
00274
00275 if(src==loop->Loop_Tail() && dest==loop->Loop_Head())
00276 return TRUE;
00277 }
00278 if(rgn->Regional_Cfg()->Find_Edge(src,dest))
00279 return TRUE;
00280 else
00281 return FALSE;
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 void Verify_Entry_Exit_BB(BB *bb){
00295 REGION *rgn = Home_Region(bb);
00296 REGIONAL_CFG_NODE *node = Regional_Cfg_Node(bb);
00297 Is_True(rgn && node, ("verify_entry_exit_bb"));
00298
00299 if(BB_preds_len(bb)==0)
00300 Is_True(node->Is_Entry(), ("verify_entry_exit_bb"));
00301 if(BB_succs_len(bb)==0)
00302 Is_True(node->Is_Exit(), ("verify_entry_exit_bb"));
00303
00304 BBLIST *pred_list;
00305 FOR_ALL_BB_PREDS(bb, pred_list){
00306 BB *pred = BBLIST_item(pred_list);
00307 Is_True(pred && Home_Region(pred), ("verify_entry_exit_bb"));
00308 if(!(Region_Contains_BB(rgn, pred))){
00309 Is_True(node->Is_Entry(), ("verify_entry_exit_bb"));
00310 break;
00311 }
00312 }
00313
00314 BBLIST *succ_list;
00315 FOR_ALL_BB_SUCCS(bb, succ_list){
00316 BB *succ = BBLIST_item(succ_list);
00317 Is_True(succ && Home_Region(succ), ("verify_entry_exit_bb"));
00318 if(!(Region_Contains_BB(rgn, succ))){
00319
00320
00321
00322
00323
00324
00325 BOOL is_cycle = TRUE;
00326 for (GLOBAL_CYCLE_VECTOR_ITER cycle_iter = global_cycles.begin();
00327 cycle_iter != global_cycles.end();cycle_iter++) {
00328 if ((succ == (*cycle_iter).dest)&&(bb == (*cycle_iter).src)) {
00329 is_cycle = TRUE;
00330
00331 break;
00332 }
00333 }
00334
00335 if (!is_cycle) {
00336 Is_True(node->Is_Exit(), ("verify_entry_exit_bb"));
00337 }
00338 }
00339 }
00340 }
00341
00342
00343
00344
00345
00346
00347
00348
00349 void Verify_Global_Edge(BB *bb, BB *succ){
00350 REGION *rgn = Home_Region(bb);
00351 REGIONAL_CFG_NODE *node=Regional_Cfg_Node(bb);
00352
00353 BBLIST *pred_list;
00354 BOOL find = FALSE;
00355 FOR_ALL_BB_PREDS(succ, pred_list){
00356 BB *pred = BBLIST_item(pred_list);
00357 if(pred == bb){
00358 find = TRUE;
00359 break;
00360 }
00361 }
00362 Is_True(find, ("bb_id:%d has one succ_bb_id:%d, but bb is not succ_bb's pred bb",
00363 BB_id(bb), BB_id(succ)));
00364
00365 REGIONAL_CFG_NODE *succ_node = Regional_Cfg_Node(succ);
00366 Is_True(succ_node, ("succ bb_id:%d has no corresponding regional cfg node",BB_id(succ)));
00367 REGION *succ_rgn = succ_node->Home_Region();
00368
00369 if(rgn == succ_rgn){
00370
00371 find = Find_Regional_Cfg_Edge(node, succ_node, rgn);
00372 }else{
00373 if(Get_Trace(TP_A_REGION, TT_RGN_VERIFY_DEBUG))
00374 printf("verify edge: rgn_id:%d succ_rgn_id:%d\n", rgn->Id(), succ_rgn->Id());
00375 REGION *par_rgn = rgn->Find_Common_Parent(succ_rgn);
00376 Is_True(par_rgn, ("rgn_id:%d and succ_rgn_id:%d should has common parent",
00377 rgn->Id(), succ_rgn->Id()));
00378
00379
00380 REGION *tmp_pred_rgn = rgn;
00381 REGIONAL_CFG_NODE *tmp_pred_node = node;
00382 while(tmp_pred_rgn != par_rgn){
00383 tmp_pred_node = tmp_pred_rgn->Regional_Cfg_Node();
00384 tmp_pred_rgn = tmp_pred_node->Home_Region();
00385 }
00386
00387
00388 REGION *tmp_succ_rgn = succ_rgn;
00389 REGIONAL_CFG_NODE *tmp_succ_node = succ_node;
00390 while(tmp_succ_rgn != par_rgn){
00391 tmp_succ_node = tmp_succ_rgn->Regional_Cfg_Node();
00392 tmp_succ_rgn = tmp_succ_node->Home_Region();
00393 }
00394
00395 find = Find_Regional_Cfg_Edge(tmp_pred_node, tmp_succ_node, par_rgn);
00396 if(!find && Get_Trace(TP_A_REGION, TT_RGN_VERIFY_DEBUG)){
00397 printf("there is no edge between pred_node_id:%d and succ_node_is:%d in rgn_id:%d \n",
00398 tmp_pred_node->Id(), tmp_succ_node->Id(), par_rgn->Id());
00399 par_rgn->Print(TFile);
00400 }
00401 }
00402
00403 if(find == FALSE){
00404 if (Get_Trace(TP_A_REGION, TT_RGN_VERIFY_DEBUG)){
00405 printf("rgn_id:%d ", rgn->Id());
00406 printf("bb_id:%d ", BB_id(bb));
00407 printf("succ_bb_id:%d\n", BB_id(succ));
00408
00409 draw_global_cfg();
00410 draw_regional_cfg(rgn->Tree()->Root());
00411 }
00412
00413
00414
00415
00416 BOOL is_cycle = TRUE;
00417 for (GLOBAL_CYCLE_VECTOR_ITER cycle_iter = global_cycles.begin();
00418 cycle_iter != global_cycles.end();cycle_iter++) {
00419 if ((succ == (*cycle_iter).dest)&&(bb == (*cycle_iter).src)) {
00420 is_cycle = TRUE;
00421
00422 break;
00423 }
00424 }
00425
00426 if (!is_cycle) {
00427 Is_True(FALSE, ("can not find corresponding edge bb_id:%d and succ_bb_id:%d",
00428 BB_id(bb), BB_id(succ)));
00429 }
00430 }
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 void Verify_Region_Tree(REGION_TREE *tree, BB *first_bb){
00442
00443 for(INNERMOST_REGION_FIRST_ITER iter(tree); iter!=0; ++iter){
00444
00445 REGION *region = *iter;
00446 BOOL find = FALSE;
00447 for( INT32 i=0; i<tree->_region_set.size(); i++){
00448 if((tree->_region_set)[i]==region){
00449 find = TRUE;
00450 break;
00451 }
00452 }
00453 Is_True(find,("region %d should be in _region_set", region->Id()));
00454
00455
00456 if(region->Region_Type() == SEME)
00457 Verify_SEME_Region(region);
00458
00459
00460 Verify_Cfg(region->Regional_Cfg());
00461
00462
00463
00464 REGION *par_rgn = region->Parent();
00465 if(par_rgn){
00466 Is_True(region->Is_Kid_Region_Of(par_rgn),
00467 ("region should be one kid region of its parent region"));
00468 }else
00469 Is_True(region->Region_Type()==ROOT, ("only root region has no parent region"));
00470 }
00471
00472
00473 for(BB *bb = first_bb; bb!=0; bb = BB_next(bb)){
00474
00475
00476
00477 if ( BB_unreachable(bb) ) {
00478 Is_True( BB_Has_Exc_Label(bb)|| BB_Has_Addr_Taken_Label(bb)|| BB_Has_Outer_Block_Label(bb),
00479 ("BB is unreachable, but not of exec/addr_taken/outer_block_label type. Refer to Delete_BB_Contents function in CFlow"));
00480 continue;
00481 }
00482 Verify_Entry_Exit_BB(bb);
00483
00484 REGIONAL_CFG_NODE *node = Regional_Cfg_Node(bb);
00485 Is_True(node, ("bb:%d has no corresponding regional cfg node", BB_id(bb)));
00486
00487 REGION *rgn = node->Home_Region();
00488 BBLIST *succ_list;
00489 FOR_ALL_BB_SUCCS(bb, succ_list) {
00490 BB *succ = BBLIST_item(succ_list);
00491
00492 Verify_Global_Edge(bb,succ);
00493 }
00494 }
00495 }
00496
00497
00498