annotate src/share/vm/opto/block.cpp @ 1721:413ad0331a0c

6977924: Changes for 6975078 produce build error with certain gcc versions Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error. Reviewed-by: jcoomes, ysr, phh
author johnc
date Wed, 18 Aug 2010 10:59:06 -0700
parents 0e35fa8ebccd
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 893
diff changeset
2 * Copyright (c) 1997, 2009, 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: 893
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 893
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: 893
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
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // Optimization - Graph Style
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
28 #include "incls/_block.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
29
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 //-----------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
32 void Block_Array::grow( uint i ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
33 assert(i >= Max(), "must be an overflow");
a61af66fc99e Initial load
duke
parents:
diff changeset
34 debug_only(_limit = i+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
35 if( i < _size ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
36 if( !_size ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 _size = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 _blocks = (Block**)_arena->Amalloc( _size * sizeof(Block*) );
a61af66fc99e Initial load
duke
parents:
diff changeset
39 _blocks[0] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 }
a61af66fc99e Initial load
duke
parents:
diff changeset
41 uint old = _size;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 while( i >= _size ) _size <<= 1; // Double to fit
a61af66fc99e Initial load
duke
parents:
diff changeset
43 _blocks = (Block**)_arena->Arealloc( _blocks, old*sizeof(Block*),_size*sizeof(Block*));
a61af66fc99e Initial load
duke
parents:
diff changeset
44 Copy::zero_to_bytes( &_blocks[old], (_size-old)*sizeof(Block*) );
a61af66fc99e Initial load
duke
parents:
diff changeset
45 }
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
48 void Block_List::remove(uint i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
49 assert(i < _cnt, "index out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
50 Copy::conjoint_words_to_lower((HeapWord*)&_blocks[i+1], (HeapWord*)&_blocks[i], ((_cnt-i-1)*sizeof(Block*)));
a61af66fc99e Initial load
duke
parents:
diff changeset
51 pop(); // shrink list by one block
a61af66fc99e Initial load
duke
parents:
diff changeset
52 }
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 void Block_List::insert(uint i, Block *b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 push(b); // grow list by one block
a61af66fc99e Initial load
duke
parents:
diff changeset
56 Copy::conjoint_words_to_higher((HeapWord*)&_blocks[i], (HeapWord*)&_blocks[i+1], ((_cnt-i-1)*sizeof(Block*)));
a61af66fc99e Initial load
duke
parents:
diff changeset
57 _blocks[i] = b;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 }
a61af66fc99e Initial load
duke
parents:
diff changeset
59
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
60 #ifndef PRODUCT
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
61 void Block_List::print() {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
62 for (uint i=0; i < size(); i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
63 tty->print("B%d ", _blocks[i]->_pre_order);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
64 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
65 tty->print("size = %d\n", size());
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
66 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
67 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 uint Block::code_alignment() {
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // Check for Root block
a61af66fc99e Initial load
duke
parents:
diff changeset
73 if( _pre_order == 0 ) return CodeEntryAlignment;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // Check for Start block
a61af66fc99e Initial load
duke
parents:
diff changeset
75 if( _pre_order == 1 ) return InteriorEntryAlignment;
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // Check for loop alignment
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
77 if (has_loop_alignment()) return loop_alignment();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
78
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
79 return 1; // no particular alignment
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
80 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
81
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
82 uint Block::compute_loop_alignment() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
83 Node *h = head();
a61af66fc99e Initial load
duke
parents:
diff changeset
84 if( h->is_Loop() && h->as_Loop()->is_inner_loop() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // Pre- and post-loops have low trip count so do not bother with
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // NOPs for align loop head. The constants are hidden from tuning
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // but only because my "divide by 4" heuristic surely gets nearly
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // all possible gain (a "do not align at all" heuristic has a
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // chance of getting a really tiny gain).
a61af66fc99e Initial load
duke
parents:
diff changeset
90 if( h->is_CountedLoop() && (h->as_CountedLoop()->is_pre_loop() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
91 h->as_CountedLoop()->is_post_loop()) )
a61af66fc99e Initial load
duke
parents:
diff changeset
92 return (OptoLoopAlignment > 4) ? (OptoLoopAlignment>>2) : 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // Loops with low backedge frequency should not be aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
94 Node *n = h->in(LoopNode::LoopBackControl)->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
95 if( n->is_MachIf() && n->as_MachIf()->_prob < 0.01 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 return 1; // Loop does not loop, more often than not!
a61af66fc99e Initial load
duke
parents:
diff changeset
97 }
a61af66fc99e Initial load
duke
parents:
diff changeset
98 return OptoLoopAlignment; // Otherwise align loop head
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
100
0
a61af66fc99e Initial load
duke
parents:
diff changeset
101 return 1; // no particular alignment
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 //-----------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // Compute the size of first 'inst_cnt' instructions in this block.
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // Return the number of instructions left to compute if the block has
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
107 // less then 'inst_cnt' instructions. Stop, and return 0 if sum_size
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
108 // exceeds OptoLoopAlignment.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
109 uint Block::compute_first_inst_size(uint& sum_size, uint inst_cnt,
a61af66fc99e Initial load
duke
parents:
diff changeset
110 PhaseRegAlloc* ra) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 uint last_inst = _nodes.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
112 for( uint j = 0; j < last_inst && inst_cnt > 0; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 uint inst_size = _nodes[j]->size(ra);
a61af66fc99e Initial load
duke
parents:
diff changeset
114 if( inst_size > 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 inst_cnt--;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 uint sz = sum_size + inst_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
117 if( sz <= (uint)OptoLoopAlignment ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // Compute size of instructions which fit into fetch buffer only
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // since all inst_cnt instructions will not fit even if we align them.
a61af66fc99e Initial load
duke
parents:
diff changeset
120 sum_size = sz;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
122 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
126 return inst_cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 //-----------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
130 uint Block::find_node( const Node *n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 for( uint i = 0; i < _nodes.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 if( _nodes[i] == n )
a61af66fc99e Initial load
duke
parents:
diff changeset
133 return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
135 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
136 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // Find and remove n from block list
a61af66fc99e Initial load
duke
parents:
diff changeset
140 void Block::find_remove( const Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 _nodes.remove(find_node(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 //------------------------------is_Empty---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // Return empty status of a block. Empty blocks contain only the head, other
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // ideal nodes, and an optional trailing goto.
a61af66fc99e Initial load
duke
parents:
diff changeset
147 int Block::is_Empty() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // Root or start block is not considered empty
a61af66fc99e Initial load
duke
parents:
diff changeset
150 if (head()->is_Root() || head()->is_Start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 return not_empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 int success_result = completely_empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
155 int end_idx = _nodes.size()-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // Check for ending goto
a61af66fc99e Initial load
duke
parents:
diff changeset
158 if ((end_idx > 0) && (_nodes[end_idx]->is_Goto())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
159 success_result = empty_with_goto;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 end_idx--;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // Unreachable blocks are considered empty
a61af66fc99e Initial load
duke
parents:
diff changeset
164 if (num_preds() <= 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 return success_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // Ideal nodes are allowable in empty blocks: skip them Only MachNodes
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // turn directly into code, because only MachNodes have non-trivial
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // emit() functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
171 while ((end_idx > 0) && !_nodes[end_idx]->is_Mach()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 end_idx--;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // No room for any interesting instructions?
a61af66fc99e Initial load
duke
parents:
diff changeset
176 if (end_idx == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 return success_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 return not_empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 //------------------------------has_uncommon_code------------------------------
605
98cb887364d3 6810672: Comment typos
twisti
parents: 601
diff changeset
184 // Return true if the block's code implies that it is likely to be
0
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // executed infrequently. Check to see if the block ends in a Halt or
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // a low probability call.
a61af66fc99e Initial load
duke
parents:
diff changeset
187 bool Block::has_uncommon_code() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 Node* en = end();
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 if (en->is_Goto())
a61af66fc99e Initial load
duke
parents:
diff changeset
191 en = en->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 if (en->is_Catch())
a61af66fc99e Initial load
duke
parents:
diff changeset
193 en = en->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 if (en->is_Proj() && en->in(0)->is_MachCall()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 MachCallNode* call = en->in(0)->as_MachCall();
a61af66fc99e Initial load
duke
parents:
diff changeset
196 if (call->cnt() != COUNT_UNKNOWN && call->cnt() <= PROB_UNLIKELY_MAG(4)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // This is true for slow-path stubs like new_{instance,array},
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // slow_arraycopy, complete_monitor_locking, uncommon_trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // The magic number corresponds to the probability of an uncommon_trap,
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // even though it is a count not a probability.
a61af66fc99e Initial load
duke
parents:
diff changeset
201 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 int op = en->is_Mach() ? en->as_Mach()->ideal_Opcode() : en->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
206 return op == Op_Halt;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 //------------------------------is_uncommon------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // True if block is low enough frequency or guarded by a test which
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // mostly does not go here.
a61af66fc99e Initial load
duke
parents:
diff changeset
212 bool Block::is_uncommon( Block_Array &bbs ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // Initial blocks must never be moved, so are never uncommon.
a61af66fc99e Initial load
duke
parents:
diff changeset
214 if (head()->is_Root() || head()->is_Start()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
215
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // Check for way-low freq
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if( _freq < BLOCK_FREQUENCY(0.00001f) ) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
218
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // Look for code shape indicating uncommon_trap or slow path
a61af66fc99e Initial load
duke
parents:
diff changeset
220 if (has_uncommon_code()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 const float epsilon = 0.05f;
a61af66fc99e Initial load
duke
parents:
diff changeset
223 const float guard_factor = PROB_UNLIKELY_MAG(4) / (1.f - epsilon);
a61af66fc99e Initial load
duke
parents:
diff changeset
224 uint uncommon_preds = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
225 uint freq_preds = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 uint uncommon_for_freq_preds = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 for( uint i=1; i<num_preds(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
229 Block* guard = bbs[pred(i)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // Check to see if this block follows its guard 1 time out of 10000
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // or less.
a61af66fc99e Initial load
duke
parents:
diff changeset
232 //
a61af66fc99e Initial load
duke
parents:
diff changeset
233 // See list of magnitude-4 unlikely probabilities in cfgnode.hpp which
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // we intend to be "uncommon", such as slow-path TLE allocation,
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // predicted call failure, and uncommon trap triggers.
a61af66fc99e Initial load
duke
parents:
diff changeset
236 //
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // Use an epsilon value of 5% to allow for variability in frequency
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // predictions and floating point calculations. The net effect is
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // that guard_factor is set to 9500.
a61af66fc99e Initial load
duke
parents:
diff changeset
240 //
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // Ignore low-frequency blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // The next check is (guard->_freq < 1.e-5 * 9500.).
a61af66fc99e Initial load
duke
parents:
diff changeset
243 if(guard->_freq*BLOCK_FREQUENCY(guard_factor) < BLOCK_FREQUENCY(0.00001f)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
244 uncommon_preds++;
a61af66fc99e Initial load
duke
parents:
diff changeset
245 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
246 freq_preds++;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 if( _freq < guard->_freq * guard_factor ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 uncommon_for_freq_preds++;
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 if( num_preds() > 1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // The block is uncommon if all preds are uncommon or
a61af66fc99e Initial load
duke
parents:
diff changeset
254 (uncommon_preds == (num_preds()-1) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // it is uncommon for all frequent preds.
a61af66fc99e Initial load
duke
parents:
diff changeset
256 uncommon_for_freq_preds == freq_preds) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
257 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262 //------------------------------dump-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
263 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
264 void Block::dump_bidx(const Block* orig) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (_pre_order) tty->print("B%d",_pre_order);
a61af66fc99e Initial load
duke
parents:
diff changeset
266 else tty->print("N%d", head()->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 if (Verbose && orig != this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // Dump the original block's idx
a61af66fc99e Initial load
duke
parents:
diff changeset
270 tty->print(" (");
a61af66fc99e Initial load
duke
parents:
diff changeset
271 orig->dump_bidx(orig);
a61af66fc99e Initial load
duke
parents:
diff changeset
272 tty->print(")");
a61af66fc99e Initial load
duke
parents:
diff changeset
273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 void Block::dump_pred(const Block_Array *bbs, Block* orig) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 if (is_connector()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
278 for (uint i=1; i<num_preds(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 Block *p = ((*bbs)[pred(i)->_idx]);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 p->dump_pred(bbs, orig);
a61af66fc99e Initial load
duke
parents:
diff changeset
281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
282 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 dump_bidx(orig);
a61af66fc99e Initial load
duke
parents:
diff changeset
284 tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 void Block::dump_head( const Block_Array *bbs ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // Print the basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
290 dump_bidx(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
291 tty->print(": #\t");
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // Print the incoming CFG edges and the outgoing CFG edges
a61af66fc99e Initial load
duke
parents:
diff changeset
294 for( uint i=0; i<_num_succs; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
295 non_connector_successor(i)->dump_bidx(_succs[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
296 tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
298 tty->print("<- ");
a61af66fc99e Initial load
duke
parents:
diff changeset
299 if( head()->is_block_start() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
300 for (uint i=1; i<num_preds(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 Node *s = pred(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 if (bbs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
303 Block *p = (*bbs)[s->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
304 p->dump_pred(bbs, p);
a61af66fc99e Initial load
duke
parents:
diff changeset
305 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
306 while (!s->is_block_start())
a61af66fc99e Initial load
duke
parents:
diff changeset
307 s = s->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 tty->print("N%d ", s->_idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
312 tty->print("BLOCK HEAD IS JUNK ");
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // Print loop, if any
a61af66fc99e Initial load
duke
parents:
diff changeset
315 const Block *bhead = this; // Head of self-loop
a61af66fc99e Initial load
duke
parents:
diff changeset
316 Node *bh = bhead->head();
a61af66fc99e Initial load
duke
parents:
diff changeset
317 if( bbs && bh->is_Loop() && !head()->is_Root() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 LoopNode *loop = bh->as_Loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
319 const Block *bx = (*bbs)[loop->in(LoopNode::LoopBackControl)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
320 while (bx->is_connector()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 bx = (*bbs)[bx->pred(1)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323 tty->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order);
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // Dump any loop-specific bits, especially for CountedLoops.
a61af66fc99e Initial load
duke
parents:
diff changeset
325 loop->dump_spec(tty);
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
326 } else if (has_loop_alignment()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
327 tty->print(" top-of-loop");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
329 tty->print(" Freq: %g",_freq);
a61af66fc99e Initial load
duke
parents:
diff changeset
330 if( Verbose || WizardMode ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
331 tty->print(" IDom: %d/#%d", _idom ? _idom->_pre_order : 0, _dom_depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
332 tty->print(" RegPressure: %d",_reg_pressure);
a61af66fc99e Initial load
duke
parents:
diff changeset
333 tty->print(" IHRP Index: %d",_ihrp_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
334 tty->print(" FRegPressure: %d",_freg_pressure);
a61af66fc99e Initial load
duke
parents:
diff changeset
335 tty->print(" FHRP Index: %d",_fhrp_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
337 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 void Block::dump() const { dump(0); }
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 void Block::dump( const Block_Array *bbs ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 dump_head(bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
344 uint cnt = _nodes.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
345 for( uint i=0; i<cnt; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
346 _nodes[i]->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
347 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
349 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
350
a61af66fc99e Initial load
duke
parents:
diff changeset
351 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
352 //------------------------------PhaseCFG---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
353 PhaseCFG::PhaseCFG( Arena *a, RootNode *r, Matcher &m ) :
a61af66fc99e Initial load
duke
parents:
diff changeset
354 Phase(CFG),
a61af66fc99e Initial load
duke
parents:
diff changeset
355 _bbs(a),
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
356 _root(r),
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
357 _node_latency(NULL)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
358 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
359 , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining"))
a61af66fc99e Initial load
duke
parents:
diff changeset
360 #endif
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 628
diff changeset
361 #ifdef ASSERT
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 628
diff changeset
362 , _raw_oops(a)
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 628
diff changeset
363 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
364 {
a61af66fc99e Initial load
duke
parents:
diff changeset
365 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // I'll need a few machine-specific GotoNodes. Make an Ideal GotoNode,
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // then Match it into a machine-specific Node. Then clone the machine
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // Node on demand.
a61af66fc99e Initial load
duke
parents:
diff changeset
369 Node *x = new (C, 1) GotoNode(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
370 x->init_req(0, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
371 _goto = m.match_tree(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
372 assert(_goto != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
373 _goto->set_req(0,_goto);
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // Build the CFG in Reverse Post Order
a61af66fc99e Initial load
duke
parents:
diff changeset
376 _num_blocks = build_cfg();
a61af66fc99e Initial load
duke
parents:
diff changeset
377 _broot = _bbs[_root->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 //------------------------------build_cfg--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
381 // Build a proper looking CFG. Make every block begin with either a StartNode
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // or a RegionNode. Make every block end with either a Goto, If or Return.
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // The RootNode both starts and ends it's own block. Do this with a recursive
a61af66fc99e Initial load
duke
parents:
diff changeset
384 // backwards walk over the control edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
385 uint PhaseCFG::build_cfg() {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 Arena *a = Thread::current()->resource_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
387 VectorSet visited(a);
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // Allocate stack with enough space to avoid frequent realloc
a61af66fc99e Initial load
duke
parents:
diff changeset
390 Node_Stack nstack(a, C->unique() >> 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
391 nstack.push(_root, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
392 uint sum = 0; // Counter for blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
393
a61af66fc99e Initial load
duke
parents:
diff changeset
394 while (nstack.is_nonempty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // node and in's index from stack's top
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // 'np' is _root (see above) or RegionNode, StartNode: we push on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // only nodes which point to the start of basic block (see below).
a61af66fc99e Initial load
duke
parents:
diff changeset
398 Node *np = nstack.node();
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // idx > 0, except for the first node (_root) pushed on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // at the beginning when idx == 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // We will use the condition (idx == 0) later to end the build.
a61af66fc99e Initial load
duke
parents:
diff changeset
402 uint idx = nstack.index();
a61af66fc99e Initial load
duke
parents:
diff changeset
403 Node *proj = np->in(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
404 const Node *x = proj->is_block_proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // Does the block end with a proper block-ending Node? One of Return,
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // If or Goto? (This check should be done for visited nodes also).
a61af66fc99e Initial load
duke
parents:
diff changeset
407 if (x == NULL) { // Does not end right...
a61af66fc99e Initial load
duke
parents:
diff changeset
408 Node *g = _goto->clone(); // Force it to end in a Goto
a61af66fc99e Initial load
duke
parents:
diff changeset
409 g->set_req(0, proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
410 np->set_req(idx, g);
a61af66fc99e Initial load
duke
parents:
diff changeset
411 x = proj = g;
a61af66fc99e Initial load
duke
parents:
diff changeset
412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
413 if (!visited.test_set(x->_idx)) { // Visit this block once
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // Skip any control-pinned middle'in stuff
a61af66fc99e Initial load
duke
parents:
diff changeset
415 Node *p = proj;
a61af66fc99e Initial load
duke
parents:
diff changeset
416 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
417 proj = p; // Update pointer to last Control
a61af66fc99e Initial load
duke
parents:
diff changeset
418 p = p->in(0); // Move control forward
a61af66fc99e Initial load
duke
parents:
diff changeset
419 } while( !p->is_block_proj() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
420 !p->is_block_start() );
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // Make the block begin with one of Region or StartNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
422 if( !p->is_block_start() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
423 RegionNode *r = new (C, 2) RegionNode( 2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
424 r->init_req(1, p); // Insert RegionNode in the way
a61af66fc99e Initial load
duke
parents:
diff changeset
425 proj->set_req(0, r); // Insert RegionNode in the way
a61af66fc99e Initial load
duke
parents:
diff changeset
426 p = r;
a61af66fc99e Initial load
duke
parents:
diff changeset
427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // 'p' now points to the start of this basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // Put self in array of basic blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
431 Block *bb = new (_bbs._arena) Block(_bbs._arena,p);
a61af66fc99e Initial load
duke
parents:
diff changeset
432 _bbs.map(p->_idx,bb);
a61af66fc99e Initial load
duke
parents:
diff changeset
433 _bbs.map(x->_idx,bb);
a61af66fc99e Initial load
duke
parents:
diff changeset
434 if( x != p ) // Only for root is x == p
a61af66fc99e Initial load
duke
parents:
diff changeset
435 bb->_nodes.push((Node*)x);
a61af66fc99e Initial load
duke
parents:
diff changeset
436
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // Now handle predecessors
a61af66fc99e Initial load
duke
parents:
diff changeset
438 ++sum; // Count 1 for self block
a61af66fc99e Initial load
duke
parents:
diff changeset
439 uint cnt = bb->num_preds();
a61af66fc99e Initial load
duke
parents:
diff changeset
440 for (int i = (cnt - 1); i > 0; i-- ) { // For all predecessors
a61af66fc99e Initial load
duke
parents:
diff changeset
441 Node *prevproj = p->in(i); // Get prior input
a61af66fc99e Initial load
duke
parents:
diff changeset
442 assert( !prevproj->is_Con(), "dead input not removed" );
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // Check to see if p->in(i) is a "control-dependent" CFG edge -
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // i.e., it splits at the source (via an IF or SWITCH) and merges
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // at the destination (via a many-input Region).
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // This breaks critical edges. The RegionNode to start the block
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // will be added when <p,i> is pulled off the node stack
a61af66fc99e Initial load
duke
parents:
diff changeset
448 if ( cnt > 2 ) { // Merging many things?
a61af66fc99e Initial load
duke
parents:
diff changeset
449 assert( prevproj== bb->pred(i),"");
a61af66fc99e Initial load
duke
parents:
diff changeset
450 if(prevproj->is_block_proj() != prevproj) { // Control-dependent edge?
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // Force a block on the control-dependent edge
a61af66fc99e Initial load
duke
parents:
diff changeset
452 Node *g = _goto->clone(); // Force it to end in a Goto
a61af66fc99e Initial load
duke
parents:
diff changeset
453 g->set_req(0,prevproj);
a61af66fc99e Initial load
duke
parents:
diff changeset
454 p->set_req(i,g);
a61af66fc99e Initial load
duke
parents:
diff changeset
455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457 nstack.push(p, i); // 'p' is RegionNode or StartNode
a61af66fc99e Initial load
duke
parents:
diff changeset
458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
459 } else { // Post-processing visited nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
460 nstack.pop(); // remove node from stack
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // Check if it the fist node pushed on stack at the beginning.
a61af66fc99e Initial load
duke
parents:
diff changeset
462 if (idx == 0) break; // end of the build
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // Find predecessor basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
464 Block *pb = _bbs[x->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // Insert into nodes array, if not already there
a61af66fc99e Initial load
duke
parents:
diff changeset
466 if( !_bbs.lookup(proj->_idx) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 assert( x != proj, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // Map basic block of projection
a61af66fc99e Initial load
duke
parents:
diff changeset
469 _bbs.map(proj->_idx,pb);
a61af66fc99e Initial load
duke
parents:
diff changeset
470 pb->_nodes.push(proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // Insert self as a child of my predecessor block
a61af66fc99e Initial load
duke
parents:
diff changeset
473 pb->_succs.map(pb->_num_succs++, _bbs[np->_idx]);
a61af66fc99e Initial load
duke
parents:
diff changeset
474 assert( pb->_nodes[ pb->_nodes.size() - pb->_num_succs ]->is_block_proj(),
a61af66fc99e Initial load
duke
parents:
diff changeset
475 "too many control users, not a CFG?" );
a61af66fc99e Initial load
duke
parents:
diff changeset
476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // Return number of basic blocks for all children and self
a61af66fc99e Initial load
duke
parents:
diff changeset
479 return sum;
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 //------------------------------insert_goto_at---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // Inserts a goto & corresponding basic block between
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // block[block_no] and its succ_no'th successor block
a61af66fc99e Initial load
duke
parents:
diff changeset
485 void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // get block with block_no
a61af66fc99e Initial load
duke
parents:
diff changeset
487 assert(block_no < _num_blocks, "illegal block number");
a61af66fc99e Initial load
duke
parents:
diff changeset
488 Block* in = _blocks[block_no];
a61af66fc99e Initial load
duke
parents:
diff changeset
489 // get successor block succ_no
a61af66fc99e Initial load
duke
parents:
diff changeset
490 assert(succ_no < in->_num_succs, "illegal successor number");
a61af66fc99e Initial load
duke
parents:
diff changeset
491 Block* out = in->_succs[succ_no];
308
756b58154237 6611837: block frequency is zero
rasbold
parents: 0
diff changeset
492 // Compute frequency of the new block. Do this before inserting
756b58154237 6611837: block frequency is zero
rasbold
parents: 0
diff changeset
493 // new block in case succ_prob() needs to infer the probability from
756b58154237 6611837: block frequency is zero
rasbold
parents: 0
diff changeset
494 // surrounding blocks.
756b58154237 6611837: block frequency is zero
rasbold
parents: 0
diff changeset
495 float freq = in->_freq * in->succ_prob(succ_no);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // get ProjNode corresponding to the succ_no'th successor of the in block
a61af66fc99e Initial load
duke
parents:
diff changeset
497 ProjNode* proj = in->_nodes[in->_nodes.size() - in->_num_succs + succ_no]->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // create region for basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
499 RegionNode* region = new (C, 2) RegionNode(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
500 region->init_req(1, proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // setup corresponding basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
502 Block* block = new (_bbs._arena) Block(_bbs._arena, region);
a61af66fc99e Initial load
duke
parents:
diff changeset
503 _bbs.map(region->_idx, block);
a61af66fc99e Initial load
duke
parents:
diff changeset
504 C->regalloc()->set_bad(region->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 // add a goto node
a61af66fc99e Initial load
duke
parents:
diff changeset
506 Node* gto = _goto->clone(); // get a new goto node
a61af66fc99e Initial load
duke
parents:
diff changeset
507 gto->set_req(0, region);
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // add it to the basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
509 block->_nodes.push(gto);
a61af66fc99e Initial load
duke
parents:
diff changeset
510 _bbs.map(gto->_idx, block);
a61af66fc99e Initial load
duke
parents:
diff changeset
511 C->regalloc()->set_bad(gto->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // hook up successor block
a61af66fc99e Initial load
duke
parents:
diff changeset
513 block->_succs.map(block->_num_succs++, out);
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // remap successor's predecessors if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
515 for (uint i = 1; i < out->num_preds(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
516 if (out->pred(i) == proj) out->head()->set_req(i, gto);
a61af66fc99e Initial load
duke
parents:
diff changeset
517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // remap predecessor's successor to new block
a61af66fc99e Initial load
duke
parents:
diff changeset
519 in->_succs.map(succ_no, block);
308
756b58154237 6611837: block frequency is zero
rasbold
parents: 0
diff changeset
520 // Set the frequency of the new block
756b58154237 6611837: block frequency is zero
rasbold
parents: 0
diff changeset
521 block->_freq = freq;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // add new basic block to basic block list
a61af66fc99e Initial load
duke
parents:
diff changeset
523 _blocks.insert(block_no + 1, block);
a61af66fc99e Initial load
duke
parents:
diff changeset
524 _num_blocks++;
a61af66fc99e Initial load
duke
parents:
diff changeset
525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
526
a61af66fc99e Initial load
duke
parents:
diff changeset
527 //------------------------------no_flip_branch---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // Does this block end in a multiway branch that cannot have the default case
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // flipped for another case?
a61af66fc99e Initial load
duke
parents:
diff changeset
530 static bool no_flip_branch( Block *b ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 int branch_idx = b->_nodes.size() - b->_num_succs-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
532 if( branch_idx < 1 ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
533 Node *bra = b->_nodes[branch_idx];
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
534 if( bra->is_Catch() )
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
535 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
536 if( bra->is_Mach() ) {
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
537 if( bra->is_MachNullCheck() )
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
538 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
539 int iop = bra->as_Mach()->ideal_Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
540 if( iop == Op_FastLock || iop == Op_FastUnlock )
a61af66fc99e Initial load
duke
parents:
diff changeset
541 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
543 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
544 }
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 //------------------------------convert_NeverBranch_to_Goto--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // Check for NeverBranch at block end. This needs to become a GOTO to the
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // true target. NeverBranch are treated as a conditional branch that always
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // goes the same direction for most of the optimizer and are used to give a
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // fake exit path to infinite loops. At this late stage they need to turn
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // into Goto's so that when you enter the infinite loop you indeed hang.
a61af66fc99e Initial load
duke
parents:
diff changeset
552 void PhaseCFG::convert_NeverBranch_to_Goto(Block *b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // Find true target
a61af66fc99e Initial load
duke
parents:
diff changeset
554 int end_idx = b->end_idx();
a61af66fc99e Initial load
duke
parents:
diff changeset
555 int idx = b->_nodes[end_idx+1]->as_Proj()->_con;
a61af66fc99e Initial load
duke
parents:
diff changeset
556 Block *succ = b->_succs[idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
557 Node* gto = _goto->clone(); // get a new goto node
a61af66fc99e Initial load
duke
parents:
diff changeset
558 gto->set_req(0, b->head());
a61af66fc99e Initial load
duke
parents:
diff changeset
559 Node *bp = b->_nodes[end_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
560 b->_nodes.map(end_idx,gto); // Slam over NeverBranch
a61af66fc99e Initial load
duke
parents:
diff changeset
561 _bbs.map(gto->_idx, b);
a61af66fc99e Initial load
duke
parents:
diff changeset
562 C->regalloc()->set_bad(gto->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
563 b->_nodes.pop(); // Yank projections
a61af66fc99e Initial load
duke
parents:
diff changeset
564 b->_nodes.pop(); // Yank projections
a61af66fc99e Initial load
duke
parents:
diff changeset
565 b->_succs.map(0,succ); // Map only successor
a61af66fc99e Initial load
duke
parents:
diff changeset
566 b->_num_succs = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
567 // remap successor's predecessors if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
568 uint j;
a61af66fc99e Initial load
duke
parents:
diff changeset
569 for( j = 1; j < succ->num_preds(); j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
570 if( succ->pred(j)->in(0) == bp )
a61af66fc99e Initial load
duke
parents:
diff changeset
571 succ->head()->set_req(j, gto);
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // Kill alternate exit path
a61af66fc99e Initial load
duke
parents:
diff changeset
573 Block *dead = b->_succs[1-idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
574 for( j = 1; j < dead->num_preds(); j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
575 if( dead->pred(j)->in(0) == bp )
a61af66fc99e Initial load
duke
parents:
diff changeset
576 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // Scan through block, yanking dead path from
a61af66fc99e Initial load
duke
parents:
diff changeset
578 // all regions and phis.
a61af66fc99e Initial load
duke
parents:
diff changeset
579 dead->head()->del_req(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
580 for( int k = 1; dead->_nodes[k]->is_Phi(); k++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
581 dead->_nodes[k]->del_req(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
584 //------------------------------move_to_next-----------------------------------
0
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // Helper function to move block bx to the slot following b_index. Return
a61af66fc99e Initial load
duke
parents:
diff changeset
586 // true if the move is successful, otherwise false
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
587 bool PhaseCFG::move_to_next(Block* bx, uint b_index) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
588 if (bx == NULL) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
589
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // Return false if bx is already scheduled.
a61af66fc99e Initial load
duke
parents:
diff changeset
591 uint bx_index = bx->_pre_order;
a61af66fc99e Initial load
duke
parents:
diff changeset
592 if ((bx_index <= b_index) && (_blocks[bx_index] == bx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
593 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
594 }
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // Find the current index of block bx on the block list
a61af66fc99e Initial load
duke
parents:
diff changeset
597 bx_index = b_index + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
598 while( bx_index < _num_blocks && _blocks[bx_index] != bx ) bx_index++;
a61af66fc99e Initial load
duke
parents:
diff changeset
599 assert(_blocks[bx_index] == bx, "block not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
600
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // If the previous block conditionally falls into bx, return false,
a61af66fc99e Initial load
duke
parents:
diff changeset
602 // because moving bx will create an extra jump.
a61af66fc99e Initial load
duke
parents:
diff changeset
603 for(uint k = 1; k < bx->num_preds(); k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
604 Block* pred = _bbs[bx->pred(k)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
605 if (pred == _blocks[bx_index-1]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
606 if (pred->_num_succs != 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
607 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
609 }
a61af66fc99e Initial load
duke
parents:
diff changeset
610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // Reinsert bx just past block 'b'
a61af66fc99e Initial load
duke
parents:
diff changeset
613 _blocks.remove(bx_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
614 _blocks.insert(b_index + 1, bx);
a61af66fc99e Initial load
duke
parents:
diff changeset
615 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
617
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
618 //------------------------------move_to_end------------------------------------
0
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // Move empty and uncommon blocks to the end.
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
620 void PhaseCFG::move_to_end(Block *b, uint i) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
621 int e = b->is_Empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
622 if (e != Block::not_empty) {
a61af66fc99e Initial load
duke
parents:
diff changeset
623 if (e == Block::empty_with_goto) {
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // Remove the goto, but leave the block.
a61af66fc99e Initial load
duke
parents:
diff changeset
625 b->_nodes.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // Mark this block as a connector block, which will cause it to be
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // ignored in certain functions such as non_connector_successor().
a61af66fc99e Initial load
duke
parents:
diff changeset
629 b->set_connector();
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // Move the empty block to the end, and don't recheck.
a61af66fc99e Initial load
duke
parents:
diff changeset
632 _blocks.remove(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
633 _blocks.push(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
636 //---------------------------set_loop_alignment--------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
637 // Set loop alignment for every block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
638 void PhaseCFG::set_loop_alignment() {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
639 uint last = _num_blocks;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
640 assert( _blocks[0] == _broot, "" );
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
641
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
642 for (uint i = 1; i < last; i++ ) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
643 Block *b = _blocks[i];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
644 if (b->head()->is_Loop()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
645 b->set_loop_alignment(b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
646 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
647 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
648 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
649
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
650 //-----------------------------remove_empty------------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
651 // Make empty basic blocks to be "connector" blocks, Move uncommon blocks
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
652 // to the end.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
653 void PhaseCFG::remove_empty() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // Move uncommon blocks to the end
a61af66fc99e Initial load
duke
parents:
diff changeset
655 uint last = _num_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
656 assert( _blocks[0] == _broot, "" );
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
657
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
658 for (uint i = 1; i < last; i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
659 Block *b = _blocks[i];
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
660 if (b->is_connector()) break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
661
a61af66fc99e Initial load
duke
parents:
diff changeset
662 // Check for NeverBranch at block end. This needs to become a GOTO to the
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // true target. NeverBranch are treated as a conditional branch that
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // always goes the same direction for most of the optimizer and are used
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // to give a fake exit path to infinite loops. At this late stage they
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // need to turn into Goto's so that when you enter the infinite loop you
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // indeed hang.
a61af66fc99e Initial load
duke
parents:
diff changeset
668 if( b->_nodes[b->end_idx()]->Opcode() == Op_NeverBranch )
a61af66fc99e Initial load
duke
parents:
diff changeset
669 convert_NeverBranch_to_Goto(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
670
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // Look for uncommon blocks and move to end.
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
672 if (!C->do_freq_based_layout()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
673 if( b->is_uncommon(_bbs) ) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
674 move_to_end(b, i);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
675 last--; // No longer check for being uncommon!
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
676 if( no_flip_branch(b) ) { // Fall-thru case must follow?
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
677 b = _blocks[i]; // Find the fall-thru block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
678 move_to_end(b, i);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
679 last--;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
680 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
681 i--; // backup block counter post-increment
0
a61af66fc99e Initial load
duke
parents:
diff changeset
682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
685
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
686 // Move empty blocks to the end
0
a61af66fc99e Initial load
duke
parents:
diff changeset
687 last = _num_blocks;
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
688 for (uint i = 1; i < last; i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
689 Block *b = _blocks[i];
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
690 if (b->is_Empty() != Block::not_empty) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
691 move_to_end(b, i);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
692 last--;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
693 i--;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
695 } // End of for all blocks
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
696 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
697
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
698 //-----------------------------fixup_flow--------------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
699 // Fix up the final control flow for basic blocks.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
700 void PhaseCFG::fixup_flow() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // Fixup final control flow for the blocks. Remove jump-to-next
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // block. If neither arm of a IF follows the conditional branch, we
a61af66fc99e Initial load
duke
parents:
diff changeset
703 // have to add a second jump after the conditional. We place the
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // TRUE branch target in succs[0] for both GOTOs and IFs.
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
705 for (uint i=0; i < _num_blocks; i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
706 Block *b = _blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
707 b->_pre_order = i; // turn pre-order into block-index
a61af66fc99e Initial load
duke
parents:
diff changeset
708
a61af66fc99e Initial load
duke
parents:
diff changeset
709 // Connector blocks need no further processing.
a61af66fc99e Initial load
duke
parents:
diff changeset
710 if (b->is_connector()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
711 assert((i+1) == _num_blocks || _blocks[i+1]->is_connector(),
a61af66fc99e Initial load
duke
parents:
diff changeset
712 "All connector blocks should sink to the end");
a61af66fc99e Initial load
duke
parents:
diff changeset
713 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
715 assert(b->is_Empty() != Block::completely_empty,
a61af66fc99e Initial load
duke
parents:
diff changeset
716 "Empty blocks should be connectors");
a61af66fc99e Initial load
duke
parents:
diff changeset
717
a61af66fc99e Initial load
duke
parents:
diff changeset
718 Block *bnext = (i < _num_blocks-1) ? _blocks[i+1] : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
719 Block *bs0 = b->non_connector_successor(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
720
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // Check for multi-way branches where I cannot negate the test to
a61af66fc99e Initial load
duke
parents:
diff changeset
722 // exchange the true and false targets.
a61af66fc99e Initial load
duke
parents:
diff changeset
723 if( no_flip_branch( b ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
724 // Find fall through case - if must fall into its target
a61af66fc99e Initial load
duke
parents:
diff changeset
725 int branch_idx = b->_nodes.size() - b->_num_succs;
a61af66fc99e Initial load
duke
parents:
diff changeset
726 for (uint j2 = 0; j2 < b->_num_succs; j2++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 const ProjNode* p = b->_nodes[branch_idx + j2]->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
728 if (p->_con == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // successor j2 is fall through case
a61af66fc99e Initial load
duke
parents:
diff changeset
730 if (b->non_connector_successor(j2) != bnext) {
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // but it is not the next block => insert a goto
a61af66fc99e Initial load
duke
parents:
diff changeset
732 insert_goto_at(i, j2);
a61af66fc99e Initial load
duke
parents:
diff changeset
733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // Put taken branch in slot 0
a61af66fc99e Initial load
duke
parents:
diff changeset
735 if( j2 == 0 && b->_num_succs == 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // Flip targets in succs map
a61af66fc99e Initial load
duke
parents:
diff changeset
737 Block *tbs0 = b->_succs[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
738 Block *tbs1 = b->_succs[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
739 b->_succs.map( 0, tbs1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
740 b->_succs.map( 1, tbs0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // Remove all CatchProjs
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
746 for (uint j1 = 0; j1 < b->_num_succs; j1++) b->_nodes.pop();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
747
a61af66fc99e Initial load
duke
parents:
diff changeset
748 } else if (b->_num_succs == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // Block ends in a Goto?
a61af66fc99e Initial load
duke
parents:
diff changeset
750 if (bnext == bs0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // We fall into next block; remove the Goto
a61af66fc99e Initial load
duke
parents:
diff changeset
752 b->_nodes.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
754
a61af66fc99e Initial load
duke
parents:
diff changeset
755 } else if( b->_num_succs == 2 ) { // Block ends in a If?
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // Get opcode of 1st projection (matches _succs[0])
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // Note: Since this basic block has 2 exits, the last 2 nodes must
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // be projections (in any order), the 3rd last node must be
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // the IfNode (we have excluded other 2-way exits such as
a61af66fc99e Initial load
duke
parents:
diff changeset
760 // CatchNodes already).
a61af66fc99e Initial load
duke
parents:
diff changeset
761 MachNode *iff = b->_nodes[b->_nodes.size()-3]->as_Mach();
a61af66fc99e Initial load
duke
parents:
diff changeset
762 ProjNode *proj0 = b->_nodes[b->_nodes.size()-2]->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
763 ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
764
a61af66fc99e Initial load
duke
parents:
diff changeset
765 // Assert that proj0 and succs[0] match up. Similarly for proj1 and succs[1].
a61af66fc99e Initial load
duke
parents:
diff changeset
766 assert(proj0->raw_out(0) == b->_succs[0]->head(), "Mismatch successor 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
767 assert(proj1->raw_out(0) == b->_succs[1]->head(), "Mismatch successor 1");
a61af66fc99e Initial load
duke
parents:
diff changeset
768
a61af66fc99e Initial load
duke
parents:
diff changeset
769 Block *bs1 = b->non_connector_successor(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // Check for neither successor block following the current
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // block ending in a conditional. If so, move one of the
a61af66fc99e Initial load
duke
parents:
diff changeset
773 // successors after the current one, provided that the
a61af66fc99e Initial load
duke
parents:
diff changeset
774 // successor was previously unscheduled, but moveable
a61af66fc99e Initial load
duke
parents:
diff changeset
775 // (i.e., all paths to it involve a branch).
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
776 if( !C->do_freq_based_layout() && bnext != bs0 && bnext != bs1 ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // Choose the more common successor based on the probability
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // of the conditional branch.
a61af66fc99e Initial load
duke
parents:
diff changeset
779 Block *bx = bs0;
a61af66fc99e Initial load
duke
parents:
diff changeset
780 Block *by = bs1;
a61af66fc99e Initial load
duke
parents:
diff changeset
781
a61af66fc99e Initial load
duke
parents:
diff changeset
782 // _prob is the probability of taking the true path. Make
a61af66fc99e Initial load
duke
parents:
diff changeset
783 // p the probability of taking successor #1.
a61af66fc99e Initial load
duke
parents:
diff changeset
784 float p = iff->as_MachIf()->_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
785 if( proj0->Opcode() == Op_IfTrue ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
786 p = 1.0 - p;
a61af66fc99e Initial load
duke
parents:
diff changeset
787 }
a61af66fc99e Initial load
duke
parents:
diff changeset
788
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // Prefer successor #1 if p > 0.5
a61af66fc99e Initial load
duke
parents:
diff changeset
790 if (p > PROB_FAIR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
791 bx = bs1;
a61af66fc99e Initial load
duke
parents:
diff changeset
792 by = bs0;
a61af66fc99e Initial load
duke
parents:
diff changeset
793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
794
a61af66fc99e Initial load
duke
parents:
diff changeset
795 // Attempt the more common successor first
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
796 if (move_to_next(bx, i)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
797 bnext = bx;
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
798 } else if (move_to_next(by, i)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
799 bnext = by;
a61af66fc99e Initial load
duke
parents:
diff changeset
800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
802
a61af66fc99e Initial load
duke
parents:
diff changeset
803 // Check for conditional branching the wrong way. Negate
a61af66fc99e Initial load
duke
parents:
diff changeset
804 // conditional, if needed, so it falls into the following block
a61af66fc99e Initial load
duke
parents:
diff changeset
805 // and branches to the not-following block.
a61af66fc99e Initial load
duke
parents:
diff changeset
806
a61af66fc99e Initial load
duke
parents:
diff changeset
807 // Check for the next block being in succs[0]. We are going to branch
a61af66fc99e Initial load
duke
parents:
diff changeset
808 // to succs[0], so we want the fall-thru case as the next block in
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // succs[1].
a61af66fc99e Initial load
duke
parents:
diff changeset
810 if (bnext == bs0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
811 // Fall-thru case in succs[0], so flip targets in succs map
a61af66fc99e Initial load
duke
parents:
diff changeset
812 Block *tbs0 = b->_succs[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
813 Block *tbs1 = b->_succs[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
814 b->_succs.map( 0, tbs1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
815 b->_succs.map( 1, tbs0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
816 // Flip projection for each target
a61af66fc99e Initial load
duke
parents:
diff changeset
817 { ProjNode *tmp = proj0; proj0 = proj1; proj1 = tmp; }
a61af66fc99e Initial load
duke
parents:
diff changeset
818
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
819 } else if( bnext != bs1 ) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
820 // Need a double-branch
0
a61af66fc99e Initial load
duke
parents:
diff changeset
821 // The existing conditional branch need not change.
a61af66fc99e Initial load
duke
parents:
diff changeset
822 // Add a unconditional branch to the false target.
a61af66fc99e Initial load
duke
parents:
diff changeset
823 // Alas, it must appear in its own block and adding a
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // block this late in the game is complicated. Sigh.
a61af66fc99e Initial load
duke
parents:
diff changeset
825 insert_goto_at(i, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
826 }
a61af66fc99e Initial load
duke
parents:
diff changeset
827
a61af66fc99e Initial load
duke
parents:
diff changeset
828 // Make sure we TRUE branch to the target
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
829 if( proj0->Opcode() == Op_IfFalse ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
830 iff->negate();
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
831 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
832
a61af66fc99e Initial load
duke
parents:
diff changeset
833 b->_nodes.pop(); // Remove IfFalse & IfTrue projections
a61af66fc99e Initial load
duke
parents:
diff changeset
834 b->_nodes.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
835
a61af66fc99e Initial load
duke
parents:
diff changeset
836 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // Multi-exit block, e.g. a switch statement
a61af66fc99e Initial load
duke
parents:
diff changeset
838 // But we don't need to do anything here
a61af66fc99e Initial load
duke
parents:
diff changeset
839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
840 } // End of for all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
842
a61af66fc99e Initial load
duke
parents:
diff changeset
843
a61af66fc99e Initial load
duke
parents:
diff changeset
844 //------------------------------dump-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
845 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
846 void PhaseCFG::_dump_cfg( const Node *end, VectorSet &visited ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
847 const Node *x = end->is_block_proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
848 assert( x, "not a CFG" );
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // Do not visit this block again
a61af66fc99e Initial load
duke
parents:
diff changeset
851 if( visited.test_set(x->_idx) ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
852
a61af66fc99e Initial load
duke
parents:
diff changeset
853 // Skip through this block
a61af66fc99e Initial load
duke
parents:
diff changeset
854 const Node *p = x;
a61af66fc99e Initial load
duke
parents:
diff changeset
855 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
856 p = p->in(0); // Move control forward
a61af66fc99e Initial load
duke
parents:
diff changeset
857 assert( !p->is_block_proj() || p->is_Root(), "not a CFG" );
a61af66fc99e Initial load
duke
parents:
diff changeset
858 } while( !p->is_block_start() );
a61af66fc99e Initial load
duke
parents:
diff changeset
859
a61af66fc99e Initial load
duke
parents:
diff changeset
860 // Recursively visit
a61af66fc99e Initial load
duke
parents:
diff changeset
861 for( uint i=1; i<p->req(); i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
862 _dump_cfg(p->in(i),visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
863
a61af66fc99e Initial load
duke
parents:
diff changeset
864 // Dump the block
a61af66fc99e Initial load
duke
parents:
diff changeset
865 _bbs[p->_idx]->dump(&_bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 void PhaseCFG::dump( ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
869 tty->print("\n--- CFG --- %d BBs\n",_num_blocks);
a61af66fc99e Initial load
duke
parents:
diff changeset
870 if( _blocks.size() ) { // Did we do basic-block layout?
a61af66fc99e Initial load
duke
parents:
diff changeset
871 for( uint i=0; i<_num_blocks; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
872 _blocks[i]->dump(&_bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
873 } else { // Else do it with a DFS
a61af66fc99e Initial load
duke
parents:
diff changeset
874 VectorSet visited(_bbs._arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
875 _dump_cfg(_root,visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
876 }
a61af66fc99e Initial load
duke
parents:
diff changeset
877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
878
a61af66fc99e Initial load
duke
parents:
diff changeset
879 void PhaseCFG::dump_headers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
880 for( uint i = 0; i < _num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
881 if( _blocks[i] == NULL ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
882 _blocks[i]->dump_head(&_bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
883 }
a61af66fc99e Initial load
duke
parents:
diff changeset
884 }
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 void PhaseCFG::verify( ) const {
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
887 #ifdef ASSERT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
888 // Verify sane CFG
a61af66fc99e Initial load
duke
parents:
diff changeset
889 for( uint i = 0; i < _num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
890 Block *b = _blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
891 uint cnt = b->_nodes.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
892 uint j;
a61af66fc99e Initial load
duke
parents:
diff changeset
893 for( j = 0; j < cnt; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
894 Node *n = b->_nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
895 assert( _bbs[n->_idx] == b, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
896 if( j >= 1 && n->is_Mach() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
897 n->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
898 assert( j == 1 || b->_nodes[j-1]->is_Phi(),
a61af66fc99e Initial load
duke
parents:
diff changeset
899 "CreateEx must be first instruction in block" );
a61af66fc99e Initial load
duke
parents:
diff changeset
900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
901 for( uint k = 0; k < n->req(); k++ ) {
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
902 Node *def = n->in(k);
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
903 if( def && def != n ) {
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
904 assert( _bbs[def->_idx] || def->is_Con(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
905 "must have block; constants for debug info ok" );
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
906 // Verify that instructions in the block is in correct order.
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
907 // Uses must follow their definition if they are at the same block.
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
908 // Mostly done to check that MachSpillCopy nodes are placed correctly
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
909 // when CreateEx node is moved in build_ifg_physical().
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
910 if( _bbs[def->_idx] == b &&
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
911 !(b->head()->is_Loop() && n->is_Phi()) &&
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
912 // See (+++) comment in reg_split.cpp
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
913 !(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) {
893
dd0a4e1e219b 6851386: assert(b->find_node(def) < j,"uses must follow definitions")
kvn
parents: 833
diff changeset
914 bool is_loop = false;
dd0a4e1e219b 6851386: assert(b->find_node(def) < j,"uses must follow definitions")
kvn
parents: 833
diff changeset
915 if (n->is_Phi()) {
dd0a4e1e219b 6851386: assert(b->find_node(def) < j,"uses must follow definitions")
kvn
parents: 833
diff changeset
916 for( uint l = 1; l < def->req(); l++ ) {
dd0a4e1e219b 6851386: assert(b->find_node(def) < j,"uses must follow definitions")
kvn
parents: 833
diff changeset
917 if (n == def->in(l)) {
dd0a4e1e219b 6851386: assert(b->find_node(def) < j,"uses must follow definitions")
kvn
parents: 833
diff changeset
918 is_loop = true;
dd0a4e1e219b 6851386: assert(b->find_node(def) < j,"uses must follow definitions")
kvn
parents: 833
diff changeset
919 break; // Some kind of loop
dd0a4e1e219b 6851386: assert(b->find_node(def) < j,"uses must follow definitions")
kvn
parents: 833
diff changeset
920 }
dd0a4e1e219b 6851386: assert(b->find_node(def) < j,"uses must follow definitions")
kvn
parents: 833
diff changeset
921 }
dd0a4e1e219b 6851386: assert(b->find_node(def) < j,"uses must follow definitions")
kvn
parents: 833
diff changeset
922 }
dd0a4e1e219b 6851386: assert(b->find_node(def) < j,"uses must follow definitions")
kvn
parents: 833
diff changeset
923 assert( is_loop || b->find_node(def) < j, "uses must follow definitions" );
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
924 }
601
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 566
diff changeset
925 if( def->is_SafePointScalarObject() ) {
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 566
diff changeset
926 assert(_bbs[def->_idx] == b, "SafePointScalarObject Node should be at the same block as its SafePoint node");
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 566
diff changeset
927 assert(_bbs[def->_idx] == _bbs[def->in(0)->_idx], "SafePointScalarObject Node should be at the same block as its control edge");
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 566
diff changeset
928 }
0
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
a61af66fc99e Initial load
duke
parents:
diff changeset
933 j = b->end_idx();
a61af66fc99e Initial load
duke
parents:
diff changeset
934 Node *bp = (Node*)b->_nodes[b->_nodes.size()-1]->is_block_proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
935 assert( bp, "last instruction must be a block proj" );
a61af66fc99e Initial load
duke
parents:
diff changeset
936 assert( bp == b->_nodes[j], "wrong number of successors for this block" );
a61af66fc99e Initial load
duke
parents:
diff changeset
937 if( bp->is_Catch() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
938 while( b->_nodes[--j]->Opcode() == Op_MachProj ) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
939 assert( b->_nodes[j]->is_Call(), "CatchProj must follow call" );
a61af66fc99e Initial load
duke
parents:
diff changeset
940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
941 else if( bp->is_Mach() && bp->as_Mach()->ideal_Opcode() == Op_If ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
942 assert( b->_num_succs == 2, "Conditional branch must have two targets");
a61af66fc99e Initial load
duke
parents:
diff changeset
943 }
a61af66fc99e Initial load
duke
parents:
diff changeset
944 }
566
91263420e1c6 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 418
diff changeset
945 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
947 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
948
a61af66fc99e Initial load
duke
parents:
diff changeset
949 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
950 //------------------------------UnionFind--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
951 UnionFind::UnionFind( uint max ) : _cnt(max), _max(max), _indices(NEW_RESOURCE_ARRAY(uint,max)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
952 Copy::zero_to_bytes( _indices, sizeof(uint)*max );
a61af66fc99e Initial load
duke
parents:
diff changeset
953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
954
a61af66fc99e Initial load
duke
parents:
diff changeset
955 void UnionFind::extend( uint from_idx, uint to_idx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
956 _nesting.check();
a61af66fc99e Initial load
duke
parents:
diff changeset
957 if( from_idx >= _max ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
958 uint size = 16;
a61af66fc99e Initial load
duke
parents:
diff changeset
959 while( size <= from_idx ) size <<=1;
a61af66fc99e Initial load
duke
parents:
diff changeset
960 _indices = REALLOC_RESOURCE_ARRAY( uint, _indices, _max, size );
a61af66fc99e Initial load
duke
parents:
diff changeset
961 _max = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
962 }
a61af66fc99e Initial load
duke
parents:
diff changeset
963 while( _cnt <= from_idx ) _indices[_cnt++] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
964 _indices[from_idx] = to_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
966
a61af66fc99e Initial load
duke
parents:
diff changeset
967 void UnionFind::reset( uint max ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
968 assert( max <= max_uint, "Must fit within uint" );
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // Force the Union-Find mapping to be at least this large
a61af66fc99e Initial load
duke
parents:
diff changeset
970 extend(max,0);
a61af66fc99e Initial load
duke
parents:
diff changeset
971 // Initialize to be the ID mapping.
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
972 for( uint i=0; i<max; i++ ) map(i,i);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
974
a61af66fc99e Initial load
duke
parents:
diff changeset
975 //------------------------------Find_compress----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
976 // Straight out of Tarjan's union-find algorithm
a61af66fc99e Initial load
duke
parents:
diff changeset
977 uint UnionFind::Find_compress( uint idx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
978 uint cur = idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
979 uint next = lookup(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
980 while( next != cur ) { // Scan chain of equivalences
a61af66fc99e Initial load
duke
parents:
diff changeset
981 assert( next < cur, "always union smaller" );
a61af66fc99e Initial load
duke
parents:
diff changeset
982 cur = next; // until find a fixed-point
a61af66fc99e Initial load
duke
parents:
diff changeset
983 next = lookup(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
985 // Core of union-find algorithm: update chain of
a61af66fc99e Initial load
duke
parents:
diff changeset
986 // equivalences to be equal to the root.
a61af66fc99e Initial load
duke
parents:
diff changeset
987 while( idx != next ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
988 uint tmp = lookup(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
989 map(idx, next);
a61af66fc99e Initial load
duke
parents:
diff changeset
990 idx = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
992 return idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
993 }
a61af66fc99e Initial load
duke
parents:
diff changeset
994
a61af66fc99e Initial load
duke
parents:
diff changeset
995 //------------------------------Find_const-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
996 // Like Find above, but no path compress, so bad asymptotic behavior
a61af66fc99e Initial load
duke
parents:
diff changeset
997 uint UnionFind::Find_const( uint idx ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
998 if( idx == 0 ) return idx; // Ignore the zero idx
a61af66fc99e Initial load
duke
parents:
diff changeset
999 // Off the end? This can happen during debugging dumps
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 // when data structures have not finished being updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 if( idx >= _max ) return idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 uint next = lookup(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 while( next != idx ) { // Scan chain of equivalences
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 idx = next; // until find a fixed-point
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 next = lookup(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 return next;
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1009
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 //------------------------------Union------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 // union 2 sets together.
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 void UnionFind::Union( uint idx1, uint idx2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 uint src = Find(idx1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 uint dst = Find(idx2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 assert( src, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 assert( dst, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 assert( src < _max, "oob" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 assert( dst < _max, "oob" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 assert( src < dst, "always union smaller" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 map(dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 }
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1022
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1023 #ifndef PRODUCT
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1024 static void edge_dump(GrowableArray<CFGEdge *> *edges) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1025 tty->print_cr("---- Edges ----");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1026 for (int i = 0; i < edges->length(); i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1027 CFGEdge *e = edges->at(i);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1028 if (e != NULL) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1029 edges->at(i)->dump();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1030 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1031 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1032 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1033
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1034 static void trace_dump(Trace *traces[], int count) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1035 tty->print_cr("---- Traces ----");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1036 for (int i = 0; i < count; i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1037 Trace *tr = traces[i];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1038 if (tr != NULL) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1039 tr->dump();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1040 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1041 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1042 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1043
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1044 void Trace::dump( ) const {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1045 tty->print_cr("Trace (freq %f)", first_block()->_freq);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1046 for (Block *b = first_block(); b != NULL; b = next(b)) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1047 tty->print(" B%d", b->_pre_order);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1048 if (b->head()->is_Loop()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1049 tty->print(" (L%d)", b->compute_loop_alignment());
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1050 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1051 if (b->has_loop_alignment()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1052 tty->print(" (T%d)", b->code_alignment());
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1053 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1054 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1055 tty->cr();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1056 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1057
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1058 void CFGEdge::dump( ) const {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1059 tty->print(" B%d --> B%d Freq: %f out:%3d%% in:%3d%% State: ",
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1060 from()->_pre_order, to()->_pre_order, freq(), _from_pct, _to_pct);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1061 switch(state()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1062 case connected:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1063 tty->print("connected");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1064 break;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1065 case open:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1066 tty->print("open");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1067 break;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1068 case interior:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1069 tty->print("interior");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1070 break;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1071 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1072 if (infrequent()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1073 tty->print(" infrequent");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1074 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1075 tty->cr();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1076 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1077 #endif
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1078
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1079 //=============================================================================
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1080
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1081 //------------------------------edge_order-------------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1082 // Comparison function for edges
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1083 static int edge_order(CFGEdge **e0, CFGEdge **e1) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1084 float freq0 = (*e0)->freq();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1085 float freq1 = (*e1)->freq();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1086 if (freq0 != freq1) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1087 return freq0 > freq1 ? -1 : 1;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1088 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1089
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1090 int dist0 = (*e0)->to()->_rpo - (*e0)->from()->_rpo;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1091 int dist1 = (*e1)->to()->_rpo - (*e1)->from()->_rpo;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1092
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1093 return dist1 - dist0;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1094 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1095
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1096 //------------------------------trace_frequency_order--------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1097 // Comparison function for edges
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1098 static int trace_frequency_order(const void *p0, const void *p1) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1099 Trace *tr0 = *(Trace **) p0;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1100 Trace *tr1 = *(Trace **) p1;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1101 Block *b0 = tr0->first_block();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1102 Block *b1 = tr1->first_block();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1103
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1104 // The trace of connector blocks goes at the end;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1105 // we only expect one such trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1106 if (b0->is_connector() != b1->is_connector()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1107 return b1->is_connector() ? -1 : 1;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1108 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1109
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1110 // Pull more frequently executed blocks to the beginning
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1111 float freq0 = b0->_freq;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1112 float freq1 = b1->_freq;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1113 if (freq0 != freq1) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1114 return freq0 > freq1 ? -1 : 1;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1115 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1116
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1117 int diff = tr0->first_block()->_rpo - tr1->first_block()->_rpo;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1118
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1119 return diff;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1120 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1121
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1122 //------------------------------find_edges-------------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1123 // Find edges of interest, i.e, those which can fall through. Presumes that
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1124 // edges which don't fall through are of low frequency and can be generally
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1125 // ignored. Initialize the list of traces.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1126 void PhaseBlockLayout::find_edges()
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1127 {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1128 // Walk the blocks, creating edges and Traces
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1129 uint i;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1130 Trace *tr = NULL;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1131 for (i = 0; i < _cfg._num_blocks; i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1132 Block *b = _cfg._blocks[i];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1133 tr = new Trace(b, next, prev);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1134 traces[tr->id()] = tr;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1135
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1136 // All connector blocks should be at the end of the list
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1137 if (b->is_connector()) break;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1138
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1139 // If this block and the next one have a one-to-one successor
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1140 // predecessor relationship, simply append the next block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1141 int nfallthru = b->num_fall_throughs();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1142 while (nfallthru == 1 &&
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1143 b->succ_fall_through(0)) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1144 Block *n = b->_succs[0];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1145
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1146 // Skip over single-entry connector blocks, we don't want to
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1147 // add them to the trace.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1148 while (n->is_connector() && n->num_preds() == 1) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1149 n = n->_succs[0];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1150 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1151
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1152 // We see a merge point, so stop search for the next block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1153 if (n->num_preds() != 1) break;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1154
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1155 i++;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1156 assert(n = _cfg._blocks[i], "expecting next block");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1157 tr->append(n);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1158 uf->map(n->_pre_order, tr->id());
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1159 traces[n->_pre_order] = NULL;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1160 nfallthru = b->num_fall_throughs();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1161 b = n;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1162 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1163
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1164 if (nfallthru > 0) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1165 // Create a CFGEdge for each outgoing
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1166 // edge that could be a fall-through.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1167 for (uint j = 0; j < b->_num_succs; j++ ) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1168 if (b->succ_fall_through(j)) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1169 Block *target = b->non_connector_successor(j);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1170 float freq = b->_freq * b->succ_prob(j);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1171 int from_pct = (int) ((100 * freq) / b->_freq);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1172 int to_pct = (int) ((100 * freq) / target->_freq);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1173 edges->append(new CFGEdge(b, target, freq, from_pct, to_pct));
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1174 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1175 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1176 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1177 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1178
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1179 // Group connector blocks into one trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1180 for (i++; i < _cfg._num_blocks; i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1181 Block *b = _cfg._blocks[i];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1182 assert(b->is_connector(), "connector blocks at the end");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1183 tr->append(b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1184 uf->map(b->_pre_order, tr->id());
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1185 traces[b->_pre_order] = NULL;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1186 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1187 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1188
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1189 //------------------------------union_traces----------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1190 // Union two traces together in uf, and null out the trace in the list
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1191 void PhaseBlockLayout::union_traces(Trace* updated_trace, Trace* old_trace)
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1192 {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1193 uint old_id = old_trace->id();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1194 uint updated_id = updated_trace->id();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1195
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1196 uint lo_id = updated_id;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1197 uint hi_id = old_id;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1198
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1199 // If from is greater than to, swap values to meet
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1200 // UnionFind guarantee.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1201 if (updated_id > old_id) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1202 lo_id = old_id;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1203 hi_id = updated_id;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1204
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1205 // Fix up the trace ids
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1206 traces[lo_id] = traces[updated_id];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1207 updated_trace->set_id(lo_id);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1208 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1209
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1210 // Union the lower with the higher and remove the pointer
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1211 // to the higher.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1212 uf->Union(lo_id, hi_id);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1213 traces[hi_id] = NULL;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1214 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1215
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1216 //------------------------------grow_traces-------------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1217 // Append traces together via the most frequently executed edges
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1218 void PhaseBlockLayout::grow_traces()
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1219 {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1220 // Order the edges, and drive the growth of Traces via the most
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1221 // frequently executed edges.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1222 edges->sort(edge_order);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1223 for (int i = 0; i < edges->length(); i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1224 CFGEdge *e = edges->at(i);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1225
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1226 if (e->state() != CFGEdge::open) continue;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1227
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1228 Block *src_block = e->from();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1229 Block *targ_block = e->to();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1230
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1231 // Don't grow traces along backedges?
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1232 if (!BlockLayoutRotateLoops) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1233 if (targ_block->_rpo <= src_block->_rpo) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1234 targ_block->set_loop_alignment(targ_block);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1235 continue;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1236 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1237 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1238
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1239 Trace *src_trace = trace(src_block);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1240 Trace *targ_trace = trace(targ_block);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1241
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1242 // If the edge in question can join two traces at their ends,
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1243 // append one trace to the other.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1244 if (src_trace->last_block() == src_block) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1245 if (src_trace == targ_trace) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1246 e->set_state(CFGEdge::interior);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1247 if (targ_trace->backedge(e)) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1248 // Reset i to catch any newly eligible edge
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1249 // (Or we could remember the first "open" edge, and reset there)
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1250 i = 0;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1251 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1252 } else if (targ_trace->first_block() == targ_block) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1253 e->set_state(CFGEdge::connected);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1254 src_trace->append(targ_trace);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1255 union_traces(src_trace, targ_trace);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1256 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1257 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1258 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1259 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1260
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1261 //------------------------------merge_traces-----------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1262 // Embed one trace into another, if the fork or join points are sufficiently
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1263 // balanced.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1264 void PhaseBlockLayout::merge_traces(bool fall_thru_only)
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1265 {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1266 // Walk the edge list a another time, looking at unprocessed edges.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1267 // Fold in diamonds
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1268 for (int i = 0; i < edges->length(); i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1269 CFGEdge *e = edges->at(i);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1270
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1271 if (e->state() != CFGEdge::open) continue;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1272 if (fall_thru_only) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1273 if (e->infrequent()) continue;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1274 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1275
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1276 Block *src_block = e->from();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1277 Trace *src_trace = trace(src_block);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1278 bool src_at_tail = src_trace->last_block() == src_block;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1279
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1280 Block *targ_block = e->to();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1281 Trace *targ_trace = trace(targ_block);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1282 bool targ_at_start = targ_trace->first_block() == targ_block;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1283
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1284 if (src_trace == targ_trace) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1285 // This may be a loop, but we can't do much about it.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1286 e->set_state(CFGEdge::interior);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1287 continue;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1288 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1289
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1290 if (fall_thru_only) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1291 // If the edge links the middle of two traces, we can't do anything.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1292 // Mark the edge and continue.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1293 if (!src_at_tail & !targ_at_start) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1294 continue;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1295 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1296
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1297 // Don't grow traces along backedges?
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1298 if (!BlockLayoutRotateLoops && (targ_block->_rpo <= src_block->_rpo)) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1299 continue;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1300 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1301
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1302 // If both ends of the edge are available, why didn't we handle it earlier?
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1303 assert(src_at_tail ^ targ_at_start, "Should have caught this edge earlier.");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1304
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1305 if (targ_at_start) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1306 // Insert the "targ" trace in the "src" trace if the insertion point
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1307 // is a two way branch.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1308 // Better profitability check possible, but may not be worth it.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1309 // Someday, see if the this "fork" has an associated "join";
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1310 // then make a policy on merging this trace at the fork or join.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1311 // For example, other things being equal, it may be better to place this
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1312 // trace at the join point if the "src" trace ends in a two-way, but
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1313 // the insertion point is one-way.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1314 assert(src_block->num_fall_throughs() == 2, "unexpected diamond");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1315 e->set_state(CFGEdge::connected);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1316 src_trace->insert_after(src_block, targ_trace);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1317 union_traces(src_trace, targ_trace);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1318 } else if (src_at_tail) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1319 if (src_trace != trace(_cfg._broot)) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1320 e->set_state(CFGEdge::connected);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1321 targ_trace->insert_before(targ_block, src_trace);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1322 union_traces(targ_trace, src_trace);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1323 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1324 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1325 } else if (e->state() == CFGEdge::open) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1326 // Append traces, even without a fall-thru connection.
605
98cb887364d3 6810672: Comment typos
twisti
parents: 601
diff changeset
1327 // But leave root entry at the beginning of the block list.
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1328 if (targ_trace != trace(_cfg._broot)) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1329 e->set_state(CFGEdge::connected);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1330 src_trace->append(targ_trace);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1331 union_traces(src_trace, targ_trace);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1332 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1333 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1334 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1335 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1336
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1337 //----------------------------reorder_traces-----------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1338 // Order the sequence of the traces in some desirable way, and fixup the
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1339 // jumps at the end of each block.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1340 void PhaseBlockLayout::reorder_traces(int count)
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1341 {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1342 ResourceArea *area = Thread::current()->resource_area();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1343 Trace ** new_traces = NEW_ARENA_ARRAY(area, Trace *, count);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1344 Block_List worklist;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1345 int new_count = 0;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1346
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1347 // Compact the traces.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1348 for (int i = 0; i < count; i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1349 Trace *tr = traces[i];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1350 if (tr != NULL) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1351 new_traces[new_count++] = tr;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1352 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1353 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1354
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1355 // The entry block should be first on the new trace list.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1356 Trace *tr = trace(_cfg._broot);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1357 assert(tr == new_traces[0], "entry trace misplaced");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1358
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1359 // Sort the new trace list by frequency
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1360 qsort(new_traces + 1, new_count - 1, sizeof(new_traces[0]), trace_frequency_order);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1361
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1362 // Patch up the successor blocks
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1363 _cfg._blocks.reset();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1364 _cfg._num_blocks = 0;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1365 for (int i = 0; i < new_count; i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1366 Trace *tr = new_traces[i];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1367 if (tr != NULL) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1368 tr->fixup_blocks(_cfg);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1369 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1370 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1371 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1372
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1373 //------------------------------PhaseBlockLayout-------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1374 // Order basic blocks based on frequency
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1375 PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg) :
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1376 Phase(BlockLayout),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1377 _cfg(cfg)
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1378 {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1379 ResourceMark rm;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1380 ResourceArea *area = Thread::current()->resource_area();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1381
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1382 // List of traces
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1383 int size = _cfg._num_blocks + 1;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1384 traces = NEW_ARENA_ARRAY(area, Trace *, size);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1385 memset(traces, 0, size*sizeof(Trace*));
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1386 next = NEW_ARENA_ARRAY(area, Block *, size);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1387 memset(next, 0, size*sizeof(Block *));
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1388 prev = NEW_ARENA_ARRAY(area, Block *, size);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1389 memset(prev , 0, size*sizeof(Block *));
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1390
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1391 // List of edges
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1392 edges = new GrowableArray<CFGEdge*>;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1393
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1394 // Mapping block index --> block_trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1395 uf = new UnionFind(size);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1396 uf->reset(size);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1397
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1398 // Find edges and create traces.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1399 find_edges();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1400
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1401 // Grow traces at their ends via most frequent edges.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1402 grow_traces();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1403
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1404 // Merge one trace into another, but only at fall-through points.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1405 // This may make diamonds and other related shapes in a trace.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1406 merge_traces(true);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1407
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1408 // Run merge again, allowing two traces to be catenated, even if
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1409 // one does not fall through into the other. This appends loosely
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1410 // related traces to be near each other.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1411 merge_traces(false);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1412
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1413 // Re-order all the remaining traces by frequency
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1414 reorder_traces(size);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1415
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1416 assert(_cfg._num_blocks >= (uint) (size - 1), "number of blocks can not shrink");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1417 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1419
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1420 //------------------------------backedge---------------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1421 // Edge e completes a loop in a trace. If the target block is head of the
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1422 // loop, rotate the loop block so that the loop ends in a conditional branch.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1423 bool Trace::backedge(CFGEdge *e) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1424 bool loop_rotated = false;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1425 Block *src_block = e->from();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1426 Block *targ_block = e->to();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1427
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1428 assert(last_block() == src_block, "loop discovery at back branch");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1429 if (first_block() == targ_block) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1430 if (BlockLayoutRotateLoops && last_block()->num_fall_throughs() < 2) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1431 // Find the last block in the trace that has a conditional
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1432 // branch.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1433 Block *b;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1434 for (b = last_block(); b != NULL; b = prev(b)) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1435 if (b->num_fall_throughs() == 2) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1436 break;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1437 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1438 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1439
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1440 if (b != last_block() && b != NULL) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1441 loop_rotated = true;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1442
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1443 // Rotate the loop by doing two-part linked-list surgery.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1444 append(first_block());
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1445 break_loop_after(b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1446 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1447 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1448
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1449 // Backbranch to the top of a trace
605
98cb887364d3 6810672: Comment typos
twisti
parents: 601
diff changeset
1450 // Scroll forward through the trace from the targ_block. If we find
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1451 // a loop head before another loop top, use the the loop head alignment.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1452 for (Block *b = targ_block; b != NULL; b = next(b)) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1453 if (b->has_loop_alignment()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1454 break;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1455 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1456 if (b->head()->is_Loop()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1457 targ_block = b;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1458 break;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1459 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1460 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1461
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1462 first_block()->set_loop_alignment(targ_block);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1463
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1464 } else {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1465 // Backbranch into the middle of a trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1466 targ_block->set_loop_alignment(targ_block);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1467 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1468
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1469 return loop_rotated;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1470 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1471
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1472 //------------------------------fixup_blocks-----------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1473 // push blocks onto the CFG list
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1474 // ensure that blocks have the correct two-way branch sense
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1475 void Trace::fixup_blocks(PhaseCFG &cfg) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1476 Block *last = last_block();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1477 for (Block *b = first_block(); b != NULL; b = next(b)) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1478 cfg._blocks.push(b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1479 cfg._num_blocks++;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1480 if (!b->is_connector()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1481 int nfallthru = b->num_fall_throughs();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1482 if (b != last) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1483 if (nfallthru == 2) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1484 // Ensure that the sense of the branch is correct
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1485 Block *bnext = next(b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1486 Block *bs0 = b->non_connector_successor(0);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1487
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1488 MachNode *iff = b->_nodes[b->_nodes.size()-3]->as_Mach();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1489 ProjNode *proj0 = b->_nodes[b->_nodes.size()-2]->as_Proj();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1490 ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1491
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1492 if (bnext == bs0) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1493 // Fall-thru case in succs[0], should be in succs[1]
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1494
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1495 // Flip targets in _succs map
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1496 Block *tbs0 = b->_succs[0];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1497 Block *tbs1 = b->_succs[1];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1498 b->_succs.map( 0, tbs1 );
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1499 b->_succs.map( 1, tbs0 );
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1500
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1501 // Flip projections to match targets
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1502 b->_nodes.map(b->_nodes.size()-2, proj1);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1503 b->_nodes.map(b->_nodes.size()-1, proj0);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1504 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1505 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1506 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1507 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1508 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 337
diff changeset
1509 }