annotate src/share/vm/opto/block.hpp @ 1941:79d04223b8a5

Added caching for resolved types and resolved fields. This is crucial, because the local load elimination will lead to wrong results, if field equality (of two RiField objects with the same object and the same RiType) is not given. The caching makes sure that the default equals implementation is sufficient.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Tue, 28 Dec 2010 18:33:26 +0100
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: 844
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: 844
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 844
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 844
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
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 class Block;
a61af66fc99e Initial load
duke
parents:
diff changeset
28 class CFGLoop;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 class MachCallNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 class Matcher;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 class RootNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
32 class VectorSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 struct Tarjan;
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 //------------------------------Block_Array------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // Map dense integer indices to Blocks. Uses classic doubling-array trick.
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // Abstractly provides an infinite array of Block*'s, initialized to NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // Note that the constructor just zeros things, and since I use Arena
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // allocation I do not need a destructor to reclaim storage.
a61af66fc99e Initial load
duke
parents:
diff changeset
40 class Block_Array : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
41 uint _size; // allocated size, as opposed to formal limit
a61af66fc99e Initial load
duke
parents:
diff changeset
42 debug_only(uint _limit;) // limit to formal domain
a61af66fc99e Initial load
duke
parents:
diff changeset
43 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
44 Block **_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 void grow( uint i ); // Grow array node to fit
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
48 Arena *_arena; // Arena to allocate in
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 Block_Array(Arena *a) : _arena(a), _size(OptoBlockListSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
51 debug_only(_limit=0);
a61af66fc99e Initial load
duke
parents:
diff changeset
52 _blocks = NEW_ARENA_ARRAY( a, Block *, OptoBlockListSize );
a61af66fc99e Initial load
duke
parents:
diff changeset
53 for( int i = 0; i < OptoBlockListSize; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
54 _blocks[i] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 }
a61af66fc99e Initial load
duke
parents:
diff changeset
56 }
a61af66fc99e Initial load
duke
parents:
diff changeset
57 Block *lookup( uint i ) const // Lookup, or NULL for not mapped
a61af66fc99e Initial load
duke
parents:
diff changeset
58 { return (i<Max()) ? _blocks[i] : (Block*)NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
59 Block *operator[] ( uint i ) const // Lookup, or assert for not mapped
a61af66fc99e Initial load
duke
parents:
diff changeset
60 { assert( i < Max(), "oob" ); return _blocks[i]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // Extend the mapping: index i maps to Block *n.
a61af66fc99e Initial load
duke
parents:
diff changeset
62 void map( uint i, Block *n ) { if( i>=Max() ) grow(i); _blocks[i] = n; }
a61af66fc99e Initial load
duke
parents:
diff changeset
63 uint Max() const { debug_only(return _limit); return _size; }
a61af66fc99e Initial load
duke
parents:
diff changeset
64 };
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 class Block_List : public Block_Array {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
69 uint _cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 Block_List() : Block_Array(Thread::current()->resource_area()), _cnt(0) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
71 void push( Block *b ) { map(_cnt++,b); }
a61af66fc99e Initial load
duke
parents:
diff changeset
72 Block *pop() { return _blocks[--_cnt]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
73 Block *rpop() { Block *b = _blocks[0]; _blocks[0]=_blocks[--_cnt]; return b;}
a61af66fc99e Initial load
duke
parents:
diff changeset
74 void remove( uint i );
a61af66fc99e Initial load
duke
parents:
diff changeset
75 void insert( uint i, Block *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
76 uint size() const { return _cnt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
77 void reset() { _cnt = 0; }
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
78 void print();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
79 };
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 class CFGElement : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
84 float _freq; // Execution frequency (estimate)
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 CFGElement() : _freq(0.0f) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
87 virtual bool is_block() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
88 virtual bool is_loop() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
89 Block* as_Block() { assert(is_block(), "must be block"); return (Block*)this; }
a61af66fc99e Initial load
duke
parents:
diff changeset
90 CFGLoop* as_CFGLoop() { assert(is_loop(), "must be loop"); return (CFGLoop*)this; }
a61af66fc99e Initial load
duke
parents:
diff changeset
91 };
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 //------------------------------Block------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // This class defines a Basic Block.
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // Basic blocks are used during the output routines, and are not used during
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // any optimization pass. They are created late in the game.
a61af66fc99e Initial load
duke
parents:
diff changeset
97 class Block : public CFGElement {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // Nodes in this block, in order
a61af66fc99e Initial load
duke
parents:
diff changeset
100 Node_List _nodes;
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // Basic blocks have a Node which defines Control for all Nodes pinned in
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // this block. This Node is a RegionNode. Exception-causing Nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // (division, subroutines) and Phi functions are always pinned. Later,
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // every Node will get pinned to some block.
a61af66fc99e Initial load
duke
parents:
diff changeset
106 Node *head() const { return _nodes[0]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // CAUTION: num_preds() is ONE based, so that predecessor numbers match
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // input edges to Regions and Phis.
a61af66fc99e Initial load
duke
parents:
diff changeset
110 uint num_preds() const { return head()->req(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
111 Node *pred(uint i) const { return head()->in(i); }
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // Array of successor blocks, same size as projs array
a61af66fc99e Initial load
duke
parents:
diff changeset
114 Block_Array _succs;
a61af66fc99e Initial load
duke
parents:
diff changeset
115
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // Basic blocks have some number of Nodes which split control to all
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // following blocks. These Nodes are always Projections. The field in
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // the Projection and the block-ending Node determine which Block follows.
a61af66fc99e Initial load
duke
parents:
diff changeset
119 uint _num_succs;
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // Basic blocks also carry all sorts of good old fashioned DFS information
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // used to find loops, loop nesting depth, dominators, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
123 uint _pre_order; // Pre-order DFS number
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // Dominator tree
a61af66fc99e Initial load
duke
parents:
diff changeset
126 uint _dom_depth; // Depth in dominator tree for fast LCA
a61af66fc99e Initial load
duke
parents:
diff changeset
127 Block* _idom; // Immediate dominator block
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 CFGLoop *_loop; // Loop to which this block belongs
a61af66fc99e Initial load
duke
parents:
diff changeset
130 uint _rpo; // Number in reverse post order walk
a61af66fc99e Initial load
duke
parents:
diff changeset
131
a61af66fc99e Initial load
duke
parents:
diff changeset
132 virtual bool is_block() { return true; }
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
133 float succ_prob(uint i); // return probability of i'th successor
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
134 int num_fall_throughs(); // How many fall-through candidate this block has
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
135 void update_uncommon_branch(Block* un); // Lower branch prob to uncommon code
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
136 bool succ_fall_through(uint i); // Is successor "i" is a fall-through candidate
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
137 Block* lone_fall_through(); // Return lone fall-through Block or null
0
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 Block* dom_lca(Block* that); // Compute LCA in dominator tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
140 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
141 bool dominates(Block* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
142 int dom_diff = this->_dom_depth - that->_dom_depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
143 if (dom_diff > 0) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 for (; dom_diff < 0; dom_diff++) that = that->_idom;
a61af66fc99e Initial load
duke
parents:
diff changeset
145 return this == that;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
147 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // Report the alignment required by this block. Must be a power of 2.
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // The previous block will insert nops to get this alignment.
a61af66fc99e Initial load
duke
parents:
diff changeset
151 uint code_alignment();
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
152 uint compute_loop_alignment();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // BLOCK_FREQUENCY is a sentinel to mark uses of constant block frequencies.
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // It is currently also used to scale such frequencies relative to
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // FreqCountInvocations relative to the old value of 1500.
a61af66fc99e Initial load
duke
parents:
diff changeset
157 #define BLOCK_FREQUENCY(f) ((f * (float) 1500) / FreqCountInvocations)
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // Register Pressure (estimate) for Splitting heuristic
a61af66fc99e Initial load
duke
parents:
diff changeset
160 uint _reg_pressure;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 uint _ihrp_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
162 uint _freg_pressure;
a61af66fc99e Initial load
duke
parents:
diff changeset
163 uint _fhrp_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // Mark and visited bits for an LCA calculation in insert_anti_dependences.
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // Since they hold unique node indexes, they do not need reinitialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
167 node_idx_t _raise_LCA_mark;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 void set_raise_LCA_mark(node_idx_t x) { _raise_LCA_mark = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
169 node_idx_t raise_LCA_mark() const { return _raise_LCA_mark; }
a61af66fc99e Initial load
duke
parents:
diff changeset
170 node_idx_t _raise_LCA_visited;
a61af66fc99e Initial load
duke
parents:
diff changeset
171 void set_raise_LCA_visited(node_idx_t x) { _raise_LCA_visited = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
172 node_idx_t raise_LCA_visited() const { return _raise_LCA_visited; }
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // Estimated size in bytes of first instructions in a loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
175 uint _first_inst_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
176 uint first_inst_size() const { return _first_inst_size; }
a61af66fc99e Initial load
duke
parents:
diff changeset
177 void set_first_inst_size(uint s) { _first_inst_size = s; }
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Compute the size of first instructions in this block.
a61af66fc99e Initial load
duke
parents:
diff changeset
180 uint compute_first_inst_size(uint& sum_size, uint inst_cnt, PhaseRegAlloc* ra);
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // Compute alignment padding if the block needs it.
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // Align a loop if loop's padding is less or equal to padding limit
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // or the size of first instructions in the loop > padding.
a61af66fc99e Initial load
duke
parents:
diff changeset
185 uint alignment_padding(int current_offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
186 int block_alignment = code_alignment();
a61af66fc99e Initial load
duke
parents:
diff changeset
187 int max_pad = block_alignment-relocInfo::addr_unit();
a61af66fc99e Initial load
duke
parents:
diff changeset
188 if( max_pad > 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 assert(is_power_of_2(max_pad+relocInfo::addr_unit()), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
190 int current_alignment = current_offset & max_pad;
a61af66fc99e Initial load
duke
parents:
diff changeset
191 if( current_alignment != 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
192 uint padding = (block_alignment-current_alignment) & max_pad;
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
193 if( has_loop_alignment() &&
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
194 padding > (uint)MaxLoopPad &&
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
195 first_inst_size() <= padding ) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
196 return 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
197 }
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
198 return padding;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
201 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // Connector blocks. Connector blocks are basic blocks devoid of
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // instructions, but may have relevant non-instruction Nodes, such as
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // Phis or MergeMems. Such blocks are discovered and marked during the
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // RemoveEmpty phase, and elided during Output.
a61af66fc99e Initial load
duke
parents:
diff changeset
208 bool _connector;
a61af66fc99e Initial load
duke
parents:
diff changeset
209 void set_connector() { _connector = true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
210 bool is_connector() const { return _connector; };
a61af66fc99e Initial load
duke
parents:
diff changeset
211
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
212 // Loop_alignment will be set for blocks which are at the top of loops.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
213 // The block layout pass may rotate loops such that the loop head may not
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
214 // be the sequentially first block of the loop encountered in the linear
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
215 // list of blocks. If the layout pass is not run, loop alignment is set
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
216 // for each block which is the head of a loop.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
217 uint _loop_alignment;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
218 void set_loop_alignment(Block *loop_top) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
219 uint new_alignment = loop_top->compute_loop_alignment();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
220 if (new_alignment > _loop_alignment) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
221 _loop_alignment = new_alignment;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
222 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
223 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
224 uint loop_alignment() const { return _loop_alignment; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
225 bool has_loop_alignment() const { return loop_alignment() > 0; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
226
0
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // Create a new Block with given head Node.
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // Creates the (empty) predecessor arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
229 Block( Arena *a, Node *headnode )
a61af66fc99e Initial load
duke
parents:
diff changeset
230 : CFGElement(),
a61af66fc99e Initial load
duke
parents:
diff changeset
231 _nodes(a),
a61af66fc99e Initial load
duke
parents:
diff changeset
232 _succs(a),
a61af66fc99e Initial load
duke
parents:
diff changeset
233 _num_succs(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
234 _pre_order(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
235 _idom(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
236 _loop(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
237 _reg_pressure(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
238 _ihrp_index(1),
a61af66fc99e Initial load
duke
parents:
diff changeset
239 _freg_pressure(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
240 _fhrp_index(1),
a61af66fc99e Initial load
duke
parents:
diff changeset
241 _raise_LCA_mark(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
242 _raise_LCA_visited(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
243 _first_inst_size(999999),
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
244 _connector(false),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
245 _loop_alignment(0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
246 _nodes.push(headnode);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // Index of 'end' Node
a61af66fc99e Initial load
duke
parents:
diff changeset
250 uint end_idx() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // %%%%% add a proj after every goto
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // so (last->is_block_proj() != last) always, then simplify this code
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // This will not give correct end_idx for block 0 when it only contains root.
a61af66fc99e Initial load
duke
parents:
diff changeset
254 int last_idx = _nodes.size() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
255 Node *last = _nodes[last_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
256 assert(last->is_block_proj() == last || last->is_block_proj() == _nodes[last_idx - _num_succs], "");
a61af66fc99e Initial load
duke
parents:
diff changeset
257 return (last->is_block_proj() == last) ? last_idx : (last_idx - _num_succs);
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // Basic blocks have a Node which ends them. This Node determines which
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // basic block follows this one in the program flow. This Node is either an
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // IfNode, a GotoNode, a JmpNode, or a ReturnNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
263 Node *end() const { return _nodes[end_idx()]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
264
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // Add an instruction to an existing block. It must go after the head
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // instruction and before the end instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
267 void add_inst( Node *n ) { _nodes.insert(end_idx(),n); }
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // Find node in block
a61af66fc99e Initial load
duke
parents:
diff changeset
269 uint find_node( const Node *n ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Find and remove n from block list
a61af66fc99e Initial load
duke
parents:
diff changeset
271 void find_remove( const Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // Schedule a call next in the block
a61af66fc99e Initial load
duke
parents:
diff changeset
274 uint sched_call(Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // Perform basic-block local scheduling
a61af66fc99e Initial load
duke
parents:
diff changeset
277 Node *select(PhaseCFG *cfg, Node_List &worklist, int *ready_cnt, VectorSet &next_call, uint sched_slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
278 void set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs );
a61af66fc99e Initial load
duke
parents:
diff changeset
279 void needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 bool schedule_local(PhaseCFG *cfg, Matcher &m, int *ready_cnt, VectorSet &next_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // Cleanup if any code lands between a Call and his Catch
a61af66fc99e Initial load
duke
parents:
diff changeset
282 void call_catch_cleanup(Block_Array &bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // Detect implicit-null-check opportunities. Basically, find NULL checks
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // with suitable memory ops nearby. Use the memory op to do the NULL check.
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // I can generate a memory op if there is not one nearby.
a61af66fc99e Initial load
duke
parents:
diff changeset
286 void implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons);
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 // Return the empty status of a block
a61af66fc99e Initial load
duke
parents:
diff changeset
289 enum { not_empty, empty_with_goto, completely_empty };
a61af66fc99e Initial load
duke
parents:
diff changeset
290 int is_Empty() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
291
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // Forward through connectors
a61af66fc99e Initial load
duke
parents:
diff changeset
293 Block* non_connector() {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 Block* s = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
295 while (s->is_connector()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 s = s->_succs[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
298 return s;
a61af66fc99e Initial load
duke
parents:
diff changeset
299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
300
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
301 // Return true if b is a successor of this block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
302 bool has_successor(Block* b) const {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
303 for (uint i = 0; i < _num_succs; i++ ) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
304 if (non_connector_successor(i) == b) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
305 return true;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
306 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
307 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
308 return false;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
309 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
310
0
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // Successor block, after forwarding through connectors
a61af66fc99e Initial load
duke
parents:
diff changeset
312 Block* non_connector_successor(int i) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
313 return _succs[i]->non_connector();
a61af66fc99e Initial load
duke
parents:
diff changeset
314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // Examine block's code shape to predict if it is not commonly executed.
a61af66fc99e Initial load
duke
parents:
diff changeset
317 bool has_uncommon_code() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // Use frequency calculations and code shape to predict if the block
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // is uncommon.
a61af66fc99e Initial load
duke
parents:
diff changeset
321 bool is_uncommon( Block_Array &bbs ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // Debugging print of basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
325 void dump_bidx(const Block* orig) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
326 void dump_pred(const Block_Array *bbs, Block* orig) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
327 void dump_head( const Block_Array *bbs ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
328 void dump( ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
329 void dump( const Block_Array *bbs ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
331 };
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333
a61af66fc99e Initial load
duke
parents:
diff changeset
334 //------------------------------PhaseCFG---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // Build an array of Basic Block pointers, one per Node.
a61af66fc99e Initial load
duke
parents:
diff changeset
336 class PhaseCFG : public Phase {
a61af66fc99e Initial load
duke
parents:
diff changeset
337 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // Build a proper looking cfg. Return count of basic blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
339 uint build_cfg();
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // Perform DFS search.
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // Setup 'vertex' as DFS to vertex mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // Setup 'semi' as vertex to DFS mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // Set 'parent' to DFS parent.
a61af66fc99e Initial load
duke
parents:
diff changeset
345 uint DFS( Tarjan *tarjan );
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // Helper function to insert a node into a block
a61af66fc99e Initial load
duke
parents:
diff changeset
348 void schedule_node_into_block( Node *n, Block *b );
a61af66fc99e Initial load
duke
parents:
diff changeset
349
604
ec59443af135 6811267: Fix for 6809798 broke linux build
kvn
parents: 601
diff changeset
350 void replace_block_proj_ctrl( Node *n );
601
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 470
diff changeset
351
0
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // Set the basic block for pinned Nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
353 void schedule_pinned_nodes( VectorSet &visited );
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // I'll need a few machine-specific GotoNodes. Clone from this one.
a61af66fc99e Initial load
duke
parents:
diff changeset
356 MachNode *_goto;
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
359 void verify_anti_dependences(Block* LCA, Node* load) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 assert(LCA == _bbs[load->_idx], "should already be scheduled");
a61af66fc99e Initial load
duke
parents:
diff changeset
361 insert_anti_dependences(LCA, load, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
365 PhaseCFG( Arena *a, RootNode *r, Matcher &m );
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 uint _num_blocks; // Count of basic blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
368 Block_List _blocks; // List of basic blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
369 RootNode *_root; // Root of whole program
a61af66fc99e Initial load
duke
parents:
diff changeset
370 Block_Array _bbs; // Map Nodes to owning Basic Block
a61af66fc99e Initial load
duke
parents:
diff changeset
371 Block *_broot; // Basic block of root
a61af66fc99e Initial load
duke
parents:
diff changeset
372 uint _rpo_ctr;
a61af66fc99e Initial load
duke
parents:
diff changeset
373 CFGLoop* _root_loop;
673
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 605
diff changeset
374 float _outer_loop_freq; // Outmost loop frequency
0
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // Per node latency estimation, valid only during GCM
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
377 GrowableArray<uint> *_node_latency;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
380 bool _trace_opto_pipelining; // tracing flag
a61af66fc99e Initial load
duke
parents:
diff changeset
381 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
382
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 673
diff changeset
383 #ifdef ASSERT
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 673
diff changeset
384 Unique_Node_List _raw_oops;
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 673
diff changeset
385 #endif
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 673
diff changeset
386
0
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // Build dominators
a61af66fc99e Initial load
duke
parents:
diff changeset
388 void Dominators();
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // Estimate block frequencies based on IfNode probabilities
a61af66fc99e Initial load
duke
parents:
diff changeset
391 void Estimate_Block_Frequency();
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // Global Code Motion. See Click's PLDI95 paper. Place Nodes in specific
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // basic blocks; i.e. _bbs now maps _idx for all Nodes to some Block.
a61af66fc99e Initial load
duke
parents:
diff changeset
395 void GlobalCodeMotion( Matcher &m, uint unique, Node_List &proj_list );
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // Compute the (backwards) latency of a node from the uses
a61af66fc99e Initial load
duke
parents:
diff changeset
398 void latency_from_uses(Node *n);
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // Compute the (backwards) latency of a node from a single use
a61af66fc99e Initial load
duke
parents:
diff changeset
401 int latency_from_use(Node *n, const Node *def, Node *use);
a61af66fc99e Initial load
duke
parents:
diff changeset
402
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // Compute the (backwards) latency of a node from the uses of this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
404 void partial_latency_of_defs(Node *n);
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // Schedule Nodes early in their basic blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
407 bool schedule_early(VectorSet &visited, Node_List &roots);
a61af66fc99e Initial load
duke
parents:
diff changeset
408
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // For each node, find the latest block it can be scheduled into
a61af66fc99e Initial load
duke
parents:
diff changeset
410 // and then select the cheapest block between the latest and earliest
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // block to place the node.
a61af66fc99e Initial load
duke
parents:
diff changeset
412 void schedule_late(VectorSet &visited, Node_List &stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // Pick a block between early and late that is a cheaper alternative
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // to late. Helper for schedule_late.
a61af66fc99e Initial load
duke
parents:
diff changeset
416 Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // Compute the instruction global latency with a backwards walk
a61af66fc99e Initial load
duke
parents:
diff changeset
419 void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
420
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
421 // Set loop alignment
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
422 void set_loop_alignment();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
423
0
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // Remove empty basic blocks
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
425 void remove_empty();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
426 void fixup_flow();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
427 bool move_to_next(Block* bx, uint b_index);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
428 void move_to_end(Block* bx, uint b_index);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
429 void insert_goto_at(uint block_no, uint succ_no);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // Check for NeverBranch at block end. This needs to become a GOTO to the
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // true target. NeverBranch are treated as a conditional branch that always
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // goes the same direction for most of the optimizer and are used to give a
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // fake exit path to infinite loops. At this late stage they need to turn
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // into Goto's so that when you enter the infinite loop you indeed hang.
a61af66fc99e Initial load
duke
parents:
diff changeset
436 void convert_NeverBranch_to_Goto(Block *b);
a61af66fc99e Initial load
duke
parents:
diff changeset
437
a61af66fc99e Initial load
duke
parents:
diff changeset
438 CFGLoop* create_loop_tree();
a61af66fc99e Initial load
duke
parents:
diff changeset
439
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // Insert a node into a block, and update the _bbs
a61af66fc99e Initial load
duke
parents:
diff changeset
441 void insert( Block *b, uint idx, Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
442 b->_nodes.insert( idx, n );
a61af66fc99e Initial load
duke
parents:
diff changeset
443 _bbs.map( n->_idx, b );
a61af66fc99e Initial load
duke
parents:
diff changeset
444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
445
a61af66fc99e Initial load
duke
parents:
diff changeset
446 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
447 bool trace_opto_pipelining() const { return _trace_opto_pipelining; }
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // Debugging print of CFG
a61af66fc99e Initial load
duke
parents:
diff changeset
450 void dump( ) const; // CFG only
a61af66fc99e Initial load
duke
parents:
diff changeset
451 void _dump_cfg( const Node *end, VectorSet &visited ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
452 void verify() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
453 void dump_headers();
a61af66fc99e Initial load
duke
parents:
diff changeset
454 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
455 bool trace_opto_pipelining() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
456 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
457 };
a61af66fc99e Initial load
duke
parents:
diff changeset
458
a61af66fc99e Initial load
duke
parents:
diff changeset
459
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
460 //------------------------------UnionFind--------------------------------------
0
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // Map Block indices to a block-index for a cfg-cover.
a61af66fc99e Initial load
duke
parents:
diff changeset
462 // Array lookup in the optimized case.
a61af66fc99e Initial load
duke
parents:
diff changeset
463 class UnionFind : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 uint _cnt, _max;
a61af66fc99e Initial load
duke
parents:
diff changeset
465 uint* _indices;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 ReallocMark _nesting; // assertion check for reallocations
a61af66fc99e Initial load
duke
parents:
diff changeset
467 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
468 UnionFind( uint max );
a61af66fc99e Initial load
duke
parents:
diff changeset
469 void reset( uint max ); // Reset to identity map for [0..max]
a61af66fc99e Initial load
duke
parents:
diff changeset
470
a61af66fc99e Initial load
duke
parents:
diff changeset
471 uint lookup( uint nidx ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 return _indices[nidx];
a61af66fc99e Initial load
duke
parents:
diff changeset
473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
474 uint operator[] (uint nidx) const { return lookup(nidx); }
a61af66fc99e Initial load
duke
parents:
diff changeset
475
a61af66fc99e Initial load
duke
parents:
diff changeset
476 void map( uint from_idx, uint to_idx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 assert( from_idx < _cnt, "oob" );
a61af66fc99e Initial load
duke
parents:
diff changeset
478 _indices[from_idx] = to_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
480 void extend( uint from_idx, uint to_idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 uint Size() const { return _cnt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
483
a61af66fc99e Initial load
duke
parents:
diff changeset
484 uint Find( uint idx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 assert( idx < 65536, "Must fit into uint");
a61af66fc99e Initial load
duke
parents:
diff changeset
486 uint uf_idx = lookup(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
487 return (uf_idx == idx) ? uf_idx : Find_compress(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
489 uint Find_compress( uint idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
490 uint Find_const( uint idx ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
491 void Union( uint idx1, uint idx2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
492
a61af66fc99e Initial load
duke
parents:
diff changeset
493 };
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495 //----------------------------BlockProbPair---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // Ordered pair of Node*.
a61af66fc99e Initial load
duke
parents:
diff changeset
497 class BlockProbPair VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
499 Block* _target; // block target
a61af66fc99e Initial load
duke
parents:
diff changeset
500 float _prob; // probability of edge to block
a61af66fc99e Initial load
duke
parents:
diff changeset
501 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
502 BlockProbPair() : _target(NULL), _prob(0.0) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
503 BlockProbPair(Block* b, float p) : _target(b), _prob(p) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
504
a61af66fc99e Initial load
duke
parents:
diff changeset
505 Block* get_target() const { return _target; }
a61af66fc99e Initial load
duke
parents:
diff changeset
506 float get_prob() const { return _prob; }
a61af66fc99e Initial load
duke
parents:
diff changeset
507 };
a61af66fc99e Initial load
duke
parents:
diff changeset
508
a61af66fc99e Initial load
duke
parents:
diff changeset
509 //------------------------------CFGLoop-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
510 class CFGLoop : public CFGElement {
a61af66fc99e Initial load
duke
parents:
diff changeset
511 int _id;
a61af66fc99e Initial load
duke
parents:
diff changeset
512 int _depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
513 CFGLoop *_parent; // root of loop tree is the method level "pseudo" loop, it's parent is null
a61af66fc99e Initial load
duke
parents:
diff changeset
514 CFGLoop *_sibling; // null terminated list
a61af66fc99e Initial load
duke
parents:
diff changeset
515 CFGLoop *_child; // first child, use child's sibling to visit all immediately nested loops
a61af66fc99e Initial load
duke
parents:
diff changeset
516 GrowableArray<CFGElement*> _members; // list of members of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
517 GrowableArray<BlockProbPair> _exits; // list of successor blocks and their probabilities
a61af66fc99e Initial load
duke
parents:
diff changeset
518 float _exit_prob; // probability any loop exit is taken on a single loop iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
519 void update_succ_freq(Block* b, float freq);
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
522 CFGLoop(int id) :
a61af66fc99e Initial load
duke
parents:
diff changeset
523 CFGElement(),
a61af66fc99e Initial load
duke
parents:
diff changeset
524 _id(id),
a61af66fc99e Initial load
duke
parents:
diff changeset
525 _depth(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
526 _parent(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
527 _sibling(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
528 _child(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
529 _exit_prob(1.0f) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
530 CFGLoop* parent() { return _parent; }
a61af66fc99e Initial load
duke
parents:
diff changeset
531 void push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
532 void add_member(CFGElement *s) { _members.push(s); }
a61af66fc99e Initial load
duke
parents:
diff changeset
533 void add_nested_loop(CFGLoop* cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
534 Block* head() {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 assert(_members.at(0)->is_block(), "head must be a block");
a61af66fc99e Initial load
duke
parents:
diff changeset
536 Block* hd = _members.at(0)->as_Block();
a61af66fc99e Initial load
duke
parents:
diff changeset
537 assert(hd->_loop == this, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
538 assert(hd->head()->is_Loop(), "must begin with loop head node");
a61af66fc99e Initial load
duke
parents:
diff changeset
539 return hd;
a61af66fc99e Initial load
duke
parents:
diff changeset
540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
541 Block* backedge_block(); // Return the block on the backedge of the loop (else NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
542 void compute_loop_depth(int depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
543 void compute_freq(); // compute frequency with loop assuming head freq 1.0f
a61af66fc99e Initial load
duke
parents:
diff changeset
544 void scale_freq(); // scale frequency by loop trip count (including outer loops)
673
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 605
diff changeset
545 float outer_loop_freq() const; // frequency of outer loop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
546 bool in_loop_nest(Block* b);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 float trip_count() const { return 1.0f / _exit_prob; }
a61af66fc99e Initial load
duke
parents:
diff changeset
548 virtual bool is_loop() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
549 int id() { return _id; }
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
552 void dump( ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
553 void dump_tree() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
554 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
555 };
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
556
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
557
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
558 //----------------------------------CFGEdge------------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
559 // A edge between two basic blocks that will be embodied by a branch or a
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
560 // fall-through.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
561 class CFGEdge : public ResourceObj {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
562 private:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
563 Block * _from; // Source basic block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
564 Block * _to; // Destination basic block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
565 float _freq; // Execution frequency (estimate)
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
566 int _state;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
567 bool _infrequent;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
568 int _from_pct;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
569 int _to_pct;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
570
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
571 // Private accessors
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
572 int from_pct() const { return _from_pct; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
573 int to_pct() const { return _to_pct; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
574 int from_infrequent() const { return from_pct() < BlockLayoutMinDiamondPercentage; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
575 int to_infrequent() const { return to_pct() < BlockLayoutMinDiamondPercentage; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
576
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
577 public:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
578 enum {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
579 open, // initial edge state; unprocessed
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
580 connected, // edge used to connect two traces together
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
581 interior // edge is interior to trace (could be backedge)
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
582 };
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
583
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
584 CFGEdge(Block *from, Block *to, float freq, int from_pct, int to_pct) :
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
585 _from(from), _to(to), _freq(freq),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
586 _from_pct(from_pct), _to_pct(to_pct), _state(open) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
587 _infrequent = from_infrequent() || to_infrequent();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
588 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
589
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
590 float freq() const { return _freq; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
591 Block* from() const { return _from; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
592 Block* to () const { return _to; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
593 int infrequent() const { return _infrequent; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
594 int state() const { return _state; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
595
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
596 void set_state(int state) { _state = state; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
597
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
598 #ifndef PRODUCT
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
599 void dump( ) const;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
600 #endif
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
601 };
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
602
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
603
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
604 //-----------------------------------Trace-------------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
605 // An ordered list of basic blocks.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
606 class Trace : public ResourceObj {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
607 private:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
608 uint _id; // Unique Trace id (derived from initial block)
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
609 Block ** _next_list; // Array mapping index to next block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
610 Block ** _prev_list; // Array mapping index to previous block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
611 Block * _first; // First block in the trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
612 Block * _last; // Last block in the trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
613
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
614 // Return the block that follows "b" in the trace.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
615 Block * next(Block *b) const { return _next_list[b->_pre_order]; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
616 void set_next(Block *b, Block *n) const { _next_list[b->_pre_order] = n; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
617
605
98cb887364d3 6810672: Comment typos
twisti
parents: 604
diff changeset
618 // Return the block that precedes "b" in the trace.
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
619 Block * prev(Block *b) const { return _prev_list[b->_pre_order]; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
620 void set_prev(Block *b, Block *p) const { _prev_list[b->_pre_order] = p; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
621
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
622 // We've discovered a loop in this trace. Reset last to be "b", and first as
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
623 // the block following "b
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
624 void break_loop_after(Block *b) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
625 _last = b;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
626 _first = next(b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
627 set_prev(_first, NULL);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
628 set_next(_last, NULL);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
629 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
630
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
631 public:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
632
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
633 Trace(Block *b, Block **next_list, Block **prev_list) :
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
634 _first(b),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
635 _last(b),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
636 _next_list(next_list),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
637 _prev_list(prev_list),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
638 _id(b->_pre_order) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
639 set_next(b, NULL);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
640 set_prev(b, NULL);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
641 };
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
642
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
643 // Return the id number
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
644 uint id() const { return _id; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
645 void set_id(uint id) { _id = id; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
646
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
647 // Return the first block in the trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
648 Block * first_block() const { return _first; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
649
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
650 // Return the last block in the trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
651 Block * last_block() const { return _last; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
652
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
653 // Insert a trace in the middle of this one after b
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
654 void insert_after(Block *b, Trace *tr) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
655 set_next(tr->last_block(), next(b));
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
656 if (next(b) != NULL) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
657 set_prev(next(b), tr->last_block());
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
658 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
659
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
660 set_next(b, tr->first_block());
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
661 set_prev(tr->first_block(), b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
662
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
663 if (b == _last) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
664 _last = tr->last_block();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
665 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
666 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
667
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
668 void insert_before(Block *b, Trace *tr) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
669 Block *p = prev(b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
670 assert(p != NULL, "use append instead");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
671 insert_after(p, tr);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
672 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
673
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
674 // Append another trace to this one.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
675 void append(Trace *tr) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
676 insert_after(_last, tr);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
677 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
678
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
679 // Append a block at the end of this trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
680 void append(Block *b) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
681 set_next(_last, b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
682 set_prev(b, _last);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
683 _last = b;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
684 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
685
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
686 // Adjust the the blocks in this trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
687 void fixup_blocks(PhaseCFG &cfg);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
688 bool backedge(CFGEdge *e);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
689
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
690 #ifndef PRODUCT
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
691 void dump( ) const;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
692 #endif
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
693 };
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
694
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
695 //------------------------------PhaseBlockLayout-------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
696 // Rearrange blocks into some canonical order, based on edges and their frequencies
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
697 class PhaseBlockLayout : public Phase {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
698 PhaseCFG &_cfg; // Control flow graph
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
699
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
700 GrowableArray<CFGEdge *> *edges;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
701 Trace **traces;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
702 Block **next;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
703 Block **prev;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
704 UnionFind *uf;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
705
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
706 // Given a block, find its encompassing Trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
707 Trace * trace(Block *b) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
708 return traces[uf->Find_compress(b->_pre_order)];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
709 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
710 public:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
711 PhaseBlockLayout(PhaseCFG &cfg);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
712
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
713 void find_edges();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
714 void grow_traces();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
715 void merge_traces(bool loose_connections);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
716 void reorder_traces(int count);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
717 void union_traces(Trace* from, Trace* to);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
718 };