1 /*
   2  * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright 2008, 2009 Red Hat, Inc.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 // Items on the stack and in local variables are tracked using
  27 // SharkValue objects.
  28 //
  29 // All SharkValues are one of two core types, SharkNormalValue
  30 // and SharkAddressValue, but no code outside this file should
  31 // ever refer to those directly.  The split is because of the
  32 // way JSRs are handled: the typeflow pass expands them into
  33 // multiple copies, so the return addresses pushed by jsr and
  34 // popped by ret only exist at compile time.  Having separate
  35 // classes for these allows us to check that our jsr handling
  36 // is correct, via assertions.
  37 //
  38 // There is one more type, SharkPHIValue, which is a subclass
  39 // of SharkNormalValue with a couple of extra methods.  Use of
  40 // SharkPHIValue outside of this file is acceptable, so long
  41 // as it is obtained via SharkValue::as_phi().
  42 
  43 class SharkBuilder;
  44 class SharkPHIValue;
  45 
  46 class SharkValue : public ResourceObj {
  47  protected:
  48   SharkValue() {}
  49 
  50   // Cloning
  51  public:
  52   virtual SharkValue* clone() const = 0;
  53 
  54   // Casting
  55  public:
  56   virtual bool           is_phi() const;
  57   virtual SharkPHIValue* as_phi();
  58 
  59   // Comparison
  60  public:
  61   virtual bool equal_to(SharkValue* other) const = 0;
  62 
  63   // Type access
  64  public:
  65   virtual BasicType basic_type() const = 0;
  66   virtual ciType*   type()       const;
  67 
  68   virtual bool is_jint()    const;
  69   virtual bool is_jlong()   const;
  70   virtual bool is_jfloat()  const;
  71   virtual bool is_jdouble() const;
  72   virtual bool is_jobject() const;
  73   virtual bool is_jarray()  const;
  74   virtual bool is_address() const;
  75 
  76   virtual int size() const = 0;
  77 
  78   bool is_one_word() const {
  79     return size() == 1;
  80   }
  81   bool is_two_word() const {
  82     return size() == 2;
  83   }
  84 
  85   // Typed conversion from SharkValues
  86  public:
  87   virtual llvm::Value* jint_value()    const;
  88   virtual llvm::Value* jlong_value()   const;
  89   virtual llvm::Value* jfloat_value()  const;
  90   virtual llvm::Value* jdouble_value() const;
  91   virtual llvm::Value* jobject_value() const;
  92   virtual llvm::Value* jarray_value()  const;
  93   virtual int          address_value() const;
  94 
  95   // Typed conversion to SharkValues
  96  public:
  97   static SharkValue* create_jint(llvm::Value* value, bool zero_checked) {
  98     assert(value->getType() == SharkType::jint_type(), "should be");
  99     return create_generic(ciType::make(T_INT), value, zero_checked);
 100   }
 101   static SharkValue* create_jlong(llvm::Value* value, bool zero_checked) {
 102     assert(value->getType() == SharkType::jlong_type(), "should be");
 103     return create_generic(ciType::make(T_LONG), value, zero_checked);
 104   }
 105   static SharkValue* create_jfloat(llvm::Value* value) {
 106     assert(value->getType() == SharkType::jfloat_type(), "should be");
 107     return create_generic(ciType::make(T_FLOAT), value, false);
 108   }
 109   static SharkValue* create_jdouble(llvm::Value* value) {
 110     assert(value->getType() == SharkType::jdouble_type(), "should be");
 111     return create_generic(ciType::make(T_DOUBLE), value, false);
 112   }
 113   static SharkValue* create_jobject(llvm::Value* value, bool zero_checked) {
 114     assert(value->getType() == SharkType::oop_type(), "should be");
 115     return create_generic(ciType::make(T_OBJECT), value, zero_checked);
 116   }
 117 
 118   // Typed conversion from constants of various types
 119  public:
 120   static SharkValue* jint_constant(jint value) {
 121     return create_jint(LLVMValue::jint_constant(value), value != 0);
 122   }
 123   static SharkValue* jlong_constant(jlong value) {
 124     return create_jlong(LLVMValue::jlong_constant(value), value != 0);
 125   }
 126   static SharkValue* jfloat_constant(jfloat value) {
 127     return create_jfloat(LLVMValue::jfloat_constant(value));
 128   }
 129   static SharkValue* jdouble_constant(jdouble value) {
 130     return create_jdouble(LLVMValue::jdouble_constant(value));
 131   }
 132   static SharkValue* null() {
 133     return create_jobject(LLVMValue::null(), false);
 134   }
 135   static inline SharkValue* address_constant(int bci);
 136 
 137   // Type-losing conversions -- use with care!
 138  public:
 139   virtual llvm::Value* generic_value() const = 0;
 140   virtual llvm::Value* intptr_value(SharkBuilder* builder) const;
 141 
 142   static inline SharkValue* create_generic(ciType*      type,
 143                                            llvm::Value* value,
 144                                            bool         zero_checked);
 145   static inline SharkValue* create_phi(ciType*              type,
 146                                        llvm::PHINode*       phi,
 147                                        const SharkPHIValue* parent = NULL);
 148 
 149   // Phi-style stuff
 150  public:
 151   virtual void addIncoming(SharkValue* value, llvm::BasicBlock* block);
 152   virtual SharkValue* merge(SharkBuilder*     builder,
 153                             SharkValue*       other,
 154                             llvm::BasicBlock* other_block,
 155                             llvm::BasicBlock* this_block,
 156                             const char*       name) = 0;
 157 
 158   // Repeated null and divide-by-zero check removal
 159  public:
 160   virtual bool zero_checked() const;
 161   virtual void set_zero_checked(bool zero_checked);
 162 };
 163 
 164 class SharkNormalValue : public SharkValue {
 165   friend class SharkValue;
 166 
 167  protected:
 168   SharkNormalValue(ciType* type, llvm::Value* value, bool zero_checked)
 169     : _type(type), _llvm_value(value), _zero_checked(zero_checked) {}
 170 
 171  private:
 172   ciType*      _type;
 173   llvm::Value* _llvm_value;
 174   bool         _zero_checked;
 175 
 176  private:
 177   llvm::Value* llvm_value() const {
 178     return _llvm_value;
 179   }
 180 
 181   // Cloning
 182  public:
 183   SharkValue* clone() const;
 184 
 185   // Comparison
 186  public:
 187   bool equal_to(SharkValue* other) const;
 188 
 189   // Type access
 190  public:
 191   ciType*   type()       const;
 192   BasicType basic_type() const;
 193   int       size()       const;
 194 
 195  public:
 196   bool is_jint()    const;
 197   bool is_jlong()   const;
 198   bool is_jfloat()  const;
 199   bool is_jdouble() const;
 200   bool is_jobject() const;
 201   bool is_jarray()  const;
 202 
 203   // Typed conversions to LLVM values
 204  public:
 205   llvm::Value* jint_value()    const;
 206   llvm::Value* jlong_value()   const;
 207   llvm::Value* jfloat_value()  const;
 208   llvm::Value* jdouble_value() const;
 209   llvm::Value* jobject_value() const;
 210   llvm::Value* jarray_value()  const;
 211 
 212   // Type-losing conversions, use with care
 213  public:
 214   llvm::Value* generic_value() const;
 215   llvm::Value* intptr_value(SharkBuilder* builder) const;
 216 
 217   // Phi-style stuff
 218  public:
 219   SharkValue* merge(SharkBuilder*     builder,
 220                     SharkValue*       other,
 221                     llvm::BasicBlock* other_block,
 222                     llvm::BasicBlock* this_block,
 223                     const char*       name);
 224 
 225   // Repeated null and divide-by-zero check removal
 226  public:
 227   bool zero_checked() const;
 228   void set_zero_checked(bool zero_checked);
 229 };
 230 
 231 class SharkPHIValue : public SharkNormalValue {
 232   friend class SharkValue;
 233 
 234  protected:
 235   SharkPHIValue(ciType* type, llvm::PHINode* phi, const SharkPHIValue *parent)
 236     : SharkNormalValue(type, phi, parent && parent->zero_checked()),
 237       _parent(parent),
 238       _all_incomers_zero_checked(true) {}
 239 
 240  private:
 241   const SharkPHIValue* _parent;
 242   bool                 _all_incomers_zero_checked;
 243 
 244  private:
 245   const SharkPHIValue* parent() const {
 246     return _parent;
 247   }
 248   bool is_clone() const {
 249     return parent() != NULL;
 250   }
 251 
 252  public:
 253   bool all_incomers_zero_checked() const {
 254     if (is_clone())
 255       return parent()->all_incomers_zero_checked();
 256 
 257     return _all_incomers_zero_checked;
 258   }
 259 
 260   // Cloning
 261  public:
 262   SharkValue* clone() const;
 263 
 264   // Casting
 265  public:
 266   bool           is_phi() const;
 267   SharkPHIValue* as_phi();
 268 
 269   // Phi-style stuff
 270  public:
 271   void addIncoming(SharkValue *value, llvm::BasicBlock* block);
 272 };
 273 
 274 class SharkAddressValue : public SharkValue {
 275   friend class SharkValue;
 276 
 277  protected:
 278   SharkAddressValue(int bci)
 279     : _bci(bci) {}
 280 
 281  private:
 282   int _bci;
 283 
 284   // Cloning
 285  public:
 286   SharkValue* clone() const;
 287 
 288   // Comparison
 289  public:
 290   bool equal_to(SharkValue* other) const;
 291 
 292   // Type access
 293  public:
 294   BasicType basic_type() const;
 295   int       size()       const;
 296   bool      is_address() const;
 297 
 298   // Typed conversion from SharkValues
 299  public:
 300   int address_value() const;
 301 
 302   // Type-losing conversion -- use with care!
 303  public:
 304   llvm::Value* generic_value() const;
 305 
 306   // Phi-style stuff
 307  public:
 308   void addIncoming(SharkValue *value, llvm::BasicBlock* block);
 309   SharkValue* merge(SharkBuilder*     builder,
 310                     SharkValue*       other,
 311                     llvm::BasicBlock* other_block,
 312                     llvm::BasicBlock* this_block,
 313                     const char*       name);
 314 };
 315 
 316 // SharkValue methods that can't be declared above
 317 
 318 inline SharkValue* SharkValue::create_generic(ciType*      type,
 319                                               llvm::Value* value,
 320                                               bool         zero_checked) {
 321   return new SharkNormalValue(type, value, zero_checked);
 322 }
 323 
 324 inline SharkValue* SharkValue::create_phi(ciType*              type,
 325                                           llvm::PHINode*       phi,
 326                                           const SharkPHIValue* parent) {
 327   return new SharkPHIValue(type, phi, parent);
 328 }
 329 
 330 inline SharkValue* SharkValue::address_constant(int bci) {
 331   return new SharkAddressValue(bci);
 332 }