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