74 init_class_id(Class_Region);
75 init_req(0,this);
76 }
77
78 Node* is_copy() const {
79 const Node* r = _in[Region];
80 if (r == NULL)
81 return nonnull_req();
82 return NULL; // not a copy!
83 }
84 PhiNode* has_phi() const; // returns an arbitrary phi user, or NULL
85 PhiNode* has_unique_phi() const; // returns the unique phi user, or NULL
86 // Is this region node unreachable from root?
87 bool is_unreachable_region(PhaseGVN *phase) const;
88 virtual int Opcode() const;
89 virtual bool pinned() const { return (const Node *)in(0) == this; }
90 virtual bool is_CFG () const { return true; }
91 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash
92 virtual bool depends_only_on_test() const { return false; }
93 virtual const Type *bottom_type() const { return Type::CONTROL; }
94 virtual const Type *Value( PhaseTransform *phase ) const;
95 virtual Node *Identity( PhaseTransform *phase );
96 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
97 virtual const RegMask &out_RegMask() const;
98 bool try_clean_mem_phi(PhaseGVN *phase);
99 };
100
101 //------------------------------JProjNode--------------------------------------
102 // jump projection for node that produces multiple control-flow paths
103 class JProjNode : public ProjNode {
104 public:
105 JProjNode( Node* ctrl, uint idx ) : ProjNode(ctrl,idx) {}
106 virtual int Opcode() const;
107 virtual bool is_CFG() const { return true; }
108 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash
109 virtual const Node* is_block_proj() const { return in(0); }
110 virtual const RegMask& out_RegMask() const;
111 virtual uint ideal_reg() const { return 0; }
112 };
113
114 //------------------------------PhiNode----------------------------------------
115 // PhiNodes merge values from different Control paths. Slot 0 points to the
181 enum LoopSafety { Safe = 0, Unsafe, UnsafeLoop };
182 LoopSafety simple_data_loop_check(Node *in) const;
183 // Is it unsafe data loop? It becomes a dead loop if this phi node removed.
184 bool is_unsafe_data_reference(Node *in) const;
185 int is_diamond_phi(bool check_control_only = false) const;
186 virtual int Opcode() const;
187 virtual bool pinned() const { return in(0) != 0; }
188 virtual const TypePtr *adr_type() const { verify_adr_type(true); return _adr_type; }
189
190 const int inst_id() const { return _inst_id; }
191 const int inst_index() const { return _inst_index; }
192 const int inst_offset() const { return _inst_offset; }
193 bool is_same_inst_field(const Type* tp, int id, int index, int offset) {
194 return type()->basic_type() == tp->basic_type() &&
195 inst_id() == id &&
196 inst_index() == index &&
197 inst_offset() == offset &&
198 type()->higher_equal(tp);
199 }
200
201 virtual const Type *Value( PhaseTransform *phase ) const;
202 virtual Node *Identity( PhaseTransform *phase );
203 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
204 virtual const RegMask &out_RegMask() const;
205 virtual const RegMask &in_RegMask(uint) const;
206 #ifndef PRODUCT
207 virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
208 virtual void dump_spec(outputStream *st) const;
209 #endif
210 #ifdef ASSERT
211 void verify_adr_type(VectorSet& visited, const TypePtr* at) const;
212 void verify_adr_type(bool recursive = false) const;
213 #else //ASSERT
214 void verify_adr_type(bool recursive = false) const {}
215 #endif //ASSERT
216 };
217
218 //------------------------------GotoNode---------------------------------------
219 // GotoNodes perform direct branches.
220 class GotoNode : public Node {
221 public:
222 GotoNode( Node *control ) : Node(control) {}
223 virtual int Opcode() const;
224 virtual bool pinned() const { return true; }
225 virtual bool is_CFG() const { return true; }
226 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash
227 virtual const Node *is_block_proj() const { return this; }
228 virtual bool depends_only_on_test() const { return false; }
229 virtual const Type *bottom_type() const { return Type::CONTROL; }
230 virtual const Type *Value( PhaseTransform *phase ) const;
231 virtual Node *Identity( PhaseTransform *phase );
232 virtual const RegMask &out_RegMask() const;
233
234 #ifndef PRODUCT
235 virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
236 #endif
237 };
238
239 //------------------------------CProjNode--------------------------------------
240 // control projection for node that produces multiple control-flow paths
241 class CProjNode : public ProjNode {
242 public:
243 CProjNode( Node *ctrl, uint idx ) : ProjNode(ctrl,idx) {}
244 virtual int Opcode() const;
245 virtual bool is_CFG() const { return true; }
246 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash
247 virtual const Node *is_block_proj() const { return in(0); }
248 virtual const RegMask &out_RegMask() const;
249 virtual uint ideal_reg() const { return 0; }
250 };
251
360 // threshold for ignoring counts when estimating path frequency
361 // likelihood of FP clipping failure
362 // likelihood of catching an exception from a try block
363 // likelihood of null check failure if a null has NOT been seen before
364 //
365 // Magic manifest probabilities such as 0.83, 0.7, ... can be found in
366 // gen_subtype_check() and catch_inline_exceptions().
367
368 float _prob; // Probability of true path being taken.
369 float _fcnt; // Frequency counter
370 IfNode( Node *control, Node *b, float p, float fcnt )
371 : MultiBranchNode(2), _prob(p), _fcnt(fcnt) {
372 init_class_id(Class_If);
373 init_req(0,control);
374 init_req(1,b);
375 }
376 virtual int Opcode() const;
377 virtual bool pinned() const { return true; }
378 virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }
379 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
380 virtual const Type *Value( PhaseTransform *phase ) const;
381 virtual int required_outcnt() const { return 2; }
382 virtual const RegMask &out_RegMask() const;
383 Node* fold_compares(PhaseIterGVN* phase);
384 static Node* up_one_dom(Node* curr, bool linear_only = false);
385
386 // Takes the type of val and filters it through the test represented
387 // by if_proj and returns a more refined type if one is produced.
388 // Returns NULL is it couldn't improve the type.
389 static const TypeInt* filtered_int_type(PhaseGVN* phase, Node* val, Node* if_proj);
390
391 #ifndef PRODUCT
392 virtual void dump_spec(outputStream *st) const;
393 virtual void related(GrowableArray <Node *> *in_rel, GrowableArray <Node *> *out_rel, bool compact) const;
394 #endif
395 };
396
397 class RangeCheckNode : public IfNode {
398 private:
399 int is_range_check(Node* &range, Node* &index, jint &offset);
400
401 public:
402 RangeCheckNode(Node* control, Node *b, float p, float fcnt)
403 : IfNode(control, b, p, fcnt) {
404 init_class_id(Class_RangeCheck);
405 }
406
407 virtual int Opcode() const;
408 virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
409 };
410
411 class IfProjNode : public CProjNode {
412 public:
413 IfProjNode(IfNode *ifnode, uint idx) : CProjNode(ifnode,idx) {}
414 virtual Node *Identity(PhaseTransform *phase);
415
416 protected:
417 // Type of If input when this branch is always taken
418 virtual bool always_taken(const TypeTuple* t) const = 0;
419
420 #ifndef PRODUCT
421 public:
422 virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
423 #endif
424 };
425
426 class IfTrueNode : public IfProjNode {
427 public:
428 IfTrueNode( IfNode *ifnode ) : IfProjNode(ifnode,1) {
429 init_class_id(Class_IfTrue);
430 }
431 virtual int Opcode() const;
432
433 protected:
434 virtual bool always_taken(const TypeTuple* t) const { return t == TypeTuple::IFTRUE; }
448
449 //------------------------------PCTableNode------------------------------------
450 // Build an indirect branch table. Given a control and a table index,
451 // control is passed to the Projection matching the table index. Used to
452 // implement switch statements and exception-handling capabilities.
453 // Undefined behavior if passed-in index is not inside the table.
454 class PCTableNode : public MultiBranchNode {
455 virtual uint hash() const; // Target count; table size
456 virtual uint cmp( const Node &n ) const;
457 virtual uint size_of() const { return sizeof(*this); }
458
459 public:
460 const uint _size; // Number of targets
461
462 PCTableNode( Node *ctrl, Node *idx, uint size ) : MultiBranchNode(2), _size(size) {
463 init_class_id(Class_PCTable);
464 init_req(0, ctrl);
465 init_req(1, idx);
466 }
467 virtual int Opcode() const;
468 virtual const Type *Value( PhaseTransform *phase ) const;
469 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
470 virtual const Type *bottom_type() const;
471 virtual bool pinned() const { return true; }
472 virtual int required_outcnt() const { return _size; }
473 };
474
475 //------------------------------JumpNode---------------------------------------
476 // Indirect branch. Uses PCTable above to implement a switch statement.
477 // It emits as a table load and local branch.
478 class JumpNode : public PCTableNode {
479 public:
480 JumpNode( Node* control, Node* switch_val, uint size) : PCTableNode(control, switch_val, size) {
481 init_class_id(Class_Jump);
482 }
483 virtual int Opcode() const;
484 virtual const RegMask& out_RegMask() const;
485 virtual const Node* is_block_proj() const { return this; }
486 #ifndef PRODUCT
487 virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
488 #endif
508 int dest_bci() const { return _dest_bci; }
509 int switch_val() const { return _switch_val; }
510 uint proj_no() const { return _proj_no; }
511 #ifndef PRODUCT
512 virtual void dump_spec(outputStream *st) const;
513 virtual void dump_compact_spec(outputStream *st) const;
514 virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
515 #endif
516 };
517
518 //------------------------------CatchNode--------------------------------------
519 // Helper node to fork exceptions. "Catch" catches any exceptions thrown by
520 // a just-prior call. Looks like a PCTableNode but emits no code - just the
521 // table. The table lookup and branch is implemented by RethrowNode.
522 class CatchNode : public PCTableNode {
523 public:
524 CatchNode( Node *ctrl, Node *idx, uint size ) : PCTableNode(ctrl,idx,size){
525 init_class_id(Class_Catch);
526 }
527 virtual int Opcode() const;
528 virtual const Type *Value( PhaseTransform *phase ) const;
529 };
530
531 // CatchProjNode controls which exception handler is targetted after a call.
532 // It is passed in the bci of the target handler, or no_handler_bci in case
533 // the projection doesn't lead to an exception handler.
534 class CatchProjNode : public CProjNode {
535 virtual uint hash() const;
536 virtual uint cmp( const Node &n ) const;
537 virtual uint size_of() const { return sizeof(*this); }
538
539 private:
540 const int _handler_bci;
541
542 public:
543 enum {
544 fall_through_index = 0, // the fall through projection index
545 catch_all_index = 1, // the projection index for catch-alls
546 no_handler_bci = -1 // the bci for fall through or catch-all projs
547 };
548
549 CatchProjNode(Node* catchnode, uint proj_no, int handler_bci)
550 : CProjNode(catchnode, proj_no), _handler_bci(handler_bci) {
551 init_class_id(Class_CatchProj);
552 assert(proj_no != fall_through_index || handler_bci < 0, "fall through case must have bci < 0");
553 }
554
555 virtual int Opcode() const;
556 virtual Node *Identity( PhaseTransform *phase );
557 virtual const Type *bottom_type() const { return Type::CONTROL; }
558 int handler_bci() const { return _handler_bci; }
559 bool is_handler_proj() const { return _handler_bci >= 0; }
560 #ifndef PRODUCT
561 virtual void dump_spec(outputStream *st) const;
562 #endif
563 };
564
565
566 //---------------------------------CreateExNode--------------------------------
567 // Helper node to create the exception coming back from a call
568 class CreateExNode : public TypeNode {
569 public:
570 CreateExNode(const Type* t, Node* control, Node* i_o) : TypeNode(t, 2) {
571 init_req(0, control);
572 init_req(1, i_o);
573 }
574 virtual int Opcode() const;
575 virtual Node *Identity( PhaseTransform *phase );
576 virtual bool pinned() const { return true; }
577 uint match_edge(uint idx) const { return 0; }
578 virtual uint ideal_reg() const { return Op_RegP; }
579 };
580
581 //------------------------------NeverBranchNode-------------------------------
582 // The never-taken branch. Used to give the appearance of exiting infinite
583 // loops to those algorithms that like all paths to be reachable. Encodes
584 // empty.
585 class NeverBranchNode : public MultiBranchNode {
586 public:
587 NeverBranchNode( Node *ctrl ) : MultiBranchNode(1) { init_req(0,ctrl); }
588 virtual int Opcode() const;
589 virtual bool pinned() const { return true; };
590 virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }
591 virtual const Type *Value( PhaseTransform *phase ) const;
592 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
593 virtual int required_outcnt() const { return 2; }
594 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { }
595 virtual uint size(PhaseRegAlloc *ra_) const { return 0; }
596 #ifndef PRODUCT
597 virtual void format( PhaseRegAlloc *, outputStream *st ) const;
598 #endif
599 };
600
601 #endif // SHARE_VM_OPTO_CFGNODE_HPP
|
74 init_class_id(Class_Region);
75 init_req(0,this);
76 }
77
78 Node* is_copy() const {
79 const Node* r = _in[Region];
80 if (r == NULL)
81 return nonnull_req();
82 return NULL; // not a copy!
83 }
84 PhiNode* has_phi() const; // returns an arbitrary phi user, or NULL
85 PhiNode* has_unique_phi() const; // returns the unique phi user, or NULL
86 // Is this region node unreachable from root?
87 bool is_unreachable_region(PhaseGVN *phase) const;
88 virtual int Opcode() const;
89 virtual bool pinned() const { return (const Node *)in(0) == this; }
90 virtual bool is_CFG () const { return true; }
91 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash
92 virtual bool depends_only_on_test() const { return false; }
93 virtual const Type *bottom_type() const { return Type::CONTROL; }
94 virtual const Type* Value(PhaseGVN* phase) const;
95 virtual Node* Identity(PhaseGVN* phase);
96 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
97 virtual const RegMask &out_RegMask() const;
98 bool try_clean_mem_phi(PhaseGVN *phase);
99 };
100
101 //------------------------------JProjNode--------------------------------------
102 // jump projection for node that produces multiple control-flow paths
103 class JProjNode : public ProjNode {
104 public:
105 JProjNode( Node* ctrl, uint idx ) : ProjNode(ctrl,idx) {}
106 virtual int Opcode() const;
107 virtual bool is_CFG() const { return true; }
108 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash
109 virtual const Node* is_block_proj() const { return in(0); }
110 virtual const RegMask& out_RegMask() const;
111 virtual uint ideal_reg() const { return 0; }
112 };
113
114 //------------------------------PhiNode----------------------------------------
115 // PhiNodes merge values from different Control paths. Slot 0 points to the
181 enum LoopSafety { Safe = 0, Unsafe, UnsafeLoop };
182 LoopSafety simple_data_loop_check(Node *in) const;
183 // Is it unsafe data loop? It becomes a dead loop if this phi node removed.
184 bool is_unsafe_data_reference(Node *in) const;
185 int is_diamond_phi(bool check_control_only = false) const;
186 virtual int Opcode() const;
187 virtual bool pinned() const { return in(0) != 0; }
188 virtual const TypePtr *adr_type() const { verify_adr_type(true); return _adr_type; }
189
190 const int inst_id() const { return _inst_id; }
191 const int inst_index() const { return _inst_index; }
192 const int inst_offset() const { return _inst_offset; }
193 bool is_same_inst_field(const Type* tp, int id, int index, int offset) {
194 return type()->basic_type() == tp->basic_type() &&
195 inst_id() == id &&
196 inst_index() == index &&
197 inst_offset() == offset &&
198 type()->higher_equal(tp);
199 }
200
201 virtual const Type* Value(PhaseGVN* phase) const;
202 virtual Node* Identity(PhaseGVN* phase);
203 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
204 virtual const RegMask &out_RegMask() const;
205 virtual const RegMask &in_RegMask(uint) const;
206 #ifndef PRODUCT
207 virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
208 virtual void dump_spec(outputStream *st) const;
209 #endif
210 #ifdef ASSERT
211 void verify_adr_type(VectorSet& visited, const TypePtr* at) const;
212 void verify_adr_type(bool recursive = false) const;
213 #else //ASSERT
214 void verify_adr_type(bool recursive = false) const {}
215 #endif //ASSERT
216 };
217
218 //------------------------------GotoNode---------------------------------------
219 // GotoNodes perform direct branches.
220 class GotoNode : public Node {
221 public:
222 GotoNode( Node *control ) : Node(control) {}
223 virtual int Opcode() const;
224 virtual bool pinned() const { return true; }
225 virtual bool is_CFG() const { return true; }
226 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash
227 virtual const Node *is_block_proj() const { return this; }
228 virtual bool depends_only_on_test() const { return false; }
229 virtual const Type *bottom_type() const { return Type::CONTROL; }
230 virtual const Type* Value(PhaseGVN* phase) const;
231 virtual Node* Identity(PhaseGVN* phase);
232 virtual const RegMask &out_RegMask() const;
233
234 #ifndef PRODUCT
235 virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
236 #endif
237 };
238
239 //------------------------------CProjNode--------------------------------------
240 // control projection for node that produces multiple control-flow paths
241 class CProjNode : public ProjNode {
242 public:
243 CProjNode( Node *ctrl, uint idx ) : ProjNode(ctrl,idx) {}
244 virtual int Opcode() const;
245 virtual bool is_CFG() const { return true; }
246 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash
247 virtual const Node *is_block_proj() const { return in(0); }
248 virtual const RegMask &out_RegMask() const;
249 virtual uint ideal_reg() const { return 0; }
250 };
251
360 // threshold for ignoring counts when estimating path frequency
361 // likelihood of FP clipping failure
362 // likelihood of catching an exception from a try block
363 // likelihood of null check failure if a null has NOT been seen before
364 //
365 // Magic manifest probabilities such as 0.83, 0.7, ... can be found in
366 // gen_subtype_check() and catch_inline_exceptions().
367
368 float _prob; // Probability of true path being taken.
369 float _fcnt; // Frequency counter
370 IfNode( Node *control, Node *b, float p, float fcnt )
371 : MultiBranchNode(2), _prob(p), _fcnt(fcnt) {
372 init_class_id(Class_If);
373 init_req(0,control);
374 init_req(1,b);
375 }
376 virtual int Opcode() const;
377 virtual bool pinned() const { return true; }
378 virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }
379 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
380 virtual const Type* Value(PhaseGVN* phase) const;
381 virtual int required_outcnt() const { return 2; }
382 virtual const RegMask &out_RegMask() const;
383 Node* fold_compares(PhaseIterGVN* phase);
384 static Node* up_one_dom(Node* curr, bool linear_only = false);
385
386 // Takes the type of val and filters it through the test represented
387 // by if_proj and returns a more refined type if one is produced.
388 // Returns NULL is it couldn't improve the type.
389 static const TypeInt* filtered_int_type(PhaseGVN* phase, Node* val, Node* if_proj);
390
391 #ifndef PRODUCT
392 virtual void dump_spec(outputStream *st) const;
393 virtual void related(GrowableArray <Node *> *in_rel, GrowableArray <Node *> *out_rel, bool compact) const;
394 #endif
395 };
396
397 class RangeCheckNode : public IfNode {
398 private:
399 int is_range_check(Node* &range, Node* &index, jint &offset);
400
401 public:
402 RangeCheckNode(Node* control, Node *b, float p, float fcnt)
403 : IfNode(control, b, p, fcnt) {
404 init_class_id(Class_RangeCheck);
405 }
406
407 virtual int Opcode() const;
408 virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
409 };
410
411 class IfProjNode : public CProjNode {
412 public:
413 IfProjNode(IfNode *ifnode, uint idx) : CProjNode(ifnode,idx) {}
414 virtual Node* Identity(PhaseGVN* phase);
415
416 protected:
417 // Type of If input when this branch is always taken
418 virtual bool always_taken(const TypeTuple* t) const = 0;
419
420 #ifndef PRODUCT
421 public:
422 virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
423 #endif
424 };
425
426 class IfTrueNode : public IfProjNode {
427 public:
428 IfTrueNode( IfNode *ifnode ) : IfProjNode(ifnode,1) {
429 init_class_id(Class_IfTrue);
430 }
431 virtual int Opcode() const;
432
433 protected:
434 virtual bool always_taken(const TypeTuple* t) const { return t == TypeTuple::IFTRUE; }
448
449 //------------------------------PCTableNode------------------------------------
450 // Build an indirect branch table. Given a control and a table index,
451 // control is passed to the Projection matching the table index. Used to
452 // implement switch statements and exception-handling capabilities.
453 // Undefined behavior if passed-in index is not inside the table.
454 class PCTableNode : public MultiBranchNode {
455 virtual uint hash() const; // Target count; table size
456 virtual uint cmp( const Node &n ) const;
457 virtual uint size_of() const { return sizeof(*this); }
458
459 public:
460 const uint _size; // Number of targets
461
462 PCTableNode( Node *ctrl, Node *idx, uint size ) : MultiBranchNode(2), _size(size) {
463 init_class_id(Class_PCTable);
464 init_req(0, ctrl);
465 init_req(1, idx);
466 }
467 virtual int Opcode() const;
468 virtual const Type* Value(PhaseGVN* phase) const;
469 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
470 virtual const Type *bottom_type() const;
471 virtual bool pinned() const { return true; }
472 virtual int required_outcnt() const { return _size; }
473 };
474
475 //------------------------------JumpNode---------------------------------------
476 // Indirect branch. Uses PCTable above to implement a switch statement.
477 // It emits as a table load and local branch.
478 class JumpNode : public PCTableNode {
479 public:
480 JumpNode( Node* control, Node* switch_val, uint size) : PCTableNode(control, switch_val, size) {
481 init_class_id(Class_Jump);
482 }
483 virtual int Opcode() const;
484 virtual const RegMask& out_RegMask() const;
485 virtual const Node* is_block_proj() const { return this; }
486 #ifndef PRODUCT
487 virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
488 #endif
508 int dest_bci() const { return _dest_bci; }
509 int switch_val() const { return _switch_val; }
510 uint proj_no() const { return _proj_no; }
511 #ifndef PRODUCT
512 virtual void dump_spec(outputStream *st) const;
513 virtual void dump_compact_spec(outputStream *st) const;
514 virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
515 #endif
516 };
517
518 //------------------------------CatchNode--------------------------------------
519 // Helper node to fork exceptions. "Catch" catches any exceptions thrown by
520 // a just-prior call. Looks like a PCTableNode but emits no code - just the
521 // table. The table lookup and branch is implemented by RethrowNode.
522 class CatchNode : public PCTableNode {
523 public:
524 CatchNode( Node *ctrl, Node *idx, uint size ) : PCTableNode(ctrl,idx,size){
525 init_class_id(Class_Catch);
526 }
527 virtual int Opcode() const;
528 virtual const Type* Value(PhaseGVN* phase) const;
529 };
530
531 // CatchProjNode controls which exception handler is targetted after a call.
532 // It is passed in the bci of the target handler, or no_handler_bci in case
533 // the projection doesn't lead to an exception handler.
534 class CatchProjNode : public CProjNode {
535 virtual uint hash() const;
536 virtual uint cmp( const Node &n ) const;
537 virtual uint size_of() const { return sizeof(*this); }
538
539 private:
540 const int _handler_bci;
541
542 public:
543 enum {
544 fall_through_index = 0, // the fall through projection index
545 catch_all_index = 1, // the projection index for catch-alls
546 no_handler_bci = -1 // the bci for fall through or catch-all projs
547 };
548
549 CatchProjNode(Node* catchnode, uint proj_no, int handler_bci)
550 : CProjNode(catchnode, proj_no), _handler_bci(handler_bci) {
551 init_class_id(Class_CatchProj);
552 assert(proj_no != fall_through_index || handler_bci < 0, "fall through case must have bci < 0");
553 }
554
555 virtual int Opcode() const;
556 virtual Node* Identity(PhaseGVN* phase);
557 virtual const Type *bottom_type() const { return Type::CONTROL; }
558 int handler_bci() const { return _handler_bci; }
559 bool is_handler_proj() const { return _handler_bci >= 0; }
560 #ifndef PRODUCT
561 virtual void dump_spec(outputStream *st) const;
562 #endif
563 };
564
565
566 //---------------------------------CreateExNode--------------------------------
567 // Helper node to create the exception coming back from a call
568 class CreateExNode : public TypeNode {
569 public:
570 CreateExNode(const Type* t, Node* control, Node* i_o) : TypeNode(t, 2) {
571 init_req(0, control);
572 init_req(1, i_o);
573 }
574 virtual int Opcode() const;
575 virtual Node* Identity(PhaseGVN* phase);
576 virtual bool pinned() const { return true; }
577 uint match_edge(uint idx) const { return 0; }
578 virtual uint ideal_reg() const { return Op_RegP; }
579 };
580
581 //------------------------------NeverBranchNode-------------------------------
582 // The never-taken branch. Used to give the appearance of exiting infinite
583 // loops to those algorithms that like all paths to be reachable. Encodes
584 // empty.
585 class NeverBranchNode : public MultiBranchNode {
586 public:
587 NeverBranchNode( Node *ctrl ) : MultiBranchNode(1) { init_req(0,ctrl); }
588 virtual int Opcode() const;
589 virtual bool pinned() const { return true; };
590 virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }
591 virtual const Type* Value(PhaseGVN* phase) const;
592 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
593 virtual int required_outcnt() const { return 2; }
594 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { }
595 virtual uint size(PhaseRegAlloc *ra_) const { return 0; }
596 #ifndef PRODUCT
597 virtual void format( PhaseRegAlloc *, outputStream *st ) const;
598 #endif
599 };
600
601 #endif // SHARE_VM_OPTO_CFGNODE_HPP
|