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/_loopOpt.cpp.incl"
00028
00029 GrowableArray<BB*>* CompiledLoop::_bbs;
00030
00031 CompiledLoop::CompiledLoop() {
00032 _bbs = NULL;
00033 _startOfLoop = _endOfLoop = _startOfBody = _endOfBody = _startOfCond = _endOfCond = NULL;
00034 _loopVar = NULL;
00035 _lowerBound = NULL; _upperBound = NULL;
00036 _isIntegerLoop = false;
00037 _hoistableTests = NULL;
00038 _loopBranch = NULL;
00039 _isCountingUp = true;
00040 }
00041
00042
00043 void CompiledLoop::set_startOfLoop(LoopHeaderNode* current) {
00044 assert(_startOfLoop == NULL, "already set");
00045 assert(current->isLoopHeaderNode(), "expected loop header");
00046 _startOfLoop = _loopHeader = current;
00047 _beforeLoop = current->firstPrev();
00048 }
00049
00050
00051 void CompiledLoop::set_endOfLoop(Node* end) {
00052 assert(_endOfLoop == NULL, "already set");
00053 _endOfLoop = end;
00054 _startOfLoop = _startOfLoop->next();
00055 _firstNodeID = _startOfLoop->id() + 1;
00056 _lastNodeID = BasicNode::currentID - 1;
00057 _scope = _startOfLoop->scope();
00058 }
00059
00060
00061 void CompiledLoop::set_startOfBody(Node* current) {
00062 assert(_startOfBody == NULL, "already set");
00063 _startOfBody = current;
00064 }
00065
00066
00067 void CompiledLoop::set_endOfBody(Node* current) {
00068 assert(_endOfBody == NULL, "already set");
00069 _endOfBody = current;
00070
00071 if (isInLoopCond(_startOfBody)) _startOfBody = _startOfBody->next();
00072 assert(!isInLoopCond(_startOfBody), "oops!");
00073 }
00074
00075
00076 void CompiledLoop::set_startOfCond(Node* current) {
00077 assert(_startOfCond == NULL, "already set");
00078 _startOfCond = current;
00079 }
00080
00081
00082 void CompiledLoop::set_endOfCond(Node* current) {
00083 assert(_endOfCond == NULL, "already set");
00084 _endOfCond = current;
00085 }
00086
00087
00088 bool CompiledLoop::isInLoop(Node* n) const {
00089 return _firstNodeID <= n->id() && n->id() <= _lastNodeID;
00090 }
00091
00092
00093 bool CompiledLoop::isInLoopCond(Node* n) const {
00094 return _startOfCond->id() <= n->id() && n->id() <= _endOfCond->id();
00095 }
00096
00097
00098 bool CompiledLoop::isInLoopBody(Node* n) const {
00099 return _startOfBody->id() <= n->id() && n->id() <= _endOfBody->id();
00100 }
00101
00102
00103 char* CompiledLoop::recognize() {
00104
00105
00106
00107
00108 discoverLoopNesting();
00109 if (!OptimizeIntegerLoops) return "!OptimizeIntegerLoops";
00110 char* msg;
00111 if ((msg = findUpperBound()) != NULL) return msg;
00112 if ((msg = checkLoopVar()) != NULL) return msg;
00113 if ((msg = checkUpperBound()) != NULL) return msg;
00114 _isIntegerLoop = true;
00115 findLowerBound();
00116 return NULL;
00117 }
00118
00119 void CompiledLoop::discoverLoopNesting() {
00120
00121 for (InlinedScope* s = _scope; s != NULL; s = s->sender()) {
00122 GrowableArray<CompiledLoop*>* loops = s->loops();
00123 for (int i = loops->length() - 1; i >= 0; i--) {
00124 CompiledLoop* l = loops->at(i);
00125 if (l->isInLoop(_loopHeader)) {
00126
00127 _loopHeader->set_enclosingLoop(l->loopHeader());
00128 l->loopHeader()->addNestedLoop(_loopHeader);
00129 return;
00130 }
00131 }
00132 }
00133 }
00134
00135
00136 char* CompiledLoop::findLowerBound() {
00137
00138
00139
00140
00141
00142 Node* defNode;
00143 for (defNode = _beforeLoop;
00144 defNode && defNode->nPredecessors() < 2 &&
00145 (!defNode->hasDest() || ((NonTrivialNode*)defNode)->dest() != _loopVar);
00146 defNode = defNode->firstPrev()) ;
00147 if (defNode && defNode->isAssignNode()) {
00148
00149 _lowerBound = ((NonTrivialNode*)defNode)->src();
00150 }
00151 return "lower bound not found";
00152 }
00153
00154
00155
00156 class SendFinder: public SpecializedMethodClosure {
00157 public:
00158 int theBCI, lastSendBCI;
00159
00160 SendFinder(methodOop m, int bci) : SpecializedMethodClosure() {
00161 theBCI = bci; lastSendBCI = IllegalBCI;
00162 MethodIterator iter(m, this);
00163 }
00164 void send() {
00165 int b = bci();
00166 if (b <= theBCI && b > lastSendBCI) lastSendBCI = b;
00167 }
00168 virtual void normal_send(InterpretedIC* ic) { send(); }
00169 virtual void self_send (InterpretedIC* ic) { send(); }
00170 virtual void super_send (InterpretedIC* ic) { send(); }
00171 };
00172
00173
00174 int CompiledLoop::findStartOfSend(int bci) {
00175
00176 SendFinder f(_scope->method(), bci);
00177 return f.lastSendBCI;
00178 }
00179
00180
00181 char* CompiledLoop::findUpperBound() {
00182
00183 int condBCI = findStartOfSend(_endOfCond->bci() - InterpretedIC::size);
00184 if (condBCI == IllegalBCI) return "loop condition: no send found";
00185
00186 Expr* loopCond = _scope->exprStackElems()->at(condBCI);
00187 if (loopCond == NULL) return "loop condition: no expr (possible compiler bug)";
00188 if (loopCond->isMergeExpr()) {
00189 MergeExpr* cond = (MergeExpr*)loopCond;
00190 if (cond->isSplittable()) {
00191 Node* first = cond->exprs->first()->node();
00192 if (first->nPredecessors() == 1) {
00193 Node* prev = first->firstPrev();
00194 if (prev->isBranchNode()) _loopBranch = (BranchNode*)prev;
00195 }
00196 }
00197 }
00198 if (!_loopBranch) return "loop condition: conditional branch not found";
00199 NonTrivialNode* n = (NonTrivialNode*)_loopBranch->firstPrev();
00200 PReg* operand;
00201 if (n->isTArithNode()) {
00202 operand = ((TArithRRNode*)n)->operand();
00203 } else if (n->isArithNode()) {
00204 operand = ((ArithRRNode*)n)->operand();
00205 } else {
00206 return "loop condition: comparison not found";
00207 }
00208 BranchOpCode op = _loopBranch->op();
00209
00210
00211
00212
00213 if (op == LTBranchOp || op == LEBranchOp) {
00214
00215 _loopVar = operand;
00216 _upperBound = n->src();
00217 } else if (op == GTBranchOp || op == GEBranchOp) {
00218
00219 _loopVar = n->src();
00220 _upperBound = operand;
00221 } else {
00222 return "loop condition: not oneof(<, <=, >, >=)";
00223 }
00224
00225
00226
00227 if (checkLoopVar()) {
00228
00229 PReg* temp = _loopVar; _loopVar = _upperBound; _upperBound = temp;
00230 }
00231 return NULL;
00232 }
00233
00234
00235
00236 class LoopClosure : public Closure<Def*> {
00237 public:
00238 NonTrivialNode* defNode;
00239 CompiledLoop* theLoop;
00240
00241 LoopClosure(CompiledLoop* l) { defNode = NULL; theLoop = l; }
00242 };
00243
00244
00245
00246 class LoopDefCounter : public LoopClosure {
00247 public:
00248 int defCount;
00249 LoopDefCounter(CompiledLoop* l) : LoopClosure(l) { defCount = 0; }
00250
00251 void do_it(Def* d) {
00252 if (theLoop->isInLoop(d->node)) {
00253 defCount++;
00254 defNode = (NonTrivialNode*)d->node;
00255 }
00256 }
00257 };
00258
00259
00260 int CompiledLoop::defsInLoop(PReg* r, NonTrivialNode** defNode) {
00261
00262
00263
00264 LoopDefCounter ldc(this);
00265 r->forAllDefsDo(&ldc);
00266 if (defNode) *defNode = ldc.defNode;
00267 return ldc.defCount;
00268 }
00269
00270
00271 class LoopDefFinder : public LoopClosure {
00272 public:
00273 LoopDefFinder(CompiledLoop* l) : LoopClosure(l) {}
00274 void do_it(Def* d) { if (theLoop->isInLoop(d->node)) defNode = d->node; }
00275 };
00276
00277
00278 NonTrivialNode* CompiledLoop::findDefInLoop(PReg* r) {
00279 assert(defsInLoop(r) == 1, "must have single definition in loop");
00280 LoopDefFinder ldf(this);
00281 r->forAllDefsDo(&ldf);
00282 return ldf.defNode;
00283 }
00284
00285
00286 char* CompiledLoop::checkLoopVar() {
00287 #ifdef unnecessary
00288
00289 BB* beforeLoopBB = _beforeLoop->bb();
00290
00291 for (Node* n = _beforeLoop;
00292 n && n->bb() == beforeLoopBB && (!n->isAssignNode() || ((AssignNode*)n)->dest() != loopVar);
00293 n = n->firstPrev()) ;
00294 if (n && n->bb() == beforeLoopBB) {
00295
00296 assert(n->isAssignNode() && ((AssignNode*)n)->dest() == loopVar, "oops");
00297 } else {
00298 return "no lower-bound assignment to loop var before loop";
00299 }
00300 #endif
00301
00302
00303
00304 if (_loopVar->isSinglyAssigned()) return "loopVar has single definition globally";
00305
00306
00307
00308 if (defsInLoop(_loopVar) != 1) return "loopVar has != 1 defs in loop";
00309 NonTrivialNode* n1 = findDefInLoop(_loopVar);
00310 if (defsInLoop(n1->src()) != 1) return "loopVar has != 1 defs in loop (2)";
00311 NonTrivialNode* n2 = findDefInLoop(n1->src());
00312 PReg* operand;
00313 ArithOpCode op;
00314 if (n2->isTArithNode()) {
00315 operand = ((TArithRRNode*)n2)->operand();
00316 op = ((TArithRRNode*)n2)->op();
00317 } else if (n2->isArithNode()) {
00318 operand = ((ArithRRNode*)n2)->operand();
00319 op = ((ArithRRNode*)n2)->op();
00320 } else {
00321 return "loopVar def not an arithmetic operation";
00322 }
00323 _incNode = n2;
00324 if (op != tAddArithOp && op != tSubArithOp) return "loopVar def isn't an add/sub";
00325 if (_incNode->src() == _loopVar) {
00326 if (!isIncrement(operand, op)) return "loopVar isn't incremented by constant/loop-invariant";
00327 } else if (operand == _loopVar) {
00328 if (!isIncrement(_incNode->src(), op)) return "loopVar isn't incremented by constant/loop-invariant";
00329 } else {
00330 return "loopVar def isn't an increment";
00331 }
00332
00333
00334
00335 BranchOpCode branchOp = _loopBranch->op();
00336 bool loopVarMustBeLeft = (branchOp == GTBranchOp || branchOp == GEBranchOp) ^ !_isCountingUp;
00337 NonTrivialNode* compare = (NonTrivialNode*)_loopBranch->firstPrev();
00338 if (loopVarMustBeLeft != (compare->src() == _loopVar)) {
00339 return "loopVar is on wrong side of comparison (loop not bounded)";
00340 }
00341
00342 return NULL;
00343 }
00344
00345
00346 bool CompiledLoop::isIncrement(PReg* p, ArithOpCode op) {
00347
00348 _increment = p;
00349 if (p->isConstPReg()) {
00350 oop c = ((ConstPReg*)p)->constant;
00351 if (!c->is_smi()) return false;
00352 _isCountingUp = (smiOop(c)->value() > 0) ^ (op == tSubArithOp);
00353 return true;
00354 } else {
00355
00356 return defsInLoop(p) == 0;
00357 }
00358 }
00359
00360
00361 char* CompiledLoop::checkUpperBound() {
00362
00363 _loopArray = NULL;
00364 _loopSizeLoad = NULL;
00365 int ndefs = defsInLoop(_upperBound, NULL);
00366 if (ndefs > 0) return "upper bound isn't loop-invariant";
00367
00368
00369 Node* defNode;
00370 for (defNode = _beforeLoop;
00371 defNode && defNode->nPredecessors() < 2 &&
00372 (!defNode->hasDest() || ((NonTrivialNode*)defNode)->dest() != _upperBound);
00373 defNode = defNode->firstPrev()) ;
00374 if (defNode && defNode->isArraySizeLoad()) {
00375
00376 if (defsInLoop(_loopArray) == 0) {
00377 _loopSizeLoad = (LoadOffsetNode*)defNode;
00378 _loopArray = _loopSizeLoad->base();
00379 }
00380 }
00381 return NULL;
00382 }
00383
00384
00385 void CompiledLoop::optimizeIntegerLoop() {
00386
00387 if (!OptimizeLoops) fatal("if OptimizeIntegerLoops is set, OptimizeLoops must be set too");
00388 if (!isIntegerLoop()) return;
00389
00390 PReg* u = _loopSizeLoad ? NULL : _upperBound;
00391 _loopHeader->activate(_loopVar, _lowerBound, u, _loopSizeLoad);
00392 _loopHeader->_integerLoop = true;
00393 removeTagChecks();
00394 checkForArraysDefinedInLoop();
00395 if (_loopArray) {
00396
00397 removeLoopVarOverflow();
00398
00399 removeBoundsChecks(_loopArray, _loopVar);
00400
00401 } else {
00402
00403 removeLoopVarOverflow();
00404 }
00405 }
00406
00407
00408
00409 class UntagClosure : public Closure<Use*> {
00410 public:
00411 CompiledLoop* theLoop;
00412 PReg* theLoopPReg;
00413 GrowableArray<klassOop>* smi_type;
00414
00415 UntagClosure(CompiledLoop* l, PReg* r) {
00416 theLoop = l; theLoopPReg = r; smi_type = new GrowableArray<klassOop>(1); smi_type->append(smiKlassObj);
00417 }
00418 void do_it(Use* u) {
00419 if (theLoop->isInLoop(u->node)) {
00420 u->node->assert_preg_type(theLoopPReg, smi_type, theLoop->loopHeader());
00421 }
00422 }
00423 };
00424
00425
00426 void CompiledLoop::removeTagChecks() {
00427
00428
00429 UntagClosure uc(this, _loopVar);
00430 _loopVar->forAllUsesDo(&uc);
00431 if (_lowerBound) {
00432 uc.theLoopPReg = _lowerBound;
00433 _lowerBound->forAllUsesDo(&uc);
00434 }
00435 uc.theLoopPReg = _upperBound;
00436 _upperBound->forAllUsesDo(&uc);
00437 }
00438
00439
00440 void CompiledLoop::removeLoopVarOverflow() {
00441
00442 Node* n = _incNode->next();
00443 assert(n->isBranchNode(), "must be branch");
00444 BranchNode* overflowCheck = (BranchNode*)n;
00445 assert(overflowCheck->op() == VSBranchOp, "should be overflow check");
00446 if (CompilerDebug || PrintLoopOpts) {
00447 cout(PrintLoopOpts)->print("*removing overflow check at node N%d\n", overflowCheck->id());
00448 }
00449 Node* taken = overflowCheck->next(1);
00450 taken->removeUpToMerge();
00451 overflowCheck->removeNext(taken);
00452 overflowCheck->eliminate(overflowCheck->bb(), NULL, true, false);
00453
00454
00455
00456 Node* a = overflowCheck->next();
00457 while (1) {
00458 if (a->nPredecessors() > 1) break;
00459 if (a->nSuccessors() > 1) break;
00460 if (a->isAssignNode()) {
00461 if (!a->deleted) {
00462 AssignNode* assign = (AssignNode*)a;
00463 if (assign->src() == _incNode->dest() && assign->dest() == _loopVar) {
00464 if (CompilerDebug || PrintLoopOpts) {
00465 cout(PrintLoopOpts)->print("*optimizing loopVar increment at N%d\n", _incNode->id());
00466 }
00467 _incNode->setDest(_incNode->bb(), _loopVar);
00468 assign->eliminate(assign->bb(), NULL, true, false);
00469 }
00470 }
00471 } else if (!a->isTrivial()) {
00472 compiler_warning("unexpected nontrivial node N%d after loopVar increment\n", a->id());
00473 }
00474 a = a->next();
00475 }
00476 }
00477
00478
00479 void CompiledLoop::checkForArraysDefinedInLoop() {
00480
00481 GrowableArray<AbstractArrayAtNode*> arraysToRemove(10);
00482 int len = _loopHeader->_arrayAccesses->length();
00483 for (int i = 0; i < len; i++) {
00484 AbstractArrayAtNode* n = _loopHeader->_arrayAccesses->at(i);
00485 if (defsInLoop(n->src())) arraysToRemove.append(n);
00486 }
00487 while (arraysToRemove.nonEmpty()) {
00488 AbstractArrayAtNode* n = arraysToRemove.pop();
00489 _loopHeader->_arrayAccesses->remove(n);
00490 }
00491 }
00492
00493
00494 void CompiledLoop::optimize() {
00495
00496 hoistTypeTests();
00497 findRegCandidates();
00498 }
00499
00500
00501 class TTHoister : public Closure<InlinedScope*> {
00502 public:
00503 GrowableArray<HoistedTypeTest*>* hoistableTests;
00504 CompiledLoop* theLoop;
00505
00506 TTHoister(CompiledLoop* l, GrowableArray<HoistedTypeTest*>* h) { hoistableTests = h; theLoop = l; }
00507
00508 void do_it(InlinedScope* s) {
00509 GrowableArray<NonTrivialNode*>* tests = s->typeTests();
00510 int len = tests->length();
00511 for (int i = 0; i < len; i++) {
00512 NonTrivialNode* n = tests->at(i);
00513 assert(n->doesTypeTests(), "shouldn't be in list");
00514 if (n->deleted) continue;
00515 if (n->hasUnknownCode()) continue;
00516 if (!theLoop->isInLoop(n)) continue;
00517 GrowableArray<PReg*> regs(4);
00518 GrowableArray<GrowableArray<klassOop>*> klasses(4);
00519 n->collectTypeTests(regs, klasses);
00520 for (int j = 0; j < regs.length(); j++) {
00521 PReg* r = regs.at(j);
00522 if (theLoop->defsInLoop(r) == 0) {
00523
00524 if (CompilerDebug || PrintLoopOpts) cout(PrintLoopOpts)->print("*moving type test of %s at N%d out of loop\n", r->name(), n->id());
00525 hoistableTests->append(new HoistedTypeTest(n, r, klasses.at(j)));
00526 }
00527 }
00528 }
00529 }
00530 };
00531
00532
00533 void CompiledLoop::hoistTypeTests() {
00534
00535 _loopHeader->_tests = _hoistableTests = new GrowableArray<HoistedTypeTest*>(10);
00536 TTHoister tth(this, _hoistableTests);
00537 _scope->subScopesDo(&tth);
00538
00539
00540
00541 GrowableArray<HoistedTypeTest*>* headerTests = new GrowableArray<HoistedTypeTest*>(_hoistableTests->length());
00542 for (int i = _hoistableTests->length() - 1; i >= 0; i--) {
00543 HoistedTypeTest* t = _hoistableTests->at(i);
00544 PReg* tested = t->testedPR;
00545 for (int j = headerTests->length() - 1; j >= 0; j--) {
00546 if (headerTests->at(j)->testedPR == tested) {
00547
00548 if (isEquivalentType(headerTests->at(j)->klasses, t->klasses)) {
00549
00550 } else {
00551
00552
00553 headerTests->at(j)->invalid = t->invalid = true;
00554 if (WizardMode) {
00555 compiler_warning("CompiledLoop::hoistTypeTests: PReg tested for different types\n");
00556 t->print();
00557 headerTests->at(j)->print();
00558 }
00559 }
00560 tested = NULL;
00561 break;
00562 }
00563 }
00564 if (tested) headerTests->append(t);
00565 }
00566
00567
00568 for (i = _hoistableTests->length() - 1; i >= 0; i--) {
00569 HoistedTypeTest* t = _hoistableTests->at(i);
00570 if (!t->invalid) {
00571 t->node->assert_preg_type(t->testedPR, t->klasses, _loopHeader);
00572 }
00573 }
00574 if (!_loopHeader->isActivated()) _loopHeader->activate();
00575 }
00576
00577 bool CompiledLoop::isEquivalentType(GrowableArray<klassOop>* klasses1, GrowableArray<klassOop>* klasses2) {
00578
00579 if (klasses1->length() != klasses2->length()) return false;
00580 for (int i = klasses2->length() - 1; i >= 0; i--) {
00581 if (klasses1->at(i) != klasses2->at(i)
00582 && (!klasses1->contains(klasses2->at(i)) || !klasses2->contains(klasses1->at(i))) ) {
00583 return false;
00584 }
00585 }
00586 return true;
00587 }
00588
00589
00590 class BoundsCheckRemover : public Closure<Use*> {
00591 public:
00592 CompiledLoop* theLoop;
00593 PReg* theLoopPReg;
00594 GrowableArray<AbstractArrayAtNode*>* theArrayList;
00595
00596 BoundsCheckRemover(CompiledLoop* l, PReg* r, GrowableArray<AbstractArrayAtNode*>* arrays) {
00597 theLoop = l; theLoopPReg = r; theArrayList = arrays;
00598 }
00599 void do_it(Use* u) {
00600 if (theLoop->isInLoop(u->node) &&
00601
00602
00603 theArrayList->contains((AbstractArrayAtNode*)u->node)) {
00604 u->node->assert_in_bounds(theLoopPReg, theLoop->loopHeader());
00605 }
00606 }
00607 };
00608
00609
00610 void CompiledLoop::removeBoundsChecks(PReg* array, PReg* var) {
00611
00612
00613
00614
00615 BoundsCheckRemover bcr(this, var, _loopHeader->_arrayAccesses);
00616 array->forAllUsesDo(&bcr);
00617 }
00618
00619 void CompiledLoop::findRegCandidates() {
00620
00621
00622
00623
00624
00625
00626 if (_bbs == NULL) _bbs = bbIterator->code_generation_order();
00627 GrowableArray<LoopRegCandidate*> candidates(PReg::currentNo, PReg::currentNo, NULL);
00628 const int len = _bbs->length();
00629 const BB* startBB = _startOfLoop->bb();
00630 int i;
00631 for (i = 0; _bbs->at(i) != startBB; i++) ;
00632 const BB* endBB = _endOfLoop->bb();
00633 int ncalls = 0;
00634
00635
00636 for (BB* bb = _bbs->at(i); bb != endBB; i++, bb = _bbs->at(i)) {
00637 const int n = bb->duInfo.info->length();
00638 if (bb->last->isCallNode()) ncalls++;
00639 for (int j = 0; j < n; j++) {
00640 DUInfo* info = bb->duInfo.info->at(j);
00641 PReg* r = info->reg;
00642 if (candidates.at(r->id()) == NULL) candidates.at_put(r->id(), new LoopRegCandidate(r));
00643 LoopRegCandidate* c = candidates.at(r->id());
00644 c->incDUs(info->uses.length(), info->defs.length());
00645 }
00646 }
00647 loopHeader()->set_nofCallsInLoop(ncalls);
00648
00649
00650 LoopRegCandidate* first = new LoopRegCandidate(NULL);
00651 LoopRegCandidate* second = new LoopRegCandidate(NULL);
00652 for (int j = candidates.length() - 1; j >= 0; j--) {
00653 LoopRegCandidate* c = candidates.at(j);
00654 if (c == NULL) continue;
00655 if (c->weight() > first->weight()) {
00656 second = first; first = c;
00657 } else if (c->weight() > second->weight()) {
00658 second = c;
00659 }
00660 }
00661
00662
00663 if (first->preg() != NULL) {
00664 loopHeader()->addRegisterCandidate(first);
00665 if (second->preg() != NULL) {
00666 loopHeader()->addRegisterCandidate(second);
00667 }
00668 } else {
00669 assert(second->preg() == NULL, "bad sorting");
00670 }
00671 }
00672
00673 void CompiledLoop::print() {
00674 std->print("((CompiledLoop*)%#x) = [N%d..N%d], cond = [N%d..N%d], body = [N%d..N%d] (bci %d..%d)\n",
00675 this, _firstNodeID, _lastNodeID, _startOfCond->id(), _endOfCond->id(),
00676 _startOfBody->id(), _endOfBody->id(),
00677 _startOfLoop->bci(), _endOfLoop->bci());
00678 std->print("\tloopVar=%s, lower=%s, upper=%s\n", _loopVar->safeName(), _lowerBound->safeName(), _upperBound->safeName());
00679 }
00680
00681
00682 HoistedTypeTest::HoistedTypeTest(NonTrivialNode* node, PReg* testedPR, GrowableArray<klassOop>* klasses) {
00683 this->node = node; this->testedPR = testedPR; this->klasses = klasses; invalid = false;
00684 }
00685
00686
00687 void HoistedTypeTest::print_test_on(outputStream* s) {
00688 s->print("%s = {", testedPR->name());
00689 int len = klasses->length();
00690 for (int j = 0; j < len; j++) {
00691 klassOop m = klasses->at(j);
00692 m->print_value_on(s);
00693 if (j < len - 1) s->print(",");
00694 }
00695 s->print("}");
00696 }
00697
00698
00699 void HoistedTypeTest::print() {
00700 std->print("((HoistedTypeTest*)%#x): ", this);
00701 print_test_on(std);
00702 std->cr();
00703 }
00704
00705 void LoopRegCandidate::print() {
00706 std->print("((LoopRegCandidate*)%#x): %s, %d uses, %d defs\n", this, _preg->name(), _nuses, _ndefs);
00707 }
00708
00709 # endif