annotate src/share/vm/opto/gcm.cpp @ 1994:6cd6d394f280

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