annotate src/share/vm/opto/chaitin.cpp @ 1941:79d04223b8a5

Added caching for resolved types and resolved fields. This is crucial, because the local load elimination will lead to wrong results, if field equality (of two RiField objects with the same object and the same RiType) is not given. The caching makes sure that the default equals implementation is sufficient.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Tue, 28 Dec 2010 18:33:26 +0100
parents 0e35fa8ebccd
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1012
diff changeset
2 * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1012
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1012
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: 1012
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_chaitin.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
29
a61af66fc99e Initial load
duke
parents:
diff changeset
30 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
31 void LRG::dump( ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
32 ttyLocker ttyl;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 tty->print("%d ",num_regs());
a61af66fc99e Initial load
duke
parents:
diff changeset
34 _mask.dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
35 if( _msize_valid ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
36 if( mask_size() == compute_mask_size() ) tty->print(", #%d ",_mask_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
37 else tty->print(", #!!!_%d_vs_%d ",_mask_size,_mask.Size());
a61af66fc99e Initial load
duke
parents:
diff changeset
38 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
39 tty->print(", #?(%d) ",_mask.Size());
a61af66fc99e Initial load
duke
parents:
diff changeset
40 }
a61af66fc99e Initial load
duke
parents:
diff changeset
41
a61af66fc99e Initial load
duke
parents:
diff changeset
42 tty->print("EffDeg: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
43 if( _degree_valid ) tty->print( "%d ", _eff_degree );
a61af66fc99e Initial load
duke
parents:
diff changeset
44 else tty->print("? ");
a61af66fc99e Initial load
duke
parents:
diff changeset
45
295
ea18057223c4 6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents: 196
diff changeset
46 if( is_multidef() ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
47 tty->print("MultiDef ");
a61af66fc99e Initial load
duke
parents:
diff changeset
48 if (_defs != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
49 tty->print("(");
a61af66fc99e Initial load
duke
parents:
diff changeset
50 for (int i = 0; i < _defs->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
51 tty->print("N%d ", _defs->at(i)->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
52 }
a61af66fc99e Initial load
duke
parents:
diff changeset
53 tty->print(") ");
a61af66fc99e Initial load
duke
parents:
diff changeset
54 }
a61af66fc99e Initial load
duke
parents:
diff changeset
55 }
a61af66fc99e Initial load
duke
parents:
diff changeset
56 else if( _def == 0 ) tty->print("Dead ");
a61af66fc99e Initial load
duke
parents:
diff changeset
57 else tty->print("Def: N%d ",_def->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 tty->print("Cost:%4.2g Area:%4.2g Score:%4.2g ",_cost,_area, score());
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // Flags
a61af66fc99e Initial load
duke
parents:
diff changeset
61 if( _is_oop ) tty->print("Oop ");
a61af66fc99e Initial load
duke
parents:
diff changeset
62 if( _is_float ) tty->print("Float ");
a61af66fc99e Initial load
duke
parents:
diff changeset
63 if( _was_spilled1 ) tty->print("Spilled ");
a61af66fc99e Initial load
duke
parents:
diff changeset
64 if( _was_spilled2 ) tty->print("Spilled2 ");
a61af66fc99e Initial load
duke
parents:
diff changeset
65 if( _direct_conflict ) tty->print("Direct_conflict ");
a61af66fc99e Initial load
duke
parents:
diff changeset
66 if( _fat_proj ) tty->print("Fat ");
a61af66fc99e Initial load
duke
parents:
diff changeset
67 if( _was_lo ) tty->print("Lo ");
a61af66fc99e Initial load
duke
parents:
diff changeset
68 if( _has_copy ) tty->print("Copy ");
a61af66fc99e Initial load
duke
parents:
diff changeset
69 if( _at_risk ) tty->print("Risk ");
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 if( _must_spill ) tty->print("Must_spill ");
a61af66fc99e Initial load
duke
parents:
diff changeset
72 if( _is_bound ) tty->print("Bound ");
a61af66fc99e Initial load
duke
parents:
diff changeset
73 if( _msize_valid ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
74 if( _degree_valid && lo_degree() ) tty->print("Trivial ");
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 //------------------------------score------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // Compute score from cost and area. Low score is best to spill.
a61af66fc99e Initial load
duke
parents:
diff changeset
83 static double raw_score( double cost, double area ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 return cost - (area*RegisterCostAreaRatio) * 1.52588e-5;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 double LRG::score() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // Scale _area by RegisterCostAreaRatio/64K then subtract from cost.
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // Bigger area lowers score, encourages spilling this live range.
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // Bigger cost raise score, prevents spilling this live range.
a61af66fc99e Initial load
duke
parents:
diff changeset
91 // (Note: 1/65536 is the magic constant below; I dont trust the C optimizer
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // to turn a divide by a constant into a multiply by the reciprical).
a61af66fc99e Initial load
duke
parents:
diff changeset
93 double score = raw_score( _cost, _area);
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // Account for area. Basically, LRGs covering large areas are better
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // to spill because more other LRGs get freed up.
a61af66fc99e Initial load
duke
parents:
diff changeset
97 if( _area == 0.0 ) // No area? Then no progress to spill
a61af66fc99e Initial load
duke
parents:
diff changeset
98 return 1e35;
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 if( _was_spilled2 ) // If spilled once before, we are unlikely
a61af66fc99e Initial load
duke
parents:
diff changeset
101 return score + 1e30; // to make progress again.
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 if( _cost >= _area*3.0 ) // Tiny area relative to cost
a61af66fc99e Initial load
duke
parents:
diff changeset
104 return score + 1e17; // Probably no progress to spill
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 if( (_cost+_cost) >= _area*3.0 ) // Small area relative to cost
a61af66fc99e Initial load
duke
parents:
diff changeset
107 return score + 1e10; // Likely no progress to spill
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 return score;
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111
a61af66fc99e Initial load
duke
parents:
diff changeset
112 //------------------------------LRG_List---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
113 LRG_List::LRG_List( uint max ) : _cnt(max), _max(max), _lidxs(NEW_RESOURCE_ARRAY(uint,max)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 memset( _lidxs, 0, sizeof(uint)*max );
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 void LRG_List::extend( uint nidx, uint lidx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 _nesting.check();
a61af66fc99e Initial load
duke
parents:
diff changeset
119 if( nidx >= _max ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 uint size = 16;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 while( size <= nidx ) size <<=1;
a61af66fc99e Initial load
duke
parents:
diff changeset
122 _lidxs = REALLOC_RESOURCE_ARRAY( uint, _lidxs, _max, size );
a61af66fc99e Initial load
duke
parents:
diff changeset
123 _max = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125 while( _cnt <= nidx )
a61af66fc99e Initial load
duke
parents:
diff changeset
126 _lidxs[_cnt++] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
127 _lidxs[nidx] = lidx;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 #define NUMBUCKS 3
a61af66fc99e Initial load
duke
parents:
diff changeset
131
a61af66fc99e Initial load
duke
parents:
diff changeset
132 //------------------------------Chaitin----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
133 PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher)
a61af66fc99e Initial load
duke
parents:
diff changeset
134 : PhaseRegAlloc(unique, cfg, matcher,
a61af66fc99e Initial load
duke
parents:
diff changeset
135 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
136 print_chaitin_statistics
a61af66fc99e Initial load
duke
parents:
diff changeset
137 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
138 NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
139 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
140 ),
a61af66fc99e Initial load
duke
parents:
diff changeset
141 _names(unique), _uf_map(unique),
a61af66fc99e Initial load
duke
parents:
diff changeset
142 _maxlrg(0), _live(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
143 _spilled_once(Thread::current()->resource_area()),
a61af66fc99e Initial load
duke
parents:
diff changeset
144 _spilled_twice(Thread::current()->resource_area()),
a61af66fc99e Initial load
duke
parents:
diff changeset
145 _lo_degree(0), _lo_stk_degree(0), _hi_degree(0), _simplified(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
146 _oldphi(unique)
a61af66fc99e Initial load
duke
parents:
diff changeset
147 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
148 , _trace_spilling(TraceSpilling || C->method_has_option("TraceSpilling"))
a61af66fc99e Initial load
duke
parents:
diff changeset
149 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
150 {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 NOT_PRODUCT( Compile::TracePhase t3("ctorChaitin", &_t_ctorChaitin, TimeCompiler); )
673
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
152
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
153 _high_frequency_lrg = MIN2(float(OPTO_LRG_HIGH_FREQ), _cfg._outer_loop_freq);
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
154
0
a61af66fc99e Initial load
duke
parents:
diff changeset
155 uint i,j;
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // Build a list of basic blocks, sorted by frequency
a61af66fc99e Initial load
duke
parents:
diff changeset
157 _blks = NEW_RESOURCE_ARRAY( Block *, _cfg._num_blocks );
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // Experiment with sorting strategies to speed compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
159 double cutoff = BLOCK_FREQUENCY(1.0); // Cutoff for high frequency bucket
a61af66fc99e Initial load
duke
parents:
diff changeset
160 Block **buckets[NUMBUCKS]; // Array of buckets
a61af66fc99e Initial load
duke
parents:
diff changeset
161 uint buckcnt[NUMBUCKS]; // Array of bucket counters
a61af66fc99e Initial load
duke
parents:
diff changeset
162 double buckval[NUMBUCKS]; // Array of bucket value cutoffs
a61af66fc99e Initial load
duke
parents:
diff changeset
163 for( i = 0; i < NUMBUCKS; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 buckets[i] = NEW_RESOURCE_ARRAY( Block *, _cfg._num_blocks );
a61af66fc99e Initial load
duke
parents:
diff changeset
165 buckcnt[i] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // Bump by three orders of magnitude each time
a61af66fc99e Initial load
duke
parents:
diff changeset
167 cutoff *= 0.001;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 buckval[i] = cutoff;
a61af66fc99e Initial load
duke
parents:
diff changeset
169 for( j = 0; j < _cfg._num_blocks; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
170 buckets[i][j] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // Sort blocks into buckets
a61af66fc99e Initial load
duke
parents:
diff changeset
174 for( i = 0; i < _cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 for( j = 0; j < NUMBUCKS; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 if( (j == NUMBUCKS-1) || (_cfg._blocks[i]->_freq > buckval[j]) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // Assign block to end of list for appropriate bucket
a61af66fc99e Initial load
duke
parents:
diff changeset
178 buckets[j][buckcnt[j]++] = _cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
179 break; // kick out of inner loop
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // Dump buckets into final block array
a61af66fc99e Initial load
duke
parents:
diff changeset
184 uint blkcnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
185 for( i = 0; i < NUMBUCKS; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
186 for( j = 0; j < buckcnt[i]; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 _blks[blkcnt++] = buckets[i][j];
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 assert(blkcnt == _cfg._num_blocks, "Block array not totally filled");
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 void PhaseChaitin::Register_Allocate() {
a61af66fc99e Initial load
duke
parents:
diff changeset
195
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // Above the OLD FP (and in registers) are the incoming arguments. Stack
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // slots in this area are called "arg_slots". Above the NEW FP (and in
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // registers) is the outgoing argument area; above that is the spill/temp
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // area. These are all "frame_slots". Arg_slots start at the zero
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // stack_slots and count up to the known arg_size. Frame_slots start at
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // the stack_slot #arg_size and go up. After allocation I map stack
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // slots to actual offsets. Stack-slots in the arg_slot area are biased
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // by the frame_size; stack-slots in the frame_slot area are biased by 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 _trip_cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 _alternate = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 _matcher._allocation_started = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 ResourceArea live_arena; // Arena for liveness & IFG info
a61af66fc99e Initial load
duke
parents:
diff changeset
210 ResourceMark rm(&live_arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 // Need live-ness for the IFG; need the IFG for coalescing. If the
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // liveness is JUST for coalescing, then I can get some mileage by renaming
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // all copy-related live ranges low and then using the max copy-related
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // live range as a cut-off for LIVE and the IFG. In other words, I can
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // build a subset of LIVE and IFG just for copies.
a61af66fc99e Initial load
duke
parents:
diff changeset
217 PhaseLive live(_cfg,_names,&live_arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
218
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // Need IFG for coalescing and coloring
a61af66fc99e Initial load
duke
parents:
diff changeset
220 PhaseIFG ifg( &live_arena );
a61af66fc99e Initial load
duke
parents:
diff changeset
221 _ifg = &ifg;
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 if (C->unique() > _names.Size()) _names.extend(C->unique()-1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // Come out of SSA world to the Named world. Assign (virtual) registers to
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // Nodes. Use the same register for all inputs and the output of PhiNodes
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // - effectively ending SSA form. This requires either coalescing live
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // ranges or inserting copies. For the moment, we insert "virtual copies"
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // - we pretend there is a copy prior to each Phi in predecessor blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // We will attempt to coalesce such "virtual copies" before we manifest
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // them for real.
a61af66fc99e Initial load
duke
parents:
diff changeset
232 de_ssa();
a61af66fc99e Initial load
duke
parents:
diff changeset
233
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
234 #ifdef ASSERT
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
235 // Veify the graph before RA.
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
236 verify(&live_arena);
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
237 #endif
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
238
0
a61af66fc99e Initial load
duke
parents:
diff changeset
239 {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 NOT_PRODUCT( Compile::TracePhase t3("computeLive", &_t_computeLive, TimeCompiler); )
a61af66fc99e Initial load
duke
parents:
diff changeset
241 _live = NULL; // Mark live as being not available
a61af66fc99e Initial load
duke
parents:
diff changeset
242 rm.reset_to_mark(); // Reclaim working storage
a61af66fc99e Initial load
duke
parents:
diff changeset
243 IndexSet::reset_memory(C, &live_arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 ifg.init(_maxlrg); // Empty IFG
a61af66fc99e Initial load
duke
parents:
diff changeset
245 gather_lrg_masks( false ); // Collect LRG masks
a61af66fc99e Initial load
duke
parents:
diff changeset
246 live.compute( _maxlrg ); // Compute liveness
a61af66fc99e Initial load
duke
parents:
diff changeset
247 _live = &live; // Mark LIVE as being available
a61af66fc99e Initial load
duke
parents:
diff changeset
248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // Base pointers are currently "used" by instructions which define new
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // derived pointers. This makes base pointers live up to the where the
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // derived pointer is made, but not beyond. Really, they need to be live
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // across any GC point where the derived value is live. So this code looks
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // at all the GC points, and "stretches" the live range of any base pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // to the GC point.
a61af66fc99e Initial load
duke
parents:
diff changeset
256 if( stretch_base_pointer_live_ranges(&live_arena) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
257 NOT_PRODUCT( Compile::TracePhase t3("computeLive (sbplr)", &_t_computeLive, TimeCompiler); )
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // Since some live range stretched, I need to recompute live
a61af66fc99e Initial load
duke
parents:
diff changeset
259 _live = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
260 rm.reset_to_mark(); // Reclaim working storage
a61af66fc99e Initial load
duke
parents:
diff changeset
261 IndexSet::reset_memory(C, &live_arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
262 ifg.init(_maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 gather_lrg_masks( false );
a61af66fc99e Initial load
duke
parents:
diff changeset
264 live.compute( _maxlrg );
a61af66fc99e Initial load
duke
parents:
diff changeset
265 _live = &live;
a61af66fc99e Initial load
duke
parents:
diff changeset
266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // Create the interference graph using virtual copies
a61af66fc99e Initial load
duke
parents:
diff changeset
268 build_ifg_virtual( ); // Include stack slots this time
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Aggressive (but pessimistic) copy coalescing.
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // This pass works on virtual copies. Any virtual copies which are not
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // coalesced get manifested as actual copies
a61af66fc99e Initial load
duke
parents:
diff changeset
273 {
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // The IFG is/was triangular. I am 'squaring it up' so Union can run
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // faster. Union requires a 'for all' operation which is slow on the
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // triangular adjacency matrix (quick reminder: the IFG is 'sparse' -
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // meaning I can visit all the Nodes neighbors less than a Node in time
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // O(# of neighbors), but I have to visit all the Nodes greater than a
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // given Node and search them for an instance, i.e., time O(#MaxLRG)).
a61af66fc99e Initial load
duke
parents:
diff changeset
280 _ifg->SquareUp();
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282 PhaseAggressiveCoalesce coalesce( *this );
a61af66fc99e Initial load
duke
parents:
diff changeset
283 coalesce.coalesce_driver( );
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // Insert un-coalesced copies. Visit all Phis. Where inputs to a Phi do
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // not match the Phi itself, insert a copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
286 coalesce.insert_copies(_matcher);
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // After aggressive coalesce, attempt a first cut at coloring.
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // To color, we need the IFG and for that we need LIVE.
a61af66fc99e Initial load
duke
parents:
diff changeset
291 {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 NOT_PRODUCT( Compile::TracePhase t3("computeLive", &_t_computeLive, TimeCompiler); )
a61af66fc99e Initial load
duke
parents:
diff changeset
293 _live = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
294 rm.reset_to_mark(); // Reclaim working storage
a61af66fc99e Initial load
duke
parents:
diff changeset
295 IndexSet::reset_memory(C, &live_arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
296 ifg.init(_maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
297 gather_lrg_masks( true );
a61af66fc99e Initial load
duke
parents:
diff changeset
298 live.compute( _maxlrg );
a61af66fc99e Initial load
duke
parents:
diff changeset
299 _live = &live;
a61af66fc99e Initial load
duke
parents:
diff changeset
300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
301
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // Build physical interference graph
a61af66fc99e Initial load
duke
parents:
diff changeset
303 uint must_spill = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 must_spill = build_ifg_physical( &live_arena );
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // If we have a guaranteed spill, might as well spill now
a61af66fc99e Initial load
duke
parents:
diff changeset
306 if( must_spill ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 if( !_maxlrg ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // Bail out if unique gets too large (ie - unique > MaxNodeLimit)
a61af66fc99e Initial load
duke
parents:
diff changeset
309 C->check_node_count(10*must_spill, "out of nodes before split");
a61af66fc99e Initial load
duke
parents:
diff changeset
310 if (C->failing()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
311 _maxlrg = Split( _maxlrg ); // Split spilling LRG everywhere
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // or we failed to split
a61af66fc99e Initial load
duke
parents:
diff changeset
314 C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
a61af66fc99e Initial load
duke
parents:
diff changeset
315 if (C->failing()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317 NOT_PRODUCT( C->verify_graph_edges(); )
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 compact(); // Compact LRGs; return new lower max lrg
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 NOT_PRODUCT( Compile::TracePhase t3("computeLive", &_t_computeLive, TimeCompiler); )
a61af66fc99e Initial load
duke
parents:
diff changeset
323 _live = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
324 rm.reset_to_mark(); // Reclaim working storage
a61af66fc99e Initial load
duke
parents:
diff changeset
325 IndexSet::reset_memory(C, &live_arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
326 ifg.init(_maxlrg); // Build a new interference graph
a61af66fc99e Initial load
duke
parents:
diff changeset
327 gather_lrg_masks( true ); // Collect intersect mask
a61af66fc99e Initial load
duke
parents:
diff changeset
328 live.compute( _maxlrg ); // Compute LIVE
a61af66fc99e Initial load
duke
parents:
diff changeset
329 _live = &live;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331 build_ifg_physical( &live_arena );
a61af66fc99e Initial load
duke
parents:
diff changeset
332 _ifg->SquareUp();
a61af66fc99e Initial load
duke
parents:
diff changeset
333 _ifg->Compute_Effective_Degree();
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // Only do conservative coalescing if requested
a61af66fc99e Initial load
duke
parents:
diff changeset
335 if( OptoCoalesce ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // Conservative (and pessimistic) copy coalescing of those spills
a61af66fc99e Initial load
duke
parents:
diff changeset
337 PhaseConservativeCoalesce coalesce( *this );
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // If max live ranges greater than cutoff, don't color the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // This cutoff can be larger than below since it is only done once.
a61af66fc99e Initial load
duke
parents:
diff changeset
340 coalesce.coalesce_driver( );
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342 compress_uf_map_for_nodes();
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 #ifdef ASSERT
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
345 verify(&live_arena, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
346 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
347 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
348 ifg.SquareUp();
a61af66fc99e Initial load
duke
parents:
diff changeset
349 ifg.Compute_Effective_Degree();
a61af66fc99e Initial load
duke
parents:
diff changeset
350 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
351 set_was_low();
a61af66fc99e Initial load
duke
parents:
diff changeset
352 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // Prepare for Simplify & Select
a61af66fc99e Initial load
duke
parents:
diff changeset
356 cache_lrg_info(); // Count degree of LRGs
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // Simplify the InterFerence Graph by removing LRGs of low degree.
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // LRGs of low degree are trivially colorable.
a61af66fc99e Initial load
duke
parents:
diff changeset
360 Simplify();
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // Select colors by re-inserting LRGs back into the IFG in reverse order.
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // Return whether or not something spills.
a61af66fc99e Initial load
duke
parents:
diff changeset
364 uint spills = Select( );
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // If we spill, split and recycle the entire thing
a61af66fc99e Initial load
duke
parents:
diff changeset
367 while( spills ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
368 if( _trip_cnt++ > 24 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
369 DEBUG_ONLY( dump_for_spill_split_recycle(); )
a61af66fc99e Initial load
duke
parents:
diff changeset
370 if( _trip_cnt > 27 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 C->record_method_not_compilable("failed spill-split-recycle sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
372 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 if( !_maxlrg ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
377 _maxlrg = Split( _maxlrg ); // Split spilling LRG everywhere
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
a61af66fc99e Initial load
duke
parents:
diff changeset
379 C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
a61af66fc99e Initial load
duke
parents:
diff changeset
380 if (C->failing()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
381
a61af66fc99e Initial load
duke
parents:
diff changeset
382 compact(); // Compact LRGs; return new lower max lrg
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 // Nuke the live-ness and interference graph and LiveRanGe info
a61af66fc99e Initial load
duke
parents:
diff changeset
385 {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 NOT_PRODUCT( Compile::TracePhase t3("computeLive", &_t_computeLive, TimeCompiler); )
a61af66fc99e Initial load
duke
parents:
diff changeset
387 _live = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 rm.reset_to_mark(); // Reclaim working storage
a61af66fc99e Initial load
duke
parents:
diff changeset
389 IndexSet::reset_memory(C, &live_arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
390 ifg.init(_maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
391
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // Create LiveRanGe array.
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // Intersect register masks for all USEs and DEFs
a61af66fc99e Initial load
duke
parents:
diff changeset
394 gather_lrg_masks( true );
a61af66fc99e Initial load
duke
parents:
diff changeset
395 live.compute( _maxlrg );
a61af66fc99e Initial load
duke
parents:
diff changeset
396 _live = &live;
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
398 must_spill = build_ifg_physical( &live_arena );
a61af66fc99e Initial load
duke
parents:
diff changeset
399 _ifg->SquareUp();
a61af66fc99e Initial load
duke
parents:
diff changeset
400 _ifg->Compute_Effective_Degree();
a61af66fc99e Initial load
duke
parents:
diff changeset
401
a61af66fc99e Initial load
duke
parents:
diff changeset
402 // Only do conservative coalescing if requested
a61af66fc99e Initial load
duke
parents:
diff changeset
403 if( OptoCoalesce ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // Conservative (and pessimistic) copy coalescing
a61af66fc99e Initial load
duke
parents:
diff changeset
405 PhaseConservativeCoalesce coalesce( *this );
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // Check for few live ranges determines how aggressive coalesce is.
a61af66fc99e Initial load
duke
parents:
diff changeset
407 coalesce.coalesce_driver( );
a61af66fc99e Initial load
duke
parents:
diff changeset
408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
409 compress_uf_map_for_nodes();
a61af66fc99e Initial load
duke
parents:
diff changeset
410 #ifdef ASSERT
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
411 verify(&live_arena, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
412 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
413 cache_lrg_info(); // Count degree of LRGs
a61af66fc99e Initial load
duke
parents:
diff changeset
414
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // Simplify the InterFerence Graph by removing LRGs of low degree.
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // LRGs of low degree are trivially colorable.
a61af66fc99e Initial load
duke
parents:
diff changeset
417 Simplify();
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // Select colors by re-inserting LRGs back into the IFG in reverse order.
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // Return whether or not something spills.
a61af66fc99e Initial load
duke
parents:
diff changeset
421 spills = Select( );
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // Count number of Simplify-Select trips per coloring success.
a61af66fc99e Initial load
duke
parents:
diff changeset
425 _allocator_attempts += _trip_cnt + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
426 _allocator_successes += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
427
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // Peephole remove copies
a61af66fc99e Initial load
duke
parents:
diff changeset
429 post_allocate_copy_removal();
a61af66fc99e Initial load
duke
parents:
diff changeset
430
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
431 #ifdef ASSERT
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
432 // Veify the graph after RA.
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
433 verify(&live_arena);
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
434 #endif
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
435
0
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // max_reg is past the largest *register* used.
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // Convert that to a frame_slot number.
a61af66fc99e Initial load
duke
parents:
diff changeset
438 if( _max_reg <= _matcher._new_SP )
a61af66fc99e Initial load
duke
parents:
diff changeset
439 _framesize = C->out_preserve_stack_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
440 else _framesize = _max_reg -_matcher._new_SP;
a61af66fc99e Initial load
duke
parents:
diff changeset
441 assert((int)(_matcher._new_SP+_framesize) >= (int)_matcher._out_arg_limit, "framesize must be large enough");
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // This frame must preserve the required fp alignment
419
0bf25c4807f9 6761594: framesize rounding code rounds using wrong units leading to slightly oversized frames
never
parents: 295
diff changeset
444 _framesize = round_to(_framesize, Matcher::stack_alignment_in_slots());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
445 assert( _framesize >= 0 && _framesize <= 1000000, "sanity check" );
a61af66fc99e Initial load
duke
parents:
diff changeset
446 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
447 _total_framesize += _framesize;
a61af66fc99e Initial load
duke
parents:
diff changeset
448 if( (int)_framesize > _max_framesize )
a61af66fc99e Initial load
duke
parents:
diff changeset
449 _max_framesize = _framesize;
a61af66fc99e Initial load
duke
parents:
diff changeset
450 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // Convert CISC spills
a61af66fc99e Initial load
duke
parents:
diff changeset
453 fixup_spills();
a61af66fc99e Initial load
duke
parents:
diff changeset
454
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // Log regalloc results
a61af66fc99e Initial load
duke
parents:
diff changeset
456 CompileLog* log = Compile::current()->log();
a61af66fc99e Initial load
duke
parents:
diff changeset
457 if (log != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 log->elem("regalloc attempts='%d' success='%d'", _trip_cnt, !C->failing());
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 if (C->failing()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
462
a61af66fc99e Initial load
duke
parents:
diff changeset
463 NOT_PRODUCT( C->verify_graph_edges(); )
a61af66fc99e Initial load
duke
parents:
diff changeset
464
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // Move important info out of the live_arena to longer lasting storage.
a61af66fc99e Initial load
duke
parents:
diff changeset
466 alloc_node_regs(_names.Size());
a61af66fc99e Initial load
duke
parents:
diff changeset
467 for( uint i=0; i < _names.Size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
468 if( _names[i] ) { // Live range associated with Node?
a61af66fc99e Initial load
duke
parents:
diff changeset
469 LRG &lrg = lrgs( _names[i] );
a61af66fc99e Initial load
duke
parents:
diff changeset
470 if( lrg.num_regs() == 1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
471 _node_regs[i].set1( lrg.reg() );
a61af66fc99e Initial load
duke
parents:
diff changeset
472 } else { // Must be a register-pair
a61af66fc99e Initial load
duke
parents:
diff changeset
473 if( !lrg._fat_proj ) { // Must be aligned adjacent register pair
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // Live ranges record the highest register in their mask.
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // We want the low register for the AD file writer's convenience.
a61af66fc99e Initial load
duke
parents:
diff changeset
476 _node_regs[i].set2( OptoReg::add(lrg.reg(),-1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
477 } else { // Misaligned; extract 2 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
478 OptoReg::Name hi = lrg.reg(); // Get hi register
a61af66fc99e Initial load
duke
parents:
diff changeset
479 lrg.Remove(hi); // Yank from mask
a61af66fc99e Initial load
duke
parents:
diff changeset
480 int lo = lrg.mask().find_first_elem(); // Find lo
a61af66fc99e Initial load
duke
parents:
diff changeset
481 _node_regs[i].set_pair( hi, lo );
a61af66fc99e Initial load
duke
parents:
diff changeset
482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
484 if( lrg._is_oop ) _node_oops.set(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
485 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 _node_regs[i].set_bad();
a61af66fc99e Initial load
duke
parents:
diff changeset
487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // Done!
a61af66fc99e Initial load
duke
parents:
diff changeset
491 _live = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
492 _ifg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
493 C->set_indexSet_arena(NULL); // ResourceArea is at end of scope
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495
a61af66fc99e Initial load
duke
parents:
diff changeset
496 //------------------------------de_ssa-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
497 void PhaseChaitin::de_ssa() {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // Set initial Names for all Nodes. Most Nodes get the virtual register
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // number. A few get the ZERO live range number. These do not
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // get allocated, but instead rely on correct scheduling to ensure that
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // only one instance is simultaneously live at a time.
a61af66fc99e Initial load
duke
parents:
diff changeset
502 uint lr_counter = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
503 for( uint i = 0; i < _cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 Block *b = _cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
505 uint cnt = b->_nodes.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // Handle all the normal Nodes in the block
a61af66fc99e Initial load
duke
parents:
diff changeset
508 for( uint j = 0; j < cnt; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 Node *n = b->_nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // Pre-color to the zero live range, or pick virtual register
a61af66fc99e Initial load
duke
parents:
diff changeset
511 const RegMask &rm = n->out_RegMask();
a61af66fc99e Initial load
duke
parents:
diff changeset
512 _names.map( n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // Reset the Union-Find mapping to be identity
a61af66fc99e Initial load
duke
parents:
diff changeset
516 reset_uf_map(lr_counter);
a61af66fc99e Initial load
duke
parents:
diff changeset
517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
518
a61af66fc99e Initial load
duke
parents:
diff changeset
519
a61af66fc99e Initial load
duke
parents:
diff changeset
520 //------------------------------gather_lrg_masks-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // Gather LiveRanGe information, including register masks. Modification of
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // cisc spillable in_RegMasks should not be done before AggressiveCoalesce.
a61af66fc99e Initial load
duke
parents:
diff changeset
523 void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // Nail down the frame pointer live range
a61af66fc99e Initial load
duke
parents:
diff changeset
526 uint fp_lrg = n2lidx(_cfg._root->in(1)->in(TypeFunc::FramePtr));
a61af66fc99e Initial load
duke
parents:
diff changeset
527 lrgs(fp_lrg)._cost += 1e12; // Cost is infinite
a61af66fc99e Initial load
duke
parents:
diff changeset
528
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // For all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
530 for( uint i = 0; i < _cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 Block *b = _cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
532
a61af66fc99e Initial load
duke
parents:
diff changeset
533 // For all instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
534 for( uint j = 1; j < b->_nodes.size(); j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 Node *n = b->_nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
536 uint input_edge_start =1; // Skip control most nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
537 if( n->is_Mach() ) input_edge_start = n->as_Mach()->oper_input_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
538 uint idx = n->is_Copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // Get virtual register number, same as LiveRanGe index
a61af66fc99e Initial load
duke
parents:
diff changeset
541 uint vreg = n2lidx(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
542 LRG &lrg = lrgs(vreg);
a61af66fc99e Initial load
duke
parents:
diff changeset
543 if( vreg ) { // No vreg means un-allocable (e.g. memory)
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // Collect has-copy bit
a61af66fc99e Initial load
duke
parents:
diff changeset
546 if( idx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
547 lrg._has_copy = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
548 uint clidx = n2lidx(n->in(idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
549 LRG &copy_src = lrgs(clidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
550 copy_src._has_copy = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
552
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // Check for float-vs-int live range (used in register-pressure
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // calculations)
a61af66fc99e Initial load
duke
parents:
diff changeset
555 const Type *n_type = n->bottom_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
556 if( n_type->is_floatingpoint() )
a61af66fc99e Initial load
duke
parents:
diff changeset
557 lrg._is_float = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
558
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // Check for twice prior spilling. Once prior spilling might have
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // spilled 'soft', 2nd prior spill should have spilled 'hard' and
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // further spilling is unlikely to make progress.
a61af66fc99e Initial load
duke
parents:
diff changeset
562 if( _spilled_once.test(n->_idx) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
563 lrg._was_spilled1 = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
564 if( _spilled_twice.test(n->_idx) )
a61af66fc99e Initial load
duke
parents:
diff changeset
565 lrg._was_spilled2 = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
569 if (trace_spilling() && lrg._def != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // collect defs for MultiDef printing
a61af66fc99e Initial load
duke
parents:
diff changeset
571 if (lrg._defs == NULL) {
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
572 lrg._defs = new (_ifg->_arena) GrowableArray<Node*>(_ifg->_arena, 2, 0, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
573 lrg._defs->append(lrg._def);
a61af66fc99e Initial load
duke
parents:
diff changeset
574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
575 lrg._defs->append(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
576 }
a61af66fc99e Initial load
duke
parents:
diff changeset
577 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // Check for a single def LRG; these can spill nicely
a61af66fc99e Initial load
duke
parents:
diff changeset
580 // via rematerialization. Flag as NULL for no def found
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // yet, or 'n' for single def or -1 for many defs.
a61af66fc99e Initial load
duke
parents:
diff changeset
582 lrg._def = lrg._def ? NodeSentinel : n;
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // Limit result register mask to acceptable registers
a61af66fc99e Initial load
duke
parents:
diff changeset
585 const RegMask &rm = n->out_RegMask();
a61af66fc99e Initial load
duke
parents:
diff changeset
586 lrg.AND( rm );
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // Check for bound register masks
a61af66fc99e Initial load
duke
parents:
diff changeset
588 const RegMask &lrgmask = lrg.mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
589 if( lrgmask.is_bound1() || lrgmask.is_bound2() )
a61af66fc99e Initial load
duke
parents:
diff changeset
590 lrg._is_bound = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
591
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // Check for maximum frequency value
a61af66fc99e Initial load
duke
parents:
diff changeset
593 if( lrg._maxfreq < b->_freq )
a61af66fc99e Initial load
duke
parents:
diff changeset
594 lrg._maxfreq = b->_freq;
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 int ireg = n->ideal_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
597 assert( !n->bottom_type()->isa_oop_ptr() || ireg == Op_RegP,
a61af66fc99e Initial load
duke
parents:
diff changeset
598 "oops must be in Op_RegP's" );
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // Check for oop-iness, or long/double
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // Check for multi-kill projection
a61af66fc99e Initial load
duke
parents:
diff changeset
601 switch( ireg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
602 case MachProjNode::fat_proj:
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // Fat projections have size equal to number of registers killed
a61af66fc99e Initial load
duke
parents:
diff changeset
604 lrg.set_num_regs(rm.Size());
a61af66fc99e Initial load
duke
parents:
diff changeset
605 lrg.set_reg_pressure(lrg.num_regs());
a61af66fc99e Initial load
duke
parents:
diff changeset
606 lrg._fat_proj = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
607 lrg._is_bound = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
608 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
609 case Op_RegP:
a61af66fc99e Initial load
duke
parents:
diff changeset
610 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
611 lrg.set_num_regs(2); // Size is 2 stack words
a61af66fc99e Initial load
duke
parents:
diff changeset
612 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
613 lrg.set_num_regs(1); // Size is 1 stack word
a61af66fc99e Initial load
duke
parents:
diff changeset
614 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // Register pressure is tracked relative to the maximum values
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // suggested for that platform, INTPRESSURE and FLOATPRESSURE,
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // and relative to other types which compete for the same regs.
a61af66fc99e Initial load
duke
parents:
diff changeset
618 //
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // The following table contains suggested values based on the
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // architectures as defined in each .ad file.
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // INTPRESSURE and FLOATPRESSURE may be tuned differently for
a61af66fc99e Initial load
duke
parents:
diff changeset
622 // compile-speed or performance.
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // Note1:
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // SPARC and SPARCV9 reg_pressures are at 2 instead of 1
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // since .ad registers are defined as high and low halves.
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // These reg_pressure values remain compatible with the code
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // in is_high_pressure() which relates get_invalid_mask_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // Block::_reg_pressure and INTPRESSURE, FLOATPRESSURE.
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // Note2:
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // SPARC -d32 has 24 registers available for integral values,
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // but only 10 of these are safe for 64-bit longs.
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Using set_reg_pressure(2) for both int and long means
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // the allocator will believe it can fit 26 longs into
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // registers. Using 2 for longs and 1 for ints means the
a61af66fc99e Initial load
duke
parents:
diff changeset
635 // allocator will attempt to put 52 integers into registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
636 // The settings below limit this problem to methods with
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // many long values which are being run on 32-bit SPARC.
a61af66fc99e Initial load
duke
parents:
diff changeset
638 //
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // ------------------- reg_pressure --------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // Each entry is reg_pressure_per_value,number_of_regs
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // RegL RegI RegFlags RegF RegD INTPRESSURE FLOATPRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // IA32 2 1 1 1 1 6 6
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // IA64 1 1 1 1 1 50 41
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // SPARC 2 2 2 2 2 48 (24) 52 (26)
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // SPARCV9 2 2 2 2 2 48 (24) 52 (26)
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // AMD64 1 1 1 1 1 14 15
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // -----------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
648 #if defined(SPARC)
a61af66fc99e Initial load
duke
parents:
diff changeset
649 lrg.set_reg_pressure(2); // use for v9 as well
a61af66fc99e Initial load
duke
parents:
diff changeset
650 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
651 lrg.set_reg_pressure(1); // normally one value per register
a61af66fc99e Initial load
duke
parents:
diff changeset
652 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
653 if( n_type->isa_oop_ptr() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
654 lrg._is_oop = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
656 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 case Op_RegL: // Check for long or double
a61af66fc99e Initial load
duke
parents:
diff changeset
658 case Op_RegD:
a61af66fc99e Initial load
duke
parents:
diff changeset
659 lrg.set_num_regs(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // Define platform specific register pressure
a61af66fc99e Initial load
duke
parents:
diff changeset
661 #ifdef SPARC
a61af66fc99e Initial load
duke
parents:
diff changeset
662 lrg.set_reg_pressure(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
663 #elif defined(IA32)
a61af66fc99e Initial load
duke
parents:
diff changeset
664 if( ireg == Op_RegL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
665 lrg.set_reg_pressure(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
666 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
667 lrg.set_reg_pressure(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
669 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
670 lrg.set_reg_pressure(1); // normally one value per register
a61af66fc99e Initial load
duke
parents:
diff changeset
671 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // If this def of a double forces a mis-aligned double,
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // flag as '_fat_proj' - really flag as allowing misalignment
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // AND changes how we count interferences. A mis-aligned
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // double can interfere with TWO aligned pairs, or effectively
a61af66fc99e Initial load
duke
parents:
diff changeset
676 // FOUR registers!
a61af66fc99e Initial load
duke
parents:
diff changeset
677 if( rm.is_misaligned_Pair() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
678 lrg._fat_proj = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
679 lrg._is_bound = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
681 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
682 case Op_RegF:
a61af66fc99e Initial load
duke
parents:
diff changeset
683 case Op_RegI:
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
684 case Op_RegN:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
685 case Op_RegFlags:
a61af66fc99e Initial load
duke
parents:
diff changeset
686 case 0: // not an ideal register
a61af66fc99e Initial load
duke
parents:
diff changeset
687 lrg.set_num_regs(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
688 #ifdef SPARC
a61af66fc99e Initial load
duke
parents:
diff changeset
689 lrg.set_reg_pressure(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
690 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
691 lrg.set_reg_pressure(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
692 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
693 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
694 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
695 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
698
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // Now do the same for inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
700 uint cnt = n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // Setup for CISC SPILLING
a61af66fc99e Initial load
duke
parents:
diff changeset
702 uint inp = (uint)AdlcVMDeps::Not_cisc_spillable;
a61af66fc99e Initial load
duke
parents:
diff changeset
703 if( UseCISCSpill && after_aggressive ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
704 inp = n->cisc_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
705 if( inp != (uint)AdlcVMDeps::Not_cisc_spillable )
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // Convert operand number to edge index number
a61af66fc99e Initial load
duke
parents:
diff changeset
707 inp = n->as_Mach()->operand_index(inp);
a61af66fc99e Initial load
duke
parents:
diff changeset
708 }
a61af66fc99e Initial load
duke
parents:
diff changeset
709 // Prepare register mask for each input
a61af66fc99e Initial load
duke
parents:
diff changeset
710 for( uint k = input_edge_start; k < cnt; k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
711 uint vreg = n2lidx(n->in(k));
a61af66fc99e Initial load
duke
parents:
diff changeset
712 if( !vreg ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // If this instruction is CISC Spillable, add the flags
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // bit to its appropriate input
a61af66fc99e Initial load
duke
parents:
diff changeset
716 if( UseCISCSpill && after_aggressive && inp == k ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
717 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
718 if( TraceCISCSpill ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
719 tty->print(" use_cisc_RegMask: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
720 n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
722 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
723 n->as_Mach()->use_cisc_RegMask();
a61af66fc99e Initial load
duke
parents:
diff changeset
724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
725
a61af66fc99e Initial load
duke
parents:
diff changeset
726 LRG &lrg = lrgs(vreg);
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // // Testing for floating point code shape
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // Node *test = n->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // if( test->is_Mach() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // MachNode *m = test->as_Mach();
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // int op = m->ideal_Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // if (n->is_Call() && (op == Op_AddF || op == Op_MulF) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // int zzz = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
736
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // Limit result register mask to acceptable registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // Do not limit registers from uncommon uses before
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // AggressiveCoalesce. This effectively pre-virtual-splits
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // around uncommon uses of common defs.
a61af66fc99e Initial load
duke
parents:
diff changeset
741 const RegMask &rm = n->in_RegMask(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
742 if( !after_aggressive &&
a61af66fc99e Initial load
duke
parents:
diff changeset
743 _cfg._bbs[n->in(k)->_idx]->_freq > 1000*b->_freq ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
744 // Since we are BEFORE aggressive coalesce, leave the register
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // mask untrimmed by the call. This encourages more coalescing.
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // Later, AFTER aggressive, this live range will have to spill
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // but the spiller handles slow-path calls very nicely.
a61af66fc99e Initial load
duke
parents:
diff changeset
748 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
749 lrg.AND( rm );
a61af66fc99e Initial load
duke
parents:
diff changeset
750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // Check for bound register masks
a61af66fc99e Initial load
duke
parents:
diff changeset
752 const RegMask &lrgmask = lrg.mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
753 if( lrgmask.is_bound1() || lrgmask.is_bound2() )
a61af66fc99e Initial load
duke
parents:
diff changeset
754 lrg._is_bound = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
755 // If this use of a double forces a mis-aligned double,
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // flag as '_fat_proj' - really flag as allowing misalignment
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // AND changes how we count interferences. A mis-aligned
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // double can interfere with TWO aligned pairs, or effectively
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // FOUR registers!
a61af66fc99e Initial load
duke
parents:
diff changeset
760 if( lrg.num_regs() == 2 && !lrg._fat_proj && rm.is_misaligned_Pair() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
761 lrg._fat_proj = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
762 lrg._is_bound = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
764 // if the LRG is an unaligned pair, we will have to spill
a61af66fc99e Initial load
duke
parents:
diff changeset
765 // so clear the LRG's register mask if it is not already spilled
a61af66fc99e Initial load
duke
parents:
diff changeset
766 if ( !n->is_SpillCopy() &&
295
ea18057223c4 6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents: 196
diff changeset
767 (lrg._def == NULL || lrg.is_multidef() || !lrg._def->is_SpillCopy()) &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
768 lrgmask.is_misaligned_Pair()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
769 lrg.Clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
770 }
a61af66fc99e Initial load
duke
parents:
diff changeset
771
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // Check for maximum frequency value
a61af66fc99e Initial load
duke
parents:
diff changeset
773 if( lrg._maxfreq < b->_freq )
a61af66fc99e Initial load
duke
parents:
diff changeset
774 lrg._maxfreq = b->_freq;
a61af66fc99e Initial load
duke
parents:
diff changeset
775
a61af66fc99e Initial load
duke
parents:
diff changeset
776 } // End for all allocated inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
777 } // end for all instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
778 } // end for all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
779
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // Final per-liverange setup
a61af66fc99e Initial load
duke
parents:
diff changeset
781 for( uint i2=0; i2<_maxlrg; i2++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 LRG &lrg = lrgs(i2);
a61af66fc99e Initial load
duke
parents:
diff changeset
783 if( lrg.num_regs() == 2 && !lrg._fat_proj )
a61af66fc99e Initial load
duke
parents:
diff changeset
784 lrg.ClearToPairs();
a61af66fc99e Initial load
duke
parents:
diff changeset
785 lrg.compute_set_mask_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
786 if( lrg.not_free() ) { // Handle case where we lose from the start
a61af66fc99e Initial load
duke
parents:
diff changeset
787 lrg.set_reg(OptoReg::Name(LRG::SPILL_REG));
a61af66fc99e Initial load
duke
parents:
diff changeset
788 lrg._direct_conflict = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
790 lrg.set_degree(0); // no neighbors in IFG yet
a61af66fc99e Initial load
duke
parents:
diff changeset
791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
793
a61af66fc99e Initial load
duke
parents:
diff changeset
794 //------------------------------set_was_low------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
795 // Set the was-lo-degree bit. Conservative coalescing should not change the
a61af66fc99e Initial load
duke
parents:
diff changeset
796 // colorability of the graph. If any live range was of low-degree before
a61af66fc99e Initial load
duke
parents:
diff changeset
797 // coalescing, it should Simplify. This call sets the was-lo-degree bit.
a61af66fc99e Initial load
duke
parents:
diff changeset
798 // The bit is checked in Simplify.
a61af66fc99e Initial load
duke
parents:
diff changeset
799 void PhaseChaitin::set_was_low() {
a61af66fc99e Initial load
duke
parents:
diff changeset
800 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
801 for( uint i = 1; i < _maxlrg; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
802 int size = lrgs(i).num_regs();
a61af66fc99e Initial load
duke
parents:
diff changeset
803 uint old_was_lo = lrgs(i)._was_lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
804 lrgs(i)._was_lo = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
805 if( lrgs(i).lo_degree() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
806 lrgs(i)._was_lo = 1; // Trivially of low degree
a61af66fc99e Initial load
duke
parents:
diff changeset
807 } else { // Else check the Brigg's assertion
a61af66fc99e Initial load
duke
parents:
diff changeset
808 // Brigg's observation is that the lo-degree neighbors of a
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // hi-degree live range will not interfere with the color choices
a61af66fc99e Initial load
duke
parents:
diff changeset
810 // of said hi-degree live range. The Simplify reverse-stack-coloring
a61af66fc99e Initial load
duke
parents:
diff changeset
811 // order takes care of the details. Hence you do not have to count
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // low-degree neighbors when determining if this guy colors.
a61af66fc99e Initial load
duke
parents:
diff changeset
813 int briggs_degree = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
814 IndexSet *s = _ifg->neighbors(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
815 IndexSetIterator elements(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
816 uint lidx;
a61af66fc99e Initial load
duke
parents:
diff changeset
817 while((lidx = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
818 if( !lrgs(lidx).lo_degree() )
a61af66fc99e Initial load
duke
parents:
diff changeset
819 briggs_degree += MAX2(size,lrgs(lidx).num_regs());
a61af66fc99e Initial load
duke
parents:
diff changeset
820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
821 if( briggs_degree < lrgs(i).degrees_of_freedom() )
a61af66fc99e Initial load
duke
parents:
diff changeset
822 lrgs(i)._was_lo = 1; // Low degree via the briggs assertion
a61af66fc99e Initial load
duke
parents:
diff changeset
823 }
a61af66fc99e Initial load
duke
parents:
diff changeset
824 assert(old_was_lo <= lrgs(i)._was_lo, "_was_lo may not decrease");
a61af66fc99e Initial load
duke
parents:
diff changeset
825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
826 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 #define REGISTER_CONSTRAINED 16
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 //------------------------------cache_lrg_info---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
832 // Compute cost/area ratio, in case we spill. Build the lo-degree list.
a61af66fc99e Initial load
duke
parents:
diff changeset
833 void PhaseChaitin::cache_lrg_info( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
834
a61af66fc99e Initial load
duke
parents:
diff changeset
835 for( uint i = 1; i < _maxlrg; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
836 LRG &lrg = lrgs(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
837
a61af66fc99e Initial load
duke
parents:
diff changeset
838 // Check for being of low degree: means we can be trivially colored.
a61af66fc99e Initial load
duke
parents:
diff changeset
839 // Low degree, dead or must-spill guys just get to simplify right away
a61af66fc99e Initial load
duke
parents:
diff changeset
840 if( lrg.lo_degree() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
841 !lrg.alive() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
842 lrg._must_spill ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
843 // Split low degree list into those guys that must get a
a61af66fc99e Initial load
duke
parents:
diff changeset
844 // register and those that can go to register or stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
845 // The idea is LRGs that can go register or stack color first when
a61af66fc99e Initial load
duke
parents:
diff changeset
846 // they have a good chance of getting a register. The register-only
a61af66fc99e Initial load
duke
parents:
diff changeset
847 // lo-degree live ranges always get a register.
a61af66fc99e Initial load
duke
parents:
diff changeset
848 OptoReg::Name hi_reg = lrg.mask().find_last_elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
849 if( OptoReg::is_stack(hi_reg)) { // Can go to stack?
a61af66fc99e Initial load
duke
parents:
diff changeset
850 lrg._next = _lo_stk_degree;
a61af66fc99e Initial load
duke
parents:
diff changeset
851 _lo_stk_degree = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
852 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
853 lrg._next = _lo_degree;
a61af66fc99e Initial load
duke
parents:
diff changeset
854 _lo_degree = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
856 } else { // Else high degree
a61af66fc99e Initial load
duke
parents:
diff changeset
857 lrgs(_hi_degree)._prev = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
858 lrg._next = _hi_degree;
a61af66fc99e Initial load
duke
parents:
diff changeset
859 lrg._prev = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
860 _hi_degree = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
864
a61af66fc99e Initial load
duke
parents:
diff changeset
865 //------------------------------Pre-Simplify-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
866 // Simplify the IFG by removing LRGs of low degree that have NO copies
a61af66fc99e Initial load
duke
parents:
diff changeset
867 void PhaseChaitin::Pre_Simplify( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
868
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // Warm up the lo-degree no-copy list
a61af66fc99e Initial load
duke
parents:
diff changeset
870 int lo_no_copy = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
871 for( uint i = 1; i < _maxlrg; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
872 if( (lrgs(i).lo_degree() && !lrgs(i)._has_copy) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
873 !lrgs(i).alive() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
874 lrgs(i)._must_spill ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
875 lrgs(i)._next = lo_no_copy;
a61af66fc99e Initial load
duke
parents:
diff changeset
876 lo_no_copy = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
878 }
a61af66fc99e Initial load
duke
parents:
diff changeset
879
a61af66fc99e Initial load
duke
parents:
diff changeset
880 while( lo_no_copy ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
881 uint lo = lo_no_copy;
a61af66fc99e Initial load
duke
parents:
diff changeset
882 lo_no_copy = lrgs(lo)._next;
a61af66fc99e Initial load
duke
parents:
diff changeset
883 int size = lrgs(lo).num_regs();
a61af66fc99e Initial load
duke
parents:
diff changeset
884
a61af66fc99e Initial load
duke
parents:
diff changeset
885 // Put the simplified guy on the simplified list.
a61af66fc99e Initial load
duke
parents:
diff changeset
886 lrgs(lo)._next = _simplified;
a61af66fc99e Initial load
duke
parents:
diff changeset
887 _simplified = lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
888
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // Yank this guy from the IFG.
a61af66fc99e Initial load
duke
parents:
diff changeset
890 IndexSet *adj = _ifg->remove_node( lo );
a61af66fc99e Initial load
duke
parents:
diff changeset
891
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // If any neighbors' degrees fall below their number of
a61af66fc99e Initial load
duke
parents:
diff changeset
893 // allowed registers, then put that neighbor on the low degree
a61af66fc99e Initial load
duke
parents:
diff changeset
894 // list. Note that 'degree' can only fall and 'numregs' is
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // unchanged by this action. Thus the two are equal at most once,
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // so LRGs hit the lo-degree worklists at most once.
a61af66fc99e Initial load
duke
parents:
diff changeset
897 IndexSetIterator elements(adj);
a61af66fc99e Initial load
duke
parents:
diff changeset
898 uint neighbor;
a61af66fc99e Initial load
duke
parents:
diff changeset
899 while ((neighbor = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
900 LRG *n = &lrgs(neighbor);
a61af66fc99e Initial load
duke
parents:
diff changeset
901 assert( _ifg->effective_degree(neighbor) == n->degree(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
902
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // Check for just becoming of-low-degree
a61af66fc99e Initial load
duke
parents:
diff changeset
904 if( n->just_lo_degree() && !n->_has_copy ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
905 assert(!(*_ifg->_yanked)[neighbor],"Cannot move to lo degree twice");
a61af66fc99e Initial load
duke
parents:
diff changeset
906 // Put on lo-degree list
a61af66fc99e Initial load
duke
parents:
diff changeset
907 n->_next = lo_no_copy;
a61af66fc99e Initial load
duke
parents:
diff changeset
908 lo_no_copy = neighbor;
a61af66fc99e Initial load
duke
parents:
diff changeset
909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
911 } // End of while lo-degree no_copy worklist not empty
a61af66fc99e Initial load
duke
parents:
diff changeset
912
a61af66fc99e Initial load
duke
parents:
diff changeset
913 // No more lo-degree no-copy live ranges to simplify
a61af66fc99e Initial load
duke
parents:
diff changeset
914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
915
a61af66fc99e Initial load
duke
parents:
diff changeset
916 //------------------------------Simplify---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
917 // Simplify the IFG by removing LRGs of low degree.
a61af66fc99e Initial load
duke
parents:
diff changeset
918 void PhaseChaitin::Simplify( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 while( 1 ) { // Repeat till simplified it all
a61af66fc99e Initial load
duke
parents:
diff changeset
921 // May want to explore simplifying lo_degree before _lo_stk_degree.
a61af66fc99e Initial load
duke
parents:
diff changeset
922 // This might result in more spills coloring into registers during
a61af66fc99e Initial load
duke
parents:
diff changeset
923 // Select().
a61af66fc99e Initial load
duke
parents:
diff changeset
924 while( _lo_degree || _lo_stk_degree ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // If possible, pull from lo_stk first
a61af66fc99e Initial load
duke
parents:
diff changeset
926 uint lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
927 if( _lo_degree ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
928 lo = _lo_degree;
a61af66fc99e Initial load
duke
parents:
diff changeset
929 _lo_degree = lrgs(lo)._next;
a61af66fc99e Initial load
duke
parents:
diff changeset
930 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
931 lo = _lo_stk_degree;
a61af66fc99e Initial load
duke
parents:
diff changeset
932 _lo_stk_degree = lrgs(lo)._next;
a61af66fc99e Initial load
duke
parents:
diff changeset
933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
934
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // Put the simplified guy on the simplified list.
a61af66fc99e Initial load
duke
parents:
diff changeset
936 lrgs(lo)._next = _simplified;
a61af66fc99e Initial load
duke
parents:
diff changeset
937 _simplified = lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
938 // If this guy is "at risk" then mark his current neighbors
a61af66fc99e Initial load
duke
parents:
diff changeset
939 if( lrgs(lo)._at_risk ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
940 IndexSetIterator elements(_ifg->neighbors(lo));
a61af66fc99e Initial load
duke
parents:
diff changeset
941 uint datum;
a61af66fc99e Initial load
duke
parents:
diff changeset
942 while ((datum = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
943 lrgs(datum)._risk_bias = lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 // Yank this guy from the IFG.
a61af66fc99e Initial load
duke
parents:
diff changeset
948 IndexSet *adj = _ifg->remove_node( lo );
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // If any neighbors' degrees fall below their number of
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // allowed registers, then put that neighbor on the low degree
a61af66fc99e Initial load
duke
parents:
diff changeset
952 // list. Note that 'degree' can only fall and 'numregs' is
a61af66fc99e Initial load
duke
parents:
diff changeset
953 // unchanged by this action. Thus the two are equal at most once,
a61af66fc99e Initial load
duke
parents:
diff changeset
954 // so LRGs hit the lo-degree worklist at most once.
a61af66fc99e Initial load
duke
parents:
diff changeset
955 IndexSetIterator elements(adj);
a61af66fc99e Initial load
duke
parents:
diff changeset
956 uint neighbor;
a61af66fc99e Initial load
duke
parents:
diff changeset
957 while ((neighbor = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
958 LRG *n = &lrgs(neighbor);
a61af66fc99e Initial load
duke
parents:
diff changeset
959 #ifdef ASSERT
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 419
diff changeset
960 if( VerifyOpto || VerifyRegisterAllocator ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
961 assert( _ifg->effective_degree(neighbor) == n->degree(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
962 }
a61af66fc99e Initial load
duke
parents:
diff changeset
963 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
964
a61af66fc99e Initial load
duke
parents:
diff changeset
965 // Check for just becoming of-low-degree just counting registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
966 // _must_spill live ranges are already on the low degree list.
a61af66fc99e Initial load
duke
parents:
diff changeset
967 if( n->just_lo_degree() && !n->_must_spill ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
968 assert(!(*_ifg->_yanked)[neighbor],"Cannot move to lo degree twice");
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // Pull from hi-degree list
a61af66fc99e Initial load
duke
parents:
diff changeset
970 uint prev = n->_prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
971 uint next = n->_next;
a61af66fc99e Initial load
duke
parents:
diff changeset
972 if( prev ) lrgs(prev)._next = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
973 else _hi_degree = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
974 lrgs(next)._prev = prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
975 n->_next = _lo_degree;
a61af66fc99e Initial load
duke
parents:
diff changeset
976 _lo_degree = neighbor;
a61af66fc99e Initial load
duke
parents:
diff changeset
977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
979 } // End of while lo-degree/lo_stk_degree worklist not empty
a61af66fc99e Initial load
duke
parents:
diff changeset
980
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // Check for got everything: is hi-degree list empty?
a61af66fc99e Initial load
duke
parents:
diff changeset
982 if( !_hi_degree ) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
983
a61af66fc99e Initial load
duke
parents:
diff changeset
984 // Time to pick a potential spill guy
a61af66fc99e Initial load
duke
parents:
diff changeset
985 uint lo_score = _hi_degree;
a61af66fc99e Initial load
duke
parents:
diff changeset
986 double score = lrgs(lo_score).score();
a61af66fc99e Initial load
duke
parents:
diff changeset
987 double area = lrgs(lo_score)._area;
1008
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
988 double cost = lrgs(lo_score)._cost;
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
989 bool bound = lrgs(lo_score)._is_bound;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
990
a61af66fc99e Initial load
duke
parents:
diff changeset
991 // Find cheapest guy
a61af66fc99e Initial load
duke
parents:
diff changeset
992 debug_only( int lo_no_simplify=0; );
1012
5f29a958a545 6889656: assert(lo_lrg->lo_degree() || !lo_no_simplify,"Live range was lo-degree before coalesce
kvn
parents: 1008
diff changeset
993 for( uint i = _hi_degree; i; i = lrgs(i)._next ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
994 assert( !(*_ifg->_yanked)[i], "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
995 // It's just vaguely possible to move hi-degree to lo-degree without
a61af66fc99e Initial load
duke
parents:
diff changeset
996 // going through a just-lo-degree stage: If you remove a double from
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // a float live range it's degree will drop by 2 and you can skip the
a61af66fc99e Initial load
duke
parents:
diff changeset
998 // just-lo-degree stage. It's very rare (shows up after 5000+ methods
a61af66fc99e Initial load
duke
parents:
diff changeset
999 // in -Xcomp of Java2Demo). So just choose this guy to simplify next.
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 if( lrgs(i).lo_degree() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 lo_score = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 debug_only( if( lrgs(i)._was_lo ) lo_no_simplify=i; );
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 double iscore = lrgs(i).score();
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 double iarea = lrgs(i)._area;
1008
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
1007 double icost = lrgs(i)._cost;
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
1008 bool ibound = lrgs(i)._is_bound;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1009
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 // Compare cost/area of i vs cost/area of lo_score. Smaller cost/area
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 // wins. Ties happen because all live ranges in question have spilled
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 // a few times before and the spill-score adds a huge number which
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // washes out the low order bits. We are choosing the lesser of 2
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // evils; in this case pick largest area to spill.
1008
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
1015 // Ties also happen when live ranges are defined and used only inside
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
1016 // one block. In which case their area is 0 and score set to max.
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
1017 // In such case choose bound live range over unbound to free registers
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
1018 // or with smaller cost to spill.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 if( iscore < score ||
1008
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
1020 (iscore == score && iarea > area && lrgs(lo_score)._was_spilled2) ||
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
1021 (iscore == score && iarea == area &&
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
1022 ( (ibound && !bound) || ibound == bound && (icost < cost) )) ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 lo_score = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 score = iscore;
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 area = iarea;
1008
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
1026 cost = icost;
e90521d61f9a 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087
kvn
parents: 729
diff changeset
1027 bound = ibound;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 LRG *lo_lrg = &lrgs(lo_score);
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 // The live range we choose for spilling is either hi-degree, or very
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 // rarely it can be low-degree. If we choose a hi-degree live range
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // there better not be any lo-degree choices.
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 assert( lo_lrg->lo_degree() || !lo_no_simplify, "Live range was lo-degree before coalesce; should simplify" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1035
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 // Pull from hi-degree list
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 uint prev = lo_lrg->_prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 uint next = lo_lrg->_next;
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 if( prev ) lrgs(prev)._next = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 else _hi_degree = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 lrgs(next)._prev = prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 // Jam him on the lo-degree list, despite his high degree.
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 // Maybe he'll get a color, and maybe he'll spill.
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 // Only Select() will know.
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 lrgs(lo_score)._at_risk = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 _lo_degree = lo_score;
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 lo_lrg->_next = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1048
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 } // End of while not simplified everything
a61af66fc99e Initial load
duke
parents:
diff changeset
1050
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1052
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 //------------------------------bias_color-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 // Choose a color using the biasing heuristic
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 OptoReg::Name PhaseChaitin::bias_color( LRG &lrg, int chunk ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1056
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 // Check for "at_risk" LRG's
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 uint risk_lrg = Find(lrg._risk_bias);
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 if( risk_lrg != 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 // Walk the colored neighbors of the "at_risk" candidate
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // Choose a color which is both legal and already taken by a neighbor
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 // of the "at_risk" candidate in order to improve the chances of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 // "at_risk" candidate of coloring
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 IndexSetIterator elements(_ifg->neighbors(risk_lrg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 uint datum;
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 while ((datum = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 OptoReg::Name reg = lrgs(datum).reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 // If this LRG's register is legal for us, choose it
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 if( reg >= chunk && reg < chunk + RegMask::CHUNK_SIZE &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 lrg.mask().Member(OptoReg::add(reg,-chunk)) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 (lrg.num_regs()==1 || // either size 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 (reg&1) == 1) ) // or aligned (adjacent reg is available since we already cleared-to-pairs)
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 return reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 uint copy_lrg = Find(lrg._copy_bias);
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 if( copy_lrg != 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // If he has a color,
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 if( !(*(_ifg->_yanked))[copy_lrg] ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 OptoReg::Name reg = lrgs(copy_lrg).reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 // And it is legal for you,
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 if( reg >= chunk && reg < chunk + RegMask::CHUNK_SIZE &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 lrg.mask().Member(OptoReg::add(reg,-chunk)) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 (lrg.num_regs()==1 || // either size 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 (reg&1) == 1) ) // or aligned (adjacent reg is available since we already cleared-to-pairs)
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 return reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 } else if( chunk == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 // Choose a color which is legal for him
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 RegMask tempmask = lrg.mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 tempmask.AND(lrgs(copy_lrg).mask());
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 OptoReg::Name reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 if( lrg.num_regs() == 1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 reg = tempmask.find_first_elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 tempmask.ClearToPairs();
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 reg = tempmask.find_first_pair();
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 if( OptoReg::is_valid(reg) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 return reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1103
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 // If no bias info exists, just go with the register selection ordering
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 if( lrg.num_regs() == 2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 // Find an aligned pair
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 return OptoReg::add(lrg.mask().find_first_pair(),chunk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1109
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // CNC - Fun hack. Alternate 1st and 2nd selection. Enables post-allocate
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 // copy removal to remove many more copies, by preventing a just-assigned
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 // register from being repeatedly assigned.
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 OptoReg::Name reg = lrg.mask().find_first_elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 if( (++_alternate & 1) && OptoReg::is_valid(reg) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 // This 'Remove; find; Insert' idiom is an expensive way to find the
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 // SECOND element in the mask.
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 lrg.Remove(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 OptoReg::Name reg2 = lrg.mask().find_first_elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 lrg.Insert(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 if( OptoReg::is_reg(reg2))
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 reg = reg2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 return OptoReg::add( reg, chunk );
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1125
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 //------------------------------choose_color-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // Choose a color in the current chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 OptoReg::Name PhaseChaitin::choose_color( LRG &lrg, int chunk ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 assert( C->in_preserve_stack_slots() == 0 || chunk != 0 || lrg._is_bound || lrg.mask().is_bound1() || !lrg.mask().Member(OptoReg::Name(_matcher._old_SP-1)), "must not allocate stack0 (inside preserve area)");
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 assert(C->out_preserve_stack_slots() == 0 || chunk != 0 || lrg._is_bound || lrg.mask().is_bound1() || !lrg.mask().Member(OptoReg::Name(_matcher._old_SP+0)), "must not allocate stack0 (inside preserve area)");
a61af66fc99e Initial load
duke
parents:
diff changeset
1131
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 if( lrg.num_regs() == 1 || // Common Case
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 !lrg._fat_proj ) // Aligned+adjacent pairs ok
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 // Use a heuristic to "bias" the color choice
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 return bias_color(lrg, chunk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1136
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 assert( lrg.num_regs() >= 2, "dead live ranges do not color" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1138
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // Fat-proj case or misaligned double argument.
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 assert(lrg.compute_mask_size() == lrg.num_regs() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 lrg.num_regs() == 2,"fat projs exactly color" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 assert( !chunk, "always color in 1st chunk" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 // Return the highest element in the set.
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 return lrg.mask().find_last_elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1146
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 //------------------------------Select-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 // Select colors by re-inserting LRGs back into the IFG. LRGs are re-inserted
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 // in reverse order of removal. As long as nothing of hi-degree was yanked,
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 // everything going back is guaranteed a color. Select that color. If some
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // hi-degree LRG cannot get a color then we record that we must spill.
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 uint PhaseChaitin::Select( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 uint spill_reg = LRG::SPILL_REG;
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 _max_reg = OptoReg::Name(0); // Past max register used
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 while( _simplified ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 // Pull next LRG from the simplified list - in reverse order of removal
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 uint lidx = _simplified;
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 LRG *lrg = &lrgs(lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 _simplified = lrg->_next;
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 if (trace_spilling()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 ttyLocker ttyl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 tty->print_cr("L%d selecting degree %d degrees_of_freedom %d", lidx, lrg->degree(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 lrg->degrees_of_freedom());
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 lrg->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1170
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // Re-insert into the IFG
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 _ifg->re_insert(lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 if( !lrg->alive() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // capture allstackedness flag before mask is hacked
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 const int is_allstack = lrg->mask().is_AllStack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1176
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // Yeah, yeah, yeah, I know, I know. I can refactor this
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 // to avoid the GOTO, although the refactored code will not
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 // be much clearer. We arrive here IFF we have a stack-based
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 // live range that cannot color in the current chunk, and it
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 // has to move into the next free stack chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 int chunk = 0; // Current chunk is first chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 retry_next_chunk:
a61af66fc99e Initial load
duke
parents:
diff changeset
1184
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 // Remove neighbor colors
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 IndexSet *s = _ifg->neighbors(lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1187
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 debug_only(RegMask orig_mask = lrg->mask();)
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 IndexSetIterator elements(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 uint neighbor;
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 while ((neighbor = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 // Note that neighbor might be a spill_reg. In this case, exclusion
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 // of its color will be a no-op, since the spill_reg chunk is in outer
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // space. Also, if neighbor is in a different chunk, this exclusion
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // will be a no-op. (Later on, if lrg runs out of possible colors in
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // its chunk, a new chunk of color may be tried, in which case
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // examination of neighbors is started again, at retry_next_chunk.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 LRG &nlrg = lrgs(neighbor);
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 OptoReg::Name nreg = nlrg.reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // Only subtract masks in the same chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 if( nreg >= chunk && nreg < chunk + RegMask::CHUNK_SIZE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 uint size = lrg->mask().Size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 RegMask rm = lrg->mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 lrg->SUBTRACT(nlrg.mask());
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 if (trace_spilling() && lrg->mask().Size() != size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 ttyLocker ttyl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 tty->print("L%d ", lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 rm.dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 tty->print(" intersected L%d ", neighbor);
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 nlrg.mask().dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 tty->print(" removed ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 rm.SUBTRACT(lrg->mask());
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 rm.dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 tty->print(" leaving ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 lrg->mask().dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 //assert(is_allstack == lrg->mask().is_AllStack(), "nbrs must not change AllStackedness");
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 // Aligned pairs need aligned masks
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 if( lrg->num_regs() == 2 && !lrg->_fat_proj )
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 lrg->ClearToPairs();
a61af66fc99e Initial load
duke
parents:
diff changeset
1228
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 // Check if a color is available and if so pick the color
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 OptoReg::Name reg = choose_color( *lrg, chunk );
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 #ifdef SPARC
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 debug_only(lrg->compute_set_mask_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 assert(lrg->num_regs() != 2 || lrg->is_bound() || is_even(reg-1), "allocate all doubles aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1235
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 //---------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 // If we fail to color and the AllStack flag is set, trigger
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // a chunk-rollover event
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 if(!OptoReg::is_valid(OptoReg::add(reg,-chunk)) && is_allstack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 // Bump register mask up to next stack chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 chunk += RegMask::CHUNK_SIZE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 lrg->Set_All();
a61af66fc99e Initial load
duke
parents:
diff changeset
1243
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 goto retry_next_chunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1246
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 //---------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 // Did we get a color?
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 else if( OptoReg::is_valid(reg)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 RegMask avail_rm = lrg->mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1253
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 // Record selected register
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 lrg->set_reg(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1256
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 if( reg >= _max_reg ) // Compute max register limit
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 _max_reg = OptoReg::add(reg,1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 // Fold reg back into normal space
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 reg = OptoReg::add(reg,-chunk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1261
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 // If the live range is not bound, then we actually had some choices
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // to make. In this case, the mask has more bits in it than the colors
605
98cb887364d3 6810672: Comment typos
twisti
parents: 566
diff changeset
1264 // chosen. Restrict the mask to just what was picked.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 if( lrg->num_regs() == 1 ) { // Size 1 live range
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 lrg->Clear(); // Clear the mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 lrg->Insert(reg); // Set regmask to match selected reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 lrg->set_mask_size(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 } else if( !lrg->_fat_proj ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 // For pairs, also insert the low bit of the pair
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 assert( lrg->num_regs() == 2, "unbound fatproj???" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 lrg->Clear(); // Clear the mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 lrg->Insert(reg); // Set regmask to match selected reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 lrg->Insert(OptoReg::add(reg,-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 lrg->set_mask_size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 } else { // Else fatproj
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // mask must be equal to fatproj bits, by definition
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 if (trace_spilling()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 ttyLocker ttyl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 tty->print("L%d selected ", lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 lrg->mask().dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 tty->print(" from ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 avail_rm.dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 // Note that reg is the highest-numbered register in the newly-bound mask.
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 } // end color available case
a61af66fc99e Initial load
duke
parents:
diff changeset
1291
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 //---------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // Live range is live and no colors available
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 assert( lrg->alive(), "" );
295
ea18057223c4 6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents: 196
diff changeset
1296 assert( !lrg->_fat_proj || lrg->is_multidef() ||
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 lrg->_def->outcnt() > 0, "fat_proj cannot spill");
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 assert( !orig_mask.is_AllStack(), "All Stack does not spill" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1299
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 // Assign the special spillreg register
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 lrg->set_reg(OptoReg::Name(spill_reg++));
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 // Do not empty the regmask; leave mask_size lying around
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 // for use during Spilling
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 if( trace_spilling() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 ttyLocker ttyl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 tty->print("L%d spilling with neighbors: ", lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 s->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 debug_only(tty->print(" original mask: "));
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 debug_only(orig_mask.dump());
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 dump_lrg(lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 } // end spill case
a61af66fc99e Initial load
duke
parents:
diff changeset
1315
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1317
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 return spill_reg-LRG::SPILL_REG; // Return number of spills
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1320
a61af66fc99e Initial load
duke
parents:
diff changeset
1321
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 //------------------------------copy_was_spilled-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // Copy 'was_spilled'-edness from the source Node to the dst Node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 void PhaseChaitin::copy_was_spilled( Node *src, Node *dst ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 if( _spilled_once.test(src->_idx) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 _spilled_once.set(dst->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 lrgs(Find(dst))._was_spilled1 = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 if( _spilled_twice.test(src->_idx) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 _spilled_twice.set(dst->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 lrgs(Find(dst))._was_spilled2 = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1334
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 //------------------------------set_was_spilled--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 // Set the 'spilled_once' or 'spilled_twice' flag on a node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 void PhaseChaitin::set_was_spilled( Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 if( _spilled_once.test_set(n->_idx) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 _spilled_twice.set(n->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1341
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 //------------------------------fixup_spills-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // Convert Ideal spill instructions into proper FramePtr + offset Loads and
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 // Stores. Use-def chains are NOT preserved, but Node->LRG->reg maps are.
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 void PhaseChaitin::fixup_spills() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 // This function does only cisc spill work.
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 if( !UseCISCSpill ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1348
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 NOT_PRODUCT( Compile::TracePhase t3("fixupSpills", &_t_fixupSpills, TimeCompiler); )
a61af66fc99e Initial load
duke
parents:
diff changeset
1350
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 // Grab the Frame Pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 Node *fp = _cfg._broot->head()->in(1)->in(TypeFunc::FramePtr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1353
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 // For all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 for( uint i = 0; i < _cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 Block *b = _cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1357
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 // For all instructions in block
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 uint last_inst = b->end_idx();
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 for( uint j = 1; j <= last_inst; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 Node *n = b->_nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
1362
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 // Dead instruction???
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 assert( n->outcnt() != 0 ||// Nothing dead after post alloc
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 C->top() == n || // Or the random TOP node
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 n->is_Proj(), // Or a fat-proj kill node
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 "No dead instructions after post-alloc" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1368
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 int inp = n->cisc_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 if( inp != AdlcVMDeps::Not_cisc_spillable ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // Convert operand number to edge index number
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 MachNode *mach = n->as_Mach();
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 inp = mach->operand_index(inp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 Node *src = n->in(inp); // Value to load or store
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 LRG &lrg_cisc = lrgs( Find_const(src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 OptoReg::Name src_reg = lrg_cisc.reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // Doubles record the HIGH register of an adjacent pair.
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 src_reg = OptoReg::add(src_reg,1-lrg_cisc.num_regs());
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 if( OptoReg::is_stack(src_reg) ) { // If input is on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 // This is a CISC Spill, get stack offset and construct new node
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 if( TraceCISCSpill ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 tty->print(" reg-instr: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 int stk_offset = reg2offset(src_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 // Bailout if we might exceed node limit when spilling this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 C->check_node_count(0, "out of nodes fixing spills");
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 if (C->failing()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 // Transform node
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 MachNode *cisc = mach->cisc_version(stk_offset, C)->as_Mach();
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 cisc->set_req(inp,fp); // Base register is frame pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 if( cisc->oper_input_base() > 1 && mach->oper_input_base() <= 1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 assert( cisc->oper_input_base() == 2, "Only adding one edge");
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 cisc->ins_req(1,src); // Requires a memory edge
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 b->_nodes.map(j,cisc); // Insert into basic block
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 113
diff changeset
1399 n->subsume_by(cisc); // Correct graph
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 ++_used_cisc_instructions;
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 if( TraceCISCSpill ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 tty->print(" cisc-instr: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 cisc->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 if( TraceCISCSpill ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 tty->print(" using reg-instr: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 ++_unused_cisc_instructions; // input can be on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1418
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 } // End of for all instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
1420
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 } // End of for all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1423
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 //------------------------------find_base_for_derived--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 // Helper to stretch above; recursively discover the base Node for a
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 // given derived Node. Easy for AddP-related machine nodes, but needs
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 // to be recursive for derived Phis.
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derived, uint &maxlrg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 // See if already computed; if so return it
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 if( derived_base_map[derived->_idx] )
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 return derived_base_map[derived->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1432
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 // See if this happens to be a base.
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 // NOTE: we use TypePtr instead of TypeOopPtr because we can have
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 // pointers derived from NULL! These are always along paths that
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 // can't happen at run-time but the optimizer cannot deduce it so
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 // we have to handle it gracefully.
729
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1438 assert(!derived->bottom_type()->isa_narrowoop() ||
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1439 derived->bottom_type()->make_ptr()->is_ptr()->_offset == 0, "sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 const TypePtr *tj = derived->bottom_type()->isa_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 // If its an OOP with a non-zero offset, then it is derived.
729
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1442 if( tj == NULL || tj->_offset == 0 ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 derived_base_map[derived->_idx] = derived;
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 return derived;
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // Derived is NULL+offset? Base is NULL!
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 if( derived->is_Con() ) {
729
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1448 Node *base = _matcher.mach_null();
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1449 assert(base != NULL, "sanity");
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1450 if (base->in(0) == NULL) {
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1451 // Initialize it once and make it shared:
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1452 // set control to _root and place it into Start block
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1453 // (where top() node is placed).
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1454 base->init_req(0, _cfg._root);
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1455 Block *startb = _cfg._bbs[C->top()->_idx];
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1456 startb->_nodes.insert(startb->find_node(C->top()), base );
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1457 _cfg._bbs.map( base->_idx, startb );
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1458 assert (n2lidx(base) == 0, "should not have LRG yet");
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1459 }
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1460 if (n2lidx(base) == 0) {
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1461 new_lrg(base, maxlrg++);
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1462 }
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1463 assert(base->in(0) == _cfg._root &&
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1464 _cfg._bbs[base->_idx] == _cfg._bbs[C->top()->_idx], "base NULL should be shared");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 derived_base_map[derived->_idx] = base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 return base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1468
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 // Check for AddP-related opcodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 if( !derived->is_Phi() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 assert( derived->as_Mach()->ideal_Opcode() == Op_AddP, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 Node *base = derived->in(AddPNode::Base);
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 derived_base_map[derived->_idx] = base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 return base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1476
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 // Recursively find bases for Phis.
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 // First check to see if we can avoid a base Phi here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 Node *base = find_base_for_derived( derived_base_map, derived->in(1),maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 for( i = 2; i < derived->req(); i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 if( base != find_base_for_derived( derived_base_map,derived->in(i),maxlrg))
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 // Went to the end without finding any different bases?
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 if( i == derived->req() ) { // No need for a base Phi here
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 derived_base_map[derived->_idx] = base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 return base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1489
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 // Now we see we need a base-Phi here to merge the bases
729
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1491 const Type *t = base->bottom_type();
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1492 base = new (C, derived->req()) PhiNode( derived->in(0), t );
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1493 for( i = 1; i < derived->req(); i++ ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 base->init_req(i, find_base_for_derived(derived_base_map, derived->in(i), maxlrg));
729
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1495 t = t->meet(base->in(i)->bottom_type());
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1496 }
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1497 base->as_Phi()->set_type(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1498
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 // Search the current block for an existing base-Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 Block *b = _cfg._bbs[derived->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 for( i = 1; i <= b->end_idx(); i++ ) {// Search for matching Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 Node *phi = b->_nodes[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 if( !phi->is_Phi() ) { // Found end of Phis with no match?
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 b->_nodes.insert( i, base ); // Must insert created Phi here as base
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 _cfg._bbs.map( base->_idx, b );
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 new_lrg(base,maxlrg++);
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 // See if Phi matches.
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 uint j;
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 for( j = 1; j < base->req(); j++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 if( phi->in(j) != base->in(j) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 !(phi->in(j)->is_Con() && base->in(j)->is_Con()) ) // allow different NULLs
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 if( j == base->req() ) { // All inputs match?
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 base = phi; // Then use existing 'phi' and drop 'base'
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1520
a61af66fc99e Initial load
duke
parents:
diff changeset
1521
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 // Cache info for later passes
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 derived_base_map[derived->_idx] = base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 return base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1526
a61af66fc99e Initial load
duke
parents:
diff changeset
1527
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 //------------------------------stretch_base_pointer_live_ranges---------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 // At each Safepoint, insert extra debug edges for each pair of derived value/
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 // base pointer that is live across the Safepoint for oopmap building. The
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 // edge pairs get added in after sfpt->jvmtail()->oopoff(), but are in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 // required edge set.
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 bool PhaseChaitin::stretch_base_pointer_live_ranges( ResourceArea *a ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 int must_recompute_live = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 uint maxlrg = _maxlrg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 Node **derived_base_map = (Node**)a->Amalloc(sizeof(Node*)*C->unique());
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 memset( derived_base_map, 0, sizeof(Node*)*C->unique() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1538
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 // For all blocks in RPO do...
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 for( uint i=0; i<_cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 Block *b = _cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 // Note use of deep-copy constructor. I cannot hammer the original
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 // liveout bits, because they are needed by the following coalesce pass.
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 IndexSet liveout(_live->live(b));
a61af66fc99e Initial load
duke
parents:
diff changeset
1545
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 for( uint j = b->end_idx() + 1; j > 1; j-- ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 Node *n = b->_nodes[j-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
1548
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 // Pre-split compares of loop-phis. Loop-phis form a cycle we would
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 // like to see in the same register. Compare uses the loop-phi and so
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 // extends its live range BUT cannot be part of the cycle. If this
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 // extended live range overlaps with the update of the loop-phi value
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 // we need both alive at the same time -- which requires at least 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 // copy. But because Intel has only 2-address registers we end up with
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 // at least 2 copies, one before the loop-phi update instruction and
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 // one after. Instead we split the input to the compare just after the
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 // phi.
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CmpI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 Node *phi = n->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 if( phi->is_Phi() && phi->as_Phi()->region()->is_Loop() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 Block *phi_block = _cfg._bbs[phi->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 if( _cfg._bbs[phi_block->pred(2)->_idx] == b ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 const RegMask *mask = C->matcher()->idealreg2spillmask[Op_RegI];
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 Node *spill = new (C) MachSpillCopyNode( phi, *mask, *mask );
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 insert_proj( phi_block, 1, spill, maxlrg++ );
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 n->set_req(1,spill);
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 must_recompute_live = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1571
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 // Get value being defined
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 uint lidx = n2lidx(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 if( lidx && lidx < _maxlrg /* Ignore the occasional brand-new live range */) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 // Remove from live-out set
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 liveout.remove(lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1577
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 // Copies do not define a new value and so do not interfere.
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 // Remove the copies source from the liveout set before interfering.
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 uint idx = n->is_Copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 if( idx ) liveout.remove( n2lidx(n->in(idx)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1583
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 // Found a safepoint?
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 JVMState *jvms = n->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 if( jvms ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 // Now scan for a live derived pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 IndexSetIterator elements(&liveout);
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 uint neighbor;
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 while ((neighbor = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 // Find reaching DEF for base and derived values
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 // This works because we are still in SSA during this call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 Node *derived = lrgs(neighbor)._def;
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 const TypePtr *tj = derived->bottom_type()->isa_ptr();
729
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1595 assert(!derived->bottom_type()->isa_narrowoop() ||
04fa5affa478 6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
kvn
parents: 673
diff changeset
1596 derived->bottom_type()->make_ptr()->is_ptr()->_offset == 0, "sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 // If its an OOP with a non-zero offset, then it is derived.
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 if( tj && tj->_offset != 0 && tj->isa_oop_ptr() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 Node *base = find_base_for_derived( derived_base_map, derived, maxlrg );
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 assert( base->_idx < _names.Size(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 // Add reaching DEFs of derived pointer and base pointer as a
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 // pair of inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 n->add_req( derived );
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 n->add_req( base );
a61af66fc99e Initial load
duke
parents:
diff changeset
1605
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 // See if the base pointer is already live to this point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 // Since I'm working on the SSA form, live-ness amounts to
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 // reaching def's. So if I find the base's live range then
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 // I know the base's def reaches here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 if( (n2lidx(base) >= _maxlrg ||// (Brand new base (hence not live) or
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 !liveout.member( n2lidx(base) ) ) && // not live) AND
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 (n2lidx(base) > 0) && // not a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 _cfg._bbs[base->_idx] != b ) { // base not def'd in blk)
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 // Base pointer is not currently live. Since I stretched
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 // the base pointer to here and it crosses basic-block
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 // boundaries, the global live info is now incorrect.
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 // Recompute live.
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 must_recompute_live = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 } // End of if base pointer is not live to debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 } // End of scan all live data for derived ptrs crossing GC point
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 } // End of if found a GC point
a61af66fc99e Initial load
duke
parents:
diff changeset
1623
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 // Make all inputs live
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 if( !n->is_Phi() ) { // Phi function uses come from prior block
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 for( uint k = 1; k < n->req(); k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 uint lidx = n2lidx(n->in(k));
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 if( lidx < _maxlrg )
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 liveout.insert( lidx );
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1632
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 } // End of forall instructions in block
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 liveout.clear(); // Free the memory used by liveout.
a61af66fc99e Initial load
duke
parents:
diff changeset
1635
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 } // End of forall blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 _maxlrg = maxlrg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1638
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 // If I created a new live range I need to recompute live
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 if( maxlrg != _ifg->_maxlrg )
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 must_recompute_live = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1642
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 return must_recompute_live != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1645
a61af66fc99e Initial load
duke
parents:
diff changeset
1646
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 //------------------------------add_reference----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // Extend the node to LRG mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 void PhaseChaitin::add_reference( const Node *node, const Node *old_node ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 _names.extend( node->_idx, n2lidx(old_node) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1652
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 //------------------------------dump-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 void PhaseChaitin::dump( const Node *n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 uint r = (n->_idx < _names.Size() ) ? Find_const(n) : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 tty->print("L%d",r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 if( r && n->Opcode() != Op_Phi ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 if( _node_regs ) { // Got a post-allocation copy of allocation?
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 tty->print("[");
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 OptoReg::Name second = get_reg_second(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 if( OptoReg::is_valid(second) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 if( OptoReg::is_reg(second) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 tty->print("%s:",Matcher::regName[second]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 tty->print("%s+%d:",OptoReg::regname(OptoReg::c_frame_pointer), reg2offset_unchecked(second));
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 OptoReg::Name first = get_reg_first(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 if( OptoReg::is_reg(first) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 tty->print("%s]",Matcher::regName[first]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 tty->print("%s+%d]",OptoReg::regname(OptoReg::c_frame_pointer), reg2offset_unchecked(first));
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 n->out_RegMask().dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 tty->print("/N%d\t",n->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 tty->print("%s === ", n->Name());
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 uint k;
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 for( k = 0; k < n->req(); k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 Node *m = n->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 if( !m ) tty->print("_ ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 uint r = (m->_idx < _names.Size() ) ? Find_const(m) : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 tty->print("L%d",r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 // Data MultiNode's can have projections with no real registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 // Don't die while dumping them.
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 int op = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 if( r && op != Op_Phi && op != Op_Proj && op != Op_SCMemProj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 if( _node_regs ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 tty->print("[");
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 OptoReg::Name second = get_reg_second(n->in(k));
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 if( OptoReg::is_valid(second) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 if( OptoReg::is_reg(second) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 tty->print("%s:",Matcher::regName[second]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 tty->print("%s+%d:",OptoReg::regname(OptoReg::c_frame_pointer),
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 reg2offset_unchecked(second));
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 OptoReg::Name first = get_reg_first(n->in(k));
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 if( OptoReg::is_reg(first) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 tty->print("%s]",Matcher::regName[first]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 tty->print("%s+%d]",OptoReg::regname(OptoReg::c_frame_pointer),
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 reg2offset_unchecked(first));
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 n->in_RegMask(k).dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 tty->print("/N%d ",m->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 if( k < n->len() && n->in(k) ) tty->print("| ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 for( ; k < n->len(); k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 Node *m = n->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 if( !m ) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 uint r = (m->_idx < _names.Size() ) ? Find_const(m) : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 tty->print("L%d",r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 tty->print("/N%d ",m->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 if( n->is_Mach() ) n->as_Mach()->dump_spec(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 else n->dump_spec(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 if( _spilled_once.test(n->_idx ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 tty->print(" Spill_1");
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 if( _spilled_twice.test(n->_idx ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 tty->print(" Spill_2");
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1728
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 void PhaseChaitin::dump( const Block * b ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 b->dump_head( &_cfg._bbs );
a61af66fc99e Initial load
duke
parents:
diff changeset
1731
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 // For all instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 for( uint j = 0; j < b->_nodes.size(); j++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 dump(b->_nodes[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 // Print live-out info at end of block
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 if( _live ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 tty->print("Liveout: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 IndexSet *live = _live->live(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 IndexSetIterator elements(live);
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 tty->print("{");
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 while ((i = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 tty->print("L%d ", Find_const(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 tty->print_cr("}");
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1749
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 void PhaseChaitin::dump() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 tty->print( "--- Chaitin -- argsize: %d framesize: %d ---\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 _matcher._new_SP, _framesize );
a61af66fc99e Initial load
duke
parents:
diff changeset
1753
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 // For all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 for( uint i = 0; i < _cfg._num_blocks; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 dump(_cfg._blocks[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 // End of per-block dump
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1759
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 if (!_ifg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 tty->print("(No IFG.)\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1764
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 // Dump LRG array
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 tty->print("--- Live RanGe Array ---\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 for(uint i2 = 1; i2 < _maxlrg; i2++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 tty->print("L%d: ",i2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 if( i2 < _ifg->_maxlrg ) lrgs(i2).dump( );
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 else tty->print("new LRG");
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1773
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 // Dump lo-degree list
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 tty->print("Lo degree: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 for(uint i3 = _lo_degree; i3; i3 = lrgs(i3)._next )
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 tty->print("L%d ",i3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1779
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 // Dump lo-stk-degree list
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 tty->print("Lo stk degree: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 for(uint i4 = _lo_stk_degree; i4; i4 = lrgs(i4)._next )
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 tty->print("L%d ",i4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1785
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 // Dump lo-degree list
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 tty->print("Hi degree: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 for(uint i5 = _hi_degree; i5; i5 = lrgs(i5)._next )
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 tty->print("L%d ",i5);
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1792
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 //------------------------------dump_degree_lists------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 void PhaseChaitin::dump_degree_lists() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 // Dump lo-degree list
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 tty->print("Lo degree: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 for( uint i = _lo_degree; i; i = lrgs(i)._next )
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 tty->print("L%d ",i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1800
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 // Dump lo-stk-degree list
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 tty->print("Lo stk degree: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 for(uint i2 = _lo_stk_degree; i2; i2 = lrgs(i2)._next )
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 tty->print("L%d ",i2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1806
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 // Dump lo-degree list
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 tty->print("Hi degree: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 for(uint i3 = _hi_degree; i3; i3 = lrgs(i3)._next )
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 tty->print("L%d ",i3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1813
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 //------------------------------dump_simplified--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 void PhaseChaitin::dump_simplified() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 tty->print("Simplified: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 for( uint i = _simplified; i; i = lrgs(i)._next )
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 tty->print("L%d ",i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1821
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 static char *print_reg( OptoReg::Name reg, const PhaseChaitin *pc, char *buf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 if ((int)reg < 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 sprintf(buf, "<OptoReg::%d>", (int)reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 else if (OptoReg::is_reg(reg))
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 strcpy(buf, Matcher::regName[reg]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 sprintf(buf,"%s + #%d",OptoReg::regname(OptoReg::c_frame_pointer),
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 pc->reg2offset(reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 return buf+strlen(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1832
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 //------------------------------dump_register----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 // Dump a register name into a buffer. Be intelligent if we get called
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 // before allocation is complete.
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 char *PhaseChaitin::dump_register( const Node *n, char *buf ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 if( !this ) { // Not got anything?
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 sprintf(buf,"N%d",n->_idx); // Then use Node index
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 } else if( _node_regs ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 // Post allocation, use direct mappings, no LRG info available
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 print_reg( get_reg_first(n), this, buf );
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 uint lidx = Find_const(n); // Grab LRG number
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 if( !_ifg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 sprintf(buf,"L%d",lidx); // No register binding yet
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 } else if( !lidx ) { // Special, not allocated value
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 strcpy(buf,"Special");
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 } else if( (lrgs(lidx).num_regs() == 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 ? !lrgs(lidx).mask().is_bound1()
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 : !lrgs(lidx).mask().is_bound2() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 sprintf(buf,"L%d",lidx); // No register binding yet
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 } else { // Hah! We have a bound machine register
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 print_reg( lrgs(lidx).reg(), this, buf );
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 return buf+strlen(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1858
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 //----------------------dump_for_spill_split_recycle--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 void PhaseChaitin::dump_for_spill_split_recycle() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 if( WizardMode && (PrintCompilation || PrintOpto) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 // Display which live ranges need to be split and the allocator's state
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 tty->print_cr("Graph-Coloring Iteration %d will split the following live ranges", _trip_cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 for( uint bidx = 1; bidx < _maxlrg; bidx++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 if( lrgs(bidx).alive() && lrgs(bidx).reg() >= LRG::SPILL_REG ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 tty->print("L%d: ", bidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 lrgs(bidx).dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1874
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 //------------------------------dump_frame------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 void PhaseChaitin::dump_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 const char *fp = OptoReg::regname(OptoReg::c_frame_pointer);
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 const TypeTuple *domain = C->tf()->domain();
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 const int argcnt = domain->cnt() - TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
1880
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 // Incoming arguments in registers dump
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 for( int k = 0; k < argcnt; k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 OptoReg::Name parmreg = _matcher._parm_regs[k].first();
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 if( OptoReg::is_reg(parmreg)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 const char *reg_name = OptoReg::regname(parmreg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 tty->print("#r%3.3d %s", parmreg, reg_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 parmreg = _matcher._parm_regs[k].second();
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 if( OptoReg::is_reg(parmreg)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 tty->print(":%s", OptoReg::regname(parmreg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 tty->print(" : parm %d: ", k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 domain->field_at(k + TypeFunc::Parms)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1896
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 // Check for un-owned padding above incoming args
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 OptoReg::Name reg = _matcher._new_SP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 if( reg > _matcher._in_arg_limit ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 reg = OptoReg::add(reg, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 tty->print_cr("#r%3.3d %s+%2d: pad0, owned by CALLER", reg, fp, reg2offset_unchecked(reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1903
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 // Incoming argument area dump
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 OptoReg::Name begin_in_arg = OptoReg::add(_matcher._old_SP,C->out_preserve_stack_slots());
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 while( reg > begin_in_arg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 reg = OptoReg::add(reg, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 tty->print("#r%3.3d %s+%2d: ",reg,fp,reg2offset_unchecked(reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 int j;
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 for( j = 0; j < argcnt; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 if( _matcher._parm_regs[j].first() == reg ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 _matcher._parm_regs[j].second() == reg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 tty->print("parm %d: ",j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 domain->field_at(j + TypeFunc::Parms)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 if( j >= argcnt )
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 tty->print_cr("HOLE, owned by SELF");
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1922
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 // Old outgoing preserve area
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 while( reg > _matcher._old_SP ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 reg = OptoReg::add(reg, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 tty->print_cr("#r%3.3d %s+%2d: old out preserve",reg,fp,reg2offset_unchecked(reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1928
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 // Old SP
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 tty->print_cr("# -- Old %s -- Framesize: %d --",fp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 reg2offset_unchecked(OptoReg::add(_matcher._old_SP,-1)) - reg2offset_unchecked(_matcher._new_SP)+jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1932
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // Preserve area dump
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 reg = OptoReg::add(reg, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 while( OptoReg::is_stack(reg)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 tty->print("#r%3.3d %s+%2d: ",reg,fp,reg2offset_unchecked(reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 if( _matcher.return_addr() == reg )
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 tty->print_cr("return address");
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 else if( _matcher.return_addr() == OptoReg::add(reg,1) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 VerifyStackAtCalls )
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 tty->print_cr("0xBADB100D +VerifyStackAtCalls");
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 else if ((int)OptoReg::reg2stack(reg) < C->fixed_slots())
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 tty->print_cr("Fixed slot %d", OptoReg::reg2stack(reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 tty->print_cr("pad2, in_preserve");
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 reg = OptoReg::add(reg, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1948
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 // Spill area dump
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 reg = OptoReg::add(_matcher._new_SP, _framesize );
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 while( reg > _matcher._out_arg_limit ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 reg = OptoReg::add(reg, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 tty->print_cr("#r%3.3d %s+%2d: spill",reg,fp,reg2offset_unchecked(reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1955
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 // Outgoing argument area dump
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 while( reg > OptoReg::add(_matcher._new_SP, C->out_preserve_stack_slots()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 reg = OptoReg::add(reg, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 tty->print_cr("#r%3.3d %s+%2d: outgoing argument",reg,fp,reg2offset_unchecked(reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1961
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 // Outgoing new preserve area
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 while( reg > _matcher._new_SP ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 reg = OptoReg::add(reg, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 tty->print_cr("#r%3.3d %s+%2d: new out preserve",reg,fp,reg2offset_unchecked(reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 tty->print_cr("#");
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1969
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 //------------------------------dump_bb----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 void PhaseChaitin::dump_bb( uint pre_order ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 tty->print_cr("---dump of B%d---",pre_order);
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 for( uint i = 0; i < _cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 Block *b = _cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 if( b->_pre_order == pre_order )
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 dump(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1979
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 //------------------------------dump_lrg---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 void PhaseChaitin::dump_lrg( uint lidx ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 tty->print_cr("---dump of L%d---",lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1983
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 if( _ifg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 if( lidx >= _maxlrg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 tty->print("Attempt to print live range index beyond max live range.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 tty->print("L%d: ",lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 lrgs(lidx).dump( );
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 if( _ifg ) { tty->print("Neighbors: %d - ", _ifg->neighbor_cnt(lidx));
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 _ifg->neighbors(lidx)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 // For all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 for( uint i = 0; i < _cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 Block *b = _cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 int dump_once = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2000
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 // For all instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 for( uint j = 0; j < b->_nodes.size(); j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 Node *n = b->_nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 if( Find_const(n) == lidx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 if( !dump_once++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 b->dump_head( &_cfg._bbs );
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 dump(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 uint cnt = n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 for( uint k = 1; k < cnt; k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 Node *m = n->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 if (!m) continue; // be robust in the dumper
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 if( Find_const(m) == lidx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 if( !dump_once++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 b->dump_head( &_cfg._bbs );
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 dump(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 } // End of per-block dump
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 #endif // not PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2029
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 //------------------------------print_chaitin_statistics-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 int PhaseChaitin::_final_loads = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 int PhaseChaitin::_final_stores = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 int PhaseChaitin::_final_memoves= 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 int PhaseChaitin::_final_copies = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 double PhaseChaitin::_final_load_cost = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 double PhaseChaitin::_final_store_cost = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 double PhaseChaitin::_final_memove_cost= 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 double PhaseChaitin::_final_copy_cost = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 int PhaseChaitin::_conserv_coalesce = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 int PhaseChaitin::_conserv_coalesce_pair = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 int PhaseChaitin::_conserv_coalesce_trie = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 int PhaseChaitin::_conserv_coalesce_quad = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 int PhaseChaitin::_post_alloc = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 int PhaseChaitin::_lost_opp_pp_coalesce = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 int PhaseChaitin::_lost_opp_cflow_coalesce = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 int PhaseChaitin::_used_cisc_instructions = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 int PhaseChaitin::_unused_cisc_instructions = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 int PhaseChaitin::_allocator_attempts = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 int PhaseChaitin::_allocator_successes = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2050
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 uint PhaseChaitin::_high_pressure = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 uint PhaseChaitin::_low_pressure = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2054
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 void PhaseChaitin::print_chaitin_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 tty->print_cr("Inserted %d spill loads, %d spill stores, %d mem-mem moves and %d copies.", _final_loads, _final_stores, _final_memoves, _final_copies);
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 tty->print_cr("Total load cost= %6.0f, store cost = %6.0f, mem-mem cost = %5.2f, copy cost = %5.0f.", _final_load_cost, _final_store_cost, _final_memove_cost, _final_copy_cost);
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 tty->print_cr("Adjusted spill cost = %7.0f.",
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 _final_load_cost*4.0 + _final_store_cost * 2.0 +
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 _final_copy_cost*1.0 + _final_memove_cost*12.0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 tty->print("Conservatively coalesced %d copies, %d pairs",
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 _conserv_coalesce, _conserv_coalesce_pair);
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 if( _conserv_coalesce_trie || _conserv_coalesce_quad )
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 tty->print(", %d tries, %d quads", _conserv_coalesce_trie, _conserv_coalesce_quad);
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 tty->print_cr(", %d post alloc.", _post_alloc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 if( _lost_opp_pp_coalesce || _lost_opp_cflow_coalesce )
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 tty->print_cr("Lost coalesce opportunity, %d private-private, and %d cflow interfered.",
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 _lost_opp_pp_coalesce, _lost_opp_cflow_coalesce );
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 if( _used_cisc_instructions || _unused_cisc_instructions )
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 tty->print_cr("Used cisc instruction %d, remained in register %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 _used_cisc_instructions, _unused_cisc_instructions);
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 if( _allocator_successes != 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 tty->print_cr("Average allocation trips %f", (float)_allocator_attempts/(float)_allocator_successes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 tty->print_cr("High Pressure Blocks = %d, Low Pressure Blocks = %d", _high_pressure, _low_pressure);
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 #endif // not PRODUCT