src/share/vm/opto/callnode.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/callnode.hpp

Print this page
rev 6442 : 8026796: Make replace_in_map() on parent maps generic
Summary: propagate node replacements along control flow edges to callers
Reviewed-by:


 295   void              set_bci(int bci) {if(_bci != bci)_reexecute=Reexecute_Undefined; _bci = bci; }
 296   void              set_should_reexecute(bool reexec) {_reexecute = reexec ? Reexecute_True : Reexecute_False;}
 297 
 298   // Miscellaneous utility functions
 299   JVMState* clone_deep(Compile* C) const;    // recursively clones caller chain
 300   JVMState* clone_shallow(Compile* C) const; // retains uncloned caller
 301   void      set_map_deep(SafePointNode *map);// reset map for all callers
 302   void      adapt_position(int delta);       // Adapt offsets in in-array after adding an edge.
 303   int       interpreter_frame_size() const;
 304 
 305 #ifndef PRODUCT
 306   void      format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const;
 307   void      dump_spec(outputStream *st) const;
 308   void      dump_on(outputStream* st) const;
 309   void      dump() const {
 310     dump_on(tty);
 311   }
 312 #endif
 313 };
 314 



















































 315 //------------------------------SafePointNode----------------------------------
 316 // A SafePointNode is a subclass of a MultiNode for convenience (and
 317 // potential code sharing) only - conceptually it is independent of
 318 // the Node semantics.
 319 class SafePointNode : public MultiNode {
 320   virtual uint           cmp( const Node &n ) const;
 321   virtual uint           size_of() const;       // Size is bigger
 322 
 323 public:
 324   SafePointNode(uint edges, JVMState* jvms,
 325                 // A plain safepoint advertises no memory effects (NULL):
 326                 const TypePtr* adr_type = NULL)
 327     : MultiNode( edges ),
 328       _jvms(jvms),
 329       _oop_map(NULL),
 330       _adr_type(adr_type)
 331   {
 332     init_class_id(Class_SafePoint);
 333   }
 334 
 335   OopMap*         _oop_map;   // Array of OopMap info (8-bit char) for GC
 336   JVMState* const _jvms;      // Pointer to list of JVM State objects
 337   const TypePtr*  _adr_type;  // What type of memory does this node produce?

 338 
 339   // Many calls take *all* of memory as input,
 340   // but some produce a limited subset of that memory as output.
 341   // The adr_type reports the call's behavior as a store, not a load.
 342 
 343   virtual JVMState* jvms() const { return _jvms; }
 344   void set_jvms(JVMState* s) {
 345     *(JVMState**)&_jvms = s;  // override const attribute in the accessor
 346   }
 347   OopMap *oop_map() const { return _oop_map; }
 348   void set_oop_map(OopMap *om) { _oop_map = om; }
 349 
 350  private:
 351   void verify_input(JVMState* jvms, uint idx) const {
 352     assert(verify_jvms(jvms), "jvms must match");
 353     Node* n = in(idx);
 354     assert((!n->bottom_type()->isa_long() && !n->bottom_type()->isa_double()) ||
 355            in(idx + 1)->is_top(), "2nd half of long/double");
 356   }
 357 


 408   Node *frameptr () const { return in(TypeFunc::FramePtr ); }
 409 
 410   void set_control  ( Node *c ) { set_req(TypeFunc::Control,c); }
 411   void set_i_o      ( Node *c ) { set_req(TypeFunc::I_O    ,c); }
 412   void set_memory   ( Node *c ) { set_req(TypeFunc::Memory ,c); }
 413 
 414   MergeMemNode* merged_memory() const {
 415     return in(TypeFunc::Memory)->as_MergeMem();
 416   }
 417 
 418   // The parser marks useless maps as dead when it's done with them:
 419   bool is_killed() { return in(TypeFunc::Control) == NULL; }
 420 
 421   // Exception states bubbling out of subgraphs such as inlined calls
 422   // are recorded here.  (There might be more than one, hence the "next".)
 423   // This feature is used only for safepoints which serve as "maps"
 424   // for JVM states during parsing, intrinsic expansion, etc.
 425   SafePointNode*         next_exception() const;
 426   void               set_next_exception(SafePointNode* n);
 427   bool                   has_exceptions() const { return next_exception() != NULL; }























 428 
 429   // Standard Node stuff
 430   virtual int            Opcode() const;
 431   virtual bool           pinned() const { return true; }
 432   virtual const Type    *Value( PhaseTransform *phase ) const;
 433   virtual const Type    *bottom_type() const { return Type::CONTROL; }
 434   virtual const TypePtr *adr_type() const { return _adr_type; }
 435   virtual Node          *Ideal(PhaseGVN *phase, bool can_reshape);
 436   virtual Node          *Identity( PhaseTransform *phase );
 437   virtual uint           ideal_reg() const { return 0; }
 438   virtual const RegMask &in_RegMask(uint) const;
 439   virtual const RegMask &out_RegMask() const;
 440   virtual uint           match_edge(uint idx) const;
 441 
 442   static  bool           needs_polling_address_input();
 443 
 444 #ifndef PRODUCT
 445   virtual void           dump_spec(outputStream *st) const;
 446 #endif
 447 };




 295   void              set_bci(int bci) {if(_bci != bci)_reexecute=Reexecute_Undefined; _bci = bci; }
 296   void              set_should_reexecute(bool reexec) {_reexecute = reexec ? Reexecute_True : Reexecute_False;}
 297 
 298   // Miscellaneous utility functions
 299   JVMState* clone_deep(Compile* C) const;    // recursively clones caller chain
 300   JVMState* clone_shallow(Compile* C) const; // retains uncloned caller
 301   void      set_map_deep(SafePointNode *map);// reset map for all callers
 302   void      adapt_position(int delta);       // Adapt offsets in in-array after adding an edge.
 303   int       interpreter_frame_size() const;
 304 
 305 #ifndef PRODUCT
 306   void      format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const;
 307   void      dump_spec(outputStream *st) const;
 308   void      dump_on(outputStream* st) const;
 309   void      dump() const {
 310     dump_on(tty);
 311   }
 312 #endif
 313 };
 314 
 315 // During parsing, when a node is "improved",
 316 // GraphKit::replace_in_map() is called to update the current map so
 317 // that the improved node is used from that point
 318 // on. GraphKit::replace_in_map() doesn't operate on the callers maps
 319 // and so some optimization opportunities may be lost. The
 320 // ReplacedNodes class addresses that problem.
 321 //
 322 // A ReplacedNodes object is a list of pair of nodes. Every
 323 // SafePointNode carries a ReplacedNodes object. Every time
 324 // GraphKit::replace_in_map() is called, a new pair of nodes is pushed
 325 // on the list of replaced nodes. When control flow paths merge, their
 326 // replaced nodes are also merged. When parsing exits a method to
 327 // return to a caller, the replaced nodes on the exit path are used to
 328 // update the caller's map.
 329 class ReplacedNodes VALUE_OBJ_CLASS_SPEC {
 330  private:
 331   class ReplacedNode VALUE_OBJ_CLASS_SPEC {
 332   private:
 333     Node* _before;
 334     Node* _after;
 335   public:
 336     ReplacedNode() : _before(NULL), _after(NULL) {}
 337     ReplacedNode(Node* before, Node* after) : _before(before), _after(after) {}
 338     Node* before() const { return _before; }
 339     Node* after() const { return _after; }
 340 
 341     bool operator==(const ReplacedNode& other) {
 342       return _before == other._before && _after == other._after;
 343     }
 344   };
 345   GrowableArray<ReplacedNode>* _replaced_nodes;
 346 
 347   void allocate_if_necessary();
 348   bool has_node(ReplacedNode r) const;
 349   bool has_target_node(Node* n) const;
 350 
 351  public:
 352   ReplacedNodes()
 353     : _replaced_nodes(NULL) {}
 354   
 355   void clone();
 356   void record(Node* o, Node* n);
 357   void transfer_from(ReplacedNodes other, uint idx);
 358   void reset();
 359   void apply(Node* n);
 360   void merge_with(ReplacedNodes other);
 361   bool is_empty() const;
 362   void dump(outputStream *st) const;
 363   void apply(Compile* C, Node* ctl);
 364 };
 365 
 366 //------------------------------SafePointNode----------------------------------
 367 // A SafePointNode is a subclass of a MultiNode for convenience (and
 368 // potential code sharing) only - conceptually it is independent of
 369 // the Node semantics.
 370 class SafePointNode : public MultiNode {
 371   virtual uint           cmp( const Node &n ) const;
 372   virtual uint           size_of() const;       // Size is bigger
 373 
 374 public:
 375   SafePointNode(uint edges, JVMState* jvms,
 376                 // A plain safepoint advertises no memory effects (NULL):
 377                 const TypePtr* adr_type = NULL)
 378     : MultiNode( edges ),
 379       _jvms(jvms),
 380       _oop_map(NULL),
 381       _adr_type(adr_type)
 382   {
 383     init_class_id(Class_SafePoint);
 384   }
 385 
 386   OopMap*         _oop_map;   // Array of OopMap info (8-bit char) for GC
 387   JVMState* const _jvms;      // Pointer to list of JVM State objects
 388   const TypePtr*  _adr_type;  // What type of memory does this node produce?
 389   ReplacedNodes   _replaced_nodes; // During parsing: list of pair of nodes from calls to GraphKit::replace_in_map()
 390 
 391   // Many calls take *all* of memory as input,
 392   // but some produce a limited subset of that memory as output.
 393   // The adr_type reports the call's behavior as a store, not a load.
 394 
 395   virtual JVMState* jvms() const { return _jvms; }
 396   void set_jvms(JVMState* s) {
 397     *(JVMState**)&_jvms = s;  // override const attribute in the accessor
 398   }
 399   OopMap *oop_map() const { return _oop_map; }
 400   void set_oop_map(OopMap *om) { _oop_map = om; }
 401 
 402  private:
 403   void verify_input(JVMState* jvms, uint idx) const {
 404     assert(verify_jvms(jvms), "jvms must match");
 405     Node* n = in(idx);
 406     assert((!n->bottom_type()->isa_long() && !n->bottom_type()->isa_double()) ||
 407            in(idx + 1)->is_top(), "2nd half of long/double");
 408   }
 409 


 460   Node *frameptr () const { return in(TypeFunc::FramePtr ); }
 461 
 462   void set_control  ( Node *c ) { set_req(TypeFunc::Control,c); }
 463   void set_i_o      ( Node *c ) { set_req(TypeFunc::I_O    ,c); }
 464   void set_memory   ( Node *c ) { set_req(TypeFunc::Memory ,c); }
 465 
 466   MergeMemNode* merged_memory() const {
 467     return in(TypeFunc::Memory)->as_MergeMem();
 468   }
 469 
 470   // The parser marks useless maps as dead when it's done with them:
 471   bool is_killed() { return in(TypeFunc::Control) == NULL; }
 472 
 473   // Exception states bubbling out of subgraphs such as inlined calls
 474   // are recorded here.  (There might be more than one, hence the "next".)
 475   // This feature is used only for safepoints which serve as "maps"
 476   // for JVM states during parsing, intrinsic expansion, etc.
 477   SafePointNode*         next_exception() const;
 478   void               set_next_exception(SafePointNode* n);
 479   bool                   has_exceptions() const { return next_exception() != NULL; }
 480 
 481   // Helper methods to operate on replaced nodes
 482   void clone_replaced_nodes() {
 483     _replaced_nodes.clone();
 484   }
 485   void record_replaced_node(Node* o, Node* n) {
 486     _replaced_nodes.record(o, n);
 487   }
 488   void transfer_replaced_nodes_from(SafePointNode* sfpt, uint idx = 0) {
 489     _replaced_nodes.transfer_from(sfpt->_replaced_nodes, idx);
 490   }
 491   void delete_replaced_nodes() {
 492     _replaced_nodes.reset();
 493   }
 494   void apply_replaced_nodes() {
 495     _replaced_nodes.apply(this);
 496   }
 497   void merge_replaced_nodes_with(SafePointNode* sfpt) {
 498     _replaced_nodes.merge_with(sfpt->_replaced_nodes);
 499   }
 500   bool has_replaced_nodes() const {
 501     return !_replaced_nodes.is_empty();
 502   }
 503 
 504   // Standard Node stuff
 505   virtual int            Opcode() const;
 506   virtual bool           pinned() const { return true; }
 507   virtual const Type    *Value( PhaseTransform *phase ) const;
 508   virtual const Type    *bottom_type() const { return Type::CONTROL; }
 509   virtual const TypePtr *adr_type() const { return _adr_type; }
 510   virtual Node          *Ideal(PhaseGVN *phase, bool can_reshape);
 511   virtual Node          *Identity( PhaseTransform *phase );
 512   virtual uint           ideal_reg() const { return 0; }
 513   virtual const RegMask &in_RegMask(uint) const;
 514   virtual const RegMask &out_RegMask() const;
 515   virtual uint           match_edge(uint idx) const;
 516 
 517   static  bool           needs_polling_address_input();
 518 
 519 #ifndef PRODUCT
 520   virtual void           dump_spec(outputStream *st) const;
 521 #endif
 522 };


src/share/vm/opto/callnode.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File