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

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
parents eb28cf662f56
children 91263420e1c6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
337
9ee9cf798b59 6754988: Update copyright year
xdono
parents: 295
diff changeset
2 * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_ifg.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 #define EXACT_PRESSURE 1
a61af66fc99e Initial load
duke
parents:
diff changeset
29
a61af66fc99e Initial load
duke
parents:
diff changeset
30 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
31 //------------------------------IFG--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
32 PhaseIFG::PhaseIFG( Arena *arena ) : Phase(Interference_Graph), _arena(arena) {
a61af66fc99e Initial load
duke
parents:
diff changeset
33 }
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 //------------------------------init-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
36 void PhaseIFG::init( uint maxlrg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 _maxlrg = maxlrg;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 _yanked = new (_arena) VectorSet(_arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
39 _is_square = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // Make uninitialized adjacency lists
a61af66fc99e Initial load
duke
parents:
diff changeset
41 _adjs = (IndexSet*)_arena->Amalloc(sizeof(IndexSet)*maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // Also make empty live range structures
a61af66fc99e Initial load
duke
parents:
diff changeset
43 _lrgs = (LRG *)_arena->Amalloc( maxlrg * sizeof(LRG) );
a61af66fc99e Initial load
duke
parents:
diff changeset
44 memset(_lrgs,0,sizeof(LRG)*maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // Init all to empty
a61af66fc99e Initial load
duke
parents:
diff changeset
46 for( uint i = 0; i < maxlrg; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 _adjs[i].initialize(maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _lrgs[i].Set_All();
a61af66fc99e Initial load
duke
parents:
diff changeset
49 }
a61af66fc99e Initial load
duke
parents:
diff changeset
50 }
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 //------------------------------add--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // Add edge between vertices a & b. These are sorted (triangular matrix),
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // then the smaller number is inserted in the larger numbered array.
a61af66fc99e Initial load
duke
parents:
diff changeset
55 int PhaseIFG::add_edge( uint a, uint b ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
56 lrgs(a).invalid_degree();
a61af66fc99e Initial load
duke
parents:
diff changeset
57 lrgs(b).invalid_degree();
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // Sort a and b, so that a is bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
59 assert( !_is_square, "only on triangular" );
a61af66fc99e Initial load
duke
parents:
diff changeset
60 if( a < b ) { uint tmp = a; a = b; b = tmp; }
a61af66fc99e Initial load
duke
parents:
diff changeset
61 return _adjs[a].insert( b );
a61af66fc99e Initial load
duke
parents:
diff changeset
62 }
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 //------------------------------add_vector-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // Add an edge between 'a' and everything in the vector.
a61af66fc99e Initial load
duke
parents:
diff changeset
66 void PhaseIFG::add_vector( uint a, IndexSet *vec ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // IFG is triangular, so do the inserts where 'a' < 'b'.
a61af66fc99e Initial load
duke
parents:
diff changeset
68 assert( !_is_square, "only on triangular" );
a61af66fc99e Initial load
duke
parents:
diff changeset
69 IndexSet *adjs_a = &_adjs[a];
a61af66fc99e Initial load
duke
parents:
diff changeset
70 if( !vec->count() ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 IndexSetIterator elements(vec);
a61af66fc99e Initial load
duke
parents:
diff changeset
73 uint neighbor;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 while ((neighbor = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
75 add_edge( a, neighbor );
a61af66fc99e Initial load
duke
parents:
diff changeset
76 }
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 //------------------------------test-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // Is there an edge between a and b?
a61af66fc99e Initial load
duke
parents:
diff changeset
81 int PhaseIFG::test_edge( uint a, uint b ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // Sort a and b, so that a is larger
a61af66fc99e Initial load
duke
parents:
diff changeset
83 assert( !_is_square, "only on triangular" );
a61af66fc99e Initial load
duke
parents:
diff changeset
84 if( a < b ) { uint tmp = a; a = b; b = tmp; }
a61af66fc99e Initial load
duke
parents:
diff changeset
85 return _adjs[a].member(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 //------------------------------SquareUp---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // Convert triangular matrix to square matrix
a61af66fc99e Initial load
duke
parents:
diff changeset
90 void PhaseIFG::SquareUp() {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 assert( !_is_square, "only on triangular" );
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // Simple transpose
a61af66fc99e Initial load
duke
parents:
diff changeset
94 for( uint i = 0; i < _maxlrg; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 IndexSetIterator elements(&_adjs[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
96 uint datum;
a61af66fc99e Initial load
duke
parents:
diff changeset
97 while ((datum = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 _adjs[datum].insert( i );
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101 _is_square = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 //------------------------------Compute_Effective_Degree-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // Compute effective degree in bulk
a61af66fc99e Initial load
duke
parents:
diff changeset
106 void PhaseIFG::Compute_Effective_Degree() {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 assert( _is_square, "only on square" );
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 for( uint i = 0; i < _maxlrg; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
110 lrgs(i).set_degree(effective_degree(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 //------------------------------test_edge_sq-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
114 int PhaseIFG::test_edge_sq( uint a, uint b ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 assert( _is_square, "only on square" );
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // Swap, so that 'a' has the lesser count. Then binary search is on
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // the smaller of a's list and b's list.
a61af66fc99e Initial load
duke
parents:
diff changeset
118 if( neighbor_cnt(a) > neighbor_cnt(b) ) { uint tmp = a; a = b; b = tmp; }
a61af66fc99e Initial load
duke
parents:
diff changeset
119 //return _adjs[a].unordered_member(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 return _adjs[a].member(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 //------------------------------Union------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // Union edges of B into A
a61af66fc99e Initial load
duke
parents:
diff changeset
125 void PhaseIFG::Union( uint a, uint b ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 assert( _is_square, "only on square" );
a61af66fc99e Initial load
duke
parents:
diff changeset
127 IndexSet *A = &_adjs[a];
a61af66fc99e Initial load
duke
parents:
diff changeset
128 IndexSetIterator b_elements(&_adjs[b]);
a61af66fc99e Initial load
duke
parents:
diff changeset
129 uint datum;
a61af66fc99e Initial load
duke
parents:
diff changeset
130 while ((datum = b_elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 if(A->insert(datum)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 _adjs[datum].insert(a);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 lrgs(a).invalid_degree();
a61af66fc99e Initial load
duke
parents:
diff changeset
134 lrgs(datum).invalid_degree();
a61af66fc99e Initial load
duke
parents:
diff changeset
135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 //------------------------------remove_node------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // Yank a Node and all connected edges from the IFG. Return a
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // list of neighbors (edges) yanked.
a61af66fc99e Initial load
duke
parents:
diff changeset
142 IndexSet *PhaseIFG::remove_node( uint a ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
143 assert( _is_square, "only on square" );
a61af66fc99e Initial load
duke
parents:
diff changeset
144 assert( !_yanked->test(a), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
145 _yanked->set(a);
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // I remove the LRG from all neighbors.
a61af66fc99e Initial load
duke
parents:
diff changeset
148 IndexSetIterator elements(&_adjs[a]);
a61af66fc99e Initial load
duke
parents:
diff changeset
149 LRG &lrg_a = lrgs(a);
a61af66fc99e Initial load
duke
parents:
diff changeset
150 uint datum;
a61af66fc99e Initial load
duke
parents:
diff changeset
151 while ((datum = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
152 _adjs[datum].remove(a);
a61af66fc99e Initial load
duke
parents:
diff changeset
153 lrgs(datum).inc_degree( -lrg_a.compute_degree(lrgs(datum)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155 return neighbors(a);
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 //------------------------------re_insert--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // Re-insert a yanked Node.
a61af66fc99e Initial load
duke
parents:
diff changeset
160 void PhaseIFG::re_insert( uint a ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 assert( _is_square, "only on square" );
a61af66fc99e Initial load
duke
parents:
diff changeset
162 assert( _yanked->test(a), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
163 (*_yanked) >>= a;
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 IndexSetIterator elements(&_adjs[a]);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 uint datum;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 while ((datum = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
168 _adjs[datum].insert(a);
a61af66fc99e Initial load
duke
parents:
diff changeset
169 lrgs(datum).invalid_degree();
a61af66fc99e Initial load
duke
parents:
diff changeset
170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
172
a61af66fc99e Initial load
duke
parents:
diff changeset
173 //------------------------------compute_degree---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // Compute the degree between 2 live ranges. If both live ranges are
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // aligned-adjacent powers-of-2 then we use the MAX size. If either is
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // mis-aligned (or for Fat-Projections, not-adjacent) then we have to
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // MULTIPLY the sizes. Inspect Brigg's thesis on register pairs to see why
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // this is so.
a61af66fc99e Initial load
duke
parents:
diff changeset
179 int LRG::compute_degree( LRG &l ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
180 int tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 int num_regs = _num_regs;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 int nregs = l.num_regs();
a61af66fc99e Initial load
duke
parents:
diff changeset
183 tmp = (_fat_proj || l._fat_proj) // either is a fat-proj?
a61af66fc99e Initial load
duke
parents:
diff changeset
184 ? (num_regs * nregs) // then use product
a61af66fc99e Initial load
duke
parents:
diff changeset
185 : MAX2(num_regs,nregs); // else use max
a61af66fc99e Initial load
duke
parents:
diff changeset
186 return tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 //------------------------------effective_degree-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // Compute effective degree for this live range. If both live ranges are
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // aligned-adjacent powers-of-2 then we use the MAX size. If either is
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // mis-aligned (or for Fat-Projections, not-adjacent) then we have to
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // MULTIPLY the sizes. Inspect Brigg's thesis on register pairs to see why
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // this is so.
a61af66fc99e Initial load
duke
parents:
diff changeset
195 int PhaseIFG::effective_degree( uint lidx ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 int eff = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
197 int num_regs = lrgs(lidx).num_regs();
a61af66fc99e Initial load
duke
parents:
diff changeset
198 int fat_proj = lrgs(lidx)._fat_proj;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 IndexSet *s = neighbors(lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
200 IndexSetIterator elements(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
201 uint nidx;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 while((nidx = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 LRG &lrgn = lrgs(nidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
204 int nregs = lrgn.num_regs();
a61af66fc99e Initial load
duke
parents:
diff changeset
205 eff += (fat_proj || lrgn._fat_proj) // either is a fat-proj?
a61af66fc99e Initial load
duke
parents:
diff changeset
206 ? (num_regs * nregs) // then use product
a61af66fc99e Initial load
duke
parents:
diff changeset
207 : MAX2(num_regs,nregs); // else use max
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209 return eff;
a61af66fc99e Initial load
duke
parents:
diff changeset
210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
214 //------------------------------dump-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
215 void PhaseIFG::dump() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 tty->print_cr("-- Interference Graph --%s--",
a61af66fc99e Initial load
duke
parents:
diff changeset
217 _is_square ? "square" : "triangular" );
a61af66fc99e Initial load
duke
parents:
diff changeset
218 if( _is_square ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 for( uint i = 0; i < _maxlrg; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 tty->print( (*_yanked)[i] ? "XX " : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
221 tty->print("L%d: { ",i);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 IndexSetIterator elements(&_adjs[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 uint datum;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 while ((datum = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 tty->print("L%d ", datum);
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227 tty->print_cr("}");
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 // Triangular
a61af66fc99e Initial load
duke
parents:
diff changeset
234 for( uint i = 0; i < _maxlrg; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
235 uint j;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 tty->print( (*_yanked)[i] ? "XX " : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
237 tty->print("L%d: { ",i);
a61af66fc99e Initial load
duke
parents:
diff changeset
238 for( j = _maxlrg; j > i; j-- )
a61af66fc99e Initial load
duke
parents:
diff changeset
239 if( test_edge(j - 1,i) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 tty->print("L%d ",j - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242 tty->print("| ");
a61af66fc99e Initial load
duke
parents:
diff changeset
243 IndexSetIterator elements(&_adjs[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 uint datum;
a61af66fc99e Initial load
duke
parents:
diff changeset
245 while ((datum = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
246 tty->print("L%d ", datum);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 tty->print("}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 //------------------------------stats------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
254 void PhaseIFG::stats() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
256 int *h_cnt = NEW_RESOURCE_ARRAY(int,_maxlrg*2);
a61af66fc99e Initial load
duke
parents:
diff changeset
257 memset( h_cnt, 0, sizeof(int)*_maxlrg*2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
258 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
259 for( i = 0; i < _maxlrg; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 h_cnt[neighbor_cnt(i)]++;
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
262 tty->print_cr("--Histogram of counts--");
a61af66fc99e Initial load
duke
parents:
diff changeset
263 for( i = 0; i < _maxlrg*2; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
264 if( h_cnt[i] )
a61af66fc99e Initial load
duke
parents:
diff changeset
265 tty->print("%d/%d ",i,h_cnt[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
266 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269 //------------------------------verify-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
270 void PhaseIFG::verify( const PhaseChaitin *pc ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // IFG is square, sorted and no need for Find
a61af66fc99e Initial load
duke
parents:
diff changeset
272 for( uint i = 0; i < _maxlrg; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 assert(!((*_yanked)[i]) || !neighbor_cnt(i), "Is removed completely" );
a61af66fc99e Initial load
duke
parents:
diff changeset
274 IndexSet *set = &_adjs[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
275 IndexSetIterator elements(set);
a61af66fc99e Initial load
duke
parents:
diff changeset
276 uint idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
277 uint last = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
278 while ((idx = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 assert( idx != i, "Must have empty diagonal");
a61af66fc99e Initial load
duke
parents:
diff changeset
280 assert( pc->Find_const(idx) == idx, "Must not need Find" );
a61af66fc99e Initial load
duke
parents:
diff changeset
281 assert( _adjs[idx].member(i), "IFG not square" );
a61af66fc99e Initial load
duke
parents:
diff changeset
282 assert( !(*_yanked)[idx], "No yanked neighbors" );
a61af66fc99e Initial load
duke
parents:
diff changeset
283 assert( last < idx, "not sorted increasing");
a61af66fc99e Initial load
duke
parents:
diff changeset
284 last = idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 assert( !lrgs(i)._degree_valid ||
a61af66fc99e Initial load
duke
parents:
diff changeset
287 effective_degree(i) == lrgs(i).degree(), "degree is valid but wrong" );
a61af66fc99e Initial load
duke
parents:
diff changeset
288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
291
a61af66fc99e Initial load
duke
parents:
diff changeset
292 //------------------------------interfere_with_live----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // Interfere this register with everything currently live. Use the RegMasks
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // to trim the set of possible interferences. Return a count of register-only
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // inteferences as an estimate of register pressure.
a61af66fc99e Initial load
duke
parents:
diff changeset
296 void PhaseChaitin::interfere_with_live( uint r, IndexSet *liveout ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
297 uint retval = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // Interfere with everything live.
a61af66fc99e Initial load
duke
parents:
diff changeset
299 const RegMask &rm = lrgs(r).mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // Check for interference by checking overlap of regmasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
301 // Only interfere if acceptable register masks overlap.
a61af66fc99e Initial load
duke
parents:
diff changeset
302 IndexSetIterator elements(liveout);
a61af66fc99e Initial load
duke
parents:
diff changeset
303 uint l;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 while( (l = elements.next()) != 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
305 if( rm.overlap( lrgs(l).mask() ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
306 _ifg->add_edge( r, l );
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 //------------------------------build_ifg_virtual------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // Actually build the interference graph. Uses virtual registers only, no
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // physical register masks. This allows me to be very aggressive when
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // coalescing copies. Some of this aggressiveness will have to be undone
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // later, but I'd rather get all the copies I can now (since unremoved copies
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // at this point can end up in bad places). Copies I re-insert later I have
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // more opportunity to insert them in low-frequency locations.
a61af66fc99e Initial load
duke
parents:
diff changeset
316 void PhaseChaitin::build_ifg_virtual( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
317
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // For all blocks (in any order) do...
a61af66fc99e Initial load
duke
parents:
diff changeset
319 for( uint i=0; i<_cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 Block *b = _cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
321 IndexSet *liveout = _live->live(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // The IFG is built by a single reverse pass over each basic block.
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // Starting with the known live-out set, we remove things that get
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // defined and add things that become live (essentially executing one
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // pass of a standard LIVE analysis). Just before a Node defines a value
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // (and removes it from the live-ness set) that value is certainly live.
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // The defined value interferes with everything currently live. The
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // value is then removed from the live-ness set and it's inputs are
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // added to the live-ness set.
a61af66fc99e Initial load
duke
parents:
diff changeset
331 for( uint j = b->end_idx() + 1; j > 1; j-- ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
332 Node *n = b->_nodes[j-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
333
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // Get value being defined
a61af66fc99e Initial load
duke
parents:
diff changeset
335 uint r = n2lidx(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // Some special values do not allocate
a61af66fc99e Initial load
duke
parents:
diff changeset
338 if( r ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // Remove from live-out set
a61af66fc99e Initial load
duke
parents:
diff changeset
341 liveout->remove(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // Copies do not define a new value and so do not interfere.
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // Remove the copies source from the liveout set before interfering.
a61af66fc99e Initial load
duke
parents:
diff changeset
345 uint idx = n->is_Copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
346 if( idx ) liveout->remove( n2lidx(n->in(idx)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // Interfere with everything live
a61af66fc99e Initial load
duke
parents:
diff changeset
349 interfere_with_live( r, liveout );
a61af66fc99e Initial load
duke
parents:
diff changeset
350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // Make all inputs live
a61af66fc99e Initial load
duke
parents:
diff changeset
353 if( !n->is_Phi() ) { // Phi function uses come from prior block
a61af66fc99e Initial load
duke
parents:
diff changeset
354 for( uint k = 1; k < n->req(); k++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
355 liveout->insert( n2lidx(n->in(k)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // 2-address instructions always have the defined value live
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // on entry to the instruction, even though it is being defined
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // by the instruction. We pretend a virtual copy sits just prior
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // to the instruction and kills the src-def'd register.
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // In other words, for 2-address instructions the defined value
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // interferes with all inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
364 uint idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
365 if( n->is_Mach() && (idx = n->as_Mach()->two_adr()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 const MachNode *mach = n->as_Mach();
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // Sometimes my 2-address ADDs are commuted in a bad way.
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // We generally want the USE-DEF register to refer to the
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // loop-varying quantity, to avoid a copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
370 uint op = mach->ideal_Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // Check that mach->num_opnds() == 3 to ensure instruction is
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // not subsuming constants, effectively excludes addI_cin_imm
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // Can NOT swap for instructions like addI_cin_imm since it
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // is adding zero to yhi + carry and the second ideal-input
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // points to the result of adding low-halves.
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // Checking req() and num_opnds() does NOT distinguish addI_cout from addI_cout_imm
a61af66fc99e Initial load
duke
parents:
diff changeset
377 if( (op == Op_AddI && mach->req() == 3 && mach->num_opnds() == 3) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
378 n->in(1)->bottom_type()->base() == Type::Int &&
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // See if the ADD is involved in a tight data loop the wrong way
a61af66fc99e Initial load
duke
parents:
diff changeset
380 n->in(2)->is_Phi() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
381 n->in(2)->in(2) == n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 Node *tmp = n->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 n->set_req( 1, n->in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
384 n->set_req( 2, tmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // Defined value interferes with all inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
387 uint lidx = n2lidx(n->in(idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
388 for( uint k = 1; k < n->req(); k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
389 uint kidx = n2lidx(n->in(k));
a61af66fc99e Initial load
duke
parents:
diff changeset
390 if( kidx != lidx )
a61af66fc99e Initial load
duke
parents:
diff changeset
391 _ifg->add_edge( r, kidx );
a61af66fc99e Initial load
duke
parents:
diff changeset
392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
394 } // End of forall instructions in block
a61af66fc99e Initial load
duke
parents:
diff changeset
395 } // End of forall blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 //------------------------------count_int_pressure-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
399 uint PhaseChaitin::count_int_pressure( IndexSet *liveout ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
400 IndexSetIterator elements(liveout);
a61af66fc99e Initial load
duke
parents:
diff changeset
401 uint lidx;
a61af66fc99e Initial load
duke
parents:
diff changeset
402 uint cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
403 while ((lidx = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
404 if( lrgs(lidx).mask().is_UP() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
405 lrgs(lidx).mask_size() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
406 !lrgs(lidx)._is_float &&
a61af66fc99e Initial load
duke
parents:
diff changeset
407 lrgs(lidx).mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) )
a61af66fc99e Initial load
duke
parents:
diff changeset
408 cnt += lrgs(lidx).reg_pressure();
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410 return cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 //------------------------------count_float_pressure---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
414 uint PhaseChaitin::count_float_pressure( IndexSet *liveout ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 IndexSetIterator elements(liveout);
a61af66fc99e Initial load
duke
parents:
diff changeset
416 uint lidx;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 uint cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
418 while ((lidx = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 if( lrgs(lidx).mask().is_UP() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
420 lrgs(lidx).mask_size() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
421 lrgs(lidx)._is_float )
a61af66fc99e Initial load
duke
parents:
diff changeset
422 cnt += lrgs(lidx).reg_pressure();
a61af66fc99e Initial load
duke
parents:
diff changeset
423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
424 return cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 //------------------------------lower_pressure---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // Adjust register pressure down by 1. Capture last hi-to-low transition,
a61af66fc99e Initial load
duke
parents:
diff changeset
429 static void lower_pressure( LRG *lrg, uint where, Block *b, uint *pressure, uint *hrp_index ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
430 if( lrg->mask().is_UP() && lrg->mask_size() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
431 if( lrg->_is_float ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
432 pressure[1] -= lrg->reg_pressure();
a61af66fc99e Initial load
duke
parents:
diff changeset
433 if( pressure[1] == (uint)FLOATPRESSURE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
434 hrp_index[1] = where;
a61af66fc99e Initial load
duke
parents:
diff changeset
435 #ifdef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
436 if( pressure[1] > b->_freg_pressure )
a61af66fc99e Initial load
duke
parents:
diff changeset
437 b->_freg_pressure = pressure[1]+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
438 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
439 b->_freg_pressure = (uint)FLOATPRESSURE+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
440 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
442 } else if( lrg->mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
443 pressure[0] -= lrg->reg_pressure();
a61af66fc99e Initial load
duke
parents:
diff changeset
444 if( pressure[0] == (uint)INTPRESSURE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
445 hrp_index[0] = where;
a61af66fc99e Initial load
duke
parents:
diff changeset
446 #ifdef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
447 if( pressure[0] > b->_reg_pressure )
a61af66fc99e Initial load
duke
parents:
diff changeset
448 b->_reg_pressure = pressure[0]+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
449 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
450 b->_reg_pressure = (uint)INTPRESSURE+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
451 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
456
a61af66fc99e Initial load
duke
parents:
diff changeset
457 //------------------------------build_ifg_physical-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // Build the interference graph using physical registers when available.
a61af66fc99e Initial load
duke
parents:
diff changeset
459 // That is, if 2 live ranges are simultaneously alive but in their acceptable
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // register sets do not overlap, then they do not interfere.
a61af66fc99e Initial load
duke
parents:
diff changeset
461 uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 NOT_PRODUCT( Compile::TracePhase t3("buildIFG", &_t_buildIFGphysical, TimeCompiler); )
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 uint spill_reg = LRG::SPILL_REG;
a61af66fc99e Initial load
duke
parents:
diff changeset
465 uint must_spill = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
466
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // For all blocks (in any order) do...
a61af66fc99e Initial load
duke
parents:
diff changeset
468 for( uint i = 0; i < _cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
469 Block *b = _cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
470 // Clone (rather than smash in place) the liveout info, so it is alive
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // for the "collect_gc_info" phase later.
a61af66fc99e Initial load
duke
parents:
diff changeset
472 IndexSet liveout(_live->live(b));
a61af66fc99e Initial load
duke
parents:
diff changeset
473 uint last_inst = b->end_idx();
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // Compute last phi index
a61af66fc99e Initial load
duke
parents:
diff changeset
475 uint last_phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
476 for( last_phi = 1; last_phi < last_inst; last_phi++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
477 if( !b->_nodes[last_phi]->is_Phi() )
a61af66fc99e Initial load
duke
parents:
diff changeset
478 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // Reset block's register pressure values for each ifg construction
a61af66fc99e Initial load
duke
parents:
diff changeset
481 uint pressure[2], hrp_index[2];
a61af66fc99e Initial load
duke
parents:
diff changeset
482 pressure[0] = pressure[1] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
483 hrp_index[0] = hrp_index[1] = last_inst+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
484 b->_reg_pressure = b->_freg_pressure = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // Liveout things are presumed live for the whole block. We accumulate
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // 'area' accordingly. If they get killed in the block, we'll subtract
a61af66fc99e Initial load
duke
parents:
diff changeset
487 // the unused part of the block from the area.
369
5f85534046c2 6750588: assert(lrg._area >= 0,"negative spill area") running NSK stmp0101 test
rasbold
parents: 295
diff changeset
488 int inst_count = last_inst - last_phi;
5f85534046c2 6750588: assert(lrg._area >= 0,"negative spill area") running NSK stmp0101 test
rasbold
parents: 295
diff changeset
489 double cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count);
5f85534046c2 6750588: assert(lrg._area >= 0,"negative spill area") running NSK stmp0101 test
rasbold
parents: 295
diff changeset
490 assert(!(cost < 0.0), "negative spill cost" );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
491 IndexSetIterator elements(&liveout);
a61af66fc99e Initial load
duke
parents:
diff changeset
492 uint lidx;
a61af66fc99e Initial load
duke
parents:
diff changeset
493 while ((lidx = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
494 LRG &lrg = lrgs(lidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
495 lrg._area += cost;
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // Compute initial register pressure
a61af66fc99e Initial load
duke
parents:
diff changeset
497 if( lrg.mask().is_UP() && lrg.mask_size() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 if( lrg._is_float ) { // Count float pressure
a61af66fc99e Initial load
duke
parents:
diff changeset
499 pressure[1] += lrg.reg_pressure();
a61af66fc99e Initial load
duke
parents:
diff changeset
500 #ifdef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
501 if( pressure[1] > b->_freg_pressure )
a61af66fc99e Initial load
duke
parents:
diff changeset
502 b->_freg_pressure = pressure[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
503 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // Count int pressure, but do not count the SP, flags
a61af66fc99e Initial load
duke
parents:
diff changeset
505 } else if( lrgs(lidx).mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 pressure[0] += lrg.reg_pressure();
a61af66fc99e Initial load
duke
parents:
diff changeset
507 #ifdef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
508 if( pressure[0] > b->_reg_pressure )
a61af66fc99e Initial load
duke
parents:
diff changeset
509 b->_reg_pressure = pressure[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
510 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
514 assert( pressure[0] == count_int_pressure (&liveout), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
515 assert( pressure[1] == count_float_pressure(&liveout), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
516
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // The IFG is built by a single reverse pass over each basic block.
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // Starting with the known live-out set, we remove things that get
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // defined and add things that become live (essentially executing one
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // pass of a standard LIVE analysis). Just before a Node defines a value
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // (and removes it from the live-ness set) that value is certainly live.
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // The defined value interferes with everything currently live. The
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // value is then removed from the live-ness set and it's inputs are added
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // to the live-ness set.
a61af66fc99e Initial load
duke
parents:
diff changeset
525 uint j;
a61af66fc99e Initial load
duke
parents:
diff changeset
526 for( j = last_inst + 1; j > 1; j-- ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
527 Node *n = b->_nodes[j - 1];
a61af66fc99e Initial load
duke
parents:
diff changeset
528
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // Get value being defined
a61af66fc99e Initial load
duke
parents:
diff changeset
530 uint r = n2lidx(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
531
a61af66fc99e Initial load
duke
parents:
diff changeset
532 // Some special values do not allocate
a61af66fc99e Initial load
duke
parents:
diff changeset
533 if( r ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // A DEF normally costs block frequency; rematerialized values are
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // removed from the DEF sight, so LOWER costs here.
a61af66fc99e Initial load
duke
parents:
diff changeset
536 lrgs(r)._cost += n->rematerialize() ? 0 : b->_freq;
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 // If it is not live, then this instruction is dead. Probably caused
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // by spilling and rematerialization. Who cares why, yank this baby.
a61af66fc99e Initial load
duke
parents:
diff changeset
540 if( !liveout.member(r) && n->Opcode() != Op_SafePoint ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 Node *def = n->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
542 if( !n->is_Proj() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // Could also be a flags-projection of a dead ADD or such.
a61af66fc99e Initial load
duke
parents:
diff changeset
544 (n2lidx(def) && !liveout.member(n2lidx(def)) ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
545 b->_nodes.remove(j - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
546 if( lrgs(r)._def == n ) lrgs(r)._def = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
547 n->disconnect_inputs(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
548 _cfg._bbs.map(n->_idx,NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
549 n->replace_by(C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // Since yanking a Node from block, high pressure moves up one
a61af66fc99e Initial load
duke
parents:
diff changeset
551 hrp_index[0]--;
a61af66fc99e Initial load
duke
parents:
diff changeset
552 hrp_index[1]--;
a61af66fc99e Initial load
duke
parents:
diff changeset
553 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
555
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // Fat-projections kill many registers which cannot be used to
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // hold live ranges.
a61af66fc99e Initial load
duke
parents:
diff changeset
558 if( lrgs(r)._fat_proj ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // Count the int-only registers
a61af66fc99e Initial load
duke
parents:
diff changeset
560 RegMask itmp = lrgs(r).mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
561 itmp.AND(*Matcher::idealreg2regmask[Op_RegI]);
a61af66fc99e Initial load
duke
parents:
diff changeset
562 int iregs = itmp.Size();
a61af66fc99e Initial load
duke
parents:
diff changeset
563 #ifdef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
564 if( pressure[0]+iregs > b->_reg_pressure )
a61af66fc99e Initial load
duke
parents:
diff changeset
565 b->_reg_pressure = pressure[0]+iregs;
a61af66fc99e Initial load
duke
parents:
diff changeset
566 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
567 if( pressure[0] <= (uint)INTPRESSURE &&
a61af66fc99e Initial load
duke
parents:
diff changeset
568 pressure[0]+iregs > (uint)INTPRESSURE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
569 #ifndef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
570 b->_reg_pressure = (uint)INTPRESSURE+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
571 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
572 hrp_index[0] = j-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
573 }
a61af66fc99e Initial load
duke
parents:
diff changeset
574 // Count the float-only registers
a61af66fc99e Initial load
duke
parents:
diff changeset
575 RegMask ftmp = lrgs(r).mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
576 ftmp.AND(*Matcher::idealreg2regmask[Op_RegD]);
a61af66fc99e Initial load
duke
parents:
diff changeset
577 int fregs = ftmp.Size();
a61af66fc99e Initial load
duke
parents:
diff changeset
578 #ifdef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
579 if( pressure[1]+fregs > b->_freg_pressure )
a61af66fc99e Initial load
duke
parents:
diff changeset
580 b->_freg_pressure = pressure[1]+fregs;
a61af66fc99e Initial load
duke
parents:
diff changeset
581 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
582 if( pressure[1] <= (uint)FLOATPRESSURE &&
a61af66fc99e Initial load
duke
parents:
diff changeset
583 pressure[1]+fregs > (uint)FLOATPRESSURE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
584 #ifndef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
585 b->_freg_pressure = (uint)FLOATPRESSURE+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
586 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
587 hrp_index[1] = j-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
590
a61af66fc99e Initial load
duke
parents:
diff changeset
591 } else { // Else it is live
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // A DEF also ends 'area' partway through the block.
a61af66fc99e Initial load
duke
parents:
diff changeset
593 lrgs(r)._area -= cost;
369
5f85534046c2 6750588: assert(lrg._area >= 0,"negative spill area") running NSK stmp0101 test
rasbold
parents: 295
diff changeset
594 assert(!(lrgs(r)._area < 0.0), "negative spill area" );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // Insure high score for immediate-use spill copies so they get a color
a61af66fc99e Initial load
duke
parents:
diff changeset
597 if( n->is_SpillCopy()
295
ea18057223c4 6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents: 0
diff changeset
598 && lrgs(r).is_singledef() // MultiDef live range can still split
0
a61af66fc99e Initial load
duke
parents:
diff changeset
599 && n->outcnt() == 1 // and use must be in this block
a61af66fc99e Initial load
duke
parents:
diff changeset
600 && _cfg._bbs[n->unique_out()->_idx] == b ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // All single-use MachSpillCopy(s) that immediately precede their
a61af66fc99e Initial load
duke
parents:
diff changeset
602 // use must color early. If a longer live range steals their
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // color, the spill copy will split and may push another spill copy
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // further away resulting in an infinite spill-split-retry cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // Assigning a zero area results in a high score() and a good
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // location in the simplify list.
a61af66fc99e Initial load
duke
parents:
diff changeset
607 //
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609 Node *single_use = n->unique_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
610 assert( b->find_node(single_use) >= j, "Use must be later in block");
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // Use can be earlier in block if it is a Phi, but then I should be a MultiDef
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // Find first non SpillCopy 'm' that follows the current instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // (j - 1) is index for current instruction 'n'
a61af66fc99e Initial load
duke
parents:
diff changeset
615 Node *m = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
616 for( uint i = j; i <= last_inst && m->is_SpillCopy(); ++i ) { m = b->_nodes[i]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
617 if( m == single_use ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
618 lrgs(r)._area = 0.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
620 }
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
622 // Remove from live-out set
a61af66fc99e Initial load
duke
parents:
diff changeset
623 if( liveout.remove(r) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // Adjust register pressure.
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // Capture last hi-to-lo pressure transition
a61af66fc99e Initial load
duke
parents:
diff changeset
626 lower_pressure( &lrgs(r), j-1, b, pressure, hrp_index );
a61af66fc99e Initial load
duke
parents:
diff changeset
627 assert( pressure[0] == count_int_pressure (&liveout), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
628 assert( pressure[1] == count_float_pressure(&liveout), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
630
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // Copies do not define a new value and so do not interfere.
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Remove the copies source from the liveout set before interfering.
a61af66fc99e Initial load
duke
parents:
diff changeset
633 uint idx = n->is_Copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
634 if( idx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
635 uint x = n2lidx(n->in(idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
636 if( liveout.remove( x ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
637 lrgs(x)._area -= cost;
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // Adjust register pressure.
a61af66fc99e Initial load
duke
parents:
diff changeset
639 lower_pressure( &lrgs(x), j-1, b, pressure, hrp_index );
a61af66fc99e Initial load
duke
parents:
diff changeset
640 assert( pressure[0] == count_int_pressure (&liveout), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
641 assert( pressure[1] == count_float_pressure(&liveout), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644 } // End of if live or not
a61af66fc99e Initial load
duke
parents:
diff changeset
645
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // Interfere with everything live. If the defined value must
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // go in a particular register, just remove that register from
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // all conflicting parties and avoid the interference.
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // Make exclusions for rematerializable defs. Since rematerializable
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // DEFs are not bound but the live range is, some uses must be bound.
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // If we spill live range 'r', it can rematerialize at each use site
a61af66fc99e Initial load
duke
parents:
diff changeset
653 // according to its bindings.
a61af66fc99e Initial load
duke
parents:
diff changeset
654 const RegMask &rmask = lrgs(r).mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
655 if( lrgs(r).is_bound() && !(n->rematerialize()) && rmask.is_NotEmpty() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // Smear odd bits; leave only aligned pairs of bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
657 RegMask r2mask = rmask;
a61af66fc99e Initial load
duke
parents:
diff changeset
658 r2mask.SmearToPairs();
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // Check for common case
a61af66fc99e Initial load
duke
parents:
diff changeset
660 int r_size = lrgs(r).num_regs();
a61af66fc99e Initial load
duke
parents:
diff changeset
661 OptoReg::Name r_reg = (r_size == 1) ? rmask.find_first_elem() : OptoReg::Physical;
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 IndexSetIterator elements(&liveout);
a61af66fc99e Initial load
duke
parents:
diff changeset
664 uint l;
a61af66fc99e Initial load
duke
parents:
diff changeset
665 while ((l = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
666 LRG &lrg = lrgs(l);
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // If 'l' must spill already, do not further hack his bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // He'll get some interferences and be forced to spill later.
a61af66fc99e Initial load
duke
parents:
diff changeset
669 if( lrg._must_spill ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // Remove bound register(s) from 'l's choices
a61af66fc99e Initial load
duke
parents:
diff changeset
671 RegMask old = lrg.mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
672 uint old_size = lrg.mask_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // Remove the bits from LRG 'r' from LRG 'l' so 'l' no
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // longer interferes with 'r'. If 'l' requires aligned
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // adjacent pairs, subtract out bit pairs.
a61af66fc99e Initial load
duke
parents:
diff changeset
676 if( lrg.num_regs() == 2 && !lrg._fat_proj ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
677 lrg.SUBTRACT( r2mask );
a61af66fc99e Initial load
duke
parents:
diff changeset
678 lrg.compute_set_mask_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
679 } else if( r_size != 1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
680 lrg.SUBTRACT( rmask );
a61af66fc99e Initial load
duke
parents:
diff changeset
681 lrg.compute_set_mask_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
682 } else { // Common case: size 1 bound removal
a61af66fc99e Initial load
duke
parents:
diff changeset
683 if( lrg.mask().Member(r_reg) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
684 lrg.Remove(r_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 lrg.set_mask_size(lrg.mask().is_AllStack() ? 65535:old_size-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
688 // If 'l' goes completely dry, it must spill.
a61af66fc99e Initial load
duke
parents:
diff changeset
689 if( lrg.not_free() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // Give 'l' some kind of reasonable mask, so he picks up
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // interferences (and will spill later).
a61af66fc99e Initial load
duke
parents:
diff changeset
692 lrg.set_mask( old );
a61af66fc99e Initial load
duke
parents:
diff changeset
693 lrg.set_mask_size(old_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
694 must_spill++;
a61af66fc99e Initial load
duke
parents:
diff changeset
695 lrg._must_spill = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
696 lrg.set_reg(OptoReg::Name(LRG::SPILL_REG));
a61af66fc99e Initial load
duke
parents:
diff changeset
697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
699 } // End of if bound
a61af66fc99e Initial load
duke
parents:
diff changeset
700
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // Now interference with everything that is live and has
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // compatible register sets.
a61af66fc99e Initial load
duke
parents:
diff changeset
703 interfere_with_live(r,&liveout);
a61af66fc99e Initial load
duke
parents:
diff changeset
704
a61af66fc99e Initial load
duke
parents:
diff changeset
705 } // End of if normal register-allocated value
a61af66fc99e Initial load
duke
parents:
diff changeset
706
369
5f85534046c2 6750588: assert(lrg._area >= 0,"negative spill area") running NSK stmp0101 test
rasbold
parents: 295
diff changeset
707 // Area remaining in the block
5f85534046c2 6750588: assert(lrg._area >= 0,"negative spill area") running NSK stmp0101 test
rasbold
parents: 295
diff changeset
708 inst_count--;
5f85534046c2 6750588: assert(lrg._area >= 0,"negative spill area") running NSK stmp0101 test
rasbold
parents: 295
diff changeset
709 cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
710
a61af66fc99e Initial load
duke
parents:
diff changeset
711 // Make all inputs live
a61af66fc99e Initial load
duke
parents:
diff changeset
712 if( !n->is_Phi() ) { // Phi function uses come from prior block
a61af66fc99e Initial load
duke
parents:
diff changeset
713 JVMState* jvms = n->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
714 uint debug_start = jvms ? jvms->debug_start() : 999999;
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // Start loop at 1 (skip control edge) for most Nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
716 // SCMemProj's might be the sole use of a StoreLConditional.
a61af66fc99e Initial load
duke
parents:
diff changeset
717 // While StoreLConditionals set memory (the SCMemProj use)
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // they also def flags; if that flag def is unused the
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // allocator sees a flag-setting instruction with no use of
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // the flags and assumes it's dead. This keeps the (useless)
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // flag-setting behavior alive while also keeping the (useful)
a61af66fc99e Initial load
duke
parents:
diff changeset
722 // memory update effect.
a61af66fc99e Initial load
duke
parents:
diff changeset
723 for( uint k = ((n->Opcode() == Op_SCMemProj) ? 0:1); k < n->req(); k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
724 Node *def = n->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 uint x = n2lidx(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
726 if( !x ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
727 LRG &lrg = lrgs(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // No use-side cost for spilling debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
729 if( k < debug_start )
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // A USE costs twice block frequency (once for the Load, once
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // for a Load-delay). Rematerialized uses only cost once.
a61af66fc99e Initial load
duke
parents:
diff changeset
732 lrg._cost += (def->rematerialize() ? b->_freq : (b->_freq + b->_freq));
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // It is live now
a61af66fc99e Initial load
duke
parents:
diff changeset
734 if( liveout.insert( x ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // Newly live things assumed live from here to top of block
a61af66fc99e Initial load
duke
parents:
diff changeset
736 lrg._area += cost;
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // Adjust register pressure
a61af66fc99e Initial load
duke
parents:
diff changeset
738 if( lrg.mask().is_UP() && lrg.mask_size() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
739 if( lrg._is_float ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
740 pressure[1] += lrg.reg_pressure();
a61af66fc99e Initial load
duke
parents:
diff changeset
741 #ifdef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
742 if( pressure[1] > b->_freg_pressure )
a61af66fc99e Initial load
duke
parents:
diff changeset
743 b->_freg_pressure = pressure[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
744 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
745 } else if( lrg.mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
746 pressure[0] += lrg.reg_pressure();
a61af66fc99e Initial load
duke
parents:
diff changeset
747 #ifdef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
748 if( pressure[0] > b->_reg_pressure )
a61af66fc99e Initial load
duke
parents:
diff changeset
749 b->_reg_pressure = pressure[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
750 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
752 }
a61af66fc99e Initial load
duke
parents:
diff changeset
753 assert( pressure[0] == count_int_pressure (&liveout), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
754 assert( pressure[1] == count_float_pressure(&liveout), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
755 }
369
5f85534046c2 6750588: assert(lrg._area >= 0,"negative spill area") running NSK stmp0101 test
rasbold
parents: 295
diff changeset
756 assert(!(lrg._area < 0.0), "negative spill area" );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
759 } // End of reverse pass over all instructions in block
a61af66fc99e Initial load
duke
parents:
diff changeset
760
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // If we run off the top of the block with high pressure and
a61af66fc99e Initial load
duke
parents:
diff changeset
762 // never see a hi-to-low pressure transition, just record that
a61af66fc99e Initial load
duke
parents:
diff changeset
763 // the whole block is high pressure.
a61af66fc99e Initial load
duke
parents:
diff changeset
764 if( pressure[0] > (uint)INTPRESSURE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
765 hrp_index[0] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
766 #ifdef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
767 if( pressure[0] > b->_reg_pressure )
a61af66fc99e Initial load
duke
parents:
diff changeset
768 b->_reg_pressure = pressure[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
769 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
770 b->_reg_pressure = (uint)INTPRESSURE+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
771 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
772 }
a61af66fc99e Initial load
duke
parents:
diff changeset
773 if( pressure[1] > (uint)FLOATPRESSURE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
774 hrp_index[1] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
775 #ifdef EXACT_PRESSURE
a61af66fc99e Initial load
duke
parents:
diff changeset
776 if( pressure[1] > b->_freg_pressure )
a61af66fc99e Initial load
duke
parents:
diff changeset
777 b->_freg_pressure = pressure[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
778 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
779 b->_freg_pressure = (uint)FLOATPRESSURE+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
780 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
782
a61af66fc99e Initial load
duke
parents:
diff changeset
783 // Compute high pressure indice; avoid landing in the middle of projnodes
a61af66fc99e Initial load
duke
parents:
diff changeset
784 j = hrp_index[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
785 if( j < b->_nodes.size() && j < b->end_idx()+1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
786 Node *cur = b->_nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
787 while( cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
788 j--;
a61af66fc99e Initial load
duke
parents:
diff changeset
789 cur = b->_nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
792 b->_ihrp_index = j;
a61af66fc99e Initial load
duke
parents:
diff changeset
793 j = hrp_index[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
794 if( j < b->_nodes.size() && j < b->end_idx()+1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
795 Node *cur = b->_nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
796 while( cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
797 j--;
a61af66fc99e Initial load
duke
parents:
diff changeset
798 cur = b->_nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
801 b->_fhrp_index = j;
a61af66fc99e Initial load
duke
parents:
diff changeset
802
a61af66fc99e Initial load
duke
parents:
diff changeset
803 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
804 // Gather Register Pressure Statistics
a61af66fc99e Initial load
duke
parents:
diff changeset
805 if( PrintOptoStatistics ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
806 if( b->_reg_pressure > (uint)INTPRESSURE || b->_freg_pressure > (uint)FLOATPRESSURE )
a61af66fc99e Initial load
duke
parents:
diff changeset
807 _high_pressure++;
a61af66fc99e Initial load
duke
parents:
diff changeset
808 else
a61af66fc99e Initial load
duke
parents:
diff changeset
809 _low_pressure++;
a61af66fc99e Initial load
duke
parents:
diff changeset
810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
811 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
812 } // End of for all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
813
a61af66fc99e Initial load
duke
parents:
diff changeset
814 return must_spill;
a61af66fc99e Initial load
duke
parents:
diff changeset
815 }