annotate src/share/vm/opto/live.cpp @ 17716:cdb71841f4bc

6498581: ThreadInterruptTest3 produces wrong output on Windows Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set. Reviewed-by: acorn, kvn Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author minqi
date Wed, 26 Feb 2014 15:20:41 -0800
parents 55fb97c4c58d
children 4ca6dc0799b6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
17467
55fb97c4c58d 8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents: 12269
diff changeset
2 * Copyright (c) 1997, 2013, 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 // Compute live-in/live-out. We use a totally incremental algorithm. The LIVE
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // problem is monotonic. The steady-state solution looks like this: pull a
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // block from the worklist. It has a set of delta's - values which are newly
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // live-in from the block. Push these to the live-out sets of all predecessor
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // blocks. At each predecessor, the new live-out values are ANDed with what is
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // already live-out (extra stuff is added to the live-out sets). Then the
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // remaining new live-out values are ANDed with what is locally defined.
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // Leftover bits become the new live-in for the predecessor block, and the pred
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // block is put on the worklist.
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // The locally live-in stuff is computed once and added to predecessor
605
98cb887364d3 6810672: Comment typos
twisti
parents: 566
diff changeset
43 // live-out sets. This separate compilation is done in the outer loop below.
10111
8373c19be854 8011621: live_ranges_in_separate_class.patch
neliasso
parents: 6848
diff changeset
44 PhaseLive::PhaseLive( const PhaseCFG &cfg, const LRG_List &names, Arena *arena ) : Phase(LIVE), _cfg(cfg), _names(names), _arena(arena), _live(0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
45 }
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 void PhaseLive::compute(uint maxlrg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _maxlrg = maxlrg;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 _worklist = new (_arena) Block_List();
a61af66fc99e Initial load
duke
parents:
diff changeset
50
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // Init the sparse live arrays. This data is live on exit from here!
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // The _live info is the live-out info.
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
53 _live = (IndexSet*)_arena->Amalloc(sizeof(IndexSet) * _cfg.number_of_blocks());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
54 uint i;
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
55 for (i = 0; i < _cfg.number_of_blocks(); i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
56 _live[i].initialize(_maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
57 }
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // Init the sparse arrays for delta-sets.
a61af66fc99e Initial load
duke
parents:
diff changeset
60 ResourceMark rm; // Nuke temp storage on exit
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // Does the memory used by _defs and _deltas get reclaimed? Does it matter? TT
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // Array of values defined locally in blocks
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
65 _defs = NEW_RESOURCE_ARRAY(IndexSet,_cfg.number_of_blocks());
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
66 for (i = 0; i < _cfg.number_of_blocks(); i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
67 _defs[i].initialize(_maxlrg);
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // Array of delta-set pointers, indexed by block pre_order-1.
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
71 _deltas = NEW_RESOURCE_ARRAY(IndexSet*,_cfg.number_of_blocks());
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
72 memset( _deltas, 0, sizeof(IndexSet*)* _cfg.number_of_blocks());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 _free_IndexSet = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // Blocks having done pass-1
a61af66fc99e Initial load
duke
parents:
diff changeset
77 VectorSet first_pass(Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // Outer loop: must compute local live-in sets and push into predecessors.
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
80 for (uint j = _cfg.number_of_blocks(); j > 0; j--) {
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
81 Block* block = _cfg.get_block(j - 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // Compute the local live-in set. Start with any new live-out bits.
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
84 IndexSet* use = getset(block);
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
85 IndexSet* def = &_defs[block->_pre_order-1];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
86 DEBUG_ONLY(IndexSet *def_outside = getfreeset();)
a61af66fc99e Initial load
duke
parents:
diff changeset
87 uint i;
12167
650868c062a9 8023691: Create interface for nodes in class Block
adlertz
parents: 12071
diff changeset
88 for (i = block->number_of_nodes(); i > 1; i--) {
650868c062a9 8023691: Create interface for nodes in class Block
adlertz
parents: 12071
diff changeset
89 Node* n = block->get_node(i-1);
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
90 if (n->is_Phi()) {
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
91 break;
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
92 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
93
12254
8c83625e3a53 8024646: Remove LRG_List container, replace it with GrowableArray
adlertz
parents: 12167
diff changeset
94 uint r = _names.at(n->_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
95 assert(!def_outside->member(r), "Use of external LRG overlaps the same LRG defined in this block");
a61af66fc99e Initial load
duke
parents:
diff changeset
96 def->insert( r );
a61af66fc99e Initial load
duke
parents:
diff changeset
97 use->remove( r );
a61af66fc99e Initial load
duke
parents:
diff changeset
98 uint cnt = n->req();
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
99 for (uint k = 1; k < cnt; k++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
100 Node *nk = n->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 uint nkidx = nk->_idx;
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
102 if (_cfg.get_block_for_node(nk) != block) {
12254
8c83625e3a53 8024646: Remove LRG_List container, replace it with GrowableArray
adlertz
parents: 12167
diff changeset
103 uint u = _names.at(nkidx);
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
104 use->insert(u);
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
105 DEBUG_ONLY(def_outside->insert(u);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
109 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
110 def_outside->set_next(_free_IndexSet);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 _free_IndexSet = def_outside; // Drop onto free list
a61af66fc99e Initial load
duke
parents:
diff changeset
112 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // Remove anything defined by Phis and the block start instruction
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
114 for (uint k = i; k > 0; k--) {
12254
8c83625e3a53 8024646: Remove LRG_List container, replace it with GrowableArray
adlertz
parents: 12167
diff changeset
115 uint r = _names.at(block->get_node(k - 1)->_idx);
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
116 def->insert(r);
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
117 use->remove(r);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
119
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // Push these live-in things to predecessors
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
121 for (uint l = 1; l < block->num_preds(); l++) {
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
122 Block* p = _cfg.get_block_for_node(block->pred(l));
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
123 add_liveout(p, use, first_pass);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // PhiNode uses go in the live-out set of prior blocks.
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
126 for (uint k = i; k > 0; k--) {
12254
8c83625e3a53 8024646: Remove LRG_List container, replace it with GrowableArray
adlertz
parents: 12167
diff changeset
127 add_liveout(p, _names.at(block->get_node(k-1)->in(l)->_idx), first_pass);
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
128 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
129 }
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
130 freeset(block);
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
131 first_pass.set(block->_pre_order);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // Inner loop: blocks that picked up new live-out values to be propagated
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
134 while (_worklist->size()) {
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
135 Block* block = _worklist->pop();
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
136 IndexSet *delta = getset(block);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
137 assert( delta->count(), "missing delta set" );
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // Add new-live-in to predecessors live-out sets
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
140 for (uint l = 1; l < block->num_preds(); l++) {
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
141 Block* predecessor = _cfg.get_block_for_node(block->pred(l));
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
142 add_liveout(predecessor, delta, first_pass);
12023
d1034bd8cefc 8022284: Hide internal data structure in PhaseCFG
adlertz
parents: 10111
diff changeset
143 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
144
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
145 freeset(block);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
146 } // End of while-worklist-not-empty
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 } // End of for-all-blocks-outer-loop
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // We explicitly clear all of the IndexSets which we are about to release.
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // This allows us to recycle their internal memory into IndexSet's free list.
a61af66fc99e Initial load
duke
parents:
diff changeset
152
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
153 for (i = 0; i < _cfg.number_of_blocks(); i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
154 _defs[i].clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
155 if (_deltas[i]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // Is this always true?
a61af66fc99e Initial load
duke
parents:
diff changeset
157 _deltas[i]->clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160 IndexSet *free = _free_IndexSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 while (free != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
162 IndexSet *temp = free;
a61af66fc99e Initial load
duke
parents:
diff changeset
163 free = free->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
164 temp->clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166
a61af66fc99e Initial load
duke
parents:
diff changeset
167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
170 void PhaseLive::stats(uint iters) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
172 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // Get an IndexSet for a block. Return existing one, if any. Make a new
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // empty one if a prior one does not exist.
a61af66fc99e Initial load
duke
parents:
diff changeset
176 IndexSet *PhaseLive::getset( Block *p ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 IndexSet *delta = _deltas[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
178 if( !delta ) // Not on worklist?
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Get a free set; flag as being on worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
180 delta = _deltas[p->_pre_order-1] = getfreeset();
a61af66fc99e Initial load
duke
parents:
diff changeset
181 return delta; // Return set of new live-out items
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // Pull from free list, or allocate. Internal allocation on the returned set
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // is always from thread local storage.
a61af66fc99e Initial load
duke
parents:
diff changeset
186 IndexSet *PhaseLive::getfreeset( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 IndexSet *f = _free_IndexSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
188 if( !f ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 f = new IndexSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // f->set_arena(Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
191 f->initialize(_maxlrg, Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
192 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // Pull from free list
a61af66fc99e Initial load
duke
parents:
diff changeset
194 _free_IndexSet = f->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
195 //f->_cnt = 0; // Reset to empty
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 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199 return f;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // Free an IndexSet from a block.
a61af66fc99e Initial load
duke
parents:
diff changeset
203 void PhaseLive::freeset( const Block *p ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 IndexSet *f = _deltas[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
205 f->set_next(_free_IndexSet);
a61af66fc99e Initial load
duke
parents:
diff changeset
206 _free_IndexSet = f; // Drop onto free list
a61af66fc99e Initial load
duke
parents:
diff changeset
207 _deltas[p->_pre_order-1] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // Add a live-out value to a given blocks live-out set. If it is new, then
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // also add it to the delta set and stick the block on the worklist.
a61af66fc99e Initial load
duke
parents:
diff changeset
212 void PhaseLive::add_liveout( Block *p, uint r, VectorSet &first_pass ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 IndexSet *live = &_live[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
214 if( live->insert(r) ) { // If actually inserted...
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // We extended the live-out set. See if the value is generated locally.
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // If it is not, then we must extend the live-in set.
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if( !_defs[p->_pre_order-1].member( r ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 if( !_deltas[p->_pre_order-1] && // Not on worklist?
a61af66fc99e Initial load
duke
parents:
diff changeset
219 first_pass.test(p->_pre_order) )
a61af66fc99e Initial load
duke
parents:
diff changeset
220 _worklist->push(p); // Actually go on worklist if already 1st pass
a61af66fc99e Initial load
duke
parents:
diff changeset
221 getset(p)->insert(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // Add a vector of live-out values to a given blocks live-out set.
a61af66fc99e Initial load
duke
parents:
diff changeset
227 void PhaseLive::add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
228 IndexSet *live = &_live[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
229 IndexSet *defs = &_defs[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
230 IndexSet *on_worklist = _deltas[p->_pre_order-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
231 IndexSet *delta = on_worklist ? on_worklist : getfreeset();
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 IndexSetIterator elements(lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
234 uint r;
a61af66fc99e Initial load
duke
parents:
diff changeset
235 while ((r = elements.next()) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 if( live->insert(r) && // If actually inserted...
a61af66fc99e Initial load
duke
parents:
diff changeset
237 !defs->member( r ) ) // and not defined locally
a61af66fc99e Initial load
duke
parents:
diff changeset
238 delta->insert(r); // Then add to live-in set
a61af66fc99e Initial load
duke
parents:
diff changeset
239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
240
a61af66fc99e Initial load
duke
parents:
diff changeset
241 if( delta->count() ) { // If actually added things
a61af66fc99e Initial load
duke
parents:
diff changeset
242 _deltas[p->_pre_order-1] = delta; // Flag as on worklist now
a61af66fc99e Initial load
duke
parents:
diff changeset
243 if( !on_worklist && // Not on worklist?
a61af66fc99e Initial load
duke
parents:
diff changeset
244 first_pass.test(p->_pre_order) )
a61af66fc99e Initial load
duke
parents:
diff changeset
245 _worklist->push(p); // Actually go on worklist if already 1st pass
a61af66fc99e Initial load
duke
parents:
diff changeset
246 } else { // Nothing there; just free it
a61af66fc99e Initial load
duke
parents:
diff changeset
247 delta->set_next(_free_IndexSet);
a61af66fc99e Initial load
duke
parents:
diff changeset
248 _free_IndexSet = delta; // Drop onto free list
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // Dump the live-out set for a block
a61af66fc99e Initial load
duke
parents:
diff changeset
254 void PhaseLive::dump( const Block *b ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 tty->print("Block %d: ",b->_pre_order);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 tty->print("LiveOut: "); _live[b->_pre_order-1].dump();
12167
650868c062a9 8023691: Create interface for nodes in class Block
adlertz
parents: 12071
diff changeset
257 uint cnt = b->number_of_nodes();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
258 for( uint i=0; i<cnt; i++ ) {
12254
8c83625e3a53 8024646: Remove LRG_List container, replace it with GrowableArray
adlertz
parents: 12167
diff changeset
259 tty->print("L%d/", _names.at(b->get_node(i)->_idx));
12167
650868c062a9 8023691: Create interface for nodes in class Block
adlertz
parents: 12071
diff changeset
260 b->get_node(i)->dump();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
262 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // Verify that base pointers and derived pointers are still sane.
a61af66fc99e Initial load
duke
parents:
diff changeset
266 void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
267 #ifdef ASSERT
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
268 Unique_Node_List worklist(a);
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
269 for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
270 Block* block = _cfg.get_block(i);
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
271 for (uint j = block->end_idx() + 1; j > 1; j--) {
12167
650868c062a9 8023691: Create interface for nodes in class Block
adlertz
parents: 12071
diff changeset
272 Node* n = block->get_node(j-1);
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
273 if (n->is_Phi()) {
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
274 break;
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
275 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // Found a safepoint?
12071
adb9a7d94cb5 8023003: Cleanup the public interface to PhaseCFG
adlertz
parents: 12023
diff changeset
277 if (n->is_MachSafePoint()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
278 MachSafePointNode *sfpt = n->as_MachSafePoint();
a61af66fc99e Initial load
duke
parents:
diff changeset
279 JVMState* jvms = sfpt->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
280 if (jvms != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // Now scan for a live derived pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
282 if (jvms->oopoff() < sfpt->req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // Check each derived/base pair
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
284 for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
285 Node *check = sfpt->in(idx);
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
286 bool is_derived = ((idx - jvms->oopoff()) & 1) == 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // 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
288 worklist.clear();
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
289 worklist.push(check);
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
290 uint k = 0;
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
291 while( k < worklist.size() ) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
292 check = worklist.at(k);
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
293 assert(check,"Bad base or derived pointer");
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
294 // See PhaseChaitin::find_base_for_derived() for all cases.
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
295 int isc = check->is_Copy();
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
296 if( isc ) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
297 worklist.push(check->in(isc));
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
298 } else if( check->is_Phi() ) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
299 for (uint m = 1; m < check->req(); m++)
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
300 worklist.push(check->in(m));
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
301 } else if( check->is_Con() ) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
302 if (is_derived) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
303 // Derived is NULL+offset
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
304 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
305 } else {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
306 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
307 // Base either ConP(NULL) or loadConP
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
308 if (check->is_Mach()) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
309 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
310 } else {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
311 assert(check->Opcode() == Op_ConP &&
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
312 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
313 }
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
314 }
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
315 } else if( check->bottom_type()->is_ptr()->_offset == 0 ) {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
316 if(check->is_Proj() || check->is_Mach() &&
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
317 (check->as_Mach()->ideal_Opcode() == Op_CreateEx ||
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
318 check->as_Mach()->ideal_Opcode() == Op_ThreadLocal ||
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
319 check->as_Mach()->ideal_Opcode() == Op_CMoveP ||
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
320 check->as_Mach()->ideal_Opcode() == Op_CheckCastPP ||
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
321 #ifdef _LP64
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
322 UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_CastPP ||
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
323 UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN ||
12226
7944aba7ba41 8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents: 12167
diff changeset
324 UseCompressedClassPointers && check->as_Mach()->ideal_Opcode() == Op_DecodeNKlass ||
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
325 #endif
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
326 check->as_Mach()->ideal_Opcode() == Op_LoadP ||
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
327 check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) {
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
328 // Valid nodes
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
329 } else {
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
330 check->dump();
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
331 assert(false,"Bad base or derived pointer");
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
332 }
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
333 } else {
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
334 assert(is_derived,"Bad base pointer");
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
335 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
336 }
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
337 k++;
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
338 assert(k < 100000,"Derived pointer checking in infinite loop");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
339 } // End while
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341 } // End of check for derived pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
342 } // End of Kcheck for debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
343 } // End of if found a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
344 } // End of forall instructions in block
a61af66fc99e Initial load
duke
parents:
diff changeset
345 } // End of forall blocks
550
96964ebdb154 6782232: assert("CreateEx must be first instruction in block" )
kvn
parents: 0
diff changeset
346 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
348
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
349 // 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
350 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
351 #ifdef ASSERT
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
352 if( VerifyOpto || VerifyRegisterAllocator ) {
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
353 _cfg.verify();
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
354 verify_base_ptrs(a);
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
355 if(verify_ifg)
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
356 _ifg->verify(this);
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
357 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
358 #endif
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
359 }
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
360
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 550
diff changeset
361 #endif