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
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 #ifdef USE_PCH
00082 #include "be_com_pch.h"
00083 #endif
00084 #pragma hdrstop
00085 #define USE_STANDARD_TYPES
00086
00087 #include <algorithm>
00088 #include <vector>
00089 #include <stack>
00090
00091 using namespace std;
00092
00093 #include <stdlib.h>
00094 #include "defs.h"
00095 #include "stab.h"
00096 #include "wn.h"
00097 #include "wn_map.h"
00098 #include "wn_util.h"
00099 #include "mempool.h"
00100 #include "tracing.h"
00101 #include "targ_sim.h"
00102 #include "wn_pragmas.h"
00103 #include "ir_reader.h"
00104 #include "cxx_template.h"
00105 #include "cxx_hash.h"
00106 #include "config_asm.h"
00107 #include "glob.h"
00108 #include "pu_info.h"
00109
00110
00111
00112 #define Verifier_DEBUG 0
00113
00114
00115
00116
00117 struct pragma_stack_type
00118 {
00119 WN *parent_wn;
00120 WN_PRAGMA_ID pragma_id;
00121 };
00122
00123
00124
00125
00126
00127
00128
00129
00130 #define NUM_PRAGMAS_SUPPORTED 26
00131
00132 struct pragma_mapped_ids
00133 {
00134 WN_PRAGMA_ID pragma_id;
00135 BOOL push;
00136 WN_PRAGMA_ID pragma_starting_id;
00137 };
00138
00139
00140
00141
00142
00143
00144
00145 pragma_mapped_ids pragmas_supported[NUM_PRAGMAS_SUPPORTED] =
00146 {
00147 { WN_PRAGMA_INLINE_BODY_START, TRUE, WN_PRAGMA_UNDEFINED },
00148 { WN_PRAGMA_INLINE_BODY_END, FALSE, WN_PRAGMA_INLINE_BODY_START },
00149 { WN_PRAGMA_ENTER_GATE, TRUE, WN_PRAGMA_UNDEFINED },
00150 { WN_PRAGMA_EXIT_GATE, FALSE, WN_PRAGMA_ENTER_GATE },
00151 { WN_PRAGMA_CRITICAL_SECTION_BEGIN, TRUE, WN_PRAGMA_UNDEFINED },
00152 { WN_PRAGMA_CRITICAL_SECTION_END, FALSE, WN_PRAGMA_CRITICAL_SECTION_BEGIN },
00153 { WN_PRAGMA_PARALLEL_BEGIN, TRUE, WN_PRAGMA_UNDEFINED },
00154 { WN_PRAGMA_PARALLEL_END, FALSE, WN_PRAGMA_PARALLEL_BEGIN },
00155 { WN_PRAGMA_PDO_BEGIN, TRUE, WN_PRAGMA_UNDEFINED },
00156 { WN_PRAGMA_PDO_END, FALSE, WN_PRAGMA_PDO_BEGIN },
00157 { WN_PRAGMA_PSECTION_BEGIN, TRUE, WN_PRAGMA_UNDEFINED },
00158 { WN_PRAGMA_PSECTION_END, FALSE, WN_PRAGMA_PSECTION_BEGIN },
00159 { WN_PRAGMA_SINGLE_PROCESS_BEGIN, TRUE, WN_PRAGMA_UNDEFINED },
00160 { WN_PRAGMA_SINGLE_PROCESS_END, FALSE, WN_PRAGMA_SINGLE_PROCESS_BEGIN },
00161 { WN_PRAGMA_FLIST_SKIP_BEGIN, TRUE, WN_PRAGMA_UNDEFINED },
00162 { WN_PRAGMA_FLIST_SKIP_END, FALSE, WN_PRAGMA_FLIST_SKIP_BEGIN },
00163 { WN_PRAGMA_CLIST_SKIP_BEGIN, TRUE, WN_PRAGMA_UNDEFINED },
00164 { WN_PRAGMA_CLIST_SKIP_END, FALSE, WN_PRAGMA_CLIST_SKIP_BEGIN },
00165 { WN_PRAGMA_INDEPENDENT_BEGIN, TRUE, WN_PRAGMA_UNDEFINED },
00166 { WN_PRAGMA_INDEPENDENT_END, FALSE, WN_PRAGMA_INDEPENDENT_BEGIN },
00167 { WN_PRAGMA_CRI_CASE, TRUE, WN_PRAGMA_UNDEFINED },
00168 { WN_PRAGMA_CRI_ENDCASE, FALSE, WN_PRAGMA_CRI_CASE },
00169 { WN_PRAGMA_CRI_GUARD, TRUE, WN_PRAGMA_UNDEFINED },
00170 { WN_PRAGMA_CRI_ENDGUARD, FALSE, WN_PRAGMA_CRI_GUARD },
00171 { WN_PRAGMA_CRI_PARALLEL, TRUE, WN_PRAGMA_UNDEFINED },
00172 { WN_PRAGMA_CRI_ENDPARALLEL, FALSE, WN_PRAGMA_CRI_PARALLEL}
00173 };
00174
00175 class WN_Verifier{
00176 private:
00177
00178
00179
00180
00181
00182 MEM_POOL _mem_pool;
00183 WN_MAP _map;
00184 BOOL _is_tree_OK;
00185 WN *_func;
00186 stack< pragma_stack_type > _pragma_stack;
00187
00188
00189
00190
00191
00192
00193 BOOL Is_return_register_of_call(WN *call_wn, PREG_NUM preg);
00194 WN *One_level_removed_node(WN *parent_wn,OPERATOR opr);
00195 BOOL Is_dedicated_return_register(WN_OFFSET preg);
00196
00197 protected:
00198
00199
00200
00201
00202
00203 BOOL Is_WHIRL_tree(WN *wn, WN *parent);
00204 BOOL CALL_parent_LDID(WN *wn, WN *parent_wn);
00205 BOOL Proper_Block_Structure(WN *wn,OPCODE op);
00206 BOOL Param_parent_is_Call(WN *wn,WN *parent_wn);
00207 BOOL Call_children_are_PARM(WN *wn);
00208 BOOL Is_legal_wn_opcode(OPCODE opc);
00209 BOOL LDA_ty_not_NULL(WN *wn);
00210 BOOL STID_check_st_class(WN *wn);
00211 BOOL TY_is_not_NULL(WN *wn, OPCODE op);
00212 BOOL ST_is_not_NULL(WN *wn, OPCODE op);
00213 BOOL Load_addr_TY_is_not_NULL(WN *wn, OPCODE op);
00214 BOOL Are_enclosed_pragmas(WN *wn, WN *parent_wn);
00215 BOOL Field_id_valid (WN* wn);
00216
00217
00218 public:
00219 WN_Verifier(WN *wn);
00220 ~WN_Verifier();
00221 BOOL WN_traverse_tree(WN *wn, WN *parent_wn);
00222 };
00223
00224
00225
00226
00227
00228
00229
00230 WN_Verifier::WN_Verifier(WN *wn)
00231 {
00232
00233
00234 MEM_POOL_Initialize(&_mem_pool, "Verifier_Pool", FALSE);
00235 MEM_POOL_Push(&_mem_pool);
00236 _map = WN_MAP_Create(&_mem_pool);
00237
00238
00239
00240 _is_tree_OK=TRUE;
00241
00242 if (WN_operator(wn) == OPR_FUNC_ENTRY)
00243 _func = wn;
00244 else
00245 _func = NULL;
00246 }
00247
00248
00249 WN_Verifier::~WN_Verifier(void)
00250 {
00251
00252
00253 WN_MAP_Delete(_map);
00254 MEM_POOL_Pop(&_mem_pool);
00255 MEM_POOL_Delete(&_mem_pool);
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265 BOOL
00266 WN_Verifier::WN_traverse_tree(WN *wn, WN *parent_wn)
00267 {
00268 OPCODE op;
00269
00270 if (wn)
00271 {
00272 op = WN_opcode(wn);
00273
00274
00275 _is_tree_OK &= Is_WHIRL_tree(wn, parent_wn);
00276
00277
00278
00279 switch(OPCODE_operator(op))
00280 {
00281 case OPR_FUNC_ENTRY:
00282 case OPR_XGOTO:
00283 case OPR_ALTENTRY:
00284
00285 _is_tree_OK &= ST_is_not_NULL(wn,op);
00286 break;
00287 case OPR_LDID:
00288
00289
00290
00291 _is_tree_OK &= CALL_parent_LDID(wn, parent_wn);
00292 _is_tree_OK &= TY_is_not_NULL(wn,op);
00293 _is_tree_OK &= ST_is_not_NULL(wn,op);
00294 _is_tree_OK &= Field_id_valid(wn);
00295 break;
00296 case OPR_LDA:
00297
00298
00299
00300 _is_tree_OK &= LDA_ty_not_NULL(wn);
00301 _is_tree_OK &= ST_is_not_NULL(wn,op);
00302 break;
00303 case OPR_IDNAME:
00304 case OPR_CONST:
00305
00306 _is_tree_OK &= ST_is_not_NULL(wn,op);
00307 break;
00308 case OPR_STID:
00309
00310
00311 _is_tree_OK &= STID_check_st_class(wn);
00312 _is_tree_OK &= TY_is_not_NULL(wn,op);
00313 _is_tree_OK &= ST_is_not_NULL(wn,op);
00314 _is_tree_OK &= Field_id_valid(wn);
00315 break;
00316 case OPR_MLOAD:
00317 case OPR_ISTORE:
00318 case OPR_MSTORE:
00319
00320 _is_tree_OK &= TY_is_not_NULL(wn,op);
00321 _is_tree_OK &= Field_id_valid(wn);
00322 break;
00323 case OPR_ISTOREX:
00324 case OPR_TAS:
00325
00326 _is_tree_OK &= TY_is_not_NULL(wn,op);
00327 break;
00328 case OPR_ILOAD:
00329
00330 _is_tree_OK &= TY_is_not_NULL(wn,op);
00331 _is_tree_OK &= Load_addr_TY_is_not_NULL(wn,op);
00332 _is_tree_OK &= Field_id_valid(wn);
00333 break;
00334 case OPR_PARM:
00335
00336 _is_tree_OK &= Param_parent_is_Call(wn,parent_wn);
00337 break;
00338 case OPR_CALL:
00339 case OPR_PICCALL:
00340
00341
00342 _is_tree_OK &= Call_children_are_PARM(wn);
00343 _is_tree_OK &= ST_is_not_NULL(wn,op);
00344 break;
00345 case OPR_ICALL:
00346
00347
00348 _is_tree_OK &= Call_children_are_PARM(wn);
00349 _is_tree_OK &= TY_is_not_NULL(wn,op);
00350 break;
00351 case OPR_INTRINSIC_CALL:
00352 case OPR_IO:
00353 case OPR_INTRINSIC_OP:
00354
00355
00356 _is_tree_OK &= Call_children_are_PARM(wn);
00357 break;
00358 case OPR_PRAGMA:
00359
00360 _is_tree_OK &= Are_enclosed_pragmas(wn,parent_wn);
00361 break;
00362 default:
00363
00364 _is_tree_OK &= Is_legal_wn_opcode(op);
00365 }
00366
00367 if ( op == OPC_BLOCK)
00368 {
00369
00370 Proper_Block_Structure(wn,op);
00371 for(WN *node = WN_first(wn); node; node = WN_next(node))
00372 _is_tree_OK &= WN_traverse_tree(node,wn);
00373 } else {
00374 for(INT32 i = 0; i < WN_kid_count(wn); i++)
00375 _is_tree_OK &= WN_traverse_tree(WN_kid(wn,i),wn);
00376 }
00377 }
00378 if (!parent_wn) {
00379 if (WN_Tree_Has_Duplicate_Labels(wn, &_mem_pool))
00380 Fail_FmtAssertion("WN_Verifier() found duplicate labels in "
00381 "WHIRL tree");
00382 }
00383 return _is_tree_OK;
00384 }
00385
00386
00387 BOOL WN_Verifier::TY_is_not_NULL(WN *wn, OPCODE op)
00388 {
00389 FmtAssert(WN_ty(wn) != (TY_IDX)NULL,
00390 ("WN_verifier Error (TY_is_not_NULL): whirl node %s has "
00391 "a TY == NULL", OPCODE_name(op)));
00392 return TRUE;
00393 }
00394
00395
00396 BOOL WN_Verifier::Load_addr_TY_is_not_NULL(WN *wn, OPCODE op)
00397 {
00398 FmtAssert(WN_load_addr_ty(wn) != (TY_IDX)NULL,
00399 ("WN_verifier Error (Load_addr_TY_is_not_NULL): whirl "
00400 "node %s has a TY == NULL", OPCODE_name(op)));
00401 return TRUE;
00402 }
00403
00404
00405
00406
00407 BOOL WN_Verifier::ST_is_not_NULL(WN *wn, OPCODE op)
00408 {
00409 FmtAssert(WN_st_idx(wn)!=(ST_IDX)NULL,
00410 ("WN_verifier Error (ST_is_not_NULL): whirl node %s "
00411 "has a ST == NULL", OPCODE_name(op)));
00412
00413 if (ST_is_not_used (WN_st(wn)) && !OPERATOR_is_store (WN_operator (wn)))
00414 DevWarn ("WN_verifier Error: whirl node %s references symbol"
00415 " %s that is marked NOT_USED", OPCODE_name(op),
00416 ST_name (WN_st(wn)));
00417 return TRUE;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427 BOOL
00428 WN_Verifier::Is_WHIRL_tree(WN *wn, WN *parent_wn)
00429 {
00430 if (Is_legal_wn_opcode(WN_opcode(wn)) == FALSE)
00431 return FALSE;
00432 if ( WN_MAP_Get(_map, wn) != NULL ) {
00433 FmtAssert(FALSE, ("WN_verifier ERROR: This is not a WHIRL tree\n\t"
00434 "(0x%x --> 0x%x, 0x%x --> 0x%x).\n",
00435 WN_MAP_Get(_map, wn), wn, parent_wn, wn));
00436 return FALSE;
00437 } else
00438 WN_MAP_Set(_map, wn, (void *)parent_wn);
00439 return TRUE;
00440 }
00441
00442
00443
00444 BOOL WN_Verifier::Is_dedicated_return_register(WN_OFFSET preg)
00445 {
00446 return ((preg == 2) || (preg == 3) || (preg == 32) || (preg==34));
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 WN *
00459 WN_Verifier::One_level_removed_node(WN *parent_wn,OPERATOR opr)
00460 {
00461 WN *temp_wn = NULL;
00462
00463 if (opr == OPR_LDID && parent_wn != NULL &&
00464 WN_operator(parent_wn) == OPR_STID)
00465 temp_wn = WN_prev(parent_wn);
00466 return temp_wn;
00467 }
00468
00469
00470
00471
00472
00473
00474
00475
00476 BOOL
00477 WN_Verifier::Is_return_register_of_call(WN *call_wn, PREG_NUM preg)
00478 {
00479 PREG_NUM retreg1, retreg2;
00480 TYPE_ID ty1,ty2;
00481
00482 if (Verifier_DEBUG)
00483 DevWarn("Verifier TODO: how do I know to use "
00484 "Use_Similated/Complex_Not...");
00485
00486
00487 const PU& pu = Pu_Table[ST_pu (WN_st (call_wn))];
00488
00489 if (WHIRL_Return_Info_On) {
00490
00491 RETURN_INFO return_info = Get_Return_Info (TY_ret_type (Ty_Table[PU_prototype (pu)]),
00492 Complex_Not_Simulated);
00493
00494 if (RETURN_INFO_count(return_info) <= 2) {
00495
00496 ty1 = RETURN_INFO_mtype (return_info, 0);
00497 ty2 = RETURN_INFO_mtype (return_info, 1);
00498 retreg1 = RETURN_INFO_preg (return_info, 0);
00499 retreg2 = RETURN_INFO_preg (return_info, 1);
00500 }
00501
00502 else
00503 Fail_FmtAssertion (
00504 "WN_Verifier::Is_return_register_of_call: more than 2 return registers");
00505 }
00506
00507 else
00508 Get_Return_Mtypes (TY_ret_type (Ty_Table[PU_prototype (pu)]),
00509 Complex_Not_Simulated, &ty1,&ty2);
00510
00511
00512
00513 if (!WHIRL_Return_Info_On)
00514 Get_Return_Pregs(ty1,ty2,&retreg1,&retreg2);
00515 return ((preg == retreg1) || (preg == retreg2));
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 BOOL WN_Verifier::CALL_parent_LDID(WN *wn, WN *parent_wn)
00530 {
00531 OPCODE opc=WN_opcode(wn);
00532 OPERATOR opr = OPCODE_operator(opc);
00533 WN *temp_wn;
00534 BOOL slink_used;
00535
00536 #ifndef TARG_IA64
00537
00538
00539
00540
00541
00542
00543 if (opr == OPR_LDID && ST_class(WN_st(wn)) == CLASS_PREG &&
00544 Is_dedicated_return_register(WN_offset(wn)))
00545 {
00546 temp_wn = One_level_removed_node(parent_wn,opr);
00547 if (_func != NULL) {
00548 const PU& pu = Pu_Table[ST_pu (WN_st (_func))];
00549 slink_used = PU_is_nested_func(pu);
00550 } else
00551 slink_used = TRUE;
00552
00553 if ((temp_wn !=NULL) && (WN_operator(temp_wn) == OPR_STID))
00554 temp_wn = WN_prev(temp_wn);
00555
00556
00557
00558
00559 if (temp_wn==NULL) {
00560 if (!slink_used) {
00561 DevWarn("WN_verifier Error (Call_parent_LDID): no CALL "
00562 "instruction one/two level(s) removed from LDID %d",
00563 WN_offset(wn));
00564 return FALSE;
00565 } else {
00566 return TRUE;
00567 }
00568 }
00569
00570 OPCODE t_opc = WN_opcode(temp_wn);
00571 OPERATOR t_opr = OPCODE_operator(t_opc);
00572
00573
00574
00575 if ( t_opr == OPR_CALL || t_opr == OPR_ICALL ||
00576 t_opr == OPR_INTRINSIC_CALL ||
00577 t_opr == OPR_PICCALL || t_opr == OPR_IO ||
00578 t_opr == OPR_INTRINSIC_OP)
00579 {
00580
00581 if ( t_opr == OPR_CALL &&
00582 !Is_return_register_of_call(temp_wn,WN_offset(wn)))
00583 {
00584 DevWarn("WN_verifier Error (Call_parent_LDID): different register "
00585 "follows CALL than needed, LDID %d", WN_offset(wn));
00586 return FALSE;
00587 }
00588 else if (Verifier_DEBUG)
00589 DevWarn("Verifier (Call_parent_LDID): Call is Ok");
00590 }
00591
00592
00593
00594
00595 else if (!slink_used)
00596 {
00597 DevWarn("WN_verifier Error (Call_parent_LDID): LDID %d was not "
00598 "following any CALL node", WN_offset(wn));
00599 return FALSE;
00600 }
00601
00602 }
00603 #endif
00604 return TRUE;
00605 }
00606
00607
00608
00609 BOOL WN_Verifier::Proper_Block_Structure(WN *wn,OPCODE op)
00610 {
00611 BOOL block_ok = TRUE;
00612
00613 if (op == OPC_BLOCK)
00614 {
00615
00616 WN *first = WN_first(wn);
00617 WN *last = WN_last(wn);
00618 if ( first == NULL ) {
00619 FmtAssert( last == NULL,
00620 ("WN_verifier Error (Proper_Block_Structure): first is NULL but last is not."));
00621 block_ok = FALSE;
00622 }
00623 if ( first != NULL && WN_prev(first) != NULL){
00624 FmtAssert(FALSE, ("WN_verifier Error (Proper_Block_Structure): This block does "
00625 "not have a null pointer in the first wn node"));
00626 block_ok = FALSE;
00627 }
00628
00629
00630 if ( last != NULL && WN_next(last) != NULL ) {
00631 FmtAssert(FALSE, ("WN_verifier Error (Proper_Block_Structure): This block does "
00632 "not have a null pointer in the last wn node"));
00633 block_ok = FALSE;
00634 }
00635
00636
00637 WN *tmp = first;
00638 while (tmp && WN_next(tmp) != NULL)
00639 tmp = WN_next(tmp);
00640 if (tmp != last) {
00641 FmtAssert (FALSE, ("WN_verifier Error (Proper_Block_Structure): last is not really last\n"));
00642 block_ok = FALSE;
00643 }
00644
00645
00646 tmp = last;
00647 while (tmp && WN_prev(tmp) != NULL)
00648 tmp = WN_prev(tmp);
00649 if (tmp != first) {
00650 FmtAssert (FALSE, ("WN_verifier Error (Proper_Block_Structure): first is not really firstt\n"));
00651 block_ok = FALSE;
00652 }
00653 }
00654 return block_ok;
00655 }
00656
00657
00658
00659
00660 BOOL WN_Verifier::Param_parent_is_Call(WN *wn,WN *parent_wn)
00661 {
00662 OPCODE opc=WN_opcode(wn);
00663 OPERATOR opr = OPCODE_operator(opc);
00664
00665 if (opr == OPR_PARM)
00666 {
00667 opc = WN_opcode(parent_wn);
00668 opr = OPCODE_operator(opc);
00669 if (opr == OPR_CALL || opr == OPR_ICALL ||
00670 opr == OPR_INTRINSIC_CALL ||
00671 opr == OPR_PICCALL || opr == OPR_IO ||
00672 opr == OPR_INTRINSIC_OP)
00673 {
00674
00675 return TRUE;
00676 } else {
00677
00678 DevWarn("WN_verifier Error (Param_parent_is_Call): The parent of the "
00679 "PARM node is not a CALL node but a %s node",OPCODE_name(opc));
00680 return FALSE;
00681 }
00682 }
00683 return TRUE;
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 BOOL WN_Verifier::Call_children_are_PARM(WN *wn)
00695 {
00696 OPCODE opc=WN_opcode(wn);
00697 OPCODE parent_opc=opc;
00698 OPERATOR opr = OPCODE_operator(opc);
00699 OPERATOR parent_opr=opr;
00700
00701 if (opr == OPR_CALL ||
00702 opr == OPR_INTRINSIC_CALL ||
00703 opr == OPR_INTRINSIC_OP ||
00704 opr == OPR_IO)
00705 {
00706 for(INT32 i=0; i < WN_kid_count(wn); i++)
00707 {
00708 opc = WN_opcode(WN_kid(wn,i));
00709 opr = OPCODE_operator(opc);
00710
00711
00712
00713
00714
00715
00716
00717
00718 if ((opr != OPR_PARM ) &&
00719 ((parent_opr == OPR_IO) && (opr != OPR_IO_ITEM)) )
00720 {
00721
00722 DevWarn("WN_verifier Error (Call_children_are_PARM): The child of %s "
00723 "node is not a PARM node but a %s node",
00724 OPCODE_name(parent_opc), OPCODE_name(opc));
00725 return FALSE;
00726 }
00727 }
00728 }
00729 else if ( opr == OPR_PICCALL || opr == OPR_ICALL)
00730 {
00731 for(INT32 i=0; i < WN_kid_count(wn); i++)
00732 { opc = WN_opcode(WN_kid(wn,i));
00733 opr = OPCODE_operator(opc);
00734
00735
00736
00737 if ((opr != OPR_PARM) && (i < (WN_kid_count(wn)-1) ))
00738 {
00739
00740 DevWarn("WN_verifier Error (Call_children_are_PARM): The child of "
00741 "CALL node is not a PARM node but a %s node",
00742 OPCODE_name(opc));
00743 return FALSE;
00744 }
00745
00746 else if ((opr == OPR_PARM) && (i == (WN_kid_count(wn)-1)))
00747 {
00748 DevWarn("WN_verifier Error (Call_children_are_PARM): The last "
00749 "child of (P)ICALL node is a PARM node");
00750 return FALSE;
00751 }
00752 }
00753 }
00754
00755 return TRUE;
00756 }
00757
00758
00759
00760
00761
00762
00763
00764
00765 BOOL WN_Verifier::Is_legal_wn_opcode(OPCODE opc)
00766 {
00767
00768 if (opc < OPCODE_FIRST || opc > OPCODE_LAST)
00769 {
00770 DevWarn("WN_verifier Error (Is_legal_wn_opcode): The opcode %s "
00771 "is illegal",OPCODE_name(opc));
00772 }
00773 return ((opc >= OPCODE_FIRST) && (opc <= OPCODE_LAST));
00774 }
00775
00776
00777
00778 BOOL WN_Verifier::LDA_ty_not_NULL(WN *wn)
00779 {
00780 OPCODE opc = WN_opcode(wn);
00781 OPERATOR opr = OPCODE_operator(opc);
00782
00783 if (opr == OPR_LDA) {
00784 const TY& ty = Ty_Table[WN_ty (wn)];
00785 if (WN_ty (wn) == 0 ||
00786 !(TY_kind(ty) == KIND_POINTER || TY_kind(ty) == KIND_SCALAR)) {
00787 DevWarn("WN_verifier Error (LDA_ty_not_NULL): TY of the %s is "
00788 "either NULL or is not a pointer or scalar",
00789 OPCODE_name(opc));
00790 ty.Print (stderr);
00791 return FALSE;
00792 }
00793 }
00794 return TRUE;
00795 }
00796
00797
00798
00799
00800
00801 BOOL WN_Verifier::STID_check_st_class(WN *wn)
00802 {
00803 OPCODE opc = WN_opcode(wn);
00804 OPERATOR opr = OPCODE_operator(opc);
00805
00806 if (opr == OPR_STID) {
00807 ST * st = WN_st(wn);
00808
00809 if ( ( ST_class(st)!=CLASS_VAR ) &&
00810 ( ST_class(st)!=CLASS_PREG ) &&
00811 ( ST_class(st)!=CLASS_BLOCK) )
00812 {
00813 DevWarn("WN_verifier Error (STID_check_st_class): ST of the STID is "
00814 "not CLASS: VAR, PREG or Block but %d", ST_class(st));
00815 return FALSE;
00816 }
00817 if ( (ST_class(st) == CLASS_PREG) &&
00818 (Is_dedicated_return_register(WN_offset(wn))) )
00819 {
00820 WN *temp_wn = WN_next(wn);
00821
00822
00823
00824 if ((temp_wn != NULL) &&
00825 (WN_operator(temp_wn) == OPR_STID) &&
00826 (ST_class(WN_st(temp_wn)) == CLASS_PREG ) &&
00827 (Is_dedicated_return_register(WN_offset(temp_wn))) )
00828 {
00829
00830
00831
00832
00833 temp_wn=WN_next(temp_wn);
00834 }
00835
00836
00837
00838
00839
00840 if ((WN_offset(wn) != Static_Link_Preg_Offset) &&
00841 ((temp_wn == NULL) || (WN_operator(temp_wn) != OPR_RETURN)) )
00842 {
00843 DevWarn("WN_verifier Error (STID_check_st_class): STID %d was "
00844 "followed by %s and not by OPC_RETURN",
00845 WN_offset(wn),
00846 temp_wn ? OPCODE_name(WN_opcode(temp_wn)) : "NULL");
00847 }
00848 else if ((WN_offset(wn) == Static_Link_Preg_Offset) &&
00849 ((temp_wn == NULL) || (WN_operator(temp_wn) != OPR_RETURN)
00850 && (WN_operator(temp_wn) != OPR_PICCALL)
00851 && (WN_operator(temp_wn) != OPR_CALL)) )
00852 {
00853 DevWarn("WN_verifier Error (STID_check_st_class): STID %d was "
00854 "followed by %s and not by OPC_RETURN or OPR_CALL or OPR_PICCALL",
00855 WN_offset(wn),OPCODE_name(WN_opcode(temp_wn)));
00856 }
00857 }
00858
00859
00860 switch(ST_sclass(st))
00861 {
00862 case SCLASS_UNKNOWN:
00863 case SCLASS_AUTO:
00864 case SCLASS_FORMAL:
00865 case SCLASS_PSTATIC:
00866 case SCLASS_FSTATIC:
00867 case SCLASS_COMMON:
00868 case SCLASS_EXTERN:
00869 case SCLASS_UGLOBAL:
00870 case SCLASS_DGLOBAL:
00871 case SCLASS_REG:
00872 case SCLASS_FORMAL_REF:
00873
00874
00875 break;
00876
00877 case SCLASS_TEXT:
00878 DevWarn("WN_verifier Error (STID_check_st_class): ST SCLASS "
00879 "is SCALSS_TEXT");
00880 Print_ST(stderr, st, FALSE);
00881 return FALSE;
00882
00883
00884 default:
00885 DevWarn("WN_verifier Error (STID_check_st_class): ST SCLASS "
00886 "is unknown");
00887 Print_ST(stderr, st, FALSE);
00888 return FALSE;
00889 }
00890 }
00891 return TRUE;
00892 }
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 BOOL WN_Verifier::Are_enclosed_pragmas(WN *wn,WN *parent_wn)
00914 {
00915 pragma_stack_type temp;
00916 WN_PRAGMA_ID temp_id= (WN_PRAGMA_ID) WN_pragma(wn);
00917 int i = 0;
00918
00919
00920 while(i<NUM_PRAGMAS_SUPPORTED)
00921 {
00922
00923 if (pragmas_supported[i].pragma_id=temp_id)
00924 {
00925
00926
00927 if (pragmas_supported[i].push)
00928 {
00929 temp.pragma_id = temp_id;
00930 temp.parent_wn = parent_wn;
00931 _pragma_stack.push(temp);
00932 return TRUE;
00933 }
00934
00935
00936 else if (_pragma_stack.size()>0)
00937 {
00938 temp= _pragma_stack.top();
00939
00940
00941
00942
00943
00944 if (temp.pragma_id == pragmas_supported[i].pragma_starting_id &&
00945 temp.parent_wn == parent_wn)
00946 {
00947 if (Verifier_DEBUG)
00948 DevWarn("Stack worked!!");
00949 _pragma_stack.pop();
00950 return TRUE;
00951 }
00952 else if (temp.pragma_id != pragmas_supported[i].pragma_starting_id)
00953 {
00954 DevWarn("WN_verifier Error (Are_enclosed_pragmas): on stack "
00955 "expecting %d but got %d",
00956 pragmas_supported[i].pragma_starting_id, temp.pragma_id);
00957 return FALSE;
00958 }
00959 else
00960 {
00961 DevWarn("WN_verifier Error (Are_enclosed_pragmas): the pragma "
00962 "is closed by different level of the parent");
00963 return FALSE;
00964 }
00965
00966 }
00967 else
00968 {
00969 return FALSE;
00970 }
00971 }
00972 i++;
00973 }
00974 return TRUE;
00975 }
00976
00977
00978 BOOL
00979 WN_Verifier::Field_id_valid (WN* wn)
00980 {
00981 const TY* ty = &Ty_Table[WN_ty (wn)];
00982
00983 switch (WN_operator(wn)) {
00984 case OPR_MLOAD:
00985 case OPR_MSTORE:
00986 Is_True (TY_kind (*ty) == KIND_POINTER,
00987 ("MLOAD/MSTORE expects a pointer type"));
00988 if (TY_kind(TY_pointed(*ty)) == KIND_STRUCT &&
00989 WN_field_id(wn) == 0) {
00990 WN* kid = WN_operator(wn) == OPR_MLOAD ? WN_kid1(wn) : WN_kid2(wn);
00991 if (WN_operator(kid) == OPR_INTCONST) {
00992 INT64 ty_size = TY_size(TY_pointed(*ty));
00993
00994 Is_True (ty_size == 0 || WN_const_val (kid) % ty_size == 0,
00995 ("MLOAD/MSTORE size is inconsistent with TY"));
00996 }
00997 }
00998 break;
00999
01000 case OPR_ISTORE:
01001 ty = &Ty_Table[TY_pointed (*ty)];
01002
01003 default:
01004 if (TY_kind(*ty) != KIND_STRUCT) {
01005 Is_True (WN_field_id(wn) == 0,
01006 ("non-zero field id for memory op on scalar"));
01007 } else if (WN_field_id(wn) == 0) {
01008 Is_True (WN_desc(wn) == MTYPE_M ||
01009 MTYPE_byte_size(WN_desc(wn)) == TY_size(*ty),
01010 ("field_id and descriptor type are inconsistent"));
01011 }
01012 break;
01013 }
01014
01015 return TRUE;
01016 }
01017
01018
01019
01020
01021
01022
01023
01024 BOOL WN_Tree_Has_Duplicate_Labels(WN *pu_wn, MEM_POOL *tmp_pool)
01025 {
01026 MEM_POOL_Popper popper(tmp_pool);
01027 WN_ITER *it = WN_WALK_TreeIter(pu_wn);
01028 HASH_TABLE<LABEL_IDX, WN *> labels_found(257, tmp_pool);
01029
01030 while (it) {
01031 WN *wn = it->wn;
01032
01033 if (WN_operator(wn) == OPR_LABEL) {
01034 LABEL_IDX lab = WN_label_number(wn);
01035 Is_True(lab > 0, ("WN_verifier: found label with number 0"));
01036 Is_True(lab <= LABEL_Table_Size(CURRENT_SYMTAB),
01037 ("WN_verifier: label %d greater than last label %d",
01038 (INT) lab, LABEL_Table_Size(CURRENT_SYMTAB)));
01039 WN *dup_lab_wn = labels_found.Find(lab);
01040
01041 if (dup_lab_wn)
01042 return TRUE;
01043
01044 labels_found.Enter(lab, wn);
01045 }
01046
01047 it = WN_WALK_TreeNext(it);
01048 }
01049
01050 return FALSE;
01051 }
01052
01053
01054
01055 enum WN_Label_Fields {
01056 WN_HAS_NO_LABELS,
01057 WN_HAS_LABEL,
01058 WN_HAS_LAST_LABEL
01059 };
01060
01061
01062 static WN_Label_Fields WN_Has_Label(WN *wn)
01063 {
01064 Is_True(wn, ("NULL wn"));
01065
01066 switch (WN_operator(wn)) {
01067 case OPR_CASEGOTO:
01068 case OPR_FALSEBR:
01069 case OPR_GOTO:
01070 case OPR_LABEL:
01071 case OPR_REGION_EXIT:
01072 case OPR_TRUEBR:
01073 return WN_HAS_LABEL;
01074 case OPR_COMPGOTO:
01075 case OPR_SWITCH:
01076 return WN_HAS_LAST_LABEL;
01077 default:
01078 break;
01079 }
01080
01081 return WN_HAS_NO_LABELS;
01082 }
01083
01084 typedef HASH_TABLE<LABEL_IDX, LABEL_IDX> LABEL_RENAMING_MAP;
01085
01086 static BOOL
01087 References_Some_Label(WN *pu_wn, LABEL_RENAMING_MAP *lab_map, WN *orig_wn);
01088
01089 static void
01090 Rename_INITV_Labels(INITO_IDX inito_idx, LABEL_RENAMING_MAP *lab_map,
01091 MEM_POOL *tmp_pool);
01092
01093 BOOL
01094 WN_Rename_Duplicate_Labels(WN *orig_wn, WN *copied_wn, WN *pu_wn,
01095 MEM_POOL *tmp_pool)
01096 {
01097 MEM_POOL_Popper popper(tmp_pool);
01098 LABEL_RENAMING_MAP lab_map(1021, tmp_pool);
01099
01100
01101 WN_ITER *orig_it = WN_WALK_TreeIter(orig_wn);
01102
01103 while (orig_it) {
01104 WN *wn = orig_it->wn;
01105
01106 if (WN_operator(wn) == OPR_LABEL) {
01107
01108 LABEL_IDX lab_idx = WN_label_number(wn), new_lab_idx;
01109 Is_True(!lab_map.Find(lab_idx),
01110 ("duplicate label %d in orig_wn", (INT) lab_idx));
01111
01112 LABEL &new_lab = New_LABEL(CURRENT_SYMTAB, new_lab_idx);
01113 char* Cur_PU_Name = ST_name(PU_Info_proc_sym(Current_PU_Info));
01114 INT strsize = strlen(User_Label_Number_Format) + 64 + strlen(Cur_PU_Name);
01115 char * labelname = (char*) calloc(strsize, 1);
01116 sprintf(labelname, User_Label_Number_Format, (INT) CURRENT_SYMTAB,
01117 (INT) new_lab_idx, Cur_PU_Name);
01118 LABEL_Init(new_lab, Save_Str(labelname),
01119 LABEL_kind((*Scope_tab[CURRENT_SYMTAB].label_tab)[lab_idx]));
01120
01121 lab_map.Enter(lab_idx, new_lab_idx);
01122 }
01123
01124 orig_it = WN_WALK_TreeNext(orig_it);
01125 }
01126
01127
01128 WN_ITER *copied_it = WN_WALK_TreeIter(copied_wn);
01129
01130 while (copied_it) {
01131 WN *wn = copied_it->wn;
01132 WN_Label_Fields wn_lab = WN_Has_Label(wn);
01133
01134 if (wn_lab == WN_HAS_LABEL || wn_lab == WN_HAS_LAST_LABEL) {
01135 LABEL_IDX lab_idx = (wn_lab == WN_HAS_LABEL) ? WN_label_number(wn) :
01136 WN_last_label(wn);
01137
01138 LABEL_IDX new_lab_idx = lab_map.Find(lab_idx);
01139 if (new_lab_idx) {
01140 if (wn_lab == WN_HAS_LABEL)
01141 WN_label_number(wn) = new_lab_idx;
01142 else
01143 WN_last_label(wn) = new_lab_idx;
01144 }
01145
01146 } else if (wn_lab != WN_HAS_NO_LABELS)
01147 Fail_FmtAssertion("impossible return value from WN_Has_Label");
01148
01149 if (WN_operator(wn) == OPR_REGION && WN_ereg_supp(wn))
01150 Rename_INITV_Labels(WN_ereg_supp(wn), &lab_map, tmp_pool);
01151
01152 copied_it = WN_WALK_TreeNext(copied_it);
01153 }
01154
01155 if (!pu_wn)
01156 return TRUE;
01157
01158
01159 return !References_Some_Label(pu_wn, &lab_map, orig_wn);
01160 }
01161
01162
01163
01164 static BOOL
01165 References_Some_Label(WN *pu_wn, LABEL_RENAMING_MAP *lab_map, WN *orig_wn)
01166 {
01167 Is_True(pu_wn, ("NULL pu_wn"));
01168
01169 if (pu_wn == orig_wn)
01170 return FALSE;
01171
01172 WN_Label_Fields wn_lab = WN_Has_Label(pu_wn);
01173
01174 if (wn_lab == WN_HAS_LABEL || wn_lab == WN_HAS_LAST_LABEL) {
01175 LABEL_IDX lab_idx = (wn_lab == WN_HAS_LABEL) ? WN_label_number(pu_wn) :
01176 WN_last_label(pu_wn);
01177 if (lab_map->Find(lab_idx))
01178 return TRUE;
01179
01180 } else if (wn_lab != WN_HAS_NO_LABELS)
01181 Fail_FmtAssertion("impossible return value from WN_Has_Label");
01182
01183 OPERATOR opr = WN_operator(pu_wn);
01184
01185 if (!OPERATOR_is_leaf(opr)) {
01186 if (opr == OPR_BLOCK) {
01187 for (WN *kid = WN_first(pu_wn); kid; kid = WN_next(kid))
01188 if (References_Some_Label(kid, lab_map, orig_wn))
01189 return TRUE;
01190
01191 } else {
01192 for (INT kidno = 0; kidno < WN_kid_count(pu_wn); kidno++)
01193 if (References_Some_Label(WN_kid(pu_wn, kidno), lab_map, orig_wn))
01194 return TRUE;
01195 }
01196 }
01197
01198 return FALSE;
01199 }
01200
01201
01202
01203
01204
01205 static void
01206 Rename_INITV_Labels(INITO_IDX inito_idx, LABEL_RENAMING_MAP *lab_map,
01207 MEM_POOL *tmp_pool)
01208 {
01209 {
01210 BOOL renamed_labels_found = FALSE;
01211 STACK<INITV_IDX> initv_stack(tmp_pool);
01212 INITV_IDX val_idx = INITO_val(inito_idx);
01213
01214 while (val_idx) {
01215 INITVKIND k = INITV_kind(val_idx);
01216 switch (k) {
01217 case INITVKIND_SYMOFF:
01218 case INITVKIND_ZERO:
01219 case INITVKIND_ONE:
01220 case INITVKIND_VAL:
01221 case INITVKIND_PAD:
01222 val_idx = INITV_next(val_idx);
01223 break;
01224
01225 case INITVKIND_BLOCK:
01226 initv_stack.Push(val_idx);
01227 val_idx = INITV_blk(val_idx);
01228 break;
01229
01230 case INITVKIND_SYMDIFF:
01231 case INITVKIND_SYMDIFF16:
01232 case INITVKIND_LABEL:
01233 {
01234 LABEL_IDX lab = (k == INITVKIND_LABEL) ? INITV_lab(val_idx) :
01235 INITV_lab1(val_idx);
01236 if (lab_map->Find(lab))
01237 renamed_labels_found = TRUE;
01238 }
01239 break;
01240
01241 default:
01242 Fail_FmtAssertion("unknown INITV kind %d", (INT) k);
01243 }
01244 if (renamed_labels_found)
01245 break;
01246
01247 while (!val_idx && initv_stack.Elements() > 0) {
01248 val_idx = INITV_next(initv_stack.Pop());
01249 }
01250 }
01251
01252 if (!renamed_labels_found)
01253 return;
01254 }
01255
01256
01257 STACK<INITV_IDX> old_stack(tmp_pool), new_stack(tmp_pool);
01258 INITV_IDX old_initv = INITO_val(inito_idx),
01259 new_initv,
01260 parent = INITV_IDX_ZERO,
01261 prev = INITV_IDX_ZERO;
01262 BOOL first_new_initv = TRUE;
01263
01264 while (old_initv) {
01265 new_initv = Copy_INITV(INITV_IDX_ZERO, INITO_IDX_ZERO, old_initv);
01266
01267 if (first_new_initv) {
01268 Set_INITO_val(inito_idx, new_initv);
01269 first_new_initv = FALSE;
01270 } else if (parent) {
01271 Set_INITV_blk(parent, new_initv);
01272 parent = INITV_IDX_ZERO;
01273 } else if (prev) {
01274 Set_INITV_next(prev, new_initv);
01275 }
01276
01277 INITVKIND k = INITV_kind(old_initv);
01278 switch (k) {
01279 case INITVKIND_SYMOFF:
01280 case INITVKIND_ZERO:
01281 case INITVKIND_ONE:
01282 case INITVKIND_VAL:
01283 case INITVKIND_PAD:
01284 old_initv = INITV_next(old_initv);
01285 prev = new_initv;
01286 break;
01287
01288 case INITVKIND_BLOCK:
01289 old_stack.Push(old_initv);
01290 new_stack.Push(new_initv);
01291 old_initv = INITV_blk(old_initv);
01292 parent = new_initv;
01293 prev = INITV_IDX_ZERO;
01294 break;
01295
01296 case INITVKIND_SYMDIFF:
01297 case INITVKIND_SYMDIFF16:
01298 case INITVKIND_LABEL:
01299 {
01300 LABEL_IDX lab = (k == INITVKIND_LABEL) ? INITV_lab(new_initv) :
01301 INITV_lab1(new_initv),
01302 new_lab = lab_map->Find(lab);
01303
01304 if (new_lab)
01305 if (k == INITVKIND_LABEL)
01306 Set_INITV_lab(new_initv, new_lab);
01307 else
01308 Set_INITV_lab1(new_initv, new_lab);
01309 }
01310 old_initv = INITV_next(old_initv);
01311 prev = new_initv;
01312 break;
01313
01314 default:
01315 Fail_FmtAssertion("unknown INITV kind %d", (INT) k);
01316 }
01317
01318 while (!old_initv && old_stack.Elements() > 0) {
01319 old_initv = INITV_next(old_stack.Pop());
01320 prev = new_stack.Pop();
01321 }
01322
01323 }
01324
01325 }
01326
01327
01328 BOOL
01329 WN_verifier(WN *wn)
01330 {
01331 Temporary_Error_Phase ("WN_verifier");
01332 #ifdef Is_True_On
01333 char *p = getenv ("WN_VERIFIER");
01334 if (p != 0 && strcasecmp (p, "off") == 0)
01335 return TRUE;
01336 if (Verifier_DEBUG)
01337 DevWarn("I am running newest verifier");
01338 WN_Verifier wnv(wn);
01339 return wnv.WN_traverse_tree(wn, NULL);
01340 #else
01341 return TRUE;
01342 #endif
01343 }