Mercurial > hg > graal-compiler
comparison src/share/vm/opto/memnode.hpp @ 18041:52b4284cb496
Merge with jdk8u20-b26
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Wed, 15 Oct 2014 16:02:50 +0200 |
parents | 89152779163c |
children | 7848fc12602b |
comparison
equal
deleted
inserted
replaced
17606:45d7b2c7029d | 18041:52b4284cb496 |
---|---|
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. |
219 | 235 |
220 //------------------------------LoadBNode-------------------------------------- | 236 //------------------------------LoadBNode-------------------------------------- |
221 // Load a byte (8bits signed) from memory | 237 // Load a byte (8bits signed) from memory |
222 class LoadBNode : public LoadNode { | 238 class LoadBNode : public LoadNode { |
223 public: | 239 public: |
224 LoadBNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::BYTE ) | 240 LoadBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo) |
225 : LoadNode(c,mem,adr,at,ti) {} | 241 : LoadNode(c, mem, adr, at, ti, mo) {} |
226 virtual int Opcode() const; | 242 virtual int Opcode() const; |
227 virtual uint ideal_reg() const { return Op_RegI; } | 243 virtual uint ideal_reg() const { return Op_RegI; } |
228 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | 244 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
229 virtual const Type *Value(PhaseTransform *phase) const; | 245 virtual const Type *Value(PhaseTransform *phase) const; |
230 virtual int store_Opcode() const { return Op_StoreB; } | 246 virtual int store_Opcode() const { return Op_StoreB; } |
233 | 249 |
234 //------------------------------LoadUBNode------------------------------------- | 250 //------------------------------LoadUBNode------------------------------------- |
235 // Load a unsigned byte (8bits unsigned) from memory | 251 // Load a unsigned byte (8bits unsigned) from memory |
236 class LoadUBNode : public LoadNode { | 252 class LoadUBNode : public LoadNode { |
237 public: | 253 public: |
238 LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti = TypeInt::UBYTE ) | 254 LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti, MemOrd mo) |
239 : LoadNode(c, mem, adr, at, ti) {} | 255 : LoadNode(c, mem, adr, at, ti, mo) {} |
240 virtual int Opcode() const; | 256 virtual int Opcode() const; |
241 virtual uint ideal_reg() const { return Op_RegI; } | 257 virtual uint ideal_reg() const { return Op_RegI; } |
242 virtual Node* Ideal(PhaseGVN *phase, bool can_reshape); | 258 virtual Node* Ideal(PhaseGVN *phase, bool can_reshape); |
243 virtual const Type *Value(PhaseTransform *phase) const; | 259 virtual const Type *Value(PhaseTransform *phase) const; |
244 virtual int store_Opcode() const { return Op_StoreB; } | 260 virtual int store_Opcode() const { return Op_StoreB; } |
247 | 263 |
248 //------------------------------LoadUSNode------------------------------------- | 264 //------------------------------LoadUSNode------------------------------------- |
249 // Load an unsigned short/char (16bits unsigned) from memory | 265 // Load an unsigned short/char (16bits unsigned) from memory |
250 class LoadUSNode : public LoadNode { | 266 class LoadUSNode : public LoadNode { |
251 public: | 267 public: |
252 LoadUSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR ) | 268 LoadUSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo) |
253 : LoadNode(c,mem,adr,at,ti) {} | 269 : LoadNode(c, mem, adr, at, ti, mo) {} |
254 virtual int Opcode() const; | 270 virtual int Opcode() const; |
255 virtual uint ideal_reg() const { return Op_RegI; } | 271 virtual uint ideal_reg() const { return Op_RegI; } |
256 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | 272 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
257 virtual const Type *Value(PhaseTransform *phase) const; | 273 virtual const Type *Value(PhaseTransform *phase) const; |
258 virtual int store_Opcode() const { return Op_StoreC; } | 274 virtual int store_Opcode() const { return Op_StoreC; } |
261 | 277 |
262 //------------------------------LoadSNode-------------------------------------- | 278 //------------------------------LoadSNode-------------------------------------- |
263 // Load a short (16bits signed) from memory | 279 // Load a short (16bits signed) from memory |
264 class LoadSNode : public LoadNode { | 280 class LoadSNode : public LoadNode { |
265 public: | 281 public: |
266 LoadSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT ) | 282 LoadSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo) |
267 : LoadNode(c,mem,adr,at,ti) {} | 283 : LoadNode(c, mem, adr, at, ti, mo) {} |
268 virtual int Opcode() const; | 284 virtual int Opcode() const; |
269 virtual uint ideal_reg() const { return Op_RegI; } | 285 virtual uint ideal_reg() const { return Op_RegI; } |
270 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | 286 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
271 virtual const Type *Value(PhaseTransform *phase) const; | 287 virtual const Type *Value(PhaseTransform *phase) const; |
272 virtual int store_Opcode() const { return Op_StoreC; } | 288 virtual int store_Opcode() const { return Op_StoreC; } |
275 | 291 |
276 //------------------------------LoadINode-------------------------------------- | 292 //------------------------------LoadINode-------------------------------------- |
277 // Load an integer from memory | 293 // Load an integer from memory |
278 class LoadINode : public LoadNode { | 294 class LoadINode : public LoadNode { |
279 public: | 295 public: |
280 LoadINode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::INT ) | 296 LoadINode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo) |
281 : LoadNode(c,mem,adr,at,ti) {} | 297 : LoadNode(c, mem, adr, at, ti, mo) {} |
282 virtual int Opcode() const; | 298 virtual int Opcode() const; |
283 virtual uint ideal_reg() const { return Op_RegI; } | 299 virtual uint ideal_reg() const { return Op_RegI; } |
284 virtual int store_Opcode() const { return Op_StoreI; } | 300 virtual int store_Opcode() const { return Op_StoreI; } |
285 virtual BasicType memory_type() const { return T_INT; } | 301 virtual BasicType memory_type() const { return T_INT; } |
286 }; | 302 }; |
287 | 303 |
288 //------------------------------LoadRangeNode---------------------------------- | 304 //------------------------------LoadRangeNode---------------------------------- |
289 // Load an array length from the array | 305 // Load an array length from the array |
290 class LoadRangeNode : public LoadINode { | 306 class LoadRangeNode : public LoadINode { |
291 public: | 307 public: |
292 LoadRangeNode( Node *c, Node *mem, Node *adr, const TypeInt *ti = TypeInt::POS ) | 308 LoadRangeNode(Node *c, Node *mem, Node *adr, const TypeInt *ti = TypeInt::POS) |
293 : LoadINode(c,mem,adr,TypeAryPtr::RANGE,ti) {} | 309 : LoadINode(c, mem, adr, TypeAryPtr::RANGE, ti, MemNode::unordered) {} |
294 virtual int Opcode() const; | 310 virtual int Opcode() const; |
295 virtual const Type *Value( PhaseTransform *phase ) const; | 311 virtual const Type *Value( PhaseTransform *phase ) const; |
296 virtual Node *Identity( PhaseTransform *phase ); | 312 virtual Node *Identity( PhaseTransform *phase ); |
297 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | 313 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
298 }; | 314 }; |
307 } | 323 } |
308 virtual uint size_of() const { return sizeof(*this); } | 324 virtual uint size_of() const { return sizeof(*this); } |
309 const bool _require_atomic_access; // is piecewise load forbidden? | 325 const bool _require_atomic_access; // is piecewise load forbidden? |
310 | 326 |
311 public: | 327 public: |
312 LoadLNode( Node *c, Node *mem, Node *adr, const TypePtr* at, | 328 LoadLNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeLong *tl, |
313 const TypeLong *tl = TypeLong::LONG, | 329 MemOrd mo, bool require_atomic_access = false) |
314 bool require_atomic_access = false ) | 330 : LoadNode(c, mem, adr, at, tl, mo), _require_atomic_access(require_atomic_access) {} |
315 : LoadNode(c,mem,adr,at,tl) | |
316 , _require_atomic_access(require_atomic_access) | |
317 {} | |
318 virtual int Opcode() const; | 331 virtual int Opcode() const; |
319 virtual uint ideal_reg() const { return Op_RegL; } | 332 virtual uint ideal_reg() const { return Op_RegL; } |
320 virtual int store_Opcode() const { return Op_StoreL; } | 333 virtual int store_Opcode() const { return Op_StoreL; } |
321 virtual BasicType memory_type() const { return T_LONG; } | 334 virtual BasicType memory_type() const { return T_LONG; } |
322 bool require_atomic_access() { return _require_atomic_access; } | 335 bool require_atomic_access() { return _require_atomic_access; } |
323 static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt); | 336 static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, |
337 const Type* rt, MemOrd mo); | |
324 #ifndef PRODUCT | 338 #ifndef PRODUCT |
325 virtual void dump_spec(outputStream *st) const { | 339 virtual void dump_spec(outputStream *st) const { |
326 LoadNode::dump_spec(st); | 340 LoadNode::dump_spec(st); |
327 if (_require_atomic_access) st->print(" Atomic!"); | 341 if (_require_atomic_access) st->print(" Atomic!"); |
328 } | 342 } |
331 | 345 |
332 //------------------------------LoadL_unalignedNode---------------------------- | 346 //------------------------------LoadL_unalignedNode---------------------------- |
333 // Load a long from unaligned memory | 347 // Load a long from unaligned memory |
334 class LoadL_unalignedNode : public LoadLNode { | 348 class LoadL_unalignedNode : public LoadLNode { |
335 public: | 349 public: |
336 LoadL_unalignedNode( Node *c, Node *mem, Node *adr, const TypePtr* at ) | 350 LoadL_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo) |
337 : LoadLNode(c,mem,adr,at) {} | 351 : LoadLNode(c, mem, adr, at, TypeLong::LONG, mo) {} |
338 virtual int Opcode() const; | 352 virtual int Opcode() const; |
339 }; | 353 }; |
340 | 354 |
341 //------------------------------LoadFNode-------------------------------------- | 355 //------------------------------LoadFNode-------------------------------------- |
342 // Load a float (64 bits) from memory | 356 // Load a float (64 bits) from memory |
343 class LoadFNode : public LoadNode { | 357 class LoadFNode : public LoadNode { |
344 public: | 358 public: |
345 LoadFNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t = Type::FLOAT ) | 359 LoadFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo) |
346 : LoadNode(c,mem,adr,at,t) {} | 360 : LoadNode(c, mem, adr, at, t, mo) {} |
347 virtual int Opcode() const; | 361 virtual int Opcode() const; |
348 virtual uint ideal_reg() const { return Op_RegF; } | 362 virtual uint ideal_reg() const { return Op_RegF; } |
349 virtual int store_Opcode() const { return Op_StoreF; } | 363 virtual int store_Opcode() const { return Op_StoreF; } |
350 virtual BasicType memory_type() const { return T_FLOAT; } | 364 virtual BasicType memory_type() const { return T_FLOAT; } |
351 }; | 365 }; |
352 | 366 |
353 //------------------------------LoadDNode-------------------------------------- | 367 //------------------------------LoadDNode-------------------------------------- |
354 // Load a double (64 bits) from memory | 368 // Load a double (64 bits) from memory |
355 class LoadDNode : public LoadNode { | 369 class LoadDNode : public LoadNode { |
356 public: | 370 public: |
357 LoadDNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t = Type::DOUBLE ) | 371 LoadDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo) |
358 : LoadNode(c,mem,adr,at,t) {} | 372 : LoadNode(c, mem, adr, at, t, mo) {} |
359 virtual int Opcode() const; | 373 virtual int Opcode() const; |
360 virtual uint ideal_reg() const { return Op_RegD; } | 374 virtual uint ideal_reg() const { return Op_RegD; } |
361 virtual int store_Opcode() const { return Op_StoreD; } | 375 virtual int store_Opcode() const { return Op_StoreD; } |
362 virtual BasicType memory_type() const { return T_DOUBLE; } | 376 virtual BasicType memory_type() const { return T_DOUBLE; } |
363 }; | 377 }; |
364 | 378 |
365 //------------------------------LoadD_unalignedNode---------------------------- | 379 //------------------------------LoadD_unalignedNode---------------------------- |
366 // Load a double from unaligned memory | 380 // Load a double from unaligned memory |
367 class LoadD_unalignedNode : public LoadDNode { | 381 class LoadD_unalignedNode : public LoadDNode { |
368 public: | 382 public: |
369 LoadD_unalignedNode( Node *c, Node *mem, Node *adr, const TypePtr* at ) | 383 LoadD_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo) |
370 : LoadDNode(c,mem,adr,at) {} | 384 : LoadDNode(c, mem, adr, at, Type::DOUBLE, mo) {} |
371 virtual int Opcode() const; | 385 virtual int Opcode() const; |
372 }; | 386 }; |
373 | 387 |
374 //------------------------------LoadPNode-------------------------------------- | 388 //------------------------------LoadPNode-------------------------------------- |
375 // Load a pointer from memory (either object or array) | 389 // Load a pointer from memory (either object or array) |
376 class LoadPNode : public LoadNode { | 390 class LoadPNode : public LoadNode { |
377 public: | 391 public: |
378 LoadPNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t ) | 392 LoadPNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t, MemOrd mo) |
379 : LoadNode(c,mem,adr,at,t) {} | 393 : LoadNode(c, mem, adr, at, t, mo) {} |
380 virtual int Opcode() const; | 394 virtual int Opcode() const; |
381 virtual uint ideal_reg() const { return Op_RegP; } | 395 virtual uint ideal_reg() const { return Op_RegP; } |
382 virtual int store_Opcode() const { return Op_StoreP; } | 396 virtual int store_Opcode() const { return Op_StoreP; } |
383 virtual BasicType memory_type() const { return T_ADDRESS; } | 397 virtual BasicType memory_type() const { return T_ADDRESS; } |
384 }; | 398 }; |
386 | 400 |
387 //------------------------------LoadNNode-------------------------------------- | 401 //------------------------------LoadNNode-------------------------------------- |
388 // Load a narrow oop from memory (either object or array) | 402 // Load a narrow oop from memory (either object or array) |
389 class LoadNNode : public LoadNode { | 403 class LoadNNode : public LoadNode { |
390 public: | 404 public: |
391 LoadNNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t ) | 405 LoadNNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t, MemOrd mo) |
392 : LoadNode(c,mem,adr,at,t) {} | 406 : LoadNode(c, mem, adr, at, t, mo) {} |
393 virtual int Opcode() const; | 407 virtual int Opcode() const; |
394 virtual uint ideal_reg() const { return Op_RegN; } | 408 virtual uint ideal_reg() const { return Op_RegN; } |
395 virtual int store_Opcode() const { return Op_StoreN; } | 409 virtual int store_Opcode() const { return Op_StoreN; } |
396 virtual BasicType memory_type() const { return T_NARROWOOP; } | 410 virtual BasicType memory_type() const { return T_NARROWOOP; } |
397 }; | 411 }; |
398 | 412 |
399 //------------------------------LoadKlassNode---------------------------------- | 413 //------------------------------LoadKlassNode---------------------------------- |
400 // Load a Klass from an object | 414 // Load a Klass from an object |
401 class LoadKlassNode : public LoadPNode { | 415 class LoadKlassNode : public LoadPNode { |
402 public: | 416 public: |
403 LoadKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk ) | 417 LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo) |
404 : LoadPNode(c,mem,adr,at,tk) {} | 418 : LoadPNode(c, mem, adr, at, tk, mo) {} |
405 virtual int Opcode() const; | 419 virtual int Opcode() const; |
406 virtual const Type *Value( PhaseTransform *phase ) const; | 420 virtual const Type *Value( PhaseTransform *phase ) const; |
407 virtual Node *Identity( PhaseTransform *phase ); | 421 virtual Node *Identity( PhaseTransform *phase ); |
408 virtual bool depends_only_on_test() const { return true; } | 422 virtual bool depends_only_on_test() const { return true; } |
409 | 423 |
414 | 428 |
415 //------------------------------LoadNKlassNode--------------------------------- | 429 //------------------------------LoadNKlassNode--------------------------------- |
416 // Load a narrow Klass from an object. | 430 // Load a narrow Klass from an object. |
417 class LoadNKlassNode : public LoadNNode { | 431 class LoadNKlassNode : public LoadNNode { |
418 public: | 432 public: |
419 LoadNKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk ) | 433 LoadNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk, MemOrd mo) |
420 : LoadNNode(c,mem,adr,at,tk) {} | 434 : LoadNNode(c, mem, adr, at, tk, mo) {} |
421 virtual int Opcode() const; | 435 virtual int Opcode() const; |
422 virtual uint ideal_reg() const { return Op_RegN; } | 436 virtual uint ideal_reg() const { return Op_RegN; } |
423 virtual int store_Opcode() const { return Op_StoreNKlass; } | 437 virtual int store_Opcode() const { return Op_StoreNKlass; } |
424 virtual BasicType memory_type() const { return T_NARROWKLASS; } | 438 virtual BasicType memory_type() const { return T_NARROWKLASS; } |
425 | 439 |
430 | 444 |
431 | 445 |
432 //------------------------------StoreNode-------------------------------------- | 446 //------------------------------StoreNode-------------------------------------- |
433 // Store value; requires Store, Address and Value | 447 // Store value; requires Store, Address and Value |
434 class StoreNode : public MemNode { | 448 class StoreNode : public MemNode { |
449 private: | |
450 // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish | |
451 // stores that can be reordered, and such requiring release semantics to | |
452 // adhere to the Java specification. The required behaviour is stored in | |
453 // this field. | |
454 const MemOrd _mo; | |
455 // Needed for proper cloning. | |
456 virtual uint size_of() const { return sizeof(*this); } | |
435 protected: | 457 protected: |
436 virtual uint cmp( const Node &n ) const; | 458 virtual uint cmp( const Node &n ) const; |
437 virtual bool depends_only_on_test() const { return false; } | 459 virtual bool depends_only_on_test() const { return false; } |
438 | 460 |
439 Node *Ideal_masked_input (PhaseGVN *phase, uint mask); | 461 Node *Ideal_masked_input (PhaseGVN *phase, uint mask); |
440 Node *Ideal_sign_extended_input(PhaseGVN *phase, int num_bits); | 462 Node *Ideal_sign_extended_input(PhaseGVN *phase, int num_bits); |
441 | 463 |
442 public: | 464 public: |
443 StoreNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) | 465 // We must ensure that stores of object references will be visible |
444 : MemNode(c,mem,adr,at,val) { | 466 // only after the object's initialization. So the callers of this |
467 // procedure must indicate that the store requires `release' | |
468 // semantics, if the stored value is an object reference that might | |
469 // point to a new object and may become externally visible. | |
470 StoreNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) | |
471 : MemNode(c, mem, adr, at, val), _mo(mo) { | |
445 init_class_id(Class_Store); | 472 init_class_id(Class_Store); |
446 } | 473 } |
447 StoreNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store ) | 474 StoreNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, MemOrd mo) |
448 : MemNode(c,mem,adr,at,val,oop_store) { | 475 : MemNode(c, mem, adr, at, val, oop_store), _mo(mo) { |
449 init_class_id(Class_Store); | 476 init_class_id(Class_Store); |
450 } | 477 } |
451 | 478 |
452 // Polymorphic factory method: | 479 inline bool is_unordered() const { return !is_release(); } |
453 static StoreNode* make( PhaseGVN& gvn, Node *c, Node *mem, Node *adr, | 480 inline bool is_release() const { |
454 const TypePtr* at, Node *val, BasicType bt ); | 481 assert((_mo == unordered || _mo == release), "unexpected"); |
482 return _mo == release; | |
483 } | |
484 | |
485 // Conservatively release stores of object references in order to | |
486 // ensure visibility of object initialization. | |
487 static inline MemOrd release_if_reference(const BasicType t) { | |
488 const MemOrd mo = (t == T_ARRAY || | |
489 t == T_ADDRESS || // Might be the address of an object reference (`boxing'). | |
490 t == T_OBJECT) ? release : unordered; | |
491 return mo; | |
492 } | |
493 | |
494 // Polymorphic factory method | |
495 // | |
496 // We must ensure that stores of object references will be visible | |
497 // only after the object's initialization. So the callers of this | |
498 // procedure must indicate that the store requires `release' | |
499 // semantics, if the stored value is an object reference that might | |
500 // point to a new object and may become externally visible. | |
501 static StoreNode* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr, | |
502 const TypePtr* at, Node *val, BasicType bt, MemOrd mo); | |
455 | 503 |
456 virtual uint hash() const; // Check the type | 504 virtual uint hash() const; // Check the type |
457 | 505 |
458 // If the store is to Field memory and the pointer is non-null, we can | 506 // If the store is to Field memory and the pointer is non-null, we can |
459 // zero out the control input. | 507 // zero out the control input. |
480 | 528 |
481 //------------------------------StoreBNode------------------------------------- | 529 //------------------------------StoreBNode------------------------------------- |
482 // Store byte to memory | 530 // Store byte to memory |
483 class StoreBNode : public StoreNode { | 531 class StoreBNode : public StoreNode { |
484 public: | 532 public: |
485 StoreBNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | 533 StoreBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
534 : StoreNode(c, mem, adr, at, val, mo) {} | |
486 virtual int Opcode() const; | 535 virtual int Opcode() const; |
487 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | 536 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
488 virtual BasicType memory_type() const { return T_BYTE; } | 537 virtual BasicType memory_type() const { return T_BYTE; } |
489 }; | 538 }; |
490 | 539 |
491 //------------------------------StoreCNode------------------------------------- | 540 //------------------------------StoreCNode------------------------------------- |
492 // Store char/short to memory | 541 // Store char/short to memory |
493 class StoreCNode : public StoreNode { | 542 class StoreCNode : public StoreNode { |
494 public: | 543 public: |
495 StoreCNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | 544 StoreCNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
545 : StoreNode(c, mem, adr, at, val, mo) {} | |
496 virtual int Opcode() const; | 546 virtual int Opcode() const; |
497 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | 547 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
498 virtual BasicType memory_type() const { return T_CHAR; } | 548 virtual BasicType memory_type() const { return T_CHAR; } |
499 }; | 549 }; |
500 | 550 |
501 //------------------------------StoreINode------------------------------------- | 551 //------------------------------StoreINode------------------------------------- |
502 // Store int to memory | 552 // Store int to memory |
503 class StoreINode : public StoreNode { | 553 class StoreINode : public StoreNode { |
504 public: | 554 public: |
505 StoreINode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | 555 StoreINode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
556 : StoreNode(c, mem, adr, at, val, mo) {} | |
506 virtual int Opcode() const; | 557 virtual int Opcode() const; |
507 virtual BasicType memory_type() const { return T_INT; } | 558 virtual BasicType memory_type() const { return T_INT; } |
508 }; | 559 }; |
509 | 560 |
510 //------------------------------StoreLNode------------------------------------- | 561 //------------------------------StoreLNode------------------------------------- |
517 } | 568 } |
518 virtual uint size_of() const { return sizeof(*this); } | 569 virtual uint size_of() const { return sizeof(*this); } |
519 const bool _require_atomic_access; // is piecewise store forbidden? | 570 const bool _require_atomic_access; // is piecewise store forbidden? |
520 | 571 |
521 public: | 572 public: |
522 StoreLNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, | 573 StoreLNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo, bool require_atomic_access = false) |
523 bool require_atomic_access = false ) | 574 : StoreNode(c, mem, adr, at, val, mo), _require_atomic_access(require_atomic_access) {} |
524 : StoreNode(c,mem,adr,at,val) | |
525 , _require_atomic_access(require_atomic_access) | |
526 {} | |
527 virtual int Opcode() const; | 575 virtual int Opcode() const; |
528 virtual BasicType memory_type() const { return T_LONG; } | 576 virtual BasicType memory_type() const { return T_LONG; } |
529 bool require_atomic_access() { return _require_atomic_access; } | 577 bool require_atomic_access() { return _require_atomic_access; } |
530 static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val); | 578 static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo); |
531 #ifndef PRODUCT | 579 #ifndef PRODUCT |
532 virtual void dump_spec(outputStream *st) const { | 580 virtual void dump_spec(outputStream *st) const { |
533 StoreNode::dump_spec(st); | 581 StoreNode::dump_spec(st); |
534 if (_require_atomic_access) st->print(" Atomic!"); | 582 if (_require_atomic_access) st->print(" Atomic!"); |
535 } | 583 } |
538 | 586 |
539 //------------------------------StoreFNode------------------------------------- | 587 //------------------------------StoreFNode------------------------------------- |
540 // Store float to memory | 588 // Store float to memory |
541 class StoreFNode : public StoreNode { | 589 class StoreFNode : public StoreNode { |
542 public: | 590 public: |
543 StoreFNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | 591 StoreFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
592 : StoreNode(c, mem, adr, at, val, mo) {} | |
544 virtual int Opcode() const; | 593 virtual int Opcode() const; |
545 virtual BasicType memory_type() const { return T_FLOAT; } | 594 virtual BasicType memory_type() const { return T_FLOAT; } |
546 }; | 595 }; |
547 | 596 |
548 //------------------------------StoreDNode------------------------------------- | 597 //------------------------------StoreDNode------------------------------------- |
549 // Store double to memory | 598 // Store double to memory |
550 class StoreDNode : public StoreNode { | 599 class StoreDNode : public StoreNode { |
551 public: | 600 public: |
552 StoreDNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | 601 StoreDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
602 : StoreNode(c, mem, adr, at, val, mo) {} | |
553 virtual int Opcode() const; | 603 virtual int Opcode() const; |
554 virtual BasicType memory_type() const { return T_DOUBLE; } | 604 virtual BasicType memory_type() const { return T_DOUBLE; } |
555 }; | 605 }; |
556 | 606 |
557 //------------------------------StorePNode------------------------------------- | 607 //------------------------------StorePNode------------------------------------- |
558 // Store pointer to memory | 608 // Store pointer to memory |
559 class StorePNode : public StoreNode { | 609 class StorePNode : public StoreNode { |
560 public: | 610 public: |
561 StorePNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | 611 StorePNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
612 : StoreNode(c, mem, adr, at, val, mo) {} | |
562 virtual int Opcode() const; | 613 virtual int Opcode() const; |
563 virtual BasicType memory_type() const { return T_ADDRESS; } | 614 virtual BasicType memory_type() const { return T_ADDRESS; } |
564 }; | 615 }; |
565 | 616 |
566 //------------------------------StoreNNode------------------------------------- | 617 //------------------------------StoreNNode------------------------------------- |
567 // Store narrow oop to memory | 618 // Store narrow oop to memory |
568 class StoreNNode : public StoreNode { | 619 class StoreNNode : public StoreNode { |
569 public: | 620 public: |
570 StoreNNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | 621 StoreNNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
622 : StoreNode(c, mem, adr, at, val, mo) {} | |
571 virtual int Opcode() const; | 623 virtual int Opcode() const; |
572 virtual BasicType memory_type() const { return T_NARROWOOP; } | 624 virtual BasicType memory_type() const { return T_NARROWOOP; } |
573 }; | 625 }; |
574 | 626 |
575 //------------------------------StoreNKlassNode-------------------------------------- | 627 //------------------------------StoreNKlassNode-------------------------------------- |
576 // Store narrow klass to memory | 628 // Store narrow klass to memory |
577 class StoreNKlassNode : public StoreNNode { | 629 class StoreNKlassNode : public StoreNNode { |
578 public: | 630 public: |
579 StoreNKlassNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNNode(c,mem,adr,at,val) {} | 631 StoreNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) |
632 : StoreNNode(c, mem, adr, at, val, mo) {} | |
580 virtual int Opcode() const; | 633 virtual int Opcode() const; |
581 virtual BasicType memory_type() const { return T_NARROWKLASS; } | 634 virtual BasicType memory_type() const { return T_NARROWKLASS; } |
582 }; | 635 }; |
583 | 636 |
584 //------------------------------StoreCMNode----------------------------------- | 637 //------------------------------StoreCMNode----------------------------------- |
595 virtual uint size_of() const { return sizeof(*this); } | 648 virtual uint size_of() const { return sizeof(*this); } |
596 int _oop_alias_idx; // The alias_idx of OopStore | 649 int _oop_alias_idx; // The alias_idx of OopStore |
597 | 650 |
598 public: | 651 public: |
599 StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, int oop_alias_idx ) : | 652 StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, int oop_alias_idx ) : |
600 StoreNode(c,mem,adr,at,val,oop_store), | 653 StoreNode(c, mem, adr, at, val, oop_store, MemNode::release), |
601 _oop_alias_idx(oop_alias_idx) { | 654 _oop_alias_idx(oop_alias_idx) { |
602 assert(_oop_alias_idx >= Compile::AliasIdxRaw || | 655 assert(_oop_alias_idx >= Compile::AliasIdxRaw || |
603 _oop_alias_idx == Compile::AliasIdxBot && Compile::current()->AliasLevel() == 0, | 656 _oop_alias_idx == Compile::AliasIdxBot && Compile::current()->AliasLevel() == 0, |
604 "bad oop alias idx"); | 657 "bad oop alias idx"); |
605 } | 658 } |
615 // Load-locked a pointer from memory (either object or array). | 668 // Load-locked a pointer from memory (either object or array). |
616 // On Sparc & Intel this is implemented as a normal pointer load. | 669 // On Sparc & Intel this is implemented as a normal pointer load. |
617 // On PowerPC and friends it's a real load-locked. | 670 // On PowerPC and friends it's a real load-locked. |
618 class LoadPLockedNode : public LoadPNode { | 671 class LoadPLockedNode : public LoadPNode { |
619 public: | 672 public: |
620 LoadPLockedNode( Node *c, Node *mem, Node *adr ) | 673 LoadPLockedNode(Node *c, Node *mem, Node *adr, MemOrd mo) |
621 : LoadPNode(c,mem,adr,TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM) {} | 674 : LoadPNode(c, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, mo) {} |
622 virtual int Opcode() const; | 675 virtual int Opcode() const; |
623 virtual int store_Opcode() const { return Op_StorePConditional; } | 676 virtual int store_Opcode() const { return Op_StorePConditional; } |
624 virtual bool depends_only_on_test() const { return true; } | 677 virtual bool depends_only_on_test() const { return true; } |
625 }; | 678 }; |
626 | 679 |
939 MemBarAcquireNode(Compile* C, int alias_idx, Node* precedent) | 992 MemBarAcquireNode(Compile* C, int alias_idx, Node* precedent) |
940 : MemBarNode(C, alias_idx, precedent) {} | 993 : MemBarNode(C, alias_idx, precedent) {} |
941 virtual int Opcode() const; | 994 virtual int Opcode() const; |
942 }; | 995 }; |
943 | 996 |
997 // "Acquire" - no following ref can move before (but earlier refs can | |
998 // follow, like an early Load stalled in cache). Requires multi-cpu | |
999 // visibility. Inserted independ of any load, as required | |
1000 // for intrinsic sun.misc.Unsafe.loadFence(). | |
1001 class LoadFenceNode: public MemBarNode { | |
1002 public: | |
1003 LoadFenceNode(Compile* C, int alias_idx, Node* precedent) | |
1004 : MemBarNode(C, alias_idx, precedent) {} | |
1005 virtual int Opcode() const; | |
1006 }; | |
1007 | |
944 // "Release" - no earlier ref can move after (but later refs can move | 1008 // "Release" - no earlier ref can move after (but later refs can move |
945 // up, like a speculative pipelined cache-hitting Load). Requires | 1009 // up, like a speculative pipelined cache-hitting Load). Requires |
946 // multi-cpu visibility. Inserted before a volatile store. | 1010 // multi-cpu visibility. Inserted before a volatile store. |
947 class MemBarReleaseNode: public MemBarNode { | 1011 class MemBarReleaseNode: public MemBarNode { |
948 public: | 1012 public: |
949 MemBarReleaseNode(Compile* C, int alias_idx, Node* precedent) | 1013 MemBarReleaseNode(Compile* C, int alias_idx, Node* precedent) |
1014 : MemBarNode(C, alias_idx, precedent) {} | |
1015 virtual int Opcode() const; | |
1016 }; | |
1017 | |
1018 // "Release" - no earlier ref can move after (but later refs can move | |
1019 // up, like a speculative pipelined cache-hitting Load). Requires | |
1020 // multi-cpu visibility. Inserted independent of any store, as required | |
1021 // for intrinsic sun.misc.Unsafe.storeFence(). | |
1022 class StoreFenceNode: public MemBarNode { | |
1023 public: | |
1024 StoreFenceNode(Compile* C, int alias_idx, Node* precedent) | |
950 : MemBarNode(C, alias_idx, precedent) {} | 1025 : MemBarNode(C, alias_idx, precedent) {} |
951 virtual int Opcode() const; | 1026 virtual int Opcode() const; |
952 }; | 1027 }; |
953 | 1028 |
954 // "Acquire" - no following ref can move before (but earlier refs can | 1029 // "Acquire" - no following ref can move before (but earlier refs can |