annotate src/share/vm/opto/gcm.cpp @ 17716:cdb71841f4bc

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