Mercurial > hg > truffle
annotate src/share/vm/opto/chaitin.hpp @ 4710:41406797186b
7113012: G1: rename not-fully-young GCs as "mixed"
Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets).
Reviewed-by: johnc, brutisso
author | tonyp |
---|---|
date | Fri, 16 Dec 2011 02:14:27 -0500 |
parents | f6f3bb0ee072 |
children | 5da7201222d5 |
rev | line source |
---|---|
0 | 1 /* |
3939 | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
923
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
923
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
923
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OPTO_CHAITIN_HPP |
26 #define SHARE_VM_OPTO_CHAITIN_HPP | |
27 | |
28 #include "code/vmreg.hpp" | |
29 #include "libadt/port.hpp" | |
30 #include "memory/resourceArea.hpp" | |
31 #include "opto/connode.hpp" | |
32 #include "opto/live.hpp" | |
33 #include "opto/matcher.hpp" | |
34 #include "opto/phase.hpp" | |
35 #include "opto/regalloc.hpp" | |
36 #include "opto/regmask.hpp" | |
37 | |
0 | 38 class LoopTree; |
39 class MachCallNode; | |
40 class MachSafePointNode; | |
41 class Matcher; | |
42 class PhaseCFG; | |
43 class PhaseLive; | |
44 class PhaseRegAlloc; | |
45 class PhaseChaitin; | |
46 | |
47 #define OPTO_DEBUG_SPLIT_FREQ BLOCK_FREQUENCY(0.001) | |
48 #define OPTO_LRG_HIGH_FREQ BLOCK_FREQUENCY(0.25) | |
49 | |
50 //------------------------------LRG-------------------------------------------- | |
51 // Live-RanGe structure. | |
52 class LRG : public ResourceObj { | |
3939 | 53 friend class VMStructs; |
0 | 54 public: |
55 enum { SPILL_REG=29999 }; // Register number of a spilled LRG | |
56 | |
57 double _cost; // 2 for loads/1 for stores times block freq | |
58 double _area; // Sum of all simultaneously live values | |
59 double score() const; // Compute score from cost and area | |
60 double _maxfreq; // Maximum frequency of any def or use | |
61 | |
62 Node *_def; // Check for multi-def live ranges | |
63 #ifndef PRODUCT | |
64 GrowableArray<Node*>* _defs; | |
65 #endif | |
66 | |
67 uint _risk_bias; // Index of LRG which we want to avoid color | |
68 uint _copy_bias; // Index of LRG which we want to share color | |
69 | |
70 uint _next; // Index of next LRG in linked list | |
71 uint _prev; // Index of prev LRG in linked list | |
72 private: | |
73 uint _reg; // Chosen register; undefined if mask is plural | |
74 public: | |
75 // Return chosen register for this LRG. Error if the LRG is not bound to | |
76 // a single register. | |
77 OptoReg::Name reg() const { return OptoReg::Name(_reg); } | |
78 void set_reg( OptoReg::Name r ) { _reg = r; } | |
79 | |
80 private: | |
81 uint _eff_degree; // Effective degree: Sum of neighbors _num_regs | |
82 public: | |
83 int degree() const { assert( _degree_valid, "" ); return _eff_degree; } | |
84 // Degree starts not valid and any change to the IFG neighbor | |
85 // set makes it not valid. | |
86 void set_degree( uint degree ) { _eff_degree = degree; debug_only(_degree_valid = 1;) } | |
87 // Made a change that hammered degree | |
88 void invalid_degree() { debug_only(_degree_valid=0;) } | |
89 // Incrementally modify degree. If it was correct, it should remain correct | |
90 void inc_degree( uint mod ) { _eff_degree += mod; } | |
91 // Compute the degree between 2 live ranges | |
92 int compute_degree( LRG &l ) const; | |
93 | |
94 private: | |
95 RegMask _mask; // Allowed registers for this LRG | |
96 uint _mask_size; // cache of _mask.Size(); | |
97 public: | |
98 int compute_mask_size() const { return _mask.is_AllStack() ? 65535 : _mask.Size(); } | |
99 void set_mask_size( int size ) { | |
100 assert((size == 65535) || (size == (int)_mask.Size()), ""); | |
101 _mask_size = size; | |
102 debug_only(_msize_valid=1;) | |
103 debug_only( if( _num_regs == 2 && !_fat_proj ) _mask.VerifyPairs(); ) | |
104 } | |
105 void compute_set_mask_size() { set_mask_size(compute_mask_size()); } | |
106 int mask_size() const { assert( _msize_valid, "mask size not valid" ); | |
107 return _mask_size; } | |
108 // Get the last mask size computed, even if it does not match the | |
109 // count of bits in the current mask. | |
110 int get_invalid_mask_size() const { return _mask_size; } | |
111 const RegMask &mask() const { return _mask; } | |
112 void set_mask( const RegMask &rm ) { _mask = rm; debug_only(_msize_valid=0;)} | |
113 void AND( const RegMask &rm ) { _mask.AND(rm); debug_only(_msize_valid=0;)} | |
114 void SUBTRACT( const RegMask &rm ) { _mask.SUBTRACT(rm); debug_only(_msize_valid=0;)} | |
115 void Clear() { _mask.Clear() ; debug_only(_msize_valid=1); _mask_size = 0; } | |
116 void Set_All() { _mask.Set_All(); debug_only(_msize_valid=1); _mask_size = RegMask::CHUNK_SIZE; } | |
117 void Insert( OptoReg::Name reg ) { _mask.Insert(reg); debug_only(_msize_valid=0;) } | |
118 void Remove( OptoReg::Name reg ) { _mask.Remove(reg); debug_only(_msize_valid=0;) } | |
119 void ClearToPairs() { _mask.ClearToPairs(); debug_only(_msize_valid=0;) } | |
120 | |
121 // Number of registers this live range uses when it colors | |
122 private: | |
123 uint8 _num_regs; // 2 for Longs and Doubles, 1 for all else | |
124 // except _num_regs is kill count for fat_proj | |
125 public: | |
126 int num_regs() const { return _num_regs; } | |
127 void set_num_regs( int reg ) { assert( _num_regs == reg || !_num_regs, "" ); _num_regs = reg; } | |
128 | |
129 private: | |
130 // Number of physical registers this live range uses when it colors | |
131 // Architecture and register-set dependent | |
132 uint8 _reg_pressure; | |
133 public: | |
134 void set_reg_pressure(int i) { _reg_pressure = i; } | |
135 int reg_pressure() const { return _reg_pressure; } | |
136 | |
137 // How much 'wiggle room' does this live range have? | |
138 // How many color choices can it make (scaled by _num_regs)? | |
139 int degrees_of_freedom() const { return mask_size() - _num_regs; } | |
140 // Bound LRGs have ZERO degrees of freedom. We also count | |
141 // must_spill as bound. | |
142 bool is_bound () const { return _is_bound; } | |
143 // Negative degrees-of-freedom; even with no neighbors this | |
144 // live range must spill. | |
145 bool not_free() const { return degrees_of_freedom() < 0; } | |
146 // Is this live range of "low-degree"? Trivially colorable? | |
147 bool lo_degree () const { return degree() <= degrees_of_freedom(); } | |
148 // Is this live range just barely "low-degree"? Trivially colorable? | |
149 bool just_lo_degree () const { return degree() == degrees_of_freedom(); } | |
150 | |
151 uint _is_oop:1, // Live-range holds an oop | |
152 _is_float:1, // True if in float registers | |
153 _was_spilled1:1, // True if prior spilling on def | |
154 _was_spilled2:1, // True if twice prior spilling on def | |
155 _is_bound:1, // live range starts life with no | |
156 // degrees of freedom. | |
157 _direct_conflict:1, // True if def and use registers in conflict | |
158 _must_spill:1, // live range has lost all degrees of freedom | |
159 // If _fat_proj is set, live range does NOT require aligned, adjacent | |
160 // registers and has NO interferences. | |
161 // If _fat_proj is clear, live range requires num_regs() to be a power of | |
162 // 2, and it requires registers to form an aligned, adjacent set. | |
163 _fat_proj:1, // | |
164 _was_lo:1, // Was lo-degree prior to coalesce | |
165 _msize_valid:1, // _mask_size cache valid | |
166 _degree_valid:1, // _degree cache valid | |
167 _has_copy:1, // Adjacent to some copy instruction | |
168 _at_risk:1; // Simplify says this guy is at risk to spill | |
169 | |
170 | |
171 // Alive if non-zero, dead if zero | |
172 bool alive() const { return _def != NULL; } | |
295
ea18057223c4
6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents:
196
diff
changeset
|
173 bool is_multidef() const { return _def == NodeSentinel; } |
ea18057223c4
6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents:
196
diff
changeset
|
174 bool is_singledef() const { return _def != NodeSentinel; } |
0 | 175 |
176 #ifndef PRODUCT | |
177 void dump( ) const; | |
178 #endif | |
179 }; | |
180 | |
181 //------------------------------LRG_List--------------------------------------- | |
182 // Map Node indices to Live RanGe indices. | |
183 // Array lookup in the optimized case. | |
184 class LRG_List : public ResourceObj { | |
3939 | 185 friend class VMStructs; |
0 | 186 uint _cnt, _max; |
187 uint* _lidxs; | |
188 ReallocMark _nesting; // assertion check for reallocations | |
189 public: | |
190 LRG_List( uint max ); | |
191 | |
192 uint lookup( uint nidx ) const { | |
193 return _lidxs[nidx]; | |
194 } | |
195 uint operator[] (uint nidx) const { return lookup(nidx); } | |
196 | |
197 void map( uint nidx, uint lidx ) { | |
198 assert( nidx < _cnt, "oob" ); | |
199 _lidxs[nidx] = lidx; | |
200 } | |
201 void extend( uint nidx, uint lidx ); | |
202 | |
203 uint Size() const { return _cnt; } | |
204 }; | |
205 | |
206 //------------------------------IFG-------------------------------------------- | |
207 // InterFerence Graph | |
208 // An undirected graph implementation. Created with a fixed number of | |
209 // vertices. Edges can be added & tested. Vertices can be removed, then | |
210 // added back later with all edges intact. Can add edges between one vertex | |
211 // and a list of other vertices. Can union vertices (and their edges) | |
212 // together. The IFG needs to be really really fast, and also fairly | |
213 // abstract! It needs abstraction so I can fiddle with the implementation to | |
214 // get even more speed. | |
215 class PhaseIFG : public Phase { | |
3939 | 216 friend class VMStructs; |
0 | 217 // Current implementation: a triangular adjacency list. |
218 | |
219 // Array of adjacency-lists, indexed by live-range number | |
220 IndexSet *_adjs; | |
221 | |
222 // Assertion bit for proper use of Squaring | |
223 bool _is_square; | |
224 | |
225 // Live range structure goes here | |
226 LRG *_lrgs; // Array of LRG structures | |
227 | |
228 public: | |
229 // Largest live-range number | |
230 uint _maxlrg; | |
231 | |
232 Arena *_arena; | |
233 | |
234 // Keep track of inserted and deleted Nodes | |
235 VectorSet *_yanked; | |
236 | |
237 PhaseIFG( Arena *arena ); | |
238 void init( uint maxlrg ); | |
239 | |
240 // Add edge between a and b. Returns true if actually addded. | |
241 int add_edge( uint a, uint b ); | |
242 | |
243 // Add edge between a and everything in the vector | |
244 void add_vector( uint a, IndexSet *vec ); | |
245 | |
246 // Test for edge existance | |
247 int test_edge( uint a, uint b ) const; | |
248 | |
249 // Square-up matrix for faster Union | |
250 void SquareUp(); | |
251 | |
252 // Return number of LRG neighbors | |
253 uint neighbor_cnt( uint a ) const { return _adjs[a].count(); } | |
254 // Union edges of b into a on Squared-up matrix | |
255 void Union( uint a, uint b ); | |
256 // Test for edge in Squared-up matrix | |
257 int test_edge_sq( uint a, uint b ) const; | |
258 // Yank a Node and all connected edges from the IFG. Be prepared to | |
259 // re-insert the yanked Node in reverse order of yanking. Return a | |
260 // list of neighbors (edges) yanked. | |
261 IndexSet *remove_node( uint a ); | |
262 // Reinsert a yanked Node | |
263 void re_insert( uint a ); | |
264 // Return set of neighbors | |
265 IndexSet *neighbors( uint a ) const { return &_adjs[a]; } | |
266 | |
267 #ifndef PRODUCT | |
268 // Dump the IFG | |
269 void dump() const; | |
270 void stats() const; | |
271 void verify( const PhaseChaitin * ) const; | |
272 #endif | |
273 | |
274 //--------------- Live Range Accessors | |
275 LRG &lrgs(uint idx) const { assert(idx < _maxlrg, "oob"); return _lrgs[idx]; } | |
276 | |
277 // Compute and set effective degree. Might be folded into SquareUp(). | |
278 void Compute_Effective_Degree(); | |
279 | |
280 // Compute effective degree as the sum of neighbors' _sizes. | |
281 int effective_degree( uint lidx ) const; | |
282 }; | |
283 | |
284 // TEMPORARILY REPLACED WITH COMMAND LINE FLAG | |
285 | |
286 //// !!!!! Magic Constants need to move into ad file | |
287 #ifdef SPARC | |
288 //#define FLOAT_PRESSURE 30 /* SFLT_REG_mask.Size() - 1 */ | |
289 //#define INT_PRESSURE 23 /* NOTEMP_I_REG_mask.Size() - 1 */ | |
290 #define FLOAT_INCREMENT(regs) regs | |
291 #else | |
292 //#define FLOAT_PRESSURE 6 | |
293 //#define INT_PRESSURE 6 | |
294 #define FLOAT_INCREMENT(regs) 1 | |
295 #endif | |
296 | |
297 //------------------------------Chaitin---------------------------------------- | |
298 // Briggs-Chaitin style allocation, mostly. | |
299 class PhaseChaitin : public PhaseRegAlloc { | |
3939 | 300 friend class VMStructs; |
0 | 301 |
302 int _trip_cnt; | |
303 int _alternate; | |
304 | |
305 uint _maxlrg; // Max live range number | |
306 LRG &lrgs(uint idx) const { return _ifg->lrgs(idx); } | |
307 PhaseLive *_live; // Liveness, used in the interference graph | |
308 PhaseIFG *_ifg; // Interference graph (for original chunk) | |
309 Node_List **_lrg_nodes; // Array of node; lists for lrgs which spill | |
310 VectorSet _spilled_once; // Nodes that have been spilled | |
311 VectorSet _spilled_twice; // Nodes that have been spilled twice | |
312 | |
313 LRG_List _names; // Map from Nodes to Live RanGes | |
314 | |
315 // Union-find map. Declared as a short for speed. | |
316 // Indexed by live-range number, it returns the compacted live-range number | |
317 LRG_List _uf_map; | |
318 // Reset the Union-Find map to identity | |
319 void reset_uf_map( uint maxlrg ); | |
320 // Remove the need for the Union-Find mapping | |
321 void compress_uf_map_for_nodes( ); | |
322 | |
323 // Combine the Live Range Indices for these 2 Nodes into a single live | |
324 // range. Future requests for any Node in either live range will | |
325 // return the live range index for the combined live range. | |
326 void Union( const Node *src, const Node *dst ); | |
327 | |
328 void new_lrg( const Node *x, uint lrg ); | |
329 | |
330 // Compact live ranges, removing unused ones. Return new maxlrg. | |
331 void compact(); | |
332 | |
333 uint _lo_degree; // Head of lo-degree LRGs list | |
334 uint _lo_stk_degree; // Head of lo-stk-degree LRGs list | |
335 uint _hi_degree; // Head of hi-degree LRGs list | |
336 uint _simplified; // Linked list head of simplified LRGs | |
337 | |
338 // Helper functions for Split() | |
339 uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray<uint> splits, int slidx ); | |
340 uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx ); | |
341 int clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg ); | |
295
ea18057223c4
6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents:
196
diff
changeset
|
342 Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits, |
ea18057223c4
6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents:
196
diff
changeset
|
343 int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru); |
0 | 344 // True if lidx is used before any real register is def'd in the block |
345 bool prompt_use( Block *b, uint lidx ); | |
346 Node *get_spillcopy_wide( Node *def, Node *use, uint uidx ); | |
605 | 347 // Insert the spill at chosen location. Skip over any intervening Proj's or |
0 | 348 // Phis. Skip over a CatchNode and projs, inserting in the fall-through block |
349 // instead. Update high-pressure indices. Create a new live range. | |
350 void insert_proj( Block *b, uint i, Node *spill, uint maxlrg ); | |
351 | |
352 bool is_high_pressure( Block *b, LRG *lrg, uint insidx ); | |
353 | |
354 uint _oldphi; // Node index which separates pre-allocation nodes | |
355 | |
356 Block **_blks; // Array of blocks sorted by frequency for coalescing | |
357 | |
673 | 358 float _high_frequency_lrg; // Frequency at which LRG will be spilled for debug info |
359 | |
0 | 360 #ifndef PRODUCT |
361 bool _trace_spilling; | |
362 #endif | |
363 | |
364 public: | |
365 PhaseChaitin( uint unique, PhaseCFG &cfg, Matcher &matcher ); | |
366 ~PhaseChaitin() {} | |
367 | |
368 // Convert a Node into a Live Range Index - a lidx | |
369 uint Find( const Node *n ) { | |
370 uint lidx = n2lidx(n); | |
371 uint uf_lidx = _uf_map[lidx]; | |
372 return (uf_lidx == lidx) ? uf_lidx : Find_compress(n); | |
373 } | |
374 uint Find_const( uint lrg ) const; | |
375 uint Find_const( const Node *n ) const; | |
376 | |
377 // Do all the real work of allocate | |
378 void Register_Allocate(); | |
379 | |
380 uint n2lidx( const Node *n ) const { return _names[n->_idx]; } | |
381 | |
673 | 382 float high_frequency_lrg() const { return _high_frequency_lrg; } |
383 | |
0 | 384 #ifndef PRODUCT |
385 bool trace_spilling() const { return _trace_spilling; } | |
386 #endif | |
387 | |
388 private: | |
389 // De-SSA the world. Assign registers to Nodes. Use the same register for | |
390 // all inputs to a PhiNode, effectively coalescing live ranges. Insert | |
391 // copies as needed. | |
392 void de_ssa(); | |
393 uint Find_compress( const Node *n ); | |
394 uint Find( uint lidx ) { | |
395 uint uf_lidx = _uf_map[lidx]; | |
396 return (uf_lidx == lidx) ? uf_lidx : Find_compress(lidx); | |
397 } | |
398 uint Find_compress( uint lidx ); | |
399 | |
400 uint Find_id( const Node *n ) { | |
401 uint retval = n2lidx(n); | |
402 assert(retval == Find(n),"Invalid node to lidx mapping"); | |
403 return retval; | |
404 } | |
405 | |
406 // Add edge between reg and everything in the vector. | |
407 // Same as _ifg->add_vector(reg,live) EXCEPT use the RegMask | |
408 // information to trim the set of interferences. Return the | |
409 // count of edges added. | |
410 void interfere_with_live( uint reg, IndexSet *live ); | |
411 // Count register pressure for asserts | |
412 uint count_int_pressure( IndexSet *liveout ); | |
413 uint count_float_pressure( IndexSet *liveout ); | |
414 | |
415 // Build the interference graph using virtual registers only. | |
416 // Used for aggressive coalescing. | |
417 void build_ifg_virtual( ); | |
418 | |
419 // Build the interference graph using physical registers when available. | |
420 // That is, if 2 live ranges are simultaneously alive but in their | |
421 // acceptable register sets do not overlap, then they do not interfere. | |
422 uint build_ifg_physical( ResourceArea *a ); | |
423 | |
424 // Gather LiveRanGe information, including register masks and base pointer/ | |
425 // derived pointer relationships. | |
426 void gather_lrg_masks( bool mod_cisc_masks ); | |
427 | |
428 // Force the bases of derived pointers to be alive at GC points. | |
429 bool stretch_base_pointer_live_ranges( ResourceArea *a ); | |
430 // Helper to stretch above; recursively discover the base Node for | |
431 // a given derived Node. Easy for AddP-related machine nodes, but | |
432 // needs to be recursive for derived Phis. | |
433 Node *find_base_for_derived( Node **derived_base_map, Node *derived, uint &maxlrg ); | |
434 | |
435 // Set the was-lo-degree bit. Conservative coalescing should not change the | |
436 // colorability of the graph. If any live range was of low-degree before | |
437 // coalescing, it should Simplify. This call sets the was-lo-degree bit. | |
438 void set_was_low(); | |
439 | |
440 // Split live-ranges that must spill due to register conflicts (as opposed | |
441 // to capacity spills). Typically these are things def'd in a register | |
442 // and used on the stack or vice-versa. | |
443 void pre_spill(); | |
444 | |
445 // Init LRG caching of degree, numregs. Init lo_degree list. | |
446 void cache_lrg_info( ); | |
447 | |
448 // Simplify the IFG by removing LRGs of low degree with no copies | |
449 void Pre_Simplify(); | |
450 | |
451 // Simplify the IFG by removing LRGs of low degree | |
452 void Simplify(); | |
453 | |
454 // Select colors by re-inserting edges into the IFG. | |
605 | 455 // Return TRUE if any spills occurred. |
0 | 456 uint Select( ); |
457 // Helper function for select which allows biased coloring | |
458 OptoReg::Name choose_color( LRG &lrg, int chunk ); | |
459 // Helper function which implements biasing heuristic | |
460 OptoReg::Name bias_color( LRG &lrg, int chunk ); | |
461 | |
462 // Split uncolorable live ranges | |
463 // Return new number of live ranges | |
464 uint Split( uint maxlrg ); | |
465 | |
466 // Copy 'was_spilled'-edness from one Node to another. | |
467 void copy_was_spilled( Node *src, Node *dst ); | |
468 // Set the 'spilled_once' or 'spilled_twice' flag on a node. | |
469 void set_was_spilled( Node *n ); | |
470 | |
471 // Convert ideal spill-nodes into machine loads & stores | |
472 // Set C->failing when fixup spills could not complete, node limit exceeded. | |
473 void fixup_spills(); | |
474 | |
475 // Post-Allocation peephole copy removal | |
476 void post_allocate_copy_removal(); | |
477 Node *skip_copies( Node *c ); | |
923 | 478 // Replace the old node with the current live version of that value |
479 // and yank the old value if it's dead. | |
480 int replace_and_yank_if_dead( Node *old, OptoReg::Name nreg, | |
481 Block *current_block, Node_List& value, Node_List& regnd ) { | |
482 Node* v = regnd[nreg]; | |
483 assert(v->outcnt() != 0, "no dead values"); | |
484 old->replace_by(v); | |
485 return yank_if_dead(old, current_block, &value, ®nd); | |
486 } | |
487 | |
0 | 488 int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd ); |
3934
8f47d8870d9a
7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents:
2016
diff
changeset
|
489 int yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd ); |
0 | 490 int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List ®nd, bool can_change_regs ); |
491 int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List ®nd ); | |
492 bool may_be_copy_of_callee( Node *def ) const; | |
493 | |
494 // If nreg already contains the same constant as val then eliminate it | |
70
b683f557224b
6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations
never
parents:
0
diff
changeset
|
495 bool eliminate_copy_of_constant(Node* val, Node* n, |
b683f557224b
6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations
never
parents:
0
diff
changeset
|
496 Block *current_block, Node_List& value, Node_List ®nd, |
0 | 497 OptoReg::Name nreg, OptoReg::Name nreg2); |
498 // Extend the node to LRG mapping | |
499 void add_reference( const Node *node, const Node *old_node); | |
500 | |
501 private: | |
502 | |
503 static int _final_loads, _final_stores, _final_copies, _final_memoves; | |
504 static double _final_load_cost, _final_store_cost, _final_copy_cost, _final_memove_cost; | |
505 static int _conserv_coalesce, _conserv_coalesce_pair; | |
506 static int _conserv_coalesce_trie, _conserv_coalesce_quad; | |
507 static int _post_alloc; | |
508 static int _lost_opp_pp_coalesce, _lost_opp_cflow_coalesce; | |
509 static int _used_cisc_instructions, _unused_cisc_instructions; | |
510 static int _allocator_attempts, _allocator_successes; | |
511 | |
512 #ifndef PRODUCT | |
513 static uint _high_pressure, _low_pressure; | |
514 | |
515 void dump() const; | |
516 void dump( const Node *n ) const; | |
517 void dump( const Block * b ) const; | |
518 void dump_degree_lists() const; | |
519 void dump_simplified() const; | |
2016
361783318e7e
7004940: CTW: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG
never
parents:
1972
diff
changeset
|
520 void dump_lrg( uint lidx, bool defs_only) const; |
361783318e7e
7004940: CTW: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG
never
parents:
1972
diff
changeset
|
521 void dump_lrg( uint lidx) const { |
361783318e7e
7004940: CTW: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG
never
parents:
1972
diff
changeset
|
522 // dump defs and uses by default |
361783318e7e
7004940: CTW: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG
never
parents:
1972
diff
changeset
|
523 dump_lrg(lidx, false); |
361783318e7e
7004940: CTW: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG
never
parents:
1972
diff
changeset
|
524 } |
0 | 525 void dump_bb( uint pre_order ) const; |
526 | |
527 // Verify that base pointers and derived pointers are still sane | |
528 void verify_base_ptrs( ResourceArea *a ) const; | |
529 | |
566
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
295
diff
changeset
|
530 void verify( ResourceArea *a, bool verify_ifg = false ) const; |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
295
diff
changeset
|
531 |
0 | 532 void dump_for_spill_split_recycle() const; |
533 | |
534 public: | |
535 void dump_frame() const; | |
536 char *dump_register( const Node *n, char *buf ) const; | |
537 private: | |
538 static void print_chaitin_statistics(); | |
539 #endif | |
540 friend class PhaseCoalesce; | |
541 friend class PhaseAggressiveCoalesce; | |
542 friend class PhaseConservativeCoalesce; | |
543 }; | |
1972 | 544 |
545 #endif // SHARE_VM_OPTO_CHAITIN_HPP |