1 | /* |
2 | * Copyright (c) 1997, 2019, 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_OPTO_MEMNODE_HPP |
26 | #define SHARE_OPTO_MEMNODE_HPP |
27 | |
28 | #include "opto/multnode.hpp" |
29 | #include "opto/node.hpp" |
30 | #include "opto/opcodes.hpp" |
31 | #include "opto/type.hpp" |
32 | |
33 | // Portions of code courtesy of Clifford Click |
34 | |
35 | class MultiNode; |
36 | class PhaseCCP; |
37 | class PhaseTransform; |
38 | |
39 | //------------------------------MemNode---------------------------------------- |
40 | // Load or Store, possibly throwing a NULL pointer exception |
41 | class MemNode : public Node { |
42 | private: |
43 | bool _unaligned_access; // Unaligned access from unsafe |
44 | bool _mismatched_access; // Mismatched access from unsafe: byte read in integer array for instance |
45 | bool _unsafe_access; // Access of unsafe origin. |
46 | protected: |
47 | #ifdef ASSERT |
48 | const TypePtr* _adr_type; // What kind of memory is being addressed? |
49 | #endif |
50 | virtual uint size_of() const; |
51 | public: |
52 | enum { Control, // When is it safe to do this load? |
53 | Memory, // Chunk of memory is being loaded from |
54 | Address, // Actually address, derived from base |
55 | ValueIn, // Value to store |
56 | OopStore // Preceeding oop store, only in StoreCM |
57 | }; |
58 | typedef enum { unordered = 0, |
59 | acquire, // Load has to acquire or be succeeded by MemBarAcquire. |
60 | release, // Store has to release or be preceded by MemBarRelease. |
61 | seqcst, // LoadStore has to have both acquire and release semantics. |
62 | unset // The memory ordering is not set (used for testing) |
63 | } MemOrd; |
64 | protected: |
65 | MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at ) |
66 | : Node(c0,c1,c2 ), _unaligned_access(false), _mismatched_access(false), _unsafe_access(false) { |
67 | init_class_id(Class_Mem); |
68 | debug_only(_adr_type=at; adr_type();) |
69 | } |
70 | MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3 ) |
71 | : Node(c0,c1,c2,c3), _unaligned_access(false), _mismatched_access(false), _unsafe_access(false) { |
72 | init_class_id(Class_Mem); |
73 | debug_only(_adr_type=at; adr_type();) |
74 | } |
75 | MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3, Node *c4) |
76 | : Node(c0,c1,c2,c3,c4), _unaligned_access(false), _mismatched_access(false), _unsafe_access(false) { |
77 | init_class_id(Class_Mem); |
78 | debug_only(_adr_type=at; adr_type();) |
79 | } |
80 | |
81 | virtual Node* find_previous_arraycopy(PhaseTransform* phase, Node* ld_alloc, Node*& mem, bool can_see_stored_value) const { return NULL; } |
82 | static bool check_if_adr_maybe_raw(Node* adr); |
83 | |
84 | public: |
85 | // Helpers for the optimizer. Documented in memnode.cpp. |
86 | static bool detect_ptr_independence(Node* p1, AllocateNode* a1, |
87 | Node* p2, AllocateNode* a2, |
88 | PhaseTransform* phase); |
89 | static bool adr_phi_is_loop_invariant(Node* adr_phi, Node* cast); |
90 | |
91 | static Node *optimize_simple_memory_chain(Node *mchain, const TypeOopPtr *t_oop, Node *load, PhaseGVN *phase); |
92 | static Node *optimize_memory_chain(Node *mchain, const TypePtr *t_adr, Node *load, PhaseGVN *phase); |
93 | // This one should probably be a phase-specific function: |
94 | static bool all_controls_dominate(Node* dom, Node* sub); |
95 | |
96 | virtual const class TypePtr *adr_type() const; // returns bottom_type of address |
97 | |
98 | // Shared code for Ideal methods: |
99 | Node *Ideal_common(PhaseGVN *phase, bool can_reshape); // Return -1 for short-circuit NULL. |
100 | |
101 | // Helper function for adr_type() implementations. |
102 | static const TypePtr* calculate_adr_type(const Type* t, const TypePtr* cross_check = NULL); |
103 | |
104 | // Raw access function, to allow copying of adr_type efficiently in |
105 | // product builds and retain the debug info for debug builds. |
106 | const TypePtr *raw_adr_type() const { |
107 | #ifdef ASSERT |
108 | return _adr_type; |
109 | #else |
110 | return 0; |
111 | #endif |
112 | } |
113 | |
114 | // Map a load or store opcode to its corresponding store opcode. |
115 | // (Return -1 if unknown.) |
116 | virtual int store_Opcode() const { return -1; } |
117 | |
118 | // What is the type of the value in memory? (T_VOID mean "unspecified".) |
119 | virtual BasicType memory_type() const = 0; |
120 | virtual int memory_size() const { |
121 | #ifdef ASSERT |
122 | return type2aelembytes(memory_type(), true); |
123 | #else |
124 | return type2aelembytes(memory_type()); |
125 | #endif |
126 | } |
127 | |
128 | // Search through memory states which precede this node (load or store). |
129 | // Look for an exact match for the address, with no intervening |
130 | // aliased stores. |
131 | Node* find_previous_store(PhaseTransform* phase); |
132 | |
133 | // Can this node (load or store) accurately see a stored value in |
134 | // the given memory state? (The state may or may not be in(Memory).) |
135 | Node* can_see_stored_value(Node* st, PhaseTransform* phase) const; |
136 | |
137 | void set_unaligned_access() { _unaligned_access = true; } |
138 | bool is_unaligned_access() const { return _unaligned_access; } |
139 | void set_mismatched_access() { _mismatched_access = true; } |
140 | bool is_mismatched_access() const { return _mismatched_access; } |
141 | void set_unsafe_access() { _unsafe_access = true; } |
142 | bool is_unsafe_access() const { return _unsafe_access; } |
143 | |
144 | #ifndef PRODUCT |
145 | static void dump_adr_type(const Node* mem, const TypePtr* adr_type, outputStream *st); |
146 | virtual void dump_spec(outputStream *st) const; |
147 | #endif |
148 | }; |
149 | |
150 | //------------------------------LoadNode--------------------------------------- |
151 | // Load value; requires Memory and Address |
152 | class LoadNode : public MemNode { |
153 | public: |
154 | // Some loads (from unsafe) should be pinned: they don't depend only |
155 | // on the dominating test. The field _control_dependency below records |
156 | // whether that node depends only on the dominating test. |
157 | // Methods used to build LoadNodes pass an argument of type enum |
158 | // ControlDependency instead of a boolean because those methods |
159 | // typically have multiple boolean parameters with default values: |
160 | // passing the wrong boolean to one of these parameters by mistake |
161 | // goes easily unnoticed. Using an enum, the compiler can check that |
162 | // the type of a value and the type of the parameter match. |
163 | enum ControlDependency { |
164 | Pinned, |
165 | DependsOnlyOnTest |
166 | }; |
167 | |
168 | private: |
169 | // LoadNode::hash() doesn't take the _control_dependency field |
170 | // into account: If the graph already has a non-pinned LoadNode and |
171 | // we add a pinned LoadNode with the same inputs, it's safe for GVN |
172 | // to replace the pinned LoadNode with the non-pinned LoadNode, |
173 | // otherwise it wouldn't be safe to have a non pinned LoadNode with |
174 | // those inputs in the first place. If the graph already has a |
175 | // pinned LoadNode and we add a non pinned LoadNode with the same |
176 | // inputs, it's safe (but suboptimal) for GVN to replace the |
177 | // non-pinned LoadNode by the pinned LoadNode. |
178 | ControlDependency _control_dependency; |
179 | |
180 | // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish |
181 | // loads that can be reordered, and such requiring acquire semantics to |
182 | // adhere to the Java specification. The required behaviour is stored in |
183 | // this field. |
184 | const MemOrd _mo; |
185 | |
186 | uint _barrier; // Bit field with barrier information |
187 | |
188 | protected: |
189 | virtual bool cmp(const Node &n) const; |
190 | virtual uint size_of() const; // Size is bigger |
191 | // Should LoadNode::Ideal() attempt to remove control edges? |
192 | virtual bool can_remove_control() const; |
193 | const Type* const _type; // What kind of value is loaded? |
194 | |
195 | virtual Node* find_previous_arraycopy(PhaseTransform* phase, Node* ld_alloc, Node*& mem, bool can_see_stored_value) const; |
196 | public: |
197 | |
198 | LoadNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt, MemOrd mo, ControlDependency control_dependency) |
199 | : MemNode(c,mem,adr,at), _control_dependency(control_dependency), _mo(mo), _barrier(0), _type(rt) { |
200 | init_class_id(Class_Load); |
201 | } |
202 | inline bool is_unordered() const { return !is_acquire(); } |
203 | inline bool is_acquire() const { |
204 | assert(_mo == unordered || _mo == acquire, "unexpected" ); |
205 | return _mo == acquire; |
206 | } |
207 | inline bool is_unsigned() const { |
208 | int lop = Opcode(); |
209 | return (lop == Op_LoadUB) || (lop == Op_LoadUS); |
210 | } |
211 | |
212 | // Polymorphic factory method: |
213 | static Node* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr, |
214 | const TypePtr* at, const Type *rt, BasicType bt, |
215 | MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest, |
216 | bool unaligned = false, bool mismatched = false, bool unsafe = false); |
217 | |
218 | virtual uint hash() const; // Check the type |
219 | |
220 | // Handle algebraic identities here. If we have an identity, return the Node |
221 | // we are equivalent to. We look for Load of a Store. |
222 | virtual Node* Identity(PhaseGVN* phase); |
223 | |
224 | // If the load is from Field memory and the pointer is non-null, it might be possible to |
225 | // zero out the control input. |
226 | // If the offset is constant and the base is an object allocation, |
227 | // try to hook me up to the exact initializing store. |
228 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
229 | |
230 | // Split instance field load through Phi. |
231 | Node* split_through_phi(PhaseGVN *phase); |
232 | |
233 | // Recover original value from boxed values |
234 | Node *eliminate_autobox(PhaseGVN *phase); |
235 | |
236 | // Compute a new Type for this node. Basically we just do the pre-check, |
237 | // then call the virtual add() to set the type. |
238 | virtual const Type* Value(PhaseGVN* phase) const; |
239 | |
240 | // Common methods for LoadKlass and LoadNKlass nodes. |
241 | const Type* klass_value_common(PhaseGVN* phase) const; |
242 | Node* klass_identity_common(PhaseGVN* phase); |
243 | |
244 | virtual uint ideal_reg() const; |
245 | virtual const Type *bottom_type() const; |
246 | // Following method is copied from TypeNode: |
247 | void set_type(const Type* t) { |
248 | assert(t != NULL, "sanity" ); |
249 | debug_only(uint check_hash = (VerifyHashTableKeys && _hash_lock) ? hash() : NO_HASH); |
250 | *(const Type**)&_type = t; // cast away const-ness |
251 | // If this node is in the hash table, make sure it doesn't need a rehash. |
252 | assert(check_hash == NO_HASH || check_hash == hash(), "type change must preserve hash code" ); |
253 | } |
254 | const Type* type() const { assert(_type != NULL, "sanity" ); return _type; }; |
255 | |
256 | // Do not match memory edge |
257 | virtual uint match_edge(uint idx) const; |
258 | |
259 | // Map a load opcode to its corresponding store opcode. |
260 | virtual int store_Opcode() const = 0; |
261 | |
262 | // Check if the load's memory input is a Phi node with the same control. |
263 | bool is_instance_field_load_with_local_phi(Node* ctrl); |
264 | |
265 | Node* convert_to_unsigned_load(PhaseGVN& gvn); |
266 | Node* convert_to_signed_load(PhaseGVN& gvn); |
267 | |
268 | void copy_barrier_info(const Node* src) { _barrier = src->as_Load()->_barrier; } |
269 | uint barrier_data() { return _barrier; } |
270 | void set_barrier_data(uint barrier_data) { _barrier |= barrier_data; } |
271 | |
272 | #ifndef PRODUCT |
273 | virtual void dump_spec(outputStream *st) const; |
274 | #endif |
275 | #ifdef ASSERT |
276 | // Helper function to allow a raw load without control edge for some cases |
277 | static bool is_immutable_value(Node* adr); |
278 | #endif |
279 | protected: |
280 | const Type* load_array_final_field(const TypeKlassPtr *tkls, |
281 | ciKlass* klass) const; |
282 | |
283 | Node* can_see_arraycopy_value(Node* st, PhaseGVN* phase) const; |
284 | |
285 | // depends_only_on_test is almost always true, and needs to be almost always |
286 | // true to enable key hoisting & commoning optimizations. However, for the |
287 | // special case of RawPtr loads from TLS top & end, and other loads performed by |
288 | // GC barriers, the control edge carries the dependence preventing hoisting past |
289 | // a Safepoint instead of the memory edge. (An unfortunate consequence of having |
290 | // Safepoints not set Raw Memory; itself an unfortunate consequence of having Nodes |
291 | // which produce results (new raw memory state) inside of loops preventing all |
292 | // manner of other optimizations). Basically, it's ugly but so is the alternative. |
293 | // See comment in macro.cpp, around line 125 expand_allocate_common(). |
294 | virtual bool depends_only_on_test() const { |
295 | return adr_type() != TypeRawPtr::BOTTOM && _control_dependency == DependsOnlyOnTest; |
296 | } |
297 | }; |
298 | |
299 | //------------------------------LoadBNode-------------------------------------- |
300 | // Load a byte (8bits signed) from memory |
301 | class LoadBNode : public LoadNode { |
302 | public: |
303 | LoadBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest) |
304 | : LoadNode(c, mem, adr, at, ti, mo, control_dependency) {} |
305 | virtual int Opcode() const; |
306 | virtual uint ideal_reg() const { return Op_RegI; } |
307 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
308 | virtual const Type* Value(PhaseGVN* phase) const; |
309 | virtual int store_Opcode() const { return Op_StoreB; } |
310 | virtual BasicType memory_type() const { return T_BYTE; } |
311 | }; |
312 | |
313 | //------------------------------LoadUBNode------------------------------------- |
314 | // Load a unsigned byte (8bits unsigned) from memory |
315 | class LoadUBNode : public LoadNode { |
316 | public: |
317 | LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest) |
318 | : LoadNode(c, mem, adr, at, ti, mo, control_dependency) {} |
319 | virtual int Opcode() const; |
320 | virtual uint ideal_reg() const { return Op_RegI; } |
321 | virtual Node* Ideal(PhaseGVN *phase, bool can_reshape); |
322 | virtual const Type* Value(PhaseGVN* phase) const; |
323 | virtual int store_Opcode() const { return Op_StoreB; } |
324 | virtual BasicType memory_type() const { return T_BYTE; } |
325 | }; |
326 | |
327 | //------------------------------LoadUSNode------------------------------------- |
328 | // Load an unsigned short/char (16bits unsigned) from memory |
329 | class LoadUSNode : public LoadNode { |
330 | public: |
331 | LoadUSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest) |
332 | : LoadNode(c, mem, adr, at, ti, mo, control_dependency) {} |
333 | virtual int Opcode() const; |
334 | virtual uint ideal_reg() const { return Op_RegI; } |
335 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
336 | virtual const Type* Value(PhaseGVN* phase) const; |
337 | virtual int store_Opcode() const { return Op_StoreC; } |
338 | virtual BasicType memory_type() const { return T_CHAR; } |
339 | }; |
340 | |
341 | //------------------------------LoadSNode-------------------------------------- |
342 | // Load a short (16bits signed) from memory |
343 | class LoadSNode : public LoadNode { |
344 | public: |
345 | LoadSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest) |
346 | : LoadNode(c, mem, adr, at, ti, mo, control_dependency) {} |
347 | virtual int Opcode() const; |
348 | virtual uint ideal_reg() const { return Op_RegI; } |
349 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
350 | virtual const Type* Value(PhaseGVN* phase) const; |
351 | virtual int store_Opcode() const { return Op_StoreC; } |
352 | virtual BasicType memory_type() const { return T_SHORT; } |
353 | }; |
354 | |
355 | //------------------------------LoadINode-------------------------------------- |
356 | // Load an integer from memory |
357 | class LoadINode : public LoadNode { |
358 | public: |
359 | LoadINode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest) |
360 | : LoadNode(c, mem, adr, at, ti, mo, control_dependency) {} |
361 | virtual int Opcode() const; |
362 | virtual uint ideal_reg() const { return Op_RegI; } |
363 | virtual int store_Opcode() const { return Op_StoreI; } |
364 | virtual BasicType memory_type() const { return T_INT; } |
365 | }; |
366 | |
367 | //------------------------------LoadRangeNode---------------------------------- |
368 | // Load an array length from the array |
369 | class LoadRangeNode : public LoadINode { |
370 | public: |
371 | LoadRangeNode(Node *c, Node *mem, Node *adr, const TypeInt *ti = TypeInt::POS) |
372 | : LoadINode(c, mem, adr, TypeAryPtr::RANGE, ti, MemNode::unordered) {} |
373 | virtual int Opcode() const; |
374 | virtual const Type* Value(PhaseGVN* phase) const; |
375 | virtual Node* Identity(PhaseGVN* phase); |
376 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
377 | }; |
378 | |
379 | //------------------------------LoadLNode-------------------------------------- |
380 | // Load a long from memory |
381 | class LoadLNode : public LoadNode { |
382 | virtual uint hash() const { return LoadNode::hash() + _require_atomic_access; } |
383 | virtual bool cmp( const Node &n ) const { |
384 | return _require_atomic_access == ((LoadLNode&)n)._require_atomic_access |
385 | && LoadNode::cmp(n); |
386 | } |
387 | virtual uint size_of() const { return sizeof(*this); } |
388 | const bool _require_atomic_access; // is piecewise load forbidden? |
389 | |
390 | public: |
391 | LoadLNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeLong *tl, |
392 | MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest, bool require_atomic_access = false) |
393 | : LoadNode(c, mem, adr, at, tl, mo, control_dependency), _require_atomic_access(require_atomic_access) {} |
394 | virtual int Opcode() const; |
395 | virtual uint ideal_reg() const { return Op_RegL; } |
396 | virtual int store_Opcode() const { return Op_StoreL; } |
397 | virtual BasicType memory_type() const { return T_LONG; } |
398 | bool require_atomic_access() const { return _require_atomic_access; } |
399 | static LoadLNode* make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, |
400 | const Type* rt, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest, |
401 | bool unaligned = false, bool mismatched = false, bool unsafe = false); |
402 | #ifndef PRODUCT |
403 | virtual void dump_spec(outputStream *st) const { |
404 | LoadNode::dump_spec(st); |
405 | if (_require_atomic_access) st->print(" Atomic!" ); |
406 | } |
407 | #endif |
408 | }; |
409 | |
410 | //------------------------------LoadL_unalignedNode---------------------------- |
411 | // Load a long from unaligned memory |
412 | class LoadL_unalignedNode : public LoadLNode { |
413 | public: |
414 | LoadL_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest) |
415 | : LoadLNode(c, mem, adr, at, TypeLong::LONG, mo, control_dependency) {} |
416 | virtual int Opcode() const; |
417 | }; |
418 | |
419 | //------------------------------LoadFNode-------------------------------------- |
420 | // Load a float (64 bits) from memory |
421 | class LoadFNode : public LoadNode { |
422 | public: |
423 | LoadFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest) |
424 | : LoadNode(c, mem, adr, at, t, mo, control_dependency) {} |
425 | virtual int Opcode() const; |
426 | virtual uint ideal_reg() const { return Op_RegF; } |
427 | virtual int store_Opcode() const { return Op_StoreF; } |
428 | virtual BasicType memory_type() const { return T_FLOAT; } |
429 | }; |
430 | |
431 | //------------------------------LoadDNode-------------------------------------- |
432 | // Load a double (64 bits) from memory |
433 | class LoadDNode : public LoadNode { |
434 | virtual uint hash() const { return LoadNode::hash() + _require_atomic_access; } |
435 | virtual bool cmp( const Node &n ) const { |
436 | return _require_atomic_access == ((LoadDNode&)n)._require_atomic_access |
437 | && LoadNode::cmp(n); |
438 | } |
439 | virtual uint size_of() const { return sizeof(*this); } |
440 | const bool _require_atomic_access; // is piecewise load forbidden? |
441 | |
442 | public: |
443 | LoadDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, |
444 | MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest, bool require_atomic_access = false) |
445 | : LoadNode(c, mem, adr, at, t, mo, control_dependency), _require_atomic_access(require_atomic_access) {} |
446 | virtual int Opcode() const; |
447 | virtual uint ideal_reg() const { return Op_RegD; } |
448 | virtual int store_Opcode() const { return Op_StoreD; } |
449 | virtual BasicType memory_type() const { return T_DOUBLE; } |
450 | bool require_atomic_access() const { return _require_atomic_access; } |
451 | static LoadDNode* make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, |
452 | const Type* rt, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest, |
453 | bool unaligned = false, bool mismatched = false, bool unsafe = false); |
454 | #ifndef PRODUCT |
455 | virtual void dump_spec(outputStream *st) const { |
456 | LoadNode::dump_spec(st); |
457 | if (_require_atomic_access) st->print(" Atomic!" ); |
458 | } |
459 | #endif |
460 | }; |
461 | |
462 | //------------------------------LoadD_unalignedNode---------------------------- |
463 | // Load a double from unaligned memory |
464 | class LoadD_unalignedNode : public LoadDNode { |
465 | public: |
466 | LoadD_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest) |
467 | : LoadDNode(c, mem, adr, at, Type::DOUBLE, mo, control_dependency) {} |
468 | virtual int Opcode() const; |
469 | }; |
470 | |
471 | //------------------------------LoadPNode-------------------------------------- |
472 | // Load a pointer from memory (either object or array) |
473 | class LoadPNode : public LoadNode { |
474 | public: |
475 | LoadPNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest) |
476 | : LoadNode(c, mem, adr, at, t, mo, control_dependency) {} |
477 | virtual int Opcode() const; |
478 | virtual uint ideal_reg() const { return Op_RegP; } |
479 | virtual int store_Opcode() const { return Op_StoreP; } |
480 | virtual BasicType memory_type() const { return T_ADDRESS; } |
481 | }; |
482 | |
483 | |
484 | //------------------------------LoadNNode-------------------------------------- |
485 | // Load a narrow oop from memory (either object or array) |
486 | class LoadNNode : public LoadNode { |
487 | public: |
488 | LoadNNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest) |
489 | : LoadNode(c, mem, adr, at, t, mo, control_dependency) {} |
490 | virtual int Opcode() const; |
491 | virtual uint ideal_reg() const { return Op_RegN; } |
492 | virtual int store_Opcode() const { return Op_StoreN; } |
493 | virtual BasicType memory_type() const { return T_NARROWOOP; } |
494 | }; |
495 | |
496 | //------------------------------LoadKlassNode---------------------------------- |
497 | // Load a Klass from an object |
498 | class LoadKlassNode : public LoadPNode { |
499 | protected: |
500 | // In most cases, LoadKlassNode does not have the control input set. If the control |
501 | // input is set, it must not be removed (by LoadNode::Ideal()). |
502 | virtual bool can_remove_control() const; |
503 | public: |
504 | LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo) |
505 | : LoadPNode(c, mem, adr, at, tk, mo) {} |
506 | virtual int Opcode() const; |
507 | virtual const Type* Value(PhaseGVN* phase) const; |
508 | virtual Node* Identity(PhaseGVN* phase); |
509 | virtual bool depends_only_on_test() const { return true; } |
510 | |
511 | // Polymorphic factory method: |
512 | static Node* make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at, |
513 | const TypeKlassPtr* tk = TypeKlassPtr::OBJECT); |
514 | }; |
515 | |
516 | //------------------------------LoadNKlassNode--------------------------------- |
517 | // Load a narrow Klass from an object. |
518 | class LoadNKlassNode : public LoadNNode { |
519 | public: |
520 | LoadNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk, MemOrd mo) |
521 | : LoadNNode(c, mem, adr, at, tk, mo) {} |
522 | virtual int Opcode() const; |
523 | virtual uint ideal_reg() const { return Op_RegN; } |
524 | virtual int store_Opcode() const { return Op_StoreNKlass; } |
525 | virtual BasicType memory_type() const { return T_NARROWKLASS; } |
526 | |
527 | virtual const Type* Value(PhaseGVN* phase) const; |
528 | virtual Node* Identity(PhaseGVN* phase); |
529 | virtual bool depends_only_on_test() const { return true; } |
530 | }; |
531 | |
532 | |
533 | //------------------------------StoreNode-------------------------------------- |
534 | // Store value; requires Store, Address and Value |
535 | class StoreNode : public MemNode { |
536 | private: |
537 | // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish |
538 | // stores that can be reordered, and such requiring release semantics to |
539 | // adhere to the Java specification. The required behaviour is stored in |
540 | // this field. |
541 | const MemOrd _mo; |
542 | // Needed for proper cloning. |
543 | virtual uint size_of() const { return sizeof(*this); } |
544 | protected: |
545 | virtual bool cmp( const Node &n ) const; |
546 | virtual bool depends_only_on_test() const { return false; } |
547 | |
548 | Node *Ideal_masked_input (PhaseGVN *phase, uint mask); |
549 | Node *Ideal_sign_extended_input(PhaseGVN *phase, int num_bits); |
550 | |
551 | public: |
552 | // We must ensure that stores of object references will be visible |
553 | // only after the object's initialization. So the callers of this |
554 | // procedure must indicate that the store requires `release' |
555 | // semantics, if the stored value is an object reference that might |
556 | // point to a new object and may become externally visible. |
557 | StoreNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
558 | : MemNode(c, mem, adr, at, val), _mo(mo) { |
559 | init_class_id(Class_Store); |
560 | } |
561 | StoreNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, MemOrd mo) |
562 | : MemNode(c, mem, adr, at, val, oop_store), _mo(mo) { |
563 | init_class_id(Class_Store); |
564 | } |
565 | |
566 | inline bool is_unordered() const { return !is_release(); } |
567 | inline bool is_release() const { |
568 | assert((_mo == unordered || _mo == release), "unexpected" ); |
569 | return _mo == release; |
570 | } |
571 | |
572 | // Conservatively release stores of object references in order to |
573 | // ensure visibility of object initialization. |
574 | static inline MemOrd release_if_reference(const BasicType t) { |
575 | #ifdef AARCH64 |
576 | // AArch64 doesn't need a release store here because object |
577 | // initialization contains the necessary barriers. |
578 | return unordered; |
579 | #else |
580 | const MemOrd mo = (t == T_ARRAY || |
581 | t == T_ADDRESS || // Might be the address of an object reference (`boxing'). |
582 | t == T_OBJECT) ? release : unordered; |
583 | return mo; |
584 | #endif |
585 | } |
586 | |
587 | // Polymorphic factory method |
588 | // |
589 | // We must ensure that stores of object references will be visible |
590 | // only after the object's initialization. So the callers of this |
591 | // procedure must indicate that the store requires `release' |
592 | // semantics, if the stored value is an object reference that might |
593 | // point to a new object and may become externally visible. |
594 | static StoreNode* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr, |
595 | const TypePtr* at, Node *val, BasicType bt, MemOrd mo); |
596 | |
597 | virtual uint hash() const; // Check the type |
598 | |
599 | // If the store is to Field memory and the pointer is non-null, we can |
600 | // zero out the control input. |
601 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
602 | |
603 | // Compute a new Type for this node. Basically we just do the pre-check, |
604 | // then call the virtual add() to set the type. |
605 | virtual const Type* Value(PhaseGVN* phase) const; |
606 | |
607 | // Check for identity function on memory (Load then Store at same address) |
608 | virtual Node* Identity(PhaseGVN* phase); |
609 | |
610 | // Do not match memory edge |
611 | virtual uint match_edge(uint idx) const; |
612 | |
613 | virtual const Type *bottom_type() const; // returns Type::MEMORY |
614 | |
615 | // Map a store opcode to its corresponding own opcode, trivially. |
616 | virtual int store_Opcode() const { return Opcode(); } |
617 | |
618 | // have all possible loads of the value stored been optimized away? |
619 | bool value_never_loaded(PhaseTransform *phase) const; |
620 | |
621 | MemBarNode* trailing_membar() const; |
622 | }; |
623 | |
624 | //------------------------------StoreBNode------------------------------------- |
625 | // Store byte to memory |
626 | class StoreBNode : public StoreNode { |
627 | public: |
628 | StoreBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
629 | : StoreNode(c, mem, adr, at, val, mo) {} |
630 | virtual int Opcode() const; |
631 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
632 | virtual BasicType memory_type() const { return T_BYTE; } |
633 | }; |
634 | |
635 | //------------------------------StoreCNode------------------------------------- |
636 | // Store char/short to memory |
637 | class StoreCNode : public StoreNode { |
638 | public: |
639 | StoreCNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
640 | : StoreNode(c, mem, adr, at, val, mo) {} |
641 | virtual int Opcode() const; |
642 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
643 | virtual BasicType memory_type() const { return T_CHAR; } |
644 | }; |
645 | |
646 | //------------------------------StoreINode------------------------------------- |
647 | // Store int to memory |
648 | class StoreINode : public StoreNode { |
649 | public: |
650 | StoreINode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
651 | : StoreNode(c, mem, adr, at, val, mo) {} |
652 | virtual int Opcode() const; |
653 | virtual BasicType memory_type() const { return T_INT; } |
654 | }; |
655 | |
656 | //------------------------------StoreLNode------------------------------------- |
657 | // Store long to memory |
658 | class StoreLNode : public StoreNode { |
659 | virtual uint hash() const { return StoreNode::hash() + _require_atomic_access; } |
660 | virtual bool cmp( const Node &n ) const { |
661 | return _require_atomic_access == ((StoreLNode&)n)._require_atomic_access |
662 | && StoreNode::cmp(n); |
663 | } |
664 | virtual uint size_of() const { return sizeof(*this); } |
665 | const bool _require_atomic_access; // is piecewise store forbidden? |
666 | |
667 | public: |
668 | StoreLNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo, bool require_atomic_access = false) |
669 | : StoreNode(c, mem, adr, at, val, mo), _require_atomic_access(require_atomic_access) {} |
670 | virtual int Opcode() const; |
671 | virtual BasicType memory_type() const { return T_LONG; } |
672 | bool require_atomic_access() const { return _require_atomic_access; } |
673 | static StoreLNode* make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo); |
674 | #ifndef PRODUCT |
675 | virtual void dump_spec(outputStream *st) const { |
676 | StoreNode::dump_spec(st); |
677 | if (_require_atomic_access) st->print(" Atomic!" ); |
678 | } |
679 | #endif |
680 | }; |
681 | |
682 | //------------------------------StoreFNode------------------------------------- |
683 | // Store float to memory |
684 | class StoreFNode : public StoreNode { |
685 | public: |
686 | StoreFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
687 | : StoreNode(c, mem, adr, at, val, mo) {} |
688 | virtual int Opcode() const; |
689 | virtual BasicType memory_type() const { return T_FLOAT; } |
690 | }; |
691 | |
692 | //------------------------------StoreDNode------------------------------------- |
693 | // Store double to memory |
694 | class StoreDNode : public StoreNode { |
695 | virtual uint hash() const { return StoreNode::hash() + _require_atomic_access; } |
696 | virtual bool cmp( const Node &n ) const { |
697 | return _require_atomic_access == ((StoreDNode&)n)._require_atomic_access |
698 | && StoreNode::cmp(n); |
699 | } |
700 | virtual uint size_of() const { return sizeof(*this); } |
701 | const bool _require_atomic_access; // is piecewise store forbidden? |
702 | public: |
703 | StoreDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, |
704 | MemOrd mo, bool require_atomic_access = false) |
705 | : StoreNode(c, mem, adr, at, val, mo), _require_atomic_access(require_atomic_access) {} |
706 | virtual int Opcode() const; |
707 | virtual BasicType memory_type() const { return T_DOUBLE; } |
708 | bool require_atomic_access() const { return _require_atomic_access; } |
709 | static StoreDNode* make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo); |
710 | #ifndef PRODUCT |
711 | virtual void dump_spec(outputStream *st) const { |
712 | StoreNode::dump_spec(st); |
713 | if (_require_atomic_access) st->print(" Atomic!" ); |
714 | } |
715 | #endif |
716 | |
717 | }; |
718 | |
719 | //------------------------------StorePNode------------------------------------- |
720 | // Store pointer to memory |
721 | class StorePNode : public StoreNode { |
722 | public: |
723 | StorePNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
724 | : StoreNode(c, mem, adr, at, val, mo) {} |
725 | virtual int Opcode() const; |
726 | virtual BasicType memory_type() const { return T_ADDRESS; } |
727 | }; |
728 | |
729 | //------------------------------StoreNNode------------------------------------- |
730 | // Store narrow oop to memory |
731 | class StoreNNode : public StoreNode { |
732 | public: |
733 | StoreNNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
734 | : StoreNode(c, mem, adr, at, val, mo) {} |
735 | virtual int Opcode() const; |
736 | virtual BasicType memory_type() const { return T_NARROWOOP; } |
737 | }; |
738 | |
739 | //------------------------------StoreNKlassNode-------------------------------------- |
740 | // Store narrow klass to memory |
741 | class StoreNKlassNode : public StoreNNode { |
742 | public: |
743 | StoreNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
744 | : StoreNNode(c, mem, adr, at, val, mo) {} |
745 | virtual int Opcode() const; |
746 | virtual BasicType memory_type() const { return T_NARROWKLASS; } |
747 | }; |
748 | |
749 | //------------------------------StoreCMNode----------------------------------- |
750 | // Store card-mark byte to memory for CM |
751 | // The last StoreCM before a SafePoint must be preserved and occur after its "oop" store |
752 | // Preceeding equivalent StoreCMs may be eliminated. |
753 | class StoreCMNode : public StoreNode { |
754 | private: |
755 | virtual uint hash() const { return StoreNode::hash() + _oop_alias_idx; } |
756 | virtual bool cmp( const Node &n ) const { |
757 | return _oop_alias_idx == ((StoreCMNode&)n)._oop_alias_idx |
758 | && StoreNode::cmp(n); |
759 | } |
760 | virtual uint size_of() const { return sizeof(*this); } |
761 | int _oop_alias_idx; // The alias_idx of OopStore |
762 | |
763 | public: |
764 | StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, int oop_alias_idx ) : |
765 | StoreNode(c, mem, adr, at, val, oop_store, MemNode::release), |
766 | _oop_alias_idx(oop_alias_idx) { |
767 | assert(_oop_alias_idx >= Compile::AliasIdxRaw || |
768 | _oop_alias_idx == Compile::AliasIdxBot && Compile::current()->AliasLevel() == 0, |
769 | "bad oop alias idx" ); |
770 | } |
771 | virtual int Opcode() const; |
772 | virtual Node* Identity(PhaseGVN* phase); |
773 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
774 | virtual const Type* Value(PhaseGVN* phase) const; |
775 | virtual BasicType memory_type() const { return T_VOID; } // unspecific |
776 | int oop_alias_idx() const { return _oop_alias_idx; } |
777 | }; |
778 | |
779 | //------------------------------LoadPLockedNode--------------------------------- |
780 | // Load-locked a pointer from memory (either object or array). |
781 | // On Sparc & Intel this is implemented as a normal pointer load. |
782 | // On PowerPC and friends it's a real load-locked. |
783 | class LoadPLockedNode : public LoadPNode { |
784 | public: |
785 | LoadPLockedNode(Node *c, Node *mem, Node *adr, MemOrd mo) |
786 | : LoadPNode(c, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, mo) {} |
787 | virtual int Opcode() const; |
788 | virtual int store_Opcode() const { return Op_StorePConditional; } |
789 | virtual bool depends_only_on_test() const { return true; } |
790 | }; |
791 | |
792 | //------------------------------SCMemProjNode--------------------------------------- |
793 | // This class defines a projection of the memory state of a store conditional node. |
794 | // These nodes return a value, but also update memory. |
795 | class SCMemProjNode : public ProjNode { |
796 | public: |
797 | enum {SCMEMPROJCON = (uint)-2}; |
798 | SCMemProjNode( Node *src) : ProjNode( src, SCMEMPROJCON) { } |
799 | virtual int Opcode() const; |
800 | virtual bool is_CFG() const { return false; } |
801 | virtual const Type *bottom_type() const {return Type::MEMORY;} |
802 | virtual const TypePtr *adr_type() const { |
803 | Node* ctrl = in(0); |
804 | if (ctrl == NULL) return NULL; // node is dead |
805 | return ctrl->in(MemNode::Memory)->adr_type(); |
806 | } |
807 | virtual uint ideal_reg() const { return 0;} // memory projections don't have a register |
808 | virtual const Type* Value(PhaseGVN* phase) const; |
809 | #ifndef PRODUCT |
810 | virtual void dump_spec(outputStream *st) const {}; |
811 | #endif |
812 | }; |
813 | |
814 | //------------------------------LoadStoreNode--------------------------- |
815 | // Note: is_Mem() method returns 'true' for this class. |
816 | class LoadStoreNode : public Node { |
817 | private: |
818 | const Type* const _type; // What kind of value is loaded? |
819 | const TypePtr* _adr_type; // What kind of memory is being addressed? |
820 | bool _has_barrier; |
821 | virtual uint size_of() const; // Size is bigger |
822 | public: |
823 | LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* rt, uint required ); |
824 | virtual bool depends_only_on_test() const { return false; } |
825 | virtual uint match_edge(uint idx) const { return idx == MemNode::Address || idx == MemNode::ValueIn; } |
826 | |
827 | virtual const Type *bottom_type() const { return _type; } |
828 | virtual uint ideal_reg() const; |
829 | virtual const class TypePtr *adr_type() const { return _adr_type; } // returns bottom_type of address |
830 | |
831 | bool result_not_used() const; |
832 | MemBarNode* trailing_membar() const; |
833 | void set_has_barrier() { _has_barrier = true; }; |
834 | bool has_barrier() const { return _has_barrier; }; |
835 | }; |
836 | |
837 | class LoadStoreConditionalNode : public LoadStoreNode { |
838 | public: |
839 | enum { |
840 | ExpectedIn = MemNode::ValueIn+1 // One more input than MemNode |
841 | }; |
842 | LoadStoreConditionalNode(Node *c, Node *mem, Node *adr, Node *val, Node *ex); |
843 | }; |
844 | |
845 | //------------------------------StorePConditionalNode--------------------------- |
846 | // Conditionally store pointer to memory, if no change since prior |
847 | // load-locked. Sets flags for success or failure of the store. |
848 | class StorePConditionalNode : public LoadStoreConditionalNode { |
849 | public: |
850 | StorePConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreConditionalNode(c, mem, adr, val, ll) { } |
851 | virtual int Opcode() const; |
852 | // Produces flags |
853 | virtual uint ideal_reg() const { return Op_RegFlags; } |
854 | }; |
855 | |
856 | //------------------------------StoreIConditionalNode--------------------------- |
857 | // Conditionally store int to memory, if no change since prior |
858 | // load-locked. Sets flags for success or failure of the store. |
859 | class StoreIConditionalNode : public LoadStoreConditionalNode { |
860 | public: |
861 | StoreIConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ii ) : LoadStoreConditionalNode(c, mem, adr, val, ii) { } |
862 | virtual int Opcode() const; |
863 | // Produces flags |
864 | virtual uint ideal_reg() const { return Op_RegFlags; } |
865 | }; |
866 | |
867 | //------------------------------StoreLConditionalNode--------------------------- |
868 | // Conditionally store long to memory, if no change since prior |
869 | // load-locked. Sets flags for success or failure of the store. |
870 | class StoreLConditionalNode : public LoadStoreConditionalNode { |
871 | public: |
872 | StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreConditionalNode(c, mem, adr, val, ll) { } |
873 | virtual int Opcode() const; |
874 | // Produces flags |
875 | virtual uint ideal_reg() const { return Op_RegFlags; } |
876 | }; |
877 | |
878 | class CompareAndSwapNode : public LoadStoreConditionalNode { |
879 | private: |
880 | const MemNode::MemOrd _mem_ord; |
881 | public: |
882 | CompareAndSwapNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : LoadStoreConditionalNode(c, mem, adr, val, ex), _mem_ord(mem_ord) {} |
883 | MemNode::MemOrd order() const { |
884 | return _mem_ord; |
885 | } |
886 | }; |
887 | |
888 | class CompareAndExchangeNode : public LoadStoreNode { |
889 | private: |
890 | const MemNode::MemOrd _mem_ord; |
891 | public: |
892 | enum { |
893 | ExpectedIn = MemNode::ValueIn+1 // One more input than MemNode |
894 | }; |
895 | CompareAndExchangeNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord, const TypePtr* at, const Type* t) : |
896 | LoadStoreNode(c, mem, adr, val, at, t, 5), _mem_ord(mem_ord) { |
897 | init_req(ExpectedIn, ex ); |
898 | } |
899 | |
900 | MemNode::MemOrd order() const { |
901 | return _mem_ord; |
902 | } |
903 | }; |
904 | |
905 | //------------------------------CompareAndSwapBNode--------------------------- |
906 | class CompareAndSwapBNode : public CompareAndSwapNode { |
907 | public: |
908 | CompareAndSwapBNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
909 | virtual int Opcode() const; |
910 | }; |
911 | |
912 | //------------------------------CompareAndSwapSNode--------------------------- |
913 | class CompareAndSwapSNode : public CompareAndSwapNode { |
914 | public: |
915 | CompareAndSwapSNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
916 | virtual int Opcode() const; |
917 | }; |
918 | |
919 | //------------------------------CompareAndSwapINode--------------------------- |
920 | class CompareAndSwapINode : public CompareAndSwapNode { |
921 | public: |
922 | CompareAndSwapINode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
923 | virtual int Opcode() const; |
924 | }; |
925 | |
926 | //------------------------------CompareAndSwapLNode--------------------------- |
927 | class CompareAndSwapLNode : public CompareAndSwapNode { |
928 | public: |
929 | CompareAndSwapLNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
930 | virtual int Opcode() const; |
931 | }; |
932 | |
933 | //------------------------------CompareAndSwapPNode--------------------------- |
934 | class CompareAndSwapPNode : public CompareAndSwapNode { |
935 | public: |
936 | CompareAndSwapPNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
937 | virtual int Opcode() const; |
938 | }; |
939 | |
940 | //------------------------------CompareAndSwapNNode--------------------------- |
941 | class CompareAndSwapNNode : public CompareAndSwapNode { |
942 | public: |
943 | CompareAndSwapNNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
944 | virtual int Opcode() const; |
945 | }; |
946 | |
947 | //------------------------------WeakCompareAndSwapBNode--------------------------- |
948 | class WeakCompareAndSwapBNode : public CompareAndSwapNode { |
949 | public: |
950 | WeakCompareAndSwapBNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
951 | virtual int Opcode() const; |
952 | }; |
953 | |
954 | //------------------------------WeakCompareAndSwapSNode--------------------------- |
955 | class WeakCompareAndSwapSNode : public CompareAndSwapNode { |
956 | public: |
957 | WeakCompareAndSwapSNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
958 | virtual int Opcode() const; |
959 | }; |
960 | |
961 | //------------------------------WeakCompareAndSwapINode--------------------------- |
962 | class WeakCompareAndSwapINode : public CompareAndSwapNode { |
963 | public: |
964 | WeakCompareAndSwapINode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
965 | virtual int Opcode() const; |
966 | }; |
967 | |
968 | //------------------------------WeakCompareAndSwapLNode--------------------------- |
969 | class WeakCompareAndSwapLNode : public CompareAndSwapNode { |
970 | public: |
971 | WeakCompareAndSwapLNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
972 | virtual int Opcode() const; |
973 | }; |
974 | |
975 | //------------------------------WeakCompareAndSwapPNode--------------------------- |
976 | class WeakCompareAndSwapPNode : public CompareAndSwapNode { |
977 | public: |
978 | WeakCompareAndSwapPNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
979 | virtual int Opcode() const; |
980 | }; |
981 | |
982 | //------------------------------WeakCompareAndSwapNNode--------------------------- |
983 | class WeakCompareAndSwapNNode : public CompareAndSwapNode { |
984 | public: |
985 | WeakCompareAndSwapNNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapNode(c, mem, adr, val, ex, mem_ord) { } |
986 | virtual int Opcode() const; |
987 | }; |
988 | |
989 | //------------------------------CompareAndExchangeBNode--------------------------- |
990 | class CompareAndExchangeBNode : public CompareAndExchangeNode { |
991 | public: |
992 | CompareAndExchangeBNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, const TypePtr* at, MemNode::MemOrd mem_ord) : CompareAndExchangeNode(c, mem, adr, val, ex, mem_ord, at, TypeInt::BYTE) { } |
993 | virtual int Opcode() const; |
994 | }; |
995 | |
996 | |
997 | //------------------------------CompareAndExchangeSNode--------------------------- |
998 | class CompareAndExchangeSNode : public CompareAndExchangeNode { |
999 | public: |
1000 | CompareAndExchangeSNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, const TypePtr* at, MemNode::MemOrd mem_ord) : CompareAndExchangeNode(c, mem, adr, val, ex, mem_ord, at, TypeInt::SHORT) { } |
1001 | virtual int Opcode() const; |
1002 | }; |
1003 | |
1004 | //------------------------------CompareAndExchangeLNode--------------------------- |
1005 | class CompareAndExchangeLNode : public CompareAndExchangeNode { |
1006 | public: |
1007 | CompareAndExchangeLNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, const TypePtr* at, MemNode::MemOrd mem_ord) : CompareAndExchangeNode(c, mem, adr, val, ex, mem_ord, at, TypeLong::LONG) { } |
1008 | virtual int Opcode() const; |
1009 | }; |
1010 | |
1011 | |
1012 | //------------------------------CompareAndExchangeINode--------------------------- |
1013 | class CompareAndExchangeINode : public CompareAndExchangeNode { |
1014 | public: |
1015 | CompareAndExchangeINode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, const TypePtr* at, MemNode::MemOrd mem_ord) : CompareAndExchangeNode(c, mem, adr, val, ex, mem_ord, at, TypeInt::INT) { } |
1016 | virtual int Opcode() const; |
1017 | }; |
1018 | |
1019 | |
1020 | //------------------------------CompareAndExchangePNode--------------------------- |
1021 | class CompareAndExchangePNode : public CompareAndExchangeNode { |
1022 | public: |
1023 | CompareAndExchangePNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, const TypePtr* at, const Type* t, MemNode::MemOrd mem_ord) : CompareAndExchangeNode(c, mem, adr, val, ex, mem_ord, at, t) { } |
1024 | virtual int Opcode() const; |
1025 | }; |
1026 | |
1027 | //------------------------------CompareAndExchangeNNode--------------------------- |
1028 | class CompareAndExchangeNNode : public CompareAndExchangeNode { |
1029 | public: |
1030 | CompareAndExchangeNNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex, const TypePtr* at, const Type* t, MemNode::MemOrd mem_ord) : CompareAndExchangeNode(c, mem, adr, val, ex, mem_ord, at, t) { } |
1031 | virtual int Opcode() const; |
1032 | }; |
1033 | |
1034 | //------------------------------GetAndAddBNode--------------------------- |
1035 | class GetAndAddBNode : public LoadStoreNode { |
1036 | public: |
1037 | GetAndAddBNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeInt::BYTE, 4) { } |
1038 | virtual int Opcode() const; |
1039 | }; |
1040 | |
1041 | //------------------------------GetAndAddSNode--------------------------- |
1042 | class GetAndAddSNode : public LoadStoreNode { |
1043 | public: |
1044 | GetAndAddSNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeInt::SHORT, 4) { } |
1045 | virtual int Opcode() const; |
1046 | }; |
1047 | |
1048 | //------------------------------GetAndAddINode--------------------------- |
1049 | class GetAndAddINode : public LoadStoreNode { |
1050 | public: |
1051 | GetAndAddINode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeInt::INT, 4) { } |
1052 | virtual int Opcode() const; |
1053 | }; |
1054 | |
1055 | //------------------------------GetAndAddLNode--------------------------- |
1056 | class GetAndAddLNode : public LoadStoreNode { |
1057 | public: |
1058 | GetAndAddLNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeLong::LONG, 4) { } |
1059 | virtual int Opcode() const; |
1060 | }; |
1061 | |
1062 | //------------------------------GetAndSetBNode--------------------------- |
1063 | class GetAndSetBNode : public LoadStoreNode { |
1064 | public: |
1065 | GetAndSetBNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeInt::BYTE, 4) { } |
1066 | virtual int Opcode() const; |
1067 | }; |
1068 | |
1069 | //------------------------------GetAndSetSNode--------------------------- |
1070 | class GetAndSetSNode : public LoadStoreNode { |
1071 | public: |
1072 | GetAndSetSNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeInt::SHORT, 4) { } |
1073 | virtual int Opcode() const; |
1074 | }; |
1075 | |
1076 | //------------------------------GetAndSetINode--------------------------- |
1077 | class GetAndSetINode : public LoadStoreNode { |
1078 | public: |
1079 | GetAndSetINode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeInt::INT, 4) { } |
1080 | virtual int Opcode() const; |
1081 | }; |
1082 | |
1083 | //------------------------------GetAndSetLNode--------------------------- |
1084 | class GetAndSetLNode : public LoadStoreNode { |
1085 | public: |
1086 | GetAndSetLNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeLong::LONG, 4) { } |
1087 | virtual int Opcode() const; |
1088 | }; |
1089 | |
1090 | //------------------------------GetAndSetPNode--------------------------- |
1091 | class GetAndSetPNode : public LoadStoreNode { |
1092 | public: |
1093 | GetAndSetPNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* t ) : LoadStoreNode(c, mem, adr, val, at, t, 4) { } |
1094 | virtual int Opcode() const; |
1095 | }; |
1096 | |
1097 | //------------------------------GetAndSetNNode--------------------------- |
1098 | class GetAndSetNNode : public LoadStoreNode { |
1099 | public: |
1100 | GetAndSetNNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* t ) : LoadStoreNode(c, mem, adr, val, at, t, 4) { } |
1101 | virtual int Opcode() const; |
1102 | }; |
1103 | |
1104 | //------------------------------ClearArray------------------------------------- |
1105 | class ClearArrayNode: public Node { |
1106 | private: |
1107 | bool _is_large; |
1108 | public: |
1109 | ClearArrayNode( Node *ctrl, Node *arymem, Node *word_cnt, Node *base, bool is_large) |
1110 | : Node(ctrl,arymem,word_cnt,base), _is_large(is_large) { |
1111 | init_class_id(Class_ClearArray); |
1112 | } |
1113 | virtual int Opcode() const; |
1114 | virtual const Type *bottom_type() const { return Type::MEMORY; } |
1115 | // ClearArray modifies array elements, and so affects only the |
1116 | // array memory addressed by the bottom_type of its base address. |
1117 | virtual const class TypePtr *adr_type() const; |
1118 | virtual Node* Identity(PhaseGVN* phase); |
1119 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
1120 | virtual uint match_edge(uint idx) const; |
1121 | bool is_large() const { return _is_large; } |
1122 | |
1123 | // Clear the given area of an object or array. |
1124 | // The start offset must always be aligned mod BytesPerInt. |
1125 | // The end offset must always be aligned mod BytesPerLong. |
1126 | // Return the new memory. |
1127 | static Node* clear_memory(Node* control, Node* mem, Node* dest, |
1128 | intptr_t start_offset, |
1129 | intptr_t end_offset, |
1130 | PhaseGVN* phase); |
1131 | static Node* clear_memory(Node* control, Node* mem, Node* dest, |
1132 | intptr_t start_offset, |
1133 | Node* end_offset, |
1134 | PhaseGVN* phase); |
1135 | static Node* clear_memory(Node* control, Node* mem, Node* dest, |
1136 | Node* start_offset, |
1137 | Node* end_offset, |
1138 | PhaseGVN* phase); |
1139 | // Return allocation input memory edge if it is different instance |
1140 | // or itself if it is the one we are looking for. |
1141 | static bool step_through(Node** np, uint instance_id, PhaseTransform* phase); |
1142 | }; |
1143 | |
1144 | //------------------------------MemBar----------------------------------------- |
1145 | // There are different flavors of Memory Barriers to match the Java Memory |
1146 | // Model. Monitor-enter and volatile-load act as Aquires: no following ref |
1147 | // can be moved to before them. We insert a MemBar-Acquire after a FastLock or |
1148 | // volatile-load. Monitor-exit and volatile-store act as Release: no |
1149 | // preceding ref can be moved to after them. We insert a MemBar-Release |
1150 | // before a FastUnlock or volatile-store. All volatiles need to be |
1151 | // serialized, so we follow all volatile-stores with a MemBar-Volatile to |
1152 | // separate it from any following volatile-load. |
1153 | class MemBarNode: public MultiNode { |
1154 | virtual uint hash() const ; // { return NO_HASH; } |
1155 | virtual bool cmp( const Node &n ) const ; // Always fail, except on self |
1156 | |
1157 | virtual uint size_of() const { return sizeof(*this); } |
1158 | // Memory type this node is serializing. Usually either rawptr or bottom. |
1159 | const TypePtr* _adr_type; |
1160 | |
1161 | // How is this membar related to a nearby memory access? |
1162 | enum { |
1163 | Standalone, |
1164 | TrailingLoad, |
1165 | TrailingStore, |
1166 | LeadingStore, |
1167 | TrailingLoadStore, |
1168 | LeadingLoadStore |
1169 | } _kind; |
1170 | |
1171 | #ifdef ASSERT |
1172 | uint _pair_idx; |
1173 | #endif |
1174 | |
1175 | public: |
1176 | enum { |
1177 | Precedent = TypeFunc::Parms // optional edge to force precedence |
1178 | }; |
1179 | MemBarNode(Compile* C, int alias_idx, Node* precedent); |
1180 | virtual int Opcode() const = 0; |
1181 | virtual const class TypePtr *adr_type() const { return _adr_type; } |
1182 | virtual const Type* Value(PhaseGVN* phase) const; |
1183 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
1184 | virtual uint match_edge(uint idx) const { return 0; } |
1185 | virtual const Type *bottom_type() const { return TypeTuple::MEMBAR; } |
1186 | virtual Node *match( const ProjNode *proj, const Matcher *m ); |
1187 | // Factory method. Builds a wide or narrow membar. |
1188 | // Optional 'precedent' becomes an extra edge if not null. |
1189 | static MemBarNode* make(Compile* C, int opcode, |
1190 | int alias_idx = Compile::AliasIdxBot, |
1191 | Node* precedent = NULL); |
1192 | |
1193 | MemBarNode* trailing_membar() const; |
1194 | MemBarNode* leading_membar() const; |
1195 | |
1196 | void set_trailing_load() { _kind = TrailingLoad; } |
1197 | bool trailing_load() const { return _kind == TrailingLoad; } |
1198 | bool trailing_store() const { return _kind == TrailingStore; } |
1199 | bool leading_store() const { return _kind == LeadingStore; } |
1200 | bool trailing_load_store() const { return _kind == TrailingLoadStore; } |
1201 | bool leading_load_store() const { return _kind == LeadingLoadStore; } |
1202 | bool trailing() const { return _kind == TrailingLoad || _kind == TrailingStore || _kind == TrailingLoadStore; } |
1203 | bool leading() const { return _kind == LeadingStore || _kind == LeadingLoadStore; } |
1204 | bool standalone() const { return _kind == Standalone; } |
1205 | |
1206 | static void set_store_pair(MemBarNode* leading, MemBarNode* trailing); |
1207 | static void set_load_store_pair(MemBarNode* leading, MemBarNode* trailing); |
1208 | |
1209 | void remove(PhaseIterGVN *igvn); |
1210 | }; |
1211 | |
1212 | // "Acquire" - no following ref can move before (but earlier refs can |
1213 | // follow, like an early Load stalled in cache). Requires multi-cpu |
1214 | // visibility. Inserted after a volatile load. |
1215 | class MemBarAcquireNode: public MemBarNode { |
1216 | public: |
1217 | MemBarAcquireNode(Compile* C, int alias_idx, Node* precedent) |
1218 | : MemBarNode(C, alias_idx, precedent) {} |
1219 | virtual int Opcode() const; |
1220 | }; |
1221 | |
1222 | // "Acquire" - no following ref can move before (but earlier refs can |
1223 | // follow, like an early Load stalled in cache). Requires multi-cpu |
1224 | // visibility. Inserted independ of any load, as required |
1225 | // for intrinsic Unsafe.loadFence(). |
1226 | class LoadFenceNode: public MemBarNode { |
1227 | public: |
1228 | LoadFenceNode(Compile* C, int alias_idx, Node* precedent) |
1229 | : MemBarNode(C, alias_idx, precedent) {} |
1230 | virtual int Opcode() const; |
1231 | }; |
1232 | |
1233 | // "Release" - no earlier ref can move after (but later refs can move |
1234 | // up, like a speculative pipelined cache-hitting Load). Requires |
1235 | // multi-cpu visibility. Inserted before a volatile store. |
1236 | class MemBarReleaseNode: public MemBarNode { |
1237 | public: |
1238 | MemBarReleaseNode(Compile* C, int alias_idx, Node* precedent) |
1239 | : MemBarNode(C, alias_idx, precedent) {} |
1240 | virtual int Opcode() const; |
1241 | }; |
1242 | |
1243 | // "Release" - no earlier ref can move after (but later refs can move |
1244 | // up, like a speculative pipelined cache-hitting Load). Requires |
1245 | // multi-cpu visibility. Inserted independent of any store, as required |
1246 | // for intrinsic Unsafe.storeFence(). |
1247 | class StoreFenceNode: public MemBarNode { |
1248 | public: |
1249 | StoreFenceNode(Compile* C, int alias_idx, Node* precedent) |
1250 | : MemBarNode(C, alias_idx, precedent) {} |
1251 | virtual int Opcode() const; |
1252 | }; |
1253 | |
1254 | // "Acquire" - no following ref can move before (but earlier refs can |
1255 | // follow, like an early Load stalled in cache). Requires multi-cpu |
1256 | // visibility. Inserted after a FastLock. |
1257 | class MemBarAcquireLockNode: public MemBarNode { |
1258 | public: |
1259 | MemBarAcquireLockNode(Compile* C, int alias_idx, Node* precedent) |
1260 | : MemBarNode(C, alias_idx, precedent) {} |
1261 | virtual int Opcode() const; |
1262 | }; |
1263 | |
1264 | // "Release" - no earlier ref can move after (but later refs can move |
1265 | // up, like a speculative pipelined cache-hitting Load). Requires |
1266 | // multi-cpu visibility. Inserted before a FastUnLock. |
1267 | class MemBarReleaseLockNode: public MemBarNode { |
1268 | public: |
1269 | MemBarReleaseLockNode(Compile* C, int alias_idx, Node* precedent) |
1270 | : MemBarNode(C, alias_idx, precedent) {} |
1271 | virtual int Opcode() const; |
1272 | }; |
1273 | |
1274 | class MemBarStoreStoreNode: public MemBarNode { |
1275 | public: |
1276 | MemBarStoreStoreNode(Compile* C, int alias_idx, Node* precedent) |
1277 | : MemBarNode(C, alias_idx, precedent) { |
1278 | init_class_id(Class_MemBarStoreStore); |
1279 | } |
1280 | virtual int Opcode() const; |
1281 | }; |
1282 | |
1283 | // Ordering between a volatile store and a following volatile load. |
1284 | // Requires multi-CPU visibility? |
1285 | class MemBarVolatileNode: public MemBarNode { |
1286 | public: |
1287 | MemBarVolatileNode(Compile* C, int alias_idx, Node* precedent) |
1288 | : MemBarNode(C, alias_idx, precedent) {} |
1289 | virtual int Opcode() const; |
1290 | }; |
1291 | |
1292 | // Ordering within the same CPU. Used to order unsafe memory references |
1293 | // inside the compiler when we lack alias info. Not needed "outside" the |
1294 | // compiler because the CPU does all the ordering for us. |
1295 | class MemBarCPUOrderNode: public MemBarNode { |
1296 | public: |
1297 | MemBarCPUOrderNode(Compile* C, int alias_idx, Node* precedent) |
1298 | : MemBarNode(C, alias_idx, precedent) {} |
1299 | virtual int Opcode() const; |
1300 | virtual uint ideal_reg() const { return 0; } // not matched in the AD file |
1301 | }; |
1302 | |
1303 | class OnSpinWaitNode: public MemBarNode { |
1304 | public: |
1305 | OnSpinWaitNode(Compile* C, int alias_idx, Node* precedent) |
1306 | : MemBarNode(C, alias_idx, precedent) {} |
1307 | virtual int Opcode() const; |
1308 | }; |
1309 | |
1310 | // Isolation of object setup after an AllocateNode and before next safepoint. |
1311 | // (See comment in memnode.cpp near InitializeNode::InitializeNode for semantics.) |
1312 | class InitializeNode: public MemBarNode { |
1313 | friend class AllocateNode; |
1314 | |
1315 | enum { |
1316 | Incomplete = 0, |
1317 | Complete = 1, |
1318 | WithArraycopy = 2 |
1319 | }; |
1320 | int _is_complete; |
1321 | |
1322 | bool _does_not_escape; |
1323 | |
1324 | public: |
1325 | enum { |
1326 | Control = TypeFunc::Control, |
1327 | Memory = TypeFunc::Memory, // MergeMem for states affected by this op |
1328 | RawAddress = TypeFunc::Parms+0, // the newly-allocated raw address |
1329 | RawStores = TypeFunc::Parms+1 // zero or more stores (or TOP) |
1330 | }; |
1331 | |
1332 | InitializeNode(Compile* C, int adr_type, Node* rawoop); |
1333 | virtual int Opcode() const; |
1334 | virtual uint size_of() const { return sizeof(*this); } |
1335 | virtual uint ideal_reg() const { return 0; } // not matched in the AD file |
1336 | virtual const RegMask &in_RegMask(uint) const; // mask for RawAddress |
1337 | |
1338 | // Manage incoming memory edges via a MergeMem on in(Memory): |
1339 | Node* memory(uint alias_idx); |
1340 | |
1341 | // The raw memory edge coming directly from the Allocation. |
1342 | // The contents of this memory are *always* all-zero-bits. |
1343 | Node* zero_memory() { return memory(Compile::AliasIdxRaw); } |
1344 | |
1345 | // Return the corresponding allocation for this initialization (or null if none). |
1346 | // (Note: Both InitializeNode::allocation and AllocateNode::initialization |
1347 | // are defined in graphKit.cpp, which sets up the bidirectional relation.) |
1348 | AllocateNode* allocation(); |
1349 | |
1350 | // Anything other than zeroing in this init? |
1351 | bool is_non_zero(); |
1352 | |
1353 | // An InitializeNode must completed before macro expansion is done. |
1354 | // Completion requires that the AllocateNode must be followed by |
1355 | // initialization of the new memory to zero, then to any initializers. |
1356 | bool is_complete() { return _is_complete != Incomplete; } |
1357 | bool is_complete_with_arraycopy() { return (_is_complete & WithArraycopy) != 0; } |
1358 | |
1359 | // Mark complete. (Must not yet be complete.) |
1360 | void set_complete(PhaseGVN* phase); |
1361 | void set_complete_with_arraycopy() { _is_complete = Complete | WithArraycopy; } |
1362 | |
1363 | bool does_not_escape() { return _does_not_escape; } |
1364 | void set_does_not_escape() { _does_not_escape = true; } |
1365 | |
1366 | #ifdef ASSERT |
1367 | // ensure all non-degenerate stores are ordered and non-overlapping |
1368 | bool stores_are_sane(PhaseTransform* phase); |
1369 | #endif //ASSERT |
1370 | |
1371 | // See if this store can be captured; return offset where it initializes. |
1372 | // Return 0 if the store cannot be moved (any sort of problem). |
1373 | intptr_t can_capture_store(StoreNode* st, PhaseTransform* phase, bool can_reshape); |
1374 | |
1375 | // Capture another store; reformat it to write my internal raw memory. |
1376 | // Return the captured copy, else NULL if there is some sort of problem. |
1377 | Node* capture_store(StoreNode* st, intptr_t start, PhaseTransform* phase, bool can_reshape); |
1378 | |
1379 | // Find captured store which corresponds to the range [start..start+size). |
1380 | // Return my own memory projection (meaning the initial zero bits) |
1381 | // if there is no such store. Return NULL if there is a problem. |
1382 | Node* find_captured_store(intptr_t start, int size_in_bytes, PhaseTransform* phase); |
1383 | |
1384 | // Called when the associated AllocateNode is expanded into CFG. |
1385 | Node* complete_stores(Node* rawctl, Node* rawmem, Node* rawptr, |
1386 | intptr_t , Node* size_in_bytes, |
1387 | PhaseGVN* phase); |
1388 | |
1389 | private: |
1390 | void (); |
1391 | |
1392 | // Find out where a captured store should be placed (or already is placed). |
1393 | int captured_store_insertion_point(intptr_t start, int size_in_bytes, |
1394 | PhaseTransform* phase); |
1395 | |
1396 | static intptr_t get_store_offset(Node* st, PhaseTransform* phase); |
1397 | |
1398 | Node* make_raw_address(intptr_t offset, PhaseTransform* phase); |
1399 | |
1400 | bool detect_init_independence(Node* n, int& count); |
1401 | |
1402 | void coalesce_subword_stores(intptr_t , Node* size_in_bytes, |
1403 | PhaseGVN* phase); |
1404 | |
1405 | intptr_t find_next_fullword_store(uint i, PhaseGVN* phase); |
1406 | }; |
1407 | |
1408 | //------------------------------MergeMem--------------------------------------- |
1409 | // (See comment in memnode.cpp near MergeMemNode::MergeMemNode for semantics.) |
1410 | class MergeMemNode: public Node { |
1411 | virtual uint hash() const ; // { return NO_HASH; } |
1412 | virtual bool cmp( const Node &n ) const ; // Always fail, except on self |
1413 | friend class MergeMemStream; |
1414 | MergeMemNode(Node* def); // clients use MergeMemNode::make |
1415 | |
1416 | public: |
1417 | // If the input is a whole memory state, clone it with all its slices intact. |
1418 | // Otherwise, make a new memory state with just that base memory input. |
1419 | // In either case, the result is a newly created MergeMem. |
1420 | static MergeMemNode* make(Node* base_memory); |
1421 | |
1422 | virtual int Opcode() const; |
1423 | virtual Node* Identity(PhaseGVN* phase); |
1424 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
1425 | virtual uint ideal_reg() const { return NotAMachineReg; } |
1426 | virtual uint match_edge(uint idx) const { return 0; } |
1427 | virtual const RegMask &out_RegMask() const; |
1428 | virtual const Type *bottom_type() const { return Type::MEMORY; } |
1429 | virtual const TypePtr *adr_type() const { return TypePtr::BOTTOM; } |
1430 | // sparse accessors |
1431 | // Fetch the previously stored "set_memory_at", or else the base memory. |
1432 | // (Caller should clone it if it is a phi-nest.) |
1433 | Node* memory_at(uint alias_idx) const; |
1434 | // set the memory, regardless of its previous value |
1435 | void set_memory_at(uint alias_idx, Node* n); |
1436 | // the "base" is the memory that provides the non-finite support |
1437 | Node* base_memory() const { return in(Compile::AliasIdxBot); } |
1438 | // warning: setting the base can implicitly set any of the other slices too |
1439 | void set_base_memory(Node* def); |
1440 | // sentinel value which denotes a copy of the base memory: |
1441 | Node* empty_memory() const { return in(Compile::AliasIdxTop); } |
1442 | static Node* make_empty_memory(); // where the sentinel comes from |
1443 | bool is_empty_memory(Node* n) const { assert((n == empty_memory()) == n->is_top(), "sanity" ); return n->is_top(); } |
1444 | // hook for the iterator, to perform any necessary setup |
1445 | void iteration_setup(const MergeMemNode* other = NULL); |
1446 | // push sentinels until I am at least as long as the other (semantic no-op) |
1447 | void grow_to_match(const MergeMemNode* other); |
1448 | bool verify_sparse() const PRODUCT_RETURN0; |
1449 | #ifndef PRODUCT |
1450 | virtual void dump_spec(outputStream *st) const; |
1451 | #endif |
1452 | }; |
1453 | |
1454 | class MergeMemStream : public StackObj { |
1455 | private: |
1456 | MergeMemNode* _mm; |
1457 | const MergeMemNode* _mm2; // optional second guy, contributes non-empty iterations |
1458 | Node* _mm_base; // loop-invariant base memory of _mm |
1459 | int _idx; |
1460 | int _cnt; |
1461 | Node* _mem; |
1462 | Node* _mem2; |
1463 | int _cnt2; |
1464 | |
1465 | void init(MergeMemNode* mm, const MergeMemNode* mm2 = NULL) { |
1466 | // subsume_node will break sparseness at times, whenever a memory slice |
1467 | // folds down to a copy of the base ("fat") memory. In such a case, |
1468 | // the raw edge will update to base, although it should be top. |
1469 | // This iterator will recognize either top or base_memory as an |
1470 | // "empty" slice. See is_empty, is_empty2, and next below. |
1471 | // |
1472 | // The sparseness property is repaired in MergeMemNode::Ideal. |
1473 | // As long as access to a MergeMem goes through this iterator |
1474 | // or the memory_at accessor, flaws in the sparseness will |
1475 | // never be observed. |
1476 | // |
1477 | // Also, iteration_setup repairs sparseness. |
1478 | assert(mm->verify_sparse(), "please, no dups of base" ); |
1479 | assert(mm2==NULL || mm2->verify_sparse(), "please, no dups of base" ); |
1480 | |
1481 | _mm = mm; |
1482 | _mm_base = mm->base_memory(); |
1483 | _mm2 = mm2; |
1484 | _cnt = mm->req(); |
1485 | _idx = Compile::AliasIdxBot-1; // start at the base memory |
1486 | _mem = NULL; |
1487 | _mem2 = NULL; |
1488 | } |
1489 | |
1490 | #ifdef ASSERT |
1491 | Node* check_memory() const { |
1492 | if (at_base_memory()) |
1493 | return _mm->base_memory(); |
1494 | else if ((uint)_idx < _mm->req() && !_mm->in(_idx)->is_top()) |
1495 | return _mm->memory_at(_idx); |
1496 | else |
1497 | return _mm_base; |
1498 | } |
1499 | Node* check_memory2() const { |
1500 | return at_base_memory()? _mm2->base_memory(): _mm2->memory_at(_idx); |
1501 | } |
1502 | #endif |
1503 | |
1504 | static bool match_memory(Node* mem, const MergeMemNode* mm, int idx) PRODUCT_RETURN0; |
1505 | void assert_synch() const { |
1506 | assert(!_mem || _idx >= _cnt || match_memory(_mem, _mm, _idx), |
1507 | "no side-effects except through the stream" ); |
1508 | } |
1509 | |
1510 | public: |
1511 | |
1512 | // expected usages: |
1513 | // for (MergeMemStream mms(mem->is_MergeMem()); next_non_empty(); ) { ... } |
1514 | // for (MergeMemStream mms(mem1, mem2); next_non_empty2(); ) { ... } |
1515 | |
1516 | // iterate over one merge |
1517 | MergeMemStream(MergeMemNode* mm) { |
1518 | mm->iteration_setup(); |
1519 | init(mm); |
1520 | debug_only(_cnt2 = 999); |
1521 | } |
1522 | // iterate in parallel over two merges |
1523 | // only iterates through non-empty elements of mm2 |
1524 | MergeMemStream(MergeMemNode* mm, const MergeMemNode* mm2) { |
1525 | assert(mm2, "second argument must be a MergeMem also" ); |
1526 | ((MergeMemNode*)mm2)->iteration_setup(); // update hidden state |
1527 | mm->iteration_setup(mm2); |
1528 | init(mm, mm2); |
1529 | _cnt2 = mm2->req(); |
1530 | } |
1531 | #ifdef ASSERT |
1532 | ~MergeMemStream() { |
1533 | assert_synch(); |
1534 | } |
1535 | #endif |
1536 | |
1537 | MergeMemNode* all_memory() const { |
1538 | return _mm; |
1539 | } |
1540 | Node* base_memory() const { |
1541 | assert(_mm_base == _mm->base_memory(), "no update to base memory, please" ); |
1542 | return _mm_base; |
1543 | } |
1544 | const MergeMemNode* all_memory2() const { |
1545 | assert(_mm2 != NULL, "" ); |
1546 | return _mm2; |
1547 | } |
1548 | bool at_base_memory() const { |
1549 | return _idx == Compile::AliasIdxBot; |
1550 | } |
1551 | int alias_idx() const { |
1552 | assert(_mem, "must call next 1st" ); |
1553 | return _idx; |
1554 | } |
1555 | |
1556 | const TypePtr* adr_type() const { |
1557 | return Compile::current()->get_adr_type(alias_idx()); |
1558 | } |
1559 | |
1560 | const TypePtr* adr_type(Compile* C) const { |
1561 | return C->get_adr_type(alias_idx()); |
1562 | } |
1563 | bool is_empty() const { |
1564 | assert(_mem, "must call next 1st" ); |
1565 | assert(_mem->is_top() == (_mem==_mm->empty_memory()), "correct sentinel" ); |
1566 | return _mem->is_top(); |
1567 | } |
1568 | bool is_empty2() const { |
1569 | assert(_mem2, "must call next 1st" ); |
1570 | assert(_mem2->is_top() == (_mem2==_mm2->empty_memory()), "correct sentinel" ); |
1571 | return _mem2->is_top(); |
1572 | } |
1573 | Node* memory() const { |
1574 | assert(!is_empty(), "must not be empty" ); |
1575 | assert_synch(); |
1576 | return _mem; |
1577 | } |
1578 | // get the current memory, regardless of empty or non-empty status |
1579 | Node* force_memory() const { |
1580 | assert(!is_empty() || !at_base_memory(), "" ); |
1581 | // Use _mm_base to defend against updates to _mem->base_memory(). |
1582 | Node *mem = _mem->is_top() ? _mm_base : _mem; |
1583 | assert(mem == check_memory(), "" ); |
1584 | return mem; |
1585 | } |
1586 | Node* memory2() const { |
1587 | assert(_mem2 == check_memory2(), "" ); |
1588 | return _mem2; |
1589 | } |
1590 | void set_memory(Node* mem) { |
1591 | if (at_base_memory()) { |
1592 | // Note that this does not change the invariant _mm_base. |
1593 | _mm->set_base_memory(mem); |
1594 | } else { |
1595 | _mm->set_memory_at(_idx, mem); |
1596 | } |
1597 | _mem = mem; |
1598 | assert_synch(); |
1599 | } |
1600 | |
1601 | // Recover from a side effect to the MergeMemNode. |
1602 | void set_memory() { |
1603 | _mem = _mm->in(_idx); |
1604 | } |
1605 | |
1606 | bool next() { return next(false); } |
1607 | bool next2() { return next(true); } |
1608 | |
1609 | bool next_non_empty() { return next_non_empty(false); } |
1610 | bool next_non_empty2() { return next_non_empty(true); } |
1611 | // next_non_empty2 can yield states where is_empty() is true |
1612 | |
1613 | private: |
1614 | // find the next item, which might be empty |
1615 | bool next(bool have_mm2) { |
1616 | assert((_mm2 != NULL) == have_mm2, "use other next" ); |
1617 | assert_synch(); |
1618 | if (++_idx < _cnt) { |
1619 | // Note: This iterator allows _mm to be non-sparse. |
1620 | // It behaves the same whether _mem is top or base_memory. |
1621 | _mem = _mm->in(_idx); |
1622 | if (have_mm2) |
1623 | _mem2 = _mm2->in((_idx < _cnt2) ? _idx : Compile::AliasIdxTop); |
1624 | return true; |
1625 | } |
1626 | return false; |
1627 | } |
1628 | |
1629 | // find the next non-empty item |
1630 | bool next_non_empty(bool have_mm2) { |
1631 | while (next(have_mm2)) { |
1632 | if (!is_empty()) { |
1633 | // make sure _mem2 is filled in sensibly |
1634 | if (have_mm2 && _mem2->is_top()) _mem2 = _mm2->base_memory(); |
1635 | return true; |
1636 | } else if (have_mm2 && !is_empty2()) { |
1637 | return true; // is_empty() == true |
1638 | } |
1639 | } |
1640 | return false; |
1641 | } |
1642 | }; |
1643 | |
1644 | //------------------------------Prefetch--------------------------------------- |
1645 | |
1646 | // Allocation prefetch which may fault, TLAB size have to be adjusted. |
1647 | class PrefetchAllocationNode : public Node { |
1648 | public: |
1649 | PrefetchAllocationNode(Node *mem, Node *adr) : Node(0,mem,adr) {} |
1650 | virtual int Opcode() const; |
1651 | virtual uint ideal_reg() const { return NotAMachineReg; } |
1652 | virtual uint match_edge(uint idx) const { return idx==2; } |
1653 | virtual const Type *bottom_type() const { return ( AllocatePrefetchStyle == 3 ) ? Type::MEMORY : Type::ABIO; } |
1654 | }; |
1655 | |
1656 | #endif // SHARE_OPTO_MEMNODE_HPP |
1657 | |