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

7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed()) 7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages. Reviewed-by: johnc, tonyp
author ysr
date Tue, 07 Dec 2010 21:55:53 -0800
parents f95d63e2154a
children 7e88bdae86ec e6beb62de02d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1693
diff changeset
2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1151
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1151
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: 1151
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: 1748
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
26 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
27 #include "opto/block.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
28 #include "opto/c2compiler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
29 #include "opto/callnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
30 #include "opto/cfgnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
31 #include "opto/machnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
32 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
33 #ifdef TARGET_ARCH_MODEL_x86_32
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
34 # include "adfiles/ad_x86_32.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
35 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
36 #ifdef TARGET_ARCH_MODEL_x86_64
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
37 # include "adfiles/ad_x86_64.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
38 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
39 #ifdef TARGET_ARCH_MODEL_sparc
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
40 # include "adfiles/ad_sparc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
41 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
42 #ifdef TARGET_ARCH_MODEL_zero
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
43 # include "adfiles/ad_zero.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
44 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
45
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
46 // Optimization - Graph Style
0
a61af66fc99e Initial load
duke
parents:
diff changeset
47
a61af66fc99e Initial load
duke
parents:
diff changeset
48 //------------------------------implicit_null_check----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // Detect implicit-null-check opportunities. Basically, find NULL checks
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // with suitable memory ops nearby. Use the memory op to do the NULL check.
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // I can generate a memory op if there is not one nearby.
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // The proj is the control projection for the not-null case.
1575
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
53 // The val is the pointer being checked for nullness or
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
54 // decodeHeapOop_not_null node if it did not fold into address.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
55 void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) {
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // Assume if null check need for 0 offset then always needed
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // Intel solaris doesn't support any null checks yet and no
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // mechanism exists (yet) to set the switches at an os_cpu level
a61af66fc99e Initial load
duke
parents:
diff changeset
59 if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // Make sure the ptr-is-null path appears to be uncommon!
a61af66fc99e Initial load
duke
parents:
diff changeset
62 float f = end()->as_MachIf()->_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 if( proj->Opcode() == Op_IfTrue ) f = 1.0f - f;
a61af66fc99e Initial load
duke
parents:
diff changeset
64 if( f > PROB_UNLIKELY_MAG(4) ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66 uint bidx = 0; // Capture index of value into memop
a61af66fc99e Initial load
duke
parents:
diff changeset
67 bool was_store; // Memory op is a store op
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // Get the successor block for if the test ptr is non-null
a61af66fc99e Initial load
duke
parents:
diff changeset
70 Block* not_null_block; // this one goes with the proj
a61af66fc99e Initial load
duke
parents:
diff changeset
71 Block* null_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 if (_nodes[_nodes.size()-1] == proj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
73 null_block = _succs[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
74 not_null_block = _succs[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
75 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 assert(_nodes[_nodes.size()-2] == proj, "proj is one or the other");
a61af66fc99e Initial load
duke
parents:
diff changeset
77 not_null_block = _succs[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
78 null_block = _succs[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
79 }
332
c792b641b8bd 6746907: Improve implicit null check generation
kvn
parents: 253
diff changeset
80 while (null_block->is_Empty() == Block::empty_with_goto) {
c792b641b8bd 6746907: Improve implicit null check generation
kvn
parents: 253
diff changeset
81 null_block = null_block->_succs[0];
c792b641b8bd 6746907: Improve implicit null check generation
kvn
parents: 253
diff changeset
82 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // Search the exception block for an uncommon trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // (See Parse::do_if and Parse::do_ifnull for the reason
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // we need an uncommon trap. Briefly, we need a way to
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // detect failure of this optimization, as in 6366351.)
a61af66fc99e Initial load
duke
parents:
diff changeset
88 {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 bool found_trap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 for (uint i1 = 0; i1 < null_block->_nodes.size(); i1++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 Node* nn = null_block->_nodes[i1];
a61af66fc99e Initial load
duke
parents:
diff changeset
92 if (nn->is_MachCall() &&
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1693
diff changeset
93 nn->as_MachCall()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
94 const Type* trtype = nn->in(TypeFunc::Parms)->bottom_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
95 if (trtype->isa_int() && trtype->is_int()->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 jint tr_con = trtype->is_int()->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
97 Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(tr_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
98 Deoptimization::DeoptAction action = Deoptimization::trap_request_action(tr_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
99 assert((int)reason < (int)BitsPerInt, "recode bit map");
a61af66fc99e Initial load
duke
parents:
diff changeset
100 if (is_set_nth_bit(allowed_reasons, (int) reason)
a61af66fc99e Initial load
duke
parents:
diff changeset
101 && action != Deoptimization::Action_none) {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // This uncommon trap is sure to recompile, eventually.
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // When that happens, C->too_many_traps will prevent
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // this transformation from happening again.
a61af66fc99e Initial load
duke
parents:
diff changeset
105 found_trap = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111 if (!found_trap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // We did not find an uncommon trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
113 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116
1575
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
117 // Check for decodeHeapOop_not_null node which did not fold into address
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
118 bool is_decoden = ((intptr_t)val) & 1;
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
119 val = (Node*)(((intptr_t)val) & ~1);
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
120
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
121 assert(!is_decoden || (val->in(0) == NULL) && val->is_Mach() &&
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
122 (val->as_Mach()->ideal_Opcode() == Op_DecodeN), "sanity");
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
123
0
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // Search the successor block for a load or store who's base value is also
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // the tested value. There may be several.
a61af66fc99e Initial load
duke
parents:
diff changeset
126 Node_List *out = new Node_List(Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
127 MachNode *best = NULL; // Best found so far
a61af66fc99e Initial load
duke
parents:
diff changeset
128 for (DUIterator i = val->outs(); val->has_out(i); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
129 Node *m = val->out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
130 if( !m->is_Mach() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
131 MachNode *mach = m->as_Mach();
a61af66fc99e Initial load
duke
parents:
diff changeset
132 was_store = false;
1693
6c9cc03d8726 6973329: C2 with Zero based COOP produces code with broken anti-dependency on x86
kvn
parents: 1685
diff changeset
133 int iop = mach->ideal_Opcode();
6c9cc03d8726 6973329: C2 with Zero based COOP produces code with broken anti-dependency on x86
kvn
parents: 1685
diff changeset
134 switch( iop ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
135 case Op_LoadB:
558
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 365
diff changeset
136 case Op_LoadUS:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
137 case Op_LoadD:
a61af66fc99e Initial load
duke
parents:
diff changeset
138 case Op_LoadF:
a61af66fc99e Initial load
duke
parents:
diff changeset
139 case Op_LoadI:
a61af66fc99e Initial load
duke
parents:
diff changeset
140 case Op_LoadL:
a61af66fc99e Initial load
duke
parents:
diff changeset
141 case Op_LoadP:
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
142 case Op_LoadN:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
143 case Op_LoadS:
a61af66fc99e Initial load
duke
parents:
diff changeset
144 case Op_LoadKlass:
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 125
diff changeset
145 case Op_LoadNKlass:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
146 case Op_LoadRange:
a61af66fc99e Initial load
duke
parents:
diff changeset
147 case Op_LoadD_unaligned:
a61af66fc99e Initial load
duke
parents:
diff changeset
148 case Op_LoadL_unaligned:
1151
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
149 assert(mach->in(2) == val, "should be address");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
150 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
151 case Op_StoreB:
a61af66fc99e Initial load
duke
parents:
diff changeset
152 case Op_StoreC:
a61af66fc99e Initial load
duke
parents:
diff changeset
153 case Op_StoreCM:
a61af66fc99e Initial load
duke
parents:
diff changeset
154 case Op_StoreD:
a61af66fc99e Initial load
duke
parents:
diff changeset
155 case Op_StoreF:
a61af66fc99e Initial load
duke
parents:
diff changeset
156 case Op_StoreI:
a61af66fc99e Initial load
duke
parents:
diff changeset
157 case Op_StoreL:
a61af66fc99e Initial load
duke
parents:
diff changeset
158 case Op_StoreP:
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
159 case Op_StoreN:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
160 was_store = true; // Memory op is a store op
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // Stores will have their address in slot 2 (memory in slot 1).
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // If the value being nul-checked is in another slot, it means we
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // are storing the checked value, which does NOT check the value!
a61af66fc99e Initial load
duke
parents:
diff changeset
164 if( mach->in(2) != val ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
165 break; // Found a memory op?
a61af66fc99e Initial load
duke
parents:
diff changeset
166 case Op_StrComp:
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 647
diff changeset
167 case Op_StrEquals:
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 647
diff changeset
168 case Op_StrIndexOf:
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 164
diff changeset
169 case Op_AryEq:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // Not a legit memory op for implicit null check regardless of
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // embedded loads
a61af66fc99e Initial load
duke
parents:
diff changeset
172 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 default: // Also check for embedded loads
a61af66fc99e Initial load
duke
parents:
diff changeset
174 if( !mach->needs_anti_dependence_check() )
a61af66fc99e Initial load
duke
parents:
diff changeset
175 continue; // Not an memory op; skip it
1693
6c9cc03d8726 6973329: C2 with Zero based COOP produces code with broken anti-dependency on x86
kvn
parents: 1685
diff changeset
176 if( must_clone[iop] ) {
6c9cc03d8726 6973329: C2 with Zero based COOP produces code with broken anti-dependency on x86
kvn
parents: 1685
diff changeset
177 // Do not move nodes which produce flags because
6c9cc03d8726 6973329: C2 with Zero based COOP produces code with broken anti-dependency on x86
kvn
parents: 1685
diff changeset
178 // RA will try to clone it to place near branch and
6c9cc03d8726 6973329: C2 with Zero based COOP produces code with broken anti-dependency on x86
kvn
parents: 1685
diff changeset
179 // it will cause recompilation, see clone_node().
6c9cc03d8726 6973329: C2 with Zero based COOP produces code with broken anti-dependency on x86
kvn
parents: 1685
diff changeset
180 continue;
6c9cc03d8726 6973329: C2 with Zero based COOP produces code with broken anti-dependency on x86
kvn
parents: 1685
diff changeset
181 }
1151
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
182 {
1575
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
183 // Check that value is used in memory address in
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
184 // instructions with embedded load (CmpP val1,(val2+off)).
1151
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
185 Node* base;
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
186 Node* index;
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
187 const MachOper* oper = mach->memory_inputs(base, index);
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
188 if (oper == NULL || oper == (MachOper*)-1) {
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
189 continue; // Not an memory op; skip it
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
190 }
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
191 if (val == base ||
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
192 val == index && val->bottom_type()->isa_narrowoop()) {
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
193 break; // Found it
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
194 } else {
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
195 continue; // Skip it
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
196 }
1271af4ec18c 6912517: JIT bug compiles out (and stops running) code that needs to be run. Causes NPE.
kvn
parents: 1137
diff changeset
197 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
198 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // check if the offset is not too high for implicit exception
a61af66fc99e Initial load
duke
parents:
diff changeset
201 {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 intptr_t offset = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 const TypePtr *adr_type = NULL; // Do not need this return value here
a61af66fc99e Initial load
duke
parents:
diff changeset
204 const Node* base = mach->get_base_and_disp(offset, adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
205 if (base == NULL || base == NodeSentinel) {
332
c792b641b8bd 6746907: Improve implicit null check generation
kvn
parents: 253
diff changeset
206 // Narrow oop address doesn't have base, only index
c792b641b8bd 6746907: Improve implicit null check generation
kvn
parents: 253
diff changeset
207 if( val->bottom_type()->isa_narrowoop() &&
c792b641b8bd 6746907: Improve implicit null check generation
kvn
parents: 253
diff changeset
208 MacroAssembler::needs_explicit_null_check(offset) )
c792b641b8bd 6746907: Improve implicit null check generation
kvn
parents: 253
diff changeset
209 continue; // Give up if offset is beyond page size
0
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // cannot reason about it; is probably not implicit null exception
a61af66fc99e Initial load
duke
parents:
diff changeset
211 } else {
642
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 558
diff changeset
212 const TypePtr* tptr;
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 558
diff changeset
213 if (UseCompressedOops && Universe::narrow_oop_shift() == 0) {
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 558
diff changeset
214 // 32-bits narrow oop can be the base of address expressions
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 558
diff changeset
215 tptr = base->bottom_type()->make_ptr();
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 558
diff changeset
216 } else {
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 558
diff changeset
217 // only regular oops are expected here
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 558
diff changeset
218 tptr = base->bottom_type()->is_ptr();
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 558
diff changeset
219 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
220 // Give up if offset is not a compile-time constant
a61af66fc99e Initial load
duke
parents:
diff changeset
221 if( offset == Type::OffsetBot || tptr->_offset == Type::OffsetBot )
a61af66fc99e Initial load
duke
parents:
diff changeset
222 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
223 offset += tptr->_offset; // correct if base is offseted
a61af66fc99e Initial load
duke
parents:
diff changeset
224 if( MacroAssembler::needs_explicit_null_check(offset) )
a61af66fc99e Initial load
duke
parents:
diff changeset
225 continue; // Give up is reference is beyond 4K page size
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // Check ctrl input to see if the null-check dominates the memory op
a61af66fc99e Initial load
duke
parents:
diff changeset
230 Block *cb = cfg->_bbs[mach->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
231 cb = cb->_idom; // Always hoist at least 1 block
a61af66fc99e Initial load
duke
parents:
diff changeset
232 if( !was_store ) { // Stores can be hoisted only one block
a61af66fc99e Initial load
duke
parents:
diff changeset
233 while( cb->_dom_depth > (_dom_depth + 1))
a61af66fc99e Initial load
duke
parents:
diff changeset
234 cb = cb->_idom; // Hoist loads as far as we want
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // The non-null-block should dominate the memory op, too. Live
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // range spilling will insert a spill in the non-null-block if it is
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // needs to spill the memory op for an implicit null check.
a61af66fc99e Initial load
duke
parents:
diff changeset
238 if (cb->_dom_depth == (_dom_depth + 1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 if (cb != not_null_block) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 cb = cb->_idom;
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
243 if( cb != this ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // Found a memory user; see if it can be hoisted to check-block
a61af66fc99e Initial load
duke
parents:
diff changeset
246 uint vidx = 0; // Capture index of value into memop
a61af66fc99e Initial load
duke
parents:
diff changeset
247 uint j;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 for( j = mach->req()-1; j > 0; j-- ) {
1575
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
249 if( mach->in(j) == val ) {
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
250 vidx = j;
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
251 // Ignore DecodeN val which could be hoisted to where needed.
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
252 if( is_decoden ) continue;
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
253 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // Block of memory-op input
a61af66fc99e Initial load
duke
parents:
diff changeset
255 Block *inb = cfg->_bbs[mach->in(j)->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
256 Block *b = this; // Start from nul check
a61af66fc99e Initial load
duke
parents:
diff changeset
257 while( b != inb && b->_dom_depth > inb->_dom_depth )
a61af66fc99e Initial load
duke
parents:
diff changeset
258 b = b->_idom; // search upwards for input
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // See if input dominates null check
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if( b != inb )
a61af66fc99e Initial load
duke
parents:
diff changeset
261 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
263 if( j > 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
264 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
265 Block *mb = cfg->_bbs[mach->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // Hoisting stores requires more checks for the anti-dependence case.
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // Give up hoisting if we have to move the store past any load.
a61af66fc99e Initial load
duke
parents:
diff changeset
268 if( was_store ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 Block *b = mb; // Start searching here for a local load
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // mach use (faulting) trying to hoist
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // n might be blocker to hoisting
a61af66fc99e Initial load
duke
parents:
diff changeset
272 while( b != this ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 uint k;
a61af66fc99e Initial load
duke
parents:
diff changeset
274 for( k = 1; k < b->_nodes.size(); k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
275 Node *n = b->_nodes[k];
a61af66fc99e Initial load
duke
parents:
diff changeset
276 if( n->needs_anti_dependence_check() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
277 n->in(LoadNode::Memory) == mach->in(StoreNode::Memory) )
a61af66fc99e Initial load
duke
parents:
diff changeset
278 break; // Found anti-dependent load
a61af66fc99e Initial load
duke
parents:
diff changeset
279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
280 if( k < b->_nodes.size() )
a61af66fc99e Initial load
duke
parents:
diff changeset
281 break; // Found anti-dependent load
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // Make sure control does not do a merge (would have to check allpaths)
a61af66fc99e Initial load
duke
parents:
diff changeset
283 if( b->num_preds() != 2 ) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
284 b = cfg->_bbs[b->pred(1)->_idx]; // Move up to predecessor block
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 if( b != this ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // Make sure this memory op is not already being used for a NullCheck
a61af66fc99e Initial load
duke
parents:
diff changeset
290 Node *e = mb->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
291 if( e->is_MachNullCheck() && e->in(1) == mach )
a61af66fc99e Initial load
duke
parents:
diff changeset
292 continue; // Already being used as a NULL check
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // Found a candidate! Pick one with least dom depth - the highest
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // in the dom tree should be closest to the null check.
a61af66fc99e Initial load
duke
parents:
diff changeset
296 if( !best ||
a61af66fc99e Initial load
duke
parents:
diff changeset
297 cfg->_bbs[mach->_idx]->_dom_depth < cfg->_bbs[best->_idx]->_dom_depth ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
298 best = mach;
a61af66fc99e Initial load
duke
parents:
diff changeset
299 bidx = vidx;
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // No candidate!
a61af66fc99e Initial load
duke
parents:
diff changeset
304 if( !best ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // ---- Found an implicit null check
a61af66fc99e Initial load
duke
parents:
diff changeset
307 extern int implicit_null_checks;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 implicit_null_checks++;
a61af66fc99e Initial load
duke
parents:
diff changeset
309
1575
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
310 if( is_decoden ) {
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
311 // Check if we need to hoist decodeHeapOop_not_null first.
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
312 Block *valb = cfg->_bbs[val->_idx];
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
313 if( this != valb && this->_dom_depth < valb->_dom_depth ) {
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
314 // Hoist it up to the end of the test block.
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
315 valb->find_remove(val);
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
316 this->add_inst(val);
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
317 cfg->_bbs.map(val->_idx,this);
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
318 // DecodeN on x86 may kill flags. Check for flag-killing projections
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
319 // that also need to be hoisted.
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
320 for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) {
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
321 Node* n = val->fast_out(j);
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
322 if( n->Opcode() == Op_MachProj ) {
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
323 cfg->_bbs[n->_idx]->find_remove(n);
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
324 this->add_inst(n);
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
325 cfg->_bbs.map(n->_idx,this);
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
326 }
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
327 }
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
328 }
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1151
diff changeset
329 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // Hoist the memory candidate up to the end of the test block.
a61af66fc99e Initial load
duke
parents:
diff changeset
331 Block *old_block = cfg->_bbs[best->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
332 old_block->find_remove(best);
a61af66fc99e Initial load
duke
parents:
diff changeset
333 add_inst(best);
a61af66fc99e Initial load
duke
parents:
diff changeset
334 cfg->_bbs.map(best->_idx,this);
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // Move the control dependence
a61af66fc99e Initial load
duke
parents:
diff changeset
337 if (best->in(0) && best->in(0) == old_block->_nodes[0])
a61af66fc99e Initial load
duke
parents:
diff changeset
338 best->set_req(0, _nodes[0]);
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // Check for flag-killing projections that also need to be hoisted
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // Should be DU safe because no edge updates.
a61af66fc99e Initial load
duke
parents:
diff changeset
342 for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 Node* n = best->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
344 if( n->Opcode() == Op_MachProj ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
345 cfg->_bbs[n->_idx]->find_remove(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
346 add_inst(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
347 cfg->_bbs.map(n->_idx,this);
a61af66fc99e Initial load
duke
parents:
diff changeset
348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
350
a61af66fc99e Initial load
duke
parents:
diff changeset
351 Compile *C = cfg->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // proj==Op_True --> ne test; proj==Op_False --> eq test.
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // One of two graph shapes got matched:
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // (IfTrue (If (Bool NE (CmpP ptr NULL))))
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // (IfFalse (If (Bool EQ (CmpP ptr NULL))))
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // NULL checks are always branch-if-eq. If we see a IfTrue projection
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // then we are replacing a 'ne' test with a 'eq' NULL check test.
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // We need to flip the projections to keep the same semantics.
a61af66fc99e Initial load
duke
parents:
diff changeset
359 if( proj->Opcode() == Op_IfTrue ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // Swap order of projections in basic block to swap branch targets
a61af66fc99e Initial load
duke
parents:
diff changeset
361 Node *tmp1 = _nodes[end_idx()+1];
a61af66fc99e Initial load
duke
parents:
diff changeset
362 Node *tmp2 = _nodes[end_idx()+2];
a61af66fc99e Initial load
duke
parents:
diff changeset
363 _nodes.map(end_idx()+1, tmp2);
a61af66fc99e Initial load
duke
parents:
diff changeset
364 _nodes.map(end_idx()+2, tmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
365 Node *tmp = new (C, 1) Node(C->top()); // Use not NULL input
a61af66fc99e Initial load
duke
parents:
diff changeset
366 tmp1->replace_by(tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
367 tmp2->replace_by(tmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
368 tmp->replace_by(tmp2);
a61af66fc99e Initial load
duke
parents:
diff changeset
369 tmp->destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
371
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // Remove the existing null check; use a new implicit null check instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // Since schedule-local needs precise def-use info, we need to correct
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // it as well.
a61af66fc99e Initial load
duke
parents:
diff changeset
375 Node *old_tst = proj->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
376 MachNode *nul_chk = new (C) MachNullCheckNode(old_tst->in(0),best,bidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
377 _nodes.map(end_idx(),nul_chk);
a61af66fc99e Initial load
duke
parents:
diff changeset
378 cfg->_bbs.map(nul_chk->_idx,this);
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // Redirect users of old_test to nul_chk
a61af66fc99e Initial load
duke
parents:
diff changeset
380 for (DUIterator_Last i2min, i2 = old_tst->last_outs(i2min); i2 >= i2min; --i2)
a61af66fc99e Initial load
duke
parents:
diff changeset
381 old_tst->last_out(i2)->set_req(0, nul_chk);
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // Clean-up any dead code
a61af66fc99e Initial load
duke
parents:
diff changeset
383 for (uint i3 = 0; i3 < old_tst->req(); i3++)
a61af66fc99e Initial load
duke
parents:
diff changeset
384 old_tst->set_req(i3, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 cfg->latency_from_uses(nul_chk);
a61af66fc99e Initial load
duke
parents:
diff changeset
387 cfg->latency_from_uses(best);
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 //------------------------------select-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // Select a nice fellow from the worklist to schedule next. If there is only
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // one choice, then use it. Projections take top priority for correctness
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // reasons - if I see a projection, then it is next. There are a number of
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // other special cases, for instructions that consume condition codes, et al.
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // These are chosen immediately. Some instructions are required to immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // precede the last instruction in the block, and these are taken last. Of the
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // remaining cases (most), choose the instruction with the greatest latency
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // (that is, the most number of pseudo-cycles required to the end of the
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // routine). If there is a tie, choose the instruction with the most inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
401 Node *Block::select(PhaseCFG *cfg, Node_List &worklist, int *ready_cnt, VectorSet &next_call, uint sched_slot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
402
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // If only a single entry on the stack, use it
a61af66fc99e Initial load
duke
parents:
diff changeset
404 uint cnt = worklist.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
405 if (cnt == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
406 Node *n = worklist[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
407 worklist.map(0,worklist.pop());
a61af66fc99e Initial load
duke
parents:
diff changeset
408 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411 uint choice = 0; // Bigger is most important
a61af66fc99e Initial load
duke
parents:
diff changeset
412 uint latency = 0; // Bigger is scheduled first
a61af66fc99e Initial load
duke
parents:
diff changeset
413 uint score = 0; // Bigger is better
253
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 196
diff changeset
414 int idx = -1; // Index in worklist
0
a61af66fc99e Initial load
duke
parents:
diff changeset
415
a61af66fc99e Initial load
duke
parents:
diff changeset
416 for( uint i=0; i<cnt; i++ ) { // Inspect entire worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // Order in worklist is used to break ties.
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // See caller for how this is used to delay scheduling
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // of induction variable increments to after the other
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // uses of the phi are scheduled.
a61af66fc99e Initial load
duke
parents:
diff changeset
421 Node *n = worklist[i]; // Get Node on worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 int iop = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
424 if( n->is_Proj() || // Projections always win
a61af66fc99e Initial load
duke
parents:
diff changeset
425 n->Opcode()== Op_Con || // So does constant 'Top'
a61af66fc99e Initial load
duke
parents:
diff changeset
426 iop == Op_CreateEx || // Create-exception must start block
a61af66fc99e Initial load
duke
parents:
diff changeset
427 iop == Op_CheckCastPP
a61af66fc99e Initial load
duke
parents:
diff changeset
428 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
429 worklist.map(i,worklist.pop());
a61af66fc99e Initial load
duke
parents:
diff changeset
430 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // Final call in a block must be adjacent to 'catch'
a61af66fc99e Initial load
duke
parents:
diff changeset
434 Node *e = end();
a61af66fc99e Initial load
duke
parents:
diff changeset
435 if( e->is_Catch() && e->in(0)->in(0) == n )
a61af66fc99e Initial load
duke
parents:
diff changeset
436 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
437
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // Memory op for an implicit null check has to be at the end of the block
a61af66fc99e Initial load
duke
parents:
diff changeset
439 if( e->is_MachNullCheck() && e->in(1) == n )
a61af66fc99e Initial load
duke
parents:
diff changeset
440 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 uint n_choice = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // See if this instruction is consumed by a branch. If so, then (as the
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // branch is the last instruction in the basic block) force it to the
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // end of the basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
447 if ( must_clone[iop] ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // See if any use is a branch
a61af66fc99e Initial load
duke
parents:
diff changeset
449 bool found_machif = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
452 Node* use = n->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // The use is a conditional branch, make them adjacent
a61af66fc99e Initial load
duke
parents:
diff changeset
455 if (use->is_MachIf() && cfg->_bbs[use->_idx]==this ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
456 found_machif = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
457 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
459
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // More than this instruction pending for successor to be ready,
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // don't choose this if other opportunities are ready
a61af66fc99e Initial load
duke
parents:
diff changeset
462 if (ready_cnt[use->_idx] > 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
463 n_choice = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 // loop terminated, prefer not to use this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
467 if (found_machif)
a61af66fc99e Initial load
duke
parents:
diff changeset
468 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
470
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // See if this has a predecessor that is "must_clone", i.e. sets the
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // condition code. If so, choose this first
a61af66fc99e Initial load
duke
parents:
diff changeset
473 for (uint j = 0; j < n->req() ; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
474 Node *inn = n->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
475 if (inn) {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 if (inn->is_Mach() && must_clone[inn->as_Mach()->ideal_Opcode()] ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 n_choice = 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
478 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // MachTemps should be scheduled last so they are near their uses
a61af66fc99e Initial load
duke
parents:
diff changeset
484 if (n->is_MachTemp()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 n_choice = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
487
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1579
diff changeset
488 uint n_latency = cfg->_node_latency->at_grow(n->_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
489 uint n_score = n->req(); // Many inputs get high score to break ties
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // Keep best latency found
a61af66fc99e Initial load
duke
parents:
diff changeset
492 if( choice < n_choice ||
a61af66fc99e Initial load
duke
parents:
diff changeset
493 ( choice == n_choice &&
a61af66fc99e Initial load
duke
parents:
diff changeset
494 ( latency < n_latency ||
a61af66fc99e Initial load
duke
parents:
diff changeset
495 ( latency == n_latency &&
a61af66fc99e Initial load
duke
parents:
diff changeset
496 ( score < n_score ))))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 choice = n_choice;
a61af66fc99e Initial load
duke
parents:
diff changeset
498 latency = n_latency;
a61af66fc99e Initial load
duke
parents:
diff changeset
499 score = n_score;
a61af66fc99e Initial load
duke
parents:
diff changeset
500 idx = i; // Also keep index in worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
502 } // End of for all ready nodes in worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
503
253
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 196
diff changeset
504 assert(idx >= 0, "index should be set");
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 196
diff changeset
505 Node *n = worklist[(uint)idx]; // Get the winner
0
a61af66fc99e Initial load
duke
parents:
diff changeset
506
253
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 196
diff changeset
507 worklist.map((uint)idx, worklist.pop()); // Compress worklist
0
a61af66fc99e Initial load
duke
parents:
diff changeset
508 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 //------------------------------set_next_call----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
513 void Block::set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 if( next_call.test_set(n->_idx) ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
515 for( uint i=0; i<n->len(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
516 Node *m = n->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
517 if( !m ) continue; // must see all nodes in block that precede call
a61af66fc99e Initial load
duke
parents:
diff changeset
518 if( bbs[m->_idx] == this )
a61af66fc99e Initial load
duke
parents:
diff changeset
519 set_next_call( m, next_call, bbs );
a61af66fc99e Initial load
duke
parents:
diff changeset
520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 //------------------------------needed_for_next_call---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // Set the flag 'next_call' for each Node that is needed for the next call to
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // be scheduled. This flag lets me bias scheduling so Nodes needed for the
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // next subroutine call get priority - basically it moves things NOT needed
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // for the next call till after the call. This prevents me from trying to
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // carry lots of stuff live across a call.
a61af66fc99e Initial load
duke
parents:
diff changeset
529 void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
530 // Find the next control-defining Node in this block
a61af66fc99e Initial load
duke
parents:
diff changeset
531 Node* call = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
532 for (DUIterator_Fast imax, i = this_call->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
533 Node* m = this_call->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
534 if( bbs[m->_idx] == this && // Local-block user
a61af66fc99e Initial load
duke
parents:
diff changeset
535 m != this_call && // Not self-start node
a61af66fc99e Initial load
duke
parents:
diff changeset
536 m->is_Call() )
a61af66fc99e Initial load
duke
parents:
diff changeset
537 call = m;
a61af66fc99e Initial load
duke
parents:
diff changeset
538 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
540 if (call == NULL) return; // No next call (e.g., block end is near)
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // Set next-call for all inputs to this call
a61af66fc99e Initial load
duke
parents:
diff changeset
542 set_next_call(call, next_call, bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545 //------------------------------sched_call-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
546 uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
547 RegMask regs;
a61af66fc99e Initial load
duke
parents:
diff changeset
548
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // Schedule all the users of the call right now. All the users are
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // projection Nodes, so they must be scheduled next to the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // Collect all the defined registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
552 for (DUIterator_Fast imax, i = mcall->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
553 Node* n = mcall->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
554 assert( n->Opcode()==Op_MachProj, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
555 --ready_cnt[n->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
556 assert( !ready_cnt[n->_idx], "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // Schedule next to call
a61af66fc99e Initial load
duke
parents:
diff changeset
558 _nodes.map(node_cnt++, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // Collect defined registers
a61af66fc99e Initial load
duke
parents:
diff changeset
560 regs.OR(n->out_RegMask());
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // Check for scheduling the next control-definer
a61af66fc99e Initial load
duke
parents:
diff changeset
562 if( n->bottom_type() == Type::CONTROL )
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // Warm up next pile of heuristic bits
a61af66fc99e Initial load
duke
parents:
diff changeset
564 needed_for_next_call(n, next_call, bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
565
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // Children of projections are now all ready
a61af66fc99e Initial load
duke
parents:
diff changeset
567 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
568 Node* m = n->fast_out(j); // Get user
a61af66fc99e Initial load
duke
parents:
diff changeset
569 if( bbs[m->_idx] != this ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
570 if( m->is_Phi() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
571 if( !--ready_cnt[m->_idx] )
a61af66fc99e Initial load
duke
parents:
diff changeset
572 worklist.push(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
573 }
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // Act as if the call defines the Frame Pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
578 // Certainly the FP is alive and well after the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
579 regs.Insert(matcher.c_frame_pointer());
a61af66fc99e Initial load
duke
parents:
diff changeset
580
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // Set all registers killed and not already defined by the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
582 uint r_cnt = mcall->tf()->range()->cnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
583 int op = mcall->ideal_Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
584 MachProjNode *proj = new (matcher.C, 1) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj );
a61af66fc99e Initial load
duke
parents:
diff changeset
585 bbs.map(proj->_idx,this);
a61af66fc99e Initial load
duke
parents:
diff changeset
586 _nodes.insert(node_cnt++, proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
587
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // Select the right register save policy.
a61af66fc99e Initial load
duke
parents:
diff changeset
589 const char * save_policy;
a61af66fc99e Initial load
duke
parents:
diff changeset
590 switch (op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
591 case Op_CallRuntime:
a61af66fc99e Initial load
duke
parents:
diff changeset
592 case Op_CallLeaf:
a61af66fc99e Initial load
duke
parents:
diff changeset
593 case Op_CallLeafNoFP:
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // Calling C code so use C calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
595 save_policy = matcher._c_reg_save_policy;
a61af66fc99e Initial load
duke
parents:
diff changeset
596 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
597
a61af66fc99e Initial load
duke
parents:
diff changeset
598 case Op_CallStaticJava:
a61af66fc99e Initial load
duke
parents:
diff changeset
599 case Op_CallDynamicJava:
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // Calling Java code so use Java calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
601 save_policy = matcher._register_save_policy;
a61af66fc99e Initial load
duke
parents:
diff changeset
602 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
605 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
607
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // When using CallRuntime mark SOE registers as killed by the call
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // so values that could show up in the RegisterMap aren't live in a
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // callee saved register since the register wouldn't know where to
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // find them. CallLeaf and CallLeafNoFP are ok because they can't
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // have debug info on them. Strictly speaking this only needs to be
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // done for oops since idealreg2debugmask takes care of debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // references but there no way to handle oops differently than other
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // pointers as far as the kill mask goes.
a61af66fc99e Initial load
duke
parents:
diff changeset
616 bool exclude_soe = op == Op_CallRuntime;
a61af66fc99e Initial load
duke
parents:
diff changeset
617
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1100
diff changeset
618 // If the call is a MethodHandle invoke, we need to exclude the
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1100
diff changeset
619 // register which is used to save the SP value over MH invokes from
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1100
diff changeset
620 // the mask. Otherwise this register could be used for
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1100
diff changeset
621 // deoptimization information.
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1100
diff changeset
622 if (op == Op_CallStaticJava) {
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1100
diff changeset
623 MachCallStaticJavaNode* mcallstaticjava = (MachCallStaticJavaNode*) mcall;
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1100
diff changeset
624 if (mcallstaticjava->_method_handle_invoke)
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1100
diff changeset
625 proj->_rout.OR(Matcher::method_handle_invoke_SP_save_mask());
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1100
diff changeset
626 }
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1100
diff changeset
627
0
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // Fill in the kill mask for the call
a61af66fc99e Initial load
duke
parents:
diff changeset
629 for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
630 if( !regs.Member(r) ) { // Not already defined by the call
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // Save-on-call register?
a61af66fc99e Initial load
duke
parents:
diff changeset
632 if ((save_policy[r] == 'C') ||
a61af66fc99e Initial load
duke
parents:
diff changeset
633 (save_policy[r] == 'A') ||
a61af66fc99e Initial load
duke
parents:
diff changeset
634 ((save_policy[r] == 'E') && exclude_soe)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
635 proj->_rout.Insert(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 return node_cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
641 }
a61af66fc99e Initial load
duke
parents:
diff changeset
642
a61af66fc99e Initial load
duke
parents:
diff changeset
643
a61af66fc99e Initial load
duke
parents:
diff changeset
644 //------------------------------schedule_local---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // Topological sort within a block. Someday become a real scheduler.
a61af66fc99e Initial load
duke
parents:
diff changeset
646 bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, int *ready_cnt, VectorSet &next_call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // Already "sorted" are the block start Node (as the first entry), and
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // the block-ending Node and any trailing control projections. We leave
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // these alone. PhiNodes and ParmNodes are made to follow the block start
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // Node. Everything else gets topo-sorted.
a61af66fc99e Initial load
duke
parents:
diff changeset
651
a61af66fc99e Initial load
duke
parents:
diff changeset
652 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
653 if (cfg->trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
654 tty->print_cr("# --- schedule_local B%d, before: ---", _pre_order);
a61af66fc99e Initial load
duke
parents:
diff changeset
655 for (uint i = 0;i < _nodes.size();i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
656 tty->print("# ");
a61af66fc99e Initial load
duke
parents:
diff changeset
657 _nodes[i]->fast_dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
659 tty->print_cr("#");
a61af66fc99e Initial load
duke
parents:
diff changeset
660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
661 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // RootNode is already sorted
a61af66fc99e Initial load
duke
parents:
diff changeset
664 if( _nodes.size() == 1 ) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
665
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // Move PhiNodes and ParmNodes from 1 to cnt up to the start
a61af66fc99e Initial load
duke
parents:
diff changeset
667 uint node_cnt = end_idx();
a61af66fc99e Initial load
duke
parents:
diff changeset
668 uint phi_cnt = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
669 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
670 for( i = 1; i<node_cnt; i++ ) { // Scan for Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
671 Node *n = _nodes[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
672 if( n->is_Phi() || // Found a PhiNode or ParmNode
a61af66fc99e Initial load
duke
parents:
diff changeset
673 (n->is_Proj() && n->in(0) == head()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // Move guy at 'phi_cnt' to the end; makes a hole at phi_cnt
a61af66fc99e Initial load
duke
parents:
diff changeset
675 _nodes.map(i,_nodes[phi_cnt]);
a61af66fc99e Initial load
duke
parents:
diff changeset
676 _nodes.map(phi_cnt++,n); // swap Phi/Parm up front
a61af66fc99e Initial load
duke
parents:
diff changeset
677 } else { // All others
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // Count block-local inputs to 'n'
a61af66fc99e Initial load
duke
parents:
diff changeset
679 uint cnt = n->len(); // Input count
a61af66fc99e Initial load
duke
parents:
diff changeset
680 uint local = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
681 for( uint j=0; j<cnt; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 Node *m = n->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
683 if( m && cfg->_bbs[m->_idx] == this && !m->is_top() )
a61af66fc99e Initial load
duke
parents:
diff changeset
684 local++; // One more block-local input
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686 ready_cnt[n->_idx] = local; // Count em up
a61af66fc99e Initial load
duke
parents:
diff changeset
687
a61af66fc99e Initial load
duke
parents:
diff changeset
688 // A few node types require changing a required edge to a precedence edge
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // before allocation.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 125
diff changeset
690 if( UseConcMarkSweepGC || UseG1GC ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
691 if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_StoreCM ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // Note: Required edges with an index greater than oper_input_base
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // are not supported by the allocator.
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // Note2: Can only depend on unmatched edge being last,
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // can not depend on its absolute position.
a61af66fc99e Initial load
duke
parents:
diff changeset
696 Node *oop_store = n->in(n->req() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
697 n->del_req(n->req() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
698 n->add_prec(oop_store);
a61af66fc99e Initial load
duke
parents:
diff changeset
699 assert(cfg->_bbs[oop_store->_idx]->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark");
a61af66fc99e Initial load
duke
parents:
diff changeset
700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
701 }
1100
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 681
diff changeset
702 if( n->is_Mach() && n->req() > TypeFunc::Parms &&
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 681
diff changeset
703 (n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire ||
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 681
diff changeset
704 n->as_Mach()->ideal_Opcode() == Op_MemBarVolatile) ) {
253
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 196
diff changeset
705 // MemBarAcquire could be created without Precedent edge.
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 196
diff changeset
706 // del_req() replaces the specified edge with the last input edge
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 196
diff changeset
707 // and then removes the last edge. If the specified edge > number of
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 196
diff changeset
708 // edges the last edge will be moved outside of the input edges array
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 196
diff changeset
709 // and the edge will be lost. This is why this code should be
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 196
diff changeset
710 // executed only when Precedent (== TypeFunc::Parms) edge is present.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
711 Node *x = n->in(TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
712 n->del_req(TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 n->add_prec(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
717 for(uint i2=i; i2<_nodes.size(); i2++ ) // Trailing guys get zapped count
a61af66fc99e Initial load
duke
parents:
diff changeset
718 ready_cnt[_nodes[i2]->_idx] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // All the prescheduled guys do not hold back internal nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
721 uint i3;
a61af66fc99e Initial load
duke
parents:
diff changeset
722 for(i3 = 0; i3<phi_cnt; i3++ ) { // For all pre-scheduled
a61af66fc99e Initial load
duke
parents:
diff changeset
723 Node *n = _nodes[i3]; // Get pre-scheduled
a61af66fc99e Initial load
duke
parents:
diff changeset
724 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
725 Node* m = n->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
726 if( cfg->_bbs[m->_idx] ==this ) // Local-block user
a61af66fc99e Initial load
duke
parents:
diff changeset
727 ready_cnt[m->_idx]--; // Fix ready count
a61af66fc99e Initial load
duke
parents:
diff changeset
728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
730
a61af66fc99e Initial load
duke
parents:
diff changeset
731 Node_List delay;
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // Make a worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
733 Node_List worklist;
a61af66fc99e Initial load
duke
parents:
diff changeset
734 for(uint i4=i3; i4<node_cnt; i4++ ) { // Put ready guys on worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
735 Node *m = _nodes[i4];
a61af66fc99e Initial load
duke
parents:
diff changeset
736 if( !ready_cnt[m->_idx] ) { // Zero ready count?
a61af66fc99e Initial load
duke
parents:
diff changeset
737 if (m->is_iteratively_computed()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // Push induction variable increments last to allow other uses
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // of the phi to be scheduled first. The select() method breaks
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // ties in scheduling by worklist order.
a61af66fc99e Initial load
duke
parents:
diff changeset
741 delay.push(m);
125
d942c7e64bd9 6601321: Assert(j == 1 || b->_nodes[j-1]->is_Phi(),"CreateEx must be first instruction in block")
never
parents: 113
diff changeset
742 } else if (m->is_Mach() && m->as_Mach()->ideal_Opcode() == Op_CreateEx) {
d942c7e64bd9 6601321: Assert(j == 1 || b->_nodes[j-1]->is_Phi(),"CreateEx must be first instruction in block")
never
parents: 113
diff changeset
743 // Force the CreateEx to the top of the list so it's processed
d942c7e64bd9 6601321: Assert(j == 1 || b->_nodes[j-1]->is_Phi(),"CreateEx must be first instruction in block")
never
parents: 113
diff changeset
744 // first and ends up at the start of the block.
d942c7e64bd9 6601321: Assert(j == 1 || b->_nodes[j-1]->is_Phi(),"CreateEx must be first instruction in block")
never
parents: 113
diff changeset
745 worklist.insert(0, m);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
746 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
747 worklist.push(m); // Then on to worklist!
a61af66fc99e Initial load
duke
parents:
diff changeset
748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
751 while (delay.size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
752 Node* d = delay.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
753 worklist.push(d);
a61af66fc99e Initial load
duke
parents:
diff changeset
754 }
a61af66fc99e Initial load
duke
parents:
diff changeset
755
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // Warm up the 'next_call' heuristic bits
a61af66fc99e Initial load
duke
parents:
diff changeset
757 needed_for_next_call(_nodes[0], next_call, cfg->_bbs);
a61af66fc99e Initial load
duke
parents:
diff changeset
758
a61af66fc99e Initial load
duke
parents:
diff changeset
759 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
760 if (cfg->trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
761 for (uint j=0; j<_nodes.size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
762 Node *n = _nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
763 int idx = n->_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 tty->print("# ready cnt:%3d ", ready_cnt[idx]);
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1579
diff changeset
765 tty->print("latency:%3d ", cfg->_node_latency->at_grow(idx));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
766 tty->print("%4d: %s\n", idx, n->Name());
a61af66fc99e Initial load
duke
parents:
diff changeset
767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
769 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // Pull from worklist and schedule
a61af66fc99e Initial load
duke
parents:
diff changeset
772 while( worklist.size() ) { // Worklist is not ready
a61af66fc99e Initial load
duke
parents:
diff changeset
773
a61af66fc99e Initial load
duke
parents:
diff changeset
774 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
775 if (cfg->trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
776 tty->print("# ready list:");
a61af66fc99e Initial load
duke
parents:
diff changeset
777 for( uint i=0; i<worklist.size(); i++ ) { // Inspect entire worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
778 Node *n = worklist[i]; // Get Node on worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
779 tty->print(" %d", n->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
780 }
a61af66fc99e Initial load
duke
parents:
diff changeset
781 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
783 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
784
a61af66fc99e Initial load
duke
parents:
diff changeset
785 // Select and pop a ready guy from worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
786 Node* n = select(cfg, worklist, ready_cnt, next_call, phi_cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
787 _nodes.map(phi_cnt++,n); // Schedule him next
a61af66fc99e Initial load
duke
parents:
diff changeset
788
a61af66fc99e Initial load
duke
parents:
diff changeset
789 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
790 if (cfg->trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
791 tty->print("# select %d: %s", n->_idx, n->Name());
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1579
diff changeset
792 tty->print(", latency:%d", cfg->_node_latency->at_grow(n->_idx));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
793 n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
794 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
795 tty->print("# ready list:");
a61af66fc99e Initial load
duke
parents:
diff changeset
796 for( uint i=0; i<worklist.size(); i++ ) { // Inspect entire worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
797 Node *n = worklist[i]; // Get Node on worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
798 tty->print(" %d", n->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
800 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
803
a61af66fc99e Initial load
duke
parents:
diff changeset
804 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
805 if( n->is_MachCall() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
806 MachCallNode *mcall = n->as_MachCall();
a61af66fc99e Initial load
duke
parents:
diff changeset
807 phi_cnt = sched_call(matcher, cfg->_bbs, phi_cnt, worklist, ready_cnt, mcall, next_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
808 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
809 }
a61af66fc99e Initial load
duke
parents:
diff changeset
810 // Children are now all ready
a61af66fc99e Initial load
duke
parents:
diff changeset
811 for (DUIterator_Fast i5max, i5 = n->fast_outs(i5max); i5 < i5max; i5++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
812 Node* m = n->fast_out(i5); // Get user
a61af66fc99e Initial load
duke
parents:
diff changeset
813 if( cfg->_bbs[m->_idx] != this ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
814 if( m->is_Phi() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
815 if( !--ready_cnt[m->_idx] )
a61af66fc99e Initial load
duke
parents:
diff changeset
816 worklist.push(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
819
a61af66fc99e Initial load
duke
parents:
diff changeset
820 if( phi_cnt != end_idx() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
821 // did not schedule all. Retry, Bailout, or Die
a61af66fc99e Initial load
duke
parents:
diff changeset
822 Compile* C = matcher.C;
a61af66fc99e Initial load
duke
parents:
diff changeset
823 if (C->subsume_loads() == true && !C->failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // Retry with subsume_loads == false
a61af66fc99e Initial load
duke
parents:
diff changeset
825 // If this is the first failure, the sentinel string will "stick"
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // to the Compile object, and the C2Compiler will see it and retry.
a61af66fc99e Initial load
duke
parents:
diff changeset
827 C->record_failure(C2Compiler::retry_no_subsuming_loads());
a61af66fc99e Initial load
duke
parents:
diff changeset
828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
829 // assert( phi_cnt == end_idx(), "did not schedule all" );
a61af66fc99e Initial load
duke
parents:
diff changeset
830 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
832
a61af66fc99e Initial load
duke
parents:
diff changeset
833 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
834 if (cfg->trace_opto_pipelining()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
835 tty->print_cr("#");
a61af66fc99e Initial load
duke
parents:
diff changeset
836 tty->print_cr("# after schedule_local");
a61af66fc99e Initial load
duke
parents:
diff changeset
837 for (uint i = 0;i < _nodes.size();i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
838 tty->print("# ");
a61af66fc99e Initial load
duke
parents:
diff changeset
839 _nodes[i]->fast_dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
840 }
a61af66fc99e Initial load
duke
parents:
diff changeset
841 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
843 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
844
a61af66fc99e Initial load
duke
parents:
diff changeset
845
a61af66fc99e Initial load
duke
parents:
diff changeset
846 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
847 }
a61af66fc99e Initial load
duke
parents:
diff changeset
848
a61af66fc99e Initial load
duke
parents:
diff changeset
849 //--------------------------catch_cleanup_fix_all_inputs-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
850 static void catch_cleanup_fix_all_inputs(Node *use, Node *old_def, Node *new_def) {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 for (uint l = 0; l < use->len(); l++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
852 if (use->in(l) == old_def) {
a61af66fc99e Initial load
duke
parents:
diff changeset
853 if (l < use->req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
854 use->set_req(l, new_def);
a61af66fc99e Initial load
duke
parents:
diff changeset
855 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
856 use->rm_prec(l);
a61af66fc99e Initial load
duke
parents:
diff changeset
857 use->add_prec(new_def);
a61af66fc99e Initial load
duke
parents:
diff changeset
858 l--;
a61af66fc99e Initial load
duke
parents:
diff changeset
859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863
a61af66fc99e Initial load
duke
parents:
diff changeset
864 //------------------------------catch_cleanup_find_cloned_def------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
865 static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def_blk, Block_Array &bbs, int n_clone_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
866 assert( use_blk != def_blk, "Inter-block cleanup only");
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // The use is some block below the Catch. Find and return the clone of the def
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // that dominates the use. If there is no clone in a dominating block, then
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // create a phi for the def in a dominating block.
a61af66fc99e Initial load
duke
parents:
diff changeset
871
a61af66fc99e Initial load
duke
parents:
diff changeset
872 // Find which successor block dominates this use. The successor
a61af66fc99e Initial load
duke
parents:
diff changeset
873 // blocks must all be single-entry (from the Catch only; I will have
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // split blocks to make this so), hence they all dominate.
a61af66fc99e Initial load
duke
parents:
diff changeset
875 while( use_blk->_dom_depth > def_blk->_dom_depth+1 )
a61af66fc99e Initial load
duke
parents:
diff changeset
876 use_blk = use_blk->_idom;
a61af66fc99e Initial load
duke
parents:
diff changeset
877
a61af66fc99e Initial load
duke
parents:
diff changeset
878 // Find the successor
a61af66fc99e Initial load
duke
parents:
diff changeset
879 Node *fixup = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881 uint j;
a61af66fc99e Initial load
duke
parents:
diff changeset
882 for( j = 0; j < def_blk->_num_succs; j++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
883 if( use_blk == def_blk->_succs[j] )
a61af66fc99e Initial load
duke
parents:
diff changeset
884 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 if( j == def_blk->_num_succs ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
887 // Block at same level in dom-tree is not a successor. It needs a
a61af66fc99e Initial load
duke
parents:
diff changeset
888 // PhiNode, the PhiNode uses from the def and IT's uses need fixup.
a61af66fc99e Initial load
duke
parents:
diff changeset
889 Node_Array inputs = new Node_List(Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
890 for(uint k = 1; k < use_blk->num_preds(); k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
891 inputs.map(k, catch_cleanup_find_cloned_def(bbs[use_blk->pred(k)->_idx], def, def_blk, bbs, n_clone_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
893
a61af66fc99e Initial load
duke
parents:
diff changeset
894 // Check to see if the use_blk already has an identical phi inserted.
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // If it exists, it will be at the first position since all uses of a
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // def are processed together.
a61af66fc99e Initial load
duke
parents:
diff changeset
897 Node *phi = use_blk->_nodes[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
898 if( phi->is_Phi() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
899 fixup = phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
900 for (uint k = 1; k < use_blk->num_preds(); k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
901 if (phi->in(k) != inputs[k]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // Not a match
a61af66fc99e Initial load
duke
parents:
diff changeset
903 fixup = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
904 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
905 }
a61af66fc99e Initial load
duke
parents:
diff changeset
906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
907 }
a61af66fc99e Initial load
duke
parents:
diff changeset
908
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // If an existing PhiNode was not found, make a new one.
a61af66fc99e Initial load
duke
parents:
diff changeset
910 if (fixup == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
911 Node *new_phi = PhiNode::make(use_blk->head(), def);
a61af66fc99e Initial load
duke
parents:
diff changeset
912 use_blk->_nodes.insert(1, new_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
913 bbs.map(new_phi->_idx, use_blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
914 for (uint k = 1; k < use_blk->num_preds(); k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
915 new_phi->set_req(k, inputs[k]);
a61af66fc99e Initial load
duke
parents:
diff changeset
916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
917 fixup = new_phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
918 }
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
921 // Found the use just below the Catch. Make it use the clone.
a61af66fc99e Initial load
duke
parents:
diff changeset
922 fixup = use_blk->_nodes[n_clone_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925 return fixup;
a61af66fc99e Initial load
duke
parents:
diff changeset
926 }
a61af66fc99e Initial load
duke
parents:
diff changeset
927
a61af66fc99e Initial load
duke
parents:
diff changeset
928 //--------------------------catch_cleanup_intra_block--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // Fix all input edges in use that reference "def". The use is in the same
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // block as the def and both have been cloned in each successor block.
a61af66fc99e Initial load
duke
parents:
diff changeset
931 static void catch_cleanup_intra_block(Node *use, Node *def, Block *blk, int beg, int n_clone_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
932
a61af66fc99e Initial load
duke
parents:
diff changeset
933 // Both the use and def have been cloned. For each successor block,
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // get the clone of the use, and make its input the clone of the def
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // found in that block.
a61af66fc99e Initial load
duke
parents:
diff changeset
936
a61af66fc99e Initial load
duke
parents:
diff changeset
937 uint use_idx = blk->find_node(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
938 uint offset_idx = use_idx - beg;
a61af66fc99e Initial load
duke
parents:
diff changeset
939 for( uint k = 0; k < blk->_num_succs; k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
940 // Get clone in each successor block
a61af66fc99e Initial load
duke
parents:
diff changeset
941 Block *sb = blk->_succs[k];
a61af66fc99e Initial load
duke
parents:
diff changeset
942 Node *clone = sb->_nodes[offset_idx+1];
a61af66fc99e Initial load
duke
parents:
diff changeset
943 assert( clone->Opcode() == use->Opcode(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
944
a61af66fc99e Initial load
duke
parents:
diff changeset
945 // Make use-clone reference the def-clone
a61af66fc99e Initial load
duke
parents:
diff changeset
946 catch_cleanup_fix_all_inputs(clone, def, sb->_nodes[n_clone_idx]);
a61af66fc99e Initial load
duke
parents:
diff changeset
947 }
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 //------------------------------catch_cleanup_inter_block---------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // Fix all input edges in use that reference "def". The use is in a different
a61af66fc99e Initial load
duke
parents:
diff changeset
952 // block than the def.
a61af66fc99e Initial load
duke
parents:
diff changeset
953 static void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, Block_Array &bbs, int n_clone_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
954 if( !use_blk ) return; // Can happen if the use is a precedence edge
a61af66fc99e Initial load
duke
parents:
diff changeset
955
a61af66fc99e Initial load
duke
parents:
diff changeset
956 Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, bbs, n_clone_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
957 catch_cleanup_fix_all_inputs(use, def, new_def);
a61af66fc99e Initial load
duke
parents:
diff changeset
958 }
a61af66fc99e Initial load
duke
parents:
diff changeset
959
a61af66fc99e Initial load
duke
parents:
diff changeset
960 //------------------------------call_catch_cleanup-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // If we inserted any instructions between a Call and his CatchNode,
a61af66fc99e Initial load
duke
parents:
diff changeset
962 // clone the instructions on all paths below the Catch.
a61af66fc99e Initial load
duke
parents:
diff changeset
963 void Block::call_catch_cleanup(Block_Array &bbs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
964
a61af66fc99e Initial load
duke
parents:
diff changeset
965 // End of region to clone
a61af66fc99e Initial load
duke
parents:
diff changeset
966 uint end = end_idx();
a61af66fc99e Initial load
duke
parents:
diff changeset
967 if( !_nodes[end]->is_Catch() ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // Start of region to clone
a61af66fc99e Initial load
duke
parents:
diff changeset
969 uint beg = end;
a61af66fc99e Initial load
duke
parents:
diff changeset
970 while( _nodes[beg-1]->Opcode() != Op_MachProj ||
a61af66fc99e Initial load
duke
parents:
diff changeset
971 !_nodes[beg-1]->in(0)->is_Call() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
972 beg--;
a61af66fc99e Initial load
duke
parents:
diff changeset
973 assert(beg > 0,"Catch cleanup walking beyond block boundary");
a61af66fc99e Initial load
duke
parents:
diff changeset
974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
975 // Range of inserted instructions is [beg, end)
a61af66fc99e Initial load
duke
parents:
diff changeset
976 if( beg == end ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 // Clone along all Catch output paths. Clone area between the 'beg' and
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // 'end' indices.
a61af66fc99e Initial load
duke
parents:
diff changeset
980 for( uint i = 0; i < _num_succs; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
981 Block *sb = _succs[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // Clone the entire area; ignoring the edge fixup for now.
a61af66fc99e Initial load
duke
parents:
diff changeset
983 for( uint j = end; j > beg; j-- ) {
1693
6c9cc03d8726 6973329: C2 with Zero based COOP produces code with broken anti-dependency on x86
kvn
parents: 1685
diff changeset
984 // It is safe here to clone a node with anti_dependence
6c9cc03d8726 6973329: C2 with Zero based COOP produces code with broken anti-dependency on x86
kvn
parents: 1685
diff changeset
985 // since clones dominate on each path.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
986 Node *clone = _nodes[j-1]->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
987 sb->_nodes.insert( 1, clone );
a61af66fc99e Initial load
duke
parents:
diff changeset
988 bbs.map(clone->_idx,sb);
a61af66fc99e Initial load
duke
parents:
diff changeset
989 }
a61af66fc99e Initial load
duke
parents:
diff changeset
990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
991
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 // Fixup edges. Check the def-use info per cloned Node
a61af66fc99e Initial load
duke
parents:
diff changeset
994 for(uint i2 = beg; i2 < end; i2++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
995 uint n_clone_idx = i2-beg+1; // Index of clone of n in each successor block
a61af66fc99e Initial load
duke
parents:
diff changeset
996 Node *n = _nodes[i2]; // Node that got cloned
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // Need DU safe iterator because of edge manipulation in calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
998 Unique_Node_List *out = new Unique_Node_List(Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
999 for (DUIterator_Fast j1max, j1 = n->fast_outs(j1max); j1 < j1max; j1++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 out->push(n->fast_out(j1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 uint max = out->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 for (uint j = 0; j < max; j++) {// For all users
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 Node *use = out->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 Block *buse = bbs[use->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 if( use->is_Phi() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 for( uint k = 1; k < use->req(); k++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 if( use->in(k) == n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 Node *fixup = catch_cleanup_find_cloned_def(bbs[buse->pred(k)->_idx], n, this, bbs, n_clone_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 use->set_req(k, fixup);
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 if (this == buse) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 catch_cleanup_intra_block(use, n, this, beg, n_clone_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 catch_cleanup_inter_block(use, buse, n, this, bbs, n_clone_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 } // End for all users
a61af66fc99e Initial load
duke
parents:
diff changeset
1020
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 } // End of for all Nodes in cloned area
a61af66fc99e Initial load
duke
parents:
diff changeset
1022
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 // Remove the now-dead cloned ops
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 for(uint i3 = beg; i3 < end; i3++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 _nodes[beg]->disconnect_inputs(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 _nodes.remove(beg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1028
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // If the successor blocks have a CreateEx node, move it back to the top
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 for(uint i4 = 0; i4 < _num_succs; i4++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 Block *sb = _succs[i4];
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 uint new_cnt = end - beg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // Remove any newly created, but dead, nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 for( uint j = new_cnt; j > 0; j-- ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 Node *n = sb->_nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 if (n->outcnt() == 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 (!n->is_Proj() || n->as_Proj()->in(0)->outcnt() == 1) ){
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 n->disconnect_inputs(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 sb->_nodes.remove(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 new_cnt--;
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 // If any newly created nodes remain, move the CreateEx node to the top
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 if (new_cnt > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 Node *cex = sb->_nodes[1+new_cnt];
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 if( cex->is_Mach() && cex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 sb->_nodes.remove(1+new_cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 sb->_nodes.insert(1,cex);
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 }