annotate src/share/vm/opto/live.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 8e47bac5643a
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: 1552
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: 628
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 628
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: 628
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 "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27 #include "opto/callnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "opto/chaitin.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "opto/live.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "opto/machnode.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
31
a61af66fc99e Initial load
duke
parents:
diff changeset
32
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
35 //------------------------------PhaseLive--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // Compute live-in/live-out. We use a totally incremental algorithm. The LIVE
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // problem is monotonic. The steady-state solution looks like this: pull a
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // block from the worklist. It has a set of delta's - values which are newly
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // live-in from the block. Push these to the live-out sets of all predecessor
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // blocks. At each predecessor, the new live-out values are ANDed with what is
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // already live-out (extra stuff is added to the live-out sets). Then the
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // remaining new live-out values are ANDed with what is locally defined.
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // Leftover bits become the new live-in for the predecessor block, and the pred
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // block is put on the worklist.
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // The locally live-in stuff is computed once and added to predecessor
605
98cb887364d3 6810672: Comment typos
twisti
parents: 566
diff changeset
46 // live-out sets. This separate compilation is done in the outer loop below.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
47 PhaseLive::PhaseLive( const PhaseCFG &cfg, LRG_List &names, Arena *arena ) : Phase(LIVE), _cfg(cfg), _names(names), _arena(arena), _live(0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 }
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 void PhaseLive::compute(uint maxlrg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
51 _maxlrg = maxlrg;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 _worklist = new (_arena) Block_List();
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // Init the sparse live arrays. This data is live on exit from here!
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // The _live info is the live-out info.
a61af66fc99e Initial load
duke
parents:
diff changeset
56 _live = (IndexSet*)_arena->Amalloc(sizeof(IndexSet)*_cfg._num_blocks);
a61af66fc99e Initial load
duke
parents:
diff changeset
57 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 for( i=0; i<_cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
59 _live[i].initialize(_maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
60 }
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // Init the sparse arrays for delta-sets.
a61af66fc99e Initial load
duke
parents:
diff changeset
63 ResourceMark rm; // Nuke temp storage on exit
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // Does the memory used by _defs and _deltas get reclaimed? Does it matter? TT
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // Array of values defined locally in blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
68 _defs = NEW_RESOURCE_ARRAY(IndexSet,_cfg._num_blocks);
a61af66fc99e Initial load
duke
parents:
diff changeset
69 for( i=0; i<_cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
70 _defs[i].initialize(_maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // Array of delta-set pointers, indexed by block pre_order-1.
a61af66fc99e Initial load
duke
parents:
diff changeset
74 _deltas = NEW_RESOURCE_ARRAY(IndexSet*,_cfg._num_blocks);
a61af66fc99e Initial load
duke
parents:
diff changeset
75 memset( _deltas, 0, sizeof(IndexSet*)* _cfg._num_blocks);
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 _free_IndexSet = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // Blocks having done pass-1
a61af66fc99e Initial load
duke
parents:
diff changeset
80 VectorSet first_pass(Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // Outer loop: must compute local live-in sets and push into predecessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
83 uint iters = _cfg._num_blocks; // stat counters
a61af66fc99e Initial load
duke
parents:
diff changeset
84 for( uint j=_cfg._num_blocks; j>0; j-- ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 Block *b = _cfg._blocks[j-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // Compute the local live-in set. Start with any new live-out bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
88 IndexSet *use = getset( b );
a61af66fc99e Initial load
duke
parents:
diff changeset
89 IndexSet *def = &_defs[b->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
90 DEBUG_ONLY(IndexSet *def_outside = getfreeset();)
a61af66fc99e Initial load
duke
parents:
diff changeset
91 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 for( i=b->_nodes.size(); i>1; i-- ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
93 Node *n = b->_nodes[i-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
94 if( n->is_Phi() ) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 uint r = _names[n->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
97 assert(!def_outside->member(r), "Use of external LRG overlaps the same LRG defined in this block");
a61af66fc99e Initial load
duke
parents:
diff changeset
98 def->insert( r );
a61af66fc99e Initial load
duke
parents:
diff changeset
99 use->remove( r );
a61af66fc99e Initial load
duke
parents:
diff changeset
100 uint cnt = n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
101 for( uint k=1; k<cnt; k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 Node *nk = n->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 uint nkidx = nk->_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 if( _cfg._bbs[nkidx] != b ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 uint u = _names[nkidx];
a61af66fc99e Initial load
duke
parents:
diff changeset
106 use->insert( u );
a61af66fc99e Initial load
duke
parents:
diff changeset
107 DEBUG_ONLY(def_outside->insert( u );)
a61af66fc99e Initial load
duke
parents:
diff changeset
108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
112 def_outside->set_next(_free_IndexSet);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 _free_IndexSet = def_outside; // Drop onto free list
a61af66fc99e Initial load
duke
parents:
diff changeset
114 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // Remove anything defined by Phis and the block start instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
116 for( uint k=i; k>0; k-- ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
117 uint r = _names[b->_nodes[k-1]->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
118 def->insert( r );
a61af66fc99e Initial load
duke
parents:
diff changeset
119 use->remove( r );
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // Push these live-in things to predecessors
a61af66fc99e Initial load
duke
parents:
diff changeset
123 for( uint l=1; l<b->num_preds(); l++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 Block *p = _cfg._bbs[b->pred(l)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
125 add_liveout( p, use, first_pass );
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // PhiNode uses go in the live-out set of prior blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
128 for( uint k=i; k>0; k-- )
a61af66fc99e Initial load
duke
parents:
diff changeset
129 add_liveout( p, _names[b->_nodes[k-1]->in(l)->_idx], first_pass );
a61af66fc99e Initial load
duke
parents:
diff changeset
130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
131 freeset( b );
a61af66fc99e Initial load
duke
parents:
diff changeset
132 first_pass.set(b->_pre_order);
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // Inner loop: blocks that picked up new live-out values to be propagated
a61af66fc99e Initial load
duke
parents:
diff changeset
135 while( _worklist->size() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // !!!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
138 iters++;
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
140 Block *b = _worklist->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
141 IndexSet *delta = getset(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
142 assert( delta->count(), "missing delta set" );
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // Add new-live-in to predecessors live-out sets
a61af66fc99e Initial load
duke
parents:
diff changeset
145 for( uint l=1; l<b->num_preds(); l++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
146 add_liveout( _cfg._bbs[b->pred(l)->_idx], delta, first_pass );
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 freeset(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
149 } // End of while-worklist-not-empty
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 } // End of for-all-blocks-outer-loop
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // We explicitly clear all of the IndexSets which we are about to release.
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // This allows us to recycle their internal memory into IndexSet's free list.
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 for( i=0; i<_cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 _defs[i].clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
158 if (_deltas[i]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // Is this always true?
a61af66fc99e Initial load
duke
parents:
diff changeset
160 _deltas[i]->clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
163 IndexSet *free = _free_IndexSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
164 while (free != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 IndexSet *temp = free;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 free = free->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
167 temp->clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 //------------------------------stats------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
173 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
174 void PhaseLive::stats(uint iters) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
176 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 //------------------------------getset-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Get an IndexSet for a block. Return existing one, if any. Make a new
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // empty one if a prior one does not exist.
a61af66fc99e Initial load
duke
parents:
diff changeset
181 IndexSet *PhaseLive::getset( Block *p ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 IndexSet *delta = _deltas[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
183 if( !delta ) // Not on worklist?
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // Get a free set; flag as being on worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
185 delta = _deltas[p->_pre_order-1] = getfreeset();
a61af66fc99e Initial load
duke
parents:
diff changeset
186 return delta; // Return set of new live-out items
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 //------------------------------getfreeset-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // Pull from free list, or allocate. Internal allocation on the returned set
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // is always from thread local storage.
a61af66fc99e Initial load
duke
parents:
diff changeset
192 IndexSet *PhaseLive::getfreeset( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 IndexSet *f = _free_IndexSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
194 if( !f ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 f = new IndexSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // f->set_arena(Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
197 f->initialize(_maxlrg, Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
198 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // Pull from free list
a61af66fc99e Initial load
duke
parents:
diff changeset
200 _free_IndexSet = f->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
201 //f->_cnt = 0; // Reset to empty
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // f->set_arena(Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
203 f->initialize(_maxlrg, Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205 return f;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 //------------------------------freeset----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // Free an IndexSet from a block.
a61af66fc99e Initial load
duke
parents:
diff changeset
210 void PhaseLive::freeset( const Block *p ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
211 IndexSet *f = _deltas[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
212 f->set_next(_free_IndexSet);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 _free_IndexSet = f; // Drop onto free list
a61af66fc99e Initial load
duke
parents:
diff changeset
214 _deltas[p->_pre_order-1] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 //------------------------------add_liveout------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // Add a live-out value to a given blocks live-out set. If it is new, then
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // also add it to the delta set and stick the block on the worklist.
a61af66fc99e Initial load
duke
parents:
diff changeset
220 void PhaseLive::add_liveout( Block *p, uint r, VectorSet &first_pass ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
221 IndexSet *live = &_live[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
222 if( live->insert(r) ) { // If actually inserted...
a61af66fc99e Initial load
duke
parents:
diff changeset
223 // We extended the live-out set. See if the value is generated locally.
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // If it is not, then we must extend the live-in set.
a61af66fc99e Initial load
duke
parents:
diff changeset
225 if( !_defs[p->_pre_order-1].member( r ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
226 if( !_deltas[p->_pre_order-1] && // Not on worklist?
a61af66fc99e Initial load
duke
parents:
diff changeset
227 first_pass.test(p->_pre_order) )
a61af66fc99e Initial load
duke
parents:
diff changeset
228 _worklist->push(p); // Actually go on worklist if already 1st pass
a61af66fc99e Initial load
duke
parents:
diff changeset
229 getset(p)->insert(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 //------------------------------add_liveout------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // Add a vector of live-out values to a given blocks live-out set.
a61af66fc99e Initial load
duke
parents:
diff changeset
237 void PhaseLive::add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
238 IndexSet *live = &_live[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
239 IndexSet *defs = &_defs[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
240 IndexSet *on_worklist = _deltas[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
241 IndexSet *delta = on_worklist ? on_worklist : getfreeset();
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 IndexSetIterator elements(lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 uint r;
a61af66fc99e Initial load
duke
parents:
diff changeset
245 while ((r = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
246 if( live->insert(r) && // If actually inserted...
a61af66fc99e Initial load
duke
parents:
diff changeset
247 !defs->member( r ) ) // and not defined locally
a61af66fc99e Initial load
duke
parents:
diff changeset
248 delta->insert(r); // Then add to live-in set
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 if( delta->count() ) { // If actually added things
a61af66fc99e Initial load
duke
parents:
diff changeset
252 _deltas[p->_pre_order-1] = delta; // Flag as on worklist now
a61af66fc99e Initial load
duke
parents:
diff changeset
253 if( !on_worklist && // Not on worklist?
a61af66fc99e Initial load
duke
parents:
diff changeset
254 first_pass.test(p->_pre_order) )
a61af66fc99e Initial load
duke
parents:
diff changeset
255 _worklist->push(p); // Actually go on worklist if already 1st pass
a61af66fc99e Initial load
duke
parents:
diff changeset
256 } else { // Nothing there; just free it
a61af66fc99e Initial load
duke
parents:
diff changeset
257 delta->set_next(_free_IndexSet);
a61af66fc99e Initial load
duke
parents:
diff changeset
258 _free_IndexSet = delta; // Drop onto free list
a61af66fc99e Initial load
duke
parents:
diff changeset
259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
263 //------------------------------dump-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // Dump the live-out set for a block
a61af66fc99e Initial load
duke
parents:
diff changeset
265 void PhaseLive::dump( const Block *b ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 tty->print("Block %d: ",b->_pre_order);
a61af66fc99e Initial load
duke
parents:
diff changeset
267 tty->print("LiveOut: "); _live[b->_pre_order-1].dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
268 uint cnt = b->_nodes.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
269 for( uint i=0; i<cnt; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
270 tty->print("L%d/", _names[b->_nodes[i]->_idx] );
a61af66fc99e Initial load
duke
parents:
diff changeset
271 b->_nodes[i]->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
273 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 //------------------------------verify_base_ptrs-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // Verify that base pointers and derived pointers are still sane.
a61af66fc99e Initial load
duke
parents:
diff changeset
278 void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
279 #ifdef ASSERT
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
280 Unique_Node_List worklist(a);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
281 for( uint i = 0; i < _cfg._num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
282 Block *b = _cfg._blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
283 for( uint j = b->end_idx() + 1; j > 1; j-- ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 Node *n = b->_nodes[j-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
285 if( n->is_Phi() ) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // Found a safepoint?
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if( n->is_MachSafePoint() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 MachSafePointNode *sfpt = n->as_MachSafePoint();
a61af66fc99e Initial load
duke
parents:
diff changeset
289 JVMState* jvms = sfpt->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
290 if (jvms != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // Now scan for a live derived pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
292 if (jvms->oopoff() < sfpt->req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // Check each derived/base pair
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
294 for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
295 Node *check = sfpt->in(idx);
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
296 bool is_derived = ((idx - jvms->oopoff()) & 1) == 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // search upwards through spills and spill phis for AddP
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
298 worklist.clear();
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
299 worklist.push(check);
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
300 uint k = 0;
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
301 while( k < worklist.size() ) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
302 check = worklist.at(k);
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
303 assert(check,"Bad base or derived pointer");
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
304 // See PhaseChaitin::find_base_for_derived() for all cases.
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
305 int isc = check->is_Copy();
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
306 if( isc ) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
307 worklist.push(check->in(isc));
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
308 } else if( check->is_Phi() ) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
309 for (uint m = 1; m < check->req(); m++)
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
310 worklist.push(check->in(m));
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
311 } else if( check->is_Con() ) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
312 if (is_derived) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
313 // Derived is NULL+offset
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
314 assert(!is_derived || check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad derived pointer");
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
315 } else {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
316 assert(check->bottom_type()->is_ptr()->_offset == 0,"Bad base pointer");
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
317 // Base either ConP(NULL) or loadConP
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
318 if (check->is_Mach()) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
319 assert(check->as_Mach()->ideal_Opcode() == Op_ConP,"Bad base pointer");
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
320 } else {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
321 assert(check->Opcode() == Op_ConP &&
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
322 check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad base pointer");
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
323 }
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
324 }
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
325 } else if( check->bottom_type()->is_ptr()->_offset == 0 ) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
326 if(check->is_Proj() || check->is_Mach() &&
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
327 (check->as_Mach()->ideal_Opcode() == Op_CreateEx ||
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
328 check->as_Mach()->ideal_Opcode() == Op_ThreadLocal ||
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
329 check->as_Mach()->ideal_Opcode() == Op_CMoveP ||
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
330 check->as_Mach()->ideal_Opcode() == Op_CheckCastPP ||
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
331 #ifdef _LP64
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
332 UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_CastPP ||
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
333 UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN ||
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
334 #endif
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
335 check->as_Mach()->ideal_Opcode() == Op_LoadP ||
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
336 check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) {
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
337 // Valid nodes
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
338 } else {
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
339 check->dump();
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
340 assert(false,"Bad base or derived pointer");
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
341 }
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
342 } else {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
343 assert(is_derived,"Bad base pointer");
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
344 assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer");
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
345 }
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
346 k++;
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
347 assert(k < 100000,"Derived pointer checking in infinite loop");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
348 } // End while
a61af66fc99e Initial load
duke
parents:
diff changeset
349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
350 } // End of check for derived pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
351 } // End of Kcheck for debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
352 } // End of if found a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
353 } // End of forall instructions in block
a61af66fc99e Initial load
duke
parents:
diff changeset
354 } // End of forall blocks
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
355 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
357
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
358 //------------------------------verify-------------------------------------
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
359 // Verify that graphs and base pointers are still sane.
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
360 void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const {
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
361 #ifdef ASSERT
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
362 if( VerifyOpto || VerifyRegisterAllocator ) {
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
363 _cfg.verify();
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
364 verify_base_ptrs(a);
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
365 if(verify_ifg)
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
366 _ifg->verify(this);
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
367 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
368 #endif
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
369 }
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
370
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
371 #endif