src/share/vm/c1/c1_IR.hpp

Print this page
rev 4136 : 7153771: array bound check elimination for c1
Summary: when possible optimize out array bound checks, inserting predicates when needed.
Reviewed-by:


 237     DebugToken* locvals = recorder->create_scope_values(locals());
 238     DebugToken* expvals = recorder->create_scope_values(expressions());
 239     DebugToken* monvals = recorder->create_monitor_values(monitors());
 240     // reexecute allowed only for the topmost frame
 241     bool reexecute = topmost ? should_reexecute() : false;
 242     bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
 243     recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
 244   }
 245 };
 246 
 247 
 248 class CodeEmitInfo: public CompilationResourceObj {
 249   friend class LinearScan;
 250  private:
 251   IRScopeDebugInfo* _scope_debug_info;
 252   IRScope*          _scope;
 253   XHandlers*        _exception_handlers;
 254   OopMap*           _oop_map;
 255   ValueStack*       _stack;                      // used by deoptimization (contains also monitors
 256   bool              _is_method_handle_invoke;    // true if the associated call site is a MethodHandle call site.

 257 
 258   FrameMap*     frame_map() const                { return scope()->compilation()->frame_map(); }
 259   Compilation*  compilation() const              { return scope()->compilation(); }
 260 
 261  public:
 262 
 263   // use scope from ValueStack
 264   CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers);
 265 
 266   // make a copy
 267   CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack = NULL);
 268 
 269   // accessors
 270   OopMap* oop_map()                              { return _oop_map; }
 271   ciMethod* method() const                       { return _scope->method(); }
 272   IRScope* scope() const                         { return _scope; }
 273   XHandlers* exception_handlers() const          { return _exception_handlers; }
 274   ValueStack* stack() const                      { return _stack; }

 275 
 276   void add_register_oop(LIR_Opr opr);
 277   void record_debug_info(DebugInformationRecorder* recorder, int pc_offset);
 278 
 279   bool     is_method_handle_invoke() const { return _is_method_handle_invoke;     }
 280   void set_is_method_handle_invoke(bool x) {        _is_method_handle_invoke = x; }
 281 };
 282 
 283 
 284 class IR: public CompilationResourceObj {
 285  private:
 286   Compilation*     _compilation;                 // the current compilation
 287   IRScope*         _top_scope;                   // the root of the scope hierarchy
 288   WordSize         _locals_size;                 // the space required for all locals
 289   int              _num_loops;                   // Total number of loops
 290   BlockList*       _code;                        // the blocks in code generation order w/ use counts
 291 
 292  public:
 293   // creation
 294   IR(Compilation* compilation, ciMethod* method, int osr_bci);
 295 
 296   // accessors
 297   bool             is_valid() const              { return top_scope()->is_valid(); }
 298   Compilation*     compilation() const           { return _compilation; }
 299   IRScope*         top_scope() const             { return _top_scope; }
 300   int              number_of_locks() const       { return top_scope()->number_of_locks(); }
 301   ciMethod*        method() const                { return top_scope()->method(); }
 302   BlockBegin*      start() const                 { return top_scope()->start(); }
 303   BlockBegin*      std_entry() const             { return start()->end()->as_Base()->std_entry(); }
 304   BlockBegin*      osr_entry() const             { return start()->end()->as_Base()->osr_entry(); }
 305   WordSize         locals_size() const           { return _locals_size; }
 306   int              locals_size_in_words() const  { return in_words(_locals_size); }
 307   BlockList*       code() const                  { return _code; }
 308   int              num_loops() const             { return _num_loops; }
 309   int              max_stack() const             { return top_scope()->max_stack(); } // expensive
 310 
 311   // ir manipulation
 312   void optimize();

 313   void compute_predecessors();
 314   void split_critical_edges();
 315   void compute_code();
 316   void compute_use_counts();
 317 
 318   // The linear-scan order and the code emission order are equal, but
 319   // this may change in future
 320   BlockList* linear_scan_order() {  assert(_code != NULL, "not computed"); return _code; }
 321 
 322   // iteration
 323   void iterate_preorder   (BlockClosure* closure);
 324   void iterate_postorder  (BlockClosure* closure);
 325   void iterate_linear_scan_order(BlockClosure* closure);
 326 
 327   // debugging
 328   static void print(BlockBegin* start, bool cfg_only, bool live_only = false) PRODUCT_RETURN;
 329   void print(bool cfg_only, bool live_only = false)                           PRODUCT_RETURN;
 330   void verify()                                                               PRODUCT_RETURN;
 331 };
 332 




 237     DebugToken* locvals = recorder->create_scope_values(locals());
 238     DebugToken* expvals = recorder->create_scope_values(expressions());
 239     DebugToken* monvals = recorder->create_monitor_values(monitors());
 240     // reexecute allowed only for the topmost frame
 241     bool reexecute = topmost ? should_reexecute() : false;
 242     bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
 243     recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
 244   }
 245 };
 246 
 247 
 248 class CodeEmitInfo: public CompilationResourceObj {
 249   friend class LinearScan;
 250  private:
 251   IRScopeDebugInfo* _scope_debug_info;
 252   IRScope*          _scope;
 253   XHandlers*        _exception_handlers;
 254   OopMap*           _oop_map;
 255   ValueStack*       _stack;                      // used by deoptimization (contains also monitors
 256   bool              _is_method_handle_invoke;    // true if the associated call site is a MethodHandle call site.
 257   bool              _deoptimize_on_exception;
 258 
 259   FrameMap*     frame_map() const                { return scope()->compilation()->frame_map(); }
 260   Compilation*  compilation() const              { return scope()->compilation(); }
 261 
 262  public:
 263 
 264   // use scope from ValueStack
 265   CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, bool deoptimize_on_exception = false);
 266 
 267   // make a copy
 268   CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack = NULL);
 269 
 270   // accessors
 271   OopMap* oop_map()                              { return _oop_map; }
 272   ciMethod* method() const                       { return _scope->method(); }
 273   IRScope* scope() const                         { return _scope; }
 274   XHandlers* exception_handlers() const          { return _exception_handlers; }
 275   ValueStack* stack() const                      { return _stack; }
 276   bool deoptimize_on_exception() const           { return _deoptimize_on_exception; }
 277 
 278   void add_register_oop(LIR_Opr opr);
 279   void record_debug_info(DebugInformationRecorder* recorder, int pc_offset);
 280 
 281   bool     is_method_handle_invoke() const { return _is_method_handle_invoke;     }
 282   void set_is_method_handle_invoke(bool x) {        _is_method_handle_invoke = x; }
 283 };
 284 
 285 
 286 class IR: public CompilationResourceObj {
 287  private:
 288   Compilation*     _compilation;                 // the current compilation
 289   IRScope*         _top_scope;                   // the root of the scope hierarchy
 290   WordSize         _locals_size;                 // the space required for all locals
 291   int              _num_loops;                   // Total number of loops
 292   BlockList*       _code;                        // the blocks in code generation order w/ use counts
 293 
 294  public:
 295   // creation
 296   IR(Compilation* compilation, ciMethod* method, int osr_bci);
 297 
 298   // accessors
 299   bool             is_valid() const              { return top_scope()->is_valid(); }
 300   Compilation*     compilation() const           { return _compilation; }
 301   IRScope*         top_scope() const             { return _top_scope; }
 302   int              number_of_locks() const       { return top_scope()->number_of_locks(); }
 303   ciMethod*        method() const                { return top_scope()->method(); }
 304   BlockBegin*      start() const                 { return top_scope()->start(); }
 305   BlockBegin*      std_entry() const             { return start()->end()->as_Base()->std_entry(); }
 306   BlockBegin*      osr_entry() const             { return start()->end()->as_Base()->osr_entry(); }
 307   WordSize         locals_size() const           { return _locals_size; }
 308   int              locals_size_in_words() const  { return in_words(_locals_size); }
 309   BlockList*       code() const                  { return _code; }
 310   int              num_loops() const             { return _num_loops; }
 311   int              max_stack() const             { return top_scope()->max_stack(); } // expensive
 312 
 313   // ir manipulation
 314   void optimize_blocks();
 315   void eliminate_null_checks();
 316   void compute_predecessors();
 317   void split_critical_edges();
 318   void compute_code();
 319   void compute_use_counts();
 320 
 321   // The linear-scan order and the code emission order are equal, but
 322   // this may change in future
 323   BlockList* linear_scan_order() {  assert(_code != NULL, "not computed"); return _code; }
 324 
 325   // iteration
 326   void iterate_preorder   (BlockClosure* closure);
 327   void iterate_postorder  (BlockClosure* closure);
 328   void iterate_linear_scan_order(BlockClosure* closure);
 329 
 330   // debugging
 331   static void print(BlockBegin* start, bool cfg_only, bool live_only = false) PRODUCT_RETURN;
 332   void print(bool cfg_only, bool live_only = false)                           PRODUCT_RETURN;
 333   void verify()                                                               PRODUCT_RETURN;
 334 };
 335