00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include "incls/_precompiled.incl"
00025
00026 # ifdef DELTA_COMPILER
00027 # include "incls/_preg.cpp.incl"
00028
00029 int PReg::currentNo = 0;
00030 int BlockPReg::_numBlocks = 0;
00031 static GrowableArray<ConstPReg*>* constants = 0;
00032 static PReg* dummyPR;
00033 const int PReg::AvgBBIndexLen = 10;
00034 const int PReg::VeryNegative = -9999;
00035
00036 #define BAD_SCOPE ((InlinedScope*)1)
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 LogicalAddress* PReg::createLogicalAddress() {
00050 PReg* r = cpReg();
00051 if (r->_logicalAddress == NULL) {
00052 r->_logicalAddress = theCompiler->scopeDescRecorder()->createLogicalAddress(nameNode());
00053 };
00054 return r->_logicalAddress;
00055 }
00056
00057
00058
00059 static int udWeight[] = { 1, 8, 8*8, 8*8*8, 8*8*8*8 };
00060 const int udWeightLen = sizeof(udWeight) / sizeof(int) - 1;
00061
00062
00063 void PReg::initPRegs() {
00064 PReg::currentNo = 0; BlockPReg::_numBlocks = 0;
00065 constants = new GrowableArray<ConstPReg*>(50);
00066 dummyPR = new PReg(BAD_SCOPE);
00067 }
00068
00069
00070 SAPReg::SAPReg(InlinedScope* s, int st, int en, bool inContext) : PReg(s), _isInContext(inContext) {
00071 creationStartBCI = _begBCI = st == IllegalBCI ? s->bci() : st;
00072 _endBCI = en == IllegalBCI ? s->bci() : en;
00073 _creationScope = s;
00074 }
00075
00076
00077 BlockPReg::BlockPReg(InlinedScope* scope, CompileTimeClosure* closure, int beg, int end) : SAPReg(scope, beg, end) {
00078 _closure = closure; assert(closure, "need a closure");
00079 _memoized = _escapes = false;
00080 _escapeNodes = NULL; _uplevelRead = _uplevelWritten = NULL; _contextCopies = NULL;
00081 _numBlocks++;
00082 theCompiler->blockClosures->append(this);
00083 if (MemoizeBlocks) memoize();
00084 }
00085
00086 void BlockPReg::addContextCopy(Location* l) {
00087 if (!_contextCopies) _contextCopies = new GrowableArray<Location*>(3);
00088 _contextCopies->append(l);
00089 }
00090
00091 void PReg::makeIncorrectDU(bool incU, bool incD) {
00092 if (incU) _nuses = VeryNegative;
00093 if (incD) _ndefs = VeryNegative;
00094 }
00095
00096
00097 bool PReg::isLocalTo(BB* bb) const {
00098
00099
00100
00101 return
00102 loc.equals(unAllocated) && !uplevelR() && !debug && !incorrectDU() &&
00103 !isConstPReg() && dus.length() == 1 && dus.first()->bb == bb;
00104 }
00105
00106
00107
00108 bool PReg::canCopyPropagate() const {
00109 if (nuses() == 0 || ndefs() != 1) return false;
00110
00111
00112 if (incorrectD() || loc.isTrashedRegister()) return false;
00113 return true;
00114 }
00115
00116
00117 void PReg::addUplevelAccessor(BlockPReg* blk, bool read, bool write) {
00118 if (read) {
00119 if (!_uplevelR) _uplevelR = new GrowableArray<BlockPReg*>(5);
00120 if (!_uplevelR->contains(blk)) _uplevelR->append(blk);
00121 }
00122 if (write) {
00123 if (!_uplevelW) _uplevelW = new GrowableArray<BlockPReg*>(5);
00124 if (!_uplevelW->contains(blk)) _uplevelW->append(blk);
00125 }
00126 }
00127
00128 void PReg::removeUplevelAccessor(BlockPReg* blk) {
00129 if (_uplevelR) {
00130 if (_uplevelR->contains(blk)) _uplevelR->remove(blk);
00131 if (_uplevelR->isEmpty()) _uplevelR = NULL;
00132 }
00133 if (_uplevelW) {
00134 if (_uplevelW->contains(blk)) _uplevelW->remove(blk);
00135 if (_uplevelW->isEmpty()) _uplevelW = NULL;
00136 }
00137 }
00138
00139 void PReg::removeAllUplevelAccessors() {
00140 _uplevelR = _uplevelW = NULL;
00141 }
00142
00143 ConstPReg* new_ConstPReg(InlinedScope* s, oop c) {
00144 for (int i = 0; i < constants->length(); i++) {
00145 ConstPReg* r = constants->at(i);
00146 if (r->constant == c) {
00147
00148
00149 r->extendLiveRange(s);
00150 return r;
00151 }
00152 }
00153
00154 ConstPReg* r = new ConstPReg(s, c);
00155 constants->append(r);
00156 r->_ndefs = 1;
00157 return r;
00158 }
00159
00160
00161 ConstPReg* findConstPReg(Node* n, oop c) {
00162
00163 for (int i = 0; i < constants->length(); i++) {
00164 ConstPReg* r = constants->at(i);
00165 if (r->constant == c) {
00166 return r->covers(n) ? r : NULL;
00167 }
00168 }
00169 return NULL;
00170 }
00171
00172
00173 bool ConstPReg::needsRegister() const {
00174
00175
00176
00177
00178 return false;
00179 }
00180
00181
00182 void ConstPReg::allocateTo(Location reg) {
00183 assert(reg.isRegisterLocation(), "should be a register");
00184 loc = reg;
00185 assert(_scope->isInlinedScope(), "expected non-access scope");
00186
00187 Unimplemented();
00188 }
00189
00190
00191 inline int computeWeight(InlinedScope* s) {
00192 const int scale = 16;
00193 if (s && s->isInlinedScope() && ((InlinedScope*)s)->primFailure()) {
00194 return 1 * udWeight[min(udWeightLen, s->loopDepth)];
00195 } else {
00196 return scale * udWeight[min(udWeightLen, s ? s->loopDepth : 0)];
00197 }
00198 }
00199
00200
00201 void PReg::incUses(Use* use) {
00202 _nuses++;
00203 if (use->isSoft()) _nsoftUses++;
00204 InlinedScope* s = use->node->scope();
00205 weight += computeWeight(s);
00206 assert(weight >= _nuses + _ndefs || isConstPReg(), "weight too small");
00207 }
00208
00209
00210 void PReg::decUses(Use* use) {
00211 _nuses--;
00212 if (use->isSoft()) _nsoftUses--;
00213 InlinedScope* s = use->node->scope();
00214 weight -= computeWeight(s);
00215 assert(weight >= _nuses + _ndefs || isConstPReg(), "weight too small");
00216 }
00217
00218
00219 void PReg::incDefs(Def* def) {
00220 _ndefs++;
00221 InlinedScope* s = def->node->scope();
00222 weight += computeWeight(s);
00223 assert(weight >= _nuses + _ndefs || isConstPReg(), "weight too small");
00224 }
00225
00226
00227 void PReg::decDefs(Def* def) {
00228 _ndefs--;
00229 InlinedScope* s = def->node->scope();
00230 weight -= computeWeight(s);
00231 assert(weight >= _nuses + _ndefs || isConstPReg(), "weight too small");
00232 }
00233
00234
00235 void PReg::removeUse(DUInfo* info, Use* use) {
00236 assert(info->reg == this, "wrong reg");
00237 info->uses.remove(use);
00238 decUses(use);
00239 }
00240
00241
00242 void PReg::removeUse(BB* bb, Use* use) {
00243 if (use == NULL) return;
00244 for (int i = 0; i < dus.length(); i++) {
00245 PRegBBIndex* index = dus.at(i);
00246 if (index->bb == bb) {
00247 DUInfo* info = bb->duInfo.info->at(index->index);
00248 removeUse(info, use);
00249 return;
00250 }
00251 }
00252 ShouldNotReachHere();
00253 }
00254
00255
00256 void PReg::removeDef(DUInfo* info, Def* def) {
00257 assert(info->reg == this, "wrong reg");
00258 info->defs.remove(def);
00259 _ndefs--;
00260 InlinedScope* s = def->node->scope();
00261 weight -= computeWeight(s);
00262 assert(weight >= _nuses + _ndefs, "weight too small");
00263 }
00264
00265
00266 void PReg::removeDef(BB* bb, Def* def) {
00267 if (def == NULL) return;
00268 for (int i = 0; i < dus.length(); i++) {
00269 PRegBBIndex* index = dus.at(i);
00270 if (index->bb == bb) {
00271 DUInfo* info = bb->duInfo.info->at(index->index);
00272 removeDef(info, def);
00273 return;
00274 }
00275 }
00276 ShouldNotReachHere();
00277 }
00278
00279
00280 void PReg::addDUHelper(Node* n, SList<DefUse*>* l, DefUse* el) {
00281 int myNum = n->num();
00282 SListElem<DefUse*>* prev = NULL;
00283 for (SListElem<DefUse*>* e = l->head();
00284 e && e->data()->node->num() < myNum;
00285 prev = e, e = e->next()) ;
00286 l->insertAfter(prev, el);
00287 }
00288
00289
00290 Use* PReg::addUse(DUInfo* info, NonTrivialNode* n) {
00291 assert(info->reg == this, "wrong reg");
00292 Use* u = new Use(n);
00293 addDUHelper(n, (SList<DefUse*>*)&info->uses, u);
00294 incUses(u);
00295 return u;
00296 }
00297
00298
00299 Use* PReg::addUse(BB* bb, NonTrivialNode* n) {
00300 for (int i = 0; i < dus.length(); i++) {
00301 PRegBBIndex* index = dus.at(i);
00302 if (index->bb == bb) {
00303 DUInfo* info = bb->duInfo.info->at(index->index);
00304 return addUse(info, n);
00305 }
00306 }
00307 return bb->addUse(n, this);
00308 }
00309
00310
00311 Def* PReg::addDef(DUInfo* info, NonTrivialNode* n) {
00312 assert(info->reg == this, "wrong reg");
00313 Def* d = new Def(n);
00314 addDUHelper(n, (SList<DefUse*>*)&info->defs, d);
00315 incDefs(d);
00316 return d;
00317 }
00318
00319
00320 Def* PReg::addDef(BB* bb, NonTrivialNode* n) {
00321 for (int i = 0; i < dus.length(); i++) {
00322 PRegBBIndex* index = dus.at(i);
00323 if (index->bb == bb) {
00324 DUInfo* info = bb->duInfo.info->at(index->index);
00325 return addDef(info, n);
00326 }
00327 }
00328 return bb->addDef(n, this);
00329 }
00330
00331 void PReg::forAllDefsDo(Closure<Def*>* c) {
00332 ::forAllDefsDo(&dus, c);
00333 }
00334
00335 void PReg::forAllUsesDo(Closure<Use*>* c) {
00336 ::forAllUsesDo(&dus, c);
00337 }
00338
00339 void PReg::allocateTo(Location r) {
00340 if (CompilerDebug) cout(PrintRegAlloc)->print("*allocating %s to %s\n", name(), r.name());
00341 assert(loc.equals(unAllocated), "already allocated");
00342 loc = r;
00343 }
00344
00345
00346 bool PReg::extendLiveRange(Node* n) {
00347
00348
00349
00350 return extendLiveRange(n->scope(), n->bci());
00351 }
00352
00353 bool PReg::extendLiveRange(InlinedScope* s, int bci) {
00354
00355
00356
00357 if (s == _scope) {
00358 return true;
00359 } else if (_scope->isSenderOf(s)) {
00360 return true;
00361 } else {
00362 return false;
00363 }
00364 }
00365
00366
00367 bool SAPReg::extendLiveRange(Node* n) {
00368
00369 return extendLiveRange(n->scope(), n->bci());
00370 }
00371
00372 bool SAPReg::extendLiveRange(InlinedScope* s, int bci) {
00373
00374 assert(_begBCI != IllegalBCI && creationStartBCI != IllegalBCI &&
00375 _endBCI != IllegalBCI, "live range not set");
00376 if (isInContext()) {
00377
00378
00379
00380 return PReg::extendLiveRange(s, bci);
00381 }
00382 bool ok = true;
00383 if (s == _scope) {
00384 if (bciLT(bci, _begBCI)) {
00385
00386
00387
00388
00389
00390 return false;
00391 }
00392 if (bciGT(bci, _endBCI)) _endBCI = bci;
00393 } else if (s->isSenderOf(_scope)) {
00394
00395 for (InlinedScope* ss = _scope; ss->sender() != s; ss = ss->sender());
00396 _scope = s;
00397 _begBCI = ss->senderBCI();
00398 _endBCI = bci;
00399 } else if (_scope->isSenderOf(s)) {
00400
00401 for (InlinedScope* ss = s; ss->sender() != _scope; ss = ss->sender()) ;
00402 int bci = ss->senderBCI();
00403 if (bciLT(bci, _begBCI)) {
00404
00405
00406
00407
00408
00409 return false;
00410 }
00411 if (bciGT(bci, _endBCI)) _endBCI = bci;
00412 } else {
00413
00414 ok = false;
00415 }
00416 assert(bciLE(_begBCI, _endBCI) && _begBCI != IllegalBCI &&
00417 (bciLE(_endBCI, scope()->nofBytes()) || _endBCI == EpilogueBCI), "invalid start/endBCI");
00418 return ok;
00419 }
00420
00421
00422 void ConstPReg::extendLiveRange(InlinedScope* s) {
00423
00424 if (_scope->isSenderOrSame(s)) {
00425
00426 } else if (s->isSenderOf(_scope)) {
00427
00428 _scope = s;
00429 } else {
00430
00431 do { s = s->sender(); } while (!s->isSenderOf(_scope));
00432 _scope = s;
00433 }
00434 }
00435
00436
00437 bool ConstPReg::covers(Node* n) const {
00438
00439 InlinedScope* s = n->scope();
00440 if (_scope->isSenderOrSame(s)) {
00441
00442 return true;
00443 }
00444 return false;
00445 }
00446
00447
00448 bool ConstPReg::extendLiveRange(Node* n) {
00449 extendLiveRange(n->scope());
00450 return true;
00451 }
00452
00453
00454 bool PReg::checkEquivalentDefs() const {
00455
00456 if (ndefs() == 1) return true;
00457 PReg* rhs = NULL;
00458 for (int i = 0; i < dus.length(); i++) {
00459 PRegBBIndex* index = dus.at(i);
00460 BB* bb = index->bb;
00461 DUInfo* info = bb->duInfo.info->at(index->index);
00462 for (SListElem<Def*>* e = info->defs.head(); e; e = e->next()) {
00463 NonTrivialNode* n = e->data()->node;
00464 if (!n->isAssignmentLike()) return false;
00465 if (rhs) {
00466 if (rhs != n->src()) return false;
00467 } else {
00468 rhs = n->src();
00469 }
00470 }
00471 }
00472
00473 return true;
00474 }
00475
00476
00477 bool PReg::canBeEliminated(bool withUses) const {
00478
00479 assert(_nuses == 0 || withUses, "still has uses");
00480 if (_ndefs + _nuses == 0) return false;
00481
00482
00483 if (incorrectDU()) {
00484 return false;
00485 }
00486
00487 assert(!_nsoftUses || debug, "nsoftUses should imply debug");
00488
00489 if (isBlockPReg() && !withUses && !uplevelR()) {
00490
00491 return true;
00492 }
00493
00494 if (debug) {
00495
00496
00497 if (cpInfo) {
00498
00499 assert(!cpReg()->loc.isLocalRegister(), "shouldn't be eliminated");
00500
00501 return true;
00502 }
00503 if (_ndefs > 1) {
00504 if (isBlockPReg()) {
00505
00506 } else if (isSAPReg() && checkEquivalentDefs()) {
00507
00508 } else {
00509 if (!checkEquivalentDefs()) {
00510 if (CompilerDebug) cout(PrintEliminateUnnededNodes)->print("*not eliminating %s: >1 def && debug-visible\n", name());
00511 return false;
00512 }
00513 }
00514 }
00515 PRegBBIndex* index = dus.first();
00516 DUInfo* info = index->bb->duInfo.info->at(index->index);
00517 SListElem<Def*>* e = info->defs.head();
00518 if (!e) {
00519
00520 if (CompilerDebug) cout(PrintEliminateUnnededNodes)->print("*not eliminating %s: def not in first info\n", name());
00521 return false;
00522 }
00523 NonTrivialNode* defNode = e->data()->node;
00524 PReg* defSrc;
00525 bool ok;
00526 if (defNode->hasConstantSrc()) {
00527
00528 ok = true;
00529 } else if (defNode->hasSrc() && (defSrc = defNode->src())->isSAPReg() &&
00530 !defSrc->loc.isRegisterLocation()) {
00531
00532
00533
00534
00535
00536 ok = defSrc->scope()->isSenderOf(_scope);
00537 if (!ok && defSrc->scope() == _scope && isSAPReg()) {
00538
00539 ok = bciGE(((SAPReg*)defSrc)->endBCI(), endBCI());
00540 }
00541 if (!ok) {
00542
00543 ok = defSrc->extendLiveRange(_scope, endBCI());
00544 }
00545 } else {
00546 ok = false;
00547 }
00548 if (!ok) {
00549 if (CompilerDebug) cout(PrintEliminateUnnededNodes)->print("*not eliminating %s: can't recover debug info\n", name());
00550 return false;
00551 }
00552 }
00553 return true;
00554 }
00555
00556
00557 bool BlockPReg::canBeEliminated(bool withUses) const {
00558 if (!PReg::canBeEliminated(withUses)) return false;
00559 if (!_escapes) return true;
00560 if (uplevelR()) return false;
00561
00562
00563
00564
00565 assert(nuses() == 0, "still has uses");
00566 return true;
00567 }
00568
00569
00570
00571 void PReg::eliminate(bool withUses) {
00572 if (!canBeEliminated(withUses)) return;
00573 for (int i = 0; i < dus.length(); i++) {
00574 PRegBBIndex* index = dus.at(i);
00575 BB* bb = index->bb;
00576 DUInfo* info = bb->duInfo.info->at(index->index);
00577 eliminateDefs(info, bb, withUses);
00578 if (withUses) eliminateUses(info, bb);
00579 }
00580 }
00581
00582 void PReg::eliminateUses(DUInfo* info, BB* bb) {
00583
00584 SListElem<Use*>* ue = info->uses.head();
00585 while (ue) {
00586 #ifdef ASSERT
00587 int oldlen = info->uses.length();
00588 #endif
00589 Node* n = ue->data()->node;
00590 if (CompilerDebug) {
00591 char buf[1024];
00592 cout(PrintEliminateUnnededNodes)->print("*%seliminating node N%ld: %s\n",
00593 n->canBeEliminated() ? "" : "not ", n->id(), n->print_string(buf));
00594 }
00595 assert(n->canBeEliminated(), "must be able to eliminate this");
00596 n->eliminate(bb, this);
00597 assert(info->uses.length() < oldlen, "didn't remove use");
00598 ue = info->uses.head();
00599 }
00600 }
00601
00602 void PReg::eliminateDefs(DUInfo* info, BB* bb, bool removing) {
00603
00604 SListElem<Def*>* e = info->defs.head();
00605 while (e) {
00606 #ifdef ASSERT
00607 int oldlen = info->defs.length();
00608 #endif
00609 NonTrivialNode* n = e->data()->node;
00610 if (n->canBeEliminated()) {
00611 updateCPInfo(n);
00612 n->eliminate(bb, this);
00613 assert(info->defs.length() < oldlen, "didn't remove def");
00614 e = info->defs.head();
00615 } else {
00616 if (CompilerDebug) {
00617 char buf[1024];
00618 cout(PrintEliminateUnnededNodes)->print("*not eliminating node N%ld: %s\n", n->id(), n->print_string(buf));
00619 }
00620 assert(!removing, "cannot eliminate this?");
00621 e = e->next();
00622 }
00623 }
00624 }
00625
00626 void BlockPReg::eliminate(bool withUses) {
00627 PReg::eliminate(withUses);
00628 if (nuses() == 0) {
00629
00630
00631 if (_uplevelRead) {
00632 for (int i = _uplevelRead->length() - 1; i >= 0; i--) _uplevelRead->at(i)->removeUplevelAccessor(this);
00633 }
00634 if (_uplevelWritten) {
00635 for (int i = _uplevelWritten->length() - 1; i >= 0; i--) _uplevelWritten->at(i)->removeUplevelAccessor(this);
00636 }
00637 }
00638 }
00639
00640 void PReg::updateCPInfo(NonTrivialNode* n) {
00641
00642 if (cpInfo) {
00643 if (debug) {
00644
00645 #ifdef ASSERT
00646 CPInfo* cpi = new_CPInfo(n);
00647 assert(cpi && cpi->r->cpReg() == cpReg(), "can't handle this");
00648 #endif
00649 } else {
00650
00651
00652 cpInfo->r = dummyPR;
00653 }
00654 } else {
00655 cpInfo = new_CPInfo(n);
00656 assert(!debug || cpInfo || isBlockPReg(), "couldn't create info");
00657 if (cpInfo) {
00658 PReg* r = cpInfo->r;
00659
00660
00661
00662 r->debug |= debug;
00663 if (r->cpRegs == NULL) r->cpRegs = new GrowableArray<PReg*>(5);
00664 r->cpRegs->append(this);
00665 }
00666 }
00667 }
00668
00669
00670
00671
00672
00673
00674 bool PReg::slow_isLiveAt(Node* n) const {
00675 if (_scope->isSenderOrSame(n->scope())) {
00676 return isLiveAt(n);
00677 } else {
00678 return false;
00679 }
00680 }
00681
00682
00683 bool PReg::isLiveAt(Node* n) const {
00684
00685 if (!_scope->isSenderOrSame(n->scope())) return false;
00686 assert(PrologueBCI == begBCI() && endBCI() == EpilogueBCI, "must be live in the entire scope");
00687 return true;
00688 }
00689
00690
00691 InlinedScope* findAncestor(InlinedScope* s1, int& bci1, InlinedScope* s2, int& bci2) {
00692
00693
00694 if (s1->depth > s2->depth) {
00695 while (s1->depth > s2->depth) {
00696 bci1 = s1->senderBCI(); s1 = s1->sender();
00697 }
00698 } else {
00699 while (s2->depth > s1->depth) {
00700 bci2 = s2->senderBCI(); s2 = s2->sender();
00701 }
00702 }
00703 assert(s1->depth == s2->depth, "just checkin'...");
00704 while (s1 != s2) {
00705 bci1 = s1->senderBCI(); s1 = s1->sender();
00706 bci2 = s2->senderBCI(); s2 = s2->sender();
00707 }
00708 assert(s1->isInlinedScope(), "oops");
00709 return (InlinedScope*)s1;
00710 }
00711
00712
00713 bool SAPReg::isLiveAt(Node* n) const {
00714
00715
00716
00717
00718 InlinedScope* s = n->scope();
00719 bool live = basic_isLiveAt(s, n->bci());
00720 if (!live || !loc.isTemporaryRegister()) return live;
00721 fatal("cannot handle temp registers");
00722 return false;
00723 }
00724
00725
00726 bool SAPReg::basic_isLiveAt(InlinedScope* s, int bci) const {
00727 int id = this->id();
00728 if (!_scope->isSenderOrSame(s)) return false;
00729 assert(bciLE(bci, s->nofBytes()) || bci == EpilogueBCI, "bci too high");
00730 assert(_scope->isSenderOrSame(s), "s is not below my scope");
00731
00732
00733
00734 int bs = bci;
00735 int bc = creationStartBCI;
00736 InlinedScope* ss = findAncestor(s, bs, creationScope(), bc);
00737 if (!_scope->isSenderOrSame(ss)) fatal("bad scope arg in basic_isLiveAt");
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 if (ss == _scope) {
00752
00753 assert(_begBCI == bc ||
00754 ss == creationScope() && creationStartBCI == bc, "oops");
00755 return bciLE(_begBCI, bs) && bciLE(bs, _endBCI);
00756 } else {
00757
00758 return bciLE(bc, bs);
00759 }
00760 }
00761
00762
00763 bool PReg::isCPEquivalent(PReg* r) const {
00764
00765 if (this == r) return true;
00766
00767 for (CPInfo* i = cpInfo; i && i->r; i = i->r->cpInfo) {
00768 if (i->r == r) return true;
00769 }
00770
00771 for (i = r->cpInfo; i && i->r; i = i->r->cpInfo) {
00772 if (i->r == this) return true;
00773 }
00774 return false;
00775 }
00776
00777
00778
00779
00780
00781 NameNode* PReg::locNameNode(bool mustBeLegal) const {
00782 assert(!loc.isTemporaryRegister() || !mustBeLegal, "shouldn't be in temp reg");
00783 if (loc.isTemporaryRegister() && !debug) {
00784 return new IllegalName;
00785 } else {
00786
00787
00788 return new LocationName(loc);
00789 }
00790 }
00791
00792
00793 InlinedScope* BlockPReg::parent() const {
00794 return _closure->parent_scope();
00795 }
00796
00797
00798 NameNode* BlockPReg::locNameNode(bool mustBeLegal) const {
00799 Unused(mustBeLegal);
00800 assert(!loc.isTemporaryRegister(), "shouldn't be in temp reg");
00801
00802
00803 return new MemoizedName(loc, closure()->method(), closure()->parent_scope()->scopeInfo());
00804 }
00805
00806
00807 NameNode* PReg::nameNode(bool mustBeLegal) const {
00808 PReg* r = cpReg();
00809 if (!(r->loc.equals(unAllocated))) {
00810 return r->locNameNode(mustBeLegal);
00811 } else if (r->isConstPReg()) {
00812 return r->nameNode(mustBeLegal);
00813 } else if (r->isBlockPReg()) {
00814 CompileTimeClosure* c = ((BlockPReg*) r)->closure();
00815 return new BlockValueName(c->method(), c->parent_scope()->scopeInfo());
00816 } else {
00817
00818
00819
00820
00821
00822 return newValueName(nilObj);
00823 #ifdef how_it_should_be
00824 assert(!debug, "couldn't recover debug info");
00825 return new IllegalName;
00826 #endif
00827 }
00828 }
00829
00830 NameNode* ConstPReg::nameNode(bool mustBeLegal) const {
00831 return newValueName(constant);
00832 }
00833
00834 NameNode* NoPReg::nameNode(bool mustBeLegal) const {
00835 return new IllegalName;
00836 }
00837
00838
00839 PReg* PReg::cpReg() const {
00840
00841
00842
00843
00844
00845 if (cpInfo == NULL) {
00846 return (PReg*)this;
00847 } else {
00848 PReg* r;
00849 for (CPInfo* i = cpInfo; i; r = i->r, i = r->cpInfo) ;
00850 return r == dummyPR ? (PReg*)this : r;
00851 }
00852 }
00853
00854
00855 void BlockPReg::memoize() {
00856 _memoized = true;
00857 }
00858
00859
00860 void BlockPReg::markEscaped() {
00861 if (!_escapes) {
00862 _escapes = true;
00863 if (CompilerDebug) cout(PrintExposed)->print("*exposing %s\n", name());
00864 if (MemoizeBlocks) memoize();
00865 }
00866 }
00867
00868
00869 void BlockPReg::markEscaped(Node* n) {
00870 markEscaped();
00871 if (_escapeNodes == NULL) _escapeNodes = new GrowableArray<Node*>(5);
00872 if (! _escapeNodes->contains(n)) _escapeNodes->append(n);
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882 class UplevelComputer: public SpecializedMethodClosure {
00883 public:
00884 BlockPReg* r;
00885 InlinedScope* scope;
00886 GrowableArray<PReg*>* read;
00887 GrowableArray<PReg*>* written;
00888 int nestingLevel;
00889 int enclosingDepth;
00890 GrowableArray<Scope*>* enclosingScopes;
00891 methodOop method;
00892
00893
00894 UplevelComputer(BlockPReg* reg) {
00895 r = reg; scope = r->scope();
00896 read = new GrowableArray<PReg*>(10);
00897 written = new GrowableArray<PReg*>(10);
00898 nestingLevel = 0;
00899 method = r->closure()->method();
00900 enclosingDepth = 0;
00901 enclosingScopes = new GrowableArray<Scope*>(5);
00902 for (Scope* s = scope; s != NULL; s = s->parent(), enclosingDepth++) enclosingScopes->push(s);
00903 }
00904
00905
00906 void record_temporary (bool reading, int no, int ctx) {
00907
00908
00909
00910 int distance = method->lexicalDistance(ctx) - nestingLevel;
00911 if (distance < 1) return;
00912 Scope* s = enclosingScopes->at(distance - 1);
00913 if (s->isInlinedScope()) {
00914
00915 InlinedScope* target = (InlinedScope*)s;
00916 assert(target->allocatesInterpretedContext(), "find_scope returned bad scope");
00917 PReg* reg = target->contextTemporary(no)->preg();
00918 if (CompilerDebug) {
00919 cout(PrintExposed)->print("*adding %s to uplevel-%s of block %s\n", reg->name(), reading ? "read" : "written", r->name());
00920 }
00921 GrowableArray<PReg*>* list = reading ? read : written;
00922 list->append(reg);
00923 } else {
00924
00925 }
00926 }
00927
00928 void push_temporary (int no, int context) { record_temporary(true, no, context); }
00929 void store_temporary(int no, int context) { record_temporary(false, no, context); }
00930 void allocate_closure(AllocationType type, int nofArgs, methodOop meth) {
00931
00932 nestingLevel++;
00933 methodOop savedMethod = method;
00934 method = meth;
00935 MethodIterator iter(meth, this);
00936 method = savedMethod;
00937 nestingLevel--;
00938 }
00939 };
00940
00941
00942 void BlockPReg::computeUplevelAccesses() {
00943
00944 assert(escapes(), "should escape");
00945 if (_uplevelRead) return;
00946 UplevelComputer c(this);
00947 MethodIterator iter(_closure->method(), &c);
00948 assert(! _uplevelWritten, "shouldn't be there");
00949 _uplevelRead = c.read;
00950 _uplevelWritten = c.written;
00951 for (int i = _uplevelRead->length() - 1; i >= 0; i--) _uplevelRead ->at(i)->addUplevelAccessor(this, true, false);
00952 for (i = _uplevelWritten->length() - 1; i >= 0; i--) _uplevelWritten->at(i)->addUplevelAccessor(this, false, true);
00953 }
00954
00955
00956 char* PReg::safeName() const {
00957 if (this == NULL) {
00958 return "(null)";
00959 } else {
00960 return name();
00961 }
00962 }
00963
00964 char* PReg::name() const {
00965 char* n = NEW_RESOURCE_ARRAY(char, 25);
00966 if (loc.equals(unAllocated)) {
00967 sprintf(n, "%s%d%s%s%s", prefix(), id(),
00968 uplevelR() || uplevelW() ? "^" : "",
00969 uplevelR() ? "R" : "", uplevelW() ? "W" : "");
00970 } else {
00971 sprintf(n, "%s%d(%s)%s%s%s", prefix(), id(), loc.name(),
00972 uplevelR() || uplevelW() ? "^" : "",
00973 uplevelR() ? "R" : "", uplevelW() ? "W" : "");
00974 }
00975 return n;
00976 }
00977
00978
00979 void PReg::print() {
00980 lprintf("%s: ", name()); printDefsAndUses(&dus); lprintf("\n");
00981 }
00982
00983
00984 void BlockPReg::print() {
00985 print_short(); lprintf(": ");
00986 printDefsAndUses(&dus);
00987 if (_uplevelRead) { lprintf("; uplevel-read: "); _uplevelRead->print(); }
00988 if (_uplevelWritten) { lprintf("; uplevel-written: "); _uplevelWritten->print(); }
00989 if (_escapeNodes) {
00990 lprintf("; escapes at: ");
00991 for (int i = 0; i < _escapeNodes->length(); i++) lprintf("N%d ", _escapeNodes->at(i)->id());
00992 }
00993 lprintf("\n");
00994 }
00995
00996
00997 char* BlockPReg::name() const {
00998 char* n = NEW_RESOURCE_ARRAY(char, 25);
00999 sprintf(n, "%s <%#lx>%s", PReg::name(), PrintHexAddresses ? this : 0, _memoized ? "#" : "");
01000 return n;
01001 }
01002
01003
01004 char* ConstPReg::name() const {
01005 char* n = NEW_RESOURCE_ARRAY(char, 25);
01006 sprintf(n, "%s <%#lx>", PReg::name(), constant);
01007 return n;
01008 }
01009
01010
01011 #ifdef not_yet_used
01012 char* SplitPReg::name() const {
01013 char* n = NEW_RESOURCE_ARRAY(char, 25);
01014
01015
01016 sprintf(n, "%s", PReg::name());
01017 return n;
01018 }
01019 #endif
01020
01021
01022 bool PReg::verify() const {
01023 bool ok = true;
01024 if (_id < 0 || _id >= currentNo) {
01025 ok = false;
01026 error("PReg %#lx %s: invalid ID %ld", this, name(), _id);
01027 }
01028 int uses = 0, defs = 0;
01029 for (int i = 0; i < dus.length(); i++) {
01030 PRegBBIndex* index = dus.at(i);
01031 DUInfo* info = index->bb->duInfo.info->at(index->index);
01032 defs += info->defs.length();
01033 uses += info->uses.length();
01034 }
01035 if (defs != _ndefs && !incorrectD() && !isConstPReg()) {
01036
01037 ok = false;
01038 error("PReg %#lx %s: wrong def count (%ld instead of %ld)",
01039 this, name(), _ndefs, defs);
01040 }
01041 if (uses != _nuses && !incorrectU()) {
01042 ok = false;
01043 error("PReg %#lx %s: wrong use count (%ld instead of %ld)",
01044 this, name(), _nuses, uses);
01045 }
01046 if (!incorrectD() && _ndefs == 0 && _nuses > 0) {
01047 ok = false;
01048 error("PReg %#lx %s: used but not defined", this, name());
01049 }
01050 # ifdef fixthis // fix this - may still be needed
01051 if (debug && !incorrectDU() && isTrashedReg(loc)) {
01052 ok = false;
01053 error("PReg %#lx %s: debug-visible but allocated to temp reg", this, name());
01054 }
01055 # endif
01056 return ok;
01057 }
01058
01059
01060 bool SAPReg::verify() const {
01061 bool ok = PReg::verify();
01062 if (ok) {
01063 if (_begBCI == IllegalBCI) {
01064 if (creationStartBCI != IllegalBCI || _endBCI != IllegalBCI) {
01065 ok = false;
01066 error("SAPReg %#lx %s: live range only partially set", this, name());
01067 }
01068 } else if (_scope->isInlinedScope()) {
01069 int ncodes = scope()->nofBytes();
01070 if (creationStartBCI < PrologueBCI ||
01071 creationStartBCI > creationScope()->nofBytes()) {
01072 ok = false;
01073 error("SAPReg %#lx %s: invalid creationStartBCI %ld", this, name(), creationStartBCI);
01074 }
01075 if (_begBCI < PrologueBCI || _begBCI > ncodes) {
01076 ok = false;
01077 error("SAPReg %#lx %s: invalid startBCI %ld", this, name(), _begBCI);
01078 }
01079 if (_endBCI < PrologueBCI || _endBCI > ncodes && _endBCI != EpilogueBCI) {
01080 ok = false;
01081 error("SAPReg %#lx %s: invalid endBCI %ld", this, name(), _endBCI);
01082 }
01083 }
01084 }
01085 return ok;
01086 }
01087
01088
01089 bool BlockPReg::verify() const {
01090 bool ok = SAPReg::verify() && _closure->verify();
01091
01092 if (_uplevelRead) {
01093 for (int i = 0; i < _uplevelRead->length(); i++) {
01094 if (_uplevelRead->at(i)->isBlockPReg()) {
01095 BlockPReg* blk = (BlockPReg*)_uplevelRead->at(i);
01096 if (!blk->escapes()) {
01097 error("BlockPReg %#lx is uplevel-accessed by escaping BlockPReg %#lx but isn't marked escaping itself",
01098 blk, this);
01099 ok = false;
01100 }
01101 }
01102 }
01103 for (i = 0; i < _uplevelWritten->length(); i++) {
01104 if (_uplevelWritten->at(i)->isBlockPReg()) {
01105 BlockPReg* blk = (BlockPReg*)_uplevelRead->at(i);
01106 error("BlockPReg %#lx is uplevel-written by escaping BlockPReg %#lx, but BlockPRegs should never be assigned",
01107 blk, this);
01108 ok = false;
01109 }
01110 }
01111 }
01112 return ok;
01113 }
01114
01115
01116 bool NoPReg::verify() const {
01117 if (_nuses != 0) {
01118 error("NoPReg %#lx: has uses", this);
01119 return false;
01120 } else {
01121 return true;
01122 }
01123 }
01124
01125
01126 bool ConstPReg::verify() const {
01127 bool ok = PReg::verify() && constant->is_klass() || constant->verify();
01128
01129
01130
01131
01132
01133
01134
01135
01136 if (!(loc.equals(unAllocated)) && !loc.isRegisterLocation()) {
01137 error("ConstPReg %#lx: was allocated to stack", this);
01138 ok = false;
01139 }
01140 if (!(loc.equals(unAllocated)) && loc.isTrashedRegister()) {
01141 error("ConstPReg %#lx: was allocated to trashed reg", this);
01142 ok = false;
01143 }
01144 return ok;
01145 }
01146
01147
01148 # endif