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

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