1/*
2 * Copyright (c) 1999, 2010, 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#ifndef SHARE_VM_SHARK_SHARKVALUE_HPP
27#define SHARE_VM_SHARK_SHARKVALUE_HPP
28
29#include "ci/ciType.hpp"
30#include "memory/allocation.hpp"
31#include "shark/llvmHeaders.hpp"
32#include "shark/llvmValue.hpp"
33#include "shark/sharkType.hpp"
34
35// Items on the stack and in local variables are tracked using
36// SharkValue objects.
37//
38// All SharkValues are one of two core types, SharkNormalValue
39// and SharkAddressValue, but no code outside this file should
40// ever refer to those directly.  The split is because of the
41// way JSRs are handled: the typeflow pass expands them into
42// multiple copies, so the return addresses pushed by jsr and
43// popped by ret only exist at compile time.  Having separate
44// classes for these allows us to check that our jsr handling
45// is correct, via assertions.
46//
47// There is one more type, SharkPHIValue, which is a subclass
48// of SharkNormalValue with a couple of extra methods.  Use of
49// SharkPHIValue outside of this file is acceptable, so long
50// as it is obtained via SharkValue::as_phi().
51
52class SharkBuilder;
53class SharkPHIValue;
54
55class SharkValue : public ResourceObj {
56 protected:
57  SharkValue() {}
58
59  // Cloning
60 public:
61  virtual SharkValue* clone() const = 0;
62
63  // Casting
64 public:
65  virtual bool           is_phi() const;
66  virtual SharkPHIValue* as_phi();
67
68  // Comparison
69 public:
70  virtual bool equal_to(SharkValue* other) const = 0;
71
72  // Type access
73 public:
74  virtual BasicType basic_type() const = 0;
75  virtual ciType*   type()       const;
76
77  virtual bool is_jint()    const;
78  virtual bool is_jlong()   const;
79  virtual bool is_jfloat()  const;
80  virtual bool is_jdouble() const;
81  virtual bool is_jobject() const;
82  virtual bool is_jarray()  const;
83  virtual bool is_address() const;
84
85  virtual int size() const = 0;
86
87  bool is_one_word() const {
88    return size() == 1;
89  }
90  bool is_two_word() const {
91    return size() == 2;
92  }
93
94  // Typed conversion from SharkValues
95 public:
96  virtual llvm::Value* jint_value()    const;
97  virtual llvm::Value* jlong_value()   const;
98  virtual llvm::Value* jfloat_value()  const;
99  virtual llvm::Value* jdouble_value() const;
100  virtual llvm::Value* jobject_value() const;
101  virtual llvm::Value* jarray_value()  const;
102  virtual int          address_value() const;
103
104  // Typed conversion to SharkValues
105 public:
106  static SharkValue* create_jint(llvm::Value* value, bool zero_checked) {
107    assert(value->getType() == SharkType::jint_type(), "should be");
108    return create_generic(ciType::make(T_INT), value, zero_checked);
109  }
110  static SharkValue* create_jlong(llvm::Value* value, bool zero_checked) {
111    assert(value->getType() == SharkType::jlong_type(), "should be");
112    return create_generic(ciType::make(T_LONG), value, zero_checked);
113  }
114  static SharkValue* create_jfloat(llvm::Value* value) {
115    assert(value->getType() == SharkType::jfloat_type(), "should be");
116    return create_generic(ciType::make(T_FLOAT), value, false);
117  }
118  static SharkValue* create_jdouble(llvm::Value* value) {
119    assert(value->getType() == SharkType::jdouble_type(), "should be");
120    return create_generic(ciType::make(T_DOUBLE), value, false);
121  }
122  static SharkValue* create_jobject(llvm::Value* value, bool zero_checked) {
123    assert(value->getType() == SharkType::oop_type(), "should be");
124    return create_generic(ciType::make(T_OBJECT), value, zero_checked);
125  }
126
127  // Typed conversion from constants of various types
128 public:
129  static SharkValue* jint_constant(jint value) {
130    return create_jint(LLVMValue::jint_constant(value), value != 0);
131  }
132  static SharkValue* jlong_constant(jlong value) {
133    return create_jlong(LLVMValue::jlong_constant(value), value != 0);
134  }
135  static SharkValue* jfloat_constant(jfloat value) {
136    return create_jfloat(LLVMValue::jfloat_constant(value));
137  }
138  static SharkValue* jdouble_constant(jdouble value) {
139    return create_jdouble(LLVMValue::jdouble_constant(value));
140  }
141  static SharkValue* null() {
142    return create_jobject(LLVMValue::null(), false);
143  }
144  static inline SharkValue* address_constant(int bci);
145
146  // Type-losing conversions -- use with care!
147 public:
148  virtual llvm::Value* generic_value() const = 0;
149  virtual llvm::Value* intptr_value(SharkBuilder* builder) const;
150
151  static inline SharkValue* create_generic(ciType*      type,
152                                           llvm::Value* value,
153                                           bool         zero_checked);
154  static inline SharkValue* create_phi(ciType*              type,
155                                       llvm::PHINode*       phi,
156                                       const SharkPHIValue* parent = NULL);
157
158  // Phi-style stuff
159 public:
160  virtual void addIncoming(SharkValue* value, llvm::BasicBlock* block);
161  virtual SharkValue* merge(SharkBuilder*     builder,
162                            SharkValue*       other,
163                            llvm::BasicBlock* other_block,
164                            llvm::BasicBlock* this_block,
165                            const char*       name) = 0;
166
167  // Repeated null and divide-by-zero check removal
168 public:
169  virtual bool zero_checked() const;
170  virtual void set_zero_checked(bool zero_checked);
171};
172
173class SharkNormalValue : public SharkValue {
174  friend class SharkValue;
175
176 protected:
177  SharkNormalValue(ciType* type, llvm::Value* value, bool zero_checked)
178    : _type(type), _llvm_value(value), _zero_checked(zero_checked) {}
179
180 private:
181  ciType*      _type;
182  llvm::Value* _llvm_value;
183  bool         _zero_checked;
184
185 private:
186  llvm::Value* llvm_value() const {
187    return _llvm_value;
188  }
189
190  // Cloning
191 public:
192  SharkValue* clone() const;
193
194  // Comparison
195 public:
196  bool equal_to(SharkValue* other) const;
197
198  // Type access
199 public:
200  ciType*   type()       const;
201  BasicType basic_type() const;
202  int       size()       const;
203
204 public:
205  bool is_jint()    const;
206  bool is_jlong()   const;
207  bool is_jfloat()  const;
208  bool is_jdouble() const;
209  bool is_jobject() const;
210  bool is_jarray()  const;
211
212  // Typed conversions to LLVM values
213 public:
214  llvm::Value* jint_value()    const;
215  llvm::Value* jlong_value()   const;
216  llvm::Value* jfloat_value()  const;
217  llvm::Value* jdouble_value() const;
218  llvm::Value* jobject_value() const;
219  llvm::Value* jarray_value()  const;
220
221  // Type-losing conversions, use with care
222 public:
223  llvm::Value* generic_value() const;
224  llvm::Value* intptr_value(SharkBuilder* builder) const;
225
226  // Phi-style stuff
227 public:
228  SharkValue* merge(SharkBuilder*     builder,
229                    SharkValue*       other,
230                    llvm::BasicBlock* other_block,
231                    llvm::BasicBlock* this_block,
232                    const char*       name);
233
234  // Repeated null and divide-by-zero check removal
235 public:
236  bool zero_checked() const;
237  void set_zero_checked(bool zero_checked);
238};
239
240class SharkPHIValue : public SharkNormalValue {
241  friend class SharkValue;
242
243 protected:
244  SharkPHIValue(ciType* type, llvm::PHINode* phi, const SharkPHIValue *parent)
245    : SharkNormalValue(type, phi, parent && parent->zero_checked()),
246      _parent(parent),
247      _all_incomers_zero_checked(true) {}
248
249 private:
250  const SharkPHIValue* _parent;
251  bool                 _all_incomers_zero_checked;
252
253 private:
254  const SharkPHIValue* parent() const {
255    return _parent;
256  }
257  bool is_clone() const {
258    return parent() != NULL;
259  }
260
261 public:
262  bool all_incomers_zero_checked() const {
263    if (is_clone())
264      return parent()->all_incomers_zero_checked();
265
266    return _all_incomers_zero_checked;
267  }
268
269  // Cloning
270 public:
271  SharkValue* clone() const;
272
273  // Casting
274 public:
275  bool           is_phi() const;
276  SharkPHIValue* as_phi();
277
278  // Phi-style stuff
279 public:
280  void addIncoming(SharkValue *value, llvm::BasicBlock* block);
281};
282
283class SharkAddressValue : public SharkValue {
284  friend class SharkValue;
285
286 protected:
287  SharkAddressValue(int bci)
288    : _bci(bci) {}
289
290 private:
291  int _bci;
292
293  // Cloning
294 public:
295  SharkValue* clone() const;
296
297  // Comparison
298 public:
299  bool equal_to(SharkValue* other) const;
300
301  // Type access
302 public:
303  BasicType basic_type() const;
304  int       size()       const;
305  bool      is_address() const;
306
307  // Typed conversion from SharkValues
308 public:
309  int address_value() const;
310
311  // Type-losing conversion -- use with care!
312 public:
313  llvm::Value* generic_value() const;
314
315  // Phi-style stuff
316 public:
317  void addIncoming(SharkValue *value, llvm::BasicBlock* block);
318  SharkValue* merge(SharkBuilder*     builder,
319                    SharkValue*       other,
320                    llvm::BasicBlock* other_block,
321                    llvm::BasicBlock* this_block,
322                    const char*       name);
323};
324
325// SharkValue methods that can't be declared above
326
327inline SharkValue* SharkValue::create_generic(ciType*      type,
328                                              llvm::Value* value,
329                                              bool         zero_checked) {
330  return new SharkNormalValue(type, value, zero_checked);
331}
332
333inline SharkValue* SharkValue::create_phi(ciType*              type,
334                                          llvm::PHINode*       phi,
335                                          const SharkPHIValue* parent) {
336  return new SharkPHIValue(type, phi, parent);
337}
338
339inline SharkValue* SharkValue::address_constant(int bci) {
340  return new SharkAddressValue(bci);
341}
342
343#endif // SHARE_VM_SHARK_SHARKVALUE_HPP
344