annotate src/share/vm/opto/block.hpp @ 3992:d1bdeef3e3e2

7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76 Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing. Reviewed-by: tonyp, brutisso, ysr
author johnc
date Wed, 12 Oct 2011 10:25:51 -0700
parents f6f3bb0ee072
children f03a3c8bd5e5
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
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // Schedule a call next in the block
a61af66fc99e Initial load
duke
parents:
diff changeset
285 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
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // Perform basic-block local scheduling
a61af66fc99e Initial load
duke
parents:
diff changeset
288 Node *select(PhaseCFG *cfg, Node_List &worklist, int *ready_cnt, VectorSet &next_call, uint sched_slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
289 void set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs );
a61af66fc99e Initial load
duke
parents:
diff changeset
290 void needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
291 bool schedule_local(PhaseCFG *cfg, Matcher &m, int *ready_cnt, VectorSet &next_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // Cleanup if any code lands between a Call and his Catch
a61af66fc99e Initial load
duke
parents:
diff changeset
293 void call_catch_cleanup(Block_Array &bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // Detect implicit-null-check opportunities. Basically, find NULL checks
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // with suitable memory ops nearby. Use the memory op to do the NULL check.
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // I can generate a memory op if there is not one nearby.
a61af66fc99e Initial load
duke
parents:
diff changeset
297 void implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons);
a61af66fc99e Initial load
duke
parents:
diff changeset
298
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // Return the empty status of a block
a61af66fc99e Initial load
duke
parents:
diff changeset
300 enum { not_empty, empty_with_goto, completely_empty };
a61af66fc99e Initial load
duke
parents:
diff changeset
301 int is_Empty() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // Forward through connectors
a61af66fc99e Initial load
duke
parents:
diff changeset
304 Block* non_connector() {
a61af66fc99e Initial load
duke
parents:
diff changeset
305 Block* s = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
306 while (s->is_connector()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 s = s->_succs[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
309 return s;
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
312 // Return true if b is a successor of this block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
313 bool has_successor(Block* b) const {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
314 for (uint i = 0; i < _num_succs; i++ ) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
315 if (non_connector_successor(i) == b) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
316 return true;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
317 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
318 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
319 return false;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
320 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
321
0
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // Successor block, after forwarding through connectors
a61af66fc99e Initial load
duke
parents:
diff changeset
323 Block* non_connector_successor(int i) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
324 return _succs[i]->non_connector();
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // Examine block's code shape to predict if it is not commonly executed.
a61af66fc99e Initial load
duke
parents:
diff changeset
328 bool has_uncommon_code() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
329
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // Use frequency calculations and code shape to predict if the block
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // is uncommon.
a61af66fc99e Initial load
duke
parents:
diff changeset
332 bool is_uncommon( Block_Array &bbs ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
333
a61af66fc99e Initial load
duke
parents:
diff changeset
334 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // Debugging print of basic block
3851
95134e034042 7063629: use cbcond in C2 generated code on T4
kvn
parents: 1972
diff changeset
336 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
337 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
338 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
339 void dump() const;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
340 void dump( const Block_Array *bbs ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
341 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
342 };
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345 //------------------------------PhaseCFG---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // Build an array of Basic Block pointers, one per Node.
a61af66fc99e Initial load
duke
parents:
diff changeset
347 class PhaseCFG : public Phase {
3939
f6f3bb0ee072 7088955: add C2 IR support to the SA
never
parents: 3851
diff changeset
348 friend class VMStructs;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
349 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // Build a proper looking cfg. Return count of basic blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
351 uint build_cfg();
a61af66fc99e Initial load
duke
parents:
diff changeset
352
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // Perform DFS search.
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // Setup 'vertex' as DFS to vertex mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // Setup 'semi' as vertex to DFS mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // Set 'parent' to DFS parent.
a61af66fc99e Initial load
duke
parents:
diff changeset
357 uint DFS( Tarjan *tarjan );
a61af66fc99e Initial load
duke
parents:
diff changeset
358
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // Helper function to insert a node into a block
a61af66fc99e Initial load
duke
parents:
diff changeset
360 void schedule_node_into_block( Node *n, Block *b );
a61af66fc99e Initial load
duke
parents:
diff changeset
361
604
ec59443af135 6811267: Fix for 6809798 broke linux build
kvn
parents: 601
diff changeset
362 void replace_block_proj_ctrl( Node *n );
601
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 470
diff changeset
363
0
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // Set the basic block for pinned Nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
365 void schedule_pinned_nodes( VectorSet &visited );
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // I'll need a few machine-specific GotoNodes. Clone from this one.
a61af66fc99e Initial load
duke
parents:
diff changeset
368 MachNode *_goto;
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
371 void verify_anti_dependences(Block* LCA, Node* load) {
a61af66fc99e Initial load
duke
parents:
diff changeset
372 assert(LCA == _bbs[load->_idx], "should already be scheduled");
a61af66fc99e Initial load
duke
parents:
diff changeset
373 insert_anti_dependences(LCA, load, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
377 PhaseCFG( Arena *a, RootNode *r, Matcher &m );
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 uint _num_blocks; // Count of basic blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
380 Block_List _blocks; // List of basic blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
381 RootNode *_root; // Root of whole program
a61af66fc99e Initial load
duke
parents:
diff changeset
382 Block_Array _bbs; // Map Nodes to owning Basic Block
a61af66fc99e Initial load
duke
parents:
diff changeset
383 Block *_broot; // Basic block of root
a61af66fc99e Initial load
duke
parents:
diff changeset
384 uint _rpo_ctr;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 CFGLoop* _root_loop;
673
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 605
diff changeset
386 float _outer_loop_freq; // Outmost loop frequency
0
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // Per node latency estimation, valid only during GCM
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
389 GrowableArray<uint> *_node_latency;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
392 bool _trace_opto_pipelining; // tracing flag
a61af66fc99e Initial load
duke
parents:
diff changeset
393 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
394
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 673
diff changeset
395 #ifdef ASSERT
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 673
diff changeset
396 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
397 #endif
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 673
diff changeset
398
0
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // Build dominators
a61af66fc99e Initial load
duke
parents:
diff changeset
400 void Dominators();
a61af66fc99e Initial load
duke
parents:
diff changeset
401
a61af66fc99e Initial load
duke
parents:
diff changeset
402 // Estimate block frequencies based on IfNode probabilities
a61af66fc99e Initial load
duke
parents:
diff changeset
403 void Estimate_Block_Frequency();
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // Global Code Motion. See Click's PLDI95 paper. Place Nodes in specific
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // basic blocks; i.e. _bbs now maps _idx for all Nodes to some Block.
a61af66fc99e Initial load
duke
parents:
diff changeset
407 void GlobalCodeMotion( Matcher &m, uint unique, Node_List &proj_list );
a61af66fc99e Initial load
duke
parents:
diff changeset
408
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // Compute the (backwards) latency of a node from the uses
a61af66fc99e Initial load
duke
parents:
diff changeset
410 void latency_from_uses(Node *n);
a61af66fc99e Initial load
duke
parents:
diff changeset
411
a61af66fc99e Initial load
duke
parents:
diff changeset
412 // Compute the (backwards) latency of a node from a single use
a61af66fc99e Initial load
duke
parents:
diff changeset
413 int latency_from_use(Node *n, const Node *def, Node *use);
a61af66fc99e Initial load
duke
parents:
diff changeset
414
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // Compute the (backwards) latency of a node from the uses of this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
416 void partial_latency_of_defs(Node *n);
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // Schedule Nodes early in their basic blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
419 bool schedule_early(VectorSet &visited, Node_List &roots);
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // For each node, find the latest block it can be scheduled into
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // and then select the cheapest block between the latest and earliest
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // block to place the node.
a61af66fc99e Initial load
duke
parents:
diff changeset
424 void schedule_late(VectorSet &visited, Node_List &stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
425
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // Pick a block between early and late that is a cheaper alternative
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // to late. Helper for schedule_late.
a61af66fc99e Initial load
duke
parents:
diff changeset
428 Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // Compute the instruction global latency with a backwards walk
a61af66fc99e Initial load
duke
parents:
diff changeset
431 void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
432
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
433 // Set loop alignment
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
434 void set_loop_alignment();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
435
0
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // Remove empty basic blocks
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
437 void remove_empty();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
438 void fixup_flow();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
439 bool move_to_next(Block* bx, uint b_index);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
440 void move_to_end(Block* bx, uint b_index);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
441 void insert_goto_at(uint block_no, uint succ_no);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // Check for NeverBranch at block end. This needs to become a GOTO to the
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // true target. NeverBranch are treated as a conditional branch that always
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // goes the same direction for most of the optimizer and are used to give a
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // fake exit path to infinite loops. At this late stage they need to turn
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // into Goto's so that when you enter the infinite loop you indeed hang.
a61af66fc99e Initial load
duke
parents:
diff changeset
448 void convert_NeverBranch_to_Goto(Block *b);
a61af66fc99e Initial load
duke
parents:
diff changeset
449
a61af66fc99e Initial load
duke
parents:
diff changeset
450 CFGLoop* create_loop_tree();
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // Insert a node into a block, and update the _bbs
a61af66fc99e Initial load
duke
parents:
diff changeset
453 void insert( Block *b, uint idx, Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 b->_nodes.insert( idx, n );
a61af66fc99e Initial load
duke
parents:
diff changeset
455 _bbs.map( n->_idx, b );
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457
a61af66fc99e Initial load
duke
parents:
diff changeset
458 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
459 bool trace_opto_pipelining() const { return _trace_opto_pipelining; }
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // Debugging print of CFG
a61af66fc99e Initial load
duke
parents:
diff changeset
462 void dump( ) const; // CFG only
a61af66fc99e Initial load
duke
parents:
diff changeset
463 void _dump_cfg( const Node *end, VectorSet &visited ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
464 void verify() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
465 void dump_headers();
a61af66fc99e Initial load
duke
parents:
diff changeset
466 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
467 bool trace_opto_pipelining() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
468 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
469 };
a61af66fc99e Initial load
duke
parents:
diff changeset
470
a61af66fc99e Initial load
duke
parents:
diff changeset
471
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
472 //------------------------------UnionFind--------------------------------------
0
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // Map Block indices to a block-index for a cfg-cover.
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // Array lookup in the optimized case.
a61af66fc99e Initial load
duke
parents:
diff changeset
475 class UnionFind : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 uint _cnt, _max;
a61af66fc99e Initial load
duke
parents:
diff changeset
477 uint* _indices;
a61af66fc99e Initial load
duke
parents:
diff changeset
478 ReallocMark _nesting; // assertion check for reallocations
a61af66fc99e Initial load
duke
parents:
diff changeset
479 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
480 UnionFind( uint max );
a61af66fc99e Initial load
duke
parents:
diff changeset
481 void reset( uint max ); // Reset to identity map for [0..max]
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 uint lookup( uint nidx ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 return _indices[nidx];
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486 uint operator[] (uint nidx) const { return lookup(nidx); }
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 void map( uint from_idx, uint to_idx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
489 assert( from_idx < _cnt, "oob" );
a61af66fc99e Initial load
duke
parents:
diff changeset
490 _indices[from_idx] = to_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
492 void extend( uint from_idx, uint to_idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
493
a61af66fc99e Initial load
duke
parents:
diff changeset
494 uint Size() const { return _cnt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
495
a61af66fc99e Initial load
duke
parents:
diff changeset
496 uint Find( uint idx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 assert( idx < 65536, "Must fit into uint");
a61af66fc99e Initial load
duke
parents:
diff changeset
498 uint uf_idx = lookup(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
499 return (uf_idx == idx) ? uf_idx : Find_compress(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501 uint Find_compress( uint idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
502 uint Find_const( uint idx ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
503 void Union( uint idx1, uint idx2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
504
a61af66fc99e Initial load
duke
parents:
diff changeset
505 };
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 //----------------------------BlockProbPair---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // Ordered pair of Node*.
a61af66fc99e Initial load
duke
parents:
diff changeset
509 class BlockProbPair VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
510 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
511 Block* _target; // block target
a61af66fc99e Initial load
duke
parents:
diff changeset
512 float _prob; // probability of edge to block
a61af66fc99e Initial load
duke
parents:
diff changeset
513 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
514 BlockProbPair() : _target(NULL), _prob(0.0) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
515 BlockProbPair(Block* b, float p) : _target(b), _prob(p) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
516
a61af66fc99e Initial load
duke
parents:
diff changeset
517 Block* get_target() const { return _target; }
a61af66fc99e Initial load
duke
parents:
diff changeset
518 float get_prob() const { return _prob; }
a61af66fc99e Initial load
duke
parents:
diff changeset
519 };
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 //------------------------------CFGLoop-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
522 class CFGLoop : public CFGElement {
3939
f6f3bb0ee072 7088955: add C2 IR support to the SA
never
parents: 3851
diff changeset
523 friend class VMStructs;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
524 int _id;
a61af66fc99e Initial load
duke
parents:
diff changeset
525 int _depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
526 CFGLoop *_parent; // root of loop tree is the method level "pseudo" loop, it's parent is null
a61af66fc99e Initial load
duke
parents:
diff changeset
527 CFGLoop *_sibling; // null terminated list
a61af66fc99e Initial load
duke
parents:
diff changeset
528 CFGLoop *_child; // first child, use child's sibling to visit all immediately nested loops
a61af66fc99e Initial load
duke
parents:
diff changeset
529 GrowableArray<CFGElement*> _members; // list of members of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
530 GrowableArray<BlockProbPair> _exits; // list of successor blocks and their probabilities
a61af66fc99e Initial load
duke
parents:
diff changeset
531 float _exit_prob; // probability any loop exit is taken on a single loop iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
532 void update_succ_freq(Block* b, float freq);
a61af66fc99e Initial load
duke
parents:
diff changeset
533
a61af66fc99e Initial load
duke
parents:
diff changeset
534 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
535 CFGLoop(int id) :
a61af66fc99e Initial load
duke
parents:
diff changeset
536 CFGElement(),
a61af66fc99e Initial load
duke
parents:
diff changeset
537 _id(id),
a61af66fc99e Initial load
duke
parents:
diff changeset
538 _depth(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
539 _parent(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
540 _sibling(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
541 _child(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
542 _exit_prob(1.0f) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
543 CFGLoop* parent() { return _parent; }
a61af66fc99e Initial load
duke
parents:
diff changeset
544 void push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
545 void add_member(CFGElement *s) { _members.push(s); }
a61af66fc99e Initial load
duke
parents:
diff changeset
546 void add_nested_loop(CFGLoop* cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 Block* head() {
a61af66fc99e Initial load
duke
parents:
diff changeset
548 assert(_members.at(0)->is_block(), "head must be a block");
a61af66fc99e Initial load
duke
parents:
diff changeset
549 Block* hd = _members.at(0)->as_Block();
a61af66fc99e Initial load
duke
parents:
diff changeset
550 assert(hd->_loop == this, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
551 assert(hd->head()->is_Loop(), "must begin with loop head node");
a61af66fc99e Initial load
duke
parents:
diff changeset
552 return hd;
a61af66fc99e Initial load
duke
parents:
diff changeset
553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
554 Block* backedge_block(); // Return the block on the backedge of the loop (else NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
555 void compute_loop_depth(int depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
556 void compute_freq(); // compute frequency with loop assuming head freq 1.0f
a61af66fc99e Initial load
duke
parents:
diff changeset
557 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
558 float outer_loop_freq() const; // frequency of outer loop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
559 bool in_loop_nest(Block* b);
a61af66fc99e Initial load
duke
parents:
diff changeset
560 float trip_count() const { return 1.0f / _exit_prob; }
a61af66fc99e Initial load
duke
parents:
diff changeset
561 virtual bool is_loop() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
562 int id() { return _id; }
a61af66fc99e Initial load
duke
parents:
diff changeset
563
a61af66fc99e Initial load
duke
parents:
diff changeset
564 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
565 void dump( ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
566 void dump_tree() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
567 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
568 };
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
569
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
570
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
571 //----------------------------------CFGEdge------------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
572 // 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
573 // fall-through.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
574 class CFGEdge : public ResourceObj {
3939
f6f3bb0ee072 7088955: add C2 IR support to the SA
never
parents: 3851
diff changeset
575 friend class VMStructs;
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
576 private:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
577 Block * _from; // Source basic block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
578 Block * _to; // Destination basic block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
579 float _freq; // Execution frequency (estimate)
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
580 int _state;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
581 bool _infrequent;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
582 int _from_pct;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
583 int _to_pct;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
584
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
585 // Private accessors
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
586 int from_pct() const { return _from_pct; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
587 int to_pct() const { return _to_pct; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
588 int from_infrequent() const { return from_pct() < BlockLayoutMinDiamondPercentage; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
589 int to_infrequent() const { return to_pct() < BlockLayoutMinDiamondPercentage; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
590
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
591 public:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
592 enum {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
593 open, // initial edge state; unprocessed
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
594 connected, // edge used to connect two traces together
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
595 interior // edge is interior to trace (could be backedge)
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
596 };
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
597
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
598 CFGEdge(Block *from, Block *to, float freq, int from_pct, int to_pct) :
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
599 _from(from), _to(to), _freq(freq),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
600 _from_pct(from_pct), _to_pct(to_pct), _state(open) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
601 _infrequent = from_infrequent() || to_infrequent();
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 float freq() const { return _freq; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
605 Block* from() const { return _from; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
606 Block* to () const { return _to; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
607 int infrequent() const { return _infrequent; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
608 int state() const { return _state; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
609
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
610 void set_state(int state) { _state = 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 #ifndef PRODUCT
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
613 void dump( ) const;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
614 #endif
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
615 };
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
616
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
617
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
618 //-----------------------------------Trace-------------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
619 // An ordered list of basic blocks.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
620 class Trace : public ResourceObj {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
621 private:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
622 uint _id; // Unique Trace id (derived from initial block)
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
623 Block ** _next_list; // Array mapping index to next block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
624 Block ** _prev_list; // Array mapping index to previous block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
625 Block * _first; // First block in the trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
626 Block * _last; // Last block in the trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
627
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
628 // Return the block that follows "b" in the trace.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
629 Block * next(Block *b) const { return _next_list[b->_pre_order]; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
630 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
631
605
98cb887364d3 6810672: Comment typos
twisti
parents: 604
diff changeset
632 // Return the block that precedes "b" in the trace.
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
633 Block * prev(Block *b) const { return _prev_list[b->_pre_order]; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
634 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
635
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
636 // 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
637 // the block following "b
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
638 void break_loop_after(Block *b) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
639 _last = b;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
640 _first = next(b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
641 set_prev(_first, NULL);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
642 set_next(_last, NULL);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
643 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
644
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
645 public:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
646
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
647 Trace(Block *b, Block **next_list, Block **prev_list) :
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
648 _first(b),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
649 _last(b),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
650 _next_list(next_list),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
651 _prev_list(prev_list),
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
652 _id(b->_pre_order) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
653 set_next(b, NULL);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
654 set_prev(b, NULL);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
655 };
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
656
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
657 // Return the id number
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
658 uint id() const { return _id; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
659 void set_id(uint id) { _id = id; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
660
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
661 // Return the first block in the trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
662 Block * first_block() const { return _first; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
663
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
664 // Return the last block in the trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
665 Block * last_block() const { return _last; }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
666
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
667 // Insert a trace in the middle of this one after b
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
668 void insert_after(Block *b, Trace *tr) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
669 set_next(tr->last_block(), next(b));
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
670 if (next(b) != NULL) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
671 set_prev(next(b), tr->last_block());
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 set_next(b, tr->first_block());
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
675 set_prev(tr->first_block(), b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
676
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
677 if (b == _last) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
678 _last = tr->last_block();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
679 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
680 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
681
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
682 void insert_before(Block *b, Trace *tr) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
683 Block *p = prev(b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
684 assert(p != NULL, "use append instead");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
685 insert_after(p, tr);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
686 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
687
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
688 // Append another trace to this one.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
689 void append(Trace *tr) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
690 insert_after(_last, tr);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
691 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
692
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
693 // Append a block at the end of this trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
694 void append(Block *b) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
695 set_next(_last, b);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
696 set_prev(b, _last);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
697 _last = b;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
698 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
699
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
700 // Adjust the the blocks in this trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
701 void fixup_blocks(PhaseCFG &cfg);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
702 bool backedge(CFGEdge *e);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
703
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
704 #ifndef PRODUCT
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
705 void dump( ) const;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
706 #endif
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
707 };
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
708
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
709 //------------------------------PhaseBlockLayout-------------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
710 // Rearrange blocks into some canonical order, based on edges and their frequencies
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
711 class PhaseBlockLayout : public Phase {
3939
f6f3bb0ee072 7088955: add C2 IR support to the SA
never
parents: 3851
diff changeset
712 friend class VMStructs;
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
713 PhaseCFG &_cfg; // Control flow graph
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
714
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
715 GrowableArray<CFGEdge *> *edges;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
716 Trace **traces;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
717 Block **next;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
718 Block **prev;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
719 UnionFind *uf;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
720
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
721 // Given a block, find its encompassing Trace
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
722 Trace * trace(Block *b) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
723 return traces[uf->Find_compress(b->_pre_order)];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
724 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
725 public:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
726 PhaseBlockLayout(PhaseCFG &cfg);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
727
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
728 void find_edges();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
729 void grow_traces();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
730 void merge_traces(bool loose_connections);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
731 void reorder_traces(int count);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
732 void union_traces(Trace* from, Trace* to);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 0
diff changeset
733 };
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
734
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
735 #endif // SHARE_VM_OPTO_BLOCK_HPP