22 *
23 */
24
25 #ifndef SHARE_VM_OPTO_MEMNODE_HPP
26 #define SHARE_VM_OPTO_MEMNODE_HPP
27
28 #include "opto/multnode.hpp"
29 #include "opto/node.hpp"
30 #include "opto/opcodes.hpp"
31 #include "opto/type.hpp"
32
33 // Portions of code courtesy of Clifford Click
34
35 class MultiNode;
36 class PhaseCCP;
37 class PhaseTransform;
38
39 //------------------------------MemNode----------------------------------------
40 // Load or Store, possibly throwing a NULL pointer exception
41 class MemNode : public Node {
42 protected:
43 #ifdef ASSERT
44 const TypePtr* _adr_type; // What kind of memory is being addressed?
45 #endif
46 virtual uint size_of() const; // Size is bigger (ASSERT only)
47 public:
48 enum { Control, // When is it safe to do this load?
49 Memory, // Chunk of memory is being loaded from
50 Address, // Actually address, derived from base
51 ValueIn, // Value to store
52 OopStore // Preceeding oop store, only in StoreCM
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;
58 protected:
59 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at )
60 : Node(c0,c1,c2 ) {
61 init_class_id(Class_Mem);
62 debug_only(_adr_type=at; adr_type();)
63 }
64 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3 )
65 : Node(c0,c1,c2,c3) {
66 init_class_id(Class_Mem);
67 debug_only(_adr_type=at; adr_type();)
68 }
69 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3, Node *c4)
70 : Node(c0,c1,c2,c3,c4) {
71 init_class_id(Class_Mem);
72 debug_only(_adr_type=at; adr_type();)
73 }
74
75 virtual Node* find_previous_arraycopy(PhaseTransform* phase, Node* ld_alloc, Node*& mem, bool can_see_stored_value) const { return NULL; }
76
77 public:
78 // Helpers for the optimizer. Documented in memnode.cpp.
79 static bool detect_ptr_independence(Node* p1, AllocateNode* a1,
80 Node* p2, AllocateNode* a2,
81 PhaseTransform* phase);
82 static bool adr_phi_is_loop_invariant(Node* adr_phi, Node* cast);
83
84 static Node *optimize_simple_memory_chain(Node *mchain, const TypeOopPtr *t_oop, Node *load, PhaseGVN *phase);
85 static Node *optimize_memory_chain(Node *mchain, const TypePtr *t_adr, Node *load, PhaseGVN *phase);
86 // This one should probably be a phase-specific function:
87 static bool all_controls_dominate(Node* dom, Node* sub);
88
89 virtual const class TypePtr *adr_type() const; // returns bottom_type of address
90
109 virtual int store_Opcode() const { return -1; }
110
111 // What is the type of the value in memory? (T_VOID mean "unspecified".)
112 virtual BasicType memory_type() const = 0;
113 virtual int memory_size() const {
114 #ifdef ASSERT
115 return type2aelembytes(memory_type(), true);
116 #else
117 return type2aelembytes(memory_type());
118 #endif
119 }
120
121 // Search through memory states which precede this node (load or store).
122 // Look for an exact match for the address, with no intervening
123 // aliased stores.
124 Node* find_previous_store(PhaseTransform* phase);
125
126 // Can this node (load or store) accurately see a stored value in
127 // the given memory state? (The state may or may not be in(Memory).)
128 Node* can_see_stored_value(Node* st, PhaseTransform* phase) const;
129
130 #ifndef PRODUCT
131 static void dump_adr_type(const Node* mem, const TypePtr* adr_type, outputStream *st);
132 virtual void dump_spec(outputStream *st) const;
133 #endif
134 };
135
136 //------------------------------LoadNode---------------------------------------
137 // Load value; requires Memory and Address
138 class LoadNode : public MemNode {
139 public:
140 // Some loads (from unsafe) should be pinned: they don't depend only
141 // on the dominating test. The boolean field _depends_only_on_test
142 // below records whether that node depends only on the dominating
143 // test.
144 // Methods used to build LoadNodes pass an argument of type enum
145 // ControlDependency instead of a boolean because those methods
146 // typically have multiple boolean parameters with default values:
147 // passing the wrong boolean to one of these parameters by mistake
148 // goes easily unnoticed. Using an enum, the compiler can check that
|
22 *
23 */
24
25 #ifndef SHARE_VM_OPTO_MEMNODE_HPP
26 #define SHARE_VM_OPTO_MEMNODE_HPP
27
28 #include "opto/multnode.hpp"
29 #include "opto/node.hpp"
30 #include "opto/opcodes.hpp"
31 #include "opto/type.hpp"
32
33 // Portions of code courtesy of Clifford Click
34
35 class MultiNode;
36 class PhaseCCP;
37 class PhaseTransform;
38
39 //------------------------------MemNode----------------------------------------
40 // Load or Store, possibly throwing a NULL pointer exception
41 class MemNode : public Node {
42 private:
43 bool _unaligned_access; // Unaligned access from unsafe
44 bool _mismatched_access; // Mismatched access from unsafe: byte read in integer array for instance
45 protected:
46 #ifdef ASSERT
47 const TypePtr* _adr_type; // What kind of memory is being addressed?
48 #endif
49 virtual uint size_of() const;
50 public:
51 enum { Control, // When is it safe to do this load?
52 Memory, // Chunk of memory is being loaded from
53 Address, // Actually address, derived from base
54 ValueIn, // Value to store
55 OopStore // Preceeding oop store, only in StoreCM
56 };
57 typedef enum { unordered = 0,
58 acquire, // Load has to acquire or be succeeded by MemBarAcquire.
59 release // Store has to release or be preceded by MemBarRelease.
60 } MemOrd;
61 protected:
62 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at )
63 : Node(c0,c1,c2 ), _unaligned_access(false), _mismatched_access(false) {
64 init_class_id(Class_Mem);
65 debug_only(_adr_type=at; adr_type();)
66 }
67 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3 )
68 : Node(c0,c1,c2,c3), _unaligned_access(false), _mismatched_access(false) {
69 init_class_id(Class_Mem);
70 debug_only(_adr_type=at; adr_type();)
71 }
72 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3, Node *c4)
73 : Node(c0,c1,c2,c3,c4), _unaligned_access(false), _mismatched_access(false) {
74 init_class_id(Class_Mem);
75 debug_only(_adr_type=at; adr_type();)
76 }
77
78 virtual Node* find_previous_arraycopy(PhaseTransform* phase, Node* ld_alloc, Node*& mem, bool can_see_stored_value) const { return NULL; }
79
80 public:
81 // Helpers for the optimizer. Documented in memnode.cpp.
82 static bool detect_ptr_independence(Node* p1, AllocateNode* a1,
83 Node* p2, AllocateNode* a2,
84 PhaseTransform* phase);
85 static bool adr_phi_is_loop_invariant(Node* adr_phi, Node* cast);
86
87 static Node *optimize_simple_memory_chain(Node *mchain, const TypeOopPtr *t_oop, Node *load, PhaseGVN *phase);
88 static Node *optimize_memory_chain(Node *mchain, const TypePtr *t_adr, Node *load, PhaseGVN *phase);
89 // This one should probably be a phase-specific function:
90 static bool all_controls_dominate(Node* dom, Node* sub);
91
92 virtual const class TypePtr *adr_type() const; // returns bottom_type of address
93
112 virtual int store_Opcode() const { return -1; }
113
114 // What is the type of the value in memory? (T_VOID mean "unspecified".)
115 virtual BasicType memory_type() const = 0;
116 virtual int memory_size() const {
117 #ifdef ASSERT
118 return type2aelembytes(memory_type(), true);
119 #else
120 return type2aelembytes(memory_type());
121 #endif
122 }
123
124 // Search through memory states which precede this node (load or store).
125 // Look for an exact match for the address, with no intervening
126 // aliased stores.
127 Node* find_previous_store(PhaseTransform* phase);
128
129 // Can this node (load or store) accurately see a stored value in
130 // the given memory state? (The state may or may not be in(Memory).)
131 Node* can_see_stored_value(Node* st, PhaseTransform* phase) const;
132
133 void set_unaligned_access() { _unaligned_access = true; }
134 bool is_unaligned_access() const { return _unaligned_access; }
135 void set_mismatched_access() { _mismatched_access = true; }
136 bool is_mismatched_access() const { return _mismatched_access; }
137
138 #ifndef PRODUCT
139 static void dump_adr_type(const Node* mem, const TypePtr* adr_type, outputStream *st);
140 virtual void dump_spec(outputStream *st) const;
141 #endif
142 };
143
144 //------------------------------LoadNode---------------------------------------
145 // Load value; requires Memory and Address
146 class LoadNode : public MemNode {
147 public:
148 // Some loads (from unsafe) should be pinned: they don't depend only
149 // on the dominating test. The boolean field _depends_only_on_test
150 // below records whether that node depends only on the dominating
151 // test.
152 // Methods used to build LoadNodes pass an argument of type enum
153 // ControlDependency instead of a boolean because those methods
154 // typically have multiple boolean parameters with default values:
155 // passing the wrong boolean to one of these parameters by mistake
156 // goes easily unnoticed. Using an enum, the compiler can check that
|