< prev index next >

src/share/vm/opto/cfgnode.hpp

Print this page
rev 8739 : 8004073: Implement C2 Ideal node specific dump() method
Summary: add Node::dump_rel() to dump a node and its related nodes (the notion of "related" depends on the node at hand); add Node::dump_comp() to dump a node in compact representation; add Node::dump_rel_comp() to dump a node and its related nodes in compact representation; add the required machinery; extend some C2 IR nodes with compact and related dumping
Reviewed-by:
   1 /*
   2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 212 #else //ASSERT
 213   void verify_adr_type(bool recursive = false) const {}
 214 #endif //ASSERT
 215 };
 216 
 217 //------------------------------GotoNode---------------------------------------
 218 // GotoNodes perform direct branches.
 219 class GotoNode : public Node {
 220 public:
 221   GotoNode( Node *control ) : Node(control) {}
 222   virtual int Opcode() const;
 223   virtual bool pinned() const { return true; }
 224   virtual bool  is_CFG() const { return true; }
 225   virtual uint hash() const { return NO_HASH; }  // CFG nodes do not hash
 226   virtual const Node *is_block_proj() const { return this; }
 227   virtual bool depends_only_on_test() const { return false; }
 228   virtual const Type *bottom_type() const { return Type::CONTROL; }
 229   virtual const Type *Value( PhaseTransform *phase ) const;
 230   virtual Node *Identity( PhaseTransform *phase );
 231   virtual const RegMask &out_RegMask() const;




 232 };
 233 
 234 //------------------------------CProjNode--------------------------------------
 235 // control projection for node that produces multiple control-flow paths
 236 class CProjNode : public ProjNode {
 237 public:
 238   CProjNode( Node *ctrl, uint idx ) : ProjNode(ctrl,idx) {}
 239   virtual int Opcode() const;
 240   virtual bool  is_CFG() const { return true; }
 241   virtual uint hash() const { return NO_HASH; }  // CFG nodes do not hash
 242   virtual const Node *is_block_proj() const { return in(0); }
 243   virtual const RegMask &out_RegMask() const;
 244   virtual uint ideal_reg() const { return 0; }
 245 };
 246 
 247 //---------------------------MultiBranchNode-----------------------------------
 248 // This class defines a MultiBranchNode, a MultiNode which yields multiple
 249 // control values. These are distinguished from other types of MultiNodes
 250 // which yield multiple values, but control is always and only projection #0.
 251 class MultiBranchNode : public MultiNode {


 365   }
 366   virtual int Opcode() const;
 367   virtual bool pinned() const { return true; }
 368   virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }
 369   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 370   virtual const Type *Value( PhaseTransform *phase ) const;
 371   virtual int required_outcnt() const { return 2; }
 372   virtual const RegMask &out_RegMask() const;
 373   void dominated_by(Node* prev_dom, PhaseIterGVN* igvn);
 374   int is_range_check(Node* &range, Node* &index, jint &offset);
 375   Node* fold_compares(PhaseIterGVN* phase);
 376   static Node* up_one_dom(Node* curr, bool linear_only = false);
 377 
 378   // Takes the type of val and filters it through the test represented
 379   // by if_proj and returns a more refined type if one is produced.
 380   // Returns NULL is it couldn't improve the type.
 381   static const TypeInt* filtered_int_type(PhaseGVN* phase, Node* val, Node* if_proj);
 382 
 383 #ifndef PRODUCT
 384   virtual void dump_spec(outputStream *st) const;

 385 #endif
 386 };
 387 
 388 class IfProjNode : public CProjNode {
 389 public:
 390   IfProjNode(IfNode *ifnode, uint idx) : CProjNode(ifnode,idx) {}
 391   virtual Node *Identity(PhaseTransform *phase);
 392 
 393 protected:
 394   // Type of If input when this branch is always taken
 395   virtual bool always_taken(const TypeTuple* t) const = 0;





 396 };
 397 
 398 class IfTrueNode : public IfProjNode {
 399 public:
 400   IfTrueNode( IfNode *ifnode ) : IfProjNode(ifnode,1) {
 401     init_class_id(Class_IfTrue);
 402   }
 403   virtual int Opcode() const;
 404 
 405 protected:
 406   virtual bool always_taken(const TypeTuple* t) const { return t == TypeTuple::IFTRUE; }
 407 };
 408 
 409 class IfFalseNode : public IfProjNode {
 410 public:
 411   IfFalseNode( IfNode *ifnode ) : IfProjNode(ifnode,0) {
 412     init_class_id(Class_IfFalse);
 413   }
 414   virtual int Opcode() const;
 415 


 438   }
 439   virtual int Opcode() const;
 440   virtual const Type *Value( PhaseTransform *phase ) const;
 441   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 442   virtual const Type *bottom_type() const;
 443   virtual bool pinned() const { return true; }
 444   virtual int required_outcnt() const { return _size; }
 445 };
 446 
 447 //------------------------------JumpNode---------------------------------------
 448 // Indirect branch.  Uses PCTable above to implement a switch statement.
 449 // It emits as a table load and local branch.
 450 class JumpNode : public PCTableNode {
 451 public:
 452   JumpNode( Node* control, Node* switch_val, uint size) : PCTableNode(control, switch_val, size) {
 453     init_class_id(Class_Jump);
 454   }
 455   virtual int   Opcode() const;
 456   virtual const RegMask& out_RegMask() const;
 457   virtual const Node* is_block_proj() const { return this; }



 458 };
 459 
 460 class JumpProjNode : public JProjNode {
 461   virtual uint hash() const;
 462   virtual uint cmp( const Node &n ) const;
 463   virtual uint size_of() const { return sizeof(*this); }
 464 
 465  private:
 466   const int  _dest_bci;
 467   const uint _proj_no;
 468   const int  _switch_val;
 469  public:
 470   JumpProjNode(Node* jumpnode, uint proj_no, int dest_bci, int switch_val)
 471     : JProjNode(jumpnode, proj_no), _dest_bci(dest_bci), _proj_no(proj_no), _switch_val(switch_val) {
 472     init_class_id(Class_JumpProj);
 473   }
 474 
 475   virtual int Opcode() const;
 476   virtual const Type* bottom_type() const { return Type::CONTROL; }
 477   int  dest_bci()    const { return _dest_bci; }
 478   int  switch_val()  const { return _switch_val; }
 479   uint proj_no()     const { return _proj_no; }
 480 #ifndef PRODUCT
 481   virtual void dump_spec(outputStream *st) const;


 482 #endif
 483 };
 484 
 485 //------------------------------CatchNode--------------------------------------
 486 // Helper node to fork exceptions.  "Catch" catches any exceptions thrown by
 487 // a just-prior call.  Looks like a PCTableNode but emits no code - just the
 488 // table.  The table lookup and branch is implemented by RethrowNode.
 489 class CatchNode : public PCTableNode {
 490 public:
 491   CatchNode( Node *ctrl, Node *idx, uint size ) : PCTableNode(ctrl,idx,size){
 492     init_class_id(Class_Catch);
 493   }
 494   virtual int Opcode() const;
 495   virtual const Type *Value( PhaseTransform *phase ) const;
 496 };
 497 
 498 // CatchProjNode controls which exception handler is targetted after a call.
 499 // It is passed in the bci of the target handler, or no_handler_bci in case
 500 // the projection doesn't lead to an exception handler.
 501 class CatchProjNode : public CProjNode {


   1 /*
   2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 212 #else //ASSERT
 213   void verify_adr_type(bool recursive = false) const {}
 214 #endif //ASSERT
 215 };
 216 
 217 //------------------------------GotoNode---------------------------------------
 218 // GotoNodes perform direct branches.
 219 class GotoNode : public Node {
 220 public:
 221   GotoNode( Node *control ) : Node(control) {}
 222   virtual int Opcode() const;
 223   virtual bool pinned() const { return true; }
 224   virtual bool  is_CFG() const { return true; }
 225   virtual uint hash() const { return NO_HASH; }  // CFG nodes do not hash
 226   virtual const Node *is_block_proj() const { return this; }
 227   virtual bool depends_only_on_test() const { return false; }
 228   virtual const Type *bottom_type() const { return Type::CONTROL; }
 229   virtual const Type *Value( PhaseTransform *phase ) const;
 230   virtual Node *Identity( PhaseTransform *phase );
 231   virtual const RegMask &out_RegMask() const;
 232 
 233 #ifndef PRODUCT
 234   virtual void rel(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
 235 #endif
 236 };
 237 
 238 //------------------------------CProjNode--------------------------------------
 239 // control projection for node that produces multiple control-flow paths
 240 class CProjNode : public ProjNode {
 241 public:
 242   CProjNode( Node *ctrl, uint idx ) : ProjNode(ctrl,idx) {}
 243   virtual int Opcode() const;
 244   virtual bool  is_CFG() const { return true; }
 245   virtual uint hash() const { return NO_HASH; }  // CFG nodes do not hash
 246   virtual const Node *is_block_proj() const { return in(0); }
 247   virtual const RegMask &out_RegMask() const;
 248   virtual uint ideal_reg() const { return 0; }
 249 };
 250 
 251 //---------------------------MultiBranchNode-----------------------------------
 252 // This class defines a MultiBranchNode, a MultiNode which yields multiple
 253 // control values. These are distinguished from other types of MultiNodes
 254 // which yield multiple values, but control is always and only projection #0.
 255 class MultiBranchNode : public MultiNode {


 369   }
 370   virtual int Opcode() const;
 371   virtual bool pinned() const { return true; }
 372   virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }
 373   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 374   virtual const Type *Value( PhaseTransform *phase ) const;
 375   virtual int required_outcnt() const { return 2; }
 376   virtual const RegMask &out_RegMask() const;
 377   void dominated_by(Node* prev_dom, PhaseIterGVN* igvn);
 378   int is_range_check(Node* &range, Node* &index, jint &offset);
 379   Node* fold_compares(PhaseIterGVN* phase);
 380   static Node* up_one_dom(Node* curr, bool linear_only = false);
 381 
 382   // Takes the type of val and filters it through the test represented
 383   // by if_proj and returns a more refined type if one is produced.
 384   // Returns NULL is it couldn't improve the type.
 385   static const TypeInt* filtered_int_type(PhaseGVN* phase, Node* val, Node* if_proj);
 386 
 387 #ifndef PRODUCT
 388   virtual void dump_spec(outputStream *st) const;
 389   virtual void rel(GrowableArray <Node *> *in_rel, GrowableArray <Node *> *out_rel, bool compact) const;
 390 #endif
 391 };
 392 
 393 class IfProjNode : public CProjNode {
 394 public:
 395   IfProjNode(IfNode *ifnode, uint idx) : CProjNode(ifnode,idx) {}
 396   virtual Node *Identity(PhaseTransform *phase);
 397 
 398 protected:
 399   // Type of If input when this branch is always taken
 400   virtual bool always_taken(const TypeTuple* t) const = 0;
 401 
 402 #ifndef PRODUCT
 403 public:
 404   virtual void rel(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
 405 #endif
 406 };
 407 
 408 class IfTrueNode : public IfProjNode {
 409 public:
 410   IfTrueNode( IfNode *ifnode ) : IfProjNode(ifnode,1) {
 411     init_class_id(Class_IfTrue);
 412   }
 413   virtual int Opcode() const;
 414 
 415 protected:
 416   virtual bool always_taken(const TypeTuple* t) const { return t == TypeTuple::IFTRUE; }
 417 };
 418 
 419 class IfFalseNode : public IfProjNode {
 420 public:
 421   IfFalseNode( IfNode *ifnode ) : IfProjNode(ifnode,0) {
 422     init_class_id(Class_IfFalse);
 423   }
 424   virtual int Opcode() const;
 425 


 448   }
 449   virtual int Opcode() const;
 450   virtual const Type *Value( PhaseTransform *phase ) const;
 451   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 452   virtual const Type *bottom_type() const;
 453   virtual bool pinned() const { return true; }
 454   virtual int required_outcnt() const { return _size; }
 455 };
 456 
 457 //------------------------------JumpNode---------------------------------------
 458 // Indirect branch.  Uses PCTable above to implement a switch statement.
 459 // It emits as a table load and local branch.
 460 class JumpNode : public PCTableNode {
 461 public:
 462   JumpNode( Node* control, Node* switch_val, uint size) : PCTableNode(control, switch_val, size) {
 463     init_class_id(Class_Jump);
 464   }
 465   virtual int   Opcode() const;
 466   virtual const RegMask& out_RegMask() const;
 467   virtual const Node* is_block_proj() const { return this; }
 468 #ifndef PRODUCT
 469   virtual void rel(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
 470 #endif
 471 };
 472 
 473 class JumpProjNode : public JProjNode {
 474   virtual uint hash() const;
 475   virtual uint cmp( const Node &n ) const;
 476   virtual uint size_of() const { return sizeof(*this); }
 477 
 478  private:
 479   const int  _dest_bci;
 480   const uint _proj_no;
 481   const int  _switch_val;
 482  public:
 483   JumpProjNode(Node* jumpnode, uint proj_no, int dest_bci, int switch_val)
 484     : JProjNode(jumpnode, proj_no), _dest_bci(dest_bci), _proj_no(proj_no), _switch_val(switch_val) {
 485     init_class_id(Class_JumpProj);
 486   }
 487 
 488   virtual int Opcode() const;
 489   virtual const Type* bottom_type() const { return Type::CONTROL; }
 490   int  dest_bci()    const { return _dest_bci; }
 491   int  switch_val()  const { return _switch_val; }
 492   uint proj_no()     const { return _proj_no; }
 493 #ifndef PRODUCT
 494   virtual void dump_spec(outputStream *st) const;
 495   virtual void dump_comp_spec(outputStream *st) const;
 496   virtual void rel(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
 497 #endif
 498 };
 499 
 500 //------------------------------CatchNode--------------------------------------
 501 // Helper node to fork exceptions.  "Catch" catches any exceptions thrown by
 502 // a just-prior call.  Looks like a PCTableNode but emits no code - just the
 503 // table.  The table lookup and branch is implemented by RethrowNode.
 504 class CatchNode : public PCTableNode {
 505 public:
 506   CatchNode( Node *ctrl, Node *idx, uint size ) : PCTableNode(ctrl,idx,size){
 507     init_class_id(Class_Catch);
 508   }
 509   virtual int Opcode() const;
 510   virtual const Type *Value( PhaseTransform *phase ) const;
 511 };
 512 
 513 // CatchProjNode controls which exception handler is targetted after a call.
 514 // It is passed in the bci of the target handler, or no_handler_bci in case
 515 // the projection doesn't lead to an exception handler.
 516 class CatchProjNode : public CProjNode {


< prev index next >