00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 # ifdef DELTA_COMPILER
00026
00027
00028
00029
00030
00031 class Node;
00032
00033 class TrivialNode;
00034 class MergeNode;
00035 class NopNode;
00036 class CommentNode;
00037 class FixedCodeNode;
00038 class LoopHeaderNode;
00039
00040 class NonTrivialNode;
00041
00042 class PrologueNode;
00043
00044 class LoadNode;
00045 class LoadIntNode;
00046 class LoadOffsetNode;
00047 class LoadUplevelNode;
00048
00049 class StoreNode;
00050 class AssignNode;
00051 class StoreOffsetNode;
00052 class StoreUplevelNode;
00053
00054 class AbstractReturnNode;
00055 class ReturnNode;
00056 class NLRSetupNode;
00057 class InlinedReturnNode;
00058 class NLRContinuationNode;
00059
00060 class ArithNode;
00061 class AbstractBranchNode;
00062 class TArithRRNode;
00063 class CallNode;
00064 class SendNode;
00065 class PrimNode;
00066 class BlockCreateNode;
00067 class BlockMaterializeNode;
00068 class InterruptCheckNode;
00069 class DLLNode;
00070 class ContextCreateNode;
00071
00072 class AbstractArrayAtNode;
00073 class ArrayAtNode;
00074 class AbstractArrayAtPutNode;
00075 class ArrayAtPutNode;
00076
00077 class InlinedPrimitiveNode;
00078
00079 class BranchNode;
00080 class TypeTestNode;
00081 class NLRTestNode;
00082 class ContextInitNode;
00083 class ContextZapNode;
00084
00085 class UncommonNode;
00086
00087 void initNodes();
00088
00089
00090
00091
00092
00093
00094 class PRegMapping;
00095
00096 class BasicNode: public PrintableResourceObj {
00097 protected:
00098 BB* _bb;
00099 int16 _id;
00100 int16 _num;
00101 InlinedScope* _scope;
00102 int16 _bci;
00103 PRegMapping* _mapping;
00104
00105 public:
00106 Label label;
00107 bool dontEliminate;
00108 bool deleted;
00109
00110 int id() const { return this == NULL ? -1 : _id; }
00111 BB* bb() const { return _bb; }
00112 int num() const { return _num; }
00113 InlinedScope* scope() const { return _scope; }
00114 int bci() const { return _bci; }
00115
00116 void setBB(BB* b) { _bb = b; }
00117 void setNum(int n) { _num = n; }
00118 void setScope(InlinedScope* s);
00119
00120 static int currentID;
00121 static int currentCommentID;
00122 static ScopeInfo lastScopeInfo;
00123 static int lastBCI;
00124
00125 BasicNode();
00126
00127 virtual bool isPrologueNode() const { return false; }
00128 virtual bool isAssignNode() const { return false; }
00129 virtual bool isTArithNode() const { return false; }
00130 virtual bool isArithNode() const { return false; }
00131 virtual bool isNLRSetupNode() const { return false; }
00132 virtual bool isNLRTestNode() const { return false; }
00133 virtual bool isNLRContinuationNode() const { return false; }
00134 virtual bool isReturnNode() const { return false; }
00135 virtual bool isInlinedReturnNode() const { return false; }
00136 virtual bool isLoopHeaderNode() const { return false; }
00137 virtual bool isExitNode() const { return false; }
00138 virtual bool isMergeNode() const { return false; }
00139 virtual bool isBranchNode() const { return false; }
00140 virtual bool isBlockCreateNode() const { return false; }
00141 virtual bool isContextCreateNode() const { return false; }
00142 virtual bool isContextInitNode() const { return false; }
00143 virtual bool isContextZapNode() const { return false; }
00144 virtual bool isCommentNode() const { return false; }
00145 virtual bool isSendNode() const { return false; }
00146 virtual bool isCallNode() const { return false; }
00147 virtual bool isStoreNode() const { return false; }
00148 virtual bool isDeadEndNode() const { return false; }
00149 virtual bool isTypeTestNode() const { return false; }
00150 virtual bool isUncommonNode() const { return false; }
00151 virtual bool isNopNode() const { return false; }
00152 virtual bool isCmpNode() const { return false; }
00153 virtual bool isArraySizeLoad() const { return false; }
00154 virtual bool isAccessingFloats() const { return false; }
00155 virtual bool isTrivial() const = 0;
00156
00157 protected:
00158 virtual Node* clone(PReg* from, PReg* to) const { SubclassResponsibility(); return NULL; }
00159 void genPcDesc();
00160 public:
00161
00162 virtual int cost() const { return oopSize; }
00163 virtual bool hasDest() const { return false; }
00164 virtual bool canCopyPropagate() const { return false; }
00165
00166
00167 bool canCopyPropagate(Node* fromNode) const;
00168 virtual bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false) = 0;
00169 virtual bool canCopyPropagateOop() const { return false; }
00170
00171
00172 virtual bool isAssignmentLike() const { return false; }
00173
00174 virtual bool shouldCopyWhenSplitting() const { return false; }
00175 virtual bool hasSrc() const { return false; }
00176 virtual bool hasConstantSrc() const { return false; }
00177 virtual oop constantSrc() const { ShouldNotCallThis(); return 0; }
00178 virtual bool canChangeDest() const { assert(hasDest(), "shouldn't call"); return true; }
00179
00180 virtual bool endsBB() const = 0;
00181 virtual bool startsBB() const { return false; }
00182
00183 int loopDepth() const { return _bb->loopDepth(); }
00184
00185 virtual BB* newBB();
00186 virtual void makeUses(BB* bb) { Unused(bb); }
00187 virtual void removeUses(BB* bb) { Unused(bb); }
00188 virtual void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false) = 0;
00189 virtual bool canBeEliminated() const { return !dontEliminate; }
00190 virtual void computeEscapingBlocks(GrowableArray<BlockPReg*>* lst) { Unused(lst); }
00191 virtual void markAllocated(int* use_count, int* def_count) = 0;
00192 virtual SimpleBitVector trashedMask();
00193 virtual void gen();
00194 virtual void apply(NodeVisitor* v) { ShouldNotCallThis(); }
00195 virtual Node* likelySuccessor() const = 0;
00196 virtual Node* uncommonSuccessor() const = 0;
00197 void removeUpToMerge();
00198 Node* copy(PReg* from, PReg* to) const;
00199
00200
00201
00202
00203
00204 virtual bool doesTypeTests() const { return false; }
00205 virtual bool hasUnknownCode() const { return false; }
00206 virtual void collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const { ShouldNotCallThis(); }
00207
00208 virtual void assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n) {}
00209 virtual void assert_in_bounds(PReg* r, LoopHeaderNode* n) {}
00210
00211 virtual void print_short();
00212 virtual void print() { print_short(); }
00213 virtual char* print_string(char* buf, bool printAddr = true) const = 0;
00214 void printID() const;
00215 virtual void verify() const {}
00216
00217
00218
00219
00220
00221 PRegMapping* mapping() const;
00222 bool hasMapping() const { return _mapping != NULL; }
00223 void setMapping(PRegMapping* mapping);
00224 };
00225
00226
00227
00228
00229
00230 class Node: public BasicNode {
00231 protected:
00232 Node *_prev, *_next;
00233 Node() { _prev = _next = NULL; }
00234
00235 public:
00236 virtual bool endsBB() const;
00237 virtual Node* likelySuccessor() const;
00238 virtual Node* uncommonSuccessor() const;
00239 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00240 virtual void verify() const;
00241
00242 friend class NodeFactory;
00243
00244
00245 virtual bool hasSingleSuccessor() const { return true; }
00246 virtual bool hasSinglePredecessor() const { return true; }
00247 virtual int nPredecessors() const { return _prev ? 1 : 0; }
00248 virtual int nSuccessors() const { return _next ? 1 : 0; }
00249 virtual bool isPredecessor(const Node* n) const { return _prev == n; }
00250 virtual bool isSuccessor(const Node* n) const { return _next == n; }
00251 Node* next() const { return _next; }
00252 virtual Node* next1() const { return NULL; }
00253 virtual Node* next(int i) const {
00254 if (i == 0) return _next; else { fatal("single next"); return NULL;} }
00255 virtual Node* firstPrev() const { return _prev; }
00256 virtual Node* prev(int n) const { if (n == 0) return _prev; else fatal("single prev"); return NULL; }
00257
00258 virtual void setPrev(Node* p) { assert(_prev == NULL, "already set"); _prev = p; }
00259 virtual void movePrev(Node* from, Node* to) { assert(_prev == from, "mismatched prev link"); _prev = to; }
00260
00261 void setNext(Node* n) { assert(_next == NULL, "already set"); _next = n; }
00262 virtual void setNext1(Node* n) { Unused(n); ShouldNotCallThis(); }
00263 virtual void setNext(int i, Node* n) { if (i == 0) setNext(n); else fatal("subclass"); }
00264 virtual void moveNext(Node* from, Node* to) { assert(_next == from, "mismatched next link"); _next = to; }
00265
00266 protected:
00267 virtual void removeMe();
00268 Node* endOfList() const;
00269
00270 public:
00271 virtual void removePrev(Node* n);
00272
00273 public:
00274 virtual void removeNext(Node* n);
00275 Node* append(Node* p) { setNext(p); p->setPrev(this); return p; }
00276 Node* append1(Node* p) { setNext1(p); p->setPrev(this); return p; }
00277 Node* append(int i, Node* p) { setNext(i, p); p->setPrev(this); return p; }
00278 Node* appendEnd(Node* p) { return endOfList()->append(p); }
00279
00280 void insertNext(Node* n) {
00281 assert(hasSingleSuccessor(), ">1 successors");
00282 n->setNext(_next); n->setPrev(this);
00283 _next->movePrev(this, n); _next = n; }
00284 void insertPrev(Node* n) {
00285 assert(n->hasSinglePredecessor(), "where to insert?");
00286 n->setPrev(_prev); n->setNext(this);
00287 _prev->moveNext(this, n); _prev = n; }
00288
00289 friend class NodeBuilder;
00290 };
00291
00292
00293 class TrivialNode: public Node {
00294 public:
00295 bool isTrivial() const { return true; }
00296 int cost() const { return 0; }
00297 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false) { return false; }
00298 void markAllocated(int* use_count, int* def_count) {}
00299
00300
00301
00302
00303 friend class NodeFactory;
00304 };
00305
00306
00307 class NonTrivialNode: public Node {
00308 protected:
00309 PReg* _dest;
00310 PReg* _src;
00311 Use* srcUse;
00312 Def* destDef;
00313
00314 NonTrivialNode();
00315
00316 public:
00317 bool isTrivial() const { return false; }
00318 PReg* src() const;
00319 PReg* dest() const;
00320 PReg* dst() const { return dest(); }
00321 void setDest(BB* bb, PReg* d);
00322 virtual bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00323 void makeUses(BB* bb);
00324 void removeUses(BB* bb);
00325 void verify() const;
00326
00327 friend class NodeFactory;
00328 };
00329
00330
00331 class PrologueNode : public NonTrivialNode {
00332 protected:
00333 LookupKey* _key;
00334 const int _nofArgs;
00335 const int _nofTemps;
00336
00337 PrologueNode(LookupKey* key, int nofArgs, int nofTemps) : _nofArgs(nofArgs), _nofTemps(nofTemps) {
00338 _key = key;
00339 }
00340
00341 public:
00342 bool isPrologueNode() const { return true; }
00343 virtual bool canChangeDest() const { return false; }
00344 Node* clone(PReg* from, PReg* to) const;
00345 void makeUses(BB* bb);
00346 void removeUses(BB* bb) { ShouldNotCallThis(); }
00347 void gen();
00348 void apply(NodeVisitor* v) { v->aPrologueNode(this); }
00349 bool canBeEliminated() const { return false; }
00350 void markAllocated(int* use_count, int* def_count) {
00351 Unused(use_count); Unused(def_count); }
00352 char* print_string(char* buf, bool printAddr = true) const;
00353
00354 friend class NodeFactory;
00355 };
00356
00357
00358 class LoadNode: public NonTrivialNode {
00359 protected:
00360 LoadNode(PReg* d) { _dest = d; assert(d, "dest is NULL"); }
00361
00362 public:
00363 bool hasDest() const { return true; }
00364 bool canCopyPropagate() const { return true; }
00365 bool canCopyPropagateOop() const { return true; }
00366 void makeUses(BB* bb);
00367 void removeUses(BB* bb);
00368 void markAllocated(int* use_count, int* def_count);
00369 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00370
00371 friend class NodeFactory;
00372 };
00373
00374
00375 class LoadIntNode: public LoadNode {
00376 protected:
00377 int _value;
00378
00379 LoadIntNode(PReg* dst, int value) : LoadNode(dst) { _value = value; }
00380
00381 public:
00382 Node* clone(PReg* from, PReg* to) const;
00383 int value() { return _value; }
00384 void gen();
00385 void apply(NodeVisitor* v) { v->aLoadIntNode(this); }
00386 char* print_string(char* buf, bool printAddr = true) const;
00387
00388 friend class NodeFactory;
00389 };
00390
00391
00392 class LoadOffsetNode: public LoadNode {
00393 public:
00394
00395 int offset;
00396 bool isArraySize;
00397
00398 protected:
00399 LoadOffsetNode(PReg* dst, PReg* b, int offs, bool arr) : LoadNode(dst) {
00400 _src = b; offset = offs; isArraySize = arr; }
00401
00402 public:
00403 Node* clone(PReg* from, PReg* to) const;
00404 PReg* base() const { return _src; }
00405 bool hasSrc() const { return true; }
00406 bool isArraySizeLoad() const { return isArraySize; }
00407 void makeUses(BB* bb);
00408 void removeUses(BB* bb);
00409 void markAllocated(int* use_count, int* def_count);
00410 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00411 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00412 void gen();
00413 void apply(NodeVisitor* v) { v->aLoadOffsetNode(this); }
00414 void verify() const;
00415 char* print_string(char* buf, bool printAddr = true) const;
00416
00417 friend class NodeFactory;
00418 };
00419
00420
00421 class LoadUplevelNode: public LoadNode {
00422 private:
00423 Use* _context0Use;
00424 PReg* _context0;
00425 int _nofLevels;
00426 int _offset;
00427 symbolOop _name;
00428
00429 protected:
00430 LoadUplevelNode(PReg* dst, PReg* context0, int nofLevels, int offset, symbolOop name);
00431
00432 public:
00433 PReg* context0() const { return _context0; }
00434 int nofLevels() const { return _nofLevels; }
00435 int offset() const { return _offset; }
00436 Node* clone(PReg* from, PReg* to) const;
00437 void makeUses(BB* bb);
00438 void removeUses(BB* bb);
00439 void markAllocated(int* use_count, int* def_count);
00440 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00441 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00442 void gen();
00443 void apply(NodeVisitor* v) { v->aLoadUplevelNode(this); }
00444 void verify() const;
00445 char* print_string(char* buf, bool printAddr = true) const;
00446
00447 friend class NodeFactory;
00448 };
00449
00450
00451 class StoreNode: public NonTrivialNode {
00452 protected:
00453 StoreNode(PReg* s) { _src = s; assert(_src, "src is NULL"); }
00454
00455 public:
00456 bool isStoreNode() const { return true; }
00457 bool canCopyPropagate() const { return true; }
00458 bool canCopyPropagateOop() const { return true; }
00459 bool hasSrc() const { return true; }
00460 virtual bool needsStoreCheck() const { return false; }
00461 virtual char* action() const = NULL;
00462 virtual void setStoreCheck(bool ncs) {}
00463 void assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n);
00464 void makeUses(BB* bb);
00465 void removeUses(BB* bb);
00466 void markAllocated(int* use_count, int* def_count);
00467 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00468 void computeEscapingBlocks(GrowableArray<BlockPReg*>* l);
00469
00470 friend class NodeFactory;
00471 };
00472
00473
00474 class StoreOffsetNode: public StoreNode {
00475
00476
00477 private:
00478 PReg* _base;
00479 Use* _baseUse;
00480 int _offset;
00481 bool _needsStoreCheck;
00482
00483 protected:
00484 StoreOffsetNode(PReg* s, PReg* b, int o, bool nsc) : StoreNode(s) {
00485 _base = b; assert(b, "base is NULL"); _offset = o; _needsStoreCheck = nsc; }
00486
00487 public:
00488 PReg* base() const { return _base; }
00489 int offset() const { return _offset; }
00490 bool needsStoreCheck() const { return _needsStoreCheck; }
00491 bool hasSrc() const { return true; }
00492 void setStoreCheck(bool ncs) { _needsStoreCheck = ncs; }
00493 char* action() const { return "stored into an object"; }
00494 Node* clone(PReg* from, PReg* to) const;
00495 void makeUses(BB* bb);
00496 void removeUses(BB* bb);
00497 void markAllocated(int* use_count, int* def_count);
00498 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00499 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00500 bool canBeEliminated() const { return false; }
00501 void gen();
00502 void apply(NodeVisitor* v) { v->aStoreOffsetNode(this); }
00503 void verify() const;
00504 char* print_string(char* buf, bool printAddr = true) const;
00505
00506 friend class NodeFactory;
00507 };
00508
00509
00510 class StoreUplevelNode: public StoreNode {
00511
00512
00513 private:
00514 Use* _context0Use;
00515 PReg* _context0;
00516 int _nofLevels;
00517 int _offset;
00518 bool _needsStoreCheck;
00519 symbolOop _name;
00520
00521 protected:
00522 StoreUplevelNode(PReg* src, PReg* context0, int nofLevels, int offset, symbolOop name, bool needsStoreCheck);
00523
00524 public:
00525 PReg* context0() const { return _context0; }
00526 int nofLevels() const { return _nofLevels; }
00527 int offset() const { return _offset; }
00528 bool needsStoreCheck() const { return _needsStoreCheck; }
00529 void setStoreCheck(bool ncs) { _needsStoreCheck = ncs; }
00530 char* action() const { return "stored into a context temporary"; }
00531 Node* clone(PReg* from, PReg* to) const;
00532 void makeUses(BB* bb);
00533 void removeUses(BB* bb);
00534 void markAllocated(int* use_count, int* def_count);
00535 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00536 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00537 void gen();
00538 void apply(NodeVisitor* v) { v->aStoreUplevelNode(this); }
00539 void verify() const;
00540 char* print_string(char* buf, bool printAddr = true) const;
00541
00542 friend class NodeFactory;
00543 };
00544
00545
00546 class AssignNode : public StoreNode {
00547
00548 protected:
00549 AssignNode(PReg* s, PReg* d);
00550
00551 public:
00552 int cost() const { return oopSize/2; }
00553 bool isAccessingFloats() const;
00554 bool isAssignNode() const { return true; }
00555 bool hasDest() const { return true; }
00556 bool hasSrc() const { return true; }
00557 bool hasConstantSrc() const { return _src->isConstPReg(); }
00558 bool isAssignmentLike() const { return true; }
00559 bool shouldCopyWhenSplitting() const { return true; }
00560 bool canBeEliminated() const;
00561 oop constantSrc() const;
00562 char* action() const { return _dest->isSAPReg() ?
00563 "passed as an argument" : "assigned to a local"; }
00564 Node* clone(PReg* from, PReg* to) const;
00565 void makeUses(BB* bb);
00566 void removeUses(BB* bb);
00567 void markAllocated(int* use_count, int* def_count);
00568 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00569 void gen();
00570 void apply(NodeVisitor* v) { v->anAssignNode(this); }
00571 char* print_string(char* buf, bool printAddr = true) const;
00572
00573 protected:
00574 void genOop();
00575
00576 friend class NodeFactory;
00577 };
00578
00579
00580 class AbstractReturnNode: public NonTrivialNode {
00581 protected:
00582 AbstractReturnNode(int bci, PReg* src, PReg* dest) { _bci = bci; _src = src; _dest = dest; }
00583
00584 public:
00585 bool canBeEliminated() const { return false; }
00586 bool isReturnNode() const { return true; }
00587 bool endsBB() const { return true; }
00588 bool canCopyPropagate() const { return true; }
00589 bool canCopyPropagateOop() const { return true; }
00590 bool hasSrc() const { return true; }
00591 bool isAssignmentLike() const { return true; }
00592 bool hasDest() const { return true; }
00593 void makeUses(BB* bb);
00594 void removeUses(BB* bb);
00595 void computeEscapingBlocks(GrowableArray<BlockPReg*>* l);
00596 void markAllocated(int* use_count, int* def_count) { Unused(use_count); Unused(def_count); }
00597
00598 friend class NodeFactory;
00599 };
00600
00601
00602 class InlinedReturnNode: public AbstractReturnNode {
00603
00604 protected:
00605 InlinedReturnNode(int bci, PReg* src, PReg* dest) : AbstractReturnNode(bci, src, dest) {}
00606
00607 public:
00608 bool isInlinedReturnNode() const { return true; }
00609 bool endsBB() const { return NonTrivialNode::endsBB(); }
00610 bool isTrivial() const { return true; }
00611 bool canBeEliminated() const { return true; }
00612 bool shouldCopyWhenSplitting() const { return true; }
00613 int cost() const { return 0; }
00614 Node* clone(PReg* from, PReg* to) const;
00615 void gen();
00616 void apply(NodeVisitor* v) { v->anInlinedReturnNode(this); }
00617 void verify() const;
00618 char* print_string(char* buf, bool printAddr = true) const;
00619
00620 friend class NodeFactory;
00621 };
00622
00623
00624
00625
00626
00627
00628
00629
00630 class NLRSetupNode: public AbstractReturnNode {
00631 Use* resultUse;
00632 Use* contextUse;
00633 protected:
00634 NLRSetupNode(PReg* result, int bci);
00635
00636 public:
00637 bool isExitNode() const { return true; }
00638 bool isNLRSetupNode() const { return true; }
00639
00640 bool canCopyPropagate() const { return false; }
00641 bool canCopyPropagateOop() const { return false; }
00642 bool hasSrc() const { return false; }
00643 bool isAssignmentLike() const { return false; }
00644 bool hasDest() const { return false; }
00645 bool canChangeDest() const { return false; }
00646 Node* clone(PReg* from, PReg* to) const;
00647 void makeUses(BB* bb);
00648 void removeUses(BB* bb);
00649 void gen();
00650 void apply(NodeVisitor* v) { v->aNLRSetupNode(this); }
00651 void verify() const;
00652 char* print_string(char* buf, bool printAddr = true) const;
00653
00654 friend class NodeFactory;
00655 };
00656
00657
00658 class NLRContinuationNode: public AbstractReturnNode {
00659 protected:
00660 NLRContinuationNode(int bci, PReg* src, PReg* dest) : AbstractReturnNode(bci, src, dest) { }
00661
00662 public:
00663 bool isExitNode() const { return true; }
00664 bool isNLRContinuationNode() const { return true; }
00665
00666 bool canCopyPropagate() const { return false; }
00667 bool canCopyPropagateOop() const { return false; }
00668 bool hasSrc() const { return false; }
00669 bool isAssignmentLike() const { return false; }
00670 bool hasDest() const { return false; }
00671 bool canChangeDest() const { return false; }
00672 Node* clone(PReg* from, PReg* to) const;
00673 void makeUses(BB* bb);
00674 void removeUses(BB* bb);
00675 void gen();
00676 void apply(NodeVisitor* v) { v->aNLRContinuationNode(this); }
00677 void verify() const;
00678 char* print_string(char* buf, bool printAddr = true) const;
00679
00680 friend class NodeFactory;
00681 };
00682
00683
00684
00685 class ReturnNode: public AbstractReturnNode {
00686 private:
00687 Use* resultUse;
00688
00689 protected:
00690 ReturnNode(PReg* res, int bci);
00691
00692 public:
00693 Node* clone(PReg* from, PReg* to) const;
00694 bool isExitNode() const { return true; }
00695 bool hasSrc() const { return false; }
00696 bool isAssignmentLike() const { return false; }
00697 bool hasDest() const { return false; }
00698 void makeUses(BB* bb);
00699 void removeUses(BB* bb);
00700 void markAllocated(int* use_count, int* def_count);
00701 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00702 void gen();
00703 void apply(NodeVisitor* v) { v->aReturnNode(this); }
00704 void verify() const;
00705 char* print_string(char* buf, bool printAddr = true) const;
00706
00707 friend class NodeFactory;
00708 };
00709
00710
00711
00712
00713
00714 class AbstractMergeNode: public TrivialNode {
00715 private:
00716 enum { N = 3 };
00717
00718 protected:
00719 GrowableArray<Node*>* _prevs;
00720
00721 public:
00722 AbstractMergeNode() { _prevs = new GrowableArray<Node*>(N); }
00723 AbstractMergeNode(Node* prev1, Node* prev2) {
00724 _prevs = new GrowableArray<Node*>(N);
00725 _prevs->append(prev1); prev1->setNext(this);
00726 _prevs->append(prev2); prev2->setNext(this);
00727 }
00728
00729 bool hasSinglePredecessor() const { return _prevs->length() <= 1; }
00730 int nPredecessors() const { return _prevs->length(); }
00731 Node* firstPrev() const { return _prevs->isEmpty() ? NULL : _prevs->at(0); }
00732
00733 void setPrev(Node* p) {
00734 assert(p, "should be something");
00735 assert(!_prevs->contains(p), "shouldn't already be there");
00736 _prevs->append(p);
00737 }
00738
00739 Node* prev(int n) const { return _prevs->at(n); }
00740
00741 protected:
00742 void removeMe();
00743 virtual void removePrev(Node* n) {
00744
00745 _prevs->remove(n);
00746 }
00747
00748 public:
00749 void movePrev(Node* from, Node* to);
00750 bool isPredecessor(const Node* n) const;
00751 };
00752
00753
00754 class MergeNode : public AbstractMergeNode {
00755 protected:
00756 MergeNode(int bci);
00757 MergeNode(Node* prev1, Node* prev2);
00758
00759 public:
00760 bool isLoopStart;
00761 bool isLoopEnd;
00762 bool didStartBB;
00763 int cost() const { return 0; }
00764 bool isTrivial() const { return _prevs->length() <= 1; }
00765 bool startsBB() const { return _prevs->length() > 1 || isLoopStart; }
00766 bool isMergeNode() const { return true; }
00767 BB* newBB();
00768 Node* clone(PReg* from, PReg* to) const;
00769 void gen();
00770 void apply(NodeVisitor* v) { v->aMergeNode(this); }
00771 void verify() const;
00772 char* print_string(char* buf, bool printAddr = true) const;
00773
00774 friend class NodeFactory;
00775 };
00776
00777
00778 class ArithNode : public NonTrivialNode {
00779
00780 protected:
00781 ArithOpCode _op;
00782 ConstPReg* _constResult;
00783
00784 ArithNode(ArithOpCode op, PReg* src, PReg* dst) {
00785 _op = op; _src = src; _dest = dst; _constResult = NULL;
00786 }
00787
00788 public:
00789 bool canCopyPropagate() const { return true; }
00790 bool canCopyPropagateOop() const { return true; }
00791 bool hasSrc() const { return true; }
00792 bool hasDest() const { return true; }
00793 bool isAssignmentLike() const { return _constResult != NULL; }
00794 bool isArithNode() const { return true; }
00795 bool isCmpNode() const { return _op == tCmpArithOp; }
00796 void makeUses(BB* bb);
00797 void removeUses(BB* bb);
00798 void markAllocated(int* use_count, int* def_count);
00799 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00800 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00801 ArithOpCode op() const { return _op; }
00802 virtual bool operIsConst() const = 0;
00803 virtual int operConst() const = 0;
00804 virtual bool doCopyPropagate(BB* bb, Use* u, PReg* d, bool repl);
00805 char* opName() const;
00806
00807 friend class NodeFactory;
00808 };
00809
00810
00811 class ArithRRNode : public ArithNode {
00812 protected:
00813 PReg* _oper;
00814 Use* _operUse;
00815
00816 ArithRRNode(ArithOpCode o, PReg* s, PReg* o2, PReg* d);
00817
00818 public:
00819 PReg* operand() const { return _oper; }
00820 Node* clone(PReg* from, PReg* to) const;
00821 bool operIsConst() const;
00822 int operConst() const;
00823 bool doCopyPropagate(BB* bb, Use* u, PReg* d, bool replace);
00824 void makeUses(BB* bb);
00825 void removeUses(BB* bb);
00826 void markAllocated(int* use_count, int* def_count);
00827 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00828 void gen();
00829 void apply(NodeVisitor* v) { v->anArithRRNode(this); }
00830 void verify() const;
00831 char* print_string(char* buf, bool printAddr = true) const;
00832
00833 friend class NodeFactory;
00834 };
00835
00836
00837 class FloatArithRRNode : public ArithRRNode {
00838 FloatArithRRNode(ArithOpCode o, PReg* s, PReg* o2, PReg* d) : ArithRRNode(o, s, o2, d) { }
00839 public:
00840 bool isAccessingFloats() const { return true; }
00841 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00842 void gen();
00843 void apply(NodeVisitor* v) { v->aFloatArithRRNode(this); }
00844 void verify() const;
00845 char* print_string(char* buf, bool printAddr = true) const;
00846
00847 friend class NodeFactory;
00848 };
00849
00850
00851 class FloatUnaryArithNode : public ArithNode {
00852
00853
00854 FloatUnaryArithNode(ArithOpCode op, PReg* src, PReg* dst) : ArithNode(op, src, dst) {}
00855 public:
00856 bool isAccessingFloats() const { return true; }
00857 bool isCmpNode() const { return false; }
00858 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00859 bool operIsConst() const { return false; }
00860 int operConst() const { ShouldNotCallThis(); return 0; }
00861 void gen();
00862 void apply(NodeVisitor* v) { v->aFloatUnaryArithNode(this); }
00863 void verify() const;
00864 char* print_string(char* buf, bool printAddr = true) const;
00865 friend class NodeFactory;
00866 };
00867
00868
00869 class ArithRCNode : public ArithNode {
00870
00871
00872 protected:
00873 int _oper;
00874
00875 ArithRCNode(ArithOpCode o, PReg* s, int o2, PReg* d)
00876 : ArithNode(o, s, d) { _oper = o2; }
00877
00878 public:
00879 int operand() const { return _oper; }
00880 Node* clone(PReg* from, PReg* to) const;
00881 void gen();
00882 void apply(NodeVisitor* v) { v->anArithRCNode(this); }
00883 bool operIsConst() const { return true; }
00884 int operConst() const { return _oper; }
00885 char* print_string(char* buf, bool printAddr = true) const;
00886
00887 friend class NodeFactory;
00888 };
00889
00890
00891 class AbstractBranchNode : public NonTrivialNode {
00892
00893 public:
00894 virtual bool canFail() const = NULL;
00895 virtual Node* failureBranch() const { return next1(); }
00896 bool endsBB() const { return true; }
00897 protected:
00898 AbstractBranchNode() { _nxt = new GrowableArray<Node*>(EstimatedSuccessors); }
00899 void removeFailureIfPossible();
00900 void verify(bool verifySuccessors) const;
00901
00902
00903 private:
00904 enum { EstimatedSuccessors = 2 };
00905 protected:
00906 GrowableArray<Node*>* _nxt;
00907 public:
00908
00909 Node* next1() const { return _nxt->length() ? _nxt->at(0) : NULL; }
00910 bool hasSingleSuccessor() const { return next1() == NULL; }
00911 int nSuccessors() const { return _nxt->length() + (_next ? 1 : 0); }
00912 Node* next() const { return _next; }
00913 Node* next(int i) const { return i == 0 ? _next : _nxt->at(i-1); }
00914
00915 void removeMe();
00916 void removeNext(Node* n);
00917
00918 void setNext1(Node* n) {
00919 assert(_nxt->length() == 0, "already set");
00920 _nxt->append(n);
00921 }
00922
00923 void setNext(Node* n) { NonTrivialNode::setNext(n); }
00924 void setNext(int i, Node* n);
00925 void moveNext(Node* from, Node* to);
00926 bool isSuccessor(const Node* n) const;
00927 };
00928
00929 class TArithRRNode : public AbstractBranchNode {
00930
00931
00932 protected:
00933 ArithOpCode _op;
00934 PReg* _oper;
00935 Use* _operUse;
00936 bool _arg1IsInt;
00937 bool _arg2IsInt;
00938 ConstPReg* _constResult;
00939
00940 TArithRRNode(ArithOpCode o, PReg* s, PReg* o2, PReg* d, bool a1, bool a2);
00941
00942 public:
00943 ArithOpCode op() const { return _op; }
00944 PReg* operand() const { return _oper; }
00945 bool arg1IsInt() const { return _arg1IsInt; }
00946 bool arg2IsInt() const { return _arg2IsInt; }
00947 bool canFail() const { return !(_arg1IsInt && _arg2IsInt); }
00948 bool isTArithNode() const { return true; }
00949 bool isAssignmentLike() const { return _constResult != NULL; }
00950 bool canCopyPropagate() const { return true; }
00951 bool canCopyPropagateOop() const { return true; }
00952 bool hasSrc() const { return true; }
00953 bool hasDest() const { return true; }
00954
00955 bool doesTypeTests() const { return true; }
00956 bool hasUnknownCode() const;
00957 void collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const;
00958 void assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n);
00959
00960 void makeUses(BB* bb);
00961 void removeUses(BB* bb);
00962 void markAllocated(int* use_count, int* def_count);
00963 Node* clone(PReg* from, PReg* to) const;
00964 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00965 Node* likelySuccessor() const;
00966 Node* uncommonSuccessor() const;
00967 void gen();
00968 void apply(NodeVisitor* v) { v->aTArithRRNode(this); }
00969 void verify() const;
00970 char* print_string(char* buf, bool printAddr = true) const;
00971
00972 protected:
00973 bool doCopyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00974
00975 friend class NodeFactory;
00976 };
00977
00978
00979 class CallNode : public AbstractBranchNode {
00980
00981
00982 protected:
00983 CallNode(MergeNode* n, GrowableArray<PReg*>* args, GrowableArray<PReg*>* exprs);
00984
00985 public:
00986 GrowableArray<PReg*>* exprStack;
00987 GrowableArray<Use*>* argUses;
00988 GrowableArray<PReg*>* uplevelUsed;
00989 GrowableArray<PReg*>* uplevelDefd;
00990 GrowableArray<Use*>* uplevelUses;
00991 GrowableArray<Def*>* uplevelDefs;
00992 GrowableArray<PReg*>* args;
00993 int nblocks;
00994
00995 bool hasDest() const { return true; }
00996 bool isCallNode() const { return true; }
00997 bool canChangeDest() const { return false; }
00998 bool canBeEliminated() const { return false; }
00999 virtual bool canInvokeDelta() const = NULL;
01000 MergeNode* nlrTestPoint() const;
01001 Node* likelySuccessor() const;
01002 Node* uncommonSuccessor() const;
01003 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
01004 void computeEscapingBlocks(GrowableArray<BlockPReg*>* ll);
01005 void makeUses(BB* bb);
01006 void removeUses(BB* bb);
01007 void markAllocated(int* use_count, int* def_count);
01008 SimpleBitVector trashedMask();
01009 void nlrCode();
01010 void verify() const;
01011
01012 friend class NodeFactory;
01013 };
01014
01015
01016 class SendNode : public CallNode {
01017 protected:
01018 LookupKey* _key;
01019 bool _superSend;
01020 SendInfo* _info;
01021
01022 SendNode(
01023 LookupKey* key,
01024 MergeNode* nlrTestPoint,
01025 GrowableArray<PReg*>* args,
01026 GrowableArray<PReg*>* exprStk,
01027 bool superSend,
01028 SendInfo* info
01029 );
01030
01031 public:
01032 bool isSendNode() const { return true; }
01033 bool isSuperSend() const { return _superSend; }
01034 bool isCounting() const;
01035 bool isUninlinable() const;
01036 bool staticReceiver() const;
01037 bool canInvokeDelta() const { return true; }
01038 bool canFail() const { return false; }
01039 int cost() const { return oopSize * 5; }
01040 PReg* recv() const;
01041 Node* clone(PReg* from, PReg* to) const;
01042 void computeEscapingBlocks(GrowableArray<BlockPReg*>* ll);
01043 void gen();
01044 void apply(NodeVisitor* v) { v->aSendNode(this); }
01045 char* print_string(char* buf, bool printAddr = true) const;
01046
01047 friend class NodeFactory;
01048 };
01049
01050
01051 class PrimNode: public CallNode {
01052 protected:
01053 primitive_desc* _pdesc;
01054
01055 PrimNode(primitive_desc* pdesc, MergeNode* nlrTestPoint, GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack);
01056
01057 public:
01058 bool canBeEliminated() const;
01059 bool canInvokeDelta() const;
01060 bool canFail() const;
01061 primitive_desc* pdesc() const { return _pdesc; }
01062 Node* clone(PReg* from, PReg* to) const;
01063 void computeEscapingBlocks(GrowableArray<BlockPReg*>* ll);
01064 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01065 void gen();
01066 void apply(NodeVisitor* v) { v->aPrimNode(this); }
01067 char* print_string(char* buf, bool printAddr = true) const;
01068
01069 friend class NodeFactory;
01070 };
01071
01072
01073 class DLLNode: public CallNode {
01074 protected:
01075 symbolOop _dll_name;
01076 symbolOop _function_name;
01077 dll_func _function;
01078 bool _async;
01079
01080 DLLNode(symbolOop dll_name, symbolOop function_name, dll_func function, bool async,
01081 MergeNode* nlrTestPoint, GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack);
01082
01083 public:
01084 bool canInvokeDelta() const;
01085 bool canFail() const { return true; }
01086 int nofArguments() const { return args == NULL ? 0 : args->length(); }
01087 symbolOop dll_name() const { return _dll_name; }
01088 symbolOop function_name() const { return _function_name; }
01089 dll_func function() const { return _function; }
01090 bool async() const { return _async; }
01091 void computeEscapingBlocks(GrowableArray<BlockPReg*>* ll);
01092 Node* clone(PReg* from, PReg* to) const;
01093 void gen();
01094 void apply(NodeVisitor* v) { v->aDLLNode(this); }
01095 char* print_string(char* buf, bool printAddr = true) const;
01096
01097 friend class NodeFactory;
01098 };
01099
01100
01101 class InterruptCheckNode : public PrimNode {
01102 protected:
01103 static primitive_desc* _intrCheck;
01104
01105 InterruptCheckNode(GrowableArray<PReg*>* exprs)
01106 : PrimNode(_intrCheck, NULL, NULL, exprs) {}
01107
01108 public:
01109 Node* clone(PReg* from, PReg* to) const;
01110 void gen();
01111 void apply(NodeVisitor* v) { Unimplemented(); }
01112 char* print_string(char* buf, bool printAddr = true) const;
01113
01114 friend void node_init();
01115 friend class NodeFactory;
01116 };
01117
01118
01119
01120
01121 class LoopHeaderNode : public TrivialNode {
01122 protected:
01123
01124 bool _integerLoop;
01125 PReg* _loopVar;
01126 PReg* _lowerBound;
01127 PReg* _upperBound;
01128 LoadOffsetNode* _upperLoad;
01129 GrowableArray<AbstractArrayAtNode*>* _arrayAccesses;
01130
01131 GrowableArray<HoistedTypeTest*>* _tests;
01132 bool _activated;
01133 LoopHeaderNode* _enclosingLoop;
01134 GrowableArray<LoopHeaderNode*>* _nestedLoops;
01135 int _nofCalls;
01136 GrowableArray<LoopRegCandidate*>* _registerCandidates;
01137
01138 LoopHeaderNode();
01139
01140 public:
01141 bool isLoopHeaderNode() const { return true; }
01142 bool isActivated() const { return _activated; }
01143 bool isInnerLoop() const { return _nestedLoops == NULL; }
01144 bool isIntegerLoop() const { return _integerLoop; }
01145 PReg* loopVar() const { return _loopVar; }
01146 PReg* lowerBound() const { return _lowerBound; }
01147 PReg* upperBound() const { return _upperBound; }
01148 LoadOffsetNode* upperLoad() const { return _upperLoad; }
01149 GrowableArray<AbstractArrayAtNode*>* arrayAccesses() const { return _arrayAccesses; }
01150 GrowableArray<HoistedTypeTest*>* tests() const { return _tests; }
01151 Node* clone(PReg* from, PReg* to) const { ShouldNotCallThis(); return NULL; }
01152 int nofCallsInLoop() const { return _nofCalls; }
01153 void set_nofCallsInLoop(int n) { _nofCalls = n; }
01154 void activate(PReg* loopVar, PReg* lowerBound, PReg* upperBound, LoadOffsetNode* upperLoad);
01155 void activate();
01156 void addArray(AbstractArrayAtNode* n);
01157 LoopHeaderNode* enclosingLoop() const { return _enclosingLoop; }
01158 void set_enclosingLoop(LoopHeaderNode* l);
01159 GrowableArray<LoopHeaderNode*>* nestedLoops() const { return _nestedLoops; }
01160 void addNestedLoop(LoopHeaderNode* l);
01161 GrowableArray<LoopRegCandidate*>* registerCandidates() const { return _registerCandidates; }
01162 void addRegisterCandidate(LoopRegCandidate* c);
01163 void gen();
01164 void apply(NodeVisitor* v) { v->aLoopHeaderNode(this); }
01165 char* print_string(char* buf, bool printAddr = true) const;
01166
01167 friend class NodeFactory;
01168 friend class CompiledLoop;
01169 protected:
01170 void generateTypeTests(Label& cont, Label& failure);
01171 void generateIntegerLoopTests(Label& cont, Label& failure);
01172 void generateArrayLoopTests(Label& cont, Label& failure);
01173 void generateIntegerLoopTest(PReg* p, Label& cont, Label& failure);
01174 void handleConstantTypeTest(ConstPReg* r, GrowableArray<klassOop>* klasses);
01175 };
01176
01177
01178 class BlockCreateNode : public PrimNode {
01179
01180
01181
01182 protected:
01183 PReg* _context;
01184 Use* _contextUse;
01185
01186 void materialize();
01187 void copyIntoContexts(Register val, Register t1, Register t2);
01188
01189 BlockCreateNode(BlockPReg* b, GrowableArray<PReg*>* expr_stack);
01190
01191 public:
01192 bool isBlockCreateNode() const { return true; }
01193
01194 bool endsBB() const { return !isMemoized() || NonTrivialNode::endsBB(); }
01195 BlockPReg* block() const { assert(_dest->isBlockPReg(), "must be BlockPReg"); return (BlockPReg*)_dest; }
01196 bool isMemoized() const { return block()->isMemoized(); }
01197 bool hasConstantSrc() const { return false; }
01198 bool hasSrc() const { return false; }
01199 int cost() const { return 2*oopSize; }
01200 Node* clone(PReg* from, PReg* to) const;
01201 bool canBeEliminated() const { return !dontEliminate; }
01202 void makeUses(BB* bb);
01203 void removeUses(BB* bb);
01204 void markAllocated(int* use_count, int* def_count);
01205 void gen();
01206 void apply(NodeVisitor* v) { v->aBlockCreateNode(this); }
01207 void verify() const;
01208 char* print_string(char* buf, bool printAddr = true) const;
01209
01210 friend void node_init();
01211
01212 friend class NodeFactory;
01213 };
01214
01215
01216 class BlockMaterializeNode : public BlockCreateNode {
01217
01218
01219 protected:
01220 BlockMaterializeNode(BlockPReg* b, GrowableArray<PReg*>* expr_stack)
01221 : BlockCreateNode(b, expr_stack) { _src = _dest; }
01222
01223 public:
01224 bool endsBB() const { return true; }
01225 bool hasSrc() const { return true; }
01226 int cost() const { return 5*oopSize; }
01227 Node* clone(PReg* from, PReg* to) const;
01228 void makeUses(BB* bb);
01229 void removeUses(BB* bb);
01230 void markAllocated(int* use_count, int* def_count);
01231 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01232 void gen();
01233 void apply(NodeVisitor* v) { v->aBlockMaterializeNode(this); }
01234 char* print_string(char* buf, bool printAddr = true) const;
01235
01236 friend class NodeFactory;
01237 };
01238
01239
01240 class ContextCreateNode: public PrimNode {
01241
01242 protected:
01243 int _nofTemps;
01244 int _contextSize;
01245 int _contextNo;
01246 GrowableArray<PReg*>* _parentContexts;
01247 GrowableArray<Use*>* _parentContextUses;
01248
01249 ContextCreateNode(PReg* parent, PReg* context, int nofTemps, GrowableArray<PReg*>* expr_stack);
01250 ContextCreateNode(PReg* b, const ContextCreateNode* n, GrowableArray<PReg*>* expr_stack);
01251
01252 public:
01253 bool hasSrc() const { return _src != NULL; }
01254 bool canChangeDest() const { return false; }
01255 bool canBeEliminated() const { return false; }
01256 bool isContextCreateNode() const { return true; }
01257 bool canFail() const { return false; }
01258 PReg* context() const { return _dest; }
01259 int nofTemps() const { return _nofTemps; }
01260 int sizeOfContext() const { return _contextSize; }
01261 void set_sizeOfContext(int s ) { _contextSize = s; }
01262 int contextNo() const { return _contextNo; }
01263 void set_contextNo(int s ) { _contextNo = s; }
01264
01265 Node* clone(PReg* from, PReg* to) const;
01266 void makeUses(BB* bb);
01267 void removeUses(BB* bb);
01268 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01269 void markAllocated(int* use_count, int* def_count);
01270 void gen();
01271 void apply(NodeVisitor* v) { v->aContextCreateNode(this); }
01272 void verify() const;
01273 char* print_string(char* buf, bool printAddr = true) const;
01274
01275 friend void node_init();
01276
01277 friend class NodeFactory;
01278 };
01279
01280
01281 class ContextInitNode: public NonTrivialNode {
01282
01283 protected:
01284 GrowableArray<Expr*>* _initializers;
01285 GrowableArray<Def*>* _contentDefs;
01286 GrowableArray<Use*>* _initializerUses;
01287 GrowableArray<BlockMaterializeNode*>* _materializedBlocks;
01288
01289
01290 ContextInitNode(ContextCreateNode* creator);
01291 ContextInitNode(PReg* b, const ContextInitNode* node);
01292
01293 public:
01294 bool hasSrc() const { return _src != NULL; }
01295 bool hasDest() const { return false; }
01296 bool isContextInitNode() const { return true; }
01297 bool canCopyPropagate() const { return true; }
01298 bool canBeEliminated() const { return false; }
01299 bool wasEliminated() const { return _src == NULL; }
01300 GrowableArray<Expr*>* contents() const { return scope()->contextTemporaries(); }
01301 int nofTemps() const { return _initializers->length(); }
01302 Expr* contextTemp(int i) const { return contents()->at(i); }
01303 Expr* initialValue(int i) const { return _initializers->at(i); }
01304 void addBlockMaterializer(BlockMaterializeNode* n);
01305 ContextCreateNode* creator() const;
01306 void notifyNoContext();
01307 bool hasNoContext() const { return _src == NULL; }
01308
01309 void initialize(int no, Expr* expr);
01310 int positionOfContextTemp(int i) const;
01311 Node* clone(PReg* from, PReg* to) const;
01312 void makeUses(BB* bb);
01313 void removeUses(BB* bb);
01314 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01315 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
01316 void markAllocated(int* use_count, int* def_count);
01317 void computeEscapingBlocks(GrowableArray<BlockPReg*>* l);
01318 void gen();
01319 void apply(NodeVisitor* v) { v->aContextInitNode(this); }
01320 void verify() const;
01321 char* print_string(char* buf, bool printAddr = true) const;
01322
01323 friend void node_init();
01324
01325 friend class NodeFactory;
01326 };
01327
01328
01329 class ContextZapNode: public NonTrivialNode {
01330
01331 private:
01332 ContextZapNode(PReg* context) { _src = context; assert(_src, "src is NULL"); }
01333
01334 public:
01335 bool isActive() const { return scope()->needsContextZapping(); }
01336 bool isContextZapNode() const { return true; }
01337 bool hasSrc() const { return true; }
01338 bool shouldCopyWhenSplitting() const { return true; }
01339 PReg* context() const { return _src; }
01340
01341 Node* clone(PReg* from, PReg* to) const;
01342 void makeUses(BB* bb);
01343 void removeUses(BB* bb);
01344 void markAllocated(int* use_count, int* def_count);
01345 void gen();
01346 void apply(NodeVisitor* v) { v->aContextZapNode(this); }
01347 void verify() const;
01348 char* print_string(char* buf, bool printAddr = true) const;
01349
01350 friend class NodeFactory;
01351 };
01352
01353
01354 class NLRTestNode: public AbstractBranchNode {
01355
01356
01357
01358 protected:
01359 NLRTestNode(int bci);
01360
01361 public:
01362 bool isNLRTestNode() const { return true; }
01363 bool canChangeDest() const { return false; }
01364 bool canBeEliminated() const { return false; }
01365 bool canFail() const { return false; }
01366 void fixup();
01367
01368 Node* clone(PReg* from, PReg* to) const;
01369 void makeUses(BB* bb);
01370 void removeUses(BB* bb);
01371
01372 void markAllocated(int* use_count, int* def_count) {};
01373 Node* likelySuccessor() const;
01374 Node* uncommonSuccessor() const;
01375 void gen();
01376 void apply(NodeVisitor* v) { v->aNLRTestNode(this); }
01377 void verify() const;
01378 char* print_string(char* buf, bool printAddr = true) const;
01379
01380 friend class NodeFactory;
01381 };
01382
01383
01384 class BranchNode : public AbstractBranchNode {
01385
01386
01387
01388 protected:
01389 BranchOpCode _op;
01390 bool _taken_is_uncommon;
01391
01392 BranchNode(BranchOpCode op, bool taken_is_uncommon) {
01393 _op = op;
01394 _taken_is_uncommon = taken_is_uncommon;
01395 }
01396
01397 public:
01398 BranchOpCode op() const { return _op; }
01399 bool isBranchNode() const { return true; }
01400 bool canFail() const { return false; }
01401 void eliminateBranch(int op1, int op2, int res);
01402 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01403 void markAllocated(int* use_count, int* def_count) { Unused(use_count); Unused(def_count); }
01404 Node* clone(PReg* from, PReg* to) const;
01405 Node* likelySuccessor() const;
01406 Node* uncommonSuccessor() const;
01407 void gen();
01408 void apply(NodeVisitor* v) { v->aBranchNode(this); }
01409 char* print_string(char* buf, bool printAddr = true) const;
01410 void verify() { AbstractBranchNode::verify(false); }
01411
01412 friend class NodeFactory;
01413 };
01414
01415
01416 class TypeTestNode : public AbstractBranchNode {
01417
01418
01419
01420 protected:
01421 GrowableArray<klassOop>* _classes;
01422 bool _hasUnknown;
01423
01424
01425 bool needsKlassLoad() const;
01426 TypeTestNode(PReg* r, GrowableArray<klassOop>* classes, bool hasUnknown);
01427
01428 public:
01429 GrowableArray<klassOop>* classes() const { return _classes; }
01430 bool hasUnknown() const { return _hasUnknown; }
01431 bool canFail() const { return _hasUnknown; }
01432 Node* failureBranch() const { return next(); }
01433 void setUnknown(bool u) { _hasUnknown = u; }
01434 bool isTypeTestNode() const { return true; }
01435 bool hasSrc() const { return true; }
01436 bool canCopyPropagate() const { return true; }
01437 bool canCopyPropagateOop() const { return true; }
01438 int cost() const { return 2 * oopSize * (_classes->length() + needsKlassLoad() ? 1 : 0); }
01439 Node* smiCase() const;
01440
01441 bool doesTypeTests() const { return true; }
01442 bool hasUnknownCode() const;
01443 void collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const;
01444 void assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n);
01445
01446 Node* clone(PReg* from, PReg* to) const;
01447 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
01448 void makeUses(BB* bb);
01449 void removeUses(BB* bb);
01450 void markAllocated(int* use_count, int* def_count);
01451 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01452 void eliminate(BB* bb, PReg* r, ConstPReg* c, klassOop m);
01453 void eliminateUnnecessary(klassOop m);
01454 Node* likelySuccessor() const;
01455 Node* uncommonSuccessor() const;
01456 void gen();
01457 void apply(NodeVisitor* v) { v->aTypeTestNode(this); }
01458 void verify() const;
01459 char* print_string(char* buf, bool printAddr = true) const;
01460
01461 friend class NodeFactory;
01462 };
01463
01464
01465 class AbstractArrayAtNode : public AbstractBranchNode {
01466
01467
01468 protected:
01469
01470 PReg* _arg;
01471 Use* _argUse;
01472 bool _intArg;
01473 PReg* _error;
01474 Def* _errorDef;
01475 bool _needBoundsCheck;
01476 int _dataOffset;
01477 int _sizeOffset;
01478
01479 AbstractArrayAtNode(PReg* r, PReg* idx, bool ia, PReg* res, PReg* err, int dataOffset, int sizeOffset) {
01480 _src = r; _arg = idx; _intArg = ia; _dest = res; _error = err;
01481 _dataOffset = dataOffset; _sizeOffset = sizeOffset;
01482 dontEliminate = true; _needBoundsCheck = true;
01483 }
01484
01485 public:
01486 bool hasSrc() const { return true; }
01487 bool hasDest() const { return _dest != NULL; }
01488 bool canFail() const = NULL;
01489 int cost() const { return 20 + (_intArg ? 0 : 12); }
01490 bool canCopyPropagate() const { return true; }
01491 int sizeOffset() const { return _sizeOffset; }
01492 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
01493
01494 bool doesTypeTests() const { return true; }
01495 bool needsBoundsCheck() const { return _needBoundsCheck; }
01496 bool hasUnknownCode() const;
01497 void collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const;
01498 void assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n);
01499 void assert_in_bounds(PReg* r, LoopHeaderNode* n);
01500
01501 void makeUses(BB* bb);
01502 void removeUses(BB* bb);
01503 void markAllocated(int* use_count, int* def_count);
01504 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01505 Node* likelySuccessor() const;
01506 Node* uncommonSuccessor() const;
01507
01508 friend class NodeFactory;
01509 };
01510
01511
01512 class ArrayAtNode : public AbstractArrayAtNode {
01513 public:
01514 enum AccessType {
01515 byte_at,
01516 double_byte_at,
01517 character_at,
01518 object_at
01519 };
01520
01521 protected:
01522 AccessType _access_type;
01523
01524 ArrayAtNode(
01525 AccessType access_type,
01526 PReg* array,
01527 PReg* index,
01528 bool smiIndex,
01529 PReg* result,
01530 PReg* error,
01531 int data_offset,
01532 int length_offset
01533 );
01534
01535 public:
01536 AccessType access_type() const { return _access_type; }
01537 PReg* array() const { return _src; }
01538 PReg* index() const { return _arg; }
01539 PReg* error() const { return _error; }
01540 bool index_is_smi() const { return _intArg; }
01541 bool index_needs_bounds_check() const { return _needBoundsCheck; }
01542 bool canFail() const { return !index_is_smi() || index_needs_bounds_check(); }
01543 int data_word_offset() const{ return _dataOffset; }
01544 int size_word_offset() const{ return _sizeOffset; }
01545 Node* clone(PReg* from, PReg* to) const;
01546 char* print_string(char* buf, bool printAddr = true) const;
01547 void gen();
01548 void apply(NodeVisitor* v) { v->anArrayAtNode(this); }
01549
01550 friend class NodeFactory;
01551 };
01552
01553
01554 class AbstractArrayAtPutNode : public AbstractArrayAtNode {
01555
01556
01557 protected:
01558 PReg* elem;
01559 Use* elemUse;
01560
01561 AbstractArrayAtPutNode(PReg* arr, PReg* idx, bool ia, PReg* el, PReg* res, PReg* err, int doff, int soff)
01562 : AbstractArrayAtNode(arr, idx, ia, res, err, doff, soff) { elem = el; }
01563
01564 public:
01565 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
01566 bool canCopyPropagateOop() const { return true; }
01567 void makeUses(BB* bb);
01568 void removeUses(BB* bb);
01569 void markAllocated(int* use_count, int* def_count);
01570
01571 friend class NodeFactory;
01572 };
01573
01574
01575 class ArrayAtPutNode : public AbstractArrayAtPutNode {
01576 public:
01577 enum AccessType {
01578 byte_at_put,
01579 double_byte_at_put,
01580 object_at_put
01581 };
01582 static bool stores_smi_elements(AccessType t) { return t != object_at_put; }
01583
01584 protected:
01585 AccessType _access_type;
01586 bool _needs_store_check;
01587 bool _smi_element;
01588 bool _needs_element_range_check;
01589
01590 ArrayAtPutNode(
01591 AccessType access_type,
01592 PReg* array,
01593 PReg* index,
01594 bool smi_index,
01595 PReg* element,
01596 bool smi_element,
01597 PReg* result,
01598 PReg* error,
01599 int data_offset,
01600 int length_offset,
01601 bool needs_store_check
01602 );
01603
01604 public:
01605 AccessType access_type() const { return _access_type; }
01606 PReg* array() const { return _src; }
01607 PReg* index() const { return _arg; }
01608 PReg* element() const { return elem; }
01609 PReg* error() const { return _error; }
01610 bool index_is_smi() const { return _intArg; }
01611 bool element_is_smi() const { return _smi_element; }
01612 bool index_needs_bounds_check() const { return _needBoundsCheck; }
01613 bool element_needs_range_check() const { return _needs_element_range_check; }
01614 bool canFail() const { return !index_is_smi() || index_needs_bounds_check() ||
01615 (access_type() != object_at_put && (!element_is_smi() || element_needs_range_check())); }
01616 bool needs_store_check() const { return _needs_store_check; }
01617 int data_word_offset() const{ return _dataOffset; }
01618 int size_word_offset() const{ return _sizeOffset; }
01619 Node* clone(PReg* from, PReg* to) const;
01620
01621 void collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const;
01622 void assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n);
01623
01624 void computeEscapingBlocks(GrowableArray<BlockPReg*>* l);
01625 char* print_string(char* buf, bool printAddr = true) const;
01626 void gen();
01627 void apply(NodeVisitor* v) { v->anArrayAtPutNode(this); }
01628
01629 friend class NodeFactory;
01630 };
01631
01632
01633 class InlinedPrimitiveNode : public AbstractBranchNode {
01634 public:
01635 enum Operation {
01636 obj_klass,
01637 obj_hash,
01638 proxy_byte_at,
01639 proxy_byte_at_put,
01640 };
01641
01642 private:
01643 Operation _op;
01644
01645 PReg* _arg1;
01646 PReg* _arg2;
01647 PReg* _error;
01648 Use* _arg1_use;
01649 Use* _arg2_use;
01650 Def* _error_def;
01651 bool _arg1_is_smi;
01652 bool _arg2_is_smi;
01653
01654 InlinedPrimitiveNode(
01655 Operation op,
01656 PReg* result,
01657 PReg* error,
01658 PReg* recv,
01659 PReg* arg1, bool arg1_is_smi,
01660 PReg* arg2, bool arg2_is_smi
01661 );
01662
01663 public:
01664 Operation op() const { return _op; }
01665 PReg* arg1() const { return _arg1; }
01666 PReg* arg2() const { return _arg2; }
01667 PReg* error() const { return _error; }
01668 bool arg1_is_smi() const { return _arg1_is_smi; }
01669 bool arg2_is_smi() const { return _arg2_is_smi; }
01670 bool hasSrc() const { return _src != NULL; }
01671 bool hasDest() const { return _dest != NULL; }
01672 bool canFail() const;
01673 void makeUses(BB* bb);
01674 void removeUses(BB* bb);
01675 void markAllocated(int* use_count, int* def_count);
01676 bool canBeEliminated() const;
01677 void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01678 bool canCopyPropagate() const { return false; }
01679 bool canCopyPropagateOop() const { return false; }
01680 bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace);
01681 Node* likelySuccessor() const;
01682 Node* uncommonSuccessor() const;
01683 void gen();
01684 void apply(NodeVisitor* v) { v->anInlinedPrimitiveNode(this); }
01685 void verify() const;
01686 char* print_string(char* buf, bool printAddr = true) const;
01687
01688 friend class NodeFactory;
01689 };
01690
01691
01692 class UncommonNode : public NonTrivialNode {
01693 GrowableArray<PReg*>* exprStack;
01694
01695 protected:
01696 UncommonNode(GrowableArray<PReg*>* e, int bci);
01697
01698 public:
01699 bool isUncommonNode() const { return true; }
01700 int cost() const { return 4; }
01701 bool isExitNode() const { return true; }
01702 bool isEndsBB() const { return true; }
01703 Node* clone(PReg* from, PReg* to) const;
01704 void markAllocated(int* use_count, int* def_count) { Unused(use_count); Unused(def_count); }
01705 void gen();
01706 void apply(NodeVisitor* v) { v->anUncommonNode(this); }
01707 void verify() const;
01708 char* print_string(char* buf, bool printAddr = true) const;
01709
01710 friend class NodeFactory;
01711 };
01712
01713
01714 class FixedCodeNode : public TrivialNode {
01715 public:
01716 enum FixedCodeKind {
01717 dead_end,
01718 inc_counter
01719 };
01720 protected:
01721 const FixedCodeKind _kind;
01722 FixedCodeNode(FixedCodeKind k) : _kind(k) {}
01723
01724 public:
01725 bool isExitNode() const { return _kind == dead_end; }
01726 bool isDeadEndNode() const { return _kind == dead_end; }
01727 FixedCodeKind kind() const { return _kind; }
01728 Node* clone(PReg* from, PReg* to) const;
01729 void gen();
01730 void apply(NodeVisitor* v) { v->aFixedCodeNode(this); }
01731 char* print_string(char* buf, bool printAddr = true) const;
01732
01733 friend class NodeFactory;
01734 };
01735
01736
01737 class NopNode : public TrivialNode {
01738 protected:
01739 NopNode() {}
01740
01741 public:
01742 bool isNopNode() const { return true; }
01743 Node* clone(PReg* from, PReg* to) const;
01744 void apply(NodeVisitor* v) { v->aNopNode(this); }
01745 char* print_string(char* buf, bool printAddr = true) const;
01746
01747 friend class NodeFactory;
01748 };
01749
01750
01751 class CommentNode : public TrivialNode {
01752 protected:
01753 CommentNode(char* s);
01754
01755 public:
01756 char* comment;
01757 bool isCommentNode() const { return true; }
01758 Node* clone(PReg* from, PReg* to) const;
01759 void apply(NodeVisitor* v) { v->aCommentNode(this); }
01760 char* print_string(char* buf, bool printAddr = true) const;
01761
01762 friend class NodeFactory;
01763 };
01764
01765
01766
01767
01768 class NodeFactory : AllStatic {
01769 public:
01770 static int cumulCost;
01771
01772 static void registerNode(Node* n) { cumulCost += n->cost(); }
01773
01774 static PrologueNode* new_PrologueNode (LookupKey* key, int nofArgs, int nofTemps);
01775
01776 static LoadOffsetNode* new_LoadOffsetNode (PReg* dst, PReg* base, int offs, bool isArray);
01777 static LoadUplevelNode* new_LoadUplevelNode (PReg* dst, PReg* context0, int nofLevels, int offset, symbolOop name);
01778 static LoadIntNode* new_LoadIntNode (PReg* dst, int value);
01779
01780 static StoreOffsetNode* new_StoreOffsetNode (PReg* src, PReg* base, int offs, bool needStoreCheck);
01781 static StoreUplevelNode* new_StoreUplevelNode (PReg* src, PReg* context0, int nofLevels, int offset, symbolOop name, bool needStoreCheck);
01782 static AssignNode* new_AssignNode (PReg* src, PReg* dst);
01783
01784 static ReturnNode* new_ReturnNode (PReg* res, int bci);
01785 static InlinedReturnNode* new_InlinedReturnNode (int bci, PReg* src, PReg* dst);
01786 static NLRSetupNode* new_NLRSetupNode (PReg* result, int bci);
01787 static NLRContinuationNode* new_NLRContinuationNode (int bci);
01788 static NLRTestNode* new_NLRTestNode (int bci);
01789
01790 static ArithRRNode* new_ArithRRNode (PReg* dst, PReg* src, ArithOpCode op, PReg* o2);
01791 static ArithRCNode* new_ArithRCNode (PReg* dst, PReg* src, ArithOpCode op, int o2);
01792 static TArithRRNode* new_TArithRRNode (PReg* dst, PReg* src, ArithOpCode op, PReg* o2, bool a1, bool a2);
01793 static FloatArithRRNode* new_FloatArithRRNode (PReg* dst, PReg* src, ArithOpCode op, PReg* o2);
01794 static FloatUnaryArithNode* new_FloatUnaryArithNode (PReg* dst, PReg* src, ArithOpCode op);
01795
01796 static MergeNode* new_MergeNode (Node* prev1, Node* prev2);
01797 static MergeNode* new_MergeNode (int bci);
01798
01799 static SendNode* new_SendNode (LookupKey* key, MergeNode* nlrTestPoint,
01800 GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack,
01801 bool superSend, SendInfo* info);
01802 static PrimNode* new_PrimNode (primitive_desc* pdesc, MergeNode* nlrTestPoint,
01803 GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack);
01804 static DLLNode* new_DLLNode (symbolOop dll_name, symbolOop function_name, dll_func function, bool async,
01805 MergeNode* nlrTestPoint, GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack);
01806
01807 static InterruptCheckNode* new_InterruptCheckNode (GrowableArray<PReg*>* expr_stack);
01808 static LoopHeaderNode* new_LoopHeaderNode ();
01809
01810 static BlockCreateNode* new_BlockCreateNode (BlockPReg* b, GrowableArray<PReg*>* expr_stack);
01811 static BlockMaterializeNode* new_BlockMaterializeNode(BlockPReg* b, GrowableArray<PReg*>* expr_stack);
01812
01813 static ContextCreateNode* new_ContextCreateNode (PReg* parent, PReg* context, int nofTemps, GrowableArray<PReg*>* expr_stack);
01814 static ContextCreateNode* new_ContextCreateNode (PReg* b, const ContextCreateNode* n, GrowableArray<PReg*>* expr_stack);
01815 static ContextInitNode* new_ContextInitNode (ContextCreateNode* creator);
01816 static ContextInitNode* new_ContextInitNode (PReg* b, const ContextInitNode* n);
01817 static ContextZapNode* new_ContextZapNode (PReg* context);
01818
01819 static BranchNode* new_BranchNode (BranchOpCode op, bool taken_is_uncommon = false);
01820
01821 static TypeTestNode* new_TypeTestNode (PReg* recv, GrowableArray<klassOop>* classes, bool hasUnknown);
01822
01823 static ArrayAtNode* new_ArrayAtNode (ArrayAtNode::AccessType access_type, PReg* array, PReg* index, bool smiIndex,
01824 PReg* result, PReg* error, int data_offset, int length_offset);
01825
01826 static ArrayAtPutNode* new_ArrayAtPutNode (ArrayAtPutNode::AccessType access_type, PReg* array, PReg* index, bool smi_index,
01827 PReg* element, bool smi_element, PReg* result, PReg* error, int data_offset, int length_offset,
01828 bool needs_store_check);
01829
01830 static InlinedPrimitiveNode* new_InlinedPrimitiveNode(InlinedPrimitiveNode::Operation op, PReg* result, PReg* error = NULL,
01831 PReg* recv = NULL,
01832 PReg* arg1 = NULL, bool arg1_is_smi = false,
01833 PReg* arg2 = NULL, bool arg2_is_smi = false);
01834
01835 static UncommonNode* new_UncommonNode (GrowableArray<PReg*>* exprStack, int bci);
01836 static FixedCodeNode* new_FixedCodeNode (FixedCodeNode::FixedCodeKind k);
01837 static NopNode* new_NopNode ();
01838 static CommentNode* new_CommentNode (char* comment);
01839 };
01840
01841 #ifdef DEBUG
01842 void printNodes(Node* n);
01843 #endif
01844
01845 # endif