1 /*
   2  * Copyright (c) 2012, 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  *
  23  */
  24 
  25 #ifndef SHARE_VM_C1_C1_RANGECHECKELIMINATION_HPP
  26 #define SHARE_VM_C1_C1_RANGECHECKELIMINATION_HPP
  27 
  28 #include "c1/c1_Instruction.hpp"
  29 
  30 // Base class for range check elimination
  31 class RangeCheckElimination : AllStatic {
  32 public:
  33   static void eliminate(IR *ir);
  34 };
  35 
  36 // Implementation
  37 class RangeCheckEliminator VALUE_OBJ_CLASS_SPEC {
  38 private:
  39   int _number_of_instructions;
  40   bool _optimistic; // Insert predicates and deoptimize when they fail
  41   IR *_ir;
  42 
  43   define_array(BlockBeginArray, BlockBegin*)
  44   define_stack(BlockBeginList, BlockBeginArray)
  45   define_stack(IntegerStack, intArray)
  46   define_array(IntegerMap, IntegerStack*)
  47 
  48   class Verification : public BlockClosure {
  49   // RangeCheckEliminator::Verification should never get instatiated on the heap.
  50   private:
  51     void* operator new(size_t size) throw();
  52     void* operator new[](size_t size) throw();
  53     void operator delete(void* p) { ShouldNotReachHere(); }
  54     void operator delete[](void* p) { ShouldNotReachHere(); }
  55 
  56     IR *_ir;
  57     boolArray _used;
  58     BlockBeginList _current;
  59     BlockBeginList _successors;
  60 
  61   public:
  62     Verification(IR *ir);
  63     virtual void block_do(BlockBegin *block);
  64     bool can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use = NULL);
  65     bool dominates(BlockBegin *dominator, BlockBegin *block);
  66   };
  67 
  68 public:
  69   // Bounds for an instruction in the form x + c which c integer
  70   // constant and x another instruction
  71   class Bound : public CompilationResourceObj {
  72   private:
  73     int _upper;
  74     Value _upper_instr;
  75     int _lower;
  76     Value _lower_instr;
  77 
  78   public:
  79     Bound();
  80     Bound(Value v);
  81     Bound(Instruction::Condition cond, Value v, int constant = 0);
  82     Bound(int lower, Value lower_instr, int upper, Value upper_instr);
  83     ~Bound();
  84 
  85 #ifdef ASSERT
  86     void add_assertion(Instruction *instruction, Instruction *position, int i, Value instr, Instruction::Condition cond);
  87 #endif
  88     int upper();
  89     Value upper_instr();
  90     int lower();
  91     Value lower_instr();
  92     void print();
  93     bool check_no_overflow(int const_value);
  94     void or_op(Bound *b);
  95     void and_op(Bound *b);
  96     bool has_upper();
  97     bool has_lower();
  98     void set_upper(int upper, Value upper_instr);
  99     void set_lower(int lower, Value lower_instr);
 100     bool is_smaller(Bound *b);
 101     void remove_upper();
 102     void remove_lower();
 103     void add_constant(int value);
 104     Bound *copy();
 105 
 106   private:
 107     void init();
 108   };
 109 
 110 
 111   class Visitor : public InstructionVisitor {
 112   private:
 113     Bound *_bound;
 114     RangeCheckEliminator *_rce;
 115 
 116   public:
 117     void set_range_check_eliminator(RangeCheckEliminator *rce) { _rce = rce; }
 118     Bound *bound() const { return _bound; }
 119     void clear_bound() { _bound = NULL; }
 120 
 121   protected:
 122     // visitor functions
 123     void do_Constant       (Constant*        x);
 124     void do_IfOp           (IfOp*            x);
 125     void do_LogicOp        (LogicOp*         x);
 126     void do_ArithmeticOp   (ArithmeticOp*    x);
 127     void do_Phi            (Phi*             x);
 128 
 129     void do_StoreField     (StoreField*      x) { /* nothing to do */ };
 130     void do_StoreIndexed   (StoreIndexed*    x) { /* nothing to do */ };
 131     void do_MonitorEnter   (MonitorEnter*    x) { /* nothing to do */ };
 132     void do_MonitorExit    (MonitorExit*     x) { /* nothing to do */ };
 133     void do_Invoke         (Invoke*          x) { /* nothing to do */ };
 134     void do_UnsafePutRaw   (UnsafePutRaw*    x) { /* nothing to do */ };
 135     void do_UnsafePutObject(UnsafePutObject* x) { /* nothing to do */ };
 136     void do_Intrinsic      (Intrinsic*       x) { /* nothing to do */ };
 137     void do_Local          (Local*           x) { /* nothing to do */ };
 138     void do_LoadField      (LoadField*       x) { /* nothing to do */ };
 139     void do_ArrayLength    (ArrayLength*     x) { /* nothing to do */ };
 140     void do_LoadIndexed    (LoadIndexed*     x) { /* nothing to do */ };
 141     void do_NegateOp       (NegateOp*        x) { /* nothing to do */ };
 142     void do_ShiftOp        (ShiftOp*         x) { /* nothing to do */ };
 143     void do_CompareOp      (CompareOp*       x) { /* nothing to do */ };
 144     void do_Convert        (Convert*         x) { /* nothing to do */ };
 145     void do_NullCheck      (NullCheck*       x) { /* nothing to do */ };
 146     void do_TypeCast       (TypeCast*        x) { /* nothing to do */ };
 147     void do_NewInstance    (NewInstance*     x) { /* nothing to do */ };
 148     void do_NewTypeArray   (NewTypeArray*    x) { /* nothing to do */ };
 149     void do_NewObjectArray (NewObjectArray*  x) { /* nothing to do */ };
 150     void do_NewMultiArray  (NewMultiArray*   x) { /* nothing to do */ };
 151     void do_CheckCast      (CheckCast*       x) { /* nothing to do */ };
 152     void do_InstanceOf     (InstanceOf*      x) { /* nothing to do */ };
 153     void do_BlockBegin     (BlockBegin*      x) { /* nothing to do */ };
 154     void do_Goto           (Goto*            x) { /* nothing to do */ };
 155     void do_If             (If*              x) { /* nothing to do */ };
 156     void do_IfInstanceOf   (IfInstanceOf*    x) { /* nothing to do */ };
 157     void do_TableSwitch    (TableSwitch*     x) { /* nothing to do */ };
 158     void do_LookupSwitch   (LookupSwitch*    x) { /* nothing to do */ };
 159     void do_Return         (Return*          x) { /* nothing to do */ };
 160     void do_Throw          (Throw*           x) { /* nothing to do */ };
 161     void do_Base           (Base*            x) { /* nothing to do */ };
 162     void do_OsrEntry       (OsrEntry*        x) { /* nothing to do */ };
 163     void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ };
 164     void do_RoundFP        (RoundFP*         x) { /* nothing to do */ };
 165     void do_UnsafeGetRaw   (UnsafeGetRaw*    x) { /* nothing to do */ };
 166     void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ };
 167     void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { /* nothing to do */ };
 168     void do_ProfileCall    (ProfileCall*     x) { /* nothing to do */ };
 169     void do_ProfileReturnType (ProfileReturnType*  x) { /* nothing to do */ };
 170     void do_ProfileInvoke  (ProfileInvoke*   x) { /* nothing to do */ };
 171     void do_RuntimeCall    (RuntimeCall*     x) { /* nothing to do */ };
 172     void do_MemBar         (MemBar*          x) { /* nothing to do */ };
 173     void do_RangeCheckPredicate(RangeCheckPredicate* x) { /* nothing to do */ };
 174 #ifdef ASSERT
 175     void do_Assert         (Assert*          x) { /* nothing to do */ };
 176 #endif
 177   };
 178 
 179 #ifdef ASSERT
 180   void add_assertions(Bound *bound, Instruction *instruction, Instruction *position);
 181 #endif
 182 
 183   define_array(BoundArray, Bound *)
 184   define_stack(BoundStack, BoundArray)
 185   define_array(BoundMap, BoundStack *)
 186   define_array(AccessIndexedArray, AccessIndexed *)
 187   define_stack(AccessIndexedList, AccessIndexedArray)
 188   define_array(InstructionArray, Instruction *)
 189   define_stack(InstructionList, InstructionArray)
 190 
 191   class AccessIndexedInfo : public CompilationResourceObj  {
 192   public:
 193     AccessIndexedList *_list;
 194     int _min;
 195     int _max;
 196   };
 197 
 198   define_array(AccessIndexedInfoArray, AccessIndexedInfo *)
 199   BoundMap _bounds; // Mapping from Instruction's id to current bound
 200   AccessIndexedInfoArray _access_indexed_info; // Mapping from Instruction's id to AccessIndexedInfo for in block motion
 201   Visitor _visitor;
 202 
 203 public:
 204   RangeCheckEliminator(IR *ir);
 205 
 206   IR *ir() const { return _ir; }
 207 
 208   // Pass over the dominator tree to identify blocks where there's an oppportunity for optimization
 209   bool set_process_block_flags(BlockBegin *block);
 210   // The core of the optimization work: pass over the dominator tree
 211   // to propagate bound information, insert predicate out of loops,
 212   // eliminate bound checks when possible and perform in block motion
 213   void calc_bounds(BlockBegin *block, BlockBegin *loop_header);
 214   // reorder bound checks within a block in order to eliminate some of them
 215   void in_block_motion(BlockBegin *block, AccessIndexedList &accessIndexed, InstructionList &arrays);
 216 
 217   // update/access current bound
 218   void update_bound(IntegerStack &pushed, Value v, Instruction::Condition cond, Value value, int constant);
 219   void update_bound(IntegerStack &pushed, Value v, Bound *bound);
 220   Bound *get_bound(Value v);
 221 
 222   bool loop_invariant(BlockBegin *loop_header, Instruction *instruction);                                    // check for loop invariance
 223   void add_access_indexed_info(InstructionList &indices, int i, Value instruction, AccessIndexed *ai); // record indexed access for in block motion
 224   void remove_range_check(AccessIndexed *ai);                                                                // Mark this instructions as not needing a range check
 225   void add_if_condition(IntegerStack &pushed, Value x, Value y, Instruction::Condition condition);           // Update bound for an If
 226   bool in_array_bound(Bound *bound, Value array);                                                            // Check whether bound is known to fall within array
 227 
 228   // helper functions to work with predicates
 229   Instruction* insert_after(Instruction* insert_position, Instruction* instr, int bci);
 230   Instruction* predicate(Instruction* left, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci=-1);
 231   Instruction* predicate_cmp_with_const(Instruction* instr, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci=1);
 232   Instruction* predicate_add(Instruction* left, int left_const, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci=-1);
 233   Instruction* predicate_add_cmp_with_const(Instruction* left, int left_const, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci=-1);
 234 
 235   void insert_deoptimization(ValueStack *state, Instruction *insert_position, Instruction *array_instr,      // Add predicate
 236                              Instruction *length_instruction, Instruction *lower_instr, int lower,
 237                              Instruction *upper_instr, int upper, AccessIndexed *ai);
 238   bool is_ok_for_deoptimization(Instruction *insert_position, Instruction *array_instr,                      // Can we safely add a predicate?
 239                                 Instruction *length_instr, Instruction *lower_instr,
 240                                 int lower, Instruction *upper_instr, int upper);
 241   void process_if(IntegerStack &pushed, BlockBegin *block, If *cond);                                        // process If Instruction
 242   void process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai);                // process indexed access
 243 
 244   void dump_condition_stack(BlockBegin *cur_block);
 245   static void print_statistics();
 246 };
 247 
 248 #endif // SHARE_VM_C1_C1_RANGECHECKELIMINATION_HPP