comparison src/share/vm/opto/memnode.hpp @ 14429:2113136690bc

8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering Summary: Add a field to C2 LoadNode and StoreNode classes which indicates whether the load/store should do an acquire/release on platforms which support it. Reviewed-by: kvn
author goetz
date Fri, 15 Nov 2013 11:05:32 -0800
parents 6f3fd5150b67
children da862781b584
comparison
equal deleted inserted replaced
14427:eb178e97560c 14429:2113136690bc
49 Memory, // Chunk of memory is being loaded from 49 Memory, // Chunk of memory is being loaded from
50 Address, // Actually address, derived from base 50 Address, // Actually address, derived from base
51 ValueIn, // Value to store 51 ValueIn, // Value to store
52 OopStore // Preceeding oop store, only in StoreCM 52 OopStore // Preceeding oop store, only in StoreCM
53 }; 53 };
54 typedef enum { unordered = 0,
55 acquire, // Load has to acquire or be succeeded by MemBarAcquire.
56 release // Store has to release or be preceded by MemBarRelease.
57 } MemOrd;
54 protected: 58 protected:
55 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at ) 59 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at )
56 : Node(c0,c1,c2 ) { 60 : Node(c0,c1,c2 ) {
57 init_class_id(Class_Mem); 61 init_class_id(Class_Mem);
58 debug_only(_adr_type=at; adr_type();) 62 debug_only(_adr_type=at; adr_type();)
132 }; 136 };
133 137
134 //------------------------------LoadNode--------------------------------------- 138 //------------------------------LoadNode---------------------------------------
135 // Load value; requires Memory and Address 139 // Load value; requires Memory and Address
136 class LoadNode : public MemNode { 140 class LoadNode : public MemNode {
141 private:
142 // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish
143 // loads that can be reordered, and such requiring acquire semantics to
144 // adhere to the Java specification. The required behaviour is stored in
145 // this field.
146 const MemOrd _mo;
147
137 protected: 148 protected:
138 virtual uint cmp( const Node &n ) const; 149 virtual uint cmp(const Node &n) const;
139 virtual uint size_of() const; // Size is bigger 150 virtual uint size_of() const; // Size is bigger
140 const Type* const _type; // What kind of value is loaded? 151 const Type* const _type; // What kind of value is loaded?
141 public: 152 public:
142 153
143 LoadNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt ) 154 LoadNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt, MemOrd mo)
144 : MemNode(c,mem,adr,at), _type(rt) { 155 : MemNode(c,mem,adr,at), _type(rt), _mo(mo) {
145 init_class_id(Class_Load); 156 init_class_id(Class_Load);
146 } 157 }
158 inline bool is_unordered() const { return !is_acquire(); }
159 inline bool is_acquire() const {
160 assert(_mo == unordered || _mo == acquire, "unexpected");
161 return _mo == acquire;
162 }
147 163
148 // Polymorphic factory method: 164 // Polymorphic factory method:
149 static Node* make( PhaseGVN& gvn, Node *c, Node *mem, Node *adr, 165 static Node* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr,
150 const TypePtr* at, const Type *rt, BasicType bt ); 166 const TypePtr* at, const Type *rt, BasicType bt, MemOrd mo);
151 167
152 virtual uint hash() const; // Check the type 168 virtual uint hash() const; // Check the type
153 169
154 // Handle algebraic identities here. If we have an identity, return the Node 170 // Handle algebraic identities here. If we have an identity, return the Node
155 // we are equivalent to. We look for Load of a Store. 171 // we are equivalent to. We look for Load of a Store.
208 224
209 //------------------------------LoadBNode-------------------------------------- 225 //------------------------------LoadBNode--------------------------------------
210 // Load a byte (8bits signed) from memory 226 // Load a byte (8bits signed) from memory
211 class LoadBNode : public LoadNode { 227 class LoadBNode : public LoadNode {
212 public: 228 public:
213 LoadBNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::BYTE ) 229 LoadBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
214 : LoadNode(c,mem,adr,at,ti) {} 230 : LoadNode(c, mem, adr, at, ti, mo) {}
215 virtual int Opcode() const; 231 virtual int Opcode() const;
216 virtual uint ideal_reg() const { return Op_RegI; } 232 virtual uint ideal_reg() const { return Op_RegI; }
217 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 233 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
218 virtual const Type *Value(PhaseTransform *phase) const; 234 virtual const Type *Value(PhaseTransform *phase) const;
219 virtual int store_Opcode() const { return Op_StoreB; } 235 virtual int store_Opcode() const { return Op_StoreB; }
222 238
223 //------------------------------LoadUBNode------------------------------------- 239 //------------------------------LoadUBNode-------------------------------------
224 // Load a unsigned byte (8bits unsigned) from memory 240 // Load a unsigned byte (8bits unsigned) from memory
225 class LoadUBNode : public LoadNode { 241 class LoadUBNode : public LoadNode {
226 public: 242 public:
227 LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti = TypeInt::UBYTE ) 243 LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti, MemOrd mo)
228 : LoadNode(c, mem, adr, at, ti) {} 244 : LoadNode(c, mem, adr, at, ti, mo) {}
229 virtual int Opcode() const; 245 virtual int Opcode() const;
230 virtual uint ideal_reg() const { return Op_RegI; } 246 virtual uint ideal_reg() const { return Op_RegI; }
231 virtual Node* Ideal(PhaseGVN *phase, bool can_reshape); 247 virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
232 virtual const Type *Value(PhaseTransform *phase) const; 248 virtual const Type *Value(PhaseTransform *phase) const;
233 virtual int store_Opcode() const { return Op_StoreB; } 249 virtual int store_Opcode() const { return Op_StoreB; }
236 252
237 //------------------------------LoadUSNode------------------------------------- 253 //------------------------------LoadUSNode-------------------------------------
238 // Load an unsigned short/char (16bits unsigned) from memory 254 // Load an unsigned short/char (16bits unsigned) from memory
239 class LoadUSNode : public LoadNode { 255 class LoadUSNode : public LoadNode {
240 public: 256 public:
241 LoadUSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR ) 257 LoadUSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
242 : LoadNode(c,mem,adr,at,ti) {} 258 : LoadNode(c, mem, adr, at, ti, mo) {}
243 virtual int Opcode() const; 259 virtual int Opcode() const;
244 virtual uint ideal_reg() const { return Op_RegI; } 260 virtual uint ideal_reg() const { return Op_RegI; }
245 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 261 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
246 virtual const Type *Value(PhaseTransform *phase) const; 262 virtual const Type *Value(PhaseTransform *phase) const;
247 virtual int store_Opcode() const { return Op_StoreC; } 263 virtual int store_Opcode() const { return Op_StoreC; }
250 266
251 //------------------------------LoadSNode-------------------------------------- 267 //------------------------------LoadSNode--------------------------------------
252 // Load a short (16bits signed) from memory 268 // Load a short (16bits signed) from memory
253 class LoadSNode : public LoadNode { 269 class LoadSNode : public LoadNode {
254 public: 270 public:
255 LoadSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT ) 271 LoadSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
256 : LoadNode(c,mem,adr,at,ti) {} 272 : LoadNode(c, mem, adr, at, ti, mo) {}
257 virtual int Opcode() const; 273 virtual int Opcode() const;
258 virtual uint ideal_reg() const { return Op_RegI; } 274 virtual uint ideal_reg() const { return Op_RegI; }
259 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 275 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
260 virtual const Type *Value(PhaseTransform *phase) const; 276 virtual const Type *Value(PhaseTransform *phase) const;
261 virtual int store_Opcode() const { return Op_StoreC; } 277 virtual int store_Opcode() const { return Op_StoreC; }
264 280
265 //------------------------------LoadINode-------------------------------------- 281 //------------------------------LoadINode--------------------------------------
266 // Load an integer from memory 282 // Load an integer from memory
267 class LoadINode : public LoadNode { 283 class LoadINode : public LoadNode {
268 public: 284 public:
269 LoadINode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::INT ) 285 LoadINode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
270 : LoadNode(c,mem,adr,at,ti) {} 286 : LoadNode(c, mem, adr, at, ti, mo) {}
271 virtual int Opcode() const; 287 virtual int Opcode() const;
272 virtual uint ideal_reg() const { return Op_RegI; } 288 virtual uint ideal_reg() const { return Op_RegI; }
273 virtual int store_Opcode() const { return Op_StoreI; } 289 virtual int store_Opcode() const { return Op_StoreI; }
274 virtual BasicType memory_type() const { return T_INT; } 290 virtual BasicType memory_type() const { return T_INT; }
275 }; 291 };
276 292
277 //------------------------------LoadRangeNode---------------------------------- 293 //------------------------------LoadRangeNode----------------------------------
278 // Load an array length from the array 294 // Load an array length from the array
279 class LoadRangeNode : public LoadINode { 295 class LoadRangeNode : public LoadINode {
280 public: 296 public:
281 LoadRangeNode( Node *c, Node *mem, Node *adr, const TypeInt *ti = TypeInt::POS ) 297 LoadRangeNode(Node *c, Node *mem, Node *adr, const TypeInt *ti = TypeInt::POS)
282 : LoadINode(c,mem,adr,TypeAryPtr::RANGE,ti) {} 298 : LoadINode(c, mem, adr, TypeAryPtr::RANGE, ti, MemNode::unordered) {}
283 virtual int Opcode() const; 299 virtual int Opcode() const;
284 virtual const Type *Value( PhaseTransform *phase ) const; 300 virtual const Type *Value( PhaseTransform *phase ) const;
285 virtual Node *Identity( PhaseTransform *phase ); 301 virtual Node *Identity( PhaseTransform *phase );
286 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 302 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
287 }; 303 };
296 } 312 }
297 virtual uint size_of() const { return sizeof(*this); } 313 virtual uint size_of() const { return sizeof(*this); }
298 const bool _require_atomic_access; // is piecewise load forbidden? 314 const bool _require_atomic_access; // is piecewise load forbidden?
299 315
300 public: 316 public:
301 LoadLNode( Node *c, Node *mem, Node *adr, const TypePtr* at, 317 LoadLNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeLong *tl,
302 const TypeLong *tl = TypeLong::LONG, 318 MemOrd mo, bool require_atomic_access = false)
303 bool require_atomic_access = false ) 319 : LoadNode(c, mem, adr, at, tl, mo), _require_atomic_access(require_atomic_access) {}
304 : LoadNode(c,mem,adr,at,tl)
305 , _require_atomic_access(require_atomic_access)
306 {}
307 virtual int Opcode() const; 320 virtual int Opcode() const;
308 virtual uint ideal_reg() const { return Op_RegL; } 321 virtual uint ideal_reg() const { return Op_RegL; }
309 virtual int store_Opcode() const { return Op_StoreL; } 322 virtual int store_Opcode() const { return Op_StoreL; }
310 virtual BasicType memory_type() const { return T_LONG; } 323 virtual BasicType memory_type() const { return T_LONG; }
311 bool require_atomic_access() { return _require_atomic_access; } 324 bool require_atomic_access() { return _require_atomic_access; }
312 static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt); 325 static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type,
326 const Type* rt, MemOrd mo);
313 #ifndef PRODUCT 327 #ifndef PRODUCT
314 virtual void dump_spec(outputStream *st) const { 328 virtual void dump_spec(outputStream *st) const {
315 LoadNode::dump_spec(st); 329 LoadNode::dump_spec(st);
316 if (_require_atomic_access) st->print(" Atomic!"); 330 if (_require_atomic_access) st->print(" Atomic!");
317 } 331 }
320 334
321 //------------------------------LoadL_unalignedNode---------------------------- 335 //------------------------------LoadL_unalignedNode----------------------------
322 // Load a long from unaligned memory 336 // Load a long from unaligned memory
323 class LoadL_unalignedNode : public LoadLNode { 337 class LoadL_unalignedNode : public LoadLNode {
324 public: 338 public:
325 LoadL_unalignedNode( Node *c, Node *mem, Node *adr, const TypePtr* at ) 339 LoadL_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo)
326 : LoadLNode(c,mem,adr,at) {} 340 : LoadLNode(c, mem, adr, at, TypeLong::LONG, mo) {}
327 virtual int Opcode() const; 341 virtual int Opcode() const;
328 }; 342 };
329 343
330 //------------------------------LoadFNode-------------------------------------- 344 //------------------------------LoadFNode--------------------------------------
331 // Load a float (64 bits) from memory 345 // Load a float (64 bits) from memory
332 class LoadFNode : public LoadNode { 346 class LoadFNode : public LoadNode {
333 public: 347 public:
334 LoadFNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t = Type::FLOAT ) 348 LoadFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo)
335 : LoadNode(c,mem,adr,at,t) {} 349 : LoadNode(c, mem, adr, at, t, mo) {}
336 virtual int Opcode() const; 350 virtual int Opcode() const;
337 virtual uint ideal_reg() const { return Op_RegF; } 351 virtual uint ideal_reg() const { return Op_RegF; }
338 virtual int store_Opcode() const { return Op_StoreF; } 352 virtual int store_Opcode() const { return Op_StoreF; }
339 virtual BasicType memory_type() const { return T_FLOAT; } 353 virtual BasicType memory_type() const { return T_FLOAT; }
340 }; 354 };
341 355
342 //------------------------------LoadDNode-------------------------------------- 356 //------------------------------LoadDNode--------------------------------------
343 // Load a double (64 bits) from memory 357 // Load a double (64 bits) from memory
344 class LoadDNode : public LoadNode { 358 class LoadDNode : public LoadNode {
345 public: 359 public:
346 LoadDNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t = Type::DOUBLE ) 360 LoadDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo)
347 : LoadNode(c,mem,adr,at,t) {} 361 : LoadNode(c, mem, adr, at, t, mo) {}
348 virtual int Opcode() const; 362 virtual int Opcode() const;
349 virtual uint ideal_reg() const { return Op_RegD; } 363 virtual uint ideal_reg() const { return Op_RegD; }
350 virtual int store_Opcode() const { return Op_StoreD; } 364 virtual int store_Opcode() const { return Op_StoreD; }
351 virtual BasicType memory_type() const { return T_DOUBLE; } 365 virtual BasicType memory_type() const { return T_DOUBLE; }
352 }; 366 };
353 367
354 //------------------------------LoadD_unalignedNode---------------------------- 368 //------------------------------LoadD_unalignedNode----------------------------
355 // Load a double from unaligned memory 369 // Load a double from unaligned memory
356 class LoadD_unalignedNode : public LoadDNode { 370 class LoadD_unalignedNode : public LoadDNode {
357 public: 371 public:
358 LoadD_unalignedNode( Node *c, Node *mem, Node *adr, const TypePtr* at ) 372 LoadD_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo)
359 : LoadDNode(c,mem,adr,at) {} 373 : LoadDNode(c, mem, adr, at, Type::DOUBLE, mo) {}
360 virtual int Opcode() const; 374 virtual int Opcode() const;
361 }; 375 };
362 376
363 //------------------------------LoadPNode-------------------------------------- 377 //------------------------------LoadPNode--------------------------------------
364 // Load a pointer from memory (either object or array) 378 // Load a pointer from memory (either object or array)
365 class LoadPNode : public LoadNode { 379 class LoadPNode : public LoadNode {
366 public: 380 public:
367 LoadPNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t ) 381 LoadPNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t, MemOrd mo)
368 : LoadNode(c,mem,adr,at,t) {} 382 : LoadNode(c, mem, adr, at, t, mo) {}
369 virtual int Opcode() const; 383 virtual int Opcode() const;
370 virtual uint ideal_reg() const { return Op_RegP; } 384 virtual uint ideal_reg() const { return Op_RegP; }
371 virtual int store_Opcode() const { return Op_StoreP; } 385 virtual int store_Opcode() const { return Op_StoreP; }
372 virtual BasicType memory_type() const { return T_ADDRESS; } 386 virtual BasicType memory_type() const { return T_ADDRESS; }
373 // depends_only_on_test is almost always true, and needs to be almost always 387 // depends_only_on_test is almost always true, and needs to be almost always
385 399
386 //------------------------------LoadNNode-------------------------------------- 400 //------------------------------LoadNNode--------------------------------------
387 // Load a narrow oop from memory (either object or array) 401 // Load a narrow oop from memory (either object or array)
388 class LoadNNode : public LoadNode { 402 class LoadNNode : public LoadNode {
389 public: 403 public:
390 LoadNNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t ) 404 LoadNNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t, MemOrd mo)
391 : LoadNode(c,mem,adr,at,t) {} 405 : LoadNode(c, mem, adr, at, t, mo) {}
392 virtual int Opcode() const; 406 virtual int Opcode() const;
393 virtual uint ideal_reg() const { return Op_RegN; } 407 virtual uint ideal_reg() const { return Op_RegN; }
394 virtual int store_Opcode() const { return Op_StoreN; } 408 virtual int store_Opcode() const { return Op_StoreN; }
395 virtual BasicType memory_type() const { return T_NARROWOOP; } 409 virtual BasicType memory_type() const { return T_NARROWOOP; }
396 // depends_only_on_test is almost always true, and needs to be almost always 410 // depends_only_on_test is almost always true, and needs to be almost always
407 421
408 //------------------------------LoadKlassNode---------------------------------- 422 //------------------------------LoadKlassNode----------------------------------
409 // Load a Klass from an object 423 // Load a Klass from an object
410 class LoadKlassNode : public LoadPNode { 424 class LoadKlassNode : public LoadPNode {
411 public: 425 public:
412 LoadKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk ) 426 LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo)
413 : LoadPNode(c,mem,adr,at,tk) {} 427 : LoadPNode(c, mem, adr, at, tk, mo) {}
414 virtual int Opcode() const; 428 virtual int Opcode() const;
415 virtual const Type *Value( PhaseTransform *phase ) const; 429 virtual const Type *Value( PhaseTransform *phase ) const;
416 virtual Node *Identity( PhaseTransform *phase ); 430 virtual Node *Identity( PhaseTransform *phase );
417 virtual bool depends_only_on_test() const { return true; } 431 virtual bool depends_only_on_test() const { return true; }
418 432
423 437
424 //------------------------------LoadNKlassNode--------------------------------- 438 //------------------------------LoadNKlassNode---------------------------------
425 // Load a narrow Klass from an object. 439 // Load a narrow Klass from an object.
426 class LoadNKlassNode : public LoadNNode { 440 class LoadNKlassNode : public LoadNNode {
427 public: 441 public:
428 LoadNKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk ) 442 LoadNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk, MemOrd mo)
429 : LoadNNode(c,mem,adr,at,tk) {} 443 : LoadNNode(c, mem, adr, at, tk, mo) {}
430 virtual int Opcode() const; 444 virtual int Opcode() const;
431 virtual uint ideal_reg() const { return Op_RegN; } 445 virtual uint ideal_reg() const { return Op_RegN; }
432 virtual int store_Opcode() const { return Op_StoreNKlass; } 446 virtual int store_Opcode() const { return Op_StoreNKlass; }
433 virtual BasicType memory_type() const { return T_NARROWKLASS; } 447 virtual BasicType memory_type() const { return T_NARROWKLASS; }
434 448
439 453
440 454
441 //------------------------------StoreNode-------------------------------------- 455 //------------------------------StoreNode--------------------------------------
442 // Store value; requires Store, Address and Value 456 // Store value; requires Store, Address and Value
443 class StoreNode : public MemNode { 457 class StoreNode : public MemNode {
458 private:
459 // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish
460 // stores that can be reordered, and such requiring release semantics to
461 // adhere to the Java specification. The required behaviour is stored in
462 // this field.
463 const MemOrd _mo;
464 // Needed for proper cloning.
465 virtual uint size_of() const { return sizeof(*this); }
444 protected: 466 protected:
445 virtual uint cmp( const Node &n ) const; 467 virtual uint cmp( const Node &n ) const;
446 virtual bool depends_only_on_test() const { return false; } 468 virtual bool depends_only_on_test() const { return false; }
447 469
448 Node *Ideal_masked_input (PhaseGVN *phase, uint mask); 470 Node *Ideal_masked_input (PhaseGVN *phase, uint mask);
449 Node *Ideal_sign_extended_input(PhaseGVN *phase, int num_bits); 471 Node *Ideal_sign_extended_input(PhaseGVN *phase, int num_bits);
450 472
451 public: 473 public:
452 StoreNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) 474 // We must ensure that stores of object references will be visible
453 : MemNode(c,mem,adr,at,val) { 475 // only after the object's initialization. So the callers of this
476 // procedure must indicate that the store requires `release'
477 // semantics, if the stored value is an object reference that might
478 // point to a new object and may become externally visible.
479 StoreNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
480 : MemNode(c, mem, adr, at, val), _mo(mo) {
454 init_class_id(Class_Store); 481 init_class_id(Class_Store);
455 } 482 }
456 StoreNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store ) 483 StoreNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, MemOrd mo)
457 : MemNode(c,mem,adr,at,val,oop_store) { 484 : MemNode(c, mem, adr, at, val, oop_store), _mo(mo) {
458 init_class_id(Class_Store); 485 init_class_id(Class_Store);
459 } 486 }
460 487
461 // Polymorphic factory method: 488 inline bool is_unordered() const { return !is_release(); }
462 static StoreNode* make( PhaseGVN& gvn, Node *c, Node *mem, Node *adr, 489 inline bool is_release() const {
463 const TypePtr* at, Node *val, BasicType bt ); 490 assert((_mo == unordered || _mo == release), "unexpected");
491 return _mo == release;
492 }
493
494 // Conservatively release stores of object references in order to
495 // ensure visibility of object initialization.
496 static inline MemOrd release_if_reference(const BasicType t) {
497 const MemOrd mo = (t == T_ARRAY ||
498 t == T_ADDRESS || // Might be the address of an object reference (`boxing').
499 t == T_OBJECT) ? release : unordered;
500 return mo;
501 }
502
503 // Polymorphic factory method
504 //
505 // We must ensure that stores of object references will be visible
506 // only after the object's initialization. So the callers of this
507 // procedure must indicate that the store requires `release'
508 // semantics, if the stored value is an object reference that might
509 // point to a new object and may become externally visible.
510 static StoreNode* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr,
511 const TypePtr* at, Node *val, BasicType bt, MemOrd mo);
464 512
465 virtual uint hash() const; // Check the type 513 virtual uint hash() const; // Check the type
466 514
467 // If the store is to Field memory and the pointer is non-null, we can 515 // If the store is to Field memory and the pointer is non-null, we can
468 // zero out the control input. 516 // zero out the control input.
489 537
490 //------------------------------StoreBNode------------------------------------- 538 //------------------------------StoreBNode-------------------------------------
491 // Store byte to memory 539 // Store byte to memory
492 class StoreBNode : public StoreNode { 540 class StoreBNode : public StoreNode {
493 public: 541 public:
494 StoreBNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 542 StoreBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
543 : StoreNode(c, mem, adr, at, val, mo) {}
495 virtual int Opcode() const; 544 virtual int Opcode() const;
496 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 545 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
497 virtual BasicType memory_type() const { return T_BYTE; } 546 virtual BasicType memory_type() const { return T_BYTE; }
498 }; 547 };
499 548
500 //------------------------------StoreCNode------------------------------------- 549 //------------------------------StoreCNode-------------------------------------
501 // Store char/short to memory 550 // Store char/short to memory
502 class StoreCNode : public StoreNode { 551 class StoreCNode : public StoreNode {
503 public: 552 public:
504 StoreCNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 553 StoreCNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
554 : StoreNode(c, mem, adr, at, val, mo) {}
505 virtual int Opcode() const; 555 virtual int Opcode() const;
506 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 556 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
507 virtual BasicType memory_type() const { return T_CHAR; } 557 virtual BasicType memory_type() const { return T_CHAR; }
508 }; 558 };
509 559
510 //------------------------------StoreINode------------------------------------- 560 //------------------------------StoreINode-------------------------------------
511 // Store int to memory 561 // Store int to memory
512 class StoreINode : public StoreNode { 562 class StoreINode : public StoreNode {
513 public: 563 public:
514 StoreINode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 564 StoreINode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
565 : StoreNode(c, mem, adr, at, val, mo) {}
515 virtual int Opcode() const; 566 virtual int Opcode() const;
516 virtual BasicType memory_type() const { return T_INT; } 567 virtual BasicType memory_type() const { return T_INT; }
517 }; 568 };
518 569
519 //------------------------------StoreLNode------------------------------------- 570 //------------------------------StoreLNode-------------------------------------
526 } 577 }
527 virtual uint size_of() const { return sizeof(*this); } 578 virtual uint size_of() const { return sizeof(*this); }
528 const bool _require_atomic_access; // is piecewise store forbidden? 579 const bool _require_atomic_access; // is piecewise store forbidden?
529 580
530 public: 581 public:
531 StoreLNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, 582 StoreLNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo, bool require_atomic_access = false)
532 bool require_atomic_access = false ) 583 : StoreNode(c, mem, adr, at, val, mo), _require_atomic_access(require_atomic_access) {}
533 : StoreNode(c,mem,adr,at,val)
534 , _require_atomic_access(require_atomic_access)
535 {}
536 virtual int Opcode() const; 584 virtual int Opcode() const;
537 virtual BasicType memory_type() const { return T_LONG; } 585 virtual BasicType memory_type() const { return T_LONG; }
538 bool require_atomic_access() { return _require_atomic_access; } 586 bool require_atomic_access() { return _require_atomic_access; }
539 static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val); 587 static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo);
540 #ifndef PRODUCT 588 #ifndef PRODUCT
541 virtual void dump_spec(outputStream *st) const { 589 virtual void dump_spec(outputStream *st) const {
542 StoreNode::dump_spec(st); 590 StoreNode::dump_spec(st);
543 if (_require_atomic_access) st->print(" Atomic!"); 591 if (_require_atomic_access) st->print(" Atomic!");
544 } 592 }
547 595
548 //------------------------------StoreFNode------------------------------------- 596 //------------------------------StoreFNode-------------------------------------
549 // Store float to memory 597 // Store float to memory
550 class StoreFNode : public StoreNode { 598 class StoreFNode : public StoreNode {
551 public: 599 public:
552 StoreFNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 600 StoreFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
601 : StoreNode(c, mem, adr, at, val, mo) {}
553 virtual int Opcode() const; 602 virtual int Opcode() const;
554 virtual BasicType memory_type() const { return T_FLOAT; } 603 virtual BasicType memory_type() const { return T_FLOAT; }
555 }; 604 };
556 605
557 //------------------------------StoreDNode------------------------------------- 606 //------------------------------StoreDNode-------------------------------------
558 // Store double to memory 607 // Store double to memory
559 class StoreDNode : public StoreNode { 608 class StoreDNode : public StoreNode {
560 public: 609 public:
561 StoreDNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 610 StoreDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
611 : StoreNode(c, mem, adr, at, val, mo) {}
562 virtual int Opcode() const; 612 virtual int Opcode() const;
563 virtual BasicType memory_type() const { return T_DOUBLE; } 613 virtual BasicType memory_type() const { return T_DOUBLE; }
564 }; 614 };
565 615
566 //------------------------------StorePNode------------------------------------- 616 //------------------------------StorePNode-------------------------------------
567 // Store pointer to memory 617 // Store pointer to memory
568 class StorePNode : public StoreNode { 618 class StorePNode : public StoreNode {
569 public: 619 public:
570 StorePNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 620 StorePNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
621 : StoreNode(c, mem, adr, at, val, mo) {}
571 virtual int Opcode() const; 622 virtual int Opcode() const;
572 virtual BasicType memory_type() const { return T_ADDRESS; } 623 virtual BasicType memory_type() const { return T_ADDRESS; }
573 }; 624 };
574 625
575 //------------------------------StoreNNode------------------------------------- 626 //------------------------------StoreNNode-------------------------------------
576 // Store narrow oop to memory 627 // Store narrow oop to memory
577 class StoreNNode : public StoreNode { 628 class StoreNNode : public StoreNode {
578 public: 629 public:
579 StoreNNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 630 StoreNNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
631 : StoreNode(c, mem, adr, at, val, mo) {}
580 virtual int Opcode() const; 632 virtual int Opcode() const;
581 virtual BasicType memory_type() const { return T_NARROWOOP; } 633 virtual BasicType memory_type() const { return T_NARROWOOP; }
582 }; 634 };
583 635
584 //------------------------------StoreNKlassNode-------------------------------------- 636 //------------------------------StoreNKlassNode--------------------------------------
585 // Store narrow klass to memory 637 // Store narrow klass to memory
586 class StoreNKlassNode : public StoreNNode { 638 class StoreNKlassNode : public StoreNNode {
587 public: 639 public:
588 StoreNKlassNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNNode(c,mem,adr,at,val) {} 640 StoreNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
641 : StoreNNode(c, mem, adr, at, val, mo) {}
589 virtual int Opcode() const; 642 virtual int Opcode() const;
590 virtual BasicType memory_type() const { return T_NARROWKLASS; } 643 virtual BasicType memory_type() const { return T_NARROWKLASS; }
591 }; 644 };
592 645
593 //------------------------------StoreCMNode----------------------------------- 646 //------------------------------StoreCMNode-----------------------------------
604 virtual uint size_of() const { return sizeof(*this); } 657 virtual uint size_of() const { return sizeof(*this); }
605 int _oop_alias_idx; // The alias_idx of OopStore 658 int _oop_alias_idx; // The alias_idx of OopStore
606 659
607 public: 660 public:
608 StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, int oop_alias_idx ) : 661 StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, int oop_alias_idx ) :
609 StoreNode(c,mem,adr,at,val,oop_store), 662 StoreNode(c, mem, adr, at, val, oop_store, MemNode::release),
610 _oop_alias_idx(oop_alias_idx) { 663 _oop_alias_idx(oop_alias_idx) {
611 assert(_oop_alias_idx >= Compile::AliasIdxRaw || 664 assert(_oop_alias_idx >= Compile::AliasIdxRaw ||
612 _oop_alias_idx == Compile::AliasIdxBot && Compile::current()->AliasLevel() == 0, 665 _oop_alias_idx == Compile::AliasIdxBot && Compile::current()->AliasLevel() == 0,
613 "bad oop alias idx"); 666 "bad oop alias idx");
614 } 667 }
624 // Load-locked a pointer from memory (either object or array). 677 // Load-locked a pointer from memory (either object or array).
625 // On Sparc & Intel this is implemented as a normal pointer load. 678 // On Sparc & Intel this is implemented as a normal pointer load.
626 // On PowerPC and friends it's a real load-locked. 679 // On PowerPC and friends it's a real load-locked.
627 class LoadPLockedNode : public LoadPNode { 680 class LoadPLockedNode : public LoadPNode {
628 public: 681 public:
629 LoadPLockedNode( Node *c, Node *mem, Node *adr ) 682 LoadPLockedNode(Node *c, Node *mem, Node *adr, MemOrd mo)
630 : LoadPNode(c,mem,adr,TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM) {} 683 : LoadPNode(c, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, mo) {}
631 virtual int Opcode() const; 684 virtual int Opcode() const;
632 virtual int store_Opcode() const { return Op_StorePConditional; } 685 virtual int store_Opcode() const { return Op_StorePConditional; }
633 virtual bool depends_only_on_test() const { return true; } 686 virtual bool depends_only_on_test() const { return true; }
634 }; 687 };
635 688