annotate src/share/vm/opto/block.hpp @ 4710:41406797186b

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