annotate src/share/vm/opto/chaitin.cpp @ 452:00b023ae2d78

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