annotate src/share/vm/opto/coalesce.cpp @ 3992:d1bdeef3e3e2

7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76 Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing. Reviewed-by: tonyp, brutisso, ysr
author johnc
date Wed, 12 Oct 2011 10:25:51 -0700
parents c7b60b601eb4
children 8373c19be854
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1730
diff changeset
2 * Copyright (c) 1997, 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: 844
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 844
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: 844
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: 1730
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1730
diff changeset
26 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1730
diff changeset
27 #include "opto/block.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1730
diff changeset
28 #include "opto/cfgnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1730
diff changeset
29 #include "opto/chaitin.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1730
diff changeset
30 #include "opto/coalesce.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1730
diff changeset
31 #include "opto/connode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1730
diff changeset
32 #include "opto/indexSet.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1730
diff changeset
33 #include "opto/machnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1730
diff changeset
34 #include "opto/matcher.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1730
diff changeset
35 #include "opto/regmask.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
36
a61af66fc99e Initial load
duke
parents:
diff changeset
37 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
38 //------------------------------reset_uf_map-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
39 void PhaseChaitin::reset_uf_map( uint maxlrg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
40 _maxlrg = maxlrg;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // Force the Union-Find mapping to be at least this large
a61af66fc99e Initial load
duke
parents:
diff changeset
42 _uf_map.extend(_maxlrg,0);
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // Initialize it to be the ID mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
44 for( uint i=0; i<_maxlrg; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
45 _uf_map.map(i,i);
a61af66fc99e Initial load
duke
parents:
diff changeset
46 }
a61af66fc99e Initial load
duke
parents:
diff changeset
47
a61af66fc99e Initial load
duke
parents:
diff changeset
48 //------------------------------compress_uf_map--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // Make all Nodes map directly to their final live range; no need for
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // the Union-Find mapping after this call.
a61af66fc99e Initial load
duke
parents:
diff changeset
51 void PhaseChaitin::compress_uf_map_for_nodes( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // For all Nodes, compress mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
53 uint unique = _names.Size();
a61af66fc99e Initial load
duke
parents:
diff changeset
54 for( uint i=0; i<unique; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 uint lrg = _names[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
56 uint compressed_lrg = Find(lrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
57 if( lrg != compressed_lrg )
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _names.map(i,compressed_lrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
59 }
a61af66fc99e Initial load
duke
parents:
diff changeset
60 }
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 //------------------------------Find-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // Straight out of Tarjan's union-find algorithm
a61af66fc99e Initial load
duke
parents:
diff changeset
64 uint PhaseChaitin::Find_compress( uint lrg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 uint cur = lrg;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 uint next = _uf_map[cur];
a61af66fc99e Initial load
duke
parents:
diff changeset
67 while( next != cur ) { // Scan chain of equivalences
a61af66fc99e Initial load
duke
parents:
diff changeset
68 assert( next < cur, "always union smaller" );
a61af66fc99e Initial load
duke
parents:
diff changeset
69 cur = next; // until find a fixed-point
a61af66fc99e Initial load
duke
parents:
diff changeset
70 next = _uf_map[cur];
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // Core of union-find algorithm: update chain of
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // equivalences to be equal to the root.
a61af66fc99e Initial load
duke
parents:
diff changeset
74 while( lrg != next ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
75 uint tmp = _uf_map[lrg];
a61af66fc99e Initial load
duke
parents:
diff changeset
76 _uf_map.map(lrg, next);
a61af66fc99e Initial load
duke
parents:
diff changeset
77 lrg = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79 return lrg;
a61af66fc99e Initial load
duke
parents:
diff changeset
80 }
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 //------------------------------Find-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // Straight out of Tarjan's union-find algorithm
a61af66fc99e Initial load
duke
parents:
diff changeset
84 uint PhaseChaitin::Find_compress( const Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 uint lrg = Find_compress(_names[n->_idx]);
a61af66fc99e Initial load
duke
parents:
diff changeset
86 _names.map(n->_idx,lrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
87 return lrg;
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90 //------------------------------Find_const-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
91 // Like Find above, but no path compress, so bad asymptotic behavior
a61af66fc99e Initial load
duke
parents:
diff changeset
92 uint PhaseChaitin::Find_const( uint lrg ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
93 if( !lrg ) return lrg; // Ignore the zero LRG
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // Off the end? This happens during debugging dumps when you got
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // brand new live ranges but have not told the allocator yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
96 if( lrg >= _maxlrg ) return lrg;
a61af66fc99e Initial load
duke
parents:
diff changeset
97 uint next = _uf_map[lrg];
a61af66fc99e Initial load
duke
parents:
diff changeset
98 while( next != lrg ) { // Scan chain of equivalences
a61af66fc99e Initial load
duke
parents:
diff changeset
99 assert( next < lrg, "always union smaller" );
a61af66fc99e Initial load
duke
parents:
diff changeset
100 lrg = next; // until find a fixed-point
a61af66fc99e Initial load
duke
parents:
diff changeset
101 next = _uf_map[lrg];
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103 return next;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 //------------------------------Find-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // Like Find above, but no path compress, so bad asymptotic behavior
a61af66fc99e Initial load
duke
parents:
diff changeset
108 uint PhaseChaitin::Find_const( const Node *n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 if( n->_idx >= _names.Size() ) return 0; // not mapped, usual for debug dump
a61af66fc99e Initial load
duke
parents:
diff changeset
110 return Find_const( _names[n->_idx] );
a61af66fc99e Initial load
duke
parents:
diff changeset
111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 //------------------------------Union------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // union 2 sets together.
a61af66fc99e Initial load
duke
parents:
diff changeset
115 void PhaseChaitin::Union( const Node *src_n, const Node *dst_n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 uint src = Find(src_n);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 uint dst = Find(dst_n);
a61af66fc99e Initial load
duke
parents:
diff changeset
118 assert( src, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
119 assert( dst, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
120 assert( src < _maxlrg, "oob" );
a61af66fc99e Initial load
duke
parents:
diff changeset
121 assert( dst < _maxlrg, "oob" );
a61af66fc99e Initial load
duke
parents:
diff changeset
122 assert( src < dst, "always union smaller" );
a61af66fc99e Initial load
duke
parents:
diff changeset
123 _uf_map.map(dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 //------------------------------new_lrg----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
127 void PhaseChaitin::new_lrg( const Node *x, uint lrg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // Make the Node->LRG mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
129 _names.extend(x->_idx,lrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // Make the Union-Find mapping an identity function
a61af66fc99e Initial load
duke
parents:
diff changeset
131 _uf_map.extend(lrg,lrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134 //------------------------------clone_projs------------------------------------
605
98cb887364d3 6810672: Comment typos
twisti
parents: 337
diff changeset
135 // After cloning some rematerialized instruction, clone any MachProj's that
0
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // use G3 as an address temp.
a61af66fc99e Initial load
duke
parents:
diff changeset
138 int PhaseChaitin::clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 Block *bcon = _cfg._bbs[con->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
140 uint cindex = bcon->find_node(con);
a61af66fc99e Initial load
duke
parents:
diff changeset
141 Node *con_next = bcon->_nodes[cindex+1];
3842
c7b60b601eb4 7069452: Cleanup NodeFlags
kvn
parents: 1972
diff changeset
142 if( con_next->in(0) != con || !con_next->is_MachProj() )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
143 return false; // No MachProj's follow
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // Copy kills after the cloned constant
a61af66fc99e Initial load
duke
parents:
diff changeset
146 Node *kills = con_next->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
147 kills->set_req( 0, copy );
a61af66fc99e Initial load
duke
parents:
diff changeset
148 b->_nodes.insert( idx, kills );
a61af66fc99e Initial load
duke
parents:
diff changeset
149 _cfg._bbs.map( kills->_idx, b );
a61af66fc99e Initial load
duke
parents:
diff changeset
150 new_lrg( kills, maxlrg++ );
a61af66fc99e Initial load
duke
parents:
diff changeset
151 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 //------------------------------compact----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // Renumber the live ranges to compact them. Makes the IFG smaller.
a61af66fc99e Initial load
duke
parents:
diff changeset
156 void PhaseChaitin::compact() {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // Current the _uf_map contains a series of short chains which are headed
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // by a self-cycle. All the chains run from big numbers to little numbers.
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // The Find() call chases the chains & shortens them for the next Find call.
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // We are going to change this structure slightly. Numbers above a moving
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // wave 'i' are unchanged. Numbers below 'j' point directly to their
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // compacted live range with no further chaining. There are no chains or
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // cycles below 'i', so the Find call no longer works.
a61af66fc99e Initial load
duke
parents:
diff changeset
164 uint j=1;
a61af66fc99e Initial load
duke
parents:
diff changeset
165 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 for( i=1; i < _maxlrg; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 uint lr = _uf_map[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // Ignore unallocated live ranges
a61af66fc99e Initial load
duke
parents:
diff changeset
169 if( !lr ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
170 assert( lr <= i, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
171 _uf_map.map(i, ( lr == i ) ? j++ : _uf_map[lr]);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173 if( false ) // PrintOptoCompactLiveRanges
a61af66fc99e Initial load
duke
parents:
diff changeset
174 printf("Compacted %d LRs from %d\n",i-j,i);
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // Now change the Node->LR mapping to reflect the compacted names
a61af66fc99e Initial load
duke
parents:
diff changeset
176 uint unique = _names.Size();
a61af66fc99e Initial load
duke
parents:
diff changeset
177 for( i=0; i<unique; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
178 _names.map(i,_uf_map[_names[i]]);
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // Reset the Union-Find mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
181 reset_uf_map(j);
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 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
186 //------------------------------Dump-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
187 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
188 void PhaseCoalesce::dump( Node *n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // Being a const function means I cannot use 'Find'
a61af66fc99e Initial load
duke
parents:
diff changeset
190 uint r = _phc.Find(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
191 tty->print("L%d/N%d ",r,n->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 //------------------------------dump-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
195 void PhaseCoalesce::dump() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // I know I have a block layout now, so I can print blocks in a loop
a61af66fc99e Initial load
duke
parents:
diff changeset
197 for( uint i=0; i<_phc._cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 uint j;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 Block *b = _phc._cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // Print a nice block header
a61af66fc99e Initial load
duke
parents:
diff changeset
201 tty->print("B%d: ",b->_pre_order);
a61af66fc99e Initial load
duke
parents:
diff changeset
202 for( j=1; j<b->num_preds(); j++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
203 tty->print("B%d ", _phc._cfg._bbs[b->pred(j)->_idx]->_pre_order);
a61af66fc99e Initial load
duke
parents:
diff changeset
204 tty->print("-> ");
a61af66fc99e Initial load
duke
parents:
diff changeset
205 for( j=0; j<b->_num_succs; j++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
206 tty->print("B%d ",b->_succs[j]->_pre_order);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 tty->print(" IDom: B%d/#%d\n", b->_idom ? b->_idom->_pre_order : 0, b->_dom_depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
208 uint cnt = b->_nodes.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
209 for( j=0; j<cnt; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 Node *n = b->_nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
211 dump( n );
a61af66fc99e Initial load
duke
parents:
diff changeset
212 tty->print("\t%s\t",n->Name());
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // Dump the inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
215 uint k; // Exit value of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
216 for( k=0; k<n->req(); k++ ) // For all required inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if( n->in(k) ) dump( n->in(k) );
a61af66fc99e Initial load
duke
parents:
diff changeset
218 else tty->print("_ ");
a61af66fc99e Initial load
duke
parents:
diff changeset
219 int any_prec = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 for( ; k<n->len(); k++ ) // For all precedence inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
221 if( n->in(k) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 if( !any_prec++ ) tty->print(" |");
a61af66fc99e Initial load
duke
parents:
diff changeset
223 dump( n->in(k) );
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // Dump node-specific info
a61af66fc99e Initial load
duke
parents:
diff changeset
227 n->dump_spec(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
234 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236 //------------------------------combine_these_two------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // Combine the live ranges def'd by these 2 Nodes. N2 is an input to N1.
a61af66fc99e Initial load
duke
parents:
diff changeset
238 void PhaseCoalesce::combine_these_two( Node *n1, Node *n2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 uint lr1 = _phc.Find(n1);
a61af66fc99e Initial load
duke
parents:
diff changeset
240 uint lr2 = _phc.Find(n2);
a61af66fc99e Initial load
duke
parents:
diff changeset
241 if( lr1 != lr2 && // Different live ranges already AND
a61af66fc99e Initial load
duke
parents:
diff changeset
242 !_phc._ifg->test_edge_sq( lr1, lr2 ) ) { // Do not interfere
a61af66fc99e Initial load
duke
parents:
diff changeset
243 LRG *lrg1 = &_phc.lrgs(lr1);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 LRG *lrg2 = &_phc.lrgs(lr2);
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // Not an oop->int cast; oop->oop, int->int, AND int->oop are OK.
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // Now, why is int->oop OK? We end up declaring a raw-pointer as an oop
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // and in general that's a bad thing. However, int->oop conversions only
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // happen at GC points, so the lifetime of the misclassified raw-pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // is from the CheckCastPP (that converts it to an oop) backwards up
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // through a merge point and into the slow-path call, and around the
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // diamond up to the heap-top check and back down into the slow-path call.
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // The misclassified raw pointer is NOT live across the slow-path call,
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // and so does not appear in any GC info, so the fact that it is
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // misclassified is OK.
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 if( (lrg1->_is_oop || !lrg2->_is_oop) && // not an oop->int cast AND
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // Compatible final mask
a61af66fc99e Initial load
duke
parents:
diff changeset
259 lrg1->mask().overlap( lrg2->mask() ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // Merge larger into smaller.
a61af66fc99e Initial load
duke
parents:
diff changeset
261 if( lr1 > lr2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 uint tmp = lr1; lr1 = lr2; lr2 = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
263 Node *n = n1; n1 = n2; n2 = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
264 LRG *ltmp = lrg1; lrg1 = lrg2; lrg2 = ltmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // Union lr2 into lr1
a61af66fc99e Initial load
duke
parents:
diff changeset
267 _phc.Union( n1, n2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
268 if (lrg1->_maxfreq < lrg2->_maxfreq)
a61af66fc99e Initial load
duke
parents:
diff changeset
269 lrg1->_maxfreq = lrg2->_maxfreq;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Merge in the IFG
a61af66fc99e Initial load
duke
parents:
diff changeset
271 _phc._ifg->Union( lr1, lr2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // Combine register restrictions
a61af66fc99e Initial load
duke
parents:
diff changeset
273 lrg1->AND(lrg2->mask());
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 //------------------------------coalesce_driver--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // Copy coalescing
a61af66fc99e Initial load
duke
parents:
diff changeset
280 void PhaseCoalesce::coalesce_driver( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282 verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // Coalesce from high frequency to low
a61af66fc99e Initial load
duke
parents:
diff changeset
284 for( uint i=0; i<_phc._cfg._num_blocks; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
285 coalesce( _phc._blks[i] );
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288
a61af66fc99e Initial load
duke
parents:
diff changeset
289 //------------------------------insert_copy_with_overlap-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // I am inserting copies to come out of SSA form. In the general case, I am
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // doing a parallel renaming. I'm in the Named world now, so I can't do a
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // general parallel renaming. All the copies now use "names" (live-ranges)
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // to carry values instead of the explicit use-def chains. Suppose I need to
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // insert 2 copies into the same block. They copy L161->L128 and L128->L132.
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // If I insert them in the wrong order then L128 will get clobbered before it
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // can get used by the second copy. This cannot happen in the SSA model;
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // direct use-def chains get me the right value. It DOES happen in the named
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // model so I have to handle the reordering of copies.
a61af66fc99e Initial load
duke
parents:
diff changeset
299 //
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // In general, I need to topo-sort the placed copies to avoid conflicts.
a61af66fc99e Initial load
duke
parents:
diff changeset
301 // Its possible to have a closed cycle of copies (e.g., recirculating the same
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // values around a loop). In this case I need a temp to break the cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
303 void PhaseAggressiveCoalesce::insert_copy_with_overlap( Block *b, Node *copy, uint dst_name, uint src_name ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // Scan backwards for the locations of the last use of the dst_name.
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // I am about to clobber the dst_name, so the copy must be inserted
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // after the last use. Last use is really first-use on a backwards scan.
a61af66fc99e Initial load
duke
parents:
diff changeset
308 uint i = b->end_idx()-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
309 while( 1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 Node *n = b->_nodes[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // Check for end of virtual copies; this is also the end of the
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // parallel renaming effort.
a61af66fc99e Initial load
duke
parents:
diff changeset
313 if( n->_idx < _unique ) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
314 uint idx = n->is_Copy();
3842
c7b60b601eb4 7069452: Cleanup NodeFlags
kvn
parents: 1972
diff changeset
315 assert( idx || n->is_Con() || n->is_MachProj(), "Only copies during parallel renaming" );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
316 if( idx && _phc.Find(n->in(idx)) == dst_name ) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
317 i--;
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319 uint last_use_idx = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // Also search for any kill of src_name that exits the block.
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // Since the copy uses src_name, I have to come before any kill.
a61af66fc99e Initial load
duke
parents:
diff changeset
323 uint kill_src_idx = b->end_idx();
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // There can be only 1 kill that exits any block and that is
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // the last kill. Thus it is the first kill on a backwards scan.
a61af66fc99e Initial load
duke
parents:
diff changeset
326 i = b->end_idx()-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
327 while( 1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 Node *n = b->_nodes[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // Check for end of virtual copies; this is also the end of the
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // parallel renaming effort.
a61af66fc99e Initial load
duke
parents:
diff changeset
331 if( n->_idx < _unique ) break;
3842
c7b60b601eb4 7069452: Cleanup NodeFlags
kvn
parents: 1972
diff changeset
332 assert( n->is_Copy() || n->is_Con() || n->is_MachProj(), "Only copies during parallel renaming" );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
333 if( _phc.Find(n) == src_name ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
334 kill_src_idx = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
335 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
337 i--;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // Need a temp? Last use of dst comes after the kill of src?
a61af66fc99e Initial load
duke
parents:
diff changeset
340 if( last_use_idx >= kill_src_idx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // Need to break a cycle with a temp
a61af66fc99e Initial load
duke
parents:
diff changeset
342 uint idx = copy->is_Copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
343 Node *tmp = copy->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
344 _phc.new_lrg(tmp,_phc._maxlrg++);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // Insert new temp between copy and source
a61af66fc99e Initial load
duke
parents:
diff changeset
346 tmp ->set_req(idx,copy->in(idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
347 copy->set_req(idx,tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // Save source in temp early, before source is killed
a61af66fc99e Initial load
duke
parents:
diff changeset
349 b->_nodes.insert(kill_src_idx,tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
350 _phc._cfg._bbs.map( tmp->_idx, b );
a61af66fc99e Initial load
duke
parents:
diff changeset
351 last_use_idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // Insert just after last use
a61af66fc99e Initial load
duke
parents:
diff changeset
355 b->_nodes.insert(last_use_idx+1,copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 //------------------------------insert_copies----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
359 void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // We do LRGs compressing and fix a liveout data only here since the other
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // place in Split() is guarded by the assert which we never hit.
a61af66fc99e Initial load
duke
parents:
diff changeset
362 _phc.compress_uf_map_for_nodes();
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // Fix block's liveout data for compressed live ranges.
a61af66fc99e Initial load
duke
parents:
diff changeset
364 for(uint lrg = 1; lrg < _phc._maxlrg; lrg++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
365 uint compressed_lrg = _phc.Find(lrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
366 if( lrg != compressed_lrg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 for( uint bidx = 0; bidx < _phc._cfg._num_blocks; bidx++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
368 IndexSet *liveout = _phc._live->live(_phc._cfg._blocks[bidx]);
a61af66fc99e Initial load
duke
parents:
diff changeset
369 if( liveout->member(lrg) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 liveout->remove(lrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
371 liveout->insert(compressed_lrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // All new nodes added are actual copies to replace virtual copies.
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // Nodes with index less than '_unique' are original, non-virtual Nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
379 _unique = C->unique();
a61af66fc99e Initial load
duke
parents:
diff changeset
380
a61af66fc99e Initial load
duke
parents:
diff changeset
381 for( uint i=0; i<_phc._cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 Block *b = _phc._cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
383 uint cnt = b->num_preds(); // Number of inputs to the Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
384
a61af66fc99e Initial load
duke
parents:
diff changeset
385 for( uint l = 1; l<b->_nodes.size(); l++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 Node *n = b->_nodes[l];
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // Do not use removed-copies, use copied value instead
a61af66fc99e Initial load
duke
parents:
diff changeset
389 uint ncnt = n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
390 for( uint k = 1; k<ncnt; k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 Node *copy = n->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
392 uint cidx = copy->is_Copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
393 if( cidx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 Node *def = copy->in(cidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
395 if( _phc.Find(copy) == _phc.Find(def) )
a61af66fc99e Initial load
duke
parents:
diff changeset
396 n->set_req(k,def);
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // Remove any explicit copies that get coalesced.
a61af66fc99e Initial load
duke
parents:
diff changeset
401 uint cidx = n->is_Copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
402 if( cidx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 Node *def = n->in(cidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
404 if( _phc.Find(n) == _phc.Find(def) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
405 n->replace_by(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
406 n->set_req(cidx,NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
407 b->_nodes.remove(l);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 l--;
a61af66fc99e Initial load
duke
parents:
diff changeset
409 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 if( n->is_Phi() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // Get the chosen name for the Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
415 uint phi_name = _phc.Find( n );
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // Ignore the pre-allocated specials
a61af66fc99e Initial load
duke
parents:
diff changeset
417 if( !phi_name ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // Check for mismatch inputs to Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
419 for( uint j = 1; j<cnt; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
420 Node *m = n->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
421 uint src_name = _phc.Find(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
422 if( src_name != phi_name ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
423 Block *pred = _phc._cfg._bbs[b->pred(j)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
424 Node *copy;
a61af66fc99e Initial load
duke
parents:
diff changeset
425 assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach");
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // Rematerialize constants instead of copying them
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if( m->is_Mach() && m->as_Mach()->is_Con() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
428 m->as_Mach()->rematerialize() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
429 copy = m->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // Insert the copy in the predecessor basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
431 pred->add_inst(copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // Copy any flags as well
a61af66fc99e Initial load
duke
parents:
diff changeset
433 _phc.clone_projs( pred, pred->end_idx(), m, copy, _phc._maxlrg );
a61af66fc99e Initial load
duke
parents:
diff changeset
434 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
435 const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
a61af66fc99e Initial load
duke
parents:
diff changeset
436 copy = new (C) MachSpillCopyNode(m,*rm,*rm);
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // Find a good place to insert. Kinda tricky, use a subroutine
a61af66fc99e Initial load
duke
parents:
diff changeset
438 insert_copy_with_overlap(pred,copy,phi_name,src_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // Insert the copy in the use-def chain
a61af66fc99e Initial load
duke
parents:
diff changeset
441 n->set_req( j, copy );
a61af66fc99e Initial load
duke
parents:
diff changeset
442 _phc._cfg._bbs.map( copy->_idx, pred );
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // Extend ("register allocate") the names array for the copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
444 _phc._names.extend( copy->_idx, phi_name );
a61af66fc99e Initial load
duke
parents:
diff changeset
445 } // End of if Phi names do not match
a61af66fc99e Initial load
duke
parents:
diff changeset
446 } // End of for all inputs to Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
447 } else { // End of if Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // Now check for 2-address instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
450 uint idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
451 if( n->is_Mach() && (idx=n->as_Mach()->two_adr()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // Get the chosen name for the Node
a61af66fc99e Initial load
duke
parents:
diff changeset
453 uint name = _phc.Find( n );
a61af66fc99e Initial load
duke
parents:
diff changeset
454 assert( name, "no 2-address specials" );
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // Check for name mis-match on the 2-address input
a61af66fc99e Initial load
duke
parents:
diff changeset
456 Node *m = n->in(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
457 if( _phc.Find(m) != name ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 Node *copy;
a61af66fc99e Initial load
duke
parents:
diff changeset
459 assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach");
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // At this point it is unsafe to extend live ranges (6550579).
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // Rematerialize only constants as we do for Phi above.
a61af66fc99e Initial load
duke
parents:
diff changeset
462 if( m->is_Mach() && m->as_Mach()->is_Con() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
463 m->as_Mach()->rematerialize() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 copy = m->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // Insert the copy in the basic block, just before us
a61af66fc99e Initial load
duke
parents:
diff changeset
466 b->_nodes.insert( l++, copy );
a61af66fc99e Initial load
duke
parents:
diff changeset
467 if( _phc.clone_projs( b, l, m, copy, _phc._maxlrg ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
468 l++;
a61af66fc99e Initial load
duke
parents:
diff changeset
469 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
a61af66fc99e Initial load
duke
parents:
diff changeset
471 copy = new (C) MachSpillCopyNode( m, *rm, *rm );
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // Insert the copy in the basic block, just before us
a61af66fc99e Initial load
duke
parents:
diff changeset
473 b->_nodes.insert( l++, copy );
a61af66fc99e Initial load
duke
parents:
diff changeset
474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // Insert the copy in the use-def chain
a61af66fc99e Initial load
duke
parents:
diff changeset
476 n->set_req(idx, copy );
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // Extend ("register allocate") the names array for the copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
478 _phc._names.extend( copy->_idx, name );
a61af66fc99e Initial load
duke
parents:
diff changeset
479 _phc._cfg._bbs.map( copy->_idx, b );
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 } // End of is two-adr
a61af66fc99e Initial load
duke
parents:
diff changeset
483
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // Insert a copy at a debug use for a lrg which has high frequency
673
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 605
diff changeset
485 if( b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(_phc._cfg._bbs) ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // Walk the debug inputs to the node and check for lrg freq
a61af66fc99e Initial load
duke
parents:
diff changeset
487 JVMState* jvms = n->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
488 uint debug_start = jvms ? jvms->debug_start() : 999999;
a61af66fc99e Initial load
duke
parents:
diff changeset
489 uint debug_end = jvms ? jvms->debug_end() : 999999;
a61af66fc99e Initial load
duke
parents:
diff changeset
490 for(uint inpidx = debug_start; inpidx < debug_end; inpidx++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // Do not split monitors; they are only needed for debug table
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // entries and need no code.
a61af66fc99e Initial load
duke
parents:
diff changeset
493 if( jvms->is_monitor_use(inpidx) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
494 Node *inp = n->in(inpidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
495 uint nidx = _phc.n2lidx(inp);
a61af66fc99e Initial load
duke
parents:
diff changeset
496 LRG &lrg = lrgs(nidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // If this lrg has a high frequency use/def
673
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 605
diff changeset
499 if( lrg._maxfreq >= _phc.high_frequency_lrg() ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // If the live range is also live out of this block (like it
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // would be for a fast/slow idiom), the normal spill mechanism
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // does an excellent job. If it is not live out of this block
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // (like it would be for debug info to uncommon trap) splitting
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // the live range now allows a better allocation in the high
a61af66fc99e Initial load
duke
parents:
diff changeset
505 // frequency blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // Build_IFG_virtual has converted the live sets to
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // live-IN info, not live-OUT info.
a61af66fc99e Initial load
duke
parents:
diff changeset
508 uint k;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 for( k=0; k < b->_num_succs; k++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
510 if( _phc._live->live(b->_succs[k])->member( nidx ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
511 break; // Live in to some successor block?
a61af66fc99e Initial load
duke
parents:
diff changeset
512 if( k < b->_num_succs )
a61af66fc99e Initial load
duke
parents:
diff changeset
513 continue; // Live out; do not pre-split
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // Split the lrg at this use
a61af66fc99e Initial load
duke
parents:
diff changeset
515 const RegMask *rm = C->matcher()->idealreg2spillmask[inp->ideal_reg()];
a61af66fc99e Initial load
duke
parents:
diff changeset
516 Node *copy = new (C) MachSpillCopyNode( inp, *rm, *rm );
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // Insert the copy in the use-def chain
a61af66fc99e Initial load
duke
parents:
diff changeset
518 n->set_req(inpidx, copy );
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // Insert the copy in the basic block, just before us
a61af66fc99e Initial load
duke
parents:
diff changeset
520 b->_nodes.insert( l++, copy );
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // Extend ("register allocate") the names array for the copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
522 _phc.new_lrg( copy, _phc._maxlrg++ );
a61af66fc99e Initial load
duke
parents:
diff changeset
523 _phc._cfg._bbs.map( copy->_idx, b );
a61af66fc99e Initial load
duke
parents:
diff changeset
524 //tty->print_cr("Split a debug use in Aggressive Coalesce");
a61af66fc99e Initial load
duke
parents:
diff changeset
525 } // End of if high frequency use/def
a61af66fc99e Initial load
duke
parents:
diff changeset
526 } // End of for all debug inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
527 } // End of if low frequency safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
528
a61af66fc99e Initial load
duke
parents:
diff changeset
529 } // End of if Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
530
a61af66fc99e Initial load
duke
parents:
diff changeset
531 } // End of for all instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
532 } // End of for all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
534
a61af66fc99e Initial load
duke
parents:
diff changeset
535 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
536 //------------------------------coalesce---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
537 // Aggressive (but pessimistic) copy coalescing of a single block
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // The following coalesce pass represents a single round of aggressive
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // pessimistic coalesce. "Aggressive" means no attempt to preserve
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // colorability when coalescing. This occasionally means more spills, but
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // it also means fewer rounds of coalescing for better code - and that means
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // faster compiles.
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // "Pessimistic" means we do not hit the fixed point in one pass (and we are
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // reaching for the least fixed point to boot). This is typically solved
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // with a few more rounds of coalescing, but the compiler must run fast. We
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // could optimistically coalescing everything touching PhiNodes together
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // into one big live range, then check for self-interference. Everywhere
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // the live range interferes with self it would have to be split. Finding
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // the right split points can be done with some heuristics (based on
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // expected frequency of edges in the live range). In short, it's a real
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // research problem and the timeline is too short to allow such research.
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // Further thoughts: (1) build the LR in a pass, (2) find self-interference
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // in another pass, (3) per each self-conflict, split, (4) split by finding
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // the low-cost cut (min-cut) of the LR, (5) edges in the LR are weighted
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // according to the GCM algorithm (or just exec freq on CFG edges).
a61af66fc99e Initial load
duke
parents:
diff changeset
558
a61af66fc99e Initial load
duke
parents:
diff changeset
559 void PhaseAggressiveCoalesce::coalesce( Block *b ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // Copies are still "virtual" - meaning we have not made them explicitly
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // copies. Instead, Phi functions of successor blocks have mis-matched
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // live-ranges. If I fail to coalesce, I'll have to insert a copy to line
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // up the live-ranges. Check for Phis in successor blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
564 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
565 for( i=0; i<b->_num_succs; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
566 Block *bs = b->_succs[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
567 // Find index of 'b' in 'bs' predecessors
a61af66fc99e Initial load
duke
parents:
diff changeset
568 uint j=1;
a61af66fc99e Initial load
duke
parents:
diff changeset
569 while( _phc._cfg._bbs[bs->pred(j)->_idx] != b ) j++;
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // Visit all the Phis in successor block
a61af66fc99e Initial load
duke
parents:
diff changeset
571 for( uint k = 1; k<bs->_nodes.size(); k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
572 Node *n = bs->_nodes[k];
a61af66fc99e Initial load
duke
parents:
diff changeset
573 if( !n->is_Phi() ) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
574 combine_these_two( n, n->in(j) );
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
576 } // End of for all successor blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
577
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // Check _this_ block for 2-address instructions and copies.
a61af66fc99e Initial load
duke
parents:
diff changeset
580 uint cnt = b->end_idx();
a61af66fc99e Initial load
duke
parents:
diff changeset
581 for( i = 1; i<cnt; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
582 Node *n = b->_nodes[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
583 uint idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // 2-address instructions have a virtual Copy matching their input
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // to their output
a61af66fc99e Initial load
duke
parents:
diff changeset
586 if( n->is_Mach() && (idx = n->as_Mach()->two_adr()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
587 MachNode *mach = n->as_Mach();
a61af66fc99e Initial load
duke
parents:
diff changeset
588 combine_these_two( mach, mach->in(idx) );
a61af66fc99e Initial load
duke
parents:
diff changeset
589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
590 } // End of for all instructions in block
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
594 //------------------------------PhaseConservativeCoalesce----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
595 PhaseConservativeCoalesce::PhaseConservativeCoalesce( PhaseChaitin &chaitin ) : PhaseCoalesce(chaitin) {
a61af66fc99e Initial load
duke
parents:
diff changeset
596 _ulr.initialize(_phc._maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 //------------------------------verify-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
600 void PhaseConservativeCoalesce::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
601 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
602 _phc.set_was_low();
a61af66fc99e Initial load
duke
parents:
diff changeset
603 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 //------------------------------union_helper-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
607 void PhaseConservativeCoalesce::union_helper( Node *lr1_node, Node *lr2_node, uint lr1, uint lr2, Node *src_def, Node *dst_copy, Node *src_copy, Block *b, uint bindex ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // Join live ranges. Merge larger into smaller. Union lr2 into lr1 in the
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // union-find tree
a61af66fc99e Initial load
duke
parents:
diff changeset
610 _phc.Union( lr1_node, lr2_node );
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // Single-def live range ONLY if both live ranges are single-def.
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // If both are single def, then src_def powers one live range
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // and def_copy powers the other. After merging, src_def powers
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // the combined live range.
295
ea18057223c4 6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents: 0
diff changeset
616 lrgs(lr1)._def = (lrgs(lr1).is_multidef() ||
ea18057223c4 6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents: 0
diff changeset
617 lrgs(lr2).is_multidef() )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
618 ? NodeSentinel : src_def;
a61af66fc99e Initial load
duke
parents:
diff changeset
619 lrgs(lr2)._def = NULL; // No def for lrg 2
a61af66fc99e Initial load
duke
parents:
diff changeset
620 lrgs(lr2).Clear(); // Force empty mask for LRG 2
a61af66fc99e Initial load
duke
parents:
diff changeset
621 //lrgs(lr2)._size = 0; // Live-range 2 goes dead
a61af66fc99e Initial load
duke
parents:
diff changeset
622 lrgs(lr1)._is_oop |= lrgs(lr2)._is_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
623 lrgs(lr2)._is_oop = 0; // In particular, not an oop for GC info
a61af66fc99e Initial load
duke
parents:
diff changeset
624
a61af66fc99e Initial load
duke
parents:
diff changeset
625 if (lrgs(lr1)._maxfreq < lrgs(lr2)._maxfreq)
a61af66fc99e Initial load
duke
parents:
diff changeset
626 lrgs(lr1)._maxfreq = lrgs(lr2)._maxfreq;
a61af66fc99e Initial load
duke
parents:
diff changeset
627
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // Copy original value instead. Intermediate copies go dead, and
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // the dst_copy becomes useless.
a61af66fc99e Initial load
duke
parents:
diff changeset
630 int didx = dst_copy->is_Copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
631 dst_copy->set_req( didx, src_def );
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Add copy to free list
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // _phc.free_spillcopy(b->_nodes[bindex]);
a61af66fc99e Initial load
duke
parents:
diff changeset
634 assert( b->_nodes[bindex] == dst_copy, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
635 dst_copy->replace_by( dst_copy->in(didx) );
a61af66fc99e Initial load
duke
parents:
diff changeset
636 dst_copy->set_req( didx, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
637 b->_nodes.remove(bindex);
a61af66fc99e Initial load
duke
parents:
diff changeset
638 if( bindex < b->_ihrp_index ) b->_ihrp_index--;
a61af66fc99e Initial load
duke
parents:
diff changeset
639 if( bindex < b->_fhrp_index ) b->_fhrp_index--;
a61af66fc99e Initial load
duke
parents:
diff changeset
640
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // Stretched lr1; add it to liveness of intermediate blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
642 Block *b2 = _phc._cfg._bbs[src_copy->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
643 while( b != b2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
644 b = _phc._cfg._bbs[b->pred(1)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
645 _phc._live->live(b)->insert(lr1);
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 //------------------------------compute_separating_interferences---------------
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // Factored code from copy_copy that computes extra interferences from
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // lengthening a live range by double-coalescing.
a61af66fc99e Initial load
duke
parents:
diff changeset
652 uint PhaseConservativeCoalesce::compute_separating_interferences(Node *dst_copy, Node *src_copy, Block *b, uint bindex, RegMask &rm, uint reg_degree, uint rm_size, uint lr1, uint lr2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
653
a61af66fc99e Initial load
duke
parents:
diff changeset
654 assert(!lrgs(lr1)._fat_proj, "cannot coalesce fat_proj");
a61af66fc99e Initial load
duke
parents:
diff changeset
655 assert(!lrgs(lr2)._fat_proj, "cannot coalesce fat_proj");
a61af66fc99e Initial load
duke
parents:
diff changeset
656 Node *prev_copy = dst_copy->in(dst_copy->is_Copy());
a61af66fc99e Initial load
duke
parents:
diff changeset
657 Block *b2 = b;
a61af66fc99e Initial load
duke
parents:
diff changeset
658 uint bindex2 = bindex;
a61af66fc99e Initial load
duke
parents:
diff changeset
659 while( 1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // Find previous instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
661 bindex2--; // Chain backwards 1 instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
662 while( bindex2 == 0 ) { // At block start, find prior block
a61af66fc99e Initial load
duke
parents:
diff changeset
663 assert( b2->num_preds() == 2, "cannot double coalesce across c-flow" );
a61af66fc99e Initial load
duke
parents:
diff changeset
664 b2 = _phc._cfg._bbs[b2->pred(1)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
665 bindex2 = b2->end_idx()-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // Get prior instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
668 assert(bindex2 < b2->_nodes.size(), "index out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
669 Node *x = b2->_nodes[bindex2];
a61af66fc99e Initial load
duke
parents:
diff changeset
670 if( x == prev_copy ) { // Previous copy in copy chain?
a61af66fc99e Initial load
duke
parents:
diff changeset
671 if( prev_copy == src_copy)// Found end of chain and all interferences
a61af66fc99e Initial load
duke
parents:
diff changeset
672 break; // So break out of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // Else work back one in copy chain
a61af66fc99e Initial load
duke
parents:
diff changeset
674 prev_copy = prev_copy->in(prev_copy->is_Copy());
a61af66fc99e Initial load
duke
parents:
diff changeset
675 } else { // Else collect interferences
a61af66fc99e Initial load
duke
parents:
diff changeset
676 uint lidx = _phc.Find(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
677 // Found another def of live-range being stretched?
a61af66fc99e Initial load
duke
parents:
diff changeset
678 if( lidx == lr1 ) return max_juint;
a61af66fc99e Initial load
duke
parents:
diff changeset
679 if( lidx == lr2 ) return max_juint;
a61af66fc99e Initial load
duke
parents:
diff changeset
680
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // If we attempt to coalesce across a bound def
a61af66fc99e Initial load
duke
parents:
diff changeset
682 if( lrgs(lidx).is_bound() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
683 // Do not let the coalesced LRG expect to get the bound color
a61af66fc99e Initial load
duke
parents:
diff changeset
684 rm.SUBTRACT( lrgs(lidx).mask() );
a61af66fc99e Initial load
duke
parents:
diff changeset
685 // Recompute rm_size
a61af66fc99e Initial load
duke
parents:
diff changeset
686 rm_size = rm.Size();
a61af66fc99e Initial load
duke
parents:
diff changeset
687 //if( rm._flags ) rm_size += 1000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
688 if( reg_degree >= rm_size ) return max_juint;
a61af66fc99e Initial load
duke
parents:
diff changeset
689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
690 if( rm.overlap(lrgs(lidx).mask()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // Insert lidx into union LRG; returns TRUE if actually inserted
a61af66fc99e Initial load
duke
parents:
diff changeset
692 if( _ulr.insert(lidx) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // Infinite-stack neighbors do not alter colorability, as they
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // can always color to some other color.
a61af66fc99e Initial load
duke
parents:
diff changeset
695 if( !lrgs(lidx).mask().is_AllStack() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // If this coalesce will make any new neighbor uncolorable,
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // do not coalesce.
a61af66fc99e Initial load
duke
parents:
diff changeset
698 if( lrgs(lidx).just_lo_degree() )
a61af66fc99e Initial load
duke
parents:
diff changeset
699 return max_juint;
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // Bump our degree
a61af66fc99e Initial load
duke
parents:
diff changeset
701 if( ++reg_degree >= rm_size )
a61af66fc99e Initial load
duke
parents:
diff changeset
702 return max_juint;
a61af66fc99e Initial load
duke
parents:
diff changeset
703 } // End of if not infinite-stack neighbor
a61af66fc99e Initial load
duke
parents:
diff changeset
704 } // End of if actually inserted
a61af66fc99e Initial load
duke
parents:
diff changeset
705 } // End of if live range overlaps
605
98cb887364d3 6810672: Comment typos
twisti
parents: 337
diff changeset
706 } // End of else collect interferences for 1 node
98cb887364d3 6810672: Comment typos
twisti
parents: 337
diff changeset
707 } // End of while forever, scan back for interferences
0
a61af66fc99e Initial load
duke
parents:
diff changeset
708 return reg_degree;
a61af66fc99e Initial load
duke
parents:
diff changeset
709 }
a61af66fc99e Initial load
duke
parents:
diff changeset
710
a61af66fc99e Initial load
duke
parents:
diff changeset
711 //------------------------------update_ifg-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
712 void PhaseConservativeCoalesce::update_ifg(uint lr1, uint lr2, IndexSet *n_lr1, IndexSet *n_lr2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
713 // Some original neighbors of lr1 might have gone away
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // because the constrained register mask prevented them.
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // Remove lr1 from such neighbors.
a61af66fc99e Initial load
duke
parents:
diff changeset
716 IndexSetIterator one(n_lr1);
a61af66fc99e Initial load
duke
parents:
diff changeset
717 uint neighbor;
a61af66fc99e Initial load
duke
parents:
diff changeset
718 LRG &lrg1 = lrgs(lr1);
a61af66fc99e Initial load
duke
parents:
diff changeset
719 while ((neighbor = one.next()) != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
720 if( !_ulr.member(neighbor) )
a61af66fc99e Initial load
duke
parents:
diff changeset
721 if( _phc._ifg->neighbors(neighbor)->remove(lr1) )
a61af66fc99e Initial load
duke
parents:
diff changeset
722 lrgs(neighbor).inc_degree( -lrg1.compute_degree(lrgs(neighbor)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724
a61af66fc99e Initial load
duke
parents:
diff changeset
725 // lr2 is now called (coalesced into) lr1.
a61af66fc99e Initial load
duke
parents:
diff changeset
726 // Remove lr2 from the IFG.
a61af66fc99e Initial load
duke
parents:
diff changeset
727 IndexSetIterator two(n_lr2);
a61af66fc99e Initial load
duke
parents:
diff changeset
728 LRG &lrg2 = lrgs(lr2);
a61af66fc99e Initial load
duke
parents:
diff changeset
729 while ((neighbor = two.next()) != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
730 if( _phc._ifg->neighbors(neighbor)->remove(lr2) )
a61af66fc99e Initial load
duke
parents:
diff changeset
731 lrgs(neighbor).inc_degree( -lrg2.compute_degree(lrgs(neighbor)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
732
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // Some neighbors of intermediate copies now interfere with the
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // combined live range.
a61af66fc99e Initial load
duke
parents:
diff changeset
735 IndexSetIterator three(&_ulr);
a61af66fc99e Initial load
duke
parents:
diff changeset
736 while ((neighbor = three.next()) != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
737 if( _phc._ifg->neighbors(neighbor)->insert(lr1) )
a61af66fc99e Initial load
duke
parents:
diff changeset
738 lrgs(neighbor).inc_degree( lrg1.compute_degree(lrgs(neighbor)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 //------------------------------record_bias------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
742 static void record_bias( const PhaseIFG *ifg, int lr1, int lr2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // Tag copy bias here
a61af66fc99e Initial load
duke
parents:
diff changeset
744 if( !ifg->lrgs(lr1)._copy_bias )
a61af66fc99e Initial load
duke
parents:
diff changeset
745 ifg->lrgs(lr1)._copy_bias = lr2;
a61af66fc99e Initial load
duke
parents:
diff changeset
746 if( !ifg->lrgs(lr2)._copy_bias )
a61af66fc99e Initial load
duke
parents:
diff changeset
747 ifg->lrgs(lr2)._copy_bias = lr1;
a61af66fc99e Initial load
duke
parents:
diff changeset
748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 //------------------------------copy_copy--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // See if I can coalesce a series of multiple copies together. I need the
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // final dest copy and the original src copy. They can be the same Node.
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // Compute the compatible register masks.
a61af66fc99e Initial load
duke
parents:
diff changeset
754 bool PhaseConservativeCoalesce::copy_copy( Node *dst_copy, Node *src_copy, Block *b, uint bindex ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
755
a61af66fc99e Initial load
duke
parents:
diff changeset
756 if( !dst_copy->is_SpillCopy() ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
757 if( !src_copy->is_SpillCopy() ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 Node *src_def = src_copy->in(src_copy->is_Copy());
a61af66fc99e Initial load
duke
parents:
diff changeset
759 uint lr1 = _phc.Find(dst_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
760 uint lr2 = _phc.Find(src_def );
a61af66fc99e Initial load
duke
parents:
diff changeset
761
a61af66fc99e Initial load
duke
parents:
diff changeset
762 // Same live ranges already?
a61af66fc99e Initial load
duke
parents:
diff changeset
763 if( lr1 == lr2 ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
764
a61af66fc99e Initial load
duke
parents:
diff changeset
765 // Interfere?
a61af66fc99e Initial load
duke
parents:
diff changeset
766 if( _phc._ifg->test_edge_sq( lr1, lr2 ) ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
767
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // Not an oop->int cast; oop->oop, int->int, AND int->oop are OK.
a61af66fc99e Initial load
duke
parents:
diff changeset
769 if( !lrgs(lr1)._is_oop && lrgs(lr2)._is_oop ) // not an oop->int cast
a61af66fc99e Initial load
duke
parents:
diff changeset
770 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
771
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // Coalescing between an aligned live range and a mis-aligned live range?
a61af66fc99e Initial load
duke
parents:
diff changeset
773 // No, no! Alignment changes how we count degree.
a61af66fc99e Initial load
duke
parents:
diff changeset
774 if( lrgs(lr1)._fat_proj != lrgs(lr2)._fat_proj )
a61af66fc99e Initial load
duke
parents:
diff changeset
775 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // Sort; use smaller live-range number
a61af66fc99e Initial load
duke
parents:
diff changeset
778 Node *lr1_node = dst_copy;
a61af66fc99e Initial load
duke
parents:
diff changeset
779 Node *lr2_node = src_def;
a61af66fc99e Initial load
duke
parents:
diff changeset
780 if( lr1 > lr2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
781 uint tmp = lr1; lr1 = lr2; lr2 = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
782 lr1_node = src_def; lr2_node = dst_copy;
a61af66fc99e Initial load
duke
parents:
diff changeset
783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
784
a61af66fc99e Initial load
duke
parents:
diff changeset
785 // Check for compatibility of the 2 live ranges by
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // intersecting their allowed register sets.
a61af66fc99e Initial load
duke
parents:
diff changeset
787 RegMask rm = lrgs(lr1).mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
788 rm.AND(lrgs(lr2).mask());
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // Number of bits free
a61af66fc99e Initial load
duke
parents:
diff changeset
790 uint rm_size = rm.Size();
a61af66fc99e Initial load
duke
parents:
diff changeset
791
1730
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1552
diff changeset
792 if (UseFPUForSpilling && rm.is_AllStack() ) {
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1552
diff changeset
793 // Don't coalesce when frequency difference is large
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1552
diff changeset
794 Block *dst_b = _phc._cfg._bbs[dst_copy->_idx];
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1552
diff changeset
795 Block *src_def_b = _phc._cfg._bbs[src_def->_idx];
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1552
diff changeset
796 if (src_def_b->_freq > 10*dst_b->_freq )
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1552
diff changeset
797 return false;
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1552
diff changeset
798 }
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1552
diff changeset
799
0
a61af66fc99e Initial load
duke
parents:
diff changeset
800 // If we can use any stack slot, then effective size is infinite
a61af66fc99e Initial load
duke
parents:
diff changeset
801 if( rm.is_AllStack() ) rm_size += 1000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
802 // Incompatible masks, no way to coalesce
a61af66fc99e Initial load
duke
parents:
diff changeset
803 if( rm_size == 0 ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 // Another early bail-out test is when we are double-coalescing and the
605
98cb887364d3 6810672: Comment typos
twisti
parents: 337
diff changeset
806 // 2 copies are separated by some control flow.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
807 if( dst_copy != src_copy ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
808 Block *src_b = _phc._cfg._bbs[src_copy->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
809 Block *b2 = b;
a61af66fc99e Initial load
duke
parents:
diff changeset
810 while( b2 != src_b ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
811 if( b2->num_preds() > 2 ){// Found merge-point
a61af66fc99e Initial load
duke
parents:
diff changeset
812 _phc._lost_opp_cflow_coalesce++;
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // extra record_bias commented out because Chris believes it is not
a61af66fc99e Initial load
duke
parents:
diff changeset
814 // productive. Since we can record only 1 bias, we want to choose one
a61af66fc99e Initial load
duke
parents:
diff changeset
815 // that stands a chance of working and this one probably does not.
a61af66fc99e Initial load
duke
parents:
diff changeset
816 //record_bias( _phc._lrgs, lr1, lr2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
817 return false; // To hard to find all interferences
a61af66fc99e Initial load
duke
parents:
diff changeset
818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
819 b2 = _phc._cfg._bbs[b2->pred(1)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
821 }
a61af66fc99e Initial load
duke
parents:
diff changeset
822
a61af66fc99e Initial load
duke
parents:
diff changeset
823 // Union the two interference sets together into '_ulr'
a61af66fc99e Initial load
duke
parents:
diff changeset
824 uint reg_degree = _ulr.lrg_union( lr1, lr2, rm_size, _phc._ifg, rm );
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 if( reg_degree >= rm_size ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
827 record_bias( _phc._ifg, lr1, lr2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
828 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 // Now I need to compute all the interferences between dst_copy and
a61af66fc99e Initial load
duke
parents:
diff changeset
832 // src_copy. I'm not willing visit the entire interference graph, so
a61af66fc99e Initial load
duke
parents:
diff changeset
833 // I limit my search to things in dst_copy's block or in a straight
a61af66fc99e Initial load
duke
parents:
diff changeset
834 // line of previous blocks. I give up at merge points or when I get
a61af66fc99e Initial load
duke
parents:
diff changeset
835 // more interferences than my degree. I can stop when I find src_copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
836 if( dst_copy != src_copy ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
837 reg_degree = compute_separating_interferences(dst_copy, src_copy, b, bindex, rm, rm_size, reg_degree, lr1, lr2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
838 if( reg_degree == max_juint ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
839 record_bias( _phc._ifg, lr1, lr2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
840 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
842 } // End of if dst_copy & src_copy are different
a61af66fc99e Initial load
duke
parents:
diff changeset
843
a61af66fc99e Initial load
duke
parents:
diff changeset
844
a61af66fc99e Initial load
duke
parents:
diff changeset
845 // ---- THE COMBINED LRG IS COLORABLE ----
a61af66fc99e Initial load
duke
parents:
diff changeset
846
a61af66fc99e Initial load
duke
parents:
diff changeset
847 // YEAH - Now coalesce this copy away
a61af66fc99e Initial load
duke
parents:
diff changeset
848 assert( lrgs(lr1).num_regs() == lrgs(lr2).num_regs(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 IndexSet *n_lr1 = _phc._ifg->neighbors(lr1);
a61af66fc99e Initial load
duke
parents:
diff changeset
851 IndexSet *n_lr2 = _phc._ifg->neighbors(lr2);
a61af66fc99e Initial load
duke
parents:
diff changeset
852
a61af66fc99e Initial load
duke
parents:
diff changeset
853 // Update the interference graph
a61af66fc99e Initial load
duke
parents:
diff changeset
854 update_ifg(lr1, lr2, n_lr1, n_lr2);
a61af66fc99e Initial load
duke
parents:
diff changeset
855
a61af66fc99e Initial load
duke
parents:
diff changeset
856 _ulr.remove(lr1);
a61af66fc99e Initial load
duke
parents:
diff changeset
857
a61af66fc99e Initial load
duke
parents:
diff changeset
858 // Uncomment the following code to trace Coalescing in great detail.
a61af66fc99e Initial load
duke
parents:
diff changeset
859 //
a61af66fc99e Initial load
duke
parents:
diff changeset
860 //if (false) {
a61af66fc99e Initial load
duke
parents:
diff changeset
861 // tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // tty->print_cr("#######################################");
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // tty->print_cr("union %d and %d", lr1, lr2);
a61af66fc99e Initial load
duke
parents:
diff changeset
864 // n_lr1->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
865 // n_lr2->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
866 // tty->print_cr("resulting set is");
a61af66fc99e Initial load
duke
parents:
diff changeset
867 // _ulr.dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
868 //}
a61af66fc99e Initial load
duke
parents:
diff changeset
869
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // Replace n_lr1 with the new combined live range. _ulr will use
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // n_lr1's old memory on the next iteration. n_lr2 is cleared to
a61af66fc99e Initial load
duke
parents:
diff changeset
872 // send its internal memory to the free list.
a61af66fc99e Initial load
duke
parents:
diff changeset
873 _ulr.swap(n_lr1);
a61af66fc99e Initial load
duke
parents:
diff changeset
874 _ulr.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
875 n_lr2->clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 lrgs(lr1).set_degree( _phc._ifg->effective_degree(lr1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
878 lrgs(lr2).set_degree( 0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
879
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // Join live ranges. Merge larger into smaller. Union lr2 into lr1 in the
a61af66fc99e Initial load
duke
parents:
diff changeset
881 // union-find tree
a61af66fc99e Initial load
duke
parents:
diff changeset
882 union_helper( lr1_node, lr2_node, lr1, lr2, src_def, dst_copy, src_copy, b, bindex );
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // Combine register restrictions
a61af66fc99e Initial load
duke
parents:
diff changeset
884 lrgs(lr1).set_mask(rm);
a61af66fc99e Initial load
duke
parents:
diff changeset
885 lrgs(lr1).compute_set_mask_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
886 lrgs(lr1)._cost += lrgs(lr2)._cost;
a61af66fc99e Initial load
duke
parents:
diff changeset
887 lrgs(lr1)._area += lrgs(lr2)._area;
a61af66fc99e Initial load
duke
parents:
diff changeset
888
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // While its uncommon to successfully coalesce live ranges that started out
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // being not-lo-degree, it can happen. In any case the combined coalesced
a61af66fc99e Initial load
duke
parents:
diff changeset
891 // live range better Simplify nicely.
a61af66fc99e Initial load
duke
parents:
diff changeset
892 lrgs(lr1)._was_lo = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
893
a61af66fc99e Initial load
duke
parents:
diff changeset
894 // kinda expensive to do all the time
a61af66fc99e Initial load
duke
parents:
diff changeset
895 //tty->print_cr("warning: slow verify happening");
a61af66fc99e Initial load
duke
parents:
diff changeset
896 //_phc._ifg->verify( &_phc );
a61af66fc99e Initial load
duke
parents:
diff changeset
897 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
899
a61af66fc99e Initial load
duke
parents:
diff changeset
900 //------------------------------coalesce---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
901 // Conservative (but pessimistic) copy coalescing of a single block
a61af66fc99e Initial load
duke
parents:
diff changeset
902 void PhaseConservativeCoalesce::coalesce( Block *b ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // Bail out on infrequent blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
904 if( b->is_uncommon(_phc._cfg._bbs) )
a61af66fc99e Initial load
duke
parents:
diff changeset
905 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
906 // Check this block for copies.
a61af66fc99e Initial load
duke
parents:
diff changeset
907 for( uint i = 1; i<b->end_idx(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // Check for actual copies on inputs. Coalesce a copy into its
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // input if use and copy's input are compatible.
a61af66fc99e Initial load
duke
parents:
diff changeset
910 Node *copy1 = b->_nodes[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
911 uint idx1 = copy1->is_Copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
912 if( !idx1 ) continue; // Not a copy
a61af66fc99e Initial load
duke
parents:
diff changeset
913
a61af66fc99e Initial load
duke
parents:
diff changeset
914 if( copy_copy(copy1,copy1,b,i) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
915 i--; // Retry, same location in block
a61af66fc99e Initial load
duke
parents:
diff changeset
916 PhaseChaitin::_conserv_coalesce++; // Collect stats on success
a61af66fc99e Initial load
duke
parents:
diff changeset
917 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
918 }
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 /* do not attempt pairs. About 1/2 of all pairs can be removed by
a61af66fc99e Initial load
duke
parents:
diff changeset
921 post-alloc. The other set are too few to bother.
a61af66fc99e Initial load
duke
parents:
diff changeset
922 Node *copy2 = copy1->in(idx1);
a61af66fc99e Initial load
duke
parents:
diff changeset
923 uint idx2 = copy2->is_Copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
924 if( !idx2 ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
925 if( copy_copy(copy1,copy2,b,i) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
926 i--; // Retry, same location in block
a61af66fc99e Initial load
duke
parents:
diff changeset
927 PhaseChaitin::_conserv_coalesce_pair++; // Collect stats on success
a61af66fc99e Initial load
duke
parents:
diff changeset
928 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
929 }
a61af66fc99e Initial load
duke
parents:
diff changeset
930 */
a61af66fc99e Initial load
duke
parents:
diff changeset
931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }