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

src/share/vm/opto/cfgnode.hpp

Print this page
rev 9360 : 8137168: Replace IfNode with a new RangeCheckNode for range checks
Summary: new RangeCheckNode to enable optimization of explicit library level range checks
Reviewed-by:


 253 // This class defines a MultiBranchNode, a MultiNode which yields multiple
 254 // control values. These are distinguished from other types of MultiNodes
 255 // which yield multiple values, but control is always and only projection #0.
 256 class MultiBranchNode : public MultiNode {
 257 public:
 258   MultiBranchNode( uint required ) : MultiNode(required) {
 259     init_class_id(Class_MultiBranch);
 260   }
 261   // returns required number of users to be well formed.
 262   virtual int required_outcnt() const = 0;
 263 };
 264 
 265 //------------------------------IfNode-----------------------------------------
 266 // Output selected Control, based on a boolean test
 267 class IfNode : public MultiBranchNode {
 268   // Size is bigger to hold the probability field.  However, _prob does not
 269   // change the semantics so it does not appear in the hash & cmp functions.
 270   virtual uint size_of() const { return sizeof(*this); }
 271 
 272 private:
 273   ProjNode* range_check_trap_proj(int& flip, Node*& l, Node*& r);
 274   ProjNode* range_check_trap_proj() {
 275     int flip_test = 0;
 276     Node* l = NULL;
 277     Node* r = NULL;
 278     return range_check_trap_proj(flip_test, l, r);
 279   }
 280 
 281   // Helper methods for fold_compares
 282   bool cmpi_folds(PhaseIterGVN* igvn);
 283   bool is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn);
 284   bool has_shared_region(ProjNode* proj, ProjNode*& success, ProjNode*& fail);
 285   bool has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNode*& fail, PhaseIterGVN* igvn);
 286   static void merge_uncommon_traps(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn);
 287   static void improve_address_types(Node* l, Node* r, ProjNode* fail, PhaseIterGVN* igvn);
 288   bool is_cmp_with_loadrange(ProjNode* proj);
 289   bool is_null_check(ProjNode* proj, PhaseIterGVN* igvn);
 290   bool is_side_effect_free_test(ProjNode* proj, PhaseIterGVN* igvn);
 291   void reroute_side_effect_free_unc(ProjNode* proj, ProjNode* dom_proj, PhaseIterGVN* igvn);
 292   ProjNode* uncommon_trap_proj(CallStaticJavaNode*& call) const;
 293   bool fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn);
 294 






 295 public:
 296 
 297   // Degrees of branch prediction probability by order of magnitude:
 298   // PROB_UNLIKELY_1e(N) is a 1 in 1eN chance.
 299   // PROB_LIKELY_1e(N) is a 1 - PROB_UNLIKELY_1e(N)
 300 #define PROB_UNLIKELY_MAG(N)    (1e- ## N ## f)
 301 #define PROB_LIKELY_MAG(N)      (1.0f-PROB_UNLIKELY_MAG(N))
 302 
 303   // Maximum and minimum branch prediction probabilties
 304   // 1 in 1,000,000 (magnitude 6)
 305   //
 306   // Although PROB_NEVER == PROB_MIN and PROB_ALWAYS == PROB_MAX
 307   // they are used to distinguish different situations:
 308   //
 309   // The name PROB_MAX (PROB_MIN) is for probabilities which correspond to
 310   // very likely (unlikely) but with a concrete possibility of a rare
 311   // contrary case.  These constants would be used for pinning
 312   // measurements, and as measures for assertions that have high
 313   // confidence, but some evidence of occasional failure.
 314   //


 358   //     likelihood of null check failure if a null has NOT been seen before
 359   //
 360   // Magic manifest probabilities such as 0.83, 0.7, ... can be found in
 361   // gen_subtype_check() and catch_inline_exceptions().
 362 
 363   float _prob;                  // Probability of true path being taken.
 364   float _fcnt;                  // Frequency counter
 365   IfNode( Node *control, Node *b, float p, float fcnt )
 366     : MultiBranchNode(2), _prob(p), _fcnt(fcnt) {
 367     init_class_id(Class_If);
 368     init_req(0,control);
 369     init_req(1,b);
 370   }
 371   virtual int Opcode() const;
 372   virtual bool pinned() const { return true; }
 373   virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }
 374   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 375   virtual const Type *Value( PhaseTransform *phase ) const;
 376   virtual int required_outcnt() const { return 2; }
 377   virtual const RegMask &out_RegMask() const;
 378   void dominated_by(Node* prev_dom, PhaseIterGVN* igvn);
 379   int is_range_check(Node* &range, Node* &index, jint &offset);
 380   Node* fold_compares(PhaseIterGVN* phase);
 381   static Node* up_one_dom(Node* curr, bool linear_only = false);
 382 
 383   // Takes the type of val and filters it through the test represented
 384   // by if_proj and returns a more refined type if one is produced.
 385   // Returns NULL is it couldn't improve the type.
 386   static const TypeInt* filtered_int_type(PhaseGVN* phase, Node* val, Node* if_proj);
 387 
 388 #ifndef PRODUCT
 389   virtual void dump_spec(outputStream *st) const;
 390   virtual void related(GrowableArray <Node *> *in_rel, GrowableArray <Node *> *out_rel, bool compact) const;
 391 #endif














 392 };
 393 
 394 class IfProjNode : public CProjNode {
 395 public:
 396   IfProjNode(IfNode *ifnode, uint idx) : CProjNode(ifnode,idx) {}
 397   virtual Node *Identity(PhaseTransform *phase);
 398 
 399 protected:
 400   // Type of If input when this branch is always taken
 401   virtual bool always_taken(const TypeTuple* t) const = 0;
 402 
 403 #ifndef PRODUCT
 404 public:
 405   virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
 406 #endif
 407 };
 408 
 409 class IfTrueNode : public IfProjNode {
 410 public:
 411   IfTrueNode( IfNode *ifnode ) : IfProjNode(ifnode,1) {




 253 // This class defines a MultiBranchNode, a MultiNode which yields multiple
 254 // control values. These are distinguished from other types of MultiNodes
 255 // which yield multiple values, but control is always and only projection #0.
 256 class MultiBranchNode : public MultiNode {
 257 public:
 258   MultiBranchNode( uint required ) : MultiNode(required) {
 259     init_class_id(Class_MultiBranch);
 260   }
 261   // returns required number of users to be well formed.
 262   virtual int required_outcnt() const = 0;
 263 };
 264 
 265 //------------------------------IfNode-----------------------------------------
 266 // Output selected Control, based on a boolean test
 267 class IfNode : public MultiBranchNode {
 268   // Size is bigger to hold the probability field.  However, _prob does not
 269   // change the semantics so it does not appear in the hash & cmp functions.
 270   virtual uint size_of() const { return sizeof(*this); }
 271 
 272 private:

 273   ProjNode* range_check_trap_proj() {
 274     int flip_test = 0;
 275     Node* l = NULL;
 276     Node* r = NULL;
 277     return range_check_trap_proj(flip_test, l, r);
 278   }
 279 
 280   // Helper methods for fold_compares
 281   bool cmpi_folds(PhaseIterGVN* igvn);
 282   bool is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn);
 283   bool has_shared_region(ProjNode* proj, ProjNode*& success, ProjNode*& fail);
 284   bool has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNode*& fail, PhaseIterGVN* igvn);
 285   Node* merge_uncommon_traps(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn);
 286   static void improve_address_types(Node* l, Node* r, ProjNode* fail, PhaseIterGVN* igvn);
 287   bool is_cmp_with_loadrange(ProjNode* proj);
 288   bool is_null_check(ProjNode* proj, PhaseIterGVN* igvn);
 289   bool is_side_effect_free_test(ProjNode* proj, PhaseIterGVN* igvn);
 290   void reroute_side_effect_free_unc(ProjNode* proj, ProjNode* dom_proj, PhaseIterGVN* igvn);
 291   ProjNode* uncommon_trap_proj(CallStaticJavaNode*& call) const;
 292   bool fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn);
 293 
 294 protected:
 295   ProjNode* range_check_trap_proj(int& flip, Node*& l, Node*& r);
 296   Node* Ideal_common(PhaseGVN *phase, bool can_reshape);
 297   Node* dominated_by(Node* prev_dom, PhaseIterGVN* igvn);
 298   Node* search_identical(int dist);
 299 
 300 public:
 301 
 302   // Degrees of branch prediction probability by order of magnitude:
 303   // PROB_UNLIKELY_1e(N) is a 1 in 1eN chance.
 304   // PROB_LIKELY_1e(N) is a 1 - PROB_UNLIKELY_1e(N)
 305 #define PROB_UNLIKELY_MAG(N)    (1e- ## N ## f)
 306 #define PROB_LIKELY_MAG(N)      (1.0f-PROB_UNLIKELY_MAG(N))
 307 
 308   // Maximum and minimum branch prediction probabilties
 309   // 1 in 1,000,000 (magnitude 6)
 310   //
 311   // Although PROB_NEVER == PROB_MIN and PROB_ALWAYS == PROB_MAX
 312   // they are used to distinguish different situations:
 313   //
 314   // The name PROB_MAX (PROB_MIN) is for probabilities which correspond to
 315   // very likely (unlikely) but with a concrete possibility of a rare
 316   // contrary case.  These constants would be used for pinning
 317   // measurements, and as measures for assertions that have high
 318   // confidence, but some evidence of occasional failure.
 319   //


 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) {


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