annotate src/share/vm/opto/gcm.cpp @ 6972:bd7a7ce2e264

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