annotate src/share/vm/opto/chaitin.cpp @ 4710:41406797186b

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