Mercurial > hg > truffle
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 |