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 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include "lego.H"
00029 #include "search.H"
00030
00031
00032 #ifdef SEARCH_DEBUG
00033 #define dprintf(s) fprintf s
00034 #define OUTF stderr
00035 #else
00036 #define dprintf(s)
00037 #endif // SEARCH_DEBUG
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 legoOp *
00049 FindMaxOpId (legoProc *proc)
00050 {
00051 legoOp *allList, *maxop = NULL;
00052 int maxid = -1;
00053
00054 if (proc->GetRegionType() != RT_PROC)
00055 return NULL;
00056 for (allList = proc->GetListOpPtr();
00057 allList != NULL; allList = allList->GetListOpPtr())
00058 if (allList->GetOpId() > maxid)
00059 {
00060 maxid = allList->GetOpId();
00061 maxop = allList;
00062 }
00063 return maxop;
00064 }
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 legoOp *
00077 FindMaxOpId (legoModule *mod)
00078 {
00079 legoProc *proc;
00080 legoOp *procop, *maxop = NULL;
00081 int i, maxid = -1;
00082
00083 if (mod->GetRegionType() != RT_MODULE)
00084 return NULL;
00085 for (i = 0; i < mod->GetCount(); i++)
00086 {
00087 proc = (legoProc *) mod->GetItem(i);
00088 procop = FindMaxOpId (proc);
00089 if (procop != NULL && procop->GetOpId() > maxid)
00090 {
00091 maxid = procop->GetOpId();
00092 maxop = procop;
00093 }
00094 }
00095 return maxop;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 int FindMaxRegNum (legoProc *proc_ptr)
00109 {
00110 int max_id = 0;
00111 legoOp *allList = NULL;
00112 legoOprd *test_oprd = NULL;
00113
00114 if(proc_ptr->GetRegionType() != RT_PROC){
00115 LegoNonFatal("FindMaxRegNum","Warning: find_max_reg_num called for non-procedure.");
00116 return 0;
00117 }
00118 for(allList=proc_ptr->GetListOpPtr();allList!=NULL;allList = allList->GetListOpPtr()){
00119
00120 test_oprd = allList->GetSrcOprdPtr();
00121 while(test_oprd){
00122 if(test_oprd->GetOprdType()==OT_REG){
00123 if(test_oprd->GetOprdRegType() == RT_BR){
00124
00125 if(test_oprd->GetOprdIntValue()>max_id) max_id = test_oprd->GetOprdIntValue();
00126 }
00127 else if(test_oprd->GetOprdRegNum()>max_id) max_id = test_oprd->GetOprdRegNum();
00128 }
00129 test_oprd = test_oprd->GetNextOprdPtr();
00130 }
00131
00132 test_oprd = allList->GetDestOprdPtr();
00133 while(test_oprd){
00134 if(test_oprd->GetOprdType()==OT_REG){
00135 if(test_oprd->GetOprdRegType() == RT_BR){
00136 if(test_oprd->GetOprdIntValue()>max_id) max_id = test_oprd->GetOprdIntValue();
00137 }
00138 else if(test_oprd->GetOprdRegNum()>max_id) max_id = test_oprd->GetOprdRegNum();
00139 }
00140 test_oprd = test_oprd->GetNextOprdPtr();
00141 }
00142 }
00143 return max_id;
00144 }
00145
00146
00147
00148
00149
00150
00151 int FindMaxRegNum (legoProc *proc_ptr,enum fileTypes current_ft)
00152 {
00153 int max_id = 0;
00154 legoOp *allList = NULL;
00155 legoOprd *test_oprd = NULL;
00156
00157 if(proc_ptr->GetRegionType() != RT_PROC){
00158 LegoNonFatal("FindMaxRegNum","Warning: find_max_reg_num called for non-procedure.");
00159 return 0;
00160 }
00161 for(allList=proc_ptr->GetListOpPtr();allList!=NULL;allList = allList->GetListOpPtr()){
00162
00163 test_oprd = allList->GetSrcOprdPtr();
00164 while(test_oprd){
00165 if((test_oprd->GetOprdType() == OT_REG)&&(test_oprd->GetOprdFileType() == current_ft)){
00166 if(test_oprd->GetOprdRegType() == RT_BR){
00167
00168 if(test_oprd->GetOprdIntValue()>max_id) max_id = test_oprd->GetOprdIntValue();
00169 }
00170 else if(test_oprd->GetOprdRegNum()>max_id) max_id = test_oprd->GetOprdRegNum();
00171 }
00172 test_oprd = test_oprd->GetNextOprdPtr();
00173 }
00174
00175 test_oprd = allList->GetDestOprdPtr();
00176 while(test_oprd){
00177 if((test_oprd->GetOprdType() == OT_REG)&&(test_oprd->GetOprdFileType() == current_ft)){
00178 if(test_oprd->GetOprdRegType() == RT_BR){
00179 if(test_oprd->GetOprdIntValue()>max_id) max_id = test_oprd->GetOprdIntValue();
00180 }
00181 else if(test_oprd->GetOprdRegNum()>max_id) max_id = test_oprd->GetOprdRegNum();
00182 }
00183 test_oprd = test_oprd->GetNextOprdPtr();
00184 }
00185 }
00186 return max_id;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 int
00200 FindMaxEdgeAttrId (legoProc *proc)
00201 {
00202 opEdges *edge;
00203 attrs *at;
00204 int maxid = 0;
00205
00206
00207 edge = ((legoProc *) proc)->GetEdgeDictionary();
00208 if (edge == NULL)
00209 {
00210 LegoNonFatal ("FindMaxEdgeAttrId", "Edge dictionary is missing.");
00211 return 0;
00212 }
00213 at = ((legoProc *) proc)->GetAttrDictionary();
00214 if (at == NULL)
00215 {
00216 LegoNonFatal ("FindMaxEdgeAttrId", "Attribute dictionary is missing.");
00217 return 0;
00218 }
00219
00220 for ( ; edge != NULL; edge = edge->GetNextOpEdgePtr())
00221 if (edge->GetEdgeId() > maxid) maxid = edge->GetEdgeId();
00222 for ( ; at != NULL; at = at->GetNextAttrPtr())
00223 if (at->GetAttrId() > maxid) maxid = at->GetAttrId();
00224
00225 return maxid;
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 legoRegion *
00239 FindParentRegionType (enum regionTypes t, legoRegion *region)
00240 {
00241 legoRegion *r;
00242 for (r = region; r != NULL; r = r->GetParentPtr())
00243 if (r->GetRegionType() == t) break;
00244 if (r == NULL) return NULL;
00245 else return (legoProc *) r;
00246 }
00247
00248 legoRegion *
00249 FindParentRegionType (legoRegion *region, enum regionTypes t)
00250 {
00251 LegoNonFatal ("FindParentRegionType", "This is a deprecated version of "
00252 "this function.\nSwap the parameters in the call.");
00253
00254 return FindParentRegionType (t, region);
00255 }
00256
00257 legoRegion *
00258 FindParentRegionType (enum regionTypes t, legoOp *op)
00259 {
00260 return FindParentRegionType (t, (legoRegion *) (op->GetParentBlockPtr()));
00261 }
00262
00263 legoRegion *
00264 FindParentRegionType (legoOp *op, enum regionTypes t)
00265 {
00266 LegoNonFatal ("FindParentRegionType", "This is a deprecated version of "
00267 "this function.\nSwap the parameters in the call.");
00268
00269 return FindParentRegionType (t, op);
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 legoOp *
00283 FindFirstBranch (legoRegion *region)
00284 {
00285 opList *opl;
00286 legoOp *opscan;
00287
00288 opl = region->GetEntryOpsPtr();
00289 if (opl == NULL) return NULL;
00290
00291 for (opscan = opl->GetOpPtr(); opscan != NULL;
00292 opscan = opscan->GetNextLink())
00293 {
00294 if (opscan->GetOutListPtr() != NULL) return opscan;
00295 }
00296
00297 return NULL;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 int
00310 IsFallThrough (legoOp *src, legoOp *dest)
00311 {
00312 legoOp *walkop;
00313 legoOprd *btr;
00314
00315 if (src->GetOutListPtr() == NULL)
00316 {
00317 LegoNonFatal ("IsFallThrough", "Source op %d is not a branch!",
00318 src->GetOpId());
00319 return 0;
00320 }
00321 if (dest->IsCMERGEOp() == false)
00322 {
00323 LegoNonFatal ("IsFallThrough", "Destination op %d is not a merge!",
00324 dest->GetOpId());
00325 return 0;
00326 }
00327
00328
00329 if (src->IsDUMMYBROp()) return 1;
00330
00331
00332 if (src->GetNextLink() == dest) return 1;
00333
00334
00335 if (src->IsBRUOp()) return 0;
00336
00337
00338
00339 if (src->IsBRCONDOp())
00340 {
00341 for (walkop = src->GetPrevLink(); walkop != NULL;
00342 walkop = walkop->GetPrevLink())
00343 {
00344 if (walkop->GetOpcode() == PBRR) break;
00345 if (walkop->GetOpcode() == PBRA) break;
00346 }
00347 if (walkop == NULL)
00348 {
00349 LegoNonFatal ("IsFallThrough", "Can't find PBR before op %d.",
00350 src->GetOpId());
00351 return 0;
00352 }
00353 btr = walkop->GetSrcOprdPtr();
00354 if (btr == NULL)
00355 {
00356 LegoNonFatal ("IsFallThrough", "No btr operand for op %d.",
00357 walkop->GetOpId());
00358 return 0;
00359 }
00360 if (btr->GetOprdType() != OT_LITERAL_CB) return 0;
00361 if (btr->GetLiteralControlBlock() ==
00362 ((legoRegion *) dest->GetParentBlockPtr())->GetRegionId())
00363 return 0;
00364 return 1;
00365 }
00366
00367
00368 LegoNonFatal ("IsFallThrough", "Don't know how to decide on ops %d and "
00369 "%d.", src->GetOpId(), dest->GetOpId());
00370 return 0;
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 opEdges *
00389 FindControlEdge (legoOp *fromop, legoOp *toop, int between = 0)
00390 {
00391 opEdges *theedge;
00392
00393 if (fromop == NULL || toop == NULL)
00394 {
00395 LegoNonFatal ("FindControlEdge", "Passed NULL op.");
00396 return NULL;
00397 }
00398 if (between)
00399 {
00400 legoRegion *fromblock, *toblock;
00401 edgeList *outedges, *inedges;
00402
00403 fromblock = (legoRegion *) fromop->GetParentBlockPtr();
00404 toblock = (legoRegion *) toop->GetParentBlockPtr();
00405 theedge = NULL;
00406
00407 if (fromblock == NULL || toblock == NULL)
00408 {
00409 LegoNonFatal ("FindControlEdge", "Can't find parent block of "
00410 "an op.");
00411 }
00412 else
00413 {
00414
00415
00416 for (outedges = fromblock->GetOutEdgesPtr();
00417 outedges != NULL; outedges = outedges->GetNextListPtr())
00418 {
00419 if (outedges->GetEdgePtr()->GetFromOpPtr() != fromop)
00420 continue;
00421
00422 for (inedges = toblock->GetInEdgesPtr();
00423 inedges != NULL; inedges = inedges->GetNextListPtr())
00424 {
00425 if (inedges->GetEdgePtr() == outedges->GetEdgePtr())
00426 {
00427 theedge = inedges->GetEdgePtr();
00428 break;
00429 }
00430 }
00431
00432 if (theedge != NULL) return theedge;
00433 }
00434
00435 }
00436 return NULL;
00437 }
00438
00439
00440 legoProc *proc = (legoProc *) FindParentRegionType (RT_PROC, fromop);
00441 if (proc == NULL)
00442 {
00443 LegoNonFatal ("FindControlEdge", "Couldn;t find proc of op %d.",
00444 fromop->GetOpId());
00445 return NULL;
00446 }
00447
00448 for (theedge = proc->GetEdgeDictionary(); theedge != NULL;
00449 theedge = theedge->GetNextOpEdgePtr())
00450 {
00451 if (theedge->GetFromOpPtr() != fromop) continue;
00452 if (theedge->GetToOpPtr() != toop) continue;
00453 if (theedge->GetEdgeType() != ET_CNTL) continue;
00454
00455 return theedge;
00456 }
00457
00458
00459 return NULL;
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 static attrs *
00473 FindLcAttribute (char *lcname, void *object, int objtype)
00474 {
00475 attrList *atl;
00476 attrs *a;
00477
00478 if (object == NULL) return NULL;
00479
00480 if (objtype == 1)
00481 atl = ((legoRegion *) object)->GetRegionAttrListPtr();
00482 else if (objtype == 0)
00483 atl = ((legoOp *) object)->GetOpAttrListPtr();
00484 else
00485 atl = ((opEdges *) object)->GetEdgeAttrListPtr();
00486
00487 for ( ; atl != NULL; atl = atl->GetNextListPtr())
00488 if (atl->GetAttrType() == ATTR_LC) break;
00489 if (atl == NULL) return NULL;
00490
00491 for (a = atl->GetAttrPtr(); a != NULL; a = a->GetNextLcEntryPtr())
00492 if (strcmp (a->GetAttrString(), lcname) == 0) break;
00493
00494 return a;
00495 }
00496
00497 attrs *
00498 FindLcAttribute (char *lcname, legoRegion *region)
00499 {
00500 return FindLcAttribute (lcname, (void *) region, 1);
00501 }
00502
00503 attrs *
00504 FindLcAttribute (char *lcname, legoOp *op)
00505 {
00506 return FindLcAttribute (lcname, (void *) op, 0);
00507 }
00508
00509 attrs *
00510 FindLcAttribute (char *lcname, opEdges *edge)
00511 {
00512 return FindLcAttribute (lcname, (void *) edge, 2);
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 attrs *
00525 FindLiveAttribute (opEdges *edge)
00526 {
00527 attrList *atl;
00528
00529 for (atl = edge->GetEdgeAttrListPtr(); atl != NULL;
00530 atl = atl->GetNextListPtr())
00531 if (atl->GetAttrType() == ATTR_LIVE)
00532 return atl->GetAttrPtr();
00533
00534 return NULL;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 attrList *
00547 FindFreqAttribute (opEdges *edge)
00548 {
00549 attrList *atl;
00550
00551 if (edge == NULL) return NULL;
00552 for (atl = edge->GetEdgeAttrListPtr(); atl != NULL;
00553 atl = atl->GetNextListPtr())
00554 if (atl->GetAttrType() == ATTR_FREQ) return atl;
00555
00556 return NULL;
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 int
00570 FindEdgeFrequency (opEdges *edge)
00571 {
00572 attrList *atl;
00573
00574 if (edge == NULL) return -1;
00575
00576 atl = FindFreqAttribute (edge);
00577 if (atl == NULL) return -1;
00578
00579 return atl->GetAttrValPtr()->GetAttrValue();
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 double
00592 FindOpWeight (legoOp *op)
00593 {
00594 legoRegion *pregion;
00595 legoOp *blockop, *prevblockop;
00596 opList *opl;
00597 attrs *a;
00598
00599 if (op == NULL)
00600 {
00601 LegoNonFatal ("FindOpWeight", "Passed NULL op.");
00602 return -1.0;
00603 }
00604 pregion = (legoRegion *) op->GetParentBlockPtr();
00605
00606
00607 if (pregion->GetRegionType() == RT_BB)
00608 return pregion->GetWeight();
00609
00610 if (op->GetPrevLink() == NULL)
00611 return pregion->GetWeight();
00612
00613
00614
00615 if ((pregion->GetRegionType() == RT_HB) &&
00616 (FindLcAttribute( "use_orig_wt", pregion) != NULL )) {
00617
00618 a = FindLcAttribute( "orig_wt", op ) ;
00619 return (a->GetAttrOprdPtr()->GetLiteralDouble());
00620 }
00621
00622
00623
00624 prevblockop = op;
00625 blockop = op->GetPrevLink();
00626 while (blockop->GetOutListPtr() == NULL && blockop->GetPrevLink() != NULL)
00627 {
00628
00629
00630
00631 prevblockop = blockop;
00632 blockop = blockop->GetPrevLink();
00633 }
00634 dprintf ((OUTF, "Stopped walk at op %d, before op %d.\n",
00635 blockop->GetOpId(), prevblockop->GetOpId()));
00636
00637
00638
00639 if (blockop->GetOutListPtr() != NULL)
00640 {
00641 for (opl = blockop->GetOutListPtr(); opl != NULL;
00642 opl = opl->GetNextListPtr())
00643 if (opl->GetOpId() == prevblockop->GetOpId())
00644 {
00645 dprintf ((OUTF, "Found fall-through weight %lf.\n",
00646 opl->GetWeight()));
00647 return opl->GetWeight();
00648 }
00649 if (opl == NULL)
00650 LegoNonFatal ("FindOpWeight", "Can't find opList from op %d to "
00651 "op %d.", blockop->GetOpId(), prevblockop->GetOpId());
00652 }
00653 else
00654 {
00655 dprintf ((OUTF, "Hit top - using weight %lf.\n", pregion->GetWeight()));
00656 return pregion->GetWeight();
00657 }
00658 return -1.0;
00659 }
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 legoOprd *
00672 FindReturnMacro (legoOp *op)
00673 {
00674 attrs *retattr;
00675
00676 if (op->IsBRLOp() == false)
00677 {
00678 LegoNonFatal ("FindReturnMacro", "Op %d not a BRL.", op->GetOpId());
00679 return NULL;
00680 }
00681
00682 retattr = FindLcAttribute ("ret", op);
00683 if (retattr == NULL) return NULL;
00684
00685 return retattr->GetAttrOprdPtr();
00686 }
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 flags *
00700 FindFlag (int name, flags *flagiter)
00701 {
00702 flags *f = flagiter;
00703
00704 for ( ; f != NULL; f = f->GetNextFlagPtr())
00705 if (f->GetFlagName() == name) return f;
00706
00707 return NULL;
00708 }
00709
00710 flags *
00711 FindFlag (int name, legoOp *op)
00712 {
00713 return FindFlag (name, op->GetOpFlagPtr());
00714 }
00715
00716 flags *
00717 FindFlag (int name, legoRegion *region)
00718 {
00719 return FindFlag (name, region->GetFlagPtr());
00720 }
00721
00722 flags *
00723 FindFlag (flags *flagiter, int name)
00724 {
00725 LegoNonFatal ("FindFlag", "This is a deprecated version of this function.\n"
00726 "Swap the parameters in the call.");
00727
00728 return FindFlag (name, flagiter);
00729 }
00730
00731 flags *
00732 FindFlag (legoOp *op, int name)
00733 {
00734 LegoNonFatal ("FindFlag", "This is a deprecated version of this function.\n"
00735 "Swap the parameters in the call.");
00736
00737 return FindFlag (name, op);
00738 }
00739
00740 flags *
00741 FindFlag (legoRegion *region, int name)
00742 {
00743 LegoNonFatal ("FindFlag", "This is a deprecated version of this function.\n"
00744 "Swap the parameters in the call.");
00745
00746 return FindFlag (name, region);
00747 }
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 static inline int in_range (int x, int a, int b)
00764 {
00765 return (x >= a && x <= b);
00766 }
00767
00768 int IsIntegerOp (legoOp *op)
00769 {
00770 return op->IsIntegerOp();
00771 }
00772
00773 int IsFloatOp (legoOp *op)
00774 {
00775 return op->IsFloatOp();
00776 }
00777
00778 int IsCompareOp (legoOp *op)
00779 {
00780 return op->IsCompareOp();
00781 }
00782
00783 int IsBranchOp (legoOp *op)
00784 {
00785 return op->IsBranchOp();
00786 }
00787
00788 int IsBranchOpButNotBRL (legoOp *op)
00789 {
00790 return op->IsBranchOpButNotBRL();
00791 }
00792
00793 int IsLoadOp (legoOp *op)
00794 {
00795 return op->IsLDOp();
00796 }
00797
00798 int IsStoreOp (legoOp *op)
00799 {
00800 return op->IsSTOp();
00801 }
00802
00803 int IsMemoryOp (legoOp *op)
00804 {
00805 return (op->IsLDOp() || op->IsSTOp());
00806 }
00807
00808
00809
00810
00811
00812 legoOp * find_op(legoRegion * region, int opid)
00813 {
00814 int i;
00815 legoOp *op1 = NULL;
00816 switch(region->GetRegionType())
00817 {
00818 case RT_PROC:
00819 {
00820 for(i = 0; i < region->GetCount(); i++)
00821 {
00822 op1 = find_op((legoRegion *) region->GetItem(i), opid);
00823 if(op1 != NULL)
00824 break;
00825 }
00826 return op1;
00827 break;
00828 }
00829 case RT_TREE:
00830 {
00831 for(i = 0; i < region->GetCount(); i++)
00832 {
00833 op1 = find_op((legoRegion *) region->GetItem(i), opid);
00834 if(op1 != NULL)
00835 break;
00836 }
00837 return op1;
00838 break;
00839 }
00840 case RT_HB:
00841 case RT_SB:
00842 case RT_BB:
00843 {
00844 for(i = 0; i < region->GetCount(); i++)
00845 {
00846 legoOp * op_ptr = (legoOp *) region->GetItem(i);
00847 if(op_ptr->GetOpId() == opid)
00848 {
00849 op1 = op_ptr;
00850 break;
00851 }
00852 }
00853 return op1;
00854 break;
00855 }
00856
00857 }
00858 return op1;
00859 }
00860
00861 bool SameOpcode(legoOp *op1, legoOp *op2)
00862 {
00863 if(op1->GetOpcodePtr() == NULL || op2->GetOpcodePtr() == NULL)
00864 return (op1->GetOpcode() == op2->GetOpcode());
00865 else
00866 {
00867 legoOpcode *opc1, *opc2;
00868 opc1 = op1->GetOpcodePtr();
00869 opc2 = op2->GetOpcodePtr();
00870 if(opc1->GetOpcodeClass() == opc2->GetOpcodeClass() &&
00871 opc1->GetBaseOpcode() == opc2->GetBaseOpcode() )
00872 {
00873 switch (opc1->GetOpcodeClass())
00874 {
00875 case OC_INT:
00876 return (opc1->GetIaluQuals() == opc2->GetIaluQuals());
00877 break;
00878 case OC_PINT:
00879 return (opc1->GetIsimdQuals() == opc2->GetIsimdQuals());
00880 break;
00881 case OC_FP:
00882 return (opc1->GetFaluQuals() == opc2->GetFaluQuals());
00883 break;
00884 case OC_PFP:
00885 return (opc1->GetFsimdQuals() == opc2->GetFsimdQuals());
00886 break;
00887 case OC_CMP:
00888 return (opc1->GetIcmpQuals() == opc2->GetIcmpQuals());
00889 break;
00890 case OC_FCMP:
00891 return (opc1->GetFcmpQuals() == opc2->GetFcmpQuals());
00892 break;
00893 case OC_BR:
00894 return (opc1->GetBranchQuals() ==
00895 opc2->GetBranchQuals());
00896 break;
00897 case OC_LDST:
00898 return (opc1->GetImemQuals() == opc2->GetImemQuals());
00899 break;
00900 case OC_FPLDST:
00901 return (opc1->GetFmemQuals() == opc2->GetFmemQuals());
00902 break;
00903 case OC_MISC:
00904 return (opc1->GetMiscQuals() == opc2->GetMiscQuals());
00905 break;
00906 default:
00907 return true;
00908 break;
00909 }
00910 }
00911 else
00912 return false;
00913 }
00914 }
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963 bool legoAudit(legoModule * Module)
00964 {
00965 int i;
00966 if(Module->GetCount() == 0)
00967 {
00968 fprintf(stderr, "legoAudit: warning Empty lego module.\n");
00969 return true;
00970 }
00971 for(i = 0; i < Module->GetCount(); i++)
00972 {
00973 legoProc * proc = (legoProc *) Module->GetItem(i);
00974
00975
00976 assert(proc->GetEntryOpsPtr() != NULL);
00977 legoOp * entry_op = proc->GetEntryOpsPtr()->GetOpPtr();
00978 assert(entry_op->IsCMERGEOp() == true);
00979
00980 if(proc->GetExitOpsPtr() == NULL)
00981 {
00982 fprintf(stderr, "Warning: there seems to be no ret from the proc %s.\n",
00983 proc->GetProcName());
00984 }
00985
00986
00987 assert(proc->GetInEdgesPtr()->GetEdgePtr() == NULL);
00988 assert(proc->GetOutEdgesPtr()->GetEdgePtr() == NULL);
00989
00990 assert(proc->GetRegionType() == RT_PROC);
00991
00992 assert(proc->GetParentPtr() == Module);
00993
00994 assert(proc->GetParents() == NULL);
00995 assert(proc->GetChildren() == NULL);
00996
00997 assert(proc->GetListOpPtr() != NULL);
00998
00999 int j;
01000 for(j = 0; j < proc->GetCount(); j++)
01001 {
01002 legoRegion * region = (legoRegion *) proc->GetItem(j);
01003 if(region->GetRegionType() == RT_BB)
01004 {
01005
01006
01007
01008 legoOp * bb_entry_op = (legoOp *)
01009 region->GetEntryOpsPtr()->GetOpPtr();
01010 assert(bb_entry_op->IsCMERGEOp() == true);
01011
01012
01013
01014 assert(region->GetEntryOpsPtr()->GetNextListPtr() == NULL);
01015
01016 assert(region->GetExitOpsPtr()->GetNextListPtr() == NULL);
01017
01018
01019
01020
01021 edgeList * bb_in_edges, * bb_out_edges;
01022 bb_in_edges = region->GetInEdgesPtr();
01023 bb_out_edges = region->GetOutEdgesPtr();
01024 if(j != 0)
01025 {
01026 if(bb_in_edges == NULL)
01027 bb_in_edges = NULL;
01028 assert(bb_in_edges->GetEdgePtr() != NULL);
01029 }
01030 if(bb_in_edges != NULL && bb_in_edges->GetEdgePtr() != NULL)
01031 {
01032 opEdges * edgep;
01033 for(; bb_in_edges != NULL; bb_in_edges =
01034 bb_in_edges->GetNextListPtr())
01035 {
01036 edgep = bb_in_edges->GetEdgePtr();
01037 assert(edgep->GetFromOpId() ==
01038 edgep->GetFromOpPtr()->GetOpId());
01039 assert(edgep->GetToOpId() ==
01040 edgep->GetToOpPtr()->GetOpId());
01041 assert(edgep->GetToOpPtr() == bb_entry_op);
01042 int parent_chk = false;
01043 regionList *pars;
01044 legoRegion *par;
01045 for(pars = region->GetParents(); pars != NULL;
01046 pars = pars->GetNextListPtr())
01047 {
01048 par = pars->GetRegionPtr();
01049 if(edgep->GetFromOpPtr()->GetParentBlockPtr() == par)
01050 {
01051 parent_chk = true;
01052 break;
01053 }
01054 }
01055 assert(parent_chk == true);
01056 }
01057 }
01058 bool exitBB = false;
01059 opList * exit_opl = proc->GetExitOpsPtr();
01060 for(; exit_opl != NULL; exit_opl = exit_opl->GetNextListPtr())
01061 {
01062
01063 if((exit_opl->GetOpPtr() != 0) && (exit_opl->GetOpPtr()->GetParentBlockPtr() == region))
01064 {
01065 exitBB = true;
01066 break;
01067 }
01068
01069 }
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081 if(exitBB == false)
01082 {
01083 if(bb_out_edges != NULL)
01084 assert(bb_out_edges->GetEdgePtr() != NULL);
01085 }
01086 if(bb_out_edges != NULL && bb_out_edges->GetEdgePtr() != NULL)
01087 {
01088
01089 opEdges * edgep;
01090 for(; bb_out_edges != NULL; bb_out_edges =
01091 bb_out_edges->GetNextListPtr())
01092 {
01093 edgep = bb_out_edges->GetEdgePtr();
01094 assert(edgep->GetFromOpId() ==
01095 edgep->GetFromOpPtr()->GetOpId());
01096 assert(edgep->GetToOpId() ==
01097 edgep->GetToOpPtr()->GetOpId());
01098 assert(edgep->GetFromOpPtr() == region->GetExitOpsPtr()->GetOpPtr());
01099 int child_chk = false;
01100 legoRegion *chd;
01101 regionList * chdren;
01102 for(chdren = region->GetChildren(); chdren != NULL;
01103 chdren = chdren->GetNextListPtr())
01104 {
01105 chd = chdren->GetRegionPtr();
01106 if(edgep->GetToOpPtr()->GetParentBlockPtr() == chd)
01107 {
01108 child_chk = true;
01109 break;
01110 }
01111 }
01112 assert(child_chk == true);
01113 }
01114 }
01115
01116
01117
01118
01119 assert(region->GetParentPtr() != NULL);
01120
01121
01122 regionList * reg_l;
01123 for(reg_l = region->GetParents(); reg_l != NULL; reg_l =
01124 reg_l->GetNextListPtr())
01125 {
01126 legoRegion * reg1 = reg_l->GetRegionPtr();
01127 bool inedge_chk = false;
01128 edgeList * edge_l;
01129 for(edge_l = region->GetInEdgesPtr(); edge_l != NULL; edge_l =
01130 edge_l->GetNextListPtr())
01131 {
01132 if(edge_l->GetEdgePtr()->GetFromOpPtr()->GetParentBlockPtr() == reg1)
01133 {
01134 inedge_chk = true;
01135 break;
01136 }
01137 }
01138 assert(inedge_chk == true);
01139 }
01140 for(reg_l = region->GetChildren(); reg_l != NULL; reg_l =
01141 reg_l->GetNextListPtr())
01142 {
01143 legoRegion * reg1 = reg_l->GetRegionPtr();
01144 bool outedge_chk = false;
01145 edgeList * edge_l;
01146 for(edge_l = region->GetOutEdgesPtr(); edge_l != NULL; edge_l =
01147 edge_l->GetNextListPtr())
01148 {
01149 if(edge_l->GetEdgePtr()->GetToOpPtr()->GetParentBlockPtr() == reg1)
01150 {
01151 outedge_chk = true;
01152 break;
01153 }
01154 }
01155 assert(outedge_chk == true);
01156 }
01157
01158
01159
01160 assert(region->GetListOpPtr() == NULL);
01161
01162
01163 int k;
01164 for(legoOp * op = region->GetEntryOpsPtr()->GetOpPtr();
01165 op != NULL; op = op->GetNextLink())
01166
01167 {
01168
01169
01170
01171
01172 if(op != region->GetEntryOpsPtr()->GetOpPtr())
01173 assert(op->GetInListPtr() == NULL);
01174 if(op->GetNextLink() != NULL)
01175 {
01176 assert(op->GetOutListPtr() == NULL);
01177 assert(op->IsRETOp() == false && op->IsBRUOp() == false
01178 && op->IsBRCONDOp() == false &&
01179 op->IsDUMMYBROp() == false);
01180 }
01181
01182
01183
01184 if(op == region->GetEntryOpsPtr()->GetOpPtr())
01185 {
01186 assert(op->IsCMERGEOp() == true);
01187 int num_entry_edges = 0;
01188 int num_in_ops = 0;
01189 edgeList * in_edges;
01190 for(in_edges = ((legoRegion *) op->GetParentBlockPtr())->GetInEdgesPtr();
01191 in_edges != NULL; in_edges = in_edges->GetNextListPtr())
01192 {
01193 if(in_edges->GetEdgePtr() != NULL)
01194 num_entry_edges++;
01195 }
01196 opList * ops;
01197 for(ops = op->GetInListPtr(); ops != NULL; ops = ops->GetNextListPtr())
01198 {
01199 if(ops->GetOpPtr() != NULL)
01200 num_in_ops++;
01201 }
01202 assert(num_in_ops == num_entry_edges);
01203
01204 if(region->GetInEdgesPtr() == NULL || region->GetInEdgesPtr()->GetEdgePtr() == NULL)
01205 assert(op->GetInListPtr() == NULL || op->GetInListPtr()->GetOpPtr() == NULL);
01206 if(region->GetInEdgesPtr() != NULL && region->GetInEdgesPtr()->GetEdgePtr() != NULL)
01207 {
01208 assert(op->GetInListPtr()->GetOpPtr() != NULL);
01209 opEdges * edgep;
01210 edgeList *inedges;
01211 for(inedges = region->GetInEdgesPtr(); inedges != NULL; inedges =
01212 inedges->GetNextListPtr())
01213 {
01214 edgep = inedges->GetEdgePtr();
01215 legoOp * from_op = edgep->GetFromOpPtr();
01216 bool from_op_chk = false;
01217 for(opList * op_l = op->GetInListPtr(); op_l !=
01218 NULL; op_l = op_l->GetNextListPtr())
01219 {
01220 if(from_op == op_l->GetOpPtr())
01221 {
01222 from_op_chk = true;
01223 break;
01224 }
01225 if(from_op != op_l->GetOpPtr() &&
01226 from_op->GetOpId() == op_l->GetOpId())
01227 {
01228 from_op_chk = true;
01229 fprintf(stderr, "legoAudit Warning: Proc name: %s BB %d\n", proc->GetProcName(), region->GetRegionId());
01230 fprintf(stderr, " The ops in the parent BB of this BB may have been changed using \
01231 AddItem, AddMidOp, etc. (add/remove op) functions.\n");
01232 fprintf(stderr, " Try with write Module out and re-load it in. Then Audit it.\n");
01233 fprintf(stderr, " The reason is that those functions may change the op_ptr in one BB\
01234 while the related oplist keeps the op_ptr when it is constructed.\n");
01235 }
01236 }
01237 assert(from_op_chk == true);
01238 }
01239 }
01240 }
01241
01242
01243
01244
01245 if(op->GetNextLink() == NULL)
01246 {
01247 if(!op->IsBRLOp())
01248 assert(op->IsDUMMYBROp() || op->IsBRUOp() || op->IsBRCONDOp() ||
01249 op->IsRETOp() || op->IsBreakOp());
01250 if(op->IsRETOp())
01251 {
01252 int num_exit_edges = 0;
01253 int num_out_ops = 0;
01254 edgeList * out_edges;
01255 for(out_edges = ((legoRegion *) op->GetParentBlockPtr())->GetOutEdgesPtr();
01256 out_edges != NULL; out_edges = out_edges->GetNextListPtr())
01257 {
01258 if(out_edges->GetEdgePtr() != NULL)
01259 num_exit_edges++;
01260 }
01261 opList * ops;
01262 for(ops = op->GetOutListPtr(); ops != NULL; ops = ops->GetNextListPtr())
01263 {
01264 if(ops->GetOpPtr() != NULL)
01265 num_out_ops++;
01266 }
01267 assert(num_out_ops == num_exit_edges);
01268 if(op->GetPredOprdPtr() == NULL)
01269 assert(num_out_ops == 0);
01270 else if(op->GetPredOprdPtr()->GetOprdType() !=
01271 OT_REG)
01272 assert(num_out_ops == 0);
01273 }
01274 if(op->IsDUMMYBROp() || op->IsBRUOp())
01275 {
01276 int num_exit_edges = 0;
01277 int num_out_ops = 0;
01278 edgeList * out_edges;
01279
01280
01281 for(out_edges = ((legoRegion *) op->GetParentBlockPtr())->GetOutEdgesPtr();
01282 out_edges != NULL; out_edges = out_edges->GetNextListPtr())
01283 {
01284 if(out_edges->GetEdgePtr() != NULL)
01285 num_exit_edges++;
01286 }
01287 opList * ops;
01288 for(ops = op->GetOutListPtr(); ops != NULL; ops = ops->GetNextListPtr())
01289 {
01290 if(ops->GetOpPtr() != NULL)
01291 num_out_ops++;
01292 }
01293 assert(num_out_ops == num_exit_edges);
01294 attrList *atl;
01295 bool jump_table = false;
01296 for(atl = op->GetOpAttrListPtr(); atl != NULL; atl =
01297 atl->GetNextListPtr())
01298 {
01299 if(atl->GetAttrType() == ATTR_TBLNAME)
01300 jump_table = true;
01301 }
01302 assert(num_out_ops >= 1);
01303 if(num_out_ops > 1 && jump_table == false)
01304 {
01305 fprintf(stderr, "legoAudit WARNING: op %d in proc %s may have too many out ops (%d). \n",
01306 op->GetOpId(), proc->GetProcName(), num_out_ops);
01307 }
01308 }
01309 if(op->IsBRCONDOp())
01310 {
01311 int num_exit_edges = 0;
01312 int num_out_ops = 0;
01313 edgeList * out_edges;
01314 for(out_edges = ((legoRegion *) op->GetParentBlockPtr())->GetOutEdgesPtr();
01315 out_edges != NULL; out_edges = out_edges->GetNextListPtr())
01316 {
01317 if(out_edges->GetEdgePtr() != NULL)
01318 num_exit_edges++;
01319 }
01320 opList * ops;
01321 for(ops = op->GetOutListPtr(); ops != NULL; ops = ops->GetNextListPtr())
01322 {
01323 if(ops->GetOpPtr() != NULL)
01324 num_out_ops++;
01325 }
01326 assert(num_out_ops == num_exit_edges);
01327 assert(num_out_ops >= 2);
01328 if(num_out_ops > 2)
01329 {
01330 fprintf(stderr, "legoAudit warning: op %d in proc %s may have too many out ops (%d).\n",
01331 op->GetOpId(), proc->GetProcName(), num_out_ops);
01332 }
01333 }
01334 if(region->GetOutEdgesPtr() == NULL || region->GetOutEdgesPtr()->GetEdgePtr() == NULL)
01335 assert(op->GetOutListPtr() == NULL || op->GetOutListPtr()->GetOpPtr() == NULL);
01336 if(region->GetOutEdgesPtr() != NULL && region->GetOutEdgesPtr()->GetEdgePtr() != NULL)
01337 {
01338 assert(op->GetOutListPtr()->GetOpPtr() != NULL);
01339 opEdges * edgep;
01340 edgeList * outedges;
01341 for(outedges = region->GetOutEdgesPtr(); outedges != NULL; outedges =
01342 outedges->GetNextListPtr())
01343 {
01344 edgep = outedges->GetEdgePtr();
01345 legoOp * to_op = edgep->GetToOpPtr();
01346 bool to_op_chk = false;
01347 for(opList * op_l = op->GetOutListPtr(); op_l !=
01348 NULL; op_l = op_l->GetNextListPtr())
01349 {
01350 if(to_op == op_l->GetOpPtr())
01351 {
01352 to_op_chk = true;
01353 break;
01354 }
01355 if(to_op != op_l->GetOpPtr() &&
01356 to_op->GetOpId() == op_l->GetOpId())
01357 {
01358 to_op_chk = true;
01359 fprintf(stderr, "legoAudit Warning: Proc name: %s BB %d\n", proc->GetProcName(), region->GetRegionId());
01360 fprintf(stderr, " The ops in the child BB of this BB may have been changed using \
01361 AddItem, AddMidOp, etc. (add/remove op)functions.\n");
01362 fprintf(stderr, " Try with write Module out and re-load it in. Then Audit it.\n");
01363 fprintf(stderr, " The reason is that those functions may change the op_ptr in one BB\
01364 while the related oplist keeps the op_ptr when it is constructed.\n");
01365 }
01366
01367 }
01368 assert(to_op_chk == true);
01369 }
01370 }
01371 }
01372
01373
01374
01375 if(op != region->GetEntryOpsPtr()->GetOpPtr())
01376 {
01377 assert(op->GetPrevLink() != NULL);
01378 assert(FindControlEdge(op->GetPrevLink(), op) != NULL);
01379 }
01380 else
01381 {
01382 assert(op->GetPrevLink() == NULL);
01383
01384 }
01385 opList * opl1;
01386 bool proc_exit = false;
01387 for(opl1 = region->GetExitOpsPtr(); opl1 != NULL; opl1 =
01388 opl1->GetNextListPtr())
01389 {
01390 if(op == opl1->GetOpPtr())
01391 {
01392 proc_exit = true;
01393 break;
01394 }
01395 }
01396 if(proc_exit == false)
01397 {
01398 assert(op->GetNextLink() != NULL);
01399 assert(FindControlEdge(op, op->GetNextLink()) != NULL);
01400 }
01401 else
01402 {
01403 assert(op->GetNextLink() == NULL);
01404
01405
01406 }
01407
01408
01409
01410
01411
01412
01413 }
01414 }
01415 if(region->GetRegionType() == RT_TREE)
01416 {
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427 fprintf(stderr, "legoAudit: treegions have not been tested.\n");
01428
01429 }
01430 }
01431
01432
01433 opEdges * edge;
01434
01435 for(edge = proc->GetEdgeDictionary(); edge != NULL; edge =
01436 edge->GetNextOpEdgePtr())
01437 {
01438 int from_op_id = edge->GetFromOpId();
01439 int to_op_id = edge->GetToOpId();
01440 legoOp * from_op, *to_op;
01441 from_op = find_op(proc, from_op_id);
01442 assert(from_op != NULL);
01443
01444
01445
01446 to_op = find_op(proc, to_op_id);
01447 assert(to_op != NULL);
01448 if(((legoRegion *)from_op->GetParentBlockPtr())->GetRegionId() !=
01449 ((legoRegion *)to_op->GetParentBlockPtr())->GetRegionId() )
01450 {
01451
01452 assert(edge->GetEdgeAttrListPtr() != NULL);
01453
01454 edgeList * in_edges = ((legoRegion *)to_op->GetParentBlockPtr())->GetInEdgesPtr();
01455 bool ck_edges = false;
01456 for(; in_edges != NULL; in_edges = in_edges->GetNextListPtr())
01457 {
01458 if(edge == in_edges->GetEdgePtr())
01459 {
01460 ck_edges = true;
01461 break;
01462 }
01463 }
01464 if(ck_edges == false)
01465 {
01466 ck_edges = false;
01467 }
01468 assert(ck_edges == true);
01469 ck_edges = false;
01470 edgeList * out_edges = ((legoRegion *)from_op->GetParentBlockPtr())->GetOutEdgesPtr();
01471 for(; out_edges != NULL; out_edges = out_edges->GetNextListPtr())
01472 {
01473 if(edge == out_edges->GetEdgePtr())
01474 {
01475 ck_edges = true;
01476 break;
01477 }
01478 }
01479 assert(ck_edges == true);
01480 }
01481 }
01482
01483
01484 legoOp * allList;
01485 int op_count1 = 0;
01486 for(allList=proc->GetListOpPtr();allList!=NULL;allList = allList->GetListOpPtr())
01487 {
01488 op_count1++;
01489 }
01490 int op_count2 = 0;
01491 for(int rc = 0; rc < proc->GetCount(); rc++)
01492 {
01493 op_count2 += ((legoRegion *)proc->GetItem(rc))->GetCount();
01494 }
01495 assert(op_count1 == op_count2);
01496
01497 }
01498
01499
01500
01501
01502 return true;
01503 }
01504
01505 int FindFirstOutGoingReg(legoProc *Proc)
01506 {
01507 legoRegion *Region;
01508 legoOp *op;
01509 legoOprd *src;
01510
01511 int Reg = 31;
01512
01513 op = Proc->GetEntryOpsPtr()->GetOpPtr();
01514 op = op->GetNextLink();
01515
01516
01517
01518 for(; op != NULL; op = op->GetNextLink())
01519 {
01520 if(op->IsAllocOp())
01521 break;
01522 }
01523
01524 if(op == NULL || !op->IsAllocOp())
01525 {
01526 LegoNonFatal ("FindFirstOutGoingReg", "This Proc %s has no alloc instruction.\n",
01527 Proc->GetProcName());
01528 return (-1);
01529 }
01530
01531 src = op->GetSrcOprdPtr();
01532
01533
01534
01535 src = src->GetNextOprdPtr();
01536 Reg = Reg + src->GetLiteralLongLong();
01537
01538
01539 src = src->GetNextOprdPtr();
01540 Reg = Reg + src->GetLiteralLongLong();
01541
01542
01543
01544
01545 return (Reg + 1);
01546
01547 }
01548
01549 int FindLastOutGoingReg(legoProc *Proc)
01550 {
01551 legoRegion *Region;
01552 legoOp *op;
01553 legoOprd *src;
01554
01555 int Reg = 31;
01556
01557 op = Proc->GetEntryOpsPtr()->GetOpPtr();
01558 op = op->GetNextLink();
01559
01560
01561
01562
01563 for(; op != NULL; op = op->GetNextLink())
01564 {
01565 if(op->IsAllocOp())
01566 break;
01567 }
01568
01569 if(op == NULL || !op->IsAllocOp())
01570 {
01571 LegoNonFatal ("FindLastOutGoingReg", "This Proc %s has no alloc instruction.\n",
01572 Proc->GetProcName());
01573 return (-2);
01574 }
01575
01576 src = op->GetSrcOprdPtr();
01577
01578
01579
01580 src = src->GetNextOprdPtr();
01581 Reg = Reg + src->GetLiteralLongLong();
01582
01583
01584 src = src->GetNextOprdPtr();
01585 Reg = Reg + src->GetLiteralLongLong();
01586
01587
01588 src = src->GetNextOprdPtr();
01589 Reg = Reg + src->GetLiteralLongLong();
01590
01591
01592
01593
01594 return (Reg);
01595
01596 }