annotate src/share/vm/opto/gcm.cpp @ 1941:79d04223b8a5

Added caching for resolved types and resolved fields. This is crucial, because the local load elimination will lead to wrong results, if field equality (of two RiField objects with the same object and the same RiType) is not given. The caching makes sure that the default equals implementation is sufficient.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Tue, 28 Dec 2010 18:33:26 +0100
parents 0e35fa8ebccd
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 833
diff changeset
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 833
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 833
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: 833
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // Portions of code courtesy of Clifford Click
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // Optimization - Graph Style
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
30 #include "incls/_gcm.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
31
552
011517bbcd7b 6784930: server jvm fails with assert(!n->is_SpillCopy(),"")
kvn
parents: 418
diff changeset
32 // To avoid float value underflow
011517bbcd7b 6784930: server jvm fails with assert(!n->is_SpillCopy(),"")
kvn
parents: 418
diff changeset
33 #define MIN_BLOCK_FREQUENCY 1.e-35f
011517bbcd7b 6784930: server jvm fails with assert(!n->is_SpillCopy(),"")
kvn
parents: 418
diff changeset
34
0
a61af66fc99e Initial load
duke
parents:
diff changeset
35 //----------------------------schedule_node_into_block-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // Insert node n into block b. Look for projections of n and make sure they
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // are in b also.
a61af66fc99e Initial load
duke
parents:
diff changeset
38 void PhaseCFG::schedule_node_into_block( Node *n, Block *b ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // Set basic block of n, Add n to b,
a61af66fc99e Initial load
duke
parents:
diff changeset
40 _bbs.map(n->_idx, b);
a61af66fc99e Initial load
duke
parents:
diff changeset
41 b->add_inst(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // After Matching, nearly any old Node may have projections trailing it.
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // These are usually machine-dependent flags. In any case, they might
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // float to another block below this one. Move them up.
a61af66fc99e Initial load
duke
parents:
diff changeset
46 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 Node* use = n->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
48 if (use->is_Proj()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
49 Block* buse = _bbs[use->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
50 if (buse != b) { // In wrong block?
a61af66fc99e Initial load
duke
parents:
diff changeset
51 if (buse != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
52 buse->find_remove(use); // Remove from wrong block
a61af66fc99e Initial load
duke
parents:
diff changeset
53 _bbs.map(use->_idx, b); // Re-insert in this block
a61af66fc99e Initial load
duke
parents:
diff changeset
54 b->add_inst(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
55 }
a61af66fc99e Initial load
duke
parents:
diff changeset
56 }
a61af66fc99e Initial load
duke
parents:
diff changeset
57 }
a61af66fc99e Initial load
duke
parents:
diff changeset
58 }
a61af66fc99e Initial load
duke
parents:
diff changeset
59
601
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
60 //----------------------------replace_block_proj_ctrl-------------------------
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
61 // Nodes that have is_block_proj() nodes as their control need to use
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
62 // the appropriate Region for their actual block as their control since
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
63 // the projection will be in a predecessor block.
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
64 void PhaseCFG::replace_block_proj_ctrl( Node *n ) {
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
65 const Node *in0 = n->in(0);
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
66 assert(in0 != NULL, "Only control-dependent");
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
67 const Node *p = in0->is_block_proj();
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
68 if (p != NULL && p != n) { // Control from a block projection?
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
69 assert(!n->pinned() || n->is_SafePointScalarObject(), "only SafePointScalarObject pinned node is expected here");
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
70 // Find trailing Region
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
71 Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
72 uint j = 0;
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
73 if (pb->_num_succs != 1) { // More then 1 successor?
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
74 // Search for successor
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
75 uint max = pb->_nodes.size();
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
76 assert( max > 1, "" );
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
77 uint start = max - pb->_num_succs;
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
78 // Find which output path belongs to projection
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
79 for (j = start; j < max; j++) {
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
80 if( pb->_nodes[j] == in0 )
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
81 break;
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
82 }
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
83 assert( j < max, "must find" );
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
84 // Change control to match head of successor basic block
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
85 j -= start;
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
86 }
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
87 n->set_req(0, pb->_succs[j]->head());
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
88 }
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
89 }
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
90
0
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 //------------------------------schedule_pinned_nodes--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // Set the basic block for Nodes pinned into blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
94 void PhaseCFG::schedule_pinned_nodes( VectorSet &visited ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // Allocate node stack of size C->unique()+8 to avoid frequent realloc
a61af66fc99e Initial load
duke
parents:
diff changeset
96 GrowableArray <Node *> spstack(C->unique()+8);
a61af66fc99e Initial load
duke
parents:
diff changeset
97 spstack.push(_root);
a61af66fc99e Initial load
duke
parents:
diff changeset
98 while ( spstack.is_nonempty() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 Node *n = spstack.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
100 if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited
a61af66fc99e Initial load
duke
parents:
diff changeset
101 if( n->pinned() && !_bbs.lookup(n->_idx) ) { // Pinned? Nail it down!
601
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
102 assert( n->in(0), "pinned Node must have Control" );
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
103 // Before setting block replace block_proj control edge
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
104 replace_block_proj_ctrl(n);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
105 Node *input = n->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
106 while( !input->is_block_start() )
a61af66fc99e Initial load
duke
parents:
diff changeset
107 input = input->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
108 Block *b = _bbs[input->_idx]; // Basic block of controlling input
a61af66fc99e Initial load
duke
parents:
diff changeset
109 schedule_node_into_block(n, b);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111 for( int i = n->req() - 1; i >= 0; --i ) { // For all inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
112 if( n->in(i) != NULL )
a61af66fc99e Initial load
duke
parents:
diff changeset
113 spstack.push(n->in(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118
a61af66fc99e Initial load
duke
parents:
diff changeset
119 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // Assert that new input b2 is dominated by all previous inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // Check this by by seeing that it is dominated by b1, the deepest
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // input observed until b2.
a61af66fc99e Initial load
duke
parents:
diff changeset
123 static void assert_dom(Block* b1, Block* b2, Node* n, Block_Array &bbs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 if (b1 == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
125 assert(b1->_dom_depth < b2->_dom_depth, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
126 Block* tmp = b2;
a61af66fc99e Initial load
duke
parents:
diff changeset
127 while (tmp != b1 && tmp != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
128 tmp = tmp->_idom;
a61af66fc99e Initial load
duke
parents:
diff changeset
129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
130 if (tmp != b1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // Detected an unschedulable graph. Print some nice stuff and die.
a61af66fc99e Initial load
duke
parents:
diff changeset
132 tty->print_cr("!!! Unschedulable graph !!!");
a61af66fc99e Initial load
duke
parents:
diff changeset
133 for (uint j=0; j<n->len(); j++) { // For all inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
134 Node* inn = n->in(j); // Get input
a61af66fc99e Initial load
duke
parents:
diff changeset
135 if (inn == NULL) continue; // Ignore NULL, missing inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
136 Block* inb = bbs[inn->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
137 tty->print("B%d idom=B%d depth=%2d ",inb->_pre_order,
a61af66fc99e Initial load
duke
parents:
diff changeset
138 inb->_idom ? inb->_idom->_pre_order : 0, inb->_dom_depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
139 inn->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141 tty->print("Failing node: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
142 n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
143 assert(false, "unscheduable graph");
a61af66fc99e Initial load
duke
parents:
diff changeset
144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
146 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 static Block* find_deepest_input(Node* n, Block_Array &bbs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // Find the last input dominated by all other inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
150 Block* deepb = NULL; // Deepest block so far
a61af66fc99e Initial load
duke
parents:
diff changeset
151 int deepb_dom_depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 for (uint k = 0; k < n->len(); k++) { // For all inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
153 Node* inn = n->in(k); // Get input
a61af66fc99e Initial load
duke
parents:
diff changeset
154 if (inn == NULL) continue; // Ignore NULL, missing inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
155 Block* inb = bbs[inn->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
156 assert(inb != NULL, "must already have scheduled this input");
a61af66fc99e Initial load
duke
parents:
diff changeset
157 if (deepb_dom_depth < (int) inb->_dom_depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // The new inb must be dominated by the previous deepb.
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // The various inputs must be linearly ordered in the dom
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // tree, or else there will not be a unique deepest block.
a61af66fc99e Initial load
duke
parents:
diff changeset
161 DEBUG_ONLY(assert_dom(deepb, inb, n, bbs));
a61af66fc99e Initial load
duke
parents:
diff changeset
162 deepb = inb; // Save deepest block
a61af66fc99e Initial load
duke
parents:
diff changeset
163 deepb_dom_depth = deepb->_dom_depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 assert(deepb != NULL, "must be at least one input to n");
a61af66fc99e Initial load
duke
parents:
diff changeset
167 return deepb;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 //------------------------------schedule_early---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Find the earliest Block any instruction can be placed in. Some instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // are pinned into Blocks. Unpinned instructions can appear in last block in
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // which all their inputs occur.
a61af66fc99e Initial load
duke
parents:
diff changeset
175 bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // Allocate stack with enough space to avoid frequent realloc
a61af66fc99e Initial load
duke
parents:
diff changeset
177 Node_Stack nstack(roots.Size() + 8); // (unique >> 1) + 24 from Java2D stats
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // roots.push(_root); _root will be processed among C->top() inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
179 roots.push(C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
180 visited.set(C->top()->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 while (roots.size() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // Use local variables nstack_top_n & nstack_top_i to cache values
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // on stack's top.
a61af66fc99e Initial load
duke
parents:
diff changeset
185 Node *nstack_top_n = roots.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
186 uint nstack_top_i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
187 //while_nstack_nonempty:
a61af66fc99e Initial load
duke
parents:
diff changeset
188 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // Get parent node and next input's index from stack's top.
a61af66fc99e Initial load
duke
parents:
diff changeset
190 Node *n = nstack_top_n;
a61af66fc99e Initial load
duke
parents:
diff changeset
191 uint i = nstack_top_i;
a61af66fc99e Initial load
duke
parents:
diff changeset
192
a61af66fc99e Initial load
duke
parents:
diff changeset
193 if (i == 0) {
601
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
194 // Fixup some control. Constants without control get attached
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
195 // to root and nodes that use is_block_proj() nodes should be attached
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
196 // to the region that starts their block.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
197 const Node *in0 = n->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
198 if (in0 != NULL) { // Control-dependent?
601
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
199 replace_block_proj_ctrl(n);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
200 } else { // n->in(0) == NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
201 if (n->req() == 1) { // This guy is a constant with NO inputs?
a61af66fc99e Initial load
duke
parents:
diff changeset
202 n->set_req(0, _root);
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // First, visit all inputs and force them to get a block. If an
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // input is already in a block we quit following inputs (to avoid
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // cycles). Instead we put that Node on a worklist to be handled
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // later (since IT'S inputs may not have a block yet).
a61af66fc99e Initial load
duke
parents:
diff changeset
211 bool done = true; // Assume all n's inputs will be processed
a61af66fc99e Initial load
duke
parents:
diff changeset
212 while (i < n->len()) { // For all inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
213 Node *in = n->in(i); // Get input
a61af66fc99e Initial load
duke
parents:
diff changeset
214 ++i;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 if (in == NULL) continue; // Ignore NULL, missing inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
216 int is_visited = visited.test_set(in->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if (!_bbs.lookup(in->_idx)) { // Missing block selection?
a61af66fc99e Initial load
duke
parents:
diff changeset
218 if (is_visited) {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // assert( !visited.test(in->_idx), "did not schedule early" );
a61af66fc99e Initial load
duke
parents:
diff changeset
220 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
222 nstack.push(n, i); // Save parent node and next input's index.
a61af66fc99e Initial load
duke
parents:
diff changeset
223 nstack_top_n = in; // Process current input now.
a61af66fc99e Initial load
duke
parents:
diff changeset
224 nstack_top_i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
225 done = false; // Not all n's inputs processed.
a61af66fc99e Initial load
duke
parents:
diff changeset
226 break; // continue while_nstack_nonempty;
a61af66fc99e Initial load
duke
parents:
diff changeset
227 } else if (!is_visited) { // Input not yet visited?
a61af66fc99e Initial load
duke
parents:
diff changeset
228 roots.push(in); // Visit this guy later, using worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 if (done) {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // All of n's inputs have been processed, complete post-processing.
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // Some instructions are pinned into a block. These include Region,
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // Phi, Start, Return, and other control-dependent instructions and
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // any projections which depend on them.
a61af66fc99e Initial load
duke
parents:
diff changeset
237 if (!n->pinned()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // Set earliest legal block.
a61af66fc99e Initial load
duke
parents:
diff changeset
239 _bbs.map(n->_idx, find_deepest_input(n, _bbs));
601
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
240 } else {
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 552
diff changeset
241 assert(_bbs[n->_idx] == _bbs[n->in(0)->_idx], "Pinned Node should be at the same block as its control edge");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 if (nstack.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // Finished all nodes on stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // Process next node on the worklist 'roots'.
a61af66fc99e Initial load
duke
parents:
diff changeset
247 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // Get saved parent node and next input's index.
a61af66fc99e Initial load
duke
parents:
diff changeset
250 nstack_top_n = nstack.node();
a61af66fc99e Initial load
duke
parents:
diff changeset
251 nstack_top_i = nstack.index();
a61af66fc99e Initial load
duke
parents:
diff changeset
252 nstack.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
253 } // if (done)
a61af66fc99e Initial load
duke
parents:
diff changeset
254 } // while (true)
a61af66fc99e Initial load
duke
parents:
diff changeset
255 } // while (roots.size() != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
256 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258
a61af66fc99e Initial load
duke
parents:
diff changeset
259 //------------------------------dom_lca----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // Find least common ancestor in dominator tree
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // LCA is a current notion of LCA, to be raised above 'this'.
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // As a convenient boundary condition, return 'this' if LCA is NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // Find the LCA of those two nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
264 Block* Block::dom_lca(Block* LCA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (LCA == NULL || LCA == this) return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 Block* anc = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 while (anc->_dom_depth > LCA->_dom_depth)
a61af66fc99e Initial load
duke
parents:
diff changeset
269 anc = anc->_idom; // Walk up till anc is as high as LCA
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271 while (LCA->_dom_depth > anc->_dom_depth)
a61af66fc99e Initial load
duke
parents:
diff changeset
272 LCA = LCA->_idom; // Walk up till LCA is as high as anc
a61af66fc99e Initial load
duke
parents:
diff changeset
273
a61af66fc99e Initial load
duke
parents:
diff changeset
274 while (LCA != anc) { // Walk both up till they are the same
a61af66fc99e Initial load
duke
parents:
diff changeset
275 LCA = LCA->_idom;
a61af66fc99e Initial load
duke
parents:
diff changeset
276 anc = anc->_idom;
a61af66fc99e Initial load
duke
parents:
diff changeset
277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279 return LCA;
a61af66fc99e Initial load
duke
parents:
diff changeset
280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282 //--------------------------raise_LCA_above_use--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // We are placing a definition, and have been given a def->use edge.
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // The definition must dominate the use, so move the LCA upward in the
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // dominator tree to dominate the use. If the use is a phi, adjust
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // the LCA only with the phi input paths which actually use this def.
a61af66fc99e Initial load
duke
parents:
diff changeset
287 static Block* raise_LCA_above_use(Block* LCA, Node* use, Node* def, Block_Array &bbs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 Block* buse = bbs[use->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
289 if (buse == NULL) return LCA; // Unused killing Projs have no use block
a61af66fc99e Initial load
duke
parents:
diff changeset
290 if (!use->is_Phi()) return buse->dom_lca(LCA);
a61af66fc99e Initial load
duke
parents:
diff changeset
291 uint pmax = use->req(); // Number of Phi inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // Why does not this loop just break after finding the matching input to
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // the Phi? Well...it's like this. I do not have true def-use/use-def
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // chains. Means I cannot distinguish, from the def-use direction, which
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // of many use-defs lead from the same use to the same def. That is, this
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // Phi might have several uses of the same def. Each use appears in a
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // different predecessor block. But when I enter here, I cannot distinguish
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // which use-def edge I should find the predecessor block for. So I find
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // them all. Means I do a little extra work if a Phi uses the same value
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // more than once.
a61af66fc99e Initial load
duke
parents:
diff changeset
301 for (uint j=1; j<pmax; j++) { // For all inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
302 if (use->in(j) == def) { // Found matching input?
a61af66fc99e Initial load
duke
parents:
diff changeset
303 Block* pred = bbs[buse->pred(j)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
304 LCA = pred->dom_lca(LCA);
a61af66fc99e Initial load
duke
parents:
diff changeset
305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307 return LCA;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 //----------------------------raise_LCA_above_marks----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // Return a new LCA that dominates LCA and any of its marked predecessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // Search all my parents up to 'early' (exclusive), looking for predecessors
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // which are marked with the given index. Return the LCA (in the dom tree)
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // of all marked blocks. If there are none marked, return the original
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // LCA.
a61af66fc99e Initial load
duke
parents:
diff changeset
316 static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark,
a61af66fc99e Initial load
duke
parents:
diff changeset
317 Block* early, Block_Array &bbs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 Block_List worklist;
a61af66fc99e Initial load
duke
parents:
diff changeset
319 worklist.push(LCA);
a61af66fc99e Initial load
duke
parents:
diff changeset
320 while (worklist.size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 Block* mid = worklist.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
322 if (mid == early) continue; // stop searching here
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // Test and set the visited bit.
a61af66fc99e Initial load
duke
parents:
diff changeset
325 if (mid->raise_LCA_visited() == mark) continue; // already visited
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // Don't process the current LCA, otherwise the search may terminate early
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if (mid != LCA && mid->raise_LCA_mark() == mark) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // Raise the LCA.
a61af66fc99e Initial load
duke
parents:
diff changeset
330 LCA = mid->dom_lca(LCA);
a61af66fc99e Initial load
duke
parents:
diff changeset
331 if (LCA == early) break; // stop searching everywhere
a61af66fc99e Initial load
duke
parents:
diff changeset
332 assert(early->dominates(LCA), "early is high enough");
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // Resume searching at that point, skipping intermediate levels.
a61af66fc99e Initial load
duke
parents:
diff changeset
334 worklist.push(LCA);
215
273eaa04d9a1 6714694: assertion in 64bit server vm (store->find_edge(load) != -1,"missing precedence edge") with COOPs
kvn
parents: 31
diff changeset
335 if (LCA == mid)
273eaa04d9a1 6714694: assertion in 64bit server vm (store->find_edge(load) != -1,"missing precedence edge") with COOPs
kvn
parents: 31
diff changeset
336 continue; // Don't mark as visited to avoid early termination.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
337 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // Keep searching through this block's predecessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
339 for (uint j = 1, jmax = mid->num_preds(); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
340 Block* mid_parent = bbs[ mid->pred(j)->_idx ];
a61af66fc99e Initial load
duke
parents:
diff changeset
341 worklist.push(mid_parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
215
273eaa04d9a1 6714694: assertion in 64bit server vm (store->find_edge(load) != -1,"missing precedence edge") with COOPs
kvn
parents: 31
diff changeset
344 mid->set_raise_LCA_visited(mark);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
346 return LCA;
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 //--------------------------memory_early_block--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // This is a variation of find_deepest_input, the heart of schedule_early.
a61af66fc99e Initial load
duke
parents:
diff changeset
351 // Find the "early" block for a load, if we considered only memory and
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // address inputs, that is, if other data inputs were ignored.
a61af66fc99e Initial load
duke
parents:
diff changeset
353 //
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // Because a subset of edges are considered, the resulting block will
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // be earlier (at a shallower dom_depth) than the true schedule_early
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // point of the node. We compute this earlier block as a more permissive
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // site for anti-dependency insertion, but only if subsume_loads is enabled.
a61af66fc99e Initial load
duke
parents:
diff changeset
358 static Block* memory_early_block(Node* load, Block* early, Block_Array &bbs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 Node* base;
a61af66fc99e Initial load
duke
parents:
diff changeset
360 Node* index;
a61af66fc99e Initial load
duke
parents:
diff changeset
361 Node* store = load->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
362 load->as_Mach()->memory_inputs(base, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 assert(base != NodeSentinel && index != NodeSentinel,
a61af66fc99e Initial load
duke
parents:
diff changeset
365 "unexpected base/index inputs");
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 Node* mem_inputs[4];
a61af66fc99e Initial load
duke
parents:
diff changeset
368 int mem_inputs_length = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
369 if (base != NULL) mem_inputs[mem_inputs_length++] = base;
a61af66fc99e Initial load
duke
parents:
diff changeset
370 if (index != NULL) mem_inputs[mem_inputs_length++] = index;
a61af66fc99e Initial load
duke
parents:
diff changeset
371 if (store != NULL) mem_inputs[mem_inputs_length++] = store;
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // In the comparision below, add one to account for the control input,
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // which may be null, but always takes up a spot in the in array.
a61af66fc99e Initial load
duke
parents:
diff changeset
375 if (mem_inputs_length + 1 < (int) load->req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // This "load" has more inputs than just the memory, base and index inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // For purposes of checking anti-dependences, we need to start
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // from the early block of only the address portion of the instruction,
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // and ignore other blocks that may have factored into the wider
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // schedule_early calculation.
a61af66fc99e Initial load
duke
parents:
diff changeset
381 if (load->in(0) != NULL) mem_inputs[mem_inputs_length++] = load->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
382
a61af66fc99e Initial load
duke
parents:
diff changeset
383 Block* deepb = NULL; // Deepest block so far
a61af66fc99e Initial load
duke
parents:
diff changeset
384 int deepb_dom_depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 for (int i = 0; i < mem_inputs_length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 Block* inb = bbs[mem_inputs[i]->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
387 if (deepb_dom_depth < (int) inb->_dom_depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // The new inb must be dominated by the previous deepb.
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // The various inputs must be linearly ordered in the dom
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // tree, or else there will not be a unique deepest block.
a61af66fc99e Initial load
duke
parents:
diff changeset
391 DEBUG_ONLY(assert_dom(deepb, inb, load, bbs));
a61af66fc99e Initial load
duke
parents:
diff changeset
392 deepb = inb; // Save deepest block
a61af66fc99e Initial load
duke
parents:
diff changeset
393 deepb_dom_depth = deepb->_dom_depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
396 early = deepb;
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
398
a61af66fc99e Initial load
duke
parents:
diff changeset
399 return early;
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401
a61af66fc99e Initial load
duke
parents:
diff changeset
402 //--------------------------insert_anti_dependences---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // A load may need to witness memory that nearby stores can overwrite.
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // For each nearby store, either insert an "anti-dependence" edge
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // from the load to the store, or else move LCA upward to force the
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // load to (eventually) be scheduled in a block above the store.
a61af66fc99e Initial load
duke
parents:
diff changeset
407 //
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // Do not add edges to stores on distinct control-flow paths;
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // only add edges to stores which might interfere.
a61af66fc99e Initial load
duke
parents:
diff changeset
410 //
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // Return the (updated) LCA. There will not be any possibly interfering
a61af66fc99e Initial load
duke
parents:
diff changeset
412 // store between the load's "early block" and the updated LCA.
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // Any stores in the updated LCA will have new precedence edges
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // back to the load. The caller is expected to schedule the load
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // in the LCA, in which case the precedence edges will make LCM
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // preserve anti-dependences. The caller may also hoist the load
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // above the LCA, if it is not the early block.
a61af66fc99e Initial load
duke
parents:
diff changeset
418 Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 assert(load->needs_anti_dependence_check(), "must be a load of some sort");
a61af66fc99e Initial load
duke
parents:
diff changeset
420 assert(LCA != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
421 DEBUG_ONLY(Block* LCA_orig = LCA);
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // Compute the alias index. Loads and stores with different alias indices
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // do not need anti-dependence edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
425 uint load_alias_idx = C->get_alias_index(load->adr_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
426 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if (load_alias_idx == Compile::AliasIdxBot && C->AliasLevel() > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
428 (PrintOpto || VerifyAliases ||
a61af66fc99e Initial load
duke
parents:
diff changeset
429 PrintMiscellaneous && (WizardMode || Verbose))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // Load nodes should not consume all of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // Reporting a bottom type indicates a bug in adlc.
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // If some particular type of node validly consumes all of memory,
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // sharpen the preceding "if" to exclude it, so we can catch bugs here.
a61af66fc99e Initial load
duke
parents:
diff changeset
434 tty->print_cr("*** Possible Anti-Dependence Bug: Load consumes all of memory.");
a61af66fc99e Initial load
duke
parents:
diff changeset
435 load->dump(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
436 if (VerifyAliases) assert(load_alias_idx != Compile::AliasIdxBot, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
437 }
a61af66fc99e Initial load
duke
parents:
diff changeset
438 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
439 assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrComp),
a61af66fc99e Initial load
duke
parents:
diff changeset
440 "String compare is only known 'load' that does not conflict with any stores");
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 673
diff changeset
441 assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrEquals),
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 673
diff changeset
442 "String equals is a 'load' that does not conflict with any stores");
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 673
diff changeset
443 assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrIndexOf),
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 673
diff changeset
444 "String indexOf is a 'load' that does not conflict with any stores");
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 673
diff changeset
445 assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_AryEq),
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 673
diff changeset
446 "Arrays equals is a 'load' that do not conflict with any stores");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 if (!C->alias_type(load_alias_idx)->is_rewritable()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // It is impossible to spoil this load by putting stores before it,
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // because we know that the stores will never update the value
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // which 'load' must witness.
a61af66fc99e Initial load
duke
parents:
diff changeset
452 return LCA;
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454
a61af66fc99e Initial load
duke
parents:
diff changeset
455 node_idx_t load_index = load->_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
456
a61af66fc99e Initial load
duke
parents:
diff changeset
457 // Note the earliest legal placement of 'load', as determined by
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // by the unique point in the dom tree where all memory effects
a61af66fc99e Initial load
duke
parents:
diff changeset
459 // and other inputs are first available. (Computed by schedule_early.)
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // For normal loads, 'early' is the shallowest place (dom graph wise)
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // to look for anti-deps between this load and any store.
a61af66fc99e Initial load
duke
parents:
diff changeset
462 Block* early = _bbs[load_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // If we are subsuming loads, compute an "early" block that only considers
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // memory or address inputs. This block may be different than the
a61af66fc99e Initial load
duke
parents:
diff changeset
466 // schedule_early block in that it could be at an even shallower depth in the
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // dominator tree, and allow for a broader discovery of anti-dependences.
a61af66fc99e Initial load
duke
parents:
diff changeset
468 if (C->subsume_loads()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
469 early = memory_early_block(load, early, _bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
471
a61af66fc99e Initial load
duke
parents:
diff changeset
472 ResourceArea *area = Thread::current()->resource_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
473 Node_List worklist_mem(area); // prior memory state to store
a61af66fc99e Initial load
duke
parents:
diff changeset
474 Node_List worklist_store(area); // possible-def to explore
31
6152cbb08ce9 6590177: jck60019 test assert(!repeated,"do not walk merges twice")
kvn
parents: 0
diff changeset
475 Node_List worklist_visited(area); // visited mergemem nodes
0
a61af66fc99e Initial load
duke
parents:
diff changeset
476 Node_List non_early_stores(area); // all relevant stores outside of early
a61af66fc99e Initial load
duke
parents:
diff changeset
477 bool must_raise_LCA = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
478
a61af66fc99e Initial load
duke
parents:
diff changeset
479 #ifdef TRACK_PHI_INPUTS
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // %%% This extra checking fails because MergeMem nodes are not GVNed.
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // Provide "phi_inputs" to check if every input to a PhiNode is from the
a61af66fc99e Initial load
duke
parents:
diff changeset
482 // original memory state. This indicates a PhiNode for which should not
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // prevent the load from sinking. For such a block, set_raise_LCA_mark
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // may be overly conservative.
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // Mechanism: count inputs seen for each Phi encountered in worklist_store.
a61af66fc99e Initial load
duke
parents:
diff changeset
486 DEBUG_ONLY(GrowableArray<uint> phi_inputs(area, C->unique(),0,0));
a61af66fc99e Initial load
duke
parents:
diff changeset
487 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
488
a61af66fc99e Initial load
duke
parents:
diff changeset
489 // 'load' uses some memory state; look for users of the same state.
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // Recurse through MergeMem nodes to the stores that use them.
a61af66fc99e Initial load
duke
parents:
diff changeset
491
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // Each of these stores is a possible definition of memory
a61af66fc99e Initial load
duke
parents:
diff changeset
493 // that 'load' needs to use. We need to force 'load'
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // to occur before each such store. When the store is in
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // the same block as 'load', we insert an anti-dependence
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // edge load->store.
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // The relevant stores "nearby" the load consist of a tree rooted
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // at initial_mem, with internal nodes of type MergeMem.
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // Therefore, the branches visited by the worklist are of this form:
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // initial_mem -> (MergeMem ->)* store
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // The anti-dependence constraints apply only to the fringe of this tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504 Node* initial_mem = load->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 worklist_store.push(initial_mem);
31
6152cbb08ce9 6590177: jck60019 test assert(!repeated,"do not walk merges twice")
kvn
parents: 0
diff changeset
506 worklist_visited.push(initial_mem);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
507 worklist_mem.push(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
508 while (worklist_store.size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // Examine a nearby store to see if it might interfere with our load.
a61af66fc99e Initial load
duke
parents:
diff changeset
510 Node* mem = worklist_mem.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
511 Node* store = worklist_store.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
512 uint op = store->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
513
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // MergeMems do not directly have anti-deps.
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // Treat them as internal nodes in a forward tree of memory states,
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // the leaves of which are each a 'possible-def'.
a61af66fc99e Initial load
duke
parents:
diff changeset
517 if (store == initial_mem // root (exclusive) of tree we are searching
a61af66fc99e Initial load
duke
parents:
diff changeset
518 || op == Op_MergeMem // internal node of tree we are searching
a61af66fc99e Initial load
duke
parents:
diff changeset
519 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
520 mem = store; // It's not a possibly interfering store.
31
6152cbb08ce9 6590177: jck60019 test assert(!repeated,"do not walk merges twice")
kvn
parents: 0
diff changeset
521 if (store == initial_mem)
6152cbb08ce9 6590177: jck60019 test assert(!repeated,"do not walk merges twice")
kvn
parents: 0
diff changeset
522 initial_mem = NULL; // only process initial memory once
6152cbb08ce9 6590177: jck60019 test assert(!repeated,"do not walk merges twice")
kvn
parents: 0
diff changeset
523
0
a61af66fc99e Initial load
duke
parents:
diff changeset
524 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
525 store = mem->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
526 if (store->is_MergeMem()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // Be sure we don't get into combinatorial problems.
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // (Allow phis to be repeated; they can merge two relevant states.)
31
6152cbb08ce9 6590177: jck60019 test assert(!repeated,"do not walk merges twice")
kvn
parents: 0
diff changeset
529 uint j = worklist_visited.size();
6152cbb08ce9 6590177: jck60019 test assert(!repeated,"do not walk merges twice")
kvn
parents: 0
diff changeset
530 for (; j > 0; j--) {
6152cbb08ce9 6590177: jck60019 test assert(!repeated,"do not walk merges twice")
kvn
parents: 0
diff changeset
531 if (worklist_visited.at(j-1) == store) break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
532 }
31
6152cbb08ce9 6590177: jck60019 test assert(!repeated,"do not walk merges twice")
kvn
parents: 0
diff changeset
533 if (j > 0) continue; // already on work list; do not repeat
6152cbb08ce9 6590177: jck60019 test assert(!repeated,"do not walk merges twice")
kvn
parents: 0
diff changeset
534 worklist_visited.push(store);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536 worklist_mem.push(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
537 worklist_store.push(store);
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 if (op == Op_MachProj || op == Op_Catch) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
543 if (store->needs_anti_dependence_check()) continue; // not really a store
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // Compute the alias index. Loads and stores with different alias
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // indices do not need anti-dependence edges. Wide MemBar's are
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // anti-dependent on everything (except immutable memories).
a61af66fc99e Initial load
duke
parents:
diff changeset
548 const TypePtr* adr_type = store->adr_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
549 if (!C->can_alias(adr_type, load_alias_idx)) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // Most slow-path runtime calls do NOT modify Java memory, but
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // they can block and so write Raw memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
553 if (store->is_Mach()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
554 MachNode* mstore = store->as_Mach();
a61af66fc99e Initial load
duke
parents:
diff changeset
555 if (load_alias_idx != Compile::AliasIdxRaw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // Check for call into the runtime using the Java calling
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // convention (and from there into a wrapper); it has no
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // _method. Can't do this optimization for Native calls because
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // they CAN write to Java memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
560 if (mstore->ideal_Opcode() == Op_CallStaticJava) {
a61af66fc99e Initial load
duke
parents:
diff changeset
561 assert(mstore->is_MachSafePoint(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
562 MachSafePointNode* ms = (MachSafePointNode*) mstore;
a61af66fc99e Initial load
duke
parents:
diff changeset
563 assert(ms->is_MachCallJava(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
564 MachCallJavaNode* mcj = (MachCallJavaNode*) ms;
a61af66fc99e Initial load
duke
parents:
diff changeset
565 if (mcj->_method == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // These runtime calls do not write to Java visible memory
a61af66fc99e Initial load
duke
parents:
diff changeset
567 // (other than Raw) and so do not require anti-dependence edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
568 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // Same for SafePoints: they read/write Raw but only read otherwise.
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // This is basically a workaround for SafePoints only defining control
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // instead of control + memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
574 if (mstore->ideal_Opcode() == Op_SafePoint)
a61af66fc99e Initial load
duke
parents:
diff changeset
575 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
576 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // Some raw memory, such as the load of "top" at an allocation,
a61af66fc99e Initial load
duke
parents:
diff changeset
578 // can be control dependent on the previous safepoint. See
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // comments in GraphKit::allocate_heap() about control input.
a61af66fc99e Initial load
duke
parents:
diff changeset
580 // Inserting an anti-dep between such a safepoint and a use
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // creates a cycle, and will cause a subsequent failure in
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // local scheduling. (BugId 4919904)
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // (%%% How can a control input be a safepoint and not a projection??)
a61af66fc99e Initial load
duke
parents:
diff changeset
584 if (mstore->ideal_Opcode() == Op_SafePoint && load->in(0) == mstore)
a61af66fc99e Initial load
duke
parents:
diff changeset
585 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
586 }
a61af66fc99e Initial load
duke
parents:
diff changeset
587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // Identify a block that the current load must be above,
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // or else observe that 'store' is all the way up in the
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // earliest legal block for 'load'. In the latter case,
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // immediately insert an anti-dependence edge.
a61af66fc99e Initial load
duke
parents:
diff changeset
593 Block* store_block = _bbs[store->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
594 assert(store_block != NULL, "unused killing projections skipped above");
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 if (store->is_Phi()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // 'load' uses memory which is one (or more) of the Phi's inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // It must be scheduled not before the Phi, but rather before
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // each of the relevant Phi inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
600 //
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // Instead of finding the LCA of all inputs to a Phi that match 'mem',
a61af66fc99e Initial load
duke
parents:
diff changeset
602 // we mark each corresponding predecessor block and do a combined
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // hoisting operation later (raise_LCA_above_marks).
a61af66fc99e Initial load
duke
parents:
diff changeset
604 //
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // Do not assert(store_block != early, "Phi merging memory after access")
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // PhiNode may be at start of block 'early' with backedge to 'early'
a61af66fc99e Initial load
duke
parents:
diff changeset
607 DEBUG_ONLY(bool found_match = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
608 for (uint j = PhiNode::Input, jmax = store->req(); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
609 if (store->in(j) == mem) { // Found matching input?
a61af66fc99e Initial load
duke
parents:
diff changeset
610 DEBUG_ONLY(found_match = true);
a61af66fc99e Initial load
duke
parents:
diff changeset
611 Block* pred_block = _bbs[store_block->pred(j)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
612 if (pred_block != early) {
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // If any predecessor of the Phi matches the load's "early block",
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // we do not need a precedence edge between the Phi and 'load'
605
98cb887364d3 6810672: Comment typos
twisti
parents: 601
diff changeset
615 // since the load will be forced into a block preceding the Phi.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
616 pred_block->set_raise_LCA_mark(load_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
617 assert(!LCA_orig->dominates(pred_block) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
618 early->dominates(pred_block), "early is high enough");
a61af66fc99e Initial load
duke
parents:
diff changeset
619 must_raise_LCA = true;
788
1851e1fb420e 6843752: missing code for an anti-dependent Phi in GCM
kvn
parents: 681
diff changeset
620 } else {
1851e1fb420e 6843752: missing code for an anti-dependent Phi in GCM
kvn
parents: 681
diff changeset
621 // anti-dependent upon PHI pinned below 'early', no edge needed
1851e1fb420e 6843752: missing code for an anti-dependent Phi in GCM
kvn
parents: 681
diff changeset
622 LCA = early; // but can not schedule below 'early'
0
a61af66fc99e Initial load
duke
parents:
diff changeset
623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626 assert(found_match, "no worklist bug");
a61af66fc99e Initial load
duke
parents:
diff changeset
627 #ifdef TRACK_PHI_INPUTS
a61af66fc99e Initial load
duke
parents:
diff changeset
628 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // This assert asks about correct handling of PhiNodes, which may not
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // have all input edges directly from 'mem'. See BugId 4621264
a61af66fc99e Initial load
duke
parents:
diff changeset
631 int num_mem_inputs = phi_inputs.at_grow(store->_idx,0) + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Increment by exactly one even if there are multiple copies of 'mem'
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // coming into the phi, because we will run this block several times
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // if there are several copies of 'mem'. (That's how DU iterators work.)
a61af66fc99e Initial load
duke
parents:
diff changeset
635 phi_inputs.at_put(store->_idx, num_mem_inputs);
a61af66fc99e Initial load
duke
parents:
diff changeset
636 assert(PhiNode::Input + num_mem_inputs < store->req(),
a61af66fc99e Initial load
duke
parents:
diff changeset
637 "Expect at least one phi input will not be from original memory state");
a61af66fc99e Initial load
duke
parents:
diff changeset
638 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
639 #endif //TRACK_PHI_INPUTS
a61af66fc99e Initial load
duke
parents:
diff changeset
640 } else if (store_block != early) {
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // 'store' is between the current LCA and earliest possible block.
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // Label its block, and decide later on how to raise the LCA
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // to include the effect on LCA of this store.
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // If this store's block gets chosen as the raised LCA, we
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // will find him on the non_early_stores list and stick him
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // with a precedence edge.
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // (But, don't bother if LCA is already raised all the way.)
a61af66fc99e Initial load
duke
parents:
diff changeset
648 if (LCA != early) {
a61af66fc99e Initial load
duke
parents:
diff changeset
649 store_block->set_raise_LCA_mark(load_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
650 must_raise_LCA = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
651 non_early_stores.push(store);
a61af66fc99e Initial load
duke
parents:
diff changeset
652 }
a61af66fc99e Initial load
duke
parents:
diff changeset
653 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // Found a possibly-interfering store in the load's 'early' block.
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // This means 'load' cannot sink at all in the dominator tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // Add an anti-dep edge, and squeeze 'load' into the highest block.
a61af66fc99e Initial load
duke
parents:
diff changeset
657 assert(store != load->in(0), "dependence cycle found");
a61af66fc99e Initial load
duke
parents:
diff changeset
658 if (verify) {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 assert(store->find_edge(load) != -1, "missing precedence edge");
a61af66fc99e Initial load
duke
parents:
diff changeset
660 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
661 store->add_prec(load);
a61af66fc99e Initial load
duke
parents:
diff changeset
662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
663 LCA = early;
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // This turns off the process of gathering non_early_stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // (Worklist is now empty; all nearby stores have been visited.)
a61af66fc99e Initial load
duke
parents:
diff changeset
668
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // Finished if 'load' must be scheduled in its 'early' block.
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // If we found any stores there, they have already been given
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // precedence edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
672 if (LCA == early) return LCA;
a61af66fc99e Initial load
duke
parents:
diff changeset
673
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // We get here only if there are no possibly-interfering stores
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // in the load's 'early' block. Move LCA up above all predecessors
a61af66fc99e Initial load
duke
parents:
diff changeset
676 // which contain stores we have noted.
a61af66fc99e Initial load
duke
parents:
diff changeset
677 //
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // The raised LCA block can be a home to such interfering stores,
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // but its predecessors must not contain any such stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
680 //
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // The raised LCA will be a lower bound for placing the load,
a61af66fc99e Initial load
duke
parents:
diff changeset
682 // preventing the load from sinking past any block containing
a61af66fc99e Initial load
duke
parents:
diff changeset
683 // a store that may invalidate the memory state required by 'load'.
a61af66fc99e Initial load
duke
parents:
diff changeset
684 if (must_raise_LCA)
a61af66fc99e Initial load
duke
parents:
diff changeset
685 LCA = raise_LCA_above_marks(LCA, load->_idx, early, _bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
686 if (LCA == early) return LCA;
a61af66fc99e Initial load
duke
parents:
diff changeset
687
a61af66fc99e Initial load
duke
parents:
diff changeset
688 // Insert anti-dependence edges from 'load' to each store
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // in the non-early LCA block.
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // Mine the non_early_stores list for such stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
691 if (LCA->raise_LCA_mark() == load_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 while (non_early_stores.size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
693 Node* store = non_early_stores.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
694 Block* store_block = _bbs[store->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
695 if (store_block == LCA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // add anti_dependence from store to load in its own block
a61af66fc99e Initial load
duke
parents:
diff changeset
697 assert(store != load->in(0), "dependence cycle found");
a61af66fc99e Initial load
duke
parents:
diff changeset
698 if (verify) {
a61af66fc99e Initial load
duke
parents:
diff changeset
699 assert(store->find_edge(load) != -1, "missing precedence edge");
a61af66fc99e Initial load
duke
parents:
diff changeset
700 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
701 store->add_prec(load);
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
704 assert(store_block->raise_LCA_mark() == load_index, "block was marked");
a61af66fc99e Initial load
duke
parents:
diff changeset
705 // Any other stores we found must be either inside the new LCA
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // or else outside the original LCA. In the latter case, they
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // did not interfere with any use of 'load'.
a61af66fc99e Initial load
duke
parents:
diff changeset
708 assert(LCA->dominates(store_block)
a61af66fc99e Initial load
duke
parents:
diff changeset
709 || !LCA_orig->dominates(store_block), "no stray stores");
a61af66fc99e Initial load
duke
parents:
diff changeset
710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
711 }
a61af66fc99e Initial load
duke
parents:
diff changeset
712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // Return the highest block containing stores; any stores
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // within that block have been given anti-dependence edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
716 return LCA;
a61af66fc99e Initial load
duke
parents:
diff changeset
717 }
a61af66fc99e Initial load
duke
parents:
diff changeset
718
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // This class is used to iterate backwards over the nodes in the graph.
a61af66fc99e Initial load
duke
parents:
diff changeset
720
a61af66fc99e Initial load
duke
parents:
diff changeset
721 class Node_Backward_Iterator {
a61af66fc99e Initial load
duke
parents:
diff changeset
722
a61af66fc99e Initial load
duke
parents:
diff changeset
723 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
724 Node_Backward_Iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
725
a61af66fc99e Initial load
duke
parents:
diff changeset
726 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // Constructor for the iterator
a61af66fc99e Initial load
duke
parents:
diff changeset
728 Node_Backward_Iterator(Node *root, VectorSet &visited, Node_List &stack, Block_Array &bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
729
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // Postincrement operator to iterate over the nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
731 Node *next();
a61af66fc99e Initial load
duke
parents:
diff changeset
732
a61af66fc99e Initial load
duke
parents:
diff changeset
733 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
734 VectorSet &_visited;
a61af66fc99e Initial load
duke
parents:
diff changeset
735 Node_List &_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
736 Block_Array &_bbs;
a61af66fc99e Initial load
duke
parents:
diff changeset
737 };
a61af66fc99e Initial load
duke
parents:
diff changeset
738
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // Constructor for the Node_Backward_Iterator
a61af66fc99e Initial load
duke
parents:
diff changeset
740 Node_Backward_Iterator::Node_Backward_Iterator( Node *root, VectorSet &visited, Node_List &stack, Block_Array &bbs )
a61af66fc99e Initial load
duke
parents:
diff changeset
741 : _visited(visited), _stack(stack), _bbs(bbs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 // The stack should contain exactly the root
a61af66fc99e Initial load
duke
parents:
diff changeset
743 stack.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
744 stack.push(root);
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // Clear the visited bits
a61af66fc99e Initial load
duke
parents:
diff changeset
747 visited.Clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 // Iterator for the Node_Backward_Iterator
a61af66fc99e Initial load
duke
parents:
diff changeset
751 Node *Node_Backward_Iterator::next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // If the _stack is empty, then just return NULL: finished.
a61af66fc99e Initial load
duke
parents:
diff changeset
754 if ( !_stack.size() )
a61af66fc99e Initial load
duke
parents:
diff changeset
755 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
756
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // '_stack' is emulating a real _stack. The 'visit-all-users' loop has been
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // made stateless, so I do not need to record the index 'i' on my _stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // Instead I visit all users each time, scanning for unvisited users.
a61af66fc99e Initial load
duke
parents:
diff changeset
760 // I visit unvisited not-anti-dependence users first, then anti-dependent
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // children next.
a61af66fc99e Initial load
duke
parents:
diff changeset
762 Node *self = _stack.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
763
a61af66fc99e Initial load
duke
parents:
diff changeset
764 // I cycle here when I am entering a deeper level of recursion.
a61af66fc99e Initial load
duke
parents:
diff changeset
765 // The key variable 'self' was set prior to jumping here.
a61af66fc99e Initial load
duke
parents:
diff changeset
766 while( 1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
767
a61af66fc99e Initial load
duke
parents:
diff changeset
768 _visited.set(self->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 // Now schedule all uses as late as possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
771 uint src = self->is_Proj() ? self->in(0)->_idx : self->_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
772 uint src_rpo = _bbs[src]->_rpo;
a61af66fc99e Initial load
duke
parents:
diff changeset
773
a61af66fc99e Initial load
duke
parents:
diff changeset
774 // Schedule all nodes in a post-order visit
a61af66fc99e Initial load
duke
parents:
diff changeset
775 Node *unvisited = NULL; // Unvisited anti-dependent Node, if any
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // Scan for unvisited nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
778 for (DUIterator_Fast imax, i = self->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
779 // For all uses, schedule late
a61af66fc99e Initial load
duke
parents:
diff changeset
780 Node* n = self->fast_out(i); // Use
a61af66fc99e Initial load
duke
parents:
diff changeset
781
a61af66fc99e Initial load
duke
parents:
diff changeset
782 // Skip already visited children
a61af66fc99e Initial load
duke
parents:
diff changeset
783 if ( _visited.test(n->_idx) )
a61af66fc99e Initial load
duke
parents:
diff changeset
784 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
785
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // do not traverse backward control edges
a61af66fc99e Initial load
duke
parents:
diff changeset
787 Node *use = n->is_Proj() ? n->in(0) : n;
a61af66fc99e Initial load
duke
parents:
diff changeset
788 uint use_rpo = _bbs[use->_idx]->_rpo;
a61af66fc99e Initial load
duke
parents:
diff changeset
789
a61af66fc99e Initial load
duke
parents:
diff changeset
790 if ( use_rpo < src_rpo )
a61af66fc99e Initial load
duke
parents:
diff changeset
791 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 // Phi nodes always precede uses in a basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
794 if ( use_rpo == src_rpo && use->is_Phi() )
a61af66fc99e Initial load
duke
parents:
diff changeset
795 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
796
a61af66fc99e Initial load
duke
parents:
diff changeset
797 unvisited = n; // Found unvisited
a61af66fc99e Initial load
duke
parents:
diff changeset
798
a61af66fc99e Initial load
duke
parents:
diff changeset
799 // Check for possible-anti-dependent
a61af66fc99e Initial load
duke
parents:
diff changeset
800 if( !n->needs_anti_dependence_check() )
a61af66fc99e Initial load
duke
parents:
diff changeset
801 break; // Not visited, not anti-dep; schedule it NOW
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
803
a61af66fc99e Initial load
duke
parents:
diff changeset
804 // Did I find an unvisited not-anti-dependent Node?
a61af66fc99e Initial load
duke
parents:
diff changeset
805 if ( !unvisited )
a61af66fc99e Initial load
duke
parents:
diff changeset
806 break; // All done with children; post-visit 'self'
a61af66fc99e Initial load
duke
parents:
diff changeset
807
a61af66fc99e Initial load
duke
parents:
diff changeset
808 // Visit the unvisited Node. Contains the obvious push to
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // indicate I'm entering a deeper level of recursion. I push the
a61af66fc99e Initial load
duke
parents:
diff changeset
810 // old state onto the _stack and set a new state and loop (recurse).
a61af66fc99e Initial load
duke
parents:
diff changeset
811 _stack.push(self);
a61af66fc99e Initial load
duke
parents:
diff changeset
812 self = unvisited;
a61af66fc99e Initial load
duke
parents:
diff changeset
813 } // End recursion loop
a61af66fc99e Initial load
duke
parents:
diff changeset
814
a61af66fc99e Initial load
duke
parents:
diff changeset
815 return self;
a61af66fc99e Initial load
duke
parents:
diff changeset
816 }
a61af66fc99e Initial load
duke
parents:
diff changeset
817
a61af66fc99e Initial load
duke
parents:
diff changeset
818 //------------------------------ComputeLatenciesBackwards----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
819 // Compute the latency of all the instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
820 void PhaseCFG::ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
821 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
822 if (trace_opto_pipelining())
a61af66fc99e Initial load
duke
parents:
diff changeset
823 tty->print("\n#---- ComputeLatenciesBackwards ----\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
824 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 Node_Backward_Iterator iter((Node *)_root, visited, stack, _bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
827 Node *n;
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 // Walk over all the nodes from last to first
a61af66fc99e Initial load
duke
parents:
diff changeset
830 while (n = iter.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
831 // Set the latency for the definitions of this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
832 partial_latency_of_defs(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
834 } // end ComputeLatenciesBackwards
a61af66fc99e Initial load
duke
parents:
diff changeset
835
a61af66fc99e Initial load
duke
parents:
diff changeset
836 //------------------------------partial_latency_of_defs------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // Compute the latency impact of this node on all defs. This computes
a61af66fc99e Initial load
duke
parents:
diff changeset
838 // a number that increases as we approach the beginning of the routine.
a61af66fc99e Initial load
duke
parents:
diff changeset
839 void PhaseCFG::partial_latency_of_defs(Node *n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
840 // Set the latency for this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
841 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
842 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
843 tty->print("# latency_to_inputs: node_latency[%d] = %d for node",
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
844 n->_idx, _node_latency->at_grow(n->_idx));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
845 dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
846 }
a61af66fc99e Initial load
duke
parents:
diff changeset
847 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
848
a61af66fc99e Initial load
duke
parents:
diff changeset
849 if (n->is_Proj())
a61af66fc99e Initial load
duke
parents:
diff changeset
850 n = n->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
851
a61af66fc99e Initial load
duke
parents:
diff changeset
852 if (n->is_Root())
a61af66fc99e Initial load
duke
parents:
diff changeset
853 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
854
a61af66fc99e Initial load
duke
parents:
diff changeset
855 uint nlen = n->len();
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
856 uint use_latency = _node_latency->at_grow(n->_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
857 uint use_pre_order = _bbs[n->_idx]->_pre_order;
a61af66fc99e Initial load
duke
parents:
diff changeset
858
a61af66fc99e Initial load
duke
parents:
diff changeset
859 for ( uint j=0; j<nlen; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
860 Node *def = n->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
861
a61af66fc99e Initial load
duke
parents:
diff changeset
862 if (!def || def == n)
a61af66fc99e Initial load
duke
parents:
diff changeset
863 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
864
a61af66fc99e Initial load
duke
parents:
diff changeset
865 // Walk backwards thru projections
a61af66fc99e Initial load
duke
parents:
diff changeset
866 if (def->is_Proj())
a61af66fc99e Initial load
duke
parents:
diff changeset
867 def = def->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
868
a61af66fc99e Initial load
duke
parents:
diff changeset
869 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
870 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
871 tty->print("# in(%2d): ", j);
a61af66fc99e Initial load
duke
parents:
diff changeset
872 def->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
874 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
875
a61af66fc99e Initial load
duke
parents:
diff changeset
876 // If the defining block is not known, assume it is ok
a61af66fc99e Initial load
duke
parents:
diff changeset
877 Block *def_block = _bbs[def->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
878 uint def_pre_order = def_block ? def_block->_pre_order : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
879
a61af66fc99e Initial load
duke
parents:
diff changeset
880 if ( (use_pre_order < def_pre_order) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
881 (use_pre_order == def_pre_order && n->is_Phi()) )
a61af66fc99e Initial load
duke
parents:
diff changeset
882 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
883
a61af66fc99e Initial load
duke
parents:
diff changeset
884 uint delta_latency = n->latency(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
885 uint current_latency = delta_latency + use_latency;
a61af66fc99e Initial load
duke
parents:
diff changeset
886
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
887 if (_node_latency->at_grow(def->_idx) < current_latency) {
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
888 _node_latency->at_put_grow(def->_idx, current_latency);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
889 }
a61af66fc99e Initial load
duke
parents:
diff changeset
890
a61af66fc99e Initial load
duke
parents:
diff changeset
891 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
892 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
893 tty->print_cr("# %d + edge_latency(%d) == %d -> %d, node_latency[%d] = %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
894 use_latency, j, delta_latency, current_latency, def->_idx,
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
895 _node_latency->at_grow(def->_idx));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
896 }
a61af66fc99e Initial load
duke
parents:
diff changeset
897 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 //------------------------------latency_from_use-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // Compute the latency of a specific use
a61af66fc99e Initial load
duke
parents:
diff changeset
903 int PhaseCFG::latency_from_use(Node *n, const Node *def, Node *use) {
a61af66fc99e Initial load
duke
parents:
diff changeset
904 // If self-reference, return no latency
a61af66fc99e Initial load
duke
parents:
diff changeset
905 if (use == n || use->is_Root())
a61af66fc99e Initial load
duke
parents:
diff changeset
906 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 uint def_pre_order = _bbs[def->_idx]->_pre_order;
a61af66fc99e Initial load
duke
parents:
diff changeset
909 uint latency = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
910
a61af66fc99e Initial load
duke
parents:
diff changeset
911 // If the use is not a projection, then it is simple...
a61af66fc99e Initial load
duke
parents:
diff changeset
912 if (!use->is_Proj()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
913 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
914 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
915 tty->print("# out(): ");
a61af66fc99e Initial load
duke
parents:
diff changeset
916 use->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
918 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 uint use_pre_order = _bbs[use->_idx]->_pre_order;
a61af66fc99e Initial load
duke
parents:
diff changeset
921
a61af66fc99e Initial load
duke
parents:
diff changeset
922 if (use_pre_order < def_pre_order)
a61af66fc99e Initial load
duke
parents:
diff changeset
923 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925 if (use_pre_order == def_pre_order && use->is_Phi())
a61af66fc99e Initial load
duke
parents:
diff changeset
926 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
927
a61af66fc99e Initial load
duke
parents:
diff changeset
928 uint nlen = use->len();
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
929 uint nl = _node_latency->at_grow(use->_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
930
a61af66fc99e Initial load
duke
parents:
diff changeset
931 for ( uint j=0; j<nlen; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
932 if (use->in(j) == n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
933 // Change this if we want local latencies
a61af66fc99e Initial load
duke
parents:
diff changeset
934 uint ul = use->latency(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
935 uint l = ul + nl;
a61af66fc99e Initial load
duke
parents:
diff changeset
936 if (latency < l) latency = l;
a61af66fc99e Initial load
duke
parents:
diff changeset
937 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
938 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
939 tty->print_cr("# %d + edge_latency(%d) == %d -> %d, latency = %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
940 nl, j, ul, l, latency);
a61af66fc99e Initial load
duke
parents:
diff changeset
941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
942 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
943 }
a61af66fc99e Initial load
duke
parents:
diff changeset
944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
945 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
946 // This is a projection, just grab the latency of the use(s)
a61af66fc99e Initial load
duke
parents:
diff changeset
947 for (DUIterator_Fast jmax, j = use->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
948 uint l = latency_from_use(use, def, use->fast_out(j));
a61af66fc99e Initial load
duke
parents:
diff changeset
949 if (latency < l) latency = l;
a61af66fc99e Initial load
duke
parents:
diff changeset
950 }
a61af66fc99e Initial load
duke
parents:
diff changeset
951 }
a61af66fc99e Initial load
duke
parents:
diff changeset
952
a61af66fc99e Initial load
duke
parents:
diff changeset
953 return latency;
a61af66fc99e Initial load
duke
parents:
diff changeset
954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
955
a61af66fc99e Initial load
duke
parents:
diff changeset
956 //------------------------------latency_from_uses------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // Compute the latency of this instruction relative to all of it's uses.
a61af66fc99e Initial load
duke
parents:
diff changeset
958 // This computes a number that increases as we approach the beginning of the
a61af66fc99e Initial load
duke
parents:
diff changeset
959 // routine.
a61af66fc99e Initial load
duke
parents:
diff changeset
960 void PhaseCFG::latency_from_uses(Node *n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // Set the latency for this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
962 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
963 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
964 tty->print("# latency_from_outputs: node_latency[%d] = %d for node",
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
965 n->_idx, _node_latency->at_grow(n->_idx));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
966 dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
967 }
a61af66fc99e Initial load
duke
parents:
diff changeset
968 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
969 uint latency=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
970 const Node *def = n->is_Proj() ? n->in(0): n;
a61af66fc99e Initial load
duke
parents:
diff changeset
971
a61af66fc99e Initial load
duke
parents:
diff changeset
972 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
973 uint l = latency_from_use(n, def, n->fast_out(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
974
a61af66fc99e Initial load
duke
parents:
diff changeset
975 if (latency < l) latency = l;
a61af66fc99e Initial load
duke
parents:
diff changeset
976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
977
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
978 _node_latency->at_put_grow(n->_idx, latency);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
980
a61af66fc99e Initial load
duke
parents:
diff changeset
981 //------------------------------hoist_to_cheaper_block-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // Pick a block for node self, between early and LCA, that is a cheaper
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // alternative to LCA.
a61af66fc99e Initial load
duke
parents:
diff changeset
984 Block* PhaseCFG::hoist_to_cheaper_block(Block* LCA, Block* early, Node* self) {
a61af66fc99e Initial load
duke
parents:
diff changeset
985 const double delta = 1+PROB_UNLIKELY_MAG(4);
a61af66fc99e Initial load
duke
parents:
diff changeset
986 Block* least = LCA;
a61af66fc99e Initial load
duke
parents:
diff changeset
987 double least_freq = least->_freq;
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
988 uint target = _node_latency->at_grow(self->_idx);
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
989 uint start_latency = _node_latency->at_grow(LCA->_nodes[0]->_idx);
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
990 uint end_latency = _node_latency->at_grow(LCA->_nodes[LCA->end_idx()]->_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
991 bool in_latency = (target <= start_latency);
a61af66fc99e Initial load
duke
parents:
diff changeset
992 const Block* root_block = _bbs[_root->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
993
a61af66fc99e Initial load
duke
parents:
diff changeset
994 // Turn off latency scheduling if scheduling is just plain off
a61af66fc99e Initial load
duke
parents:
diff changeset
995 if (!C->do_scheduling())
a61af66fc99e Initial load
duke
parents:
diff changeset
996 in_latency = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
997
a61af66fc99e Initial load
duke
parents:
diff changeset
998 // Do not hoist (to cover latency) instructions which target a
a61af66fc99e Initial load
duke
parents:
diff changeset
999 // single register. Hoisting stretches the live range of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 // single register and may force spilling.
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 MachNode* mach = self->is_Mach() ? self->as_Mach() : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 if (mach && mach->out_RegMask().is_bound1() && mach->out_RegMask().is_NotEmpty())
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 in_latency = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1004
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 tty->print("# Find cheaper block for latency %d: ",
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
1008 _node_latency->at_grow(self->_idx));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 self->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 tty->print_cr("# B%d: start latency for [%4d]=%d, end latency for [%4d]=%d, freq=%g",
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 LCA->_pre_order,
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 LCA->_nodes[0]->_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 start_latency,
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 LCA->_nodes[LCA->end_idx()]->_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 end_latency,
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 least_freq);
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1019
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 // Walk up the dominator tree from LCA (Lowest common ancestor) to
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 // the earliest legal location. Capture the least execution frequency.
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 while (LCA != early) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 LCA = LCA->_idom; // Follow up the dominator tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 if (LCA == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 // Bailout without retry
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 C->record_method_not_compilable("late schedule failed: LCA == NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 return least;
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1030
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 // Don't hoist machine instructions to the root basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 if (mach && LCA == root_block)
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
1035 uint start_lat = _node_latency->at_grow(LCA->_nodes[0]->_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 uint end_idx = LCA->end_idx();
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
1037 uint end_lat = _node_latency->at_grow(LCA->_nodes[end_idx]->_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 double LCA_freq = LCA->_freq;
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 tty->print_cr("# B%d: start latency for [%4d]=%d, end latency for [%4d]=%d, freq=%g",
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 LCA->_pre_order, LCA->_nodes[0]->_idx, start_lat, end_idx, end_lat, LCA_freq);
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 if (LCA_freq < least_freq || // Better Frequency
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 ( !in_latency && // No block containing latency
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 LCA_freq < least_freq * delta && // No worse frequency
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 target >= end_lat && // within latency range
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 !self->is_iteratively_computed() ) // But don't hoist IV increments
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 // because they may end up above other uses of their phi forcing
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // their result register to be different from their input.
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 least = LCA; // Found cheaper block
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 least_freq = LCA_freq;
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 start_latency = start_lat;
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 end_latency = end_lat;
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 if (target <= start_lat)
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 in_latency = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1061
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 tty->print_cr("# Choose block B%d with start latency=%d and freq=%g",
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 least->_pre_order, start_latency, least_freq);
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1068
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // See if the latency needs to be updated
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 if (target < end_latency) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 tty->print_cr("# Change latency for [%4d] from %d to %d", self->_idx, target, end_latency);
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 #endif
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
1076 _node_latency->at_put_grow(self->_idx, end_latency);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 partial_latency_of_defs(self);
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1079
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 return least;
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1082
a61af66fc99e Initial load
duke
parents:
diff changeset
1083
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 //------------------------------schedule_late-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 // Now schedule all codes as LATE as possible. This is the LCA in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 // dominator tree of all USES of a value. Pick the block with the least
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 // loop nesting depth that is lowest in the dominator tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 extern const char must_clone[];
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 void PhaseCFG::schedule_late(VectorSet &visited, Node_List &stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 if (trace_opto_pipelining())
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 tty->print("\n#---- schedule_late ----\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1094
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 Node_Backward_Iterator iter((Node *)_root, visited, stack, _bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 Node *self;
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 // Walk over all the nodes from last to first
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 while (self = iter.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 Block* early = _bbs[self->_idx]; // Earliest legal placement
a61af66fc99e Initial load
duke
parents:
diff changeset
1101
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 if (self->is_top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 // Top node goes in bb #2 with other constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 // It must be special-cased, because it has no out edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 early->add_inst(self);
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1108
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // No uses, just terminate
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 if (self->outcnt() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 assert(self->Opcode() == Op_MachProj, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 continue; // Must be a dead machine projection
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1114
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 // If node is pinned in the block, then no scheduling can be done.
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 if( self->pinned() ) // Pinned in block?
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1118
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 MachNode* mach = self->is_Mach() ? self->as_Mach() : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 if (mach) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 switch (mach->ideal_Opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 case Op_CreateEx:
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 // Don't move exception creation
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 early->add_inst(self);
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 case Op_CheckCastPP:
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // Don't move CheckCastPP nodes away from their input, if the input
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 // is a rawptr (5071820).
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 Node *def = self->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 if (def != NULL && def->bottom_type()->base() == Type::RawPtr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 early->add_inst(self);
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 788
diff changeset
1133 #ifdef ASSERT
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 788
diff changeset
1134 _raw_oops.push(def);
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 788
diff changeset
1135 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1141
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // Gather LCA of all uses
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 Block *LCA = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 for (DUIterator_Fast imax, i = self->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // For all uses, find LCA
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 Node* use = self->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 LCA = raise_LCA_above_use(LCA, use, self, _bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 } // (Hide defs of imax, i from rest of block.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1151
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // Place temps in the block of their use. This isn't a
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // requirement for correctness but it reduces useless
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // interference between temps and other nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 if (mach != NULL && mach->is_MachTemp()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 _bbs.map(self->_idx, LCA);
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 LCA->add_inst(self);
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // Check if 'self' could be anti-dependent on memory
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 if (self->needs_anti_dependence_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 // Hoist LCA above possible-defs and insert anti-dependences to
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 // defs in new LCA block.
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 LCA = insert_anti_dependences(LCA, self);
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1167
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 if (early->_dom_depth > LCA->_dom_depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 // Somehow the LCA has moved above the earliest legal point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 // (One way this can happen is via memory_early_block.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 if (C->subsume_loads() == true && !C->failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 // Retry with subsume_loads == false
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // If this is the first failure, the sentinel string will "stick"
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // to the Compile object, and the C2Compiler will see it and retry.
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 C->record_failure(C2Compiler::retry_no_subsuming_loads());
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // Bailout without retry when (early->_dom_depth > LCA->_dom_depth)
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 C->record_method_not_compilable("late schedule failed: incorrect graph");
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1182
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 // If there is no opportunity to hoist, then we're done.
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 bool try_to_hoist = (LCA != early);
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 // Must clone guys stay next to use; no hoisting allowed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 // Also cannot hoist guys that alter memory or are otherwise not
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 // allocatable (hoisting can make a value live longer, leading to
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 // anti and output dependency problems which are normally resolved
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 // by the register allocator giving everyone a different register).
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 if (mach != NULL && must_clone[mach->ideal_Opcode()])
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 try_to_hoist = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1193
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 Block* late = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 if (try_to_hoist) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // Now find the block with the least execution frequency.
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // Start at the latest schedule and work up to the earliest schedule
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // in the dominator tree. Thus the Node will dominate all its uses.
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 late = hoist_to_cheaper_block(LCA, early, self);
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 // Just use the LCA of the uses.
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 late = LCA;
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1204
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 // Put the node into target block
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 schedule_node_into_block(self, late);
a61af66fc99e Initial load
duke
parents:
diff changeset
1207
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 if (self->needs_anti_dependence_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 // since precedence edges are only inserted when we're sure they
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 // are needed make sure that after placement in a block we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 // need any new precedence edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 verify_anti_dependences(late, self);
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 } // Loop until all nodes have been visited
a61af66fc99e Initial load
duke
parents:
diff changeset
1217
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 } // end ScheduleLate
a61af66fc99e Initial load
duke
parents:
diff changeset
1219
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 //------------------------------GlobalCodeMotion-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_list ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1223
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 tty->print("\n---- Start GlobalCodeMotion ----\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1229
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 // Initialize the bbs.map for things on the proj_list
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 for( i=0; i < proj_list.size(); i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 _bbs.map(proj_list[i]->_idx, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1234
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 // Set the basic block for Nodes pinned into blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 Arena *a = Thread::current()->resource_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 VectorSet visited(a);
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 schedule_pinned_nodes( visited );
a61af66fc99e Initial load
duke
parents:
diff changeset
1239
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 // Find the earliest Block any instruction can be placed in. Some
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 // instructions are pinned into Blocks. Unpinned instructions can
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 // appear in last block in which all their inputs occur.
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 visited.Clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 Node_List stack(a);
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 stack.map( (unique >> 1) + 16, NULL); // Pre-grow the list
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 if (!schedule_early(visited, stack)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 // Bailout without retry
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 C->record_method_not_compilable("early schedule failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1251
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 // Build Def-Use edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 proj_list.push(_root); // Add real root as another root
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 proj_list.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1255
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 // Compute the latency information (via backwards walk) for all the
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 // instructions in the graph
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
1258 _node_latency = new GrowableArray<uint>(); // resource_area allocation
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1259
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 if( C->do_scheduling() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 ComputeLatenciesBackwards(visited, stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
1262
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // Now schedule all codes as LATE as possible. This is the LCA in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 // dominator tree of all USES of a value. Pick the block with the least
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 // loop nesting depth that is lowest in the dominator tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 // ( visited.Clear() called in schedule_late()->Node_Backward_Iterator() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 schedule_late(visited, stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 if( C->failing() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 // schedule_late fails only when graph is incorrect.
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 assert(!VerifyGraphEdges, "verification should have failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1273
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 unique = C->unique();
a61af66fc99e Initial load
duke
parents:
diff changeset
1275
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 tty->print("\n---- Detect implicit null checks ----\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1281
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // Detect implicit-null-check opportunities. Basically, find NULL checks
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // with suitable memory ops nearby. Use the memory op to do the NULL check.
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // I can generate a memory op if there is not one nearby.
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 if (C->is_method_compilation()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 // Don't do it for natives, adapters, or runtime stubs
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 int allowed_reasons = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // ...and don't do it when there have been too many traps, globally.
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 for (int reason = (int)Deoptimization::Reason_none+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 reason < Compile::trapHistLength; reason++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 assert(reason < BitsPerInt, "recode bit map");
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 if (!C->too_many_traps((Deoptimization::DeoptReason) reason))
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 allowed_reasons |= nth_bit(reason);
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // By reversing the loop direction we get a very minor gain on mpegaudio.
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 // Feel free to revert to a forward loop for clarity.
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // for( int i=0; i < (int)matcher._null_check_tests.size(); i+=2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 for( int i= matcher._null_check_tests.size()-2; i>=0; i-=2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 Node *proj = matcher._null_check_tests[i ];
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 Node *val = matcher._null_check_tests[i+1];
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 _bbs[proj->_idx]->implicit_null_check(this, proj, val, allowed_reasons);
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 // The implicit_null_check will only perform the transformation
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 // if the null branch is truly uncommon, *and* it leads to an
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // uncommon trap. Combined with the too_many_traps guards
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // above, this prevents SEGV storms reported in 6366351,
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 // by recompiling offending methods without this optimization.
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1309
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 tty->print("\n---- Start Local Scheduling ----\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1315
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // Schedule locally. Right now a simple topological sort.
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 // Later, do a real latency aware scheduler.
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 int *ready_cnt = NEW_RESOURCE_ARRAY(int,C->unique());
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 memset( ready_cnt, -1, C->unique() * sizeof(int) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 visited.Clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 for (i = 0; i < _num_blocks; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 if (!_blocks[i]->schedule_local(this, matcher, ready_cnt, visited)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 C->record_method_not_compilable("local schedule failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1329
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 // If we inserted any instructions between a Call and his CatchNode,
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 // clone the instructions on all paths below the Catch.
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 for( i=0; i < _num_blocks; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 _blocks[i]->call_catch_cleanup(_bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1334
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 if (trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 tty->print("\n---- After GlobalCodeMotion ----\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 for (uint i = 0; i < _num_blocks; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 _blocks[i]->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 #endif
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
1343 // Dead.
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
1344 _node_latency = (GrowableArray<uint> *)0xdeadbeef;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1346
a61af66fc99e Initial load
duke
parents:
diff changeset
1347
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 //------------------------------Estimate_Block_Frequency-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 // Estimate block frequencies based on IfNode probabilities.
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 void PhaseCFG::Estimate_Block_Frequency() {
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1351
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1352 // Force conditional branches leading to uncommon traps to be unlikely,
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1353 // not because we get to the uncommon_trap with less relative frequency,
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1354 // but because an uncommon_trap typically causes a deopt, so we only get
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1355 // there once.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1356 if (C->do_freq_based_layout()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1357 Block_List worklist;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1358 Block* root_blk = _blocks[0];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1359 for (uint i = 1; i < root_blk->num_preds(); i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1360 Block *pb = _bbs[root_blk->pred(i)->_idx];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1361 if (pb->has_uncommon_code()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1362 worklist.push(pb);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1363 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1364 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1365 while (worklist.size() > 0) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1366 Block* uct = worklist.pop();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1367 if (uct == _broot) continue;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1368 for (uint i = 1; i < uct->num_preds(); i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1369 Block *pb = _bbs[uct->pred(i)->_idx];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1370 if (pb->_num_succs == 1) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1371 worklist.push(pb);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1372 } else if (pb->num_fall_throughs() == 2) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1373 pb->update_uncommon_branch(uct);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1374 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1375 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1376 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1377 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1378
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 // Create the loop tree and calculate loop depth.
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 _root_loop = create_loop_tree();
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 _root_loop->compute_loop_depth(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1382
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 // Compute block frequency of each block, relative to a single loop entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 _root_loop->compute_freq();
a61af66fc99e Initial load
duke
parents:
diff changeset
1385
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 // Adjust all frequencies to be relative to a single method entry
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1387 _root_loop->_freq = 1.0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 _root_loop->scale_freq();
a61af66fc99e Initial load
duke
parents:
diff changeset
1389
673
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1390 // Save outmost loop frequency for LRG frequency threshold
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1391 _outer_loop_freq = _root_loop->outer_loop_freq();
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1392
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 // force paths ending at uncommon traps to be infrequent
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1394 if (!C->do_freq_based_layout()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1395 Block_List worklist;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1396 Block* root_blk = _blocks[0];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1397 for (uint i = 1; i < root_blk->num_preds(); i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1398 Block *pb = _bbs[root_blk->pred(i)->_idx];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1399 if (pb->has_uncommon_code()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1400 worklist.push(pb);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1401 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 }
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1403 while (worklist.size() > 0) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1404 Block* uct = worklist.pop();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1405 uct->_freq = PROB_MIN;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1406 for (uint i = 1; i < uct->num_preds(); i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1407 Block *pb = _bbs[uct->pred(i)->_idx];
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1408 if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1409 worklist.push(pb);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1410 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1414
552
011517bbcd7b 6784930: server jvm fails with assert(!n->is_SpillCopy(),"")
kvn
parents: 418
diff changeset
1415 #ifdef ASSERT
011517bbcd7b 6784930: server jvm fails with assert(!n->is_SpillCopy(),"")
kvn
parents: 418
diff changeset
1416 for (uint i = 0; i < _num_blocks; i++ ) {
011517bbcd7b 6784930: server jvm fails with assert(!n->is_SpillCopy(),"")
kvn
parents: 418
diff changeset
1417 Block *b = _blocks[i];
605
98cb887364d3 6810672: Comment typos
twisti
parents: 601
diff changeset
1418 assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requires meaningful block frequency");
552
011517bbcd7b 6784930: server jvm fails with assert(!n->is_SpillCopy(),"")
kvn
parents: 418
diff changeset
1419 }
011517bbcd7b 6784930: server jvm fails with assert(!n->is_SpillCopy(),"")
kvn
parents: 418
diff changeset
1420 #endif
011517bbcd7b 6784930: server jvm fails with assert(!n->is_SpillCopy(),"")
kvn
parents: 418
diff changeset
1421
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 if (PrintCFGBlockFreq) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 tty->print_cr("CFG Block Frequencies");
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 _root_loop->dump_tree();
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 tty->print_cr("PhaseCFG dump");
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 tty->print_cr("Node dump");
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 _root->dump(99999);
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1435
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 //----------------------------create_loop_tree--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 // Create a loop tree from the CFG
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 CFGLoop* PhaseCFG::create_loop_tree() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1439
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 assert( _blocks[0] == _broot, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 for (uint i = 0; i < _num_blocks; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 Block *b = _blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 // Check that _loop field are clear...we could clear them if not.
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 assert(b->_loop == NULL, "clear _loop expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // Sanity check that the RPO numbering is reflected in the _blocks array.
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 // It doesn't have to be for the loop tree to be built, but if it is not,
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 // then the blocks have been reordered since dom graph building...which
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 // may question the RPO numbering
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 assert(b->_rpo == i, "unexpected reverse post order number");
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1453
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 int idct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 CFGLoop* root_loop = new CFGLoop(idct++);
a61af66fc99e Initial load
duke
parents:
diff changeset
1456
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 Block_List worklist;
a61af66fc99e Initial load
duke
parents:
diff changeset
1458
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // Assign blocks to loops
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 for(uint i = _num_blocks - 1; i > 0; i-- ) { // skip Root block
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 Block *b = _blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1462
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 if (b->head()->is_Loop()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 Block* loop_head = b;
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 assert(loop_head->num_preds() - 1 == 2, "loop must have 2 predecessors");
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 Node* tail_n = loop_head->pred(LoopNode::LoopBackControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 Block* tail = _bbs[tail_n->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1468
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 // Defensively filter out Loop nodes for non-single-entry loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 // For all reasonable loops, the head occurs before the tail in RPO.
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 if (i <= tail->_rpo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1472
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 // The tail and (recursive) predecessors of the tail
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 // are made members of a new loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1475
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 assert(worklist.size() == 0, "nonempty worklist");
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 CFGLoop* nloop = new CFGLoop(idct++);
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 assert(loop_head->_loop == NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 loop_head->_loop = nloop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 // Add to nloop so push_pred() will skip over inner loops
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 nloop->add_member(loop_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 nloop->push_pred(loop_head, LoopNode::LoopBackControl, worklist, _bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1483
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 while (worklist.size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 Block* member = worklist.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 if (member != loop_head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 for (uint j = 1; j < member->num_preds(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 nloop->push_pred(member, j, worklist, _bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1495
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 // Create a member list for each loop consisting
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 // of both blocks and (immediate child) loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 for (uint i = 0; i < _num_blocks; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 Block *b = _blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 CFGLoop* lp = b->_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 if (lp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 // Not assigned to a loop. Add it to the method's pseudo loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 b->_loop = root_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 lp = root_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 if (lp == root_loop || b != lp->head()) { // loop heads are already members
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 lp->add_member(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 if (lp != root_loop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 if (lp->parent() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 // Not a nested loop. Make it a child of the method's pseudo loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 root_loop->add_nested_loop(lp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 if (b == lp->head()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 // Add nested loop to member list of parent loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 lp->parent()->add_member(lp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1520
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 return root_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1523
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 //------------------------------push_pred--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 void CFGLoop::push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 Node* pred_n = blk->pred(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 Block* pred = node_to_blk[pred_n->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 CFGLoop *pred_loop = pred->_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 if (pred_loop == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 // Filter out blocks for non-single-entry loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 // For all reasonable loops, the head occurs before the tail in RPO.
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 if (pred->_rpo > head()->_rpo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 pred->_loop = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 worklist.push(pred);
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 } else if (pred_loop != this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 // Nested loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 while (pred_loop->_parent != NULL && pred_loop->_parent != this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 pred_loop = pred_loop->_parent;
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 // Make pred's loop be a child
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 if (pred_loop->_parent == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 add_nested_loop(pred_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 // Continue with loop entry predecessor.
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 Block* pred_head = pred_loop->head();
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 assert(pred_head->num_preds() - 1 == 2, "loop must have 2 predecessors");
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 assert(pred_head != head(), "loop head in only one loop");
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 push_pred(pred_head, LoopNode::EntryControl, worklist, node_to_blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 assert(pred_loop->_parent == this && _parent == NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1554
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 //------------------------------add_nested_loop--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 // Make cl a child of the current loop in the loop tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 void CFGLoop::add_nested_loop(CFGLoop* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 assert(_parent == NULL, "no parent yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 assert(cl != this, "not my own parent");
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 cl->_parent = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 CFGLoop* ch = _child;
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 if (ch == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 _child = cl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 while (ch->_sibling != NULL) { ch = ch->_sibling; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 ch->_sibling = cl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1569
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 //------------------------------compute_loop_depth-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 // Store the loop depth in each CFGLoop object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 // Recursively walk the children to do the same for them.
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 void CFGLoop::compute_loop_depth(int depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 _depth = depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 CFGLoop* ch = _child;
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 while (ch != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 ch->compute_loop_depth(depth + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 ch = ch->_sibling;
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1581
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 //------------------------------compute_freq-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 // Compute the frequency of each block and loop, relative to a single entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 // into the dominating loop head.
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 void CFGLoop::compute_freq() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 // Bottom up traversal of loop tree (visit inner loops first.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 // Set loop head frequency to 1.0, then transitively
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 // compute frequency for all successors in the loop,
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 // as well as for each exit edge. Inner loops are
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 // treated as single blocks with loop exit targets
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 // as the successor blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1592
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 // Nested loops first
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 CFGLoop* ch = _child;
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 while (ch != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 ch->compute_freq();
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 ch = ch->_sibling;
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 assert (_members.length() > 0, "no empty loops");
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 Block* hd = head();
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 hd->_freq = 1.0f;
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 for (int i = 0; i < _members.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 CFGElement* s = _members.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 float freq = s->_freq;
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 if (s->is_block()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 Block* b = s->as_Block();
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 for (uint j = 0; j < b->_num_succs; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 Block* sb = b->_succs[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 update_succ_freq(sb, freq * b->succ_prob(j));
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 CFGLoop* lp = s->as_CFGLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 assert(lp->_parent == this, "immediate child");
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 for (int k = 0; k < lp->_exits.length(); k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 Block* eb = lp->_exits.at(k).get_target();
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 float prob = lp->_exits.at(k).get_prob();
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 update_succ_freq(eb, freq * prob);
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1621
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // For all loops other than the outer, "method" loop,
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 // sum and normalize the exit probability. The "method" loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 // should keep the initial exit probability of 1, so that
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 // inner blocks do not get erroneously scaled.
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 if (_depth != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 // Total the exit probabilities for this loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 float exits_sum = 0.0f;
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 for (int i = 0; i < _exits.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 exits_sum += _exits.at(i).get_prob();
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1632
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // Normalize the exit probabilities. Until now, the
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 // probabilities estimate the possibility of exit per
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // a single loop iteration; afterward, they estimate
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 // the probability of exit per loop entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 for (int i = 0; i < _exits.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 Block* et = _exits.at(i).get_target();
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1639 float new_prob = 0.0f;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1640 if (_exits.at(i).get_prob() > 0.0f) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1641 new_prob = _exits.at(i).get_prob() / exits_sum;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1642 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 BlockProbPair bpp(et, new_prob);
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 _exits.at_put(i, bpp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1646
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1647 // Save the total, but guard against unreasonable probability,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // as the value is used to estimate the loop trip count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 // An infinite trip count would blur relative block
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 // frequencies.
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 if (exits_sum > 1.0f) exits_sum = 1.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 if (exits_sum < PROB_MIN) exits_sum = PROB_MIN;
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 _exit_prob = exits_sum;
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1656
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 //------------------------------succ_prob-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 // Determine the probability of reaching successor 'i' from the receiver block.
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 float Block::succ_prob(uint i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 int eidx = end_idx();
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 Node *n = _nodes[eidx]; // Get ending Node
308
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1662
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1663 int op = n->Opcode();
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1664 if (n->is_Mach()) {
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1665 if (n->is_MachNullCheck()) {
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1666 // Can only reach here if called after lcm. The original Op_If is gone,
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1667 // so we attempt to infer the probability from one or both of the
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1668 // successor blocks.
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1669 assert(_num_succs == 2, "expecting 2 successors of a null check");
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1670 // If either successor has only one predecessor, then the
605
98cb887364d3 6810672: Comment typos
twisti
parents: 601
diff changeset
1671 // probability estimate can be derived using the
308
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1672 // relative frequency of the successor and this block.
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1673 if (_succs[i]->num_preds() == 2) {
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1674 return _succs[i]->_freq / _freq;
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1675 } else if (_succs[1-i]->num_preds() == 2) {
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1676 return 1 - (_succs[1-i]->_freq / _freq);
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1677 } else {
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1678 // Estimate using both successor frequencies
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1679 float freq = _succs[i]->_freq;
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1680 return freq / (freq + _succs[1-i]->_freq);
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1681 }
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1682 }
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1683 op = n->as_Mach()->ideal_Opcode();
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1684 }
756b58154237 6611837: block frequency is zero
rasbold
parents: 235
diff changeset
1685
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1686
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 // Switch on branch type
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 switch( op ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 case Op_CountedLoopEnd:
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 case Op_If: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 assert (i < 2, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 // Conditionals pass on only part of their frequency
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 float prob = n->as_MachIf()->_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 assert(prob >= 0.0 && prob <= 1.0, "out of range probability");
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 // If succ[i] is the FALSE branch, invert path info
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 if( _nodes[i + eidx + 1]->Opcode() == Op_IfFalse ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 return 1.0f - prob; // not taken
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 return prob; // taken
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1702
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 case Op_Jump:
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // Divide the frequency between all successors evenly
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 return 1.0f/_num_succs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1706
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 case Op_Catch: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 if (ci->_con == CatchProjNode::fall_through_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 // Fall-thru path gets the lion's share.
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 return 1.0f - PROB_UNLIKELY_MAG(5)*_num_succs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 // Presume exceptional paths are equally unlikely
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 return PROB_UNLIKELY_MAG(5);
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1717
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 case Op_Root:
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 case Op_Goto:
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 // Pass frequency straight thru to target
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 return 1.0f;
a61af66fc99e Initial load
duke
parents:
diff changeset
1722
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 case Op_NeverBranch:
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 return 0.0f;
a61af66fc99e Initial load
duke
parents:
diff changeset
1725
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 case Op_TailCall:
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 case Op_TailJump:
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 case Op_Return:
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 case Op_Halt:
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 case Op_Rethrow:
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 // Do not push out freq to root block
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 return 0.0f;
a61af66fc99e Initial load
duke
parents:
diff changeset
1733
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1737
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 return 0.0f;
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1740
418
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1741 //------------------------------num_fall_throughs-----------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1742 // Return the number of fall-through candidates for a block
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1743 int Block::num_fall_throughs() {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1744 int eidx = end_idx();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1745 Node *n = _nodes[eidx]; // Get ending Node
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1746
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1747 int op = n->Opcode();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1748 if (n->is_Mach()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1749 if (n->is_MachNullCheck()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1750 // In theory, either side can fall-thru, for simplicity sake,
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1751 // let's say only the false branch can now.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1752 return 1;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1753 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1754 op = n->as_Mach()->ideal_Opcode();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1755 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1756
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1757 // Switch on branch type
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1758 switch( op ) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1759 case Op_CountedLoopEnd:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1760 case Op_If:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1761 return 2;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1762
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1763 case Op_Root:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1764 case Op_Goto:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1765 return 1;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1766
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1767 case Op_Catch: {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1768 for (uint i = 0; i < _num_succs; i++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1769 const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1770 if (ci->_con == CatchProjNode::fall_through_index) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1771 return 1;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1772 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1773 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1774 return 0;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1775 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1776
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1777 case Op_Jump:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1778 case Op_NeverBranch:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1779 case Op_TailCall:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1780 case Op_TailJump:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1781 case Op_Return:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1782 case Op_Halt:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1783 case Op_Rethrow:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1784 return 0;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1785
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1786 default:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1787 ShouldNotReachHere();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1788 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1789
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1790 return 0;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1791 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1792
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1793 //------------------------------succ_fall_through-----------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1794 // Return true if a specific successor could be fall-through target.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1795 bool Block::succ_fall_through(uint i) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1796 int eidx = end_idx();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1797 Node *n = _nodes[eidx]; // Get ending Node
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1798
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1799 int op = n->Opcode();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1800 if (n->is_Mach()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1801 if (n->is_MachNullCheck()) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1802 // In theory, either side can fall-thru, for simplicity sake,
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1803 // let's say only the false branch can now.
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1804 return _nodes[i + eidx + 1]->Opcode() == Op_IfFalse;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1805 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1806 op = n->as_Mach()->ideal_Opcode();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1807 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1808
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1809 // Switch on branch type
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1810 switch( op ) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1811 case Op_CountedLoopEnd:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1812 case Op_If:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1813 case Op_Root:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1814 case Op_Goto:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1815 return true;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1816
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1817 case Op_Catch: {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1818 const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1819 return ci->_con == CatchProjNode::fall_through_index;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1820 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1821
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1822 case Op_Jump:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1823 case Op_NeverBranch:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1824 case Op_TailCall:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1825 case Op_TailJump:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1826 case Op_Return:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1827 case Op_Halt:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1828 case Op_Rethrow:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1829 return false;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1830
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1831 default:
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1832 ShouldNotReachHere();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1833 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1834
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1835 return false;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1836 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1837
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1838 //------------------------------update_uncommon_branch------------------------
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1839 // Update the probability of a two-branch to be uncommon
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1840 void Block::update_uncommon_branch(Block* ub) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1841 int eidx = end_idx();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1842 Node *n = _nodes[eidx]; // Get ending Node
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1843
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1844 int op = n->as_Mach()->ideal_Opcode();
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1845
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1846 assert(op == Op_CountedLoopEnd || op == Op_If, "must be a If");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1847 assert(num_fall_throughs() == 2, "must be a two way branch block");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1848
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1849 // Which successor is ub?
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1850 uint s;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1851 for (s = 0; s <_num_succs; s++) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1852 if (_succs[s] == ub) break;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1853 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1854 assert(s < 2, "uncommon successor must be found");
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1855
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1856 // If ub is the true path, make the proability small, else
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1857 // ub is the false path, and make the probability large
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1858 bool invert = (_nodes[s + eidx + 1]->Opcode() == Op_IfFalse);
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1859
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1860 // Get existing probability
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1861 float p = n->as_MachIf()->_prob;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1862
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1863 if (invert) p = 1.0 - p;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1864 if (p > PROB_MIN) {
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1865 p = PROB_MIN;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1866 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1867 if (invert) p = 1.0 - p;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1868
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1869 n->as_MachIf()->_prob = p;
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1870 }
72c5366e5d86 6743900: frequency based block layout
rasbold
parents: 308
diff changeset
1871
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 //------------------------------update_succ_freq-------------------------------
605
98cb887364d3 6810672: Comment typos
twisti
parents: 601
diff changeset
1873 // Update the appropriate frequency associated with block 'b', a successor of
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 // a block in this loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 void CFGLoop::update_succ_freq(Block* b, float freq) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 if (b->_loop == this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 if (b == head()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 // back branch within the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 // Do nothing now, the loop carried frequency will be
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 // adjust later in scale_freq().
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 // simple branch within the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 b->_freq += freq;
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 } else if (!in_loop_nest(b)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 // branch is exit from this loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 BlockProbPair bpp(b, freq);
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 _exits.append(bpp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 // branch into nested loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 CFGLoop* ch = b->_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 ch->_freq += freq;
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1895
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 //------------------------------in_loop_nest-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 // Determine if block b is in the receiver's loop nest.
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 bool CFGLoop::in_loop_nest(Block* b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 int depth = _depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 CFGLoop* b_loop = b->_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 int b_depth = b_loop->_depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 if (depth == b_depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 while (b_depth > depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 b_loop = b_loop->_parent;
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 b_depth = b_loop->_depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 return b_loop == this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1911
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 //------------------------------scale_freq-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 // Scale frequency of loops and blocks by trip counts from outer loops
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 // Do a top down traversal of loop tree (visit outer loops first.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 void CFGLoop::scale_freq() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 float loop_freq = _freq * trip_count();
673
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1917 _freq = loop_freq;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 for (int i = 0; i < _members.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 CFGElement* s = _members.at(i);
552
011517bbcd7b 6784930: server jvm fails with assert(!n->is_SpillCopy(),"")
kvn
parents: 418
diff changeset
1920 float block_freq = s->_freq * loop_freq;
621
19f25e603e7b 6812721: Block's frequency should not be NaN
kvn
parents: 605
diff changeset
1921 if (g_isnan(block_freq) || block_freq < MIN_BLOCK_FREQUENCY)
19f25e603e7b 6812721: Block's frequency should not be NaN
kvn
parents: 605
diff changeset
1922 block_freq = MIN_BLOCK_FREQUENCY;
552
011517bbcd7b 6784930: server jvm fails with assert(!n->is_SpillCopy(),"")
kvn
parents: 418
diff changeset
1923 s->_freq = block_freq;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 CFGLoop* ch = _child;
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 while (ch != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 ch->scale_freq();
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 ch = ch->_sibling;
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1931
673
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1932 // Frequency of outer loop
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1933 float CFGLoop::outer_loop_freq() const {
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1934 if (_child != NULL) {
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1935 return _child->_freq;
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1936 }
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1937 return _freq;
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1938 }
fbc12e71c476 6810845: Performance regression in mpegaudio on x64
kvn
parents: 628
diff changeset
1939
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 //------------------------------dump_tree--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 void CFGLoop::dump_tree() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 if (_child != NULL) _child->dump_tree();
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 if (_sibling != NULL) _sibling->dump_tree();
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1947
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 //------------------------------dump-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 void CFGLoop::dump() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 for (int i = 0; i < _depth; i++) tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 tty->print("%s: %d trip_count: %6.0f freq: %6.0f\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 _depth == 0 ? "Method" : "Loop", _id, trip_count(), _freq);
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 for (int i = 0; i < _depth; i++) tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 tty->print(" members:", _id);
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 int k = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 for (int i = 0; i < _members.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 if (k++ >= 6) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 tty->print("\n ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 for (int j = 0; j < _depth+1; j++) tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 k = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 CFGElement *s = _members.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 if (s->is_block()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 Block *b = s->as_Block();
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 tty->print(" B%d(%6.3f)", b->_pre_order, b->_freq);
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 CFGLoop* lp = s->as_CFGLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 tty->print(" L%d(%6.3f)", lp->_id, lp->_freq);
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 for (int i = 0; i < _depth; i++) tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 tty->print(" exits: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 k = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 for (int i = 0; i < _exits.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 if (k++ >= 7) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 tty->print("\n ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 for (int j = 0; j < _depth+1; j++) tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 k = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 Block *blk = _exits.at(i).get_target();
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 float prob = _exits.at(i).get_prob();
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 tty->print(" ->%d@%d%%", blk->_pre_order, (int)(prob*100));
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 #endif