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/_node.cpp.incl"
00028
00029 int BasicNode::currentID;
00030 int BasicNode::currentCommentID;
00031 int BasicNode::lastBCI;
00032 ScopeInfo BasicNode::lastScopeInfo;
00033 primitive_desc* InterruptCheckNode::_intrCheck;
00034
00035 int NodeFactory::cumulCost;
00036
00037
00038
00039
00040 PrologueNode* NodeFactory::new_PrologueNode(LookupKey* key, int nofArgs, int nofTemps) {
00041 PrologueNode* res = new PrologueNode(key, nofArgs, nofTemps);
00042 registerNode(res);
00043 return res;
00044 }
00045
00046 LoadOffsetNode* NodeFactory::new_LoadOffsetNode(PReg* dst, PReg* base, int offs, bool isArray) {
00047 LoadOffsetNode* res = new LoadOffsetNode(dst, base, offs, isArray);
00048 registerNode(res);
00049 return res;
00050 }
00051
00052 LoadUplevelNode* NodeFactory::new_LoadUplevelNode(PReg* dst, PReg* context0, int nofLevels, int offset, symbolOop name) {
00053 LoadUplevelNode* res = new LoadUplevelNode(dst, context0, nofLevels, offset, name);
00054 registerNode(res);
00055 return res;
00056 }
00057
00058 LoadIntNode* NodeFactory::new_LoadIntNode(PReg* dst, int value) {
00059 LoadIntNode* res = new LoadIntNode(dst, value);
00060 registerNode(res);
00061 return res;
00062 }
00063
00064 StoreOffsetNode* NodeFactory::new_StoreOffsetNode(PReg* src, PReg* base, int offs, bool needStoreCheck) {
00065 StoreOffsetNode* res = new StoreOffsetNode(src, base, offs, needStoreCheck);
00066 registerNode(res);
00067 return res;
00068 }
00069
00070 StoreUplevelNode* NodeFactory::new_StoreUplevelNode(PReg* src, PReg* context0, int nofLevels, int offset, symbolOop name, bool needStoreCheck) {
00071 StoreUplevelNode* res = new StoreUplevelNode(src, context0, nofLevels, offset, name, needStoreCheck);
00072 registerNode(res);
00073 return res;
00074 }
00075
00076 AssignNode* NodeFactory::new_AssignNode(PReg* src, PReg* dst) {
00077 AssignNode* res = new AssignNode(src, dst);
00078 registerNode(res);
00079 return res;
00080 }
00081
00082 ReturnNode* NodeFactory::new_ReturnNode(PReg* result, int bci) {
00083 ReturnNode* res = new ReturnNode(result, bci);
00084 registerNode(res);
00085 return res;
00086 }
00087
00088 InlinedReturnNode* NodeFactory::new_InlinedReturnNode(int bci, PReg* src, PReg* dst) {
00089 InlinedReturnNode* res = new InlinedReturnNode(bci, src, dst);
00090 registerNode(res);
00091 return res;
00092 }
00093
00094 NLRSetupNode* NodeFactory::new_NLRSetupNode(PReg* result, int bci) {
00095 NLRSetupNode* res = new NLRSetupNode(result, bci);
00096 registerNode(res);
00097 return res;
00098 }
00099
00100 NLRContinuationNode* NodeFactory::new_NLRContinuationNode(int bci) {
00101 InlinedScope* scope = theCompiler->currentScope();
00102 PReg* reg = new PReg(scope, NLRResultLoc, false, false);
00103 NLRContinuationNode* res = new NLRContinuationNode(bci, reg, reg);
00104 registerNode(res);
00105 return res;
00106 }
00107
00108 NLRTestNode* NodeFactory::new_NLRTestNode(int bci) {
00109 NLRTestNode* res = new NLRTestNode(bci);
00110 registerNode(res);
00111 theCompiler->nlrTestPoints->append(res);
00112 return res;
00113 }
00114
00115 ArithRRNode* NodeFactory::new_ArithRRNode(PReg* dst, PReg* src, ArithOpCode op, PReg* o2) {
00116 ArithRRNode* res = new ArithRRNode(op, src, o2, dst);
00117 registerNode(res);
00118 return res;
00119 }
00120
00121 ArithRCNode* NodeFactory::new_ArithRCNode(PReg* dst, PReg* src, ArithOpCode op, int o2) {
00122 ArithRCNode* res = new ArithRCNode(op, src, o2, dst);
00123 registerNode(res);
00124 return res;
00125 }
00126
00127 TArithRRNode* NodeFactory::new_TArithRRNode(PReg* dst, PReg* src, ArithOpCode op, PReg* o2, bool a1, bool a2) {
00128 TArithRRNode* res = new TArithRRNode(op, src, o2, dst, a1, a2);
00129 registerNode(res);
00130 return res;
00131 }
00132
00133 FloatArithRRNode* NodeFactory::new_FloatArithRRNode(PReg* dst, PReg* src, ArithOpCode op, PReg* o2) {
00134 FloatArithRRNode* res = new FloatArithRRNode(op, src, o2, dst);
00135 registerNode(res);
00136 return res;
00137 }
00138
00139 FloatUnaryArithNode* NodeFactory::new_FloatUnaryArithNode(PReg* dst, PReg* src, ArithOpCode op) {
00140 FloatUnaryArithNode* res = new FloatUnaryArithNode(op, src, dst);
00141 registerNode(res);
00142 return res;
00143 }
00144
00145 MergeNode* NodeFactory::new_MergeNode(Node* prev1, Node* prev2) {
00146 MergeNode* res = new MergeNode(prev1, prev2);
00147 registerNode(res);
00148 return res;
00149 }
00150
00151 MergeNode* NodeFactory::new_MergeNode(int bci) {
00152 MergeNode* res = new MergeNode(bci);
00153 registerNode(res);
00154 return res;
00155 }
00156
00157 SendNode* NodeFactory::new_SendNode(LookupKey* key, MergeNode* nlrTestPoint, GrowableArray<PReg*>* args,
00158 GrowableArray<PReg*>* expr_stack, bool superSend, SendInfo* info) {
00159 SendNode* res = new SendNode(key, nlrTestPoint, args, expr_stack, superSend, info);
00160 assert(expr_stack, "must have expression stack");
00161 res->scope()->addSend(expr_stack, true);
00162 registerNode(res);
00163 return res;
00164 }
00165
00166 PrimNode* NodeFactory::new_PrimNode(primitive_desc* pdesc, MergeNode* nlrTestPoint, GrowableArray<PReg*>* args,
00167 GrowableArray<PReg*>* expr_stack) {
00168 PrimNode* res = new PrimNode(pdesc, nlrTestPoint, args, expr_stack);
00169 if (pdesc->can_walk_stack()) {
00170 assert(expr_stack, "must have expression stack");
00171 if (expr_stack) res->scope()->addSend(expr_stack, true);
00172 } else {
00173 assert(expr_stack == NULL, "should not have expression stack");
00174 }
00175 registerNode(res);
00176 return res;
00177 }
00178
00179 DLLNode* NodeFactory::new_DLLNode(symbolOop dll_name, symbolOop function_name, dll_func function, bool async,
00180 MergeNode* nlrTestPoint, GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack) {
00181 DLLNode* res = new DLLNode(dll_name, function_name, function, async, nlrTestPoint, args, expr_stack);
00182 res->scope()->addSend(expr_stack, true);
00183 registerNode(res);
00184 return res;
00185 }
00186
00187 InterruptCheckNode* NodeFactory::new_InterruptCheckNode(GrowableArray<PReg*>* exprStack) {
00188 InterruptCheckNode* res = new InterruptCheckNode(exprStack);
00189 registerNode(res);
00190 return res;
00191 }
00192
00193 LoopHeaderNode* NodeFactory::new_LoopHeaderNode() {
00194 LoopHeaderNode* res = new LoopHeaderNode();
00195 registerNode(res);
00196 return res;
00197 }
00198
00199 BlockCreateNode* NodeFactory::new_BlockCreateNode(BlockPReg* b, GrowableArray<PReg*>* expr_stack) {
00200 BlockCreateNode* res = new BlockCreateNode(b, expr_stack);
00201 registerNode(res);
00202 return res;
00203 }
00204
00205 BlockMaterializeNode* NodeFactory::new_BlockMaterializeNode(BlockPReg* b, GrowableArray<PReg*>* expr_stack) {
00206 BlockMaterializeNode* res = new BlockMaterializeNode(b, expr_stack);
00207 registerNode(res);
00208 return res;
00209 }
00210
00211 ContextCreateNode* NodeFactory::new_ContextCreateNode(PReg* parent, PReg* context, int nofTemps, GrowableArray<PReg*>* expr_stack) {
00212 ContextCreateNode* res = new ContextCreateNode(parent, context, nofTemps, expr_stack);
00213 registerNode(res);
00214 return res;
00215 }
00216
00217 ContextCreateNode* NodeFactory::new_ContextCreateNode(PReg* b, const ContextCreateNode* n, GrowableArray<PReg*>* expr_stack) {
00218 ContextCreateNode* res = new ContextCreateNode(b, n, expr_stack);
00219 registerNode(res);
00220 return res;
00221 }
00222
00223 ContextInitNode* NodeFactory::new_ContextInitNode(ContextCreateNode* creator) {
00224 ContextInitNode* res = new ContextInitNode(creator);
00225 registerNode(res);
00226 return res;
00227 }
00228
00229 ContextInitNode* NodeFactory::new_ContextInitNode(PReg* b, const ContextInitNode* n) {
00230 ContextInitNode* res = new ContextInitNode(b, n);
00231 registerNode(res);
00232 return res;
00233 }
00234
00235 ContextZapNode* NodeFactory::new_ContextZapNode(PReg* context) {
00236 ContextZapNode* res = new ContextZapNode(context);
00237 registerNode(res);
00238 return res;
00239 }
00240
00241 BranchNode* NodeFactory::new_BranchNode(BranchOpCode op, bool taken_is_uncommon) {
00242 BranchNode* res = new BranchNode(op, taken_is_uncommon);
00243 registerNode(res);
00244 return res;
00245 }
00246
00247 TypeTestNode* NodeFactory::new_TypeTestNode(PReg* recv, GrowableArray<klassOop>* classes, bool hasUnknown) {
00248 TypeTestNode* res = new TypeTestNode(recv, classes, hasUnknown);
00249 registerNode(res);
00250 res->scope()->addTypeTest(res);
00251 return res;
00252 }
00253
00254 ArrayAtNode* NodeFactory::new_ArrayAtNode(ArrayAtNode::AccessType access_type, PReg* array, PReg* index, bool smiIndex,
00255 PReg* result, PReg* error, int data_offset, int length_offset) {
00256 ArrayAtNode* res = new ArrayAtNode(access_type, array, index, smiIndex, result, error, data_offset, length_offset);
00257 registerNode(res);
00258 return res;
00259 }
00260
00261 ArrayAtPutNode* NodeFactory::new_ArrayAtPutNode(ArrayAtPutNode::AccessType access_type, PReg* array, PReg* index, bool smi_index,
00262 PReg* element, bool smi_element, PReg* result, PReg* error, int data_offset, int length_offset,
00263 bool needs_store_check) {
00264 ArrayAtPutNode* res = new ArrayAtPutNode(access_type, array, index, smi_index, element, smi_element, result, error, data_offset, length_offset, needs_store_check);
00265 registerNode(res);
00266 return res;
00267 }
00268
00269 InlinedPrimitiveNode* NodeFactory::new_InlinedPrimitiveNode(InlinedPrimitiveNode::Operation op, PReg* result, PReg* error,
00270 PReg* recv, PReg* arg1, bool arg1_is_smi, PReg* arg2, bool arg2_is_smi) {
00271 InlinedPrimitiveNode* res = new InlinedPrimitiveNode(op, result, error, recv, arg1, arg1_is_smi, arg2, arg2_is_smi);
00272 registerNode(res);
00273 return res;
00274 }
00275
00276 UncommonNode* NodeFactory::new_UncommonNode(GrowableArray<PReg*>* exprStack, int bci) {
00277 UncommonNode* res = new UncommonNode(exprStack, bci);
00278 registerNode(res);
00279 assert(exprStack, "must have expr. stack");
00280 res->scope()->addSend(exprStack, false);
00281 return res;
00282 }
00283
00284 FixedCodeNode* NodeFactory::new_FixedCodeNode(FixedCodeNode::FixedCodeKind k) {
00285 FixedCodeNode* res = new FixedCodeNode(k);
00286 registerNode(res);
00287 return res;
00288 }
00289
00290 NopNode* NodeFactory::new_NopNode() {
00291 NopNode* res = new NopNode();
00292 registerNode(res);
00293 return res;
00294 }
00295
00296 CommentNode* NodeFactory::new_CommentNode(char* comment) {
00297 CommentNode* res = new CommentNode(comment);
00298 registerNode(res);
00299 return res;
00300 }
00301
00302
00303
00304 void initNodes() {
00305 Node::currentID = Node::currentCommentID = 0;
00306 Node::lastScopeInfo = (ScopeInfo)-1;
00307 Node::lastBCI = IllegalBCI;
00308 NodeFactory::cumulCost = 0;
00309 }
00310
00311
00312 void BasicNode::setScope(InlinedScope* s) {
00313 _scope = s;
00314 _bci = s ? s->bci() : IllegalBCI;
00315 assert(!s || !s->isInlinedScope() || s->bci() <= ((InlinedScope*)s)->nofBytes(), "illegal bci");
00316 }
00317
00318
00319 BasicNode::BasicNode() {
00320 _id = currentID++; _bb = NULL;
00321 setScope(theCompiler->currentScope());
00322 _num = -1;
00323 dontEliminate = deleted = false;
00324 _mapping = NULL;
00325 }
00326
00327
00328 PRegMapping* BasicNode::mapping() const {
00329 return new PRegMapping(_mapping);
00330 }
00331
00332
00333 void BasicNode::setMapping(PRegMapping* mapping) {
00334 assert(!hasMapping(), "cannot be assigned twice");
00335 _mapping = new PRegMapping(mapping);
00336 }
00337
00338
00339 NonTrivialNode::NonTrivialNode() {
00340 _src = _dest = NULL;
00341 srcUse = NULL; destDef = NULL;
00342 }
00343
00344
00345 LoadUplevelNode::LoadUplevelNode(PReg* dst, PReg* context0, int nofLevels, int offset, symbolOop name) : LoadNode(dst) {
00346 assert(context0 != NULL, "context0 is NULL");
00347 assert(nofLevels >= 0 , "nofLevels must be >= 0");
00348 assert(offset >= 0 , "offset must be >= 0");
00349 _context0 = context0; _context0Use = NULL;
00350 _nofLevels = nofLevels;
00351 _offset = offset;
00352 _name = name;
00353 }
00354
00355
00356 StoreUplevelNode::StoreUplevelNode(PReg* src, PReg* context0, int nofLevels, int offset, symbolOop name, bool needsStoreCheck)
00357 : StoreNode(src) {
00358 assert(context0 != NULL, "context0 is NULL");
00359 assert(nofLevels >= 0 , "nofLevels must be >= 0");
00360 assert(offset >= 0 , "offset must be >= 0");
00361 _context0 = context0;
00362 _nofLevels = nofLevels;
00363 _offset = offset;
00364 _needsStoreCheck = needsStoreCheck;
00365 _name = name;
00366 }
00367
00368
00369 AssignNode::AssignNode(PReg* s, PReg* d) : StoreNode(s) {
00370 _dest = d; assert(d, "dest is NULL");
00371
00372 assert(s != d, "creating dummy assignment");
00373 }
00374
00375
00376 CommentNode::CommentNode(char* s) {
00377 comment = s;
00378
00379
00380 _id = --currentCommentID; currentID--;
00381 }
00382
00383
00384 ArrayAtNode::ArrayAtNode(AccessType access_type, PReg* array, PReg* index, bool smiIndex,
00385 PReg* result, PReg* error, int data_offset, int length_offset)
00386 : AbstractArrayAtNode(array, index, smiIndex, result, error, data_offset, length_offset) {
00387 _access_type = access_type;
00388 }
00389
00390
00391 ArrayAtPutNode::ArrayAtPutNode(AccessType access_type, PReg* array, PReg* index, bool smi_index,
00392 PReg* element, bool smi_element, PReg* result, PReg* error, int data_offset, int length_offset,
00393 bool needs_store_check)
00394 : AbstractArrayAtPutNode(array, index, smi_index, element, result, error, data_offset, length_offset) {
00395 _access_type = access_type;
00396 _needs_store_check = needs_store_check;
00397 _smi_element = smi_element;
00398 _needs_element_range_check = (access_type == byte_at_put || access_type == double_byte_at_put);
00399 }
00400
00401
00402 TypeTestNode::TypeTestNode(PReg* rr, GrowableArray<klassOop>* classes, bool hasUnknown) {
00403 _src = rr;
00404 _classes = classes;
00405 _hasUnknown = hasUnknown;
00406 int len = classes->length();
00407 assert(len > 0, "should have at least one class to test");
00408
00409
00410
00411
00412 if ((len == 1) && !hasUnknown) {
00413 warning("TypeTestNode with only one klass & no uncommon case => performance bug");
00414 }
00415 # ifdef ASSERT
00416 for (int i = 0; i < len; i++) {
00417 for (int j = i + 1; j < len; j++) {
00418 assert(classes->at(i) != classes->at(j), "duplicate class");
00419 }
00420 }
00421 # endif
00422 }
00423
00424
00425 ArithRRNode::ArithRRNode(ArithOpCode op, PReg* arg1, PReg* arg2, PReg* dst) : ArithNode(op, arg1, dst) {
00426 _oper = arg2;
00427 if (_src->isConstPReg() && ArithOpIsCommutative[_op]) {
00428
00429 PReg* t1 = _src; _src = _oper; _oper = t1;
00430 }
00431 }
00432
00433
00434 TArithRRNode::TArithRRNode(ArithOpCode op, PReg* arg1, PReg* arg2, PReg* dst, bool arg1IsInt, bool arg2IsInt) {
00435 if (arg1->isConstPReg() && ArithOpIsCommutative[op]) {
00436
00437 PReg* t1 = arg1; arg1 = arg2; arg2 = t1;
00438 bool t2 = arg1IsInt; arg1IsInt = arg2IsInt; arg2IsInt = t2;
00439 }
00440 _op = op;
00441 _src = arg1;
00442 _oper = arg2;
00443 _dest = dst;
00444 _arg1IsInt = arg1IsInt;
00445 _arg2IsInt = arg2IsInt;
00446 _constResult = NULL;
00447 dontEliminate = true;
00448 }
00449
00450
00451 PReg* NonTrivialNode::dest() const {
00452 if (!hasDest()) fatal("has no dest");
00453 return _dest;
00454 }
00455
00456
00457 void NonTrivialNode::setDest(BB* bb, PReg* d) {
00458
00459 if (!hasDest()) fatal("has no dest");
00460 assert(bb || !destDef, "shouldn't have a def");
00461 if (destDef) _dest->removeDef(bb, destDef);
00462 _dest = d;
00463 if (bb) destDef = _dest->addDef(bb, (NonTrivialNode*)this);
00464 }
00465
00466
00467 PReg* NonTrivialNode::src() const {
00468 if (!hasSrc()) fatal("has no src");
00469 return _src;
00470 }
00471
00472
00473 bool AssignNode::isAccessingFloats() const {
00474
00475
00476
00477
00478 return
00479 _src ->loc.isFloatLocation() || _src ->loc == topOfFloatStack || Mapping::isFloatTemporary(_src ->loc) ||
00480 _dest->loc.isFloatLocation() || _dest->loc == topOfFloatStack || Mapping::isFloatTemporary(_dest->loc) ;
00481 }
00482
00483
00484 oop AssignNode::constantSrc() const {
00485 assert(hasConstantSrc(), "no constant src");
00486 return ((ConstPReg*)_src)->constant;
00487 }
00488
00489
00490 bool AssignNode::canBeEliminated() const {
00491 return !(_src->loc.isTopOfStack() || _dest->loc.isTopOfStack());
00492 }
00493
00494
00495 bool Node::endsBB() const {
00496 return next() == NULL || next()->startsBB();
00497 }
00498
00499 void Node::removeMe() {
00500 assert(hasSingleSuccessor() && hasSinglePredecessor(), "subclass");
00501 if (_prev) _prev->moveNext(this, _next);
00502 if (_next) _next->movePrev(this, _prev);
00503 _prev = _next = NULL;
00504 }
00505
00506 void Node::removePrev(Node* n) {
00507
00508 assert(hasSinglePredecessor(), "subclass");
00509 assert(_prev == n, "should be same");
00510 _prev = NULL;
00511 }
00512
00513 void Node::removeNext(Node* n) {
00514
00515 assert(hasSingleSuccessor(), "subclass");
00516 assert(_next == n, "should be same");
00517 n->removePrev(this);
00518 _next = NULL;
00519 }
00520
00521 Node* Node::endOfList() const {
00522 if (_next == NULL) return (Node*)this;
00523 for (Node* n = _next; n->_next; n = n->_next) {
00524 assert(n->hasSingleSuccessor(), ">1 successors");
00525 }
00526 return n;
00527 }
00528
00529 void AbstractMergeNode::removeMe() {
00530 if (hasSinglePredecessor()) {
00531 _prev = firstPrev();
00532 TrivialNode::removeMe();
00533 } else {
00534 fatal("not implemented yet");
00535 }
00536 }
00537
00538 void AbstractMergeNode::movePrev(Node* from, Node* to) {
00539 for (int i = _prevs->length() - 1; i >= 0; i--) {
00540 if (_prevs->at(i) == from) { _prevs->at_put(i, to); return; }
00541 }
00542 fatal("from not found");
00543 }
00544
00545 bool AbstractMergeNode::isPredecessor(const Node* n) const {
00546 for (int i = _prevs->length() - 1; i >= 0; i--) {
00547 if (_prevs->at(i) == n) return true;
00548 }
00549 return false;
00550 }
00551
00552 void AbstractBranchNode::removeMe() {
00553 if (hasSingleSuccessor()) {
00554 if (!_next && _nxt->nonEmpty()) { _next = next1(); _nxt->pop(); }
00555 NonTrivialNode::removeMe();
00556 } else {
00557 fatal("not implemented yet");
00558 }
00559 }
00560
00561 void AbstractBranchNode::removeNext(Node* n) {
00562
00563 if (n == _next) {
00564 n->removePrev(this);
00565 _next = NULL;
00566 } else {
00567 for (int i = 0; i < _nxt->length() && _nxt->at(i) != n; i++) ;
00568 assert(i < _nxt->length(), "not found");
00569 n->removePrev(this);
00570 for ( ; i < _nxt->length() - 1; i++) _nxt->at_put(i, _nxt->at(i+1));
00571 _nxt->pop();
00572 }
00573 }
00574
00575 void AbstractBranchNode::setNext(int i, Node* n) {
00576 if (i == 0) {
00577 setNext(n);
00578 } else {
00579 assert(_nxt->length() == i - 1, "wrong index");
00580 _nxt->append(n);
00581 }
00582 }
00583
00584 void AbstractBranchNode::moveNext(Node* from, Node* to) {
00585 if (_next == from) {
00586 _next = to;
00587 } else {
00588 for (int i = 0; i < _nxt->length() && _nxt->at(i) != from; i++) ;
00589 assert(i < _nxt->length(), "not found");
00590 _nxt->at_put(i, to);
00591 }
00592 }
00593
00594 bool AbstractBranchNode::isSuccessor(const Node* n) const {
00595 if (_next == n) {
00596 return true;
00597 } else {
00598 for (int i = 0; i < _nxt->length() && _nxt->at(i) != n; i++) ;
00599 return i < _nxt->length();
00600 }
00601 }
00602
00603 BB* BasicNode::newBB() {
00604 if (_bb == NULL) {
00605 int len = 0;
00606 _bb = new BB((Node*)this, (Node*)this, 1);
00607 for (Node* n = (Node*)this; !n->endsBB() && n->next() != NULL; n = n->next()) {
00608 n->_num = len++; n->_bb = _bb;
00609 }
00610 n->_num = len++; n->_bb = _bb;
00611 _bb->last = n;
00612 _bb->nnodes = len;
00613 }
00614 return _bb;
00615 }
00616
00617
00618 MergeNode::MergeNode(Node* prev1, Node* prev2) : AbstractMergeNode(prev1, prev2) {
00619 _bci = max(prev1->bci(), prev2->bci());
00620 isLoopStart = isLoopEnd = didStartBB = false;
00621 }
00622
00623
00624 MergeNode::MergeNode(int bci) {
00625 _bci = bci;
00626 isLoopStart = isLoopEnd = didStartBB = false;
00627 }
00628
00629
00630 BB* MergeNode::newBB() {
00631 if (_bb == NULL) {
00632
00633 didStartBB = true;
00634 _bb = Node::newBB();
00635 }
00636 return _bb;
00637 }
00638
00639
00640 ReturnNode::ReturnNode(PReg* res, int bci)
00641 : AbstractReturnNode(
00642 bci,
00643 res,
00644 new TempPReg(theCompiler->currentScope(), resultLoc, true, true)
00645 ) {
00646 assert(res->loc == resultLoc, "must be in special location");
00647 }
00648
00649
00650 NLRSetupNode::NLRSetupNode(PReg* result, int bci)
00651 : AbstractReturnNode(
00652 bci,
00653 result,
00654 new TempPReg(theCompiler->currentScope(), resultLoc, true, true)
00655 ) {
00656 contextUse = resultUse = NULL;
00657 assert(result->loc == NLRResultLoc, "must be in special location");
00658 }
00659
00660
00661 MergeNode* CallNode::nlrTestPoint() const {
00662 if (nSuccessors() > 1) {
00663 assert(next1()->isMergeNode(), "should be a merge");
00664 return (MergeNode*)next1();
00665 } else {
00666 return NULL;
00667 }
00668 }
00669
00670
00671 CallNode::CallNode(MergeNode* n, GrowableArray<PReg*>* a, GrowableArray<PReg*>* e) {
00672 if (n != NULL) append1(n);
00673 exprStack = e;
00674 args = a;
00675 _dest = new SAPReg(scope(), resultLoc, false, false, _bci, _bci);
00676 argUses = uplevelUses = NULL;
00677 uplevelDefs = NULL;
00678 uplevelUsed = uplevelDefd = NULL;
00679 nblocks = theCompiler->blockClosures->length();
00680 }
00681
00682
00683 SendNode::SendNode(
00684 LookupKey* key,
00685 MergeNode* nlrTestPoint,
00686 GrowableArray<PReg*>* args,
00687 GrowableArray<PReg*>* expr_stack,
00688 bool superSend,
00689 SendInfo* info
00690 )
00691 : CallNode(nlrTestPoint, args, expr_stack) {
00692 _key = key;
00693 _superSend = superSend; _info = info;
00694 assert(exprStack, "should have expr stack");
00695
00696
00697 if (_superSend && !UseNewBackend) warning("We cannot yet have super sends in nmethods");
00698 }
00699
00700
00701 ContextCreateNode::ContextCreateNode(PReg* parent, PReg* context, int nofTemps, GrowableArray<PReg*>* expr_stack)
00702 : PrimNode(primitives::context_allocate(), NULL, NULL, expr_stack) {
00703 _src = parent;
00704 _dest = context;
00705 _nofTemps = nofTemps;
00706 _contextSize = 0;
00707 _parentContexts = NULL;
00708 _parentContextUses = NULL;
00709 Scope* p = _scope->parent();
00710 PReg* prevContext = parent;
00711
00712 while (p && p->isInlinedScope() && ((InlinedScope*)p)->context()) {
00713 PReg* c = ((InlinedScope*)p)->context();
00714 if (c != prevContext) {
00715 if (!_parentContexts) _parentContexts = new GrowableArray<PReg*>(5);
00716 _parentContexts->append(c);
00717 prevContext = c;
00718 }
00719 p = p->parent();
00720 }
00721 }
00722
00723
00724 ContextCreateNode::ContextCreateNode(PReg* b, const ContextCreateNode* n, GrowableArray<PReg*>* expr_stack)
00725 : PrimNode(primitives::context_allocate(), NULL, NULL, expr_stack) {
00726 warning("check this implementation");
00727 Unimplemented();
00728
00729
00730
00731
00732 _dest = b;
00733 _nofTemps = n->_nofTemps;
00734 _parentContextUses = NULL;
00735 }
00736
00737
00738 ContextInitNode::ContextInitNode(ContextCreateNode* creator) {
00739 int nofTemps = creator->nofTemps();
00740 _src = creator->context();
00741 assert(_src, "must have context");
00742 _initializers = new GrowableArray<Expr*>(nofTemps, nofTemps, NULL);
00743 _contentDefs = NULL;
00744 _initializerUses = NULL;
00745 _materializedBlocks = NULL;
00746 }
00747
00748
00749 ContextInitNode::ContextInitNode(PReg* b, const ContextInitNode* node) {
00750 _src = b;
00751 assert(_src, "must have context");
00752 _initializers = node->_initializers;
00753 assert((node->_contentDefs == NULL) && (node->_initializerUses == NULL), "shouldn't copy after uses have been built");
00754 _contentDefs = NULL;
00755 _initializerUses = NULL;
00756 _materializedBlocks = NULL;
00757 }
00758
00759
00760 BlockCreateNode::BlockCreateNode(BlockPReg* b, GrowableArray<PReg*>* expr_stack) :
00761 PrimNode(primitives::block_allocate(), NULL, NULL, expr_stack) {
00762 _src = NULL;
00763 _dest = b;
00764 _contextUse = NULL;
00765 switch (b->method()->block_info()) {
00766 case methodOopDesc::expects_nil:
00767 _context = NULL; break;
00768 case methodOopDesc::expects_self:
00769 _context = b->scope()->self()->preg(); break;
00770 case methodOopDesc::expects_parameter:
00771 _context = NULL;
00772 break;
00773 case methodOopDesc::expects_context:
00774 _context = b->scope()->context(); break;
00775 default:
00776 fatal("unexpected incoming info");
00777 };
00778 }
00779
00780
00781 int ContextInitNode::positionOfContextTemp(int n) const {
00782
00783 int pos = 0;
00784 for (int i = 0; i < n; i++) {
00785 PReg* p = contents()->at(i)->preg();
00786 if (p->loc.isContextLocation()) pos++;
00787 }
00788 return pos;
00789 }
00790
00791 void ContextInitNode::initialize(int no, Expr* expr) {
00792 assert((_initializers->at(no) == NULL) || (_initializers->at(no)->constant() == nilObj),
00793 "already initialized this context element");
00794 _initializers->at_put(no, expr);
00795 }
00796
00797
00798 ContextCreateNode* ContextInitNode::creator() const {
00799
00800 Node* n = _prev;
00801 assert(n->isContextCreateNode(), "must be creator node");
00802 return (ContextCreateNode*)n;
00803 }
00804
00805
00806 void ContextInitNode::addBlockMaterializer(BlockMaterializeNode* n) {
00807 if (!_materializedBlocks) _materializedBlocks = new GrowableArray<BlockMaterializeNode*>(5);
00808 _materializedBlocks->append(n);
00809 }
00810
00811 void ContextInitNode::notifyNoContext() {
00812
00813
00814
00815 _src->removeUse(bb(), srcUse);
00816 _src = NULL;
00817 if (_materializedBlocks) {
00818 for (int i = _materializedBlocks->length() - 1; i >= 0; i--) {
00819
00820 BlockMaterializeNode* n = _materializedBlocks->at(i);
00821 n->eliminate(n->bb(), NULL, true, false);
00822 PReg* blk = n->src();
00823 assert(blk->isBlockPReg(), "must be a block");
00824
00825
00826 for (int j = _initializers->length() - 1; j >= 0; j--) {
00827 if (_initializers->at(j)->preg() == blk) {
00828 blk->removeUse(_bb, _initializerUses->at(j));
00829 break;
00830 }
00831 }
00832
00833
00834 if (blk->hasNoUses()) {
00835
00836 blk->eliminate(false);
00837 }
00838 }
00839 }
00840 }
00841
00842
00843 PrimNode::PrimNode(primitive_desc* pdesc, MergeNode* nlrTestPoint, GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack)
00844 : CallNode(nlrTestPoint, args, expr_stack) {
00845 _pdesc = pdesc;
00846 assert(_pdesc->can_perform_NLR() || (nlrTestPoint == NULL), "no NLR target needed");
00847 if (pdesc->can_invoke_delta()) {
00848 assert(expr_stack != NULL, "should have expr stack");
00849 } else {
00850
00851
00852
00853 exprStack = NULL;
00854 }
00855 }
00856
00857
00858 InlinedPrimitiveNode::InlinedPrimitiveNode(Operation op, PReg* result, PReg* error,
00859 PReg* recv, PReg* arg1, bool arg1_is_smi, PReg* arg2, bool arg2_is_smi) {
00860 _op = op;
00861 _dest = result;
00862 _error = error;
00863 _src = recv;
00864 _arg1 = arg1;
00865 _arg2 = arg2;
00866 _arg1_is_smi = arg1_is_smi;
00867 _arg2_is_smi = arg2_is_smi;
00868 }
00869
00870
00871 bool InlinedPrimitiveNode::canFail() const {
00872 switch (op()) {
00873 case obj_klass : return false;
00874 case obj_hash : return false;
00875 case proxy_byte_at : return !arg1_is_smi();
00876 case proxy_byte_at_put: return !arg1_is_smi() || !arg2_is_smi();
00877 };
00878 ShouldNotReachHere();
00879 return false;
00880 }
00881
00882
00883 bool InlinedPrimitiveNode::canBeEliminated() const {
00884 switch (op()) {
00885 case obj_klass : return true;
00886 case obj_hash : return true;
00887 case proxy_byte_at : return !canFail();
00888 case proxy_byte_at_put: return false;
00889 };
00890 ShouldNotReachHere();
00891 return false;
00892 }
00893
00894
00895 UncommonNode::UncommonNode(GrowableArray<PReg*>* e, int bci) { exprStack = e; _bci = bci;}
00896
00897
00898 bool PrimNode::canBeEliminated() const {
00899 if (!Node::canBeEliminated()) return false;
00900 if (_pdesc->can_be_constant_folded() && !canFail()) return true;
00901
00902
00903
00904 if (_pdesc->can_be_constant_folded()) return true;
00905 if (_pdesc->fn() == fntype(&behaviorPrimitives::allocate) ||
00906 _pdesc->fn() == fntype(&primitiveNew0) ||
00907 _pdesc->fn() == fntype(&primitiveNew1) ||
00908 _pdesc->fn() == fntype(&primitiveNew2) ||
00909 _pdesc->fn() == fntype(&primitiveNew3) ||
00910 _pdesc->fn() == fntype(&primitiveNew4) ||
00911 _pdesc->fn() == fntype(&primitiveNew5) ||
00912 _pdesc->fn() == fntype(&primitiveNew6) ||
00913 _pdesc->fn() == fntype(&primitiveNew7) ||
00914 _pdesc->fn() == fntype(&primitiveNew8) ||
00915 _pdesc->fn() == fntype(&primitiveNew9)
00916 ) {
00917 return true;
00918 }
00919 return false;
00920 }
00921
00922 bool PrimNode::canInvokeDelta() const {
00923 return _pdesc->can_invoke_delta();
00924 }
00925
00926 bool PrimNode::canFail() const {
00927 return _pdesc->can_fail();
00928 }
00929
00930
00931 DLLNode::DLLNode(symbolOop dll_name, symbolOop function_name, dll_func function, bool async,
00932 MergeNode* nlrTestPoint, GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack)
00933 : CallNode(nlrTestPoint, args, expr_stack) {
00934 _dll_name = dll_name;
00935 _function_name = function_name;
00936 _function = function;
00937 _async = async;
00938 }
00939
00940
00941 bool DLLNode::canInvokeDelta() const {
00942 return true;
00943 }
00944
00945
00946 NLRTestNode::NLRTestNode(int bci) {}
00947
00948
00949 void NLRTestNode::fixup() {
00950
00951 if (scope()->isTop()) {
00952 theCompiler->enterScope(scope());
00953
00954 append(0, NodeFactory::new_NLRContinuationNode(bci()));
00955
00956 PReg* nlr_result = new TempPReg(scope(), resultOfNLR, true, true);
00957 Node* n = NodeFactory::new_AssignNode(nlr_result, scope()->resultPR);
00958 append(1, n);
00959 n->append(scope()->returnPoint());
00960 theCompiler->exitScope(scope());
00961 } else {
00962
00963
00964
00965 InlinedScope* s = scope()->sender();
00966 while (!s->has_nlrTestPoint()) s = s->sender();
00967 append(0, s->nlrTestPoint());
00968
00969
00970 s = scope();
00971 while (s->returnPoint() == NULL) s = s->sender();
00972 theCompiler->enterScope(s);
00973 PReg* nlr_result = new TempPReg(scope(), resultOfNLR, true, true);
00974 Node* n = NodeFactory::new_AssignNode(nlr_result, s->resultPR);
00975 theCompiler->exitScope(s);
00976 append(1, n);
00977 n->append(s->returnPoint());
00978 }
00979 }
00980
00981
00982 bool SendNode::isCounting() const { return _info->counting; }
00983 bool SendNode::isUninlinable() const { return _info->uninlinable; }
00984 bool SendNode::staticReceiver() const { return _info->receiverStatic; }
00985
00986 PReg* SendNode::recv() const {
00987 int i = args->length() - 1;
00988 while (i >= 0 && args->at(i)->loc != receiverLoc) i--;
00989 assert(i >= 0, "must have a receiver");
00990 return args->at(i);
00991 }
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 Node* BasicNode::copy(PReg* from, PReg* to) const {
01003 Node* c = clone(from, to);
01004 if (c) { c->_scope = _scope; c->_bci = _bci; }
01005 return c;
01006 }
01007
01008 # define SHOULD_NOT_CLONE { Unused(from); Unused(to); ShouldNotCallThis(); return NULL; }
01009 # define TRANSLATE(s) ((s == from) ? to : s)
01010
01011 Node* PrologueNode::clone (PReg* from, PReg* to) const { SHOULD_NOT_CLONE }
01012 Node* NLRSetupNode::clone (PReg* from, PReg* to) const { SHOULD_NOT_CLONE }
01013 Node* NLRContinuationNode::clone(PReg* from, PReg* to) const { SHOULD_NOT_CLONE }
01014 Node* ReturnNode::clone (PReg* from, PReg* to) const { SHOULD_NOT_CLONE }
01015 Node* BranchNode::clone (PReg* from, PReg* to) const { SHOULD_NOT_CLONE }
01016 Node* TypeTestNode::clone (PReg* from, PReg* to) const { SHOULD_NOT_CLONE }
01017 Node* FixedCodeNode::clone (PReg* from, PReg* to) const { SHOULD_NOT_CLONE }
01018
01019 Node* LoadOffsetNode::clone(PReg* from, PReg* to) const {
01020 return NodeFactory::new_LoadOffsetNode(TRANSLATE(_dest), _src, offset, isArraySize);
01021 }
01022 Node* LoadIntNode::clone(PReg* from, PReg* to) const {
01023 return NodeFactory::new_LoadIntNode(TRANSLATE(_dest), _value);
01024 }
01025 Node* LoadUplevelNode::clone(PReg* from, PReg* to) const {
01026 return NodeFactory::new_LoadUplevelNode(TRANSLATE(_dest), TRANSLATE(_context0), _nofLevels, _offset, _name);
01027 }
01028 Node* StoreOffsetNode::clone(PReg* from, PReg* to) const {
01029 return NodeFactory::new_StoreOffsetNode(TRANSLATE(_src), _base, _offset, _needsStoreCheck);
01030 }
01031 Node* StoreUplevelNode::clone(PReg* from, PReg* to) const {
01032 return NodeFactory::new_StoreUplevelNode(TRANSLATE(_src), TRANSLATE(_context0), _nofLevels, _offset, _name, _needsStoreCheck);
01033 }
01034 Node* AssignNode::clone(PReg* from, PReg* to) const {
01035 return NodeFactory::new_AssignNode(TRANSLATE(_src), TRANSLATE(_dest));
01036 }
01037 Node* ArithRRNode::clone(PReg* from, PReg* to) const {
01038 return NodeFactory::new_ArithRRNode(TRANSLATE(_dest), TRANSLATE(_src), _op, _oper);
01039 }
01040 Node* TArithRRNode::clone(PReg* from, PReg* to) const {
01041 return NodeFactory::new_TArithRRNode(TRANSLATE(_dest), TRANSLATE(_src), _op, _oper, _arg1IsInt, _arg2IsInt);
01042 }
01043 Node* ArithRCNode::clone(PReg* from, PReg* to) const {
01044 return NodeFactory::new_ArithRCNode(TRANSLATE(_dest), TRANSLATE(_src), _op, _oper);
01045 }
01046
01047 Node* SendNode::clone(PReg* from, PReg* to) const {
01048 Unused(from); Unused(to);
01049
01050 SendNode* n = NodeFactory::new_SendNode(_key, nlrTestPoint(), args, exprStack, _superSend, _info);
01051 n->_dest = _dest;
01052 return n;
01053 }
01054
01055 Node* PrimNode::clone(PReg* from, PReg* to) const {
01056
01057 PrimNode* n = NodeFactory::new_PrimNode(_pdesc, nlrTestPoint(), args, exprStack);
01058 assert(_dest != from, "shouldn't change dest");
01059 n->_dest = _dest;
01060 return n;
01061 }
01062
01063 Node* DLLNode::clone(PReg* from, PReg* to) const {
01064
01065 DLLNode* n = NodeFactory::new_DLLNode(_dll_name, _function_name, _function, _async, nlrTestPoint(), args, exprStack);
01066 assert(_dest != from, "shouldn't change dest");
01067 n->_dest = _dest;
01068 return n;
01069 }
01070
01071
01072 Node* InterruptCheckNode::clone(PReg* from, PReg* to) const {
01073 Unused(from); Unused(to);
01074
01075 InterruptCheckNode* n = NodeFactory::new_InterruptCheckNode(exprStack);
01076 assert(_dest != from, "shouldn't change dest");
01077 n->_dest = _dest;
01078 return n;
01079 }
01080
01081
01082 Node* BlockCreateNode::clone(PReg* from, PReg* to) const {
01083
01084 BlockCreateNode* n = NodeFactory::new_BlockCreateNode((BlockPReg*)TRANSLATE(block()), exprStack);
01085 assert(_dest != from, "shouldn't change dest");
01086 n->_dest = _dest;
01087 return n;
01088 }
01089
01090
01091 Node* BlockMaterializeNode::clone(PReg* from, PReg* to) const {
01092
01093 BlockMaterializeNode* n = NodeFactory::new_BlockMaterializeNode((BlockPReg*)TRANSLATE(block()), exprStack);
01094 assert(_dest != from, "shouldn't change dest");
01095 n->_dest = _dest;
01096 return n;
01097 }
01098
01099
01100 Node* ContextCreateNode::clone(PReg* from, PReg* to) const {
01101 return NodeFactory::new_ContextCreateNode(TRANSLATE(_dest), this, exprStack);
01102 }
01103
01104
01105 Node* ContextInitNode::clone(PReg* from, PReg* to) const {
01106 return NodeFactory::new_ContextInitNode(TRANSLATE(_src), this);
01107 }
01108
01109
01110 Node* ContextZapNode::clone(PReg* from, PReg* to) const {
01111 return NodeFactory::new_ContextZapNode(TRANSLATE(_src));
01112 }
01113
01114
01115 Node* NLRTestNode::clone(PReg* from, PReg* to) const {
01116 Unimplemented();
01117 return NULL;
01118 }
01119
01120
01121 Node* ArrayAtNode::clone(PReg* from, PReg* to) const {
01122 return NodeFactory::new_ArrayAtNode(_access_type,
01123 TRANSLATE(_src), TRANSLATE(_arg), _intArg,
01124 TRANSLATE(_dest), TRANSLATE(_error),
01125 _dataOffset, _sizeOffset);
01126 }
01127
01128
01129 Node* ArrayAtPutNode::clone(PReg* from, PReg* to) const {
01130 return NodeFactory::new_ArrayAtPutNode(_access_type,
01131 TRANSLATE(_src), TRANSLATE(_arg), _intArg,
01132 TRANSLATE(elem), _smi_element, TRANSLATE(_dest),
01133 TRANSLATE(_error), _dataOffset, _sizeOffset, _needs_store_check);
01134 }
01135
01136
01137 Node* UncommonNode::clone(PReg* from, PReg* to) const {
01138 Unused(from); Unused(to);
01139 return NodeFactory::new_UncommonNode(exprStack, _bci);
01140 }
01141
01142
01143 Node* InlinedReturnNode::clone (PReg* from, PReg* to) const {
01144 return NodeFactory::new_InlinedReturnNode(bci(), TRANSLATE(src()), TRANSLATE(dest()));
01145 }
01146
01147
01148 # define NO_NEED_TO_COPY { Unused(from); Unused(to); return NULL; }
01149
01150 Node* MergeNode::clone (PReg* from, PReg* to) const { NO_NEED_TO_COPY }
01151 Node* NopNode::clone (PReg* from, PReg* to) const { NO_NEED_TO_COPY }
01152 Node* CommentNode::clone (PReg* from, PReg* to) const { NO_NEED_TO_COPY }
01153
01154
01155
01156
01157
01158
01159 void PrologueNode::makeUses(BB* bb) {
01160 InlinedScope* s = scope();
01161
01162 bb->addDef(this, s->self()->preg());
01163 if (s->isBlockScope()) {
01164 bb->addDef(this, s->context());
01165 }
01166
01167 for (int i = 0; i < _nofArgs; i++) {
01168 Expr* a = s->argument(i);
01169 if (a) bb->addDef(this, a->preg());
01170 }
01171
01172 for (i = 0; i < _nofTemps; i++) {
01173 Expr* t = s->temporary(i);
01174 if (t) bb->addDef(this, t->preg());
01175 }
01176 }
01177
01178 void NonTrivialNode::makeUses(BB* bb) {
01179 _bb = bb;
01180 assert(!hasSrc() || srcUse, "should have srcUse");
01181 assert(!hasDest() || destDef || _dest->isNoPReg(), "should have destDef");
01182 }
01183
01184 void LoadNode::makeUses(BB* bb) {
01185 destDef = bb->addDef(this, _dest); NonTrivialNode::makeUses(bb); }
01186 void LoadOffsetNode::makeUses(BB* bb) {
01187 srcUse = bb->addUse(this, _src); LoadNode::makeUses(bb); }
01188 void LoadUplevelNode::makeUses(BB* bb) {
01189 _context0Use = bb->addUse(this, _context0); LoadNode::makeUses(bb);
01190 }
01191
01192 void StoreNode::makeUses(BB* bb) {
01193 srcUse = bb->addUse(this, _src); NonTrivialNode::makeUses(bb); }
01194 void StoreOffsetNode::makeUses(BB* bb) {
01195 _baseUse = bb->addUse(this, _base); StoreNode::makeUses(bb); }
01196 void StoreUplevelNode::makeUses(BB* bb) {
01197 _context0Use = bb->addUse(this, _context0); StoreNode::makeUses(bb);
01198 }
01199
01200 void AssignNode::makeUses(BB* bb) {
01201 destDef = bb->addDef(this, _dest); StoreNode::makeUses(bb); }
01202
01203 void AbstractReturnNode::makeUses(BB* bb) {
01204 srcUse = bb->addUse(this, _src);
01205 destDef = bb->addDef(this, _dest);
01206 NonTrivialNode::makeUses(bb);
01207 }
01208
01209 void ReturnNode::makeUses(BB* bb) {
01210
01211 resultUse = bb->addUse(this, _dest);
01212 AbstractReturnNode::makeUses(bb);
01213 }
01214
01215 void NLRSetupNode::makeUses(BB* bb) {
01216
01217
01218
01219 resultUse = bb->addUse(this, _dest);
01220 contextUse = bb->addUse(this, _scope->context());
01221 AbstractReturnNode::makeUses(bb);
01222 }
01223
01224 void NLRTestNode::makeUses(BB* bb) {
01225 AbstractBranchNode::makeUses(bb);
01226 }
01227
01228 void NLRContinuationNode::makeUses(BB* bb) {
01229
01230
01231 AbstractReturnNode::makeUses(bb);
01232 }
01233
01234 void ArithNode::makeUses(BB* bb) {
01235 srcUse = bb->addUse(this, _src); destDef = bb->addDef(this, _dest);
01236 NonTrivialNode::makeUses(bb);
01237 }
01238 void ArithRRNode::makeUses(BB* bb) {
01239 _operUse = bb->addUse(this, _oper); ArithNode::makeUses(bb); }
01240
01241 void TArithRRNode::makeUses(BB* bb) {
01242 _operUse = bb->addUse(this, _oper);
01243 srcUse = bb->addUse(this, _src);
01244 destDef = bb->addDef(this, _dest);
01245 NonTrivialNode::makeUses(bb);
01246 }
01247
01248 void CallNode::makeUses(BB* bb) {
01249 destDef = bb->addDef(this, _dest);
01250 if (args) {
01251 int len = args->length();
01252 argUses = new GrowableArray<Use*>(len);
01253 for (int i = 0; i < len; i++) {
01254 argUses->append(bb->addUse(this, args->at(i)));
01255 }
01256 }
01257 NonTrivialNode::makeUses(bb);
01258 if (canInvokeDelta()) {
01259
01260 const int InitialSize = 5;
01261 uplevelUses = new GrowableArray<Use*> (InitialSize);
01262 uplevelDefs = new GrowableArray<Def*> (InitialSize);
01263 uplevelUsed = new GrowableArray<PReg*>(InitialSize);
01264 uplevelDefd = new GrowableArray<PReg*>(InitialSize);
01265 GrowableArray<BlockPReg*>* blks = theCompiler->blockClosures;
01266 for (int i = 0; i < nblocks; i++) {
01267 BlockPReg* blk = blks->at(i);
01268 if (blk->escapes()) {
01269
01270
01271
01272 Scope* home = blk->scope()->home();
01273 if (home->isSenderOrSame(scope())) {
01274
01275 GrowableArray<PReg*>* uplevelRead = blk->uplevelRead();
01276 for (int j = uplevelRead->length() - 1; j >= 0; j--) {
01277 PReg* r = uplevelRead->at(j);
01278 uplevelUses->append(bb->addUse(this, r));
01279 uplevelUsed->append(r);
01280 }
01281 GrowableArray<PReg*>* uplevelWritten = blk->uplevelWritten();
01282 for (j = uplevelWritten->length() - 1; j >= 0; j--) {
01283 PReg* r = uplevelWritten->at(j);
01284 uplevelDefs->append(bb->addDef(this, r));
01285 uplevelDefd->append(r);
01286 }
01287 }
01288 }
01289 }
01290 }
01291 }
01292
01293 void BlockCreateNode::makeUses(BB* bb) {
01294 if (_context && !isMemoized()) {
01295 _contextUse = bb->addUse(this, _context);
01296 }
01297 destDef = bb->addDef(this, _dest);
01298 NonTrivialNode::makeUses(bb);
01299 }
01300
01301 void BlockMaterializeNode::makeUses(BB* bb) {
01302
01303 if (isMemoized()) {
01304 srcUse = bb->addUse(this, _src);
01305 if (_context) _contextUse = bb->addUse(this, _context);
01306 BlockCreateNode::makeUses(bb);
01307 }
01308 }
01309
01310 void ContextCreateNode::makeUses(BB* bb) {
01311 if (_src) srcUse = bb->addUse(this, _src);
01312 destDef = bb->addDef(this, _dest);
01313 if (_parentContexts) {
01314 int len = _parentContexts->length();
01315 _parentContextUses = new GrowableArray<Use*>(len, len, NULL);
01316 for (int i = _parentContexts->length() - 1; i>= 0; i--) {
01317 Use* u = bb->addUse(this, _parentContexts->at(i));
01318 _parentContextUses->at_put(i, u);
01319 }
01320 }
01321 NonTrivialNode::makeUses(bb);
01322 }
01323
01324 void ContextInitNode::makeUses(BB* bb) {
01325 srcUse = bb->addUse(this, _src);
01326 int i = nofTemps();
01327 _contentDefs = new GrowableArray<Def*>(i, i, NULL);
01328 _initializerUses = new GrowableArray<Use*>(i, i, NULL);
01329 while (i-- > 0) {
01330 PReg* r = contents()->at(i)->preg();
01331 if (r->isBlockPReg()) {
01332 _contentDefs->at_put(i, NULL);
01333 } else {
01334 _contentDefs->at_put(i, bb->addDef(this, r));
01335 }
01336 _initializerUses->at_put(i, bb->addUse(this, _initializers->at(i)->preg()));
01337 }
01338 NonTrivialNode::makeUses(bb);
01339 }
01340
01341 void ContextZapNode::makeUses(BB* bb) {
01342 srcUse = bb->addUse(this, _src);
01343 }
01344
01345 void TypeTestNode::makeUses(BB* bb) {
01346 srcUse = bb->addUse(this, _src); AbstractBranchNode::makeUses(bb);
01347 }
01348
01349 void AbstractArrayAtNode::makeUses(BB* bb) {
01350 srcUse = bb->addUse(this, _src);
01351 destDef = _dest ? bb->addDef(this, _dest) : NULL;
01352 _argUse = bb->addUse(this, _arg);
01353 _errorDef = (_error && canFail()) ? bb->addDef(this, _error) : NULL;
01354 AbstractBranchNode::makeUses(bb);
01355 }
01356
01357 void AbstractArrayAtPutNode::makeUses(BB* bb) {
01358 elemUse = bb->addUse(this, elem);
01359 AbstractArrayAtNode::makeUses(bb);
01360 }
01361
01362 void InlinedPrimitiveNode::makeUses(BB* bb) {
01363 srcUse = _src ? bb->addUse(this, _src ) : NULL;
01364 _arg1_use = _arg1 ? bb->addUse(this, _arg1 ) : NULL;
01365 _arg2_use = _arg2 ? bb->addUse(this, _arg2 ) : NULL;
01366 destDef = _dest ? bb->addDef(this, _dest ) : NULL;
01367 _error_def = (_error && canFail()) ? bb->addDef(this, _error) : NULL;
01368 AbstractBranchNode::makeUses(bb);
01369 }
01370
01371
01372
01373
01374
01375
01376 void NonTrivialNode::removeUses(BB* bb) { assert(_bb == bb, "wrong BB"); }
01377
01378 void LoadNode::removeUses(BB* bb) {
01379 _dest->removeDef(bb, destDef); NonTrivialNode::removeUses(bb);
01380 }
01381
01382 void LoadOffsetNode::removeUses(BB* bb) {
01383 _src->removeUse(bb, srcUse); LoadNode::removeUses(bb);
01384 }
01385
01386 void LoadUplevelNode::removeUses(BB* bb) {
01387 _context0->removeUse(bb, _context0Use); LoadNode::removeUses(bb);
01388 }
01389
01390 void StoreNode::removeUses(BB* bb) {
01391 _src->removeUse(bb, srcUse); NonTrivialNode::removeUses(bb);
01392 }
01393
01394 void StoreOffsetNode::removeUses(BB* bb) {
01395 _base->removeUse(bb, _baseUse); StoreNode::removeUses(bb);
01396 }
01397
01398 void StoreUplevelNode::removeUses(BB* bb) {
01399 _context0->removeUse(bb, _context0Use); StoreNode::removeUses(bb);
01400 }
01401
01402 void AssignNode::removeUses(BB* bb) {
01403 _dest->removeDef(bb, destDef); StoreNode::removeUses(bb);
01404 }
01405
01406 void AbstractReturnNode::removeUses(BB* bb) {
01407 _src->removeUse(bb, srcUse); _dest->removeDef(bb, destDef);
01408 NonTrivialNode::removeUses(bb);
01409 }
01410
01411 void ReturnNode::removeUses(BB* bb) {
01412 _dest->removeUse(bb, resultUse);
01413 AbstractReturnNode::removeUses(bb);
01414 }
01415
01416 void NLRSetupNode::removeUses(BB* bb) {
01417 _dest->removeUse(bb, resultUse);
01418 _scope->context()->removeUse(bb, contextUse);
01419 AbstractReturnNode::removeUses(bb);
01420 }
01421
01422 void NLRTestNode::removeUses(BB* bb) {
01423 AbstractBranchNode::removeUses(bb);
01424 }
01425
01426 void NLRContinuationNode::removeUses(BB* bb) {
01427 AbstractReturnNode::removeUses(bb);
01428 }
01429
01430 void ArithNode::removeUses(BB* bb) {
01431 _src->removeUse(bb, srcUse); _dest->removeDef(bb, destDef);
01432 NonTrivialNode::removeUses(bb);
01433 }
01434
01435 void ArithRRNode::removeUses(BB* bb) {
01436 _oper->removeUse(bb, _operUse); ArithNode::removeUses(bb);
01437 }
01438
01439 void TArithRRNode::removeUses(BB* bb) {
01440 _oper->removeUse(bb, _operUse);
01441 _src->removeUse(bb, srcUse);
01442 _dest->removeDef(bb, destDef);
01443 NonTrivialNode::removeUses(bb);
01444 }
01445
01446 void CallNode::removeUses(BB* bb) {
01447 _dest->removeDef(bb, destDef);
01448 if (argUses) {
01449 int len = args->length();
01450 for (int i = 0; i < len; i++) {
01451 args->at(i)->removeUse(bb, argUses->at(i));
01452 }
01453 }
01454 if (uplevelUses) {
01455 for (int i = uplevelUses->length() - 1; i >= 0; i--) uplevelUsed->at(i)->removeUse(bb, uplevelUses->at(i));
01456 for (i = uplevelDefs->length() - 1; i >= 0; i--) uplevelDefd->at(i)->removeDef(bb, uplevelDefs->at(i));
01457 }
01458 NonTrivialNode::removeUses(bb);
01459 }
01460
01461 void BlockCreateNode::removeUses(BB* bb) {
01462 if (_contextUse) _context->removeUse(bb, _contextUse);
01463 if (_src) _src->removeUse(bb, srcUse);
01464 _dest->removeDef(bb, destDef);
01465 NonTrivialNode::removeUses(bb);
01466 }
01467
01468 void BlockMaterializeNode::removeUses(BB* bb) {
01469
01470 if (isMemoized()) BlockCreateNode::removeUses(bb);
01471 }
01472
01473 void ContextCreateNode::removeUses(BB* bb) {
01474 if (_src) _src->removeUse(bb, srcUse);
01475 _dest->removeDef(bb, destDef);
01476 NonTrivialNode::removeUses(bb);
01477 }
01478
01479 void ContextInitNode::removeUses(BB* bb) {
01480 int i = nofTemps();
01481 while (i-- > 0) {
01482 contents()->at(i)->preg()->removeDef(bb, _contentDefs->at(i));
01483 _initializers->at(i)->preg()->removeUse(bb, _initializerUses->at(i));
01484 }
01485 _src->removeUse(bb, srcUse);
01486 NonTrivialNode::removeUses(bb);
01487 }
01488
01489 void ContextZapNode::removeUses(BB* bb) {
01490 _src->removeUse(bb, srcUse);
01491 NonTrivialNode::removeUses(bb);
01492 }
01493
01494 void TypeTestNode::removeUses(BB* bb) {
01495 _src->removeUse(bb, srcUse);
01496 AbstractBranchNode::removeUses(bb);
01497 }
01498
01499 void AbstractArrayAtNode::removeUses(BB* bb) {
01500 _src->removeUse(bb, srcUse);
01501 if (_dest) _dest->removeDef(bb, destDef);
01502 _arg->removeUse(bb, _argUse);
01503 if (_errorDef) _error->removeDef(bb, _errorDef);
01504 AbstractBranchNode::removeUses(bb);
01505 }
01506
01507 void AbstractArrayAtPutNode::removeUses(BB* bb) {
01508 elem->removeUse(bb, elemUse);
01509 AbstractArrayAtNode::removeUses(bb);
01510 }
01511
01512 void InlinedPrimitiveNode::removeUses(BB* bb) {
01513 if (srcUse ) _src ->removeUse (bb, srcUse );
01514 if (_arg1_use ) _arg1->removeUse (bb, _arg1_use );
01515 if (_arg2_use ) _arg2->removeUse (bb, _arg2_use );
01516 if (destDef ) _dest ->removeDef(bb, destDef );
01517 if (_error_def) _error->removeDef(bb, _error_def);
01518 AbstractBranchNode::removeUses(bb);
01519 }
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533 inline void Node::eliminate(BB* bb, PReg* r, bool removing, bool cp) {
01534 assert(!deleted, "already deleted this node");
01535 if (CompilerDebug) {
01536 char buf[1024];
01537 cout(PrintEliminateUnnededNodes)->print("*%s node N%ld: %s\n", removing ? "removing" : "eliminating",
01538 id(), print_string(buf, PrintHexAddresses));
01539 }
01540 assert(!dontEliminate || removing, "shouldn't eliminate this node");
01541 bb->remove(this);
01542 }
01543
01544 # define CHECK(preg, r) \
01545 if (preg != r && preg->isOnlySoftUsed()) preg->eliminate(false);
01546
01547 inline void LoadNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01548 if (deleted) return;
01549 assert(canBeEliminated() || rem, "cannot be eliminated");
01550 NonTrivialNode::eliminate(bb, r, rem, cp); CHECK(_dest, r); }
01551
01552 inline void LoadOffsetNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01553 if (deleted) return;
01554 LoadNode::eliminate(bb, r, rem, cp); CHECK(_src, r); }
01555
01556 inline void LoadUplevelNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01557 if (deleted) return;
01558 LoadNode::eliminate(bb, r, rem, cp); CHECK(_context0, r);
01559 }
01560
01561 inline void StoreNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01562 if (deleted) return;
01563 NonTrivialNode::eliminate(bb, r, rem, cp); CHECK(_src, r); }
01564 inline void StoreOffsetNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01565 if (deleted) return;
01566 StoreNode::eliminate(bb, r, rem, cp); CHECK(_base, r); }
01567 inline void StoreUplevelNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01568 if (deleted) return;
01569 StoreNode::eliminate(bb, r, rem, cp); CHECK(_context0, r);
01570 }
01571
01572 inline void AssignNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01573 if (deleted) return;
01574 StoreNode::eliminate(bb, r, rem, cp); CHECK(_dest, r); }
01575
01576 inline void ReturnNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01577 if (deleted) return;
01578 assert(rem, "should not delete except during dead-code elimination");
01579 AbstractReturnNode::eliminate(bb, r, rem, cp); CHECK(_src, r); CHECK(_dest, r);
01580
01581 }
01582
01583 inline void ArithNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01584 if (deleted) return;
01585 NonTrivialNode::eliminate(bb, r, rem, cp); CHECK(_src, r); CHECK(_dest, r); }
01586 inline void ArithRRNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01587 if (deleted) return;
01588 ArithNode::eliminate(bb, r, rem, cp); CHECK(_oper, r); }
01589
01590 inline void BranchNode::eliminate(BB* bb, PReg* r, bool removing, bool cp) {
01591 if (deleted) return;
01592 if (removing && nSuccessors() <= 1) {
01593 NonTrivialNode::eliminate(bb, r, removing, cp);
01594 } else {
01595
01596 fatal("removing branch node with > 1 successor");
01597 }
01598 }
01599
01600 inline void BlockMaterializeNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01601 if (deleted) return;
01602 BlockCreateNode::eliminate(bb, r, rem, cp);
01603 }
01604
01605 void BasicNode::removeUpToMerge() {
01606 BB* thisBB = _bb;
01607 for (Node* n = (Node*)this; n && n->hasSinglePredecessor(); ) {
01608 while (n->nSuccessors() > 1) {
01609 int i = n->nSuccessors() - 1;
01610 Node* succ = n->next(i);
01611 n->removeNext(succ);
01612 succ->removeUpToMerge();
01613 }
01614 Node* nextn = n->next();
01615 if (!n->deleted) n->eliminate(thisBB, NULL, true, false);
01616 if (nextn) {
01617 BB* nextBB = nextn->bb();
01618 if (nextBB != thisBB) {
01619 if (nextn->nPredecessors() >= 2) {
01620
01621
01622 n->removeNext(nextn);
01623
01624
01625
01626 break;
01627 }
01628 thisBB = nextBB;
01629 }
01630 }
01631 n = nextn;
01632 }
01633 BB* nextBB = n ? n->bb() : NULL;
01634 }
01635
01636 void PrimNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01637 if (deleted) return;
01638 assert(rem || canBeEliminated(), "shouldn't call");
01639 if (nlrTestPoint()) {
01640
01641
01642 MergeNode* n1 = nlrTestPoint();
01643 Node* n2 = n1->next();
01644 assert(n2->isNLRTestNode(), "unexpected node sequence");
01645 _nxt->pop();
01646 assert(nlrTestPoint() == NULL, "should be NULL now");
01647 n1->eliminate(n1->bb(), NULL, true, false);
01648 n2->eliminate(n2->bb(), NULL, true, false);
01649 }
01650 NonTrivialNode::eliminate(bb, r, rem, cp);
01651 CHECK(_dest, r);
01652 if (args) {
01653
01654 int len = args->length();
01655 for (int i = 0; i < len; i++) {
01656 PReg* arg = args->at(i);
01657 if (arg->loc.isTopOfStack()) {
01658
01659
01660 arg->loc = unAllocated;
01661 } else {
01662 fatal("internal compiler error");
01663
01664 }
01665 CHECK(arg, r);
01666 }
01667 }
01668 }
01669
01670 void TypeTestNode::eliminate(BB* bb, PReg* rr, bool rem, bool cp) {
01671
01672 Unused(rem); Unused(cp);
01673 if (deleted) return;
01674
01675 eliminate(bb, rr, (ConstPReg*)NULL, (klassOop)badOop);
01676 }
01677
01678 void TypeTestNode::eliminate(BB* bb, PReg* r, ConstPReg* c, klassOop theKlass) {
01679
01680 if (deleted) return;
01681 GrowableArray<Node*>* successors = _nxt;
01682 _nxt = new GrowableArray<Node*>(1);
01683 oop constant = c ? c->constant : 0;
01684 Node* keep = NULL;
01685 if (CompilerDebug) {
01686 cout(PrintEliminateUnnededNodes)->print("*eliminating tt node %#lx const %#lx klass %#lx\n",
01687 PrintHexAddresses ? this : 0, constant, theKlass);
01688 }
01689 Node* un = _next;
01690
01691 for (int i = 0; i < successors->length(); i++) {
01692 Node* succ = successors->at(i);
01693 succ->removePrev(this);
01694 klassOop m = _classes->at(i);
01695 if (constant == m || theKlass == m) {
01696 assert(keep == NULL, "shouldn't have more than one match");
01697 keep = succ;
01698 } else {
01699 _next = succ;
01700 _next->removeUpToMerge();
01701 }
01702 }
01703
01704 if (keep || theKlass == klassOop(badOop)) {
01705
01706
01707 _next = un;
01708 un->removeUpToMerge();
01709 _next = NULL;
01710 } else {
01711
01712
01713
01714 if (WizardMode) {
01715 warning("Compiler: typetest didn't predict klass %#lx", theKlass);
01716 lprintf("predicted klasses: ");
01717 _classes->print();
01718 }
01719 _next = un;
01720 }
01721 assert(this == bb->last, "should end my BB");
01722
01723 if (keep) {
01724
01725 append(keep);
01726 }
01727 NonTrivialNode::eliminate(bb, r, true, false);
01728 CHECK(_dest, r);
01729 }
01730
01731 void TypeTestNode::eliminateUnnecessary(klassOop m) {
01732
01733 eliminate(bb(), NULL, NULL, m);
01734 }
01735
01736 void AbstractArrayAtNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01737 Unused(cp); Unused(rem);
01738 assert(rem, "shouldn't eliminate because of side effects (errors)");
01739 if (deleted) return;
01740
01741 Node* fail = next1();
01742 if (fail) {
01743 fail->removePrev(this);
01744 fail->removeUpToMerge();
01745 }
01746 AbstractBranchNode::eliminate(bb, r, rem, cp);
01747 }
01748
01749 void InlinedPrimitiveNode::eliminate(BB* bb, PReg* r, bool rem, bool cp) {
01750 if (deleted) return;
01751 AbstractBranchNode::eliminate(bb, r, rem, cp);
01752 if (_arg1) CHECK(_arg1, r);
01753 if (_arg2) CHECK(_arg2, r);
01754 if (_dest) CHECK(_dest, r);
01755 if (_error) CHECK(_error, r);
01756 }
01757
01758 void ContextCreateNode::eliminate(BB* bb, PReg* r, bool removing, bool cp) {
01759 if (deleted) return;
01760 PrimNode::eliminate(bb, r, removing, cp);
01761 }
01762
01763 void ContextInitNode::eliminate(BB* bb, PReg* r, bool removing, bool cp) {
01764 assert(removing, "should only remove when removing unreachable code");
01765 if (deleted) return;
01766 NonTrivialNode::eliminate(bb, r, removing, cp);
01767 }
01768
01769 void BranchNode::eliminateBranch(int op1, int op2, int res) {
01770
01771
01772 bool ok;
01773 switch (_op) {
01774 case EQBranchOp: ok = op1 == op2; break;
01775 case NEBranchOp: ok = op1 != op2; break;
01776 case LTBranchOp: ok = op1 < op2; break;
01777 case LEBranchOp: ok = op1 <= op2; break;
01778 case GTBranchOp: ok = op1 > op2; break;
01779 case GEBranchOp: ok = op1 >= op2; break;
01780 case LTUBranchOp: ok = (unsigned)op1 < (unsigned)op2; break;
01781 case LEUBranchOp: ok = (unsigned)op1 <= (unsigned)op2; break;
01782 case GTUBranchOp: ok = (unsigned)op1 > (unsigned)op2; break;
01783 case GEUBranchOp: ok = (unsigned)op1 >= (unsigned)op2; break;
01784 case VSBranchOp: return;
01785 case VCBranchOp: return;
01786 default: fatal("unexpected branch type");
01787 }
01788 int nodeToRemove;
01789 if (ok) {
01790 nodeToRemove = 0;
01791 } else {
01792 nodeToRemove = 1;
01793 }
01794
01795
01796 Node* discard = next(nodeToRemove);
01797 removeNext(discard);
01798 discard->removeUpToMerge();
01799 Node* succ = next(1 - nodeToRemove);
01800 removeNext(succ);
01801 append(succ);
01802 bb()->remove(this);
01803 }
01804
01805
01806
01807
01808
01809
01810 Node* Node::likelySuccessor() const {
01811 assert(hasSingleSuccessor(), "should override likelySuccessor()");
01812 return next();
01813 }
01814
01815 Node* TArithRRNode::likelySuccessor() const {
01816 return next();
01817 }
01818
01819 Node* CallNode::likelySuccessor() const {
01820 return next();
01821 }
01822
01823 Node* NLRTestNode::likelySuccessor() const {
01824 return next();
01825 }
01826
01827 Node* BranchNode::likelySuccessor() const {
01828 return next();
01829 }
01830
01831 Node* TypeTestNode::likelySuccessor() const {
01832 if (deleted) return next();
01833 assert(classes()->length() > 0, "no TypeTestNode needed");
01834 return next(hasUnknown() ? classes()->length() : classes()->length() - 1);
01835 }
01836
01837 Node* AbstractArrayAtNode::likelySuccessor() const {
01838 return next();
01839 }
01840
01841 Node* InlinedPrimitiveNode::likelySuccessor() const {
01842 return next();
01843 }
01844
01845
01846
01847
01848
01849
01850
01851 Node* Node::uncommonSuccessor() const {
01852 assert(hasSingleSuccessor(), "should override uncommonSuccessor()");
01853 return NULL;
01854 }
01855
01856 Node* TArithRRNode::uncommonSuccessor() const {
01857 return (deleted || !canFail()) ? NULL : next(1);
01858 }
01859
01860 Node* CallNode::uncommonSuccessor() const {
01861 return NULL;
01862 }
01863
01864 Node* NLRTestNode::uncommonSuccessor() const {
01865 return NULL;
01866 }
01867
01868 Node* BranchNode::uncommonSuccessor() const {
01869 return (!deleted && _taken_is_uncommon) ? next(1) : NULL;
01870 }
01871
01872 Node* TypeTestNode::uncommonSuccessor() const {
01873 if (!deleted && hasUnknown()) {
01874
01875 assert(next() != NULL, "just checking");
01876 return next();
01877 } else {
01878
01879 return NULL;
01880 }
01881 }
01882
01883 Node* AbstractArrayAtNode::uncommonSuccessor() const {
01884 return (deleted || !canFail()) ? NULL : next(1);
01885 }
01886
01887 Node* InlinedPrimitiveNode::uncommonSuccessor() const {
01888 return nSuccessors() == 2 ? next(1) : NULL;
01889 }
01890
01891
01892
01893
01894
01895
01896 # define CP_HELPER(_src, srcUse, return) \
01897 \
01898 \
01899 \
01900 if (replace || (!d->loc.isTopOfStack() && d->extendLiveRange(this))) { \
01901 _src->removeUse(bb, srcUse); \
01902 _src = d; \
01903 srcUse = _src->addUse(bb, this); \
01904 return true; \
01905 } else { \
01906 return false; \
01907 }
01908
01909
01910 void AbstractBranchNode::removeFailureIfPossible() {
01911 Node* taken = next1();
01912 if (!canFail() && taken != NULL && taken->bb()->isPredecessor(bb())) {
01913 taken->removeUpToMerge();
01914 removeNext(taken);
01915 }
01916 }
01917
01918 bool BasicNode::canCopyPropagate(Node* fromNode) const {
01919
01920
01921
01922 return canCopyPropagate() && fromNode->bb()->loopDepth() == _bb->loopDepth();
01923 }
01924
01925 bool NonTrivialNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
01926 assert(canCopyPropagate(), "can't copy-propagate");
01927 assert(hasSrc(), "has no src");
01928 if (srcUse == u) {
01929 CP_HELPER(_src, srcUse, return);
01930 } else {
01931 fatal("copyPropagate: not the source use");
01932 }
01933 return false;
01934 }
01935
01936 bool LoadOffsetNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
01937 if (u == srcUse) {
01938
01939
01940
01941 CP_HELPER(_src, srcUse, return);
01942 } else {
01943 return LoadNode::copyPropagate(bb, u, d, replace);
01944 }
01945 return false;
01946 }
01947
01948 bool LoadUplevelNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
01949 if (u == _context0Use) {
01950 CP_HELPER(_context0, _context0Use, return);
01951 } else {
01952 return LoadNode::copyPropagate(bb, u, d, replace);
01953 }
01954 return false;
01955 }
01956
01957 bool StoreOffsetNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
01958 if (u == _baseUse) {
01959 CP_HELPER(_base, _baseUse, return);
01960 } else {
01961 return StoreNode::copyPropagate(bb, u, d, replace);
01962 }
01963 return false;
01964 }
01965
01966 bool StoreUplevelNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
01967 if (u == _context0Use) {
01968 CP_HELPER(_context0, _context0Use, return);
01969 } else {
01970 return StoreNode::copyPropagate(bb, u, d, replace);
01971 }
01972 return false;
01973 }
01974
01975 bool CallNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
01976
01977 return false;
01978 }
01979
01980 bool ArithRRNode::operIsConst() const { return _oper->isConstPReg(); }
01981 int ArithRRNode::operConst() const {
01982 assert(operIsConst(), "not a constant");
01983 return _oper->isConstPReg();
01984 }
01985
01986 bool ArithNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
01987 bool success = doCopyPropagate(bb, u, d, replace);
01988 if (_src->isConstPReg() && operIsConst()) {
01989 assert(success, "CP must have worked");
01990
01991 int c1 = (int)((ConstPReg*)_src)->constant;
01992 int c2 = (int)operConst();
01993 int res;
01994 switch (_op) {
01995 case AddArithOp:
01996 res = c1 + c2; break;
01997
01998 case SubArithOp:
01999 res = c1 - c2; break;
02000
02001 case AndArithOp:
02002 res = c1 & c2; break;
02003
02004 case OrArithOp:
02005 res = c1 | c2; break;
02006
02007 case XOrArithOp:
02008 res = c1 ^ c2; break;
02009
02010 default: return success;
02011 }
02012
02013 _constResult = new_ConstPReg(scope(), (oop)res);
02014
02015 dontEliminate = false;
02016 _src->removeUse(bb, srcUse);
02017 _src = _constResult;
02018 srcUse = bb->addUse(this, _src);
02019
02020
02021 Node* branch = next();
02022 if (branch->isBranchNode()) {
02023 ((BranchNode*)branch)->eliminateBranch(c1, c2, res);
02024 }
02025 }
02026 return success;
02027 }
02028
02029 bool ArithNode::doCopyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
02030 return NonTrivialNode::copyPropagate(bb, u, d, replace);
02031 }
02032
02033 bool ArithRRNode::doCopyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
02034 if (u == _operUse) {
02035 CP_HELPER(_oper, _operUse, return);
02036 } else {
02037 return ArithNode::doCopyPropagate(bb, u, d, replace);
02038 }
02039 return false;
02040 }
02041
02042 bool TArithRRNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
02043 bool res = doCopyPropagate(bb, u, d, replace);
02044 if (_src->isConstPReg() && _oper->isConstPReg()) {
02045 assert(res, "CP must have worked");
02046
02047 oop c1 = ((ConstPReg*)_src)->constant;
02048 oop c2 = ((ConstPReg*)_oper)->constant;
02049 oop result;
02050 switch (_op) {
02051 case tAddArithOp : result = smiOopPrimitives_add(c1, c2); break;
02052 case tSubArithOp : result = smiOopPrimitives_subtract(c1, c2); break;
02053 case tMulArithOp : result = smiOopPrimitives_multiply(c1, c2); break;
02054 case tDivArithOp : result = smiOopPrimitives_div(c1, c2); break;
02055 case tModArithOp : result = smiOopPrimitives_mod(c1, c2); break;
02056 case tAndArithOp : result = smiOopPrimitives::bitAnd(c1, c2); break;
02057 case tOrArithOp : result = smiOopPrimitives::bitOr(c1, c2); break;
02058 case tXOrArithOp : result = smiOopPrimitives::bitXor(c1, c2); break;
02059 case tShiftArithOp: warning("possible performance bug: constant folding of tShiftArithOp not implemented"); return false;
02060 case tCmpArithOp : warning("possible performance bug: constant folding of tCmpArithOp not implemented"); return false;
02061 default : fatal1("unknown tagged opcode %ld", _op);
02062 }
02063 bool ok = !result->is_mark();
02064 if (ok) {
02065
02066 if (CompilerDebug) cout(PrintCopyPropagation)->print("*constant-folding N%d --> %#x\n", _id, result);
02067 _constResult = new_ConstPReg(scope(), result);
02068
02069 Node* discard = next1();
02070 if (discard != NULL) {
02071 discard->bb()->remove(discard);
02072 discard->removeUpToMerge();
02073 # ifdef ASSERT
02074 bb->verify();
02075 ((BB*)bb->next())->verify();
02076 # endif
02077 }
02078
02079 discard = next();
02080 assert(discard->isBranchNode(), "must be a cond. branch");
02081 assert(((BranchNode*)discard)->op() == VSBranchOp, "expected an overflow check");
02082 discard->bb()->remove(discard);
02083
02084 discard = discard->next1();
02085 discard->bb()->remove(discard);
02086 discard->removeUpToMerge();
02087 # ifdef ASSERT
02088 bb->verify();
02089 ((BB*)bb->next())->verify();
02090 # endif
02091
02092 dontEliminate = false;
02093 _src->removeUse(bb, srcUse);
02094 _src = _constResult;
02095 srcUse = bb->addUse(this, _src);
02096 } else {
02097
02098
02099 }
02100 }
02101 removeFailureIfPossible();
02102 return res;
02103 }
02104
02105 bool TArithRRNode::doCopyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
02106 bool res;
02107 if (u == srcUse) {
02108 if (d->isConstPReg() && ((ConstPReg*)d)->constant->is_smi())
02109 _arg1IsInt = true;
02110 CP_HELPER(_src, srcUse, res = );
02111 } else if (u == _operUse) {
02112 if (d->isConstPReg() && ((ConstPReg*)d)->constant->is_smi())
02113 _arg2IsInt = true;
02114 CP_HELPER(_oper, _operUse, res =);
02115 } else {
02116 fatal("copyPropagate: not the source use");
02117 }
02118 removeFailureIfPossible();
02119 return res;
02120 }
02121
02122 bool FloatArithRRNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
02123 if (d->isConstPReg() && !((ConstPReg*)d)->constant->is_double()) {
02124
02125 return false;
02126 }
02127 bool res = ArithRRNode::copyPropagate(bb, u, d, replace);
02128
02129 return res;
02130 }
02131
02132 bool FloatUnaryArithNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
02133 if (d->isConstPReg() && !((ConstPReg*)d)->constant->is_double()) {
02134
02135 return false;
02136 }
02137 bool res = ArithNode::copyPropagate(bb, u, d, replace);
02138
02139 return res;
02140 }
02141
02142 bool TypeTestNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
02143 if (u == srcUse) {
02144 if (d->isConstPReg()) {
02145
02146 ConstPReg* c = (ConstPReg*)d;
02147
02148
02149
02150
02151 if (false) {
02152 eliminate(bb, NULL, c, c->constant->klass());
02153 return true;
02154 }
02155 return false;
02156 } else {
02157 CP_HELPER(_src, srcUse, return);
02158 }
02159 } else {
02160 fatal("don't have this use");
02161 }
02162 return false;
02163 }
02164
02165 bool AbstractArrayAtNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
02166 if (u == _argUse) {
02167 bool res;
02168 CP_HELPER(_arg, _argUse, res =);
02169 removeFailureIfPossible();
02170 return res;
02171 } else {
02172 return AbstractBranchNode::copyPropagate(bb, u, d, replace);
02173 }
02174 return false;
02175 }
02176
02177 bool AbstractArrayAtPutNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
02178 bool res;
02179 if (u == _argUse) {
02180 CP_HELPER(_arg, _argUse, res = );
02181 } else if (u == elemUse) {
02182 CP_HELPER(elem, elemUse, res =);
02183 } else {
02184 return AbstractBranchNode::copyPropagate(bb, u, d, replace);
02185 }
02186 removeFailureIfPossible();
02187 return res;
02188 }
02189
02190 bool InlinedPrimitiveNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
02191
02192 return false;
02193 }
02194
02195 bool ContextInitNode::copyPropagate(BB* bb, Use* u, PReg* d, bool replace) {
02196 for (int i = nofTemps() - 1; i >= 0; i--) {
02197 if (_initializerUses->at(i) == u) {
02198 Expr* initExpr = _initializers->at(i);
02199 PReg* initPR = initExpr->preg();
02200 Use* newUse = u;
02201 bool ok;
02202 CP_HELPER(initPR, newUse, ok = );
02203 if (ok) {
02204 assert(newUse != u, "must have new use");
02205 _initializers->at_put(i, initExpr->shallowCopy(d, initExpr->node()));
02206 _initializerUses->at_put(i, newUse);
02207 }
02208 return ok;
02209 }
02210 }
02211 return NonTrivialNode::copyPropagate(bb, u, d, replace);
02212 }
02213
02214
02215
02216
02217
02218
02219 # define U_CHECK(r) if (r->loc.isRegisterLocation()) use_count[r->loc.number()]++
02220 # define D_CHECK(r) if (r->loc.isRegisterLocation()) def_count[r->loc.number()]++
02221
02222 void LoadNode::markAllocated(int* use_count, int* def_count) {
02223 Unused(use_count);
02224 D_CHECK(_dest);
02225 }
02226 void LoadOffsetNode::markAllocated(int* use_count, int* def_count) {
02227 U_CHECK(_src); LoadNode::markAllocated(use_count, def_count);
02228 }
02229 void LoadUplevelNode::markAllocated(int* use_count, int* def_count) {
02230 U_CHECK(_context0); LoadNode::markAllocated(use_count, def_count);
02231 }
02232
02233 void StoreNode::markAllocated(int* use_count, int* def_count) {
02234 Unused(def_count);
02235 U_CHECK(_src);
02236 }
02237 void StoreOffsetNode::markAllocated(int* use_count, int* def_count) {
02238 U_CHECK(_base); StoreNode::markAllocated(use_count, def_count);
02239 }
02240 void StoreUplevelNode::markAllocated(int* use_count, int* def_count) {
02241 U_CHECK(_context0); StoreNode::markAllocated(use_count, def_count);
02242 }
02243 void AssignNode::markAllocated(int* use_count, int* def_count) {
02244 U_CHECK(_src); D_CHECK(_dest);
02245 }
02246
02247 void ReturnNode::markAllocated(int* use_count, int* def_count) {
02248 U_CHECK(_src); D_CHECK(_dest);
02249 AbstractReturnNode::markAllocated(use_count, def_count);
02250 }
02251
02252 void ArithNode::markAllocated(int* use_count, int* def_count) {
02253 U_CHECK(_src); D_CHECK(_dest);
02254 }
02255
02256 void ArithRRNode::markAllocated(int* use_count, int* def_count) {
02257 U_CHECK(_oper); ArithNode::markAllocated(use_count, def_count);
02258 }
02259
02260 void TArithRRNode::markAllocated(int* use_count, int* def_count) {
02261 U_CHECK(_src); D_CHECK(_dest);
02262 U_CHECK(_oper);
02263 }
02264
02265 void CallNode::markAllocated(int* use_count, int* def_count) {
02266 D_CHECK(_dest);
02267
02268 for (int i = 0; i < nofRegisters; i++) { use_count[i]++; def_count[i]++; }
02269 }
02270
02271 void BlockCreateNode::markAllocated(int* use_count, int* def_count) {
02272 if (_src) U_CHECK(_src);
02273 if (_context) U_CHECK(_context);
02274 PrimNode::markAllocated(use_count, def_count);
02275 }
02276
02277 void BlockMaterializeNode::markAllocated(int* use_count, int* def_count) {
02278 if (isMemoized()) BlockCreateNode::markAllocated(use_count, def_count);
02279 }
02280
02281 void ContextCreateNode::markAllocated(int* use_count, int* def_count) {
02282 if (_src) U_CHECK(_src);
02283 if (_parentContexts) {
02284 for (int i = _parentContexts->length() - 1; i>= 0; i--) {
02285 U_CHECK(_parentContexts->at(i));
02286 }
02287 }
02288 PrimNode::markAllocated(use_count, def_count);
02289 };
02290
02291 void ContextInitNode::markAllocated(int* use_count, int* def_count) {
02292 if (_src) U_CHECK(_src);
02293 int i = nofTemps();
02294 while (i-- > 0) {
02295 D_CHECK(contents()->at(i)->preg());
02296 }
02297 }
02298
02299 void ContextZapNode::markAllocated(int* use_count, int* def_count) {
02300 U_CHECK(_src);
02301 }
02302
02303 void TypeTestNode::markAllocated(int* use_count, int* def_count) {
02304 Unused(def_count);
02305 U_CHECK(_src);
02306 }
02307
02308 void AbstractArrayAtNode::markAllocated(int* use_count, int* def_count) {
02309 U_CHECK(_src);
02310 if (_dest) D_CHECK(_dest);
02311 U_CHECK(_arg);
02312 if (_error) D_CHECK(_error);
02313 }
02314
02315 void AbstractArrayAtPutNode::markAllocated(int* use_count, int* def_count) {
02316 if (elem) U_CHECK(elem);
02317 AbstractArrayAtNode::markAllocated(use_count, def_count);
02318 }
02319
02320 void InlinedPrimitiveNode::markAllocated(int* use_count, int* def_count) {
02321 if (_src ) U_CHECK(_src );
02322 if (_arg1 ) U_CHECK(_arg1 );
02323 if (_arg2 ) U_CHECK(_arg2 );
02324 if (_dest ) D_CHECK(_dest );
02325 if (_error) D_CHECK(_error);
02326 }
02327
02328
02329 SimpleBitVector BasicNode::trashedMask() { return SimpleBitVector(0); }
02330 SimpleBitVector CallNode::trashedMask() { return SimpleBitVector(-1); }
02331
02332
02333
02334
02335
02336 inline void computeEscapingBlocks(Node* n, PReg* src, GrowableArray<BlockPReg*>* l, char* msg) {
02337
02338 if (src->isBlockPReg()) {
02339 BlockPReg* r = (BlockPReg*)src;
02340 r->markEscaped(n);
02341 if (!l->contains(r)) l->append(r);
02342 if (msg) theCompiler->reporter->report_block(n, r, msg);
02343 }
02344 }
02345
02346 void StoreNode::computeEscapingBlocks(GrowableArray<BlockPReg*>* ll) {
02347
02348
02349 ::computeEscapingBlocks(this, _src, ll, action());
02350 }
02351
02352 void AbstractReturnNode::computeEscapingBlocks(GrowableArray<BlockPReg*>* ll) {
02353
02354 if (_src) ::computeEscapingBlocks(this, _src, ll, "returned");
02355 }
02356
02357 void CallNode::computeEscapingBlocks(GrowableArray<BlockPReg*>* ll) {
02358 SubclassResponsibility();
02359 }
02360
02361 void SendNode::computeEscapingBlocks(GrowableArray<BlockPReg*>* ll) {
02362
02363 if (exprStack && (args != NULL)) {
02364
02365
02366
02367 int len = exprStack->length();
02368 int i = min(args->length(), len);
02369 while (i-- > 0) {
02370 ::computeEscapingBlocks(this, exprStack->at(--len), ll, "exposed by a send");
02371 }
02372 }
02373 }
02374
02375 void PrimNode::computeEscapingBlocks(GrowableArray<BlockPReg*>* ll) {
02376
02377 if (exprStack) {
02378 int len = exprStack->length();
02379 int i = min(len, _pdesc->number_of_parameters());
02380 while (i-- > 0) {
02381 ::computeEscapingBlocks(this, exprStack->at(--len), ll, "exposed by a primitive call");
02382 }
02383 }
02384 }
02385
02386 void DLLNode::computeEscapingBlocks(GrowableArray<BlockPReg*>* ll) {
02387
02388 if (exprStack) {
02389 int len = exprStack->length();
02390 int i = min(len, nofArguments());
02391 while (i-- > 0) {
02392 ::computeEscapingBlocks(this, exprStack->at(--len), ll, "exposed by a DLL call");
02393 }
02394 }
02395 }
02396
02397 void ContextInitNode::computeEscapingBlocks(GrowableArray<BlockPReg*>* ll) {
02398
02399
02400 int i = nofTemps();
02401 while (i-- > 0) {
02402 Expr* e = _initializers->at(i);
02403 if (e) ::computeEscapingBlocks(this, e->preg(), ll, NULL);
02404 }
02405 }
02406
02407 void ArrayAtPutNode::computeEscapingBlocks(GrowableArray<BlockPReg*>* ll) {
02408
02409 ::computeEscapingBlocks(this, elem, ll, "stored into an array");
02410 }
02411
02412
02413
02414
02415
02416
02417 bool TypeTestNode::needsKlassLoad() const {
02418
02419 const int len = _hasUnknown ? _classes->length() : _classes->length() - 1;
02420 for (int i = 0; i < len; i++) {
02421 klassOop klass = _classes->at(i);
02422 if (klass != trueObj->klass() &&
02423 klass != falseObj->klass() &&
02424 klass != nilObj->klass() &&
02425 klass != smiKlassObj) {
02426 return true;
02427 }
02428 }
02429 return false;
02430 }
02431
02432 static bool hasUnknownCode(Node* n) {
02433 while (n->isTrivial()) n = n->next();
02434 return !n->isUncommonNode();
02435 }
02436
02437
02438 bool TypeTestNode::hasUnknownCode() const {
02439 if (!_hasUnknown) return false;
02440 return ::hasUnknownCode(next());
02441 }
02442
02443 bool TArithRRNode::hasUnknownCode() const {
02444 return ::hasUnknownCode(next1());
02445 }
02446
02447 bool AbstractArrayAtNode::hasUnknownCode() const {
02448 return ::hasUnknownCode(next1());
02449 }
02450
02451 Node* TypeTestNode::smiCase() const {
02452 int i = _classes->length();
02453 while (i-- > 0) {
02454 if (_classes->at(i) == smiKlassObj) return next(i+1);
02455 }
02456 return NULL;
02457 }
02458
02459
02460
02461
02462
02463 LoopHeaderNode::LoopHeaderNode() {
02464 _activated = false; _integerLoop = false; _tests = NULL;
02465 _enclosingLoop = NULL; _nestedLoops = NULL;
02466 _nofCalls = 0; _registerCandidates = NULL;
02467 }
02468
02469
02470 void LoopHeaderNode::activate(PReg* loopVar, PReg* lowerBound, PReg* upperBound, LoadOffsetNode* loopSizeLoad) {
02471 _activated = true;
02472 _integerLoop = true;
02473 _loopVar = loopVar;
02474 _lowerBound = lowerBound;
02475 _upperBound = upperBound;
02476 _upperLoad = loopSizeLoad;
02477 _arrayAccesses = new GrowableArray<AbstractArrayAtNode*>(10);
02478 }
02479
02480 void LoopHeaderNode::activate() {
02481 _activated = true;
02482 assert(_tests, "should have type tests");
02483 _loopVar = _lowerBound = _upperBound = NULL;
02484 _upperLoad = NULL;
02485 _arrayAccesses = NULL;
02486 }
02487
02488 void LoopHeaderNode::addArray(AbstractArrayAtNode* n) {
02489 assert(_activated, "shouldn't call");
02490 _arrayAccesses->append(n);
02491 }
02492
02493 void LoopHeaderNode::set_enclosingLoop(LoopHeaderNode* l) {
02494 assert(_enclosingLoop == NULL, "already set");
02495 _enclosingLoop = l;
02496 }
02497
02498 void LoopHeaderNode::addNestedLoop(LoopHeaderNode* l) {
02499 if (_nestedLoops == NULL) _nestedLoops = new GrowableArray<LoopHeaderNode*>(5);
02500 _nestedLoops->append(l);
02501 }
02502
02503 void LoopHeaderNode::addRegisterCandidate(LoopRegCandidate* c) {
02504 if (_registerCandidates == NULL) _registerCandidates = new GrowableArray<LoopRegCandidate*>(2);
02505 _registerCandidates->append(c);
02506 }
02507
02508
02509
02510 inline bool is_smi_type(GrowableArray<klassOop>* klasses) {
02511 return klasses->length() == 1 && klasses->at(0) == smiKlassObj;
02512 }
02513
02514 inline GrowableArray<klassOop>* make_smi_type() {
02515 GrowableArray<klassOop>* t = new GrowableArray<klassOop>(1);
02516 t->append(smiKlassObj);
02517 return t;
02518 }
02519
02520 void StoreNode::assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n) {
02521 if (is_smi_type(klasses) && r == src()) {
02522 if (CompilerDebug) cout(PrintLoopOpts)->print("*removing store check from N%d\n", id());
02523 setStoreCheck(false);
02524 }
02525 }
02526
02527 void AbstractArrayAtNode::assert_in_bounds(PReg* r, LoopHeaderNode* n) {
02528 if (r == _arg) {
02529 if (CompilerDebug && _needBoundsCheck) cout(PrintLoopOpts)->print("*removing bounds check from N%d\n", id());
02530 _needBoundsCheck = false;
02531 removeFailureIfPossible();
02532 }
02533 }
02534
02535 void AbstractArrayAtNode::collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const {
02536
02537 regs.append(_arg);
02538 klasses.append(make_smi_type());
02539 }
02540
02541 void AbstractArrayAtNode::assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n) {
02542 if (is_smi_type(klasses) && r == _arg) {
02543 if (CompilerDebug && !_intArg) cout(PrintLoopOpts)->print("*removing index tag check from N%d\n", id());
02544 _intArg = true;
02545 n->addArray(this);
02546 removeFailureIfPossible();
02547 } else if (r != _arg) {
02548 fatal("array can't be an integer");
02549 }
02550 }
02551
02552 void ArrayAtPutNode::collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const {
02553
02554 AbstractArrayAtNode::collectTypeTests(regs, klasses);
02555 if (stores_smi_elements(_access_type)) {
02556 regs.append(elem);
02557 assert(klasses.first()->first() == smiKlassObj, "must be smi type for index");
02558 klasses.append(klasses.first());
02559 }
02560 }
02561
02562 void ArrayAtPutNode::assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n) {
02563 if (is_smi_type(klasses) && r == elem) {
02564 if (CompilerDebug && _needs_store_check)
02565 cout(PrintLoopOpts)->print("*removing array store check from N%d\n", id());
02566 _needs_store_check = false;
02567 removeFailureIfPossible();
02568 } else if (r == _arg) {
02569 AbstractArrayAtPutNode::assert_preg_type(r, klasses, n);
02570 }
02571 }
02572
02573 void TArithRRNode::collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const {
02574
02575 if (canFail()) {
02576 GrowableArray<klassOop>* t = make_smi_type();
02577 if (!_arg1IsInt) {
02578 regs.append(_src);
02579 klasses.append(t);
02580 }
02581 if (!_arg2IsInt) {
02582 regs.append(_oper);
02583 klasses.append(t);
02584 }
02585 }
02586 }
02587
02588 void TArithRRNode::assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n) {
02589 if (is_smi_type(klasses) && r == _src) {
02590 if (CompilerDebug && !_arg1IsInt) cout(PrintLoopOpts)->print("*removing arith arg1 tag check from N%d\n", id());
02591 _arg1IsInt = true;
02592 }
02593 if (is_smi_type(klasses) && r == _oper) {
02594 if (CompilerDebug && !_arg2IsInt) cout(PrintLoopOpts)->print("*removing arith arg2 tag check from N%d\n", id());
02595 _arg2IsInt = true;
02596 }
02597 removeFailureIfPossible();
02598 }
02599
02600 void TypeTestNode::collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const {
02601 regs.append(_src);
02602 klasses.append(_classes);
02603 }
02604
02605 void TypeTestNode::assert_preg_type(PReg* r, GrowableArray<klassOop>* k, LoopHeaderNode* n) {
02606 assert(r == src(), "must be source");
02607 if (k->length() == 1) {
02608
02609 eliminateUnnecessary(k->at(0));
02610 } else {
02611
02612 assert(k->length() <= _classes->length(), "type cannot widen");
02613 setUnknown(false);
02614 }
02615 }
02616
02617
02618
02619
02620
02621 #ifdef PRODUCT
02622 #define DISABLED_IN_PRODUCT return buf;
02623 #else
02624 #define DISABLED_IN_PRODUCT
02625 #endif
02626
02627
02628 const int PrintStringLen = 40;
02629
02630 void BasicNode::print_short() { char buf[1024]; lprintf(print_string(buf, PrintHexAddresses)); }
02631 static int id_of(Node* node) { return node == NULL ? -1 : node->id(); }
02632
02633 char* PrologueNode::print_string(char* buf, bool printAddr) const {
02634 DISABLED_IN_PRODUCT
02635 char* b = buf;
02636 my_sprintf_len(buf, PrintStringLen, "Prologue");
02637 if (printAddr) my_sprintf(buf, "((PrologueNode*)%#lx", this);
02638 return b;
02639 }
02640
02641 char* InterruptCheckNode::print_string(char* buf, bool printAddr) const {
02642 DISABLED_IN_PRODUCT
02643 char* b = buf;
02644 my_sprintf_len(buf, PrintStringLen, "InterruptCheckNode");
02645 if (printAddr) my_sprintf(buf, "((InterruptCheckNode*)%#lx)", this);
02646 return b;
02647 }
02648
02649 char* LoadOffsetNode::print_string(char* buf, bool printAddr) const {
02650 DISABLED_IN_PRODUCT
02651 char* b = buf;
02652 my_sprintf_len(buf, PrintStringLen, "LoadOffset %s := %s[%#lx]", _dest->safeName(), _src->safeName(), offset);
02653 if (printAddr) my_sprintf(buf, "((LoadOffsetNode*)%#lx)", this);
02654 return b;
02655 }
02656
02657 char* LoadIntNode::print_string(char* buf, bool printAddr) const {
02658 DISABLED_IN_PRODUCT
02659 char* b = buf;
02660 my_sprintf_len(buf, PrintStringLen, "LoadInt %s := %#lx", _dest->safeName(), _value);
02661 if (printAddr) my_sprintf(buf, "((LoadIntNode*)%#lx)", this);
02662 return b;
02663 }
02664
02665 char* LoadUplevelNode::print_string(char* buf, bool printAddr) const {
02666 DISABLED_IN_PRODUCT
02667 char* b = buf;
02668 my_sprintf_len(buf, PrintStringLen, "LoadUpLevel %s := %s^%d[%d]", _dest->safeName(),
02669 _context0->safeName(), _nofLevels, _offset);
02670 if (printAddr) my_sprintf(buf, "((LoadUplevelNode*)%#lx)", this);
02671 return b;
02672 }
02673
02674 char* StoreOffsetNode::print_string(char* buf, bool printAddr) const {
02675 DISABLED_IN_PRODUCT
02676 char* b = buf;
02677 my_sprintf_len(buf, PrintStringLen, "StoreOffset %s[%#lx] := %s", _base->safeName(), _offset, _src->safeName());
02678 if (printAddr) my_sprintf(buf, "((StoreOffsetNode*)%#lx)", this);
02679 return b;
02680 }
02681
02682 char* StoreUplevelNode::print_string(char* buf, bool printAddr) const {
02683 DISABLED_IN_PRODUCT
02684 char* b = buf;
02685 my_sprintf_len(buf, PrintStringLen, "StoreUpLevel %s^%d[%d] := %s",
02686 _context0->safeName(), _nofLevels, _offset, _src->safeName());
02687 if (printAddr) my_sprintf(buf, "((StoreUplevelNode*)%#lx)", this);
02688 return b;
02689 }
02690
02691 char* AssignNode::print_string(char* buf, bool printAddr) const {
02692 DISABLED_IN_PRODUCT
02693 char* b = buf;
02694 my_sprintf_len(buf, PrintStringLen, "%s := %s", _dest->safeName(), _src->safeName());
02695 if (printAddr) my_sprintf(buf, "((AssignNode*)%#lx)", this);
02696 return b;
02697 }
02698
02699 char* SendNode::print_string(char* buf, bool printAddr) const {
02700 DISABLED_IN_PRODUCT
02701 char* b = buf;
02702 my_sprintf_len(buf,PrintStringLen, "Send %s NLR %ld ", _key->print_string(), id_of(nlrTestPoint()));
02703 if (printAddr) my_sprintf(buf, "((SendNode*)%#lx)", this);
02704 return b;
02705 }
02706
02707
02708 char* PrimNode::print_string(char* buf, bool printAddr) const {
02709 DISABLED_IN_PRODUCT
02710 char* b = buf;
02711 my_sprintf_len(buf, PrintStringLen, "PrimCall _%s NLR %ld", _pdesc->name(), id_of(nlrTestPoint()));
02712 if (printAddr) my_sprintf(buf, "((PrimNode*)%#lx)", this);
02713 return b;
02714 }
02715
02716
02717 char* DLLNode::print_string(char* buf, bool printAddr) const {
02718 DISABLED_IN_PRODUCT
02719 char* b = buf;
02720 my_sprintf_len(buf, PrintStringLen, "DLLCall <%s, %s> NLR %ld", _dll_name->as_string(), _function_name->as_string(), id_of(nlrTestPoint()));
02721 if (printAddr) my_sprintf(buf, "((DLLNode*)%#lx)", this);
02722 return b;
02723 }
02724
02725
02726 char* BlockCreateNode::print_string(char* buf, bool printAddr) const {
02727 DISABLED_IN_PRODUCT
02728 char* b = buf;
02729 my_sprintf_len(buf, PrintStringLen, "BlockCreate %s", _dest->safeName());
02730 if (printAddr) my_sprintf(buf, "((BlockCreateNode*)%#lx)", this);
02731 return b;
02732 }
02733
02734 char* BlockMaterializeNode::print_string(char* buf, bool printAddr) const {
02735 DISABLED_IN_PRODUCT
02736 char* b = buf;
02737 my_sprintf_len(buf, PrintStringLen, "BlockMaterialize %s", _dest->safeName());
02738 if (printAddr) my_sprintf(buf, "((BlockMaterializeNode*)%#lx)", this);
02739 return b;
02740 }
02741
02742 char* InlinedReturnNode::print_string(char* buf, bool printAddr) const {
02743 DISABLED_IN_PRODUCT
02744 char* b = buf;
02745 my_sprintf_len(buf, PrintStringLen, "InlinedReturn %s := %s", _dest->safeName(), _src->safeName());
02746 if (printAddr) my_sprintf(buf, "((InlinedReturnNode*)%#lx)", this);
02747 return b;
02748 }
02749
02750 char* NLRSetupNode::print_string(char* buf, bool printAddr) const {
02751 DISABLED_IN_PRODUCT
02752 char* b = buf;
02753 my_sprintf_len(buf, PrintStringLen, "NLReturn %s := %s", _dest->safeName(), _src->safeName());
02754 if (printAddr) my_sprintf(buf, "((NLRSetupNode*)%#lx)", this);
02755 return b;
02756 }
02757
02758 char* NLRContinuationNode::print_string(char* buf, bool printAddr) const {
02759 DISABLED_IN_PRODUCT
02760 char* b = buf;
02761 my_sprintf_len(buf, PrintStringLen, "NLR Continuation");
02762 if (printAddr) my_sprintf(buf, "((NLRContinuationNode*)%#lx)", this);
02763 return b;
02764 }
02765
02766 char* ReturnNode::print_string(char* buf, bool printAddr) const {
02767 DISABLED_IN_PRODUCT
02768 char* b = buf;
02769 my_sprintf_len(buf, PrintStringLen, "MethodReturn %s", _src->safeName());
02770 if (printAddr) my_sprintf(buf, "((ReturnNode*)%#lx)", this);
02771 return b;
02772 }
02773
02774 char* NLRTestNode::print_string(char* buf, bool printAddr) const {
02775 DISABLED_IN_PRODUCT
02776 char* b = buf;
02777 my_sprintf_len(buf, PrintStringLen, "NLRTest N%ld N%ld", id_of(next1()), id_of(next()));
02778 if (printAddr) my_sprintf(buf, "((NLRTestNode*)%#lx)", this);
02779 return b;
02780 }
02781
02782 char* ArithNode::opName() const { return ArithOpName[_op]; }
02783
02784 char* ArithRRNode::print_string(char* buf, bool printAddr) const {
02785 DISABLED_IN_PRODUCT
02786 char* b = buf;
02787 my_sprintf_len(buf, PrintStringLen, "%s := %s %s %s",
02788 _dest->safeName(), _src->safeName(), opName(), _oper->safeName());
02789 if (printAddr) my_sprintf(buf, "((ArithRRNode*)%#lx)", this);
02790 return b;
02791 }
02792
02793 char* FloatArithRRNode::print_string(char* buf, bool printAddr) const {
02794 DISABLED_IN_PRODUCT
02795 char* b = buf;
02796 my_sprintf_len(buf, PrintStringLen, "%s := %s %s %s",
02797 _dest->safeName(), _src->safeName(), opName(), _oper->safeName());
02798 if (printAddr) my_sprintf(buf, "((FloatArithRRNode*)%#lx)", this);
02799 return b;
02800 }
02801
02802 char* FloatUnaryArithNode::print_string(char* buf, bool printAddr) const {
02803 DISABLED_IN_PRODUCT
02804 char* b = buf;
02805 my_sprintf_len(buf, PrintStringLen, "%s := %s %s",
02806 _dest->safeName(), opName(), _src->safeName());
02807 if (printAddr) my_sprintf(buf, "((FloatUnaryArithNode*)%#lx)", this);
02808 return b;
02809 }
02810
02811 char* TArithRRNode::print_string(char* buf, bool printAddr) const {
02812 DISABLED_IN_PRODUCT
02813 char* b = buf;
02814 my_sprintf_len(buf, PrintStringLen, "%s := %s %s %s N%d, N%d",
02815 _dest->safeName(), _src->safeName(), ArithOpName[_op], _oper->safeName(),
02816 id_of(next1()), id_of(next()));
02817 if (printAddr) my_sprintf(buf, "((TArithRRNode*)%#lx)", this);
02818 return b;
02819 }
02820
02821 char* ArithRCNode::print_string(char* buf, bool printAddr) const {
02822 DISABLED_IN_PRODUCT
02823 char* b = buf;
02824 my_sprintf_len(buf, PrintStringLen, "%s := %s %s %#lx",
02825 _dest->safeName(), _src->safeName(), opName(), _oper);
02826 if (printAddr) my_sprintf(buf, "((ArithRCNode*)%#lx)", this);
02827 return b;
02828 }
02829
02830 char* BranchNode::print_string(char* buf, bool printAddr) const {
02831 DISABLED_IN_PRODUCT
02832 char* b = buf;
02833 my_sprintf_len(buf, PrintStringLen, "%s N%ld N%ld", BranchOpName[_op], id_of(next1()), id_of(next()));
02834 if (printAddr) my_sprintf(buf, "((BranchNode*)%#lx)", this);
02835 return b;
02836 }
02837
02838 char* TypeTestNode::print_string(char* buf, bool printAddr) const {
02839 DISABLED_IN_PRODUCT
02840 char* b = buf;
02841 my_sprintf(buf, "TypeTest %s, ", _src->safeName());
02842 for (int i = 1; i <= _classes->length(); i++) {
02843 klassOop m = _classes->at(i-1);
02844 my_sprintf(buf, m->print_value_string());
02845 my_sprintf(buf, ": N%ld; ", (i < nSuccessors() && next(i) != NULL) ? next(i)->id() : -1);
02846 }
02847 my_sprintf_len(buf, b + PrintStringLen - buf,
02848 "N%ld%s", id_of(next()),
02849 _hasUnknown ? "" : "*");
02850 if (printAddr) my_sprintf(buf, "((TypeTestNode*)%#lx)", this);
02851 return b;
02852 }
02853
02854 char* ArrayAtNode::print_string(char* buf, bool printAddr) const {
02855 DISABLED_IN_PRODUCT
02856 char* b = buf;
02857 my_sprintf_len(buf, PrintStringLen, "ArrayAt %s := %s[%s]",
02858 _dest->safeName(), _src->safeName(), _arg->safeName());
02859 if (printAddr) my_sprintf(buf, "((ArrayAtNode*)%#lx)", this);
02860 return b;
02861 }
02862
02863 char* ArrayAtPutNode::print_string(char* buf, bool printAddr) const {
02864 DISABLED_IN_PRODUCT
02865 char* b = buf;
02866 my_sprintf_len(buf, PrintStringLen, "ArrayAtPut %s[%s] := %s",
02867 _src->safeName(), _arg->safeName(), elem->safeName());
02868 if (printAddr) my_sprintf(buf, "((ArrayAtPutNode*)%#lx)", this);
02869 return b;
02870 }
02871
02872 char* FixedCodeNode::print_string(char* buf, bool printAddr) const {
02873 DISABLED_IN_PRODUCT
02874 char* b = buf;
02875 my_sprintf_len(buf, PrintStringLen, "DeadEnd");
02876 if (printAddr) my_sprintf(buf, "((FixedCodeNode*)%#lx)", this);
02877 return b;
02878 }
02879
02880 static int prevsLen;
02881 static char* mergePrintBuf;
02882 static void printPrevNodes(Node* n) {
02883 my_sprintf(mergePrintBuf, "N%ld%s", id_of(n), --prevsLen > 0 ? ", " : "");
02884 }
02885
02886 char* MergeNode::print_string(char* buf, bool printAddr) const {
02887 DISABLED_IN_PRODUCT
02888 char* b = buf;
02889 my_sprintf(buf, "Merge ");
02890 prevsLen = _prevs->length();
02891 mergePrintBuf = buf;
02892 _prevs->apply(printPrevNodes);
02893 buf = mergePrintBuf;
02894 my_sprintf_len(buf, b + PrintStringLen - buf, " ");
02895 if (printAddr) my_sprintf(buf, "((MergeNode*)%#lx)", this);
02896 return b;
02897 }
02898
02899 char* LoopHeaderNode::print_string(char* buf, bool printAddr) const {
02900 DISABLED_IN_PRODUCT
02901 char* b = buf;
02902 my_sprintf(buf, "LoopHeader ");
02903 if (_activated) {
02904 if (_integerLoop) {
02905 my_sprintf(buf, "int ");
02906 my_sprintf(buf, "%s=[%s..%s] ", _loopVar->safeName(), _lowerBound->safeName(),
02907 _upperBound ? _upperBound->safeName() : _upperLoad->base()->safeName());
02908 }
02909 if (_registerCandidates != NULL) {
02910 my_sprintf(buf, "reg vars = ");
02911 for (int i = 0; i < _tests->length(); i++) my_sprintf(buf, "%s ", _registerCandidates->at(i)->preg()->name());
02912 }
02913 if (_tests != NULL) {
02914 for (int i = 0; i < _tests->length(); i++) {
02915 HoistedTypeTest* t = _tests->at(i);
02916 if (t->testedPR->loc != unAllocated) {
02917 stringStream s(50);
02918 t->print_test_on(&s);
02919 my_sprintf(buf, "%s ", s.as_string());
02920 }
02921 }
02922 }
02923 my_sprintf_len(buf, PrintStringLen - (buf - b), " ");
02924 } else {
02925 my_sprintf_len(buf, PrintStringLen - 11, "(inactive)");
02926 }
02927 if (printAddr) my_sprintf(buf, "((LoopHeaderNode*)%#lx)", this);
02928 return b;
02929 }
02930
02931 char* ContextCreateNode::print_string(char* buf, bool printAddr) const {
02932 DISABLED_IN_PRODUCT
02933 char* b = buf;
02934 my_sprintf_len(buf, PrintStringLen, "Create Context %s", _dest->safeName());
02935 if (printAddr) my_sprintf(buf, "((ContextCreateNode*)%#lx)", this);
02936 return b;
02937 }
02938
02939 char* ContextInitNode::print_string(char* buf, bool printAddr) const {
02940 DISABLED_IN_PRODUCT
02941 char* b = buf;
02942 my_sprintf(buf, "Initialize context ");
02943 if (_src == NULL) {
02944 my_sprintf(buf, "(optimized away) ");
02945 } else {
02946 my_sprintf(buf, "%s { ", _src->safeName());
02947 for (int i = 0; i < contents()->length(); i++) {
02948 my_sprintf(buf, " %s := ", contents()->at(i)->preg()->safeName());
02949 Expr* e = _initializers->at(i);
02950 my_sprintf(buf, " %s; ", e->preg()->safeName());
02951 }
02952 }
02953 my_sprintf_len(buf, b + PrintStringLen - buf, "}");
02954 if (printAddr) my_sprintf(buf, "((ContextInitNode*)%#lx)", this);
02955 return b;
02956 }
02957
02958 char* ContextZapNode::print_string(char* buf, bool printAddr) const {
02959 DISABLED_IN_PRODUCT
02960 char* b = buf;
02961 my_sprintf_len(buf, PrintStringLen, "Zap Context %s", isActive() ? context()->safeName() : "- inactive");
02962 if (printAddr) my_sprintf(buf, "((ContextZapNode*)%#lx)", this);
02963 return b;
02964 }
02965
02966 char* InlinedPrimitiveNode::print_string(char* buf, bool printAddr) const {
02967 DISABLED_IN_PRODUCT
02968 char* b = buf;
02969 my_sprintf(buf, "%s := ", _dest->safeName());
02970 char* op_name;
02971 switch (_op) {
02972 case obj_klass : op_name = "obj_klass"; break;
02973 case obj_hash : op_name = "obj_hash"; break;
02974 case proxy_byte_at : op_name = "proxy_byte_at"; break;
02975 case proxy_byte_at_put : op_name = "proxy_byte_at_put"; break;
02976 default : op_name = "*** unknown primitive ***";break;
02977 }
02978 my_sprintf(buf, "%s(", op_name);
02979 my_sprintf(buf, " %s", _src ->safeName());
02980 my_sprintf(buf, " %s", _arg1->safeName());
02981 my_sprintf(buf, " %s", _arg2->safeName());
02982 my_sprintf_len(buf, b + PrintStringLen - buf, ")");
02983 if (printAddr) my_sprintf(buf, "((InlinedPrimitiveNode*)%#lx)", this);
02984 return b;
02985 }
02986
02987 char* UncommonNode::print_string(char* buf, bool printAddr) const {
02988 DISABLED_IN_PRODUCT
02989 char* b = buf;
02990 my_sprintf_len(buf, PrintStringLen, "UncommonBranch");
02991 if (printAddr) my_sprintf(buf, "((UncommonNode*)%#lx)", this);
02992 return b;
02993 }
02994
02995 char* NopNode::print_string(char* buf, bool printAddr) const {
02996 DISABLED_IN_PRODUCT
02997 char* b = buf;
02998 my_sprintf_len(buf, PrintStringLen, "Nop");
02999 if (printAddr) my_sprintf(buf, "((NopNode*)%#lx)", this);
03000 return b;
03001 }
03002
03003 char* CommentNode::print_string(char* buf, bool printAddr) const {
03004 DISABLED_IN_PRODUCT
03005 char* b = buf;
03006 my_sprintf_len(buf, PrintStringLen, "'%s' ", comment);
03007 if (printAddr) my_sprintf(buf, "((CommentNode*)%#lx)", this);
03008 return b;
03009 }
03010
03011 void BasicNode::printID() const {
03012 lprintf("%4ld:%1s %-4s", id(), deleted ? "D" : " ", " ");
03013
03014 }
03015
03016 void Node::verify() const {
03017 if (deleted) return;
03018 if (!firstPrev() && !isPrologueNode())
03019 error("Node %#lx: no predecessor", this);
03020 if (firstPrev() && !firstPrev()->isSuccessor(this))
03021 error("prev->next != this for Node %#lx", this);
03022 if (_bb && !_bb->contains(this))
03023 error("BB doesn't contain Node %#lx", this);
03024 if (next() && ! next()->isPredecessor(this))
03025 error("next->prev != this for Node %#lx", this);
03026 if (bbIterator->blocksBuilt && _bb == NULL) error("Node %#lx: doesn't belong to any BB", this);
03027 if (next() == NULL && !isExitNode() &&
03028 !isCommentNode())
03029 error("Node %#lx has no successor", this);
03030 if (next() != NULL && isExitNode()) {
03031 for (Node* n = next();
03032 n && (n->isCommentNode() || n->isDeadEndNode());
03033 n = n->next()) ;
03034 if (n) error("exit node %#lx has a successor (%#lx)", this, next());
03035 }
03036 }
03037
03038 void NonTrivialNode::verify() const {
03039 if (deleted) return;
03040 if (hasSrc()) src()->verify();
03041 if (hasDest()) {
03042 dest()->verify();
03043 if (dest()->isConstPReg()) {
03044 error("Node %#lx: dest %#lx is ConstPR", this, dest());
03045 }
03046 }
03047 if (isAssignmentLike() && (!hasSrc() || !hasDest()))
03048 error("Node %#lx: isAssignmentLike() implies hasSrc/Dest", this);
03049 Node::verify();
03050 }
03051
03052 void LoadOffsetNode::verify() const {
03053 if (deleted) return;
03054 NonTrivialNode::verify();
03055 base()->verify();
03056 if (offset < 0) error("Node %#lx: offset must be >= 0", this);
03057 }
03058
03059 void LoadUplevelNode::verify() const {
03060 if (deleted) return;
03061 if (_context0 == NULL) error("Node %#lx: context0 is NULL", this);
03062 if (_nofLevels < 0) error("Node %#lx: nofLevels must be >= 0", this);
03063 if (_offset < 0) error("Node %#lx: offset must be >= 0", this);
03064 NonTrivialNode::verify();
03065 _context0->verify();
03066 }
03067
03068 void StoreOffsetNode::verify() const {
03069 if (deleted) return;
03070 NonTrivialNode::verify();
03071 base()->verify();
03072 if (_offset < 0) error("Node %#lx: offset must be >= 0", this);
03073 }
03074
03075 void StoreUplevelNode::verify() const {
03076 if (deleted) return;
03077 if (_context0 == NULL) error("Node %#lx: context0 is NULL", this);
03078 if (_nofLevels < 0) error("Node %#lx: nofLevels must be > 0", this);
03079 if (_offset < 0) error("Node %#lx: offset must be >= 0", this);
03080 NonTrivialNode::verify();
03081 _context0->verify();
03082 }
03083
03084 void MergeNode::verify() const {
03085 if (deleted) return;
03086 if (isLoopStart && isLoopEnd) error("MergeNode %#x: cannot be both start and end of loop");
03087 TrivialNode::verify();
03088 }
03089
03090 void BlockCreateNode::verify() const {
03091 if (deleted) return;
03092 PrimNode::verify();
03093 }
03094
03095 void ReturnNode::verify() const {
03096 if (deleted) return;
03097 AbstractReturnNode::verify();
03098 if (next()) error("ReturnNode %#lx has a successor", this);
03099 }
03100
03101 void NLRSetupNode::verify() const {
03102 if (deleted) return;
03103 AbstractReturnNode::verify();
03104 if (next()) error("NLRSetupNode %#lx has a successor", this);
03105 }
03106
03107 void NLRContinuationNode::verify() const {
03108 if (deleted) return;
03109 AbstractReturnNode::verify();
03110 if (next()) error("NLRContinuationNode %#lx has a successor", this);
03111 }
03112
03113 void NLRTestNode::verify() const {
03114 if (deleted) return;
03115 AbstractBranchNode::verify(false);
03116 if (next() == NULL) error("NLRTestNode %#lx has no continue-NLR node", this);
03117 if (next1() == NULL) error("NLRTestNode %#lx has no end-of-NLR node", this);
03118 }
03119
03120 void InlinedReturnNode::verify() const {
03121 if (deleted) return;
03122 AbstractReturnNode::verify();
03123 if (!next()) {
03124 error("InlinedReturnNode %#lx has no successor", this);
03125 } else {
03126 Node* nextAfterMerge = next()->next();
03127 if (nextAfterMerge->scope() == scope())
03128 error("InlinedReturnNode %#lx: successor is in same scope", this);
03129 }
03130 }
03131
03132 void ContextCreateNode::verify() const {
03133 PrimNode::verify();
03134 }
03135
03136 void ContextInitNode::verify() const {
03137 if (deleted) return;
03138 int n = nofTemps();
03139 if ((n != contents()->length()) ||
03140 (n != _initializers->length()) ||
03141 (_contentDefs != NULL) && (n != _contentDefs->length()) ||
03142 (_initializerUses != NULL) && (n != _initializerUses->length())) {
03143 error("ContextInitNode %#lx: bad nofTemps %d", this, n);
03144 }
03145 int i = nofTemps();
03146 while (i-- > 0) {
03147 Expr* e = _initializers->at(i);
03148 if (e != NULL) e->verify();
03149 contents()->at(i)->verify();
03150 PReg* r = contents()->at(i)->preg();
03151 if (_src == NULL && r->loc.isContextLocation()) {
03152 ((ContextInitNode*)this)->print();
03153 scope()->print();
03154 error("ContextInitNode %#lx: context eliminated but temp %d is context location", this, i);
03155 }
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169 }
03170 }
03171
03172 void ContextZapNode::verify() const {
03173 if (deleted) return;
03174 if (_src != scope()->context()) {
03175 error("ContextZapNode %#lx: wrong context %#lx", this, _src);
03176 }
03177 NonTrivialNode::verify();
03178 }
03179
03180 void CallNode::verify() const {
03181 if (deleted) return;
03182 if ((exprStack != NULL) && (args != NULL)) {
03183 if (exprStack->length() + 1 < args->length()) {
03184 error("CallNode %#lx: exprStack is too short", this);
03185 }
03186 }
03187 }
03188
03189 void ArithRRNode::verify() const {
03190 if (deleted) return;
03191 ArithNode::verify();
03192 _oper->verify();
03193 }
03194
03195 void TArithRRNode::verify() const {
03196 if (deleted) return;
03197 AbstractBranchNode::verify(true);
03198 if ((_op < tAddArithOp) || (tCmpArithOp < _op)) {
03199 error("TArithRRNode %#lx: wrong opcode %ld", this, _op);
03200 }
03201 }
03202
03203 void FloatArithRRNode::verify() const {
03204 if (deleted) return;
03205 ArithRRNode::verify();
03206
03207 }
03208
03209 void FloatUnaryArithNode::verify() const {
03210 if (deleted) return;
03211 ArithNode::verify();
03212
03213 }
03214
03215 void AbstractBranchNode::verify(bool verifySuccessors) const {
03216 if (deleted) return;
03217 NonTrivialNode::verify();
03218 if (verifySuccessors && !canFail() && failureBranch() != NULL) {
03219 error("Node %#x: cannot fail, but failure branch is still there", this);
03220 }
03221 }
03222
03223 void InlinedPrimitiveNode::verify() const {
03224 if (deleted) return;
03225 AbstractBranchNode::verify(true);
03226
03227 }
03228
03229 void UncommonNode::verify() const {
03230 if (deleted) return;
03231 if ((Node*)this != bb()->last)
03232 error("UncommonNode %#lx: not last node in BB", this);
03233 NonTrivialNode::verify();
03234 }
03235
03236 void TypeTestNode::verify() const {
03237 if (deleted) return;
03238 if ((Node*)this != bb()->last)
03239 error("TypeTestNode %#lx: not last node in BB", this);
03240 NonTrivialNode::verify();
03241 }
03242
03243
03244
03245 void printNodes(Node* n) {
03246 for ( ; n; n = n->next()) {
03247 n->printID(); n->print_short(); lprintf("\n");
03248 }
03249 }
03250
03251 # endif