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/_basicBlock.cpp.incl"
00028
00029 int BB::genCounter = 0;
00030
00031 void BB::init(Node* f, Node* l, int n) {
00032 first = f; last = l; nnodes = n;
00033 _id = 0; _genCount = 0; BB::genCounter = 0;
00034 _loopDepth = 0;
00035 }
00036
00037 BB* BB::next() const { Node* n = last ->next(); return n ? n->bb() : NULL; }
00038 BB* BB::firstPrev() const { Node* n = first->firstPrev(); return n ? n->bb() : NULL; }
00039 BB* BB::next(int i) const { Node* n = last ->next(i); return n ? n->bb() : NULL; }
00040 BB* BB::prev(int i) const { Node* n = first->prev(i); return n ? n->bb() : NULL; }
00041 int BB::nSuccessors() const { return last ->nSuccessors(); }
00042 int BB::nPredecessors()const { return first->nPredecessors(); }
00043 bool BB::isSuccessor (const BB* bb) const { return last->isSuccessor(bb->first); }
00044 bool BB::isPredecessor(const BB* bb) const { return first->isPredecessor(bb->last); }
00045
00046
00047
00048 const int MaxSearch = 50;
00049 NonTrivialNode* findDefinitionOf(Node* endNode, const PReg* r, int max = MaxSearch) {
00050
00051 Node* current = endNode;
00052 for (int i = 0; i < max && current != NULL; i++) {
00053 if (current->deleted) continue;
00054 if (current->hasSinglePredecessor()) {
00055 if ((current->isAssignNode() || current->isInlinedReturnNode()) &&
00056 ((NonTrivialNode*)current)->dest() == r) {
00057 return (NonTrivialNode*)current;
00058 }
00059 } else {
00060
00061 assert(current->isMergeNode(), "must be a merge");
00062 MergeNode* merge = (MergeNode*)current;
00063 NonTrivialNode* candidate = NULL;
00064 for (int j = merge->nPredecessors() - 1; j >= 0; j--) {
00065 Node* prev = merge->prev(j);
00066 NonTrivialNode* cand = findDefinitionOf(prev, r, max - i);
00067 if (cand == NULL || candidate && cand != candidate) return NULL;
00068 candidate = cand;
00069 }
00070 return candidate;
00071 }
00072 current = current->firstPrev();
00073 }
00074 return NULL;
00075 }
00076
00077
00078 void propagateTo(BB* useBB, Use* use, NonTrivialNode* fromNode, PReg* src,
00079 NonTrivialNode* toNode) {
00080
00081 if (toNode->canCopyPropagate(fromNode)) {
00082 if (!src->extendLiveRange(toNode)) {
00083 if (CompilerDebug) {
00084 cout(PrintCopyPropagation)->print("*brute-force cp: cannot propagate %s from N%ld to N%ld because of extendLiveRange\n",
00085 src->name(), fromNode->id(), toNode->id());
00086 }
00087 return;
00088 }
00089 PReg* replaced = fromNode->dest();
00090 bool ok = toNode->copyPropagate(useBB, use, src, true);
00091
00092 if (!ok) {
00093
00094
00095 return;
00096 }
00097 assert(ok, "should have worked");
00098 if (CompilerDebug) {
00099 cout(PrintCopyPropagation)->print("*brute-force cp: propagate %s from N%ld to N%ld\n",
00100 src->name(), fromNode->id(), toNode->id());
00101 }
00102
00103 if (replaced->debug && replaced->hasNoUses()) {
00104 assert(!replaced->cpInfo, "already has cpInfo");
00105 replaced->cpInfo = new_CPInfo(fromNode);
00106 assert(replaced->cpInfo, "should have cpInfo now");
00107 }
00108 } else {
00109 if (CompilerDebug) cout(PrintCopyPropagation)->print("*Node N%d cannot copy-propagate\n", toNode->id());
00110 }
00111 }
00112
00113
00114 bool regAssignedBetween(const PReg* r, const Node* startNode, Node* endNode) {
00115
00116
00117
00118 BB* bbWithoutDefs = NULL;
00119 for (Node* n = endNode; n != startNode; n = n->firstPrev()) {
00120
00121 BB* bb = n->bb();
00122 if (bb == bbWithoutDefs) continue;
00123 bool hasDefs = false;
00124 for (int i = 0; i < bb->duInfo.info->length(); i++) {
00125 DUInfo* dui = bb->duInfo.info->at(i);
00126 if (dui->reg == r && !dui->defs.isEmpty()) {
00127
00128 hasDefs = true;
00129 for (SListElem<Def*>* d = dui->defs.head(); d; d = d->next()) {
00130 if (d->data()->node == n) return true;
00131 }
00132 break;
00133 }
00134 }
00135 if (!hasDefs) {
00136
00137 bbWithoutDefs = bb;
00138 }
00139 }
00140 return false;
00141 }
00142
00143
00144 void BB::bruteForceCopyPropagate() {
00145 const int len = duInfo.info->length();
00146
00147 for (int i = 0; i < len; i++) {
00148 DUInfo* dui = duInfo.info->at(i);
00149 const PReg* r = dui->reg;
00150 if (!r->isSAPReg() || !r->loc.equals(unAllocated)) {
00151
00152
00153 continue;
00154 }
00155
00156
00157 if (dui->uses.isEmpty()) continue;
00158 const Use* use = dui->uses.head()->data();
00159 Node* firstUseNode = use->node;
00160 NonTrivialNode* defNode = findDefinitionOf(firstUseNode, r);
00161 if (defNode == NULL) continue;
00162
00163 PReg* candidate = ((NonTrivialNode*)defNode)->src();
00164 if (!candidate->loc.equals(unAllocated)) continue;
00165 assert(candidate->isUsed(), "should not be unused");
00166 if (!regAssignedBetween(candidate, defNode, firstUseNode)) {
00167
00168
00169 SListElem<Use*>* nextu;
00170 for (SListElem<Use*>* u = dui->uses.head(); u; u = nextu) {
00171 nextu = u->next();
00172 Use* thisUse = u->data();
00173 NonTrivialNode* thisNode = thisUse->node;
00174 if (!regAssignedBetween(candidate, firstUseNode, thisNode)) {
00175 propagateTo(this, thisUse, defNode, candidate, thisNode);
00176 } else {
00177
00178 break;
00179 }
00180 }
00181 }
00182 }
00183 }
00184
00185
00186 void BB::localCopyPropagate() {
00187
00188
00189
00190 const int len = duInfo.info->length();
00191 SimpleBitVector used = 0;
00192 SimpleBitVector usedTwice = 0;
00193 for (int i = 0; i < len; i++) {
00194 PReg* r = duInfo.info->at(i)->reg;
00195 if (!r->loc.equals(unAllocated) && r->loc.isRegisterLocation()) {
00196 if (used.isAllocated(r->loc.number())) {
00197
00198 usedTwice = usedTwice.allocate(r->loc.number());
00199 } else {
00200 used = used.allocate(r->loc.number());
00201 }
00202 }
00203 }
00204
00205 for (i = 0; i < len; i++) {
00206 const int BIG = 9999999;
00207 DUInfo* dui = duInfo.info->at(i);
00208 PReg* r = dui->reg;
00209 if (!r->loc.equals(unAllocated) && r->loc.isRegisterLocation() && usedTwice.isAllocated(r->loc.number())) {
00210
00211 continue;
00212 }
00213 SListElem<Use*>* u = dui->uses.head();
00214 SListElem<Def*>* nextd;
00215 for (SListElem<Def*>* d = dui->defs.head(); d && u; d = nextd) {
00216
00217 nextd = d->next();
00218 const Def* def = d->data();
00219 SList<Def*>* srcDefs = NULL;
00220 if (def->node->hasSrc()) {
00221 PReg* src = def->node->src();
00222 if (src->loc.isRegisterLocation() && usedTwice.isAllocated(src->loc.number())) {
00223
00224 continue;
00225 }
00226 if (!src->isSinglyAssigned()) {
00227
00228
00229 for (int j = 0; j < len; j++) {
00230 PReg* r = duInfo.info->at(j)->reg;
00231 if (r == src) break;
00232 }
00233 assert(j < len, "should have found duInfo for src");
00234 srcDefs = &duInfo.info->at(j)->defs;
00235 if (srcDefs->length() == 0) {
00236 srcDefs = NULL;
00237 }
00238 }
00239 }
00240 const int d_id = def->node->num();
00241 int u_id;
00242
00243 for ( ; u && (u_id = u->data()->node->num()) <= d_id; u = u->next()) ;
00244 if (!u) break;
00245
00246
00247
00248 int stop_id = nextd ? nextd->data()->node->num() : BIG;
00249 if (srcDefs) {
00250 for (SListElem<Def*>* d = srcDefs->head();
00251 d && d->data()->node->num() < u_id;
00252 d = d->next()) ;
00253 if (d) stop_id = min(stop_id, d->data()->node->num());
00254 }
00255
00256 while (u_id <= stop_id) {
00257
00258 assert(d_id < u_id, "just checking");
00259 dui->propagateTo(this, r, def, u->data(), false);
00260 u = u->next();
00261 u_id = u ? u->data()->node->num() : BIG + 1;
00262 }
00263 }
00264 }
00265 }
00266
00267
00268 void BB::makeUses() {
00269
00270 assert(duInfo.info == NULL, "shouldn't be set");
00271 duInfo.info = new GrowableArray<DUInfo*>(nnodes + 10);
00272 for (Node* n = first; n != last->next(); n = n->next()) {
00273 if (n->deleted) continue;
00274 n->makeUses(this);
00275 }
00276 }
00277
00278
00279 void BB::renumber() {
00280 int count = 0;
00281 for (Node* n = first; n != last->next(); n = n->next()) n->setNum(count++);
00282 nnodes = count;
00283 }
00284
00285
00286 void BB::remove(Node* n) {
00287
00288
00289
00290
00291 assert(contains(n), "node isn't in this BB");
00292 n->removeUses(this);
00293 n->deleted = true;
00294 }
00295
00296
00297 void BB::addAfter(Node* prev, Node* newNode) {
00298
00299 assert(nnodes, "shouldn't add anything to this BB");
00300 assert(prev == NULL || contains(prev), "node isn't in this BB");
00301 if (prev) {
00302 prev->insertNext(newNode);
00303 if (prev == last) last = newNode;
00304 } else {
00305 first->insertPrev(newNode);
00306 first = newNode;
00307 }
00308 if (bbIterator->usesBuilt) {
00309 newNode->makeUses(this);
00310 } else {
00311 newNode->setBB(this);
00312 }
00313 renumber();
00314 assert(newNode->bb() == this, "should point to me now");
00315 }
00316
00317
00318 static BB* thisBB;
00319 static void duChecker(PRegBBIndex* p) {
00320 if (p->bb == thisBB) fatal("should not be in middle of list");
00321 }
00322
00323
00324 static bool findMyBB(void* bb, PRegBBIndex* p) {
00325 return p->bb == (BB*)bb;
00326 }
00327
00328
00329 int BB::addUDHelper(PReg* r) {
00330
00331
00332 assert(nnodes, "shouldn't add anything to this BB");
00333 bbIterator->pregTable->at_put_grow(r->id(), r);
00334 PRegBBIndex* p;
00335 if (bbIterator->usesBuilt) {
00336
00337 int i = r->dus.find(this, findMyBB);
00338 if (i >= 0) {
00339 p = r->dus.at(i);
00340 } else {
00341
00342 duInfo.info->append(new DUInfo(r));
00343 r->dus.append(p = new PRegBBIndex(this, duInfo.info->length() - 1, r));
00344 }
00345 } else {
00346
00347
00348 if (r->dus.isEmpty() || r->dus.last()->bb != this) {
00349
00350 # ifdef ASSERT
00351 thisBB = this;
00352 r->dus.apply(duChecker);
00353 # endif
00354 duInfo.info->append(new DUInfo(r));
00355 r->dus.append(new PRegBBIndex(this, duInfo.info->length() - 1, r));
00356 }
00357 p = r->dus.last();
00358 }
00359 assert(p->bb == this, "wrong BB");
00360 assert(duInfo.info->at(p->index)->reg == r, "wrong PReg");
00361 return p->index;
00362 }
00363
00364
00365 Use* BB::addUse(NonTrivialNode* n, PReg* r, bool soft) {
00366 assert(contains(n), "node isn't in this BB");
00367 if (r->isNoPReg()) return NULL;
00368 Use* u = soft ? new PSoftUse(n) : new Use(n);
00369 r->incUses(u);
00370 int index = addUDHelper(r);
00371 duInfo.info->at(index)->uses.append(u);
00372 return u;
00373 }
00374
00375
00376 Def* BB::addDef(NonTrivialNode* n, PReg* r) {
00377 assert(contains(n), "node isn't in this BB");
00378 if (r->isNoPReg()) return NULL;
00379 Def* d = new Def(n);
00380 r->incDefs(d);
00381 int index = addUDHelper(r);
00382 duInfo.info->at(index)->defs.append(d);
00383 return d;
00384 }
00385
00386
00387
00388 void BB::localAlloc(GrowableArray<BitVector*>* hardwired,
00389 GrowableArray<PReg*>* localRegs,
00390 GrowableArray<BitVector*>* lives) {
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 if (!nnodes) return;
00402
00403 GrowableArray<RegCandidate*> cands(nnodes);
00404 GrowableArray<RegisterEqClass*> regClasses(nnodes + 1);
00405 regClasses.append(NULL);
00406
00407 int use_count[nofRegisters], def_count[nofRegisters];
00408 for (int i = 0; i < nofRegisters; i++) use_count[i] = def_count[i] = 0;
00409
00410 for (Node* nn = first; nn != last->next(); nn = nn->next()) {
00411 if (nn->deleted) continue;
00412 nn->markAllocated(use_count, def_count);
00413 if (nn->isAssignNode()) {
00414 NonTrivialNode* n = (NonTrivialNode*)nn;
00415 PReg* src = n->src();
00416 PReg* dest = n->dest();
00417 bool localSrc = src ->isLocalTo(this);
00418 bool localDest = dest->isLocalTo(this);
00419 if (src->loc.isRegisterLocation()) {
00420 if (dest->loc.equals(unAllocated) && localDest) {
00421
00422
00423
00424 cands.append(new RegCandidate(dest, src->loc, def_count[src->loc.number()]));
00425 }
00426 } else if (dest->loc.isRegisterLocation()) {
00427 if (src->loc.equals(unAllocated) && localSrc) {
00428
00429
00430
00431
00432 if (def_count[dest->loc.number()] != 1 || use_count[dest->loc.number()]) {
00433
00434 } else {
00435 cands.append(new RegCandidate(src, dest->loc, 1));
00436 }
00437 }
00438 } else if (localSrc && localDest) {
00439
00440
00441
00442 } else {
00443
00444 }
00445 }
00446 }
00447
00448
00449
00450 while (cands.nonEmpty()) {
00451 RegCandidate* c = cands.pop();
00452 if (def_count[c->loc.number()] == c->ndefs) {
00453 doAlloc(c->r, c->loc);
00454 }
00455 }
00456
00457
00458 int temp = 0;
00459 for (i = 0; i < duInfo.info->length(); i++) {
00460
00461 PReg* r = duInfo.info->at(i)->reg;
00462 if (r->loc.equals(unAllocated) && !r->isUnused() && r->isLocalTo(this)) {
00463 assert(r->dus.first()->index == i, "should be the same");
00464 for ( ; temp < nofLocalRegisters &&
00465 use_count[Mapping::localRegister(temp).number()] + def_count[Mapping::localRegister(temp).number()] > 0;
00466 temp++) ;
00467 if (temp == nofLocalRegisters) break;
00468
00469 Location t = Mapping::localRegister(temp++);
00470 PReg* frst = r->regClass ? regClasses.at(r->regClass)->first : r;
00471 for (PReg* pr = frst; pr;
00472 pr = pr->regClassLink) {
00473 doAlloc(pr, t);
00474 pr->regClass = 0;
00475 }
00476 }
00477 r->regClass = 0;
00478 }
00479
00480 if (temp == nofLocalRegisters) {
00481
00482
00483 slowLocalAlloc(hardwired, localRegs, lives);
00484 }
00485 }
00486
00487
00488
00489
00490
00491
00492 void BB::slowLocalAlloc(GrowableArray<BitVector*>* hardwired,
00493 GrowableArray<PReg*>* localRegs,
00494 GrowableArray<BitVector*>* lives) {
00495
00496 localRegs->clear();
00497 lives->clear();
00498 for (int i = 0; i < nofLocalRegisters; i++) {
00499 hardwired->at(i)->setLength(nnodes);
00500 hardwired->at(i)->clear();
00501 }
00502
00503
00504
00505
00506 for (i = 0; i < duInfo.info->length(); i++) {
00507
00508 PReg* r = duInfo.info->at(i)->reg;
00509 if (r->isLocalTo(this)) {
00510 assert(r->dus.first()->index == i, "should be the same");
00511 if (r->isUnused()) {
00512
00513 } else {
00514 DUInfo* info = duInfo.info->at(r->dus.first()->index);
00515 localRegs->append(r);
00516 BitVector* bv = new BitVector(nnodes);
00517 lives->append(bv);
00518 int firstUse = 0, lastUse = nnodes - 1;
00519 duInfo.info->at(i)->getLiveRange(firstUse, lastUse);
00520 bv->addFromTo(firstUse, lastUse);
00521 }
00522 } else if (r->loc.isLocalRegister()) {
00523
00524 assert(!r->loc.equals(unAllocated), "unAllocated should not count as isRegister()");
00525 int firstUse = 0, lastUse = nnodes - 1;
00526 if (!r->incorrectDU()) {
00527 duInfo.info->at(i)->getLiveRange(firstUse, lastUse);
00528 } else {
00529
00530
00531 }
00532 hardwired->at(Mapping::localRegisterIndex(r->loc))->addFromTo(firstUse, lastUse);
00533 }
00534 }
00535
00536
00537
00538
00539
00540
00541 for (Node* n = first; n != last->next(); n = n->next()) {
00542 if (n->deleted) continue;
00543 SimpleBitVector v = n->trashedMask();
00544 if (v.isEmpty()) continue;
00545 for (int i = 0; i < nofLocalRegisters; i++) {
00546 if (v.isAllocated(i)) hardwired->at(i)->add(n->num());
00547 }
00548 }
00549
00550
00551
00552
00553 int lastTemp = 0;
00554 # define nextTemp(n) (n == nofLocalRegisters - 1) ? 0 : n + 1
00555
00556 for (i = 0; i < localRegs->length(); i++) {
00557
00558 PReg* r = localRegs->at(i);
00559 if (!r->loc.equals(unAllocated)) {
00560 assert(r->regClass == 0, "should have been cleared");
00561 continue;
00562 }
00563 BitVector* liveRange = lives->at(i);
00564 for (int tempNo = lastTemp, ntries = 0; ntries < nofLocalRegisters;
00565 tempNo = nextTemp(tempNo), ntries++) {
00566 if (liveRange->isDisjointFrom(hardwired->at(tempNo))) {
00567 Location temp = Mapping::localRegister(tempNo);
00568 doAlloc(r, temp);
00569 hardwired->at(tempNo)->unionWith(liveRange);
00570 lastTemp = nextTemp(tempNo);
00571 break;
00572 }
00573 }
00574 if (CompilerDebug) {
00575 if (r->loc.equals(unAllocated)) {
00576 cout(PrintLocalAllocation)->print("*could NOT find local assignment for local %s in BB%ld\n", r->name(), id());
00577 }
00578 }
00579 r->regClass = 0;
00580 }
00581 }
00582
00583
00584 void BB::doAlloc(PReg* r, Location l) {
00585 if (CompilerDebug) cout(PrintLocalAllocation)->print("*assigning %s to local %s in BB%ld\n", l.name(), r->name(), id());
00586 assert(!r->debug, "should not allocate to temp reg");
00587 r->loc = l;
00588 }
00589
00590
00591 void BB::computeEscapingBlocks(GrowableArray<BlockPReg*>* l) {
00592
00593 for (Node* n = first; n != last->next(); n = n->next()) {
00594 if (n->deleted) continue;
00595 n->computeEscapingBlocks(l);
00596 }
00597 }
00598
00599
00600 void BB::apply(NodeVisitor* v) {
00601 if (nnodes > 0) {
00602 Node* end = last->next();
00603 for (Node* n = first; n != end; n = n->next()) {
00604 if (!n->deleted) {
00605 v->beginOfNode(n);
00606 n->apply(v);
00607 v->endOfNode(n);
00608 }
00609 }
00610 } else {
00611 #ifdef ASSERT
00612
00613 assert(nnodes == 0, "nnodes should be 0");
00614 Node* end = last->next();
00615 for (Node* n = first; n != end; n = n->next) {
00616 assert(n->deleted, "basic block is not empty even though nnodes == 0!");
00617 }
00618 #endif
00619 }
00620 }
00621
00622
00623 bool BB::verifyLabels() {
00624 bool ok = true;
00625 if (nnodes > 0) {
00626 for (Node* n = first; n != last->next(); n = n->next()) {
00627 if (n->deleted) continue;
00628 if (n->label.is_unbound()) {
00629 ok = false;
00630 lprintf("unbound label at N%d\n", n->id());
00631 }
00632 }
00633 }
00634 return ok;
00635 }
00636
00637
00638 static void printPrevBBs(BB* b, const char* str) {
00639 lprintf("BB%ld%s", b->id(), str);
00640 }
00641
00642
00643 void BB::print_short() {
00644 lprintf("BB%-3ld[%d] %#lx (%ld, %ld); prevs ", id(), _loopDepth, this, first->id(), last->id());
00645 for (int i = 0; i < nPredecessors(); i++) printPrevBBs(prev(i), (i == nPredecessors() - 1) ? " : " : ", ");
00646 lprintf("; ");
00647 if (next ()) lprintf("next BB%ld", next ()->id());
00648 for (i = 1; i < nSuccessors(); i++) printPrevBBs(next(i), (i == nSuccessors() - 1) ? " : " : ", ");
00649 }
00650
00651
00652 void BB::print() {
00653 print_short(); lprintf("(%ld nodes):\n", nnodes);
00654 print_code(false);
00655 lprintf("duInfo: "); duInfo.print();
00656 }
00657
00658
00659 void BB::print_code(bool suppressTrivial) {
00660 for (Node* n = first; n != last->next(); n = n->next()) {
00661 if (n->deleted && !(n == first || n == last)) continue;
00662 if (suppressTrivial && n->isTrivial()) {
00663
00664 } else {
00665 n->printID(); n->print_short(); lprintf("\n");
00666 }
00667 }
00668 }
00669
00670
00671 bool BB::contains(const Node* which) const {
00672 for (Node* n = first; n != last->next(); n = n->next()) {
00673 if (n == which) return true;
00674 }
00675 return false;
00676 }
00677
00678
00679 void BB::verify() {
00680 int count = 0;
00681 for (Node* n = first; n != last->next(); n = n->next()) {
00682 count++;
00683 if (n->deleted) continue;
00684 n->verify();
00685 if (n->bb() != this)
00686 error("BB %#lx: Node %#lx doesn't point back to me", this, n);
00687 if (n == last && !n->endsBB() &&
00688 !(n->next() && n->next()->isMergeNode() &&
00689 ((MergeNode*)(n->next()))->didStartBB)) {
00690 error("BB %#lx: last Node %#lx isn't endsBB()", this, n);
00691 }
00692 if (n->endsBB() && n != last)
00693 error("BB %#lx: Node %#lx ends BB but isn't last node", this, n);
00694 }
00695 if (count != nnodes) error("incorrect nnodes in BB %#lx", this);
00696 if (_loopDepth < 0) error ("BB %#lx: negative loopDepth %d", this, _loopDepth);
00697
00698
00699 if (_loopDepth > 9) warning("BB %#lx: suspiciously high loopDepth %d", this, _loopDepth);
00700 }
00701
00702
00703 BBIterator* bbIterator;
00704
00705 void BBIterator::build(Node* first) {
00706 assert(bbTable == NULL, "already built");
00707 _first = first;
00708 bbCount = 0;
00709 pregTable = globals = NULL;
00710 buildBBs();
00711 blocksBuilt = true;
00712 }
00713
00714
00715 void BBIterator::buildBBs() {
00716
00717
00718
00719 GrowableArray<BB*>* list = new GrowableArray<BB*>(max(BasicNode::currentID >> 3, 10));
00720 _first->newBB()->dfs(list, 0);
00721
00722 bbCount = list->length();
00723 bbTable = new GrowableArray<BB*>(bbCount);
00724 for (int i = bbCount-1; i >= 0; i--) {
00725 BB* bb = list->at(i);
00726 bb->_id = bbCount - i - 1;
00727 bbTable->append(bb);
00728 }
00729 }
00730
00731
00732 void BB::dfs(GrowableArray<BB*>* list, int loopDepth) {
00733
00734 if (_id == 1) return;
00735 _id = 1;
00736 #ifdef fix_this
00737 setting of isLoopStart/End is broken -- fix this (currently not used)
00738 if (first->isMergeNode()) {
00739 MergeNode* m = (MergeNode*)first;
00740 if (m->isLoopStart) {
00741 loopDepth++;
00742 } else if (m->isLoopEnd) {
00743 assert(loopDepth > 0, "bad loop end marker");
00744 loopDepth--;
00745 }
00746 }
00747 #endif
00748 _loopDepth = loopDepth;
00749
00750
00751
00752
00753
00754 int n = last->nSuccessors();
00755 for (int i = 0; i < n; i++) {
00756 Node* next = last->next(i);
00757 BB* nextBB = next->newBB();
00758 }
00759 for (i = nSuccessors() - 1; i >= 0; i--) {
00760 BB* nextBB = next(i);
00761
00762 if (nextBB->id() == 0) nextBB->dfs(list, loopDepth);
00763 }
00764 list->append(this);
00765 }
00766
00767
00768 static void clearNodes(BB* bb) {
00769 for (Node* n = bb->first; n != bb->last->next(); n = n->next()) {
00770 n->setBB(NULL);
00771 }
00772 }
00773
00774
00775 void BBIterator::clear() {
00776 apply(clearNodes);
00777 bbTable = NULL; pregTable = globals = NULL;
00778 }
00779
00780
00781 void BBIterator::makeUses() {
00782
00783
00784 const int ExtraPRegs = 10;
00785 int n = PReg::currentNo + ExtraPRegs;
00786 pregTable = new GrowableArray<PReg*>(n);
00787 for (int i = 0; i < n; i++) pregTable->append(NULL);
00788 for (i = 0; i < bbCount; i++) { bbTable->at(i)->makeUses(); }
00789 usesBuilt = true;
00790 }
00791
00792
00793 void BBIterator::localAlloc() {
00794
00795
00796 { ResourceMark rm;
00797 GrowableArray<BitVector*> hardwired(nofLocalRegisters, nofLocalRegisters, NULL);
00798 GrowableArray<PReg*> localRegs(BasicNode::currentID);
00799 GrowableArray<BitVector*> lives(BasicNode::currentID);
00800 for (int i = 0; i < nofLocalRegisters; i++) {
00801 hardwired.at_put(i, new BitVector(roundTo(BasicNode::currentID, BitsPerWord)));
00802 }
00803
00804 for (i = 0; i < bbCount; i++) {
00805 bbTable->at(i)->localAlloc(&hardwired, &localRegs, &lives);
00806 }
00807 }
00808
00809 int done = 0;
00810 globals = new GrowableArray<PReg*>(pregTable->length());
00811 for (int i = 0; i < pregTable->length(); i++) {
00812 PReg* r = pregTable->at(i);
00813 if (r) {
00814 if (r->isUnused()) {
00815 pregTable->at_put(i, NULL);
00816 } else if (r->loc.equals(unAllocated)) {
00817 globals->append(r);
00818 } else {
00819 done++;
00820 }
00821 }
00822 }
00823 if (PrintLocalAllocation) {
00824 int total = globals->length() + done;
00825 lprintf("*local reg. allocations done; %ld out of %ld = (%3.1f%%).\n",
00826 done, total, 100.0 * done / total);
00827 }
00828 }
00829
00830
00831 void BBIterator::print() {
00832 for (int i = 0; i < bbCount; i++) {
00833 lprintf(" "); bbTable->at(i)->print_short(); lprintf("\n");
00834 }
00835 }
00836
00837
00838 void BBIterator::localCopyPropagate() {
00839 for (int i = 0; i < bbCount; i++) { bbTable->at(i)->localCopyPropagate(); }
00840 }
00841
00842
00843 void BBIterator::bruteForceCopyPropagate() {
00844 for (int i = 0; i < bbCount; i++) { bbTable->at(i)->bruteForceCopyPropagate(); }
00845 }
00846
00847
00848 void BBIterator::computeEscapingBlocks() {
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860 exposedBlks = new GrowableArray<BlockPReg*>(BlockPReg::numBlocks());
00861 for (int i = 0; i < bbCount; i++) {
00862 bbTable->at(i)->computeEscapingBlocks(exposedBlks);
00863 }
00864 }
00865
00866
00867 void BBIterator::computeUplevelAccesses() {
00868
00869
00870
00871
00872 int len = exposedBlks->length();
00873 for (int i = 0; i < len; i++) {
00874 BlockPReg* r = exposedBlks->at(i);
00875 assert (r->parent() == r->scope(), "block preg was copied/changed scope");
00876 assert(r->scope()->isInlinedScope(), "must be code scope");
00877 r->computeUplevelAccesses();
00878 }
00879 }
00880
00881
00882 bool BBIterator::isSequentialCode(BB* curr, BB* next) const {
00883 return curr == next ||
00884 (curr->genCount() + 1 == next->genCount() &&
00885 curr->next() == next);
00886 }
00887
00888
00889 bool BBIterator::isSequential(int curr, int next) const {
00890
00891 if (curr == next) return true;
00892 if (next < bbCount && bbTable->at(curr)->next() != NULL &&
00893 bbTable->at(curr)->next() != bbTable->at(next)) {
00894 return false;
00895 }
00896
00897 if (next == bbCount && bbTable->at(curr)->next() != NULL) {
00898
00899 return false;
00900 }
00901
00902 return true;
00903 }
00904
00905
00906 BB* BBIterator::bb_for(Node* n) {
00907 return n != NULL ? n->bb() : NULL;
00908 }
00909
00910
00911 void BBIterator::add_BBs_to_list(GrowableArray<BB*>& list, GrowableArray<BB*>& work) {
00912 if (!work.isEmpty()) {
00913 GrowableArray<BB*> uncommon;
00914 do {
00915 BB* bb = work.pop();
00916 assert(bb->visited(), "must have been visited");
00917 list.append(bb);
00918 bb->setGenCount();
00919
00920 BB* likely_next = bb_for(bb->last->likelySuccessor());
00921 BB* uncommon_next = bb_for(bb->last->uncommonSuccessor());
00922 assert(likely_next != uncommon_next || likely_next == NULL, "likely BB cannot be uncommon BB at the same time");
00923
00924 for (int i = bb->nSuccessors(); i-- > 0; ) {
00925 BB* next = (BB*)bb->next(i);
00926 if (next != NULL && !next->visited() && next != likely_next && next != uncommon_next) {
00927 work.push(next->after_visit());
00928 }
00929 }
00930
00931 if (likely_next != NULL && !likely_next->visited()) {
00932 work.push(likely_next->after_visit());
00933 }
00934
00935 if (uncommon_next != NULL && !uncommon_next->visited()) uncommon.push(uncommon_next->after_visit());
00936 } while(!work.isEmpty());
00937
00938 add_BBs_to_list(list, uncommon);
00939 }
00940 }
00941
00942
00943 GrowableArray<BB*>* BBIterator::code_generation_order() {
00944 if (!ReorderBBs) return bbTable;
00945
00946 for (int i = 0; i < bbCount; i++) bbTable->at(i)->before_visit();
00947
00948 GrowableArray<BB*>* list = new GrowableArray<BB*>(bbCount);
00949 GrowableArray<BB*> work(bbCount);
00950
00951 BB* bb = _first->bb();
00952 work.push(bb->after_visit());
00953
00954 add_BBs_to_list(*list, work);
00955
00956 assert(list->length() <= bbCount, "gained BBs?");
00957 return list;
00958 }
00959
00960
00961 void BBIterator::print_code(bool suppressTrivial) {
00962 GrowableArray<BB*>* list = code_generation_order();
00963 for (int i = 0; i < list->length(); i++) {
00964 BB* bb = list->at(i);
00965 if (bb->nnodes > 0) bb->print_code(suppressTrivial);
00966 if (bb->next() != NULL) std->print_cr("\tgoto N%d", bb->next()->first->id());
00967 if (!suppressTrivial) lprintf("\n");
00968 }
00969 }
00970
00971
00972 void BBIterator::apply(NodeVisitor* v) {
00973 GrowableArray<BB*>* list = code_generation_order();
00974 int length = list->length();
00975 for (int i = 0; i < length; i++) {
00976 BB* bb = list->at(i);
00977 Node* first = bb->first;
00978 Node* last = bb->last;
00979 v->beginOfBasicBlock(first);
00980 bb->apply(v);
00981 v->endOfBasicBlock(last);
00982 }
00983 }
00984
00985
00986 bool BBIterator::verifyLabels() {
00987 bool ok = true;
00988 for (int i = 0; i < bbCount; i++) ok &= bbTable->at(i)->verifyLabels();
00989 return ok;
00990 }
00991
00992
00993 void BBIterator::globalCopyPropagate() {
00994
00995
00996 for (int i = 0; i < pregTable->length(); i++) {
00997 PReg* r = pregTable->at(i);
00998 if (!r || r->isConstPReg() || !r->canCopyPropagate()) continue;
00999 Def* def = NULL;
01000
01001 int dulength = r->dus.length();
01002 for (int e = 0; e < dulength; e++) {
01003 PRegBBIndex* index = r->dus.at(e);
01004 DUInfo* info = index->bb->duInfo.info->at(index->index);
01005 if (info->defs.length()) {
01006 assert(info->defs.length() == 1, "should be one definition only");
01007 assert(def == NULL, "already have def!?!");
01008 def = info->defs.first();
01009 # ifndef ASSERT
01010 break;
01011 # endif
01012 }
01013 }
01014 assert(def, "should have found the definition");
01015 NonTrivialNode* defNode = def->node;
01016
01017
01018 if (!defNode->isAssignmentLike()) continue;
01019 assert(defNode->dest() == r, "not assignment-like");
01020
01021 PReg* defSrc = defNode->src();
01022
01023
01024
01025
01026 if (!defSrc->isSinglyAssigned() || defSrc->loc.isTrashedRegister())
01027 continue;
01028
01029
01030 for (e = 0; e < dulength; e++) {
01031 PRegBBIndex* index = r->dus.at(e);
01032 BB* bb = index->bb;
01033 DUInfo* info = bb->duInfo.info->at(index->index);
01034
01035
01036 int j = 0;
01037 while (j < info->uses.length()) {
01038 int oldLen = info->uses.length();
01039 info->propagateTo(bb, info->reg, def, info->uses.at(j), true);
01040 if (info->uses.length() == oldLen) {
01041
01042 j++;
01043 }
01044 }
01045 }
01046 }
01047 }
01048
01049
01050 void BBIterator::eliminateUnneededResults() {
01051
01052 for (int i = 0; i < pregTable->length(); i++) {
01053 PReg* r = pregTable->at(i);
01054 if (r && r->isOnlySoftUsed()) {
01055 r->eliminate(false);
01056 }
01057 }
01058 }
01059
01060
01061 void BBIterator::apply(BBDoFn f) {
01062 for (int i = 0; i < bbCount; i++) { f(bbTable->at(i)); }
01063 }
01064
01065
01066 void BBIterator::verify() {
01067 if (bbTable) {
01068 for (int i = 0; i < bbCount; i++) { bbTable->at(i)->verify(); }
01069 if (pregTable) {
01070 for (i = 0; i < pregTable->length(); i++) {
01071 if (pregTable->at(i)) pregTable->at(i)->verify();
01072 }
01073 }
01074 }
01075 }
01076
01077
01078 # endif