comparison src/share/vm/opto/escape.hpp @ 4137:04b9a2566eec

Merge with hsx23/hotspot.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 17 Dec 2011 21:40:27 +0100
parents cc81b9c09bbb
children ee138854b3a6
comparison
equal deleted inserted replaced
3737:9dc19b7d89a3 4137:04b9a2566eec
72 // to the static memory. 72 // to the static memory.
73 // 73 //
74 // C2 does not have local variables. However for the purposes of constructing 74 // C2 does not have local variables. However for the purposes of constructing
75 // the connection graph, the following IR nodes are treated as local variables: 75 // the connection graph, the following IR nodes are treated as local variables:
76 // Phi (pointer values) 76 // Phi (pointer values)
77 // LoadP 77 // LoadP, LoadN
78 // Proj#5 (value returned from callnodes including allocations) 78 // Proj#5 (value returned from callnodes including allocations)
79 // CheckCastPP, CastPP 79 // CheckCastPP, CastPP
80 // 80 //
81 // The LoadP, Proj and CheckCastPP behave like variables assigned to only once. 81 // The LoadP, Proj and CheckCastPP behave like variables assigned to only once.
82 // Only a Phi can have multiple assignments. Each input to a Phi is treated 82 // Only a Phi can have multiple assignments. Each input to a Phi is treated
83 // as an assignment to it. 83 // as an assignment to it.
84 // 84 //
85 // The following node types are JavaObject: 85 // The following node types are JavaObject:
86 // 86 //
87 // top() 87 // phantom_object (general globally escaped object)
88 // Allocate 88 // Allocate
89 // AllocateArray 89 // AllocateArray
90 // Parm (for incoming arguments) 90 // Parm (for incoming arguments)
91 // CastX2P ("unsafe" operations) 91 // CastX2P ("unsafe" operations)
92 // CreateEx 92 // CreateEx
93 // ConP 93 // ConP
94 // LoadKlass 94 // LoadKlass
95 // ThreadLocal 95 // ThreadLocal
96 // CallStaticJava (which returns Object)
96 // 97 //
97 // AddP nodes are fields. 98 // AddP nodes are fields.
98 // 99 //
99 // After building the graph, a pass is made over the nodes, deleting deferred 100 // After building the graph, a pass is made over the nodes, deleting deferred
100 // nodes and copying the edges from the target of the deferred edge to the 101 // nodes and copying the edges from the target of the deferred edge to the
128 Field = 3 129 Field = 3
129 } NodeType; 130 } NodeType;
130 131
131 typedef enum { 132 typedef enum {
132 UnknownEscape = 0, 133 UnknownEscape = 0,
133 NoEscape = 1, // A scalar replaceable object with unique type. 134 NoEscape = 1, // An object does not escape method or thread and it is
134 ArgEscape = 2, // An object passed as argument or referenced by 135 // not passed to call. It could be replaced with scalar.
135 // argument (and not globally escape during call). 136 ArgEscape = 2, // An object does not escape method or thread but it is
136 GlobalEscape = 3 // An object escapes the method and thread. 137 // passed as argument to call or referenced by argument
138 // and it does not escape during call.
139 GlobalEscape = 3 // An object escapes the method or thread.
137 } EscapeState; 140 } EscapeState;
138 141
139 typedef enum { 142 typedef enum {
140 UnknownEdge = 0, 143 UnknownEdge = 0,
141 PointsToEdge = 1, 144 PointsToEdge = 1,
151 INITIAL_EDGE_COUNT = 4 154 INITIAL_EDGE_COUNT = 4
152 }; 155 };
153 156
154 NodeType _type; 157 NodeType _type;
155 EscapeState _escape; 158 EscapeState _escape;
156 GrowableArray<uint>* _edges; // outgoing edges 159 GrowableArray<uint>* _edges; // outgoing edges
160 Node* _node; // Ideal node corresponding to this PointsTo node.
161 int _offset; // Object fields offsets.
162 bool _scalar_replaceable; // Not escaped object could be replaced with scalar
163 bool _has_unknown_ptr; // Has edge to phantom_object
157 164
158 public: 165 public:
159 Node* _node; // Ideal node corresponding to this PointsTo node.
160 int _offset; // Object fields offsets.
161 bool _scalar_replaceable;// Not escaped object could be replaced with scalar
162 bool _hidden_alias; // This node is an argument to a function.
163 // which may return it creating a hidden alias.
164
165 PointsToNode(): 166 PointsToNode():
166 _type(UnknownType), 167 _type(UnknownType),
167 _escape(UnknownEscape), 168 _escape(UnknownEscape),
168 _edges(NULL), 169 _edges(NULL),
169 _node(NULL), 170 _node(NULL),
170 _offset(-1), 171 _offset(-1),
171 _scalar_replaceable(true), 172 _has_unknown_ptr(false),
172 _hidden_alias(false) {} 173 _scalar_replaceable(true) {}
173 174
174 175
175 EscapeState escape_state() const { return _escape; } 176 EscapeState escape_state() const { return _escape; }
176 NodeType node_type() const { return _type;} 177 NodeType node_type() const { return _type;}
177 int offset() { return _offset;} 178 int offset() { return _offset;}
179 bool scalar_replaceable() { return _scalar_replaceable;}
180 bool has_unknown_ptr() { return _has_unknown_ptr;}
178 181
179 void set_offset(int offs) { _offset = offs;} 182 void set_offset(int offs) { _offset = offs;}
180 void set_escape_state(EscapeState state) { _escape = state; } 183 void set_escape_state(EscapeState state) { _escape = state; }
181 void set_node_type(NodeType ntype) { 184 void set_node_type(NodeType ntype) {
182 assert(_type == UnknownType || _type == ntype, "Can't change node type"); 185 assert(_type == UnknownType || _type == ntype, "Can't change node type");
183 _type = ntype; 186 _type = ntype;
184 } 187 }
188 void set_scalar_replaceable(bool v) { _scalar_replaceable = v; }
189 void set_has_unknown_ptr() { _has_unknown_ptr = true; }
185 190
186 // count of outgoing edges 191 // count of outgoing edges
187 uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); } 192 uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); }
188 193
189 // node index of target of outgoing edge "e" 194 // node index of target of outgoing edge "e"
231 236
232 uint _phantom_object; // Index of globally escaping object 237 uint _phantom_object; // Index of globally escaping object
233 // that pointer values loaded from 238 // that pointer values loaded from
234 // a field which has not been set 239 // a field which has not been set
235 // are assumed to point to. 240 // are assumed to point to.
236 uint _oop_null; // ConP(#NULL) 241 uint _oop_null; // ConP(#NULL)->_idx
237 uint _noop_null; // ConN(#NULL) 242 uint _noop_null; // ConN(#NULL)->_idx
243 Node* _pcmp_neq; // ConI(#CC_GT)
244 Node* _pcmp_eq; // ConI(#CC_EQ)
238 245
239 Compile * _compile; // Compile object for current compilation 246 Compile * _compile; // Compile object for current compilation
240 PhaseIterGVN * _igvn; // Value numbering 247 PhaseIterGVN * _igvn; // Value numbering
241 248
242 // Address of an element in _nodes. Used when the element is to be modified 249 // Address of an element in _nodes. Used when the element is to be modified
244 // There should be no new ideal nodes during ConnectionGraph build, 251 // There should be no new ideal nodes during ConnectionGraph build,
245 // growableArray::adr_at() will throw assert otherwise. 252 // growableArray::adr_at() will throw assert otherwise.
246 return _nodes.adr_at(idx); 253 return _nodes.adr_at(idx);
247 } 254 }
248 uint nodes_size() const { return _nodes.length(); } 255 uint nodes_size() const { return _nodes.length(); }
256
257 bool is_null_ptr(uint idx) const { return (idx == _noop_null || idx == _oop_null); }
249 258
250 // Add node to ConnectionGraph. 259 // Add node to ConnectionGraph.
251 void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done); 260 void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done);
252 261
253 // offset of a field reference 262 // offset of a field reference
328 Node *phi = _node_map[idx]; 337 Node *phi = _node_map[idx];
329 return (phi == NULL) ? NULL : phi->as_Phi(); 338 return (phi == NULL) ? NULL : phi->as_Phi();
330 } 339 }
331 340
332 // Notify optimizer that a node has been modified 341 // Notify optimizer that a node has been modified
333 // Node: This assumes that escape analysis is run before
334 // PhaseIterGVN creation
335 void record_for_optimizer(Node *n) { 342 void record_for_optimizer(Node *n) {
336 _igvn->_worklist.push(n); 343 _igvn->_worklist.push(n);
344 _igvn->add_users_to_worklist(n);
337 } 345 }
338 346
339 // Set the escape state of a node 347 // Set the escape state of a node
340 void set_escape_state(uint ni, PointsToNode::EscapeState es); 348 void set_escape_state(uint ni, PointsToNode::EscapeState es);
341 349
350 // Find fields initializing values for allocations.
351 void find_init_values(Node* n, VectorSet* visited, PhaseTransform* phase);
352
342 // Adjust escape state after Connection Graph is built. 353 // Adjust escape state after Connection Graph is built.
343 void adjust_escape_state(int nidx, PhaseTransform* phase); 354 void adjust_escape_state(Node* n);
355
356 // Propagate escape states to referenced nodes.
357 bool propagate_escape_state(GrowableArray<int>* cg_worklist,
358 GrowableArray<uint>* worklist,
359 PointsToNode::EscapeState esc_state);
360
361 // Optimize objects compare.
362 Node* optimize_ptr_compare(Node* n);
344 363
345 // Compute the escape information 364 // Compute the escape information
346 bool compute_escape(); 365 bool compute_escape();
347 366
348 public: 367 public:
354 // Perform escape analysis 373 // Perform escape analysis
355 static void do_analysis(Compile *C, PhaseIterGVN *igvn); 374 static void do_analysis(Compile *C, PhaseIterGVN *igvn);
356 375
357 // escape state of a node 376 // escape state of a node
358 PointsToNode::EscapeState escape_state(Node *n); 377 PointsToNode::EscapeState escape_state(Node *n);
359
360 // other information we have collected
361 bool is_scalar_replaceable(Node *n) {
362 if (_collecting || (n->_idx >= nodes_size()))
363 return false;
364 PointsToNode* ptn = ptnode_adr(n->_idx);
365 return ptn->escape_state() == PointsToNode::NoEscape && ptn->_scalar_replaceable;
366 }
367
368 bool hidden_alias(Node *n) {
369 if (_collecting || (n->_idx >= nodes_size()))
370 return true;
371 PointsToNode* ptn = ptnode_adr(n->_idx);
372 return (ptn->escape_state() != PointsToNode::NoEscape) || ptn->_hidden_alias;
373 }
374 378
375 #ifndef PRODUCT 379 #ifndef PRODUCT
376 void dump(); 380 void dump();
377 #endif 381 #endif
378 }; 382 };