00001 #include "CompleteLiveness.H"
00002
00003
00004
00005 struct UseDefOprd {
00006 int OprdRegNum;
00007 int OprdFileType;
00008 struct UseDefOprd *next;
00009 };
00010
00011 legoHash <int, iavector *, legoHash_lt_int> *LiveNess;
00012
00013 static legoHash <int, struct UseDefOprd *, legoHash_lt_int> *Use;
00014 static legoHash <int, struct UseDefOprd *, legoHash_lt_int> *Def;
00015 static legoHash <int, struct UseDefOprd *, legoHash_lt_int> *L_Out;
00016
00017 static int MaxGregNum = 0;
00018 static int MaxFregNum = 0;
00019 static int MaxPregNum = 0;
00020 static int MaxBregNum = 0;
00021
00022 static void
00023 SetUsesAndDefs_Op(legoOp *op) {
00024 legoOprd *dest, *src;
00025 struct UseDefOprd *use, *def;
00026
00027
00028
00029
00030
00031
00032 if(op->GetPredOprdPtr() != NULL && op->GetPredOprdPtr()->GetOprdType() ==
00033 OT_REG && op->GetPredOprdPtr()->GetOprdFileType() == FT_PR &&
00034 op->GetPredOprdPtr()->GetOprdRegNum() != 0)
00035 {
00036 ;
00037 }
00038 else
00039 {
00040 for(dest = op->GetDestOprdPtr();
00041 dest != NULL; dest = dest->GetNextOprdPtr()) {
00042 if(dest->GetOprdType() != OT_REG)
00043 continue;
00044 def = Def->Lookup(op->GetOpId());
00045 if(Def->NotFound()) {
00046
00047
00048 def = new struct UseDefOprd;
00049 def->OprdRegNum = dest->GetOprdRegNum();
00050 def->OprdFileType = dest->GetOprdFileType();
00051 def->next = NULL;
00052
00053 Def->Set (op->GetOpId(), def);
00054 }
00055 else {
00056
00057
00058 while(def->next != NULL)
00059 def = def->next;
00060
00061
00062 def->next = new struct UseDefOprd;
00063 def->next->OprdRegNum = dest->GetOprdRegNum();
00064 def->next->OprdFileType = dest->GetOprdFileType();
00065 def->next->next = NULL;
00066 }
00067 }
00068 }
00069
00070
00071 for(src = op->GetSrcOprdPtr();
00072 src != NULL; src = src->GetNextOprdPtr()) {
00073 if(src->GetOprdType() != OT_REG)
00074 continue;
00075 use = Use->Lookup(op->GetOpId());
00076 if(Use->NotFound()) {
00077
00078
00079 use = new struct UseDefOprd;
00080 use->OprdRegNum = src->GetOprdRegNum();
00081 use->OprdFileType = src->GetOprdFileType();
00082 use->next = NULL;
00083
00084 Use->Set (op->GetOpId(), use);
00085 }
00086 else {
00087
00088
00089 while(use->next != NULL)
00090 use = use->next;
00091
00092
00093 use->next = new struct UseDefOprd;
00094 use->next->OprdRegNum = src->GetOprdRegNum();
00095 use->next->OprdFileType = src->GetOprdFileType();
00096 use->next->next = NULL;
00097 }
00098 }
00099
00100
00101
00102
00103
00104
00105 for(src = op->GetPredOprdPtr();
00106 src != NULL; src = src->GetNextOprdPtr()) {
00107 if(src->GetOprdType() != OT_REG)
00108 continue;
00109 use = Use->Lookup(op->GetOpId());
00110 if(Use->NotFound()) {
00111
00112
00113 use = new struct UseDefOprd;
00114 use->OprdRegNum = src->GetOprdRegNum();
00115 use->OprdFileType = src->GetOprdFileType();
00116 use->next = NULL;
00117
00118 Use->Set (op->GetOpId(), use);
00119 }
00120 else {
00121
00122
00123 while(use->next != NULL)
00124 use = use->next;
00125
00126
00127 use->next = new struct UseDefOprd;
00128 use->next->OprdRegNum = src->GetOprdRegNum();
00129 use->next->OprdFileType = src->GetOprdFileType();
00130 use->next->next = NULL;
00131 }
00132 }
00133
00134 }
00135
00136 static int
00137 Redefine(legoOprd *def, legoOp *UseOp)
00138 {
00139 int Redef;
00140 legoOp *op;
00141 legoOprd *dest;
00142
00143
00144
00145
00146 Redef = 0;
00147 for(op = UseOp; op != NULL;
00148 op = op->GetNextLink()) {
00149 for(dest = op->GetDestOprdPtr(); dest != NULL;
00150 dest = dest->GetNextOprdPtr()) {
00151 if(dest->GetOprdType() !=
00152 def->GetOprdType()) continue;
00153 if(dest->GetOprdFileType() !=
00154 def->GetOprdFileType()) continue;
00155 if(dest->GetOprdRegNum() !=
00156 def->GetOprdRegNum()) continue;
00157
00158
00159 Redef = 1;
00160 break;
00161 }
00162 if(Redef) break;
00163 }
00164
00165 return Redef;
00166 }
00167 static struct UseDefOprd *
00168 AttachOprdInfo(struct UseDefOprd *Live,
00169 legoOprd *oprd) {
00170 struct UseDefOprd *temp;
00171
00172 if(Live != NULL) {
00173 int confidence = 1;
00174 for(temp = Live; temp->next != NULL;
00175 temp = temp->next) {
00176 if(temp->OprdRegNum != oprd->GetOprdRegNum())
00177 continue;
00178 if(temp->OprdFileType != oprd->GetOprdFileType())
00179 continue;
00180
00181
00182 confidence = 0;
00183 }
00184
00185 if(temp->OprdRegNum == oprd->GetOprdRegNum() &&
00186 temp->OprdFileType == oprd->GetOprdFileType())
00187 confidence = 0;
00188 if(confidence) {
00189 temp->next = new struct UseDefOprd;
00190 temp = temp->next;
00191 temp->OprdRegNum = oprd->GetOprdRegNum();
00192 temp->OprdFileType = oprd->GetOprdFileType();
00193 temp->next = NULL;
00194 }
00195 }
00196 else {
00197 Live = new struct UseDefOprd;
00198 Live->OprdRegNum = oprd->GetOprdRegNum();
00199 Live->OprdFileType = oprd->GetOprdFileType();
00200 Live->next = NULL;
00201 }
00202 return Live;
00203 }
00204 static struct UseDefOprd *
00205 GetLiveOut(legoOp *LastOp,
00206 legoOp *StartOp, legoProc *Proc) {
00207 struct UseDefOprd *LiveOut = NULL, *LiveTemp = NULL;
00208 attrs *Attr;
00209 legoOprd *AttrOprd;
00210 opList *opl;
00211 legoOp *PredOp;
00212 opEdges *ControlEdge1;
00213
00214 if(LastOp->GetOutListPtr() != NULL) {
00215 for(opl = LastOp->GetOutListPtr(); opl != NULL;
00216 opl = opl->GetNextListPtr()) {
00217 PredOp = (legoOp *) opl->GetOpPtr();
00218
00219 ControlEdge1 = FindControlEdge (LastOp, PredOp);
00220 if(ControlEdge1 == NULL) {
00221 fprintf(stderr, "There is no Ctrl edge between op %d and op %d\n",
00222 LastOp->GetOpId(), PredOp->GetOpId());
00223 exit(-1);
00224 }
00225 Attr = FindLiveAttribute(ControlEdge1);
00226 for(AttrOprd = Attr->GetAttrOprdPtr(); AttrOprd != NULL;
00227 AttrOprd = AttrOprd->GetNextOprdPtr()) {
00228 LiveOut = AttachOprdInfo(LiveOut, AttrOprd);
00229 }
00230 }
00231 }
00232 else {
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 if(Proc->GetCount() < 2) {
00251
00252
00253
00254
00255 legoOprd *Oprd = new legoOprd;
00256 Oprd->SetOprdType(OT_REG);
00257 Oprd->SetOprdFileType(FT_GPR);
00258 int i;
00259 for(i = 8; i < 12; i++) {
00260 Oprd->SetOprdRegNum(i);
00261 if(1){
00262 LiveOut = AttachOprdInfo(LiveOut, Oprd);
00263 }
00264 }
00265 delete Oprd;
00266 }
00267 else {
00268
00269
00270
00271 for(opl = StartOp->GetInListPtr(); opl != NULL;
00272 opl = opl->GetNextListPtr()) {
00273 PredOp = (legoOp *) opl->GetOpPtr();
00274
00275 ControlEdge1 = FindControlEdge (PredOp, StartOp);
00276 if(ControlEdge1 == NULL) {
00277 fprintf(stderr, "There is no Ctrl edge between op %d and op %d\n",
00278 PredOp->GetOpId(), StartOp->GetOpId());
00279 exit(-1);
00280 }
00281 Attr = FindLiveAttribute(ControlEdge1);
00282 for(AttrOprd = Attr->GetAttrOprdPtr(); AttrOprd != NULL;
00283 AttrOprd = AttrOprd->GetNextOprdPtr()) {
00284 if(AttrOprd->GetOprdFileType() != FT_GPR)
00285 continue;
00286 if(AttrOprd->GetOprdRegNum() >= 8 &&
00287 AttrOprd->GetOprdRegNum() <= 11) {
00288 if(1) {
00289 LiveOut = AttachOprdInfo(LiveOut, AttrOprd);
00290 }
00291 }
00292 }
00293 }
00294 }
00295 }
00296 return LiveOut;
00297 }
00298 static struct UseDefOprd *
00299 AttachLiveOut(struct UseDefOprd *Live,
00300 struct UseDefOprd *oprd) {
00301 struct UseDefOprd *temp;
00302
00303 if(Live != NULL) {
00304 int confidence = 1;
00305 for(temp = Live; temp->next != NULL;
00306 temp = temp->next) {
00307 if(temp->OprdRegNum != oprd->OprdRegNum)
00308 continue;
00309 if(temp->OprdFileType != oprd->OprdFileType)
00310 continue;
00311
00312
00313 confidence = 0;
00314 }
00315
00316 if(temp->OprdRegNum == oprd->OprdRegNum &&
00317 temp->OprdFileType == oprd->OprdFileType)
00318 confidence = 0;
00319 if(confidence) {
00320 temp->next = new struct UseDefOprd;
00321 temp = temp->next;
00322 temp->OprdRegNum = oprd->OprdRegNum;
00323 temp->OprdFileType = oprd->OprdFileType;
00324 temp->next = NULL;
00325 }
00326 }
00327 else {
00328 Live = new struct UseDefOprd;
00329 Live->OprdRegNum = oprd->OprdRegNum;
00330 Live->OprdFileType = oprd->OprdFileType;
00331 Live->next = NULL;
00332 }
00333 return Live;
00334 }
00335 static void
00336 SetLiveOut_AllOps(struct UseDefOprd *LiveOut,
00337 legoOp *LastOp) {
00338 legoOp *op;
00339 struct UseDefOprd *Out, *use, *def, *def1, *In = NULL;
00340
00341
00342
00343
00344
00345 L_Out->Set (LastOp->GetOpId(), LiveOut);
00346
00347 for(op = LastOp; op != NULL;
00348 op = op->GetPrevLink()) {
00349 Out = L_Out->Lookup(op->GetOpId());
00350 if(L_Out->NotFound()) {
00351 fprintf(stderr, "There is something wrong with Live\n");
00352 exit(-1);
00353 }
00354
00355
00356
00357 if(op->GetPrevLink() != NULL) {
00358 for(;Out != NULL; Out = Out->next) {
00359 def1 = Def->Lookup(op->GetOpId());
00360 int confidence = 1;
00361 if(!Def->NotFound()) {
00362 for(def = def1; def != NULL; def = def->next) {
00363 if(def->OprdRegNum != Out->OprdRegNum)
00364 continue;
00365 if(def->OprdFileType != Out->OprdFileType)
00366 continue;
00367
00368 confidence = 0;
00369 break;
00370 }
00371 }
00372 if(!confidence)
00373 continue;
00374 In = AttachLiveOut(In, Out);
00375 }
00376
00377 use = Use->Lookup(op->GetOpId());
00378 if(!Use->NotFound()) {
00379 for(; use != NULL; use = use->next) {
00380 In = AttachLiveOut(In, use);
00381 }
00382 }
00383 L_Out->Set (((legoOp *) op->GetPrevLink())->GetOpId(),
00384 In);
00385 In = NULL;
00386 }
00387 }
00388 }
00389
00390 static void
00391 SetLiveInformation() {
00392 iavector *s;
00393 struct UseDefOprd *liveOprd;
00394 int opid;
00395 for(L_Out->Start(); !(L_Out->AtEnd()); L_Out->Next()){
00396 liveOprd = L_Out->LookupCurrent();
00397 opid = L_Out->GetCurrentKey();
00398 while(liveOprd != NULL) {
00399 switch(liveOprd->OprdFileType)
00400 {
00401 case FT_GPR: s = LiveNess->Lookup(opid);
00402 if(LiveNess->NotFound()) {
00403 s = new iavector(MaxGregNum,
00404 MaxFregNum, MaxPregNum, MaxBregNum);
00405
00406
00407 s->SetGreg(liveOprd->OprdRegNum);
00408
00409 LiveNess->Set(opid, s);
00410 }
00411 else
00412 s->SetGreg(liveOprd->OprdRegNum);
00413 break;
00414 case FT_FPR: s = LiveNess->Lookup(opid);
00415 if(LiveNess->NotFound()) {
00416 s = new iavector(MaxGregNum,
00417 MaxFregNum, MaxPregNum, MaxBregNum);
00418
00419
00420 s->SetFreg(liveOprd->OprdRegNum);
00421
00422 LiveNess->Set(opid, s);
00423 }
00424 else
00425 s->SetFreg(liveOprd->OprdRegNum);
00426 break;
00427 case FT_PR: s = LiveNess->Lookup(opid);
00428 if(LiveNess->NotFound()) {
00429 s = new iavector(MaxGregNum,
00430 MaxFregNum, MaxPregNum, MaxBregNum);
00431
00432
00433 s->SetPreg(liveOprd->OprdRegNum);
00434
00435 LiveNess->Set(opid, s);
00436 }
00437 else
00438 s->SetPreg(liveOprd->OprdRegNum);
00439 break;
00440 case FT_BTR: s = LiveNess->Lookup(opid);
00441 if(LiveNess->NotFound()) {
00442 s = new iavector(MaxGregNum,
00443 MaxFregNum, MaxPregNum, MaxBregNum);
00444
00445
00446 s->SetBreg(liveOprd->OprdRegNum);
00447
00448 LiveNess->Set(opid, s);
00449 }
00450 else
00451 s->SetBreg(liveOprd->OprdRegNum);
00452 break;
00453 }
00454 liveOprd = liveOprd->next;
00455 }
00456 }
00457 }
00458
00459 static void
00460 PrintLiveNess() {
00461 iavector *s;
00462 for(LiveNess->Start(); !(LiveNess->AtEnd());
00463 LiveNess->Next()) {
00464 printf("\nGetting the liveness information for op %d\n",
00465 LiveNess->GetCurrentKey());
00466 s = LiveNess->LookupCurrent();
00467 printf("\nGetting the Live Gregs\n");
00468 int i;
00469 for(i = 0; i < s->GetGregSize(); i++) {
00470 if(s->ReadGreg(i))
00471 printf("reg %d\t", i);
00472 }
00473 printf("\nGetting the Live Gregs\n");
00474 for(i = 0; i < s->GetFregSize(); i++) {
00475 if(s->ReadFreg(i))
00476 printf("freg %d\t", i);
00477 }
00478 printf("\nGetting the Live Pregs\n");
00479 for(i = 0; i < s->GetPregSize(); i++) {
00480 if(s->ReadPreg(i))
00481 printf("preg %d\t", i);
00482 }
00483 printf("\nGetting the Live Bregs\n");
00484 for(i = 0; i < s->GetBregSize(); i++) {
00485 if(s->ReadBreg(i))
00486 printf("breg %d\t", i);
00487 }
00488 }
00489 }
00490
00491 legoHash <int, iavector *, legoHash_lt_int> *
00492 CompleteLiveNess(legoProc *Proc) {
00493 legoRegion *Region;
00494 legoOp *op, *StartOp, *LastOp;
00495 legoOprd *src, *preg;
00496 struct UseDefOprd *LiveOut;
00497 LiveVariables(Proc);
00498
00499 LiveNess = new legoHash <int, iavector *, legoHash_lt_int>;
00500
00501
00502 MaxGregNum = FindMaxRegNum (Proc,FT_GPR) + 1;
00503
00504
00505 if(MaxGregNum < 32) MaxGregNum = 32;
00506
00507 MaxFregNum = FindMaxRegNum (Proc,FT_FPR) + 1;
00508 MaxPregNum = FindMaxRegNum (Proc,FT_PR) + 1;
00509 MaxBregNum = FindMaxRegNum (Proc,FT_BTR) + 1;
00510 L_Out = new legoHash <int, struct UseDefOprd *, legoHash_lt_int>;
00511 int j;
00512 for(j = 0; j < Proc->GetCount(); j++) {
00513 Region = (legoRegion *) Proc->GetItem(j);
00514 StartOp = (legoOp *) (Region->GetEntryOpsPtr())->GetOpPtr();
00515 LastOp = (legoOp *) (Region->GetExitOpsPtr())->GetOpPtr();
00516
00517
00518 LiveOut = GetLiveOut(LastOp, StartOp, Proc);
00519
00520 Use = new legoHash <int, struct UseDefOprd *, legoHash_lt_int>;
00521 Def = new legoHash <int, struct UseDefOprd *, legoHash_lt_int>;
00522 int k;
00523 for(k = 0; k < Region->GetCount(); k++) {
00524 op = (legoOp *) Region->GetItem(k);
00525
00526
00527
00528
00529
00530
00531 SetUsesAndDefs_Op(op);
00532 }
00533 SetLiveOut_AllOps(LiveOut, LastOp);
00534
00535 for(Use->Start(); !(Use->AtEnd()); Use->Next()) {
00536 delete Use->LookupCurrent();
00537 }
00538 delete Use;
00539 Use = NULL;
00540 for(Def->Start(); !(Def->AtEnd()); Def->Next()) {
00541 delete Def->LookupCurrent();
00542 }
00543 delete Def;
00544 Def = NULL;
00545 }
00546 SetLiveInformation();
00547 #ifdef _LIVE_VAR_DEBUG_
00548
00549 printf("Getting Live out information for the Proc %s\n",
00550 Proc->GetProcName());
00551 for(L_Out->Start(); !(L_Out->AtEnd()); L_Out->Next()) {
00552 struct UseDefOprd *sau = L_Out->LookupCurrent();
00553 printf("LiveOut for op %d\n",
00554 L_Out->GetCurrentKey());
00555 while(sau != NULL) {
00556 switch(sau->OprdFileType) {
00557 case FT_GPR: printf("r%d\t",
00558 sau->OprdRegNum);
00559 break;
00560 case FT_FPR: printf("f%d\t",
00561 sau->OprdRegNum);
00562 break;
00563 case FT_PR: printf("p%d\t",
00564 sau->OprdRegNum);
00565 break;
00566 case FT_BTR: printf("b%d\t",
00567 sau->OprdRegNum);
00568 break;
00569 }
00570 sau = sau->next;
00571 }
00572 printf("\n");
00573 }
00574 #endif
00575 for(L_Out->Start(); !(L_Out->AtEnd()); L_Out->Next()) {
00576 delete L_Out->LookupCurrent();
00577 }
00578 delete L_Out;
00579 L_Out = NULL;
00580
00581 return LiveNess;
00582 }