annotate src/share/vm/opto/matcher.cpp @ 452:00b023ae2d78

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
parents a1980da045cc
children 3b5ac9e7e6ea
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
196
d1605aabd0a1 6719955: Update copyright year
xdono
parents: 169
diff changeset
2 * Copyright 1997-2008 Sun Microsystems, Inc. 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 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_matcher.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 OptoReg::Name OptoReg::c_frame_pointer;
a61af66fc99e Initial load
duke
parents:
diff changeset
29
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31
a61af66fc99e Initial load
duke
parents:
diff changeset
32 const int Matcher::base2reg[Type::lastype] = {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
33 Node::NotAMachineReg,0,0, Op_RegI, Op_RegL, 0, Op_RegN,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
34 Node::NotAMachineReg, Node::NotAMachineReg, /* tuple, array */
a61af66fc99e Initial load
duke
parents:
diff changeset
35 Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, /* the pointers */
a61af66fc99e Initial load
duke
parents:
diff changeset
36 0, 0/*abio*/,
a61af66fc99e Initial load
duke
parents:
diff changeset
37 Op_RegP /* Return address */, 0, /* the memories */
a61af66fc99e Initial load
duke
parents:
diff changeset
38 Op_RegF, Op_RegF, Op_RegF, Op_RegD, Op_RegD, Op_RegD,
a61af66fc99e Initial load
duke
parents:
diff changeset
39 0 /*bottom*/
a61af66fc99e Initial load
duke
parents:
diff changeset
40 };
a61af66fc99e Initial load
duke
parents:
diff changeset
41
a61af66fc99e Initial load
duke
parents:
diff changeset
42 const RegMask *Matcher::idealreg2regmask[_last_machine_leaf];
a61af66fc99e Initial load
duke
parents:
diff changeset
43 RegMask Matcher::mreg2regmask[_last_Mach_Reg];
a61af66fc99e Initial load
duke
parents:
diff changeset
44 RegMask Matcher::STACK_ONLY_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 RegMask Matcher::c_frame_ptr_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 const uint Matcher::_begin_rematerialize = _BEGIN_REMATERIALIZE;
a61af66fc99e Initial load
duke
parents:
diff changeset
47 const uint Matcher::_end_rematerialize = _END_REMATERIALIZE;
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 //---------------------------Matcher-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
50 Matcher::Matcher( Node_List &proj_list ) :
a61af66fc99e Initial load
duke
parents:
diff changeset
51 PhaseTransform( Phase::Ins_Select ),
a61af66fc99e Initial load
duke
parents:
diff changeset
52 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
53 _old2new_map(C->comp_arena()),
222
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
54 _new2old_map(C->comp_arena()),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
55 #endif
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
56 _shared_nodes(C->comp_arena()),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
57 _reduceOp(reduceOp), _leftOp(leftOp), _rightOp(rightOp),
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _swallowed(swallowed),
a61af66fc99e Initial load
duke
parents:
diff changeset
59 _begin_inst_chain_rule(_BEGIN_INST_CHAIN_RULE),
a61af66fc99e Initial load
duke
parents:
diff changeset
60 _end_inst_chain_rule(_END_INST_CHAIN_RULE),
a61af66fc99e Initial load
duke
parents:
diff changeset
61 _must_clone(must_clone), _proj_list(proj_list),
a61af66fc99e Initial load
duke
parents:
diff changeset
62 _register_save_policy(register_save_policy),
a61af66fc99e Initial load
duke
parents:
diff changeset
63 _c_reg_save_policy(c_reg_save_policy),
a61af66fc99e Initial load
duke
parents:
diff changeset
64 _register_save_type(register_save_type),
a61af66fc99e Initial load
duke
parents:
diff changeset
65 _ruleName(ruleName),
a61af66fc99e Initial load
duke
parents:
diff changeset
66 _allocation_started(false),
a61af66fc99e Initial load
duke
parents:
diff changeset
67 _states_arena(Chunk::medium_size),
a61af66fc99e Initial load
duke
parents:
diff changeset
68 _visited(&_states_arena),
a61af66fc99e Initial load
duke
parents:
diff changeset
69 _shared(&_states_arena),
a61af66fc99e Initial load
duke
parents:
diff changeset
70 _dontcare(&_states_arena) {
a61af66fc99e Initial load
duke
parents:
diff changeset
71 C->set_matcher(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 idealreg2spillmask[Op_RegI] = NULL;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
74 idealreg2spillmask[Op_RegN] = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
75 idealreg2spillmask[Op_RegL] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
76 idealreg2spillmask[Op_RegF] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 idealreg2spillmask[Op_RegD] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 idealreg2spillmask[Op_RegP] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 idealreg2debugmask[Op_RegI] = NULL;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
81 idealreg2debugmask[Op_RegN] = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
82 idealreg2debugmask[Op_RegL] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
83 idealreg2debugmask[Op_RegF] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
84 idealreg2debugmask[Op_RegD] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 idealreg2debugmask[Op_RegP] = NULL;
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
86 debug_only(_mem_node = NULL;) // Ideal memory node consumed by mach node
0
a61af66fc99e Initial load
duke
parents:
diff changeset
87 }
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 //------------------------------warp_incoming_stk_arg------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // This warps a VMReg into an OptoReg::Name
a61af66fc99e Initial load
duke
parents:
diff changeset
91 OptoReg::Name Matcher::warp_incoming_stk_arg( VMReg reg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
92 OptoReg::Name warped;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 if( reg->is_stack() ) { // Stack slot argument?
a61af66fc99e Initial load
duke
parents:
diff changeset
94 warped = OptoReg::add(_old_SP, reg->reg2stack() );
a61af66fc99e Initial load
duke
parents:
diff changeset
95 warped = OptoReg::add(warped, C->out_preserve_stack_slots());
a61af66fc99e Initial load
duke
parents:
diff changeset
96 if( warped >= _in_arg_limit )
a61af66fc99e Initial load
duke
parents:
diff changeset
97 _in_arg_limit = OptoReg::add(warped, 1); // Bump max stack slot seen
a61af66fc99e Initial load
duke
parents:
diff changeset
98 if (!RegMask::can_represent(warped)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // the compiler cannot represent this method's calling sequence
a61af66fc99e Initial load
duke
parents:
diff changeset
100 C->record_method_not_compilable_all_tiers("unsupported incoming calling sequence");
a61af66fc99e Initial load
duke
parents:
diff changeset
101 return OptoReg::Bad;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103 return warped;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105 return OptoReg::as_OptoReg(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 //---------------------------compute_old_SP------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
109 OptoReg::Name Compile::compute_old_SP() {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 int fixed = fixed_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
111 int preserve = in_preserve_stack_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
112 return OptoReg::stack2reg(round_to(fixed + preserve, Matcher::stack_alignment_in_slots()));
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
118 void Matcher::verify_new_nodes_only(Node* xroot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // Make sure that the new graph only references new nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
120 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 Unique_Node_List worklist;
a61af66fc99e Initial load
duke
parents:
diff changeset
122 VectorSet visited(Thread::current()->resource_area());
a61af66fc99e Initial load
duke
parents:
diff changeset
123 worklist.push(xroot);
a61af66fc99e Initial load
duke
parents:
diff changeset
124 while (worklist.size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
125 Node* n = worklist.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
126 visited <<= n->_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
127 assert(C->node_arena()->contains(n), "dead node");
a61af66fc99e Initial load
duke
parents:
diff changeset
128 for (uint j = 0; j < n->req(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
129 Node* in = n->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
130 if (in != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 assert(C->node_arena()->contains(in), "dead node");
a61af66fc99e Initial load
duke
parents:
diff changeset
132 if (!visited.test(in->_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
133 worklist.push(in);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 //---------------------------match---------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
143 void Matcher::match( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // One-time initialization of some register masks.
a61af66fc99e Initial load
duke
parents:
diff changeset
145 init_spill_mask( C->root()->in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
146 _return_addr_mask = return_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
147 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // Pointers take 2 slots in 64-bit land
a61af66fc99e Initial load
duke
parents:
diff changeset
149 _return_addr_mask.Insert(OptoReg::add(return_addr(),1));
a61af66fc99e Initial load
duke
parents:
diff changeset
150 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // Map a Java-signature return type into return register-value
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // machine registers for 0, 1 and 2 returned values.
a61af66fc99e Initial load
duke
parents:
diff changeset
154 const TypeTuple *range = C->tf()->range();
a61af66fc99e Initial load
duke
parents:
diff changeset
155 if( range->cnt() > TypeFunc::Parms ) { // If not a void function
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // Get ideal-register return type
a61af66fc99e Initial load
duke
parents:
diff changeset
157 int ireg = base2reg[range->field_at(TypeFunc::Parms)->base()];
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // Get machine return register
a61af66fc99e Initial load
duke
parents:
diff changeset
159 uint sop = C->start()->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
160 OptoRegPair regs = return_value(ireg, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // And mask for same
a61af66fc99e Initial load
duke
parents:
diff changeset
163 _return_value_mask = RegMask(regs.first());
a61af66fc99e Initial load
duke
parents:
diff changeset
164 if( OptoReg::is_valid(regs.second()) )
a61af66fc99e Initial load
duke
parents:
diff changeset
165 _return_value_mask.Insert(regs.second());
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // ---------------
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // Frame Layout
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Need the method signature to determine the incoming argument types,
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // because the types determine which registers the incoming arguments are
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // in, and this affects the matched code.
a61af66fc99e Initial load
duke
parents:
diff changeset
174 const TypeTuple *domain = C->tf()->domain();
a61af66fc99e Initial load
duke
parents:
diff changeset
175 uint argcnt = domain->cnt() - TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
176 BasicType *sig_bt = NEW_RESOURCE_ARRAY( BasicType, argcnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
177 VMRegPair *vm_parm_regs = NEW_RESOURCE_ARRAY( VMRegPair, argcnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
178 _parm_regs = NEW_RESOURCE_ARRAY( OptoRegPair, argcnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
179 _calling_convention_mask = NEW_RESOURCE_ARRAY( RegMask, argcnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
180 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 for( i = 0; i<argcnt; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 sig_bt[i] = domain->field_at(i+TypeFunc::Parms)->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // Pass array of ideal registers and length to USER code (from the AD file)
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // that will convert this to an array of register numbers.
a61af66fc99e Initial load
duke
parents:
diff changeset
187 const StartNode *start = C->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
188 start->calling_convention( sig_bt, vm_parm_regs, argcnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
189 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // Sanity check users' calling convention. Real handy while trying to
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // get the initial port correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
192 { for (uint i = 0; i<argcnt; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 if( !vm_parm_regs[i].first()->is_valid() && !vm_parm_regs[i].second()->is_valid() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 assert(domain->field_at(i+TypeFunc::Parms)==Type::HALF, "only allowed on halve" );
a61af66fc99e Initial load
duke
parents:
diff changeset
195 _parm_regs[i].set_bad();
a61af66fc99e Initial load
duke
parents:
diff changeset
196 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
198 VMReg parm_reg = vm_parm_regs[i].first();
a61af66fc99e Initial load
duke
parents:
diff changeset
199 assert(parm_reg->is_valid(), "invalid arg?");
a61af66fc99e Initial load
duke
parents:
diff changeset
200 if (parm_reg->is_reg()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 OptoReg::Name opto_parm_reg = OptoReg::as_OptoReg(parm_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
202 assert(can_be_java_arg(opto_parm_reg) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
203 C->stub_function() == CAST_FROM_FN_PTR(address, OptoRuntime::rethrow_C) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
204 opto_parm_reg == inline_cache_reg(),
a61af66fc99e Initial load
duke
parents:
diff changeset
205 "parameters in register must be preserved by runtime stubs");
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207 for (uint j = 0; j < i; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 assert(parm_reg != vm_parm_regs[j].first(),
a61af66fc99e Initial load
duke
parents:
diff changeset
209 "calling conv. must produce distinct regs");
a61af66fc99e Initial load
duke
parents:
diff changeset
210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
213 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // Do some initial frame layout.
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // Compute the old incoming SP (may be called FP) as
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // OptoReg::stack0() + locks + in_preserve_stack_slots + pad2.
a61af66fc99e Initial load
duke
parents:
diff changeset
219 _old_SP = C->compute_old_SP();
a61af66fc99e Initial load
duke
parents:
diff changeset
220 assert( is_even(_old_SP), "must be even" );
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // Compute highest incoming stack argument as
a61af66fc99e Initial load
duke
parents:
diff changeset
223 // _old_SP + out_preserve_stack_slots + incoming argument size.
a61af66fc99e Initial load
duke
parents:
diff changeset
224 _in_arg_limit = OptoReg::add(_old_SP, C->out_preserve_stack_slots());
a61af66fc99e Initial load
duke
parents:
diff changeset
225 assert( is_even(_in_arg_limit), "out_preserve must be even" );
a61af66fc99e Initial load
duke
parents:
diff changeset
226 for( i = 0; i < argcnt; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // Permit args to have no register
a61af66fc99e Initial load
duke
parents:
diff changeset
228 _calling_convention_mask[i].Clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
229 if( !vm_parm_regs[i].first()->is_valid() && !vm_parm_regs[i].second()->is_valid() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // calling_convention returns stack arguments as a count of
a61af66fc99e Initial load
duke
parents:
diff changeset
233 // slots beyond OptoReg::stack0()/VMRegImpl::stack0. We need to convert this to
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // the allocators point of view, taking into account all the
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // preserve area, locks & pad2.
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 OptoReg::Name reg1 = warp_incoming_stk_arg(vm_parm_regs[i].first());
a61af66fc99e Initial load
duke
parents:
diff changeset
238 if( OptoReg::is_valid(reg1))
a61af66fc99e Initial load
duke
parents:
diff changeset
239 _calling_convention_mask[i].Insert(reg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
240
a61af66fc99e Initial load
duke
parents:
diff changeset
241 OptoReg::Name reg2 = warp_incoming_stk_arg(vm_parm_regs[i].second());
a61af66fc99e Initial load
duke
parents:
diff changeset
242 if( OptoReg::is_valid(reg2))
a61af66fc99e Initial load
duke
parents:
diff changeset
243 _calling_convention_mask[i].Insert(reg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // Saved biased stack-slot register number
a61af66fc99e Initial load
duke
parents:
diff changeset
246 _parm_regs[i].set_pair(reg2, reg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // Finally, make sure the incoming arguments take up an even number of
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // words, in case the arguments or locals need to contain doubleword stack
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // slots. The rest of the system assumes that stack slot pairs (in
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // particular, in the spill area) which look aligned will in fact be
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // aligned relative to the stack pointer in the target machine. Double
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // stack slots will always be allocated aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
255 _new_SP = OptoReg::Name(round_to(_in_arg_limit, RegMask::SlotsPerLong));
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // Compute highest outgoing stack argument as
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // _new_SP + out_preserve_stack_slots + max(outgoing argument size).
a61af66fc99e Initial load
duke
parents:
diff changeset
259 _out_arg_limit = OptoReg::add(_new_SP, C->out_preserve_stack_slots());
a61af66fc99e Initial load
duke
parents:
diff changeset
260 assert( is_even(_out_arg_limit), "out_preserve must be even" );
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262 if (!RegMask::can_represent(OptoReg::add(_out_arg_limit,-1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // the compiler cannot represent this method's calling sequence
a61af66fc99e Initial load
duke
parents:
diff changeset
264 C->record_method_not_compilable("must be able to represent all call arguments in reg mask");
a61af66fc99e Initial load
duke
parents:
diff changeset
265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 if (C->failing()) return; // bailed out on incoming arg failure
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // ---------------
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Collect roots of matcher trees. Every node for which
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // _shared[_idx] is cleared is guaranteed to not be shared, and thus
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // can be a valid interior of some tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
273 find_shared( C->root() );
a61af66fc99e Initial load
duke
parents:
diff changeset
274 find_shared( C->top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
275
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 309
diff changeset
276 C->print_method("Before Matching");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // Swap out to old-space; emptying new-space
a61af66fc99e Initial load
duke
parents:
diff changeset
279 Arena *old = C->node_arena()->move_contents(C->old_arena());
a61af66fc99e Initial load
duke
parents:
diff changeset
280
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // Save debug and profile information for nodes in old space:
a61af66fc99e Initial load
duke
parents:
diff changeset
282 _old_node_note_array = C->node_note_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
283 if (_old_node_note_array != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 C->set_node_note_array(new(C->comp_arena()) GrowableArray<Node_Notes*>
a61af66fc99e Initial load
duke
parents:
diff changeset
285 (C->comp_arena(), _old_node_note_array->length(),
a61af66fc99e Initial load
duke
parents:
diff changeset
286 0, NULL));
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // Pre-size the new_node table to avoid the need for range checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
290 grow_new_node_array(C->unique());
a61af66fc99e Initial load
duke
parents:
diff changeset
291
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // Reset node counter so MachNodes start with _idx at 0
a61af66fc99e Initial load
duke
parents:
diff changeset
293 int nodes = C->unique(); // save value
a61af66fc99e Initial load
duke
parents:
diff changeset
294 C->set_unique(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // Recursively match trees from old space into new space.
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // Correct leaves of new-space Nodes; they point to old-space.
a61af66fc99e Initial load
duke
parents:
diff changeset
298 _visited.Clear(); // Clear visit bits for xform call
a61af66fc99e Initial load
duke
parents:
diff changeset
299 C->set_cached_top_node(xform( C->top(), nodes ));
a61af66fc99e Initial load
duke
parents:
diff changeset
300 if (!C->failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 Node* xroot = xform( C->root(), 1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
302 if (xroot == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
303 Matcher::soft_match_failure(); // recursive matching process failed
a61af66fc99e Initial load
duke
parents:
diff changeset
304 C->record_method_not_compilable("instruction match failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
305 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // During matching shared constants were attached to C->root()
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // because xroot wasn't available yet, so transfer the uses to
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // the xroot.
a61af66fc99e Initial load
duke
parents:
diff changeset
309 for( DUIterator_Fast jmax, j = C->root()->fast_outs(jmax); j < jmax; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 Node* n = C->root()->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 if (C->node_arena()->contains(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
312 assert(n->in(0) == C->root(), "should be control user");
a61af66fc99e Initial load
duke
parents:
diff changeset
313 n->set_req(0, xroot);
a61af66fc99e Initial load
duke
parents:
diff changeset
314 --j;
a61af66fc99e Initial load
duke
parents:
diff changeset
315 --jmax;
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 C->set_root(xroot->is_Root() ? xroot->as_Root() : NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
320 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
321 verify_new_nodes_only(xroot);
a61af66fc99e Initial load
duke
parents:
diff changeset
322 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
325 if (C->top() == NULL || C->root() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 C->record_method_not_compilable("graph lost"); // %%% cannot happen?
a61af66fc99e Initial load
duke
parents:
diff changeset
327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if (C->failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // delete old;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 old->destruct_contents();
a61af66fc99e Initial load
duke
parents:
diff changeset
331 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
333 assert( C->top(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
334 assert( C->root(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
335 validate_null_checks();
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // Now smoke old-space
a61af66fc99e Initial load
duke
parents:
diff changeset
338 NOT_DEBUG( old->destruct_contents() );
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // ------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // Set up save-on-entry registers
a61af66fc99e Initial load
duke
parents:
diff changeset
342 Fixup_Save_On_Entry( );
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 //------------------------------Fixup_Save_On_Entry----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // The stated purpose of this routine is to take care of save-on-entry
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // registers. However, the overall goal of the Match phase is to convert into
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // machine-specific instructions which have RegMasks to guide allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // So what this procedure really does is put a valid RegMask on each input
a61af66fc99e Initial load
duke
parents:
diff changeset
351 // to the machine-specific variations of all Return, TailCall and Halt
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // instructions. It also adds edgs to define the save-on-entry values (and of
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // course gives them a mask).
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355 static RegMask *init_input_masks( uint size, RegMask &ret_adr, RegMask &fp ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
356 RegMask *rms = NEW_RESOURCE_ARRAY( RegMask, size );
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // Do all the pre-defined register masks
a61af66fc99e Initial load
duke
parents:
diff changeset
358 rms[TypeFunc::Control ] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
359 rms[TypeFunc::I_O ] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
360 rms[TypeFunc::Memory ] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
361 rms[TypeFunc::ReturnAdr] = ret_adr;
a61af66fc99e Initial load
duke
parents:
diff changeset
362 rms[TypeFunc::FramePtr ] = fp;
a61af66fc99e Initial load
duke
parents:
diff changeset
363 return rms;
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 //---------------------------init_first_stack_mask-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // Create the initial stack mask used by values spilling to the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // Disallow any debug info in outgoing argument areas by setting the
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // initial mask accordingly.
a61af66fc99e Initial load
duke
parents:
diff changeset
370 void Matcher::init_first_stack_mask() {
a61af66fc99e Initial load
duke
parents:
diff changeset
371
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // Allocate storage for spill masks as masks for the appropriate load type.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
373 RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_D(sizeof(RegMask)*12);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
374 idealreg2spillmask[Op_RegN] = &rms[0];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
375 idealreg2spillmask[Op_RegI] = &rms[1];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
376 idealreg2spillmask[Op_RegL] = &rms[2];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
377 idealreg2spillmask[Op_RegF] = &rms[3];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
378 idealreg2spillmask[Op_RegD] = &rms[4];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
379 idealreg2spillmask[Op_RegP] = &rms[5];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
380 idealreg2debugmask[Op_RegN] = &rms[6];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
381 idealreg2debugmask[Op_RegI] = &rms[7];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
382 idealreg2debugmask[Op_RegL] = &rms[8];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
383 idealreg2debugmask[Op_RegF] = &rms[9];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
384 idealreg2debugmask[Op_RegD] = &rms[10];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
385 idealreg2debugmask[Op_RegP] = &rms[11];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
386
a61af66fc99e Initial load
duke
parents:
diff changeset
387 OptoReg::Name i;
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // At first, start with the empty mask
a61af66fc99e Initial load
duke
parents:
diff changeset
390 C->FIRST_STACK_mask().Clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
391
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // Add in the incoming argument area
a61af66fc99e Initial load
duke
parents:
diff changeset
393 OptoReg::Name init = OptoReg::add(_old_SP, C->out_preserve_stack_slots());
a61af66fc99e Initial load
duke
parents:
diff changeset
394 for (i = init; i < _in_arg_limit; i = OptoReg::add(i,1))
a61af66fc99e Initial load
duke
parents:
diff changeset
395 C->FIRST_STACK_mask().Insert(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // Add in all bits past the outgoing argument area
a61af66fc99e Initial load
duke
parents:
diff changeset
398 guarantee(RegMask::can_represent(OptoReg::add(_out_arg_limit,-1)),
a61af66fc99e Initial load
duke
parents:
diff changeset
399 "must be able to represent all call arguments in reg mask");
a61af66fc99e Initial load
duke
parents:
diff changeset
400 init = _out_arg_limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
401 for (i = init; RegMask::can_represent(i); i = OptoReg::add(i,1))
a61af66fc99e Initial load
duke
parents:
diff changeset
402 C->FIRST_STACK_mask().Insert(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
403
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // Finally, set the "infinite stack" bit.
a61af66fc99e Initial load
duke
parents:
diff changeset
405 C->FIRST_STACK_mask().set_AllStack();
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 // Make spill masks. Registers for their class, plus FIRST_STACK_mask.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
408 #ifdef _LP64
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
409 *idealreg2spillmask[Op_RegN] = *idealreg2regmask[Op_RegN];
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
410 idealreg2spillmask[Op_RegN]->OR(C->FIRST_STACK_mask());
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
411 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
412 *idealreg2spillmask[Op_RegI] = *idealreg2regmask[Op_RegI];
a61af66fc99e Initial load
duke
parents:
diff changeset
413 idealreg2spillmask[Op_RegI]->OR(C->FIRST_STACK_mask());
a61af66fc99e Initial load
duke
parents:
diff changeset
414 *idealreg2spillmask[Op_RegL] = *idealreg2regmask[Op_RegL];
a61af66fc99e Initial load
duke
parents:
diff changeset
415 idealreg2spillmask[Op_RegL]->OR(C->FIRST_STACK_mask());
a61af66fc99e Initial load
duke
parents:
diff changeset
416 *idealreg2spillmask[Op_RegF] = *idealreg2regmask[Op_RegF];
a61af66fc99e Initial load
duke
parents:
diff changeset
417 idealreg2spillmask[Op_RegF]->OR(C->FIRST_STACK_mask());
a61af66fc99e Initial load
duke
parents:
diff changeset
418 *idealreg2spillmask[Op_RegD] = *idealreg2regmask[Op_RegD];
a61af66fc99e Initial load
duke
parents:
diff changeset
419 idealreg2spillmask[Op_RegD]->OR(C->FIRST_STACK_mask());
a61af66fc99e Initial load
duke
parents:
diff changeset
420 *idealreg2spillmask[Op_RegP] = *idealreg2regmask[Op_RegP];
a61af66fc99e Initial load
duke
parents:
diff changeset
421 idealreg2spillmask[Op_RegP]->OR(C->FIRST_STACK_mask());
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // Make up debug masks. Any spill slot plus callee-save registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // Caller-save registers are assumed to be trashable by the various
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // inline-cache fixup routines.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
426 *idealreg2debugmask[Op_RegN]= *idealreg2spillmask[Op_RegN];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
427 *idealreg2debugmask[Op_RegI]= *idealreg2spillmask[Op_RegI];
a61af66fc99e Initial load
duke
parents:
diff changeset
428 *idealreg2debugmask[Op_RegL]= *idealreg2spillmask[Op_RegL];
a61af66fc99e Initial load
duke
parents:
diff changeset
429 *idealreg2debugmask[Op_RegF]= *idealreg2spillmask[Op_RegF];
a61af66fc99e Initial load
duke
parents:
diff changeset
430 *idealreg2debugmask[Op_RegD]= *idealreg2spillmask[Op_RegD];
a61af66fc99e Initial load
duke
parents:
diff changeset
431 *idealreg2debugmask[Op_RegP]= *idealreg2spillmask[Op_RegP];
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // Prevent stub compilations from attempting to reference
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // callee-saved registers from debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
435 bool exclude_soe = !Compile::current()->is_method_compilation();
a61af66fc99e Initial load
duke
parents:
diff changeset
436
a61af66fc99e Initial load
duke
parents:
diff changeset
437 for( i=OptoReg::Name(0); i<OptoReg::Name(_last_Mach_Reg); i = OptoReg::add(i,1) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // registers the caller has to save do not work
a61af66fc99e Initial load
duke
parents:
diff changeset
439 if( _register_save_policy[i] == 'C' ||
a61af66fc99e Initial load
duke
parents:
diff changeset
440 _register_save_policy[i] == 'A' ||
a61af66fc99e Initial load
duke
parents:
diff changeset
441 (_register_save_policy[i] == 'E' && exclude_soe) ) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
442 idealreg2debugmask[Op_RegN]->Remove(i);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
443 idealreg2debugmask[Op_RegI]->Remove(i); // Exclude save-on-call
a61af66fc99e Initial load
duke
parents:
diff changeset
444 idealreg2debugmask[Op_RegL]->Remove(i); // registers from debug
a61af66fc99e Initial load
duke
parents:
diff changeset
445 idealreg2debugmask[Op_RegF]->Remove(i); // masks
a61af66fc99e Initial load
duke
parents:
diff changeset
446 idealreg2debugmask[Op_RegD]->Remove(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
447 idealreg2debugmask[Op_RegP]->Remove(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 //---------------------------is_save_on_entry----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
453 bool Matcher::is_save_on_entry( int reg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 return
a61af66fc99e Initial load
duke
parents:
diff changeset
455 _register_save_policy[reg] == 'E' ||
a61af66fc99e Initial load
duke
parents:
diff changeset
456 _register_save_policy[reg] == 'A' || // Save-on-entry register?
a61af66fc99e Initial load
duke
parents:
diff changeset
457 // Also save argument registers in the trampolining stubs
a61af66fc99e Initial load
duke
parents:
diff changeset
458 (C->save_argument_registers() && is_spillable_arg(reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 //---------------------------Fixup_Save_On_Entry-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
462 void Matcher::Fixup_Save_On_Entry( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 init_first_stack_mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
464
a61af66fc99e Initial load
duke
parents:
diff changeset
465 Node *root = C->root(); // Short name for root
a61af66fc99e Initial load
duke
parents:
diff changeset
466 // Count number of save-on-entry registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
467 uint soe_cnt = number_of_saved_registers();
a61af66fc99e Initial load
duke
parents:
diff changeset
468 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
469
a61af66fc99e Initial load
duke
parents:
diff changeset
470 // Find the procedure Start Node
a61af66fc99e Initial load
duke
parents:
diff changeset
471 StartNode *start = C->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
472 assert( start, "Expect a start node" );
a61af66fc99e Initial load
duke
parents:
diff changeset
473
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // Save argument registers in the trampolining stubs
a61af66fc99e Initial load
duke
parents:
diff changeset
475 if( C->save_argument_registers() )
a61af66fc99e Initial load
duke
parents:
diff changeset
476 for( i = 0; i < _last_Mach_Reg; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
477 if( is_spillable_arg(i) )
a61af66fc99e Initial load
duke
parents:
diff changeset
478 soe_cnt++;
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // Input RegMask array shared by all Returns.
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // The type for doubles and longs has a count of 2, but
a61af66fc99e Initial load
duke
parents:
diff changeset
482 // there is only 1 returned value
a61af66fc99e Initial load
duke
parents:
diff changeset
483 uint ret_edge_cnt = TypeFunc::Parms + ((C->tf()->range()->cnt() == TypeFunc::Parms) ? 0 : 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
484 RegMask *ret_rms = init_input_masks( ret_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // Returns have 0 or 1 returned values depending on call signature.
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // Return register is specified by return_value in the AD file.
a61af66fc99e Initial load
duke
parents:
diff changeset
487 if (ret_edge_cnt > TypeFunc::Parms)
a61af66fc99e Initial load
duke
parents:
diff changeset
488 ret_rms[TypeFunc::Parms+0] = _return_value_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // Input RegMask array shared by all Rethrows.
a61af66fc99e Initial load
duke
parents:
diff changeset
491 uint reth_edge_cnt = TypeFunc::Parms+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
492 RegMask *reth_rms = init_input_masks( reth_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );
a61af66fc99e Initial load
duke
parents:
diff changeset
493 // Rethrow takes exception oop only, but in the argument 0 slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
494 reth_rms[TypeFunc::Parms] = mreg2regmask[find_receiver(false)];
a61af66fc99e Initial load
duke
parents:
diff changeset
495 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // Need two slots for ptrs in 64-bit land
a61af66fc99e Initial load
duke
parents:
diff changeset
497 reth_rms[TypeFunc::Parms].Insert(OptoReg::add(OptoReg::Name(find_receiver(false)),1));
a61af66fc99e Initial load
duke
parents:
diff changeset
498 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
499
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // Input RegMask array shared by all TailCalls
a61af66fc99e Initial load
duke
parents:
diff changeset
501 uint tail_call_edge_cnt = TypeFunc::Parms+2;
a61af66fc99e Initial load
duke
parents:
diff changeset
502 RegMask *tail_call_rms = init_input_masks( tail_call_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // Input RegMask array shared by all TailJumps
a61af66fc99e Initial load
duke
parents:
diff changeset
505 uint tail_jump_edge_cnt = TypeFunc::Parms+2;
a61af66fc99e Initial load
duke
parents:
diff changeset
506 RegMask *tail_jump_rms = init_input_masks( tail_jump_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // TailCalls have 2 returned values (target & moop), whose masks come
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // from the usual MachNode/MachOper mechanism. Find a sample
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // TailCall to extract these masks and put the correct masks into
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // the tail_call_rms array.
a61af66fc99e Initial load
duke
parents:
diff changeset
512 for( i=1; i < root->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 MachReturnNode *m = root->in(i)->as_MachReturn();
a61af66fc99e Initial load
duke
parents:
diff changeset
514 if( m->ideal_Opcode() == Op_TailCall ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 tail_call_rms[TypeFunc::Parms+0] = m->MachNode::in_RegMask(TypeFunc::Parms+0);
a61af66fc99e Initial load
duke
parents:
diff changeset
516 tail_call_rms[TypeFunc::Parms+1] = m->MachNode::in_RegMask(TypeFunc::Parms+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
517 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // TailJumps have 2 returned values (target & ex_oop), whose masks come
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // from the usual MachNode/MachOper mechanism. Find a sample
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // TailJump to extract these masks and put the correct masks into
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // the tail_jump_rms array.
a61af66fc99e Initial load
duke
parents:
diff changeset
525 for( i=1; i < root->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
526 MachReturnNode *m = root->in(i)->as_MachReturn();
a61af66fc99e Initial load
duke
parents:
diff changeset
527 if( m->ideal_Opcode() == Op_TailJump ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 tail_jump_rms[TypeFunc::Parms+0] = m->MachNode::in_RegMask(TypeFunc::Parms+0);
a61af66fc99e Initial load
duke
parents:
diff changeset
529 tail_jump_rms[TypeFunc::Parms+1] = m->MachNode::in_RegMask(TypeFunc::Parms+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
530 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
533
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // Input RegMask array shared by all Halts
a61af66fc99e Initial load
duke
parents:
diff changeset
535 uint halt_edge_cnt = TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
536 RegMask *halt_rms = init_input_masks( halt_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 // Capture the return input masks into each exit flavor
a61af66fc99e Initial load
duke
parents:
diff changeset
539 for( i=1; i < root->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
540 MachReturnNode *exit = root->in(i)->as_MachReturn();
a61af66fc99e Initial load
duke
parents:
diff changeset
541 switch( exit->ideal_Opcode() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
542 case Op_Return : exit->_in_rms = ret_rms; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
543 case Op_Rethrow : exit->_in_rms = reth_rms; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
544 case Op_TailCall : exit->_in_rms = tail_call_rms; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
545 case Op_TailJump : exit->_in_rms = tail_jump_rms; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
546 case Op_Halt : exit->_in_rms = halt_rms; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
547 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // Next unused projection number from Start.
a61af66fc99e Initial load
duke
parents:
diff changeset
552 int proj_cnt = C->tf()->domain()->cnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
553
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // Do all the save-on-entry registers. Make projections from Start for
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // them, and give them a use at the exit points. To the allocator, they
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // look like incoming register arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
557 for( i = 0; i < _last_Mach_Reg; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
558 if( is_save_on_entry(i) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
559
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // Add the save-on-entry to the mask array
a61af66fc99e Initial load
duke
parents:
diff changeset
561 ret_rms [ ret_edge_cnt] = mreg2regmask[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
562 reth_rms [ reth_edge_cnt] = mreg2regmask[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
563 tail_call_rms[tail_call_edge_cnt] = mreg2regmask[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
564 tail_jump_rms[tail_jump_edge_cnt] = mreg2regmask[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // Halts need the SOE registers, but only in the stack as debug info.
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // A just-prior uncommon-trap or deoptimization will use the SOE regs.
a61af66fc99e Initial load
duke
parents:
diff changeset
567 halt_rms [ halt_edge_cnt] = *idealreg2spillmask[_register_save_type[i]];
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 Node *mproj;
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // Is this a RegF low half of a RegD? Double up 2 adjacent RegF's
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // into a single RegD.
a61af66fc99e Initial load
duke
parents:
diff changeset
573 if( (i&1) == 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
574 _register_save_type[i ] == Op_RegF &&
a61af66fc99e Initial load
duke
parents:
diff changeset
575 _register_save_type[i+1] == Op_RegF &&
a61af66fc99e Initial load
duke
parents:
diff changeset
576 is_save_on_entry(i+1) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // Add other bit for double
a61af66fc99e Initial load
duke
parents:
diff changeset
578 ret_rms [ ret_edge_cnt].Insert(OptoReg::Name(i+1));
a61af66fc99e Initial load
duke
parents:
diff changeset
579 reth_rms [ reth_edge_cnt].Insert(OptoReg::Name(i+1));
a61af66fc99e Initial load
duke
parents:
diff changeset
580 tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1));
a61af66fc99e Initial load
duke
parents:
diff changeset
581 tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1));
a61af66fc99e Initial load
duke
parents:
diff changeset
582 halt_rms [ halt_edge_cnt].Insert(OptoReg::Name(i+1));
a61af66fc99e Initial load
duke
parents:
diff changeset
583 mproj = new (C, 1) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegD );
a61af66fc99e Initial load
duke
parents:
diff changeset
584 proj_cnt += 2; // Skip 2 for doubles
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586 else if( (i&1) == 1 && // Else check for high half of double
a61af66fc99e Initial load
duke
parents:
diff changeset
587 _register_save_type[i-1] == Op_RegF &&
a61af66fc99e Initial load
duke
parents:
diff changeset
588 _register_save_type[i ] == Op_RegF &&
a61af66fc99e Initial load
duke
parents:
diff changeset
589 is_save_on_entry(i-1) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
590 ret_rms [ ret_edge_cnt] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
591 reth_rms [ reth_edge_cnt] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
592 tail_call_rms[tail_call_edge_cnt] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
593 tail_jump_rms[tail_jump_edge_cnt] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
594 halt_rms [ halt_edge_cnt] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
595 mproj = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
596 }
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // Is this a RegI low half of a RegL? Double up 2 adjacent RegI's
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // into a single RegL.
a61af66fc99e Initial load
duke
parents:
diff changeset
599 else if( (i&1) == 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
600 _register_save_type[i ] == Op_RegI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
601 _register_save_type[i+1] == Op_RegI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
602 is_save_on_entry(i+1) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // Add other bit for long
a61af66fc99e Initial load
duke
parents:
diff changeset
604 ret_rms [ ret_edge_cnt].Insert(OptoReg::Name(i+1));
a61af66fc99e Initial load
duke
parents:
diff changeset
605 reth_rms [ reth_edge_cnt].Insert(OptoReg::Name(i+1));
a61af66fc99e Initial load
duke
parents:
diff changeset
606 tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1));
a61af66fc99e Initial load
duke
parents:
diff changeset
607 tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1));
a61af66fc99e Initial load
duke
parents:
diff changeset
608 halt_rms [ halt_edge_cnt].Insert(OptoReg::Name(i+1));
a61af66fc99e Initial load
duke
parents:
diff changeset
609 mproj = new (C, 1) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegL );
a61af66fc99e Initial load
duke
parents:
diff changeset
610 proj_cnt += 2; // Skip 2 for longs
a61af66fc99e Initial load
duke
parents:
diff changeset
611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
612 else if( (i&1) == 1 && // Else check for high half of long
a61af66fc99e Initial load
duke
parents:
diff changeset
613 _register_save_type[i-1] == Op_RegI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
614 _register_save_type[i ] == Op_RegI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
615 is_save_on_entry(i-1) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
616 ret_rms [ ret_edge_cnt] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
617 reth_rms [ reth_edge_cnt] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
618 tail_call_rms[tail_call_edge_cnt] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
619 tail_jump_rms[tail_jump_edge_cnt] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
620 halt_rms [ halt_edge_cnt] = RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
621 mproj = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
622 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // Make a projection for it off the Start
a61af66fc99e Initial load
duke
parents:
diff changeset
624 mproj = new (C, 1) MachProjNode( start, proj_cnt++, ret_rms[ret_edge_cnt], _register_save_type[i] );
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627 ret_edge_cnt ++;
a61af66fc99e Initial load
duke
parents:
diff changeset
628 reth_edge_cnt ++;
a61af66fc99e Initial load
duke
parents:
diff changeset
629 tail_call_edge_cnt ++;
a61af66fc99e Initial load
duke
parents:
diff changeset
630 tail_jump_edge_cnt ++;
a61af66fc99e Initial load
duke
parents:
diff changeset
631 halt_edge_cnt ++;
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // Add a use of the SOE register to all exit paths
a61af66fc99e Initial load
duke
parents:
diff changeset
634 for( uint j=1; j < root->req(); j++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
635 root->in(j)->add_req(mproj);
a61af66fc99e Initial load
duke
parents:
diff changeset
636 } // End of if a save-on-entry register
a61af66fc99e Initial load
duke
parents:
diff changeset
637 } // End of for all machine registers
a61af66fc99e Initial load
duke
parents:
diff changeset
638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 //------------------------------init_spill_mask--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
641 void Matcher::init_spill_mask( Node *ret ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
642 if( idealreg2regmask[Op_RegI] ) return; // One time only init
a61af66fc99e Initial load
duke
parents:
diff changeset
643
a61af66fc99e Initial load
duke
parents:
diff changeset
644 OptoReg::c_frame_pointer = c_frame_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
645 c_frame_ptr_mask = c_frame_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
646 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // pointers are twice as big
a61af66fc99e Initial load
duke
parents:
diff changeset
648 c_frame_ptr_mask.Insert(OptoReg::add(c_frame_pointer(),1));
a61af66fc99e Initial load
duke
parents:
diff changeset
649 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // Start at OptoReg::stack0()
a61af66fc99e Initial load
duke
parents:
diff changeset
652 STACK_ONLY_mask.Clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
653 OptoReg::Name init = OptoReg::stack2reg(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // STACK_ONLY_mask is all stack bits
a61af66fc99e Initial load
duke
parents:
diff changeset
655 OptoReg::Name i;
a61af66fc99e Initial load
duke
parents:
diff changeset
656 for (i = init; RegMask::can_represent(i); i = OptoReg::add(i,1))
a61af66fc99e Initial load
duke
parents:
diff changeset
657 STACK_ONLY_mask.Insert(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // Also set the "infinite stack" bit.
a61af66fc99e Initial load
duke
parents:
diff changeset
659 STACK_ONLY_mask.set_AllStack();
a61af66fc99e Initial load
duke
parents:
diff changeset
660
a61af66fc99e Initial load
duke
parents:
diff changeset
661 // Copy the register names over into the shared world
a61af66fc99e Initial load
duke
parents:
diff changeset
662 for( i=OptoReg::Name(0); i<OptoReg::Name(_last_Mach_Reg); i = OptoReg::add(i,1) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // SharedInfo::regName[i] = regName[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // Handy RegMasks per machine register
a61af66fc99e Initial load
duke
parents:
diff changeset
665 mreg2regmask[i].Insert(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
667
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // Grab the Frame Pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
669 Node *fp = ret->in(TypeFunc::FramePtr);
a61af66fc99e Initial load
duke
parents:
diff changeset
670 Node *mem = ret->in(TypeFunc::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
671 const TypePtr* atp = TypePtr::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // Share frame pointer while making spill ops
a61af66fc99e Initial load
duke
parents:
diff changeset
673 set_shared(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
674
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // Compute generic short-offset Loads
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
676 #ifdef _LP64
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
677 MachNode *spillCP = match_tree(new (C, 3) LoadNNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM));
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
678 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
679 MachNode *spillI = match_tree(new (C, 3) LoadINode(NULL,mem,fp,atp));
a61af66fc99e Initial load
duke
parents:
diff changeset
680 MachNode *spillL = match_tree(new (C, 3) LoadLNode(NULL,mem,fp,atp));
a61af66fc99e Initial load
duke
parents:
diff changeset
681 MachNode *spillF = match_tree(new (C, 3) LoadFNode(NULL,mem,fp,atp));
a61af66fc99e Initial load
duke
parents:
diff changeset
682 MachNode *spillD = match_tree(new (C, 3) LoadDNode(NULL,mem,fp,atp));
a61af66fc99e Initial load
duke
parents:
diff changeset
683 MachNode *spillP = match_tree(new (C, 3) LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM));
a61af66fc99e Initial load
duke
parents:
diff changeset
684 assert(spillI != NULL && spillL != NULL && spillF != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
685 spillD != NULL && spillP != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687 // Get the ADLC notion of the right regmask, for each basic type.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
688 #ifdef _LP64
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
689 idealreg2regmask[Op_RegN] = &spillCP->out_RegMask();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
690 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
691 idealreg2regmask[Op_RegI] = &spillI->out_RegMask();
a61af66fc99e Initial load
duke
parents:
diff changeset
692 idealreg2regmask[Op_RegL] = &spillL->out_RegMask();
a61af66fc99e Initial load
duke
parents:
diff changeset
693 idealreg2regmask[Op_RegF] = &spillF->out_RegMask();
a61af66fc99e Initial load
duke
parents:
diff changeset
694 idealreg2regmask[Op_RegD] = &spillD->out_RegMask();
a61af66fc99e Initial load
duke
parents:
diff changeset
695 idealreg2regmask[Op_RegP] = &spillP->out_RegMask();
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697
a61af66fc99e Initial load
duke
parents:
diff changeset
698 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
699 static void match_alias_type(Compile* C, Node* n, Node* m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
700 if (!VerifyAliases) return; // do not go looking for trouble by default
a61af66fc99e Initial load
duke
parents:
diff changeset
701 const TypePtr* nat = n->adr_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
702 const TypePtr* mat = m->adr_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
703 int nidx = C->get_alias_index(nat);
a61af66fc99e Initial load
duke
parents:
diff changeset
704 int midx = C->get_alias_index(mat);
a61af66fc99e Initial load
duke
parents:
diff changeset
705 // Detune the assert for cases like (AndI 0xFF (LoadB p)).
a61af66fc99e Initial load
duke
parents:
diff changeset
706 if (nidx == Compile::AliasIdxTop && midx >= Compile::AliasIdxRaw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
707 for (uint i = 1; i < n->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
708 Node* n1 = n->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
709 const TypePtr* n1at = n1->adr_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
710 if (n1at != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
711 nat = n1at;
a61af66fc99e Initial load
duke
parents:
diff changeset
712 nidx = C->get_alias_index(n1at);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 }
a61af66fc99e Initial load
duke
parents:
diff changeset
714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
716 // %%% Kludgery. Instead, fix ideal adr_type methods for all these cases:
a61af66fc99e Initial load
duke
parents:
diff changeset
717 if (nidx == Compile::AliasIdxTop && midx == Compile::AliasIdxRaw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
718 switch (n->Opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
719 case Op_PrefetchRead:
a61af66fc99e Initial load
duke
parents:
diff changeset
720 case Op_PrefetchWrite:
a61af66fc99e Initial load
duke
parents:
diff changeset
721 nidx = Compile::AliasIdxRaw;
a61af66fc99e Initial load
duke
parents:
diff changeset
722 nat = TypeRawPtr::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
726 if (nidx == Compile::AliasIdxRaw && midx == Compile::AliasIdxTop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 switch (n->Opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
728 case Op_ClearArray:
a61af66fc99e Initial load
duke
parents:
diff changeset
729 midx = Compile::AliasIdxRaw;
a61af66fc99e Initial load
duke
parents:
diff changeset
730 mat = TypeRawPtr::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
731 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
734 if (nidx == Compile::AliasIdxTop && midx == Compile::AliasIdxBot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
735 switch (n->Opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 case Op_Return:
a61af66fc99e Initial load
duke
parents:
diff changeset
737 case Op_Rethrow:
a61af66fc99e Initial load
duke
parents:
diff changeset
738 case Op_Halt:
a61af66fc99e Initial load
duke
parents:
diff changeset
739 case Op_TailCall:
a61af66fc99e Initial load
duke
parents:
diff changeset
740 case Op_TailJump:
a61af66fc99e Initial load
duke
parents:
diff changeset
741 nidx = Compile::AliasIdxBot;
a61af66fc99e Initial load
duke
parents:
diff changeset
742 nat = TypePtr::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
743 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
746 if (nidx == Compile::AliasIdxBot && midx == Compile::AliasIdxTop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
747 switch (n->Opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
748 case Op_StrComp:
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 168
diff changeset
749 case Op_AryEq:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
750 case Op_MemBarVolatile:
a61af66fc99e Initial load
duke
parents:
diff changeset
751 case Op_MemBarCPUOrder: // %%% these ideals should have narrower adr_type?
a61af66fc99e Initial load
duke
parents:
diff changeset
752 nidx = Compile::AliasIdxTop;
a61af66fc99e Initial load
duke
parents:
diff changeset
753 nat = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
754 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
755 }
a61af66fc99e Initial load
duke
parents:
diff changeset
756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
757 if (nidx != midx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
758 if (PrintOpto || (PrintMiscellaneous && (WizardMode || Verbose))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
759 tty->print_cr("==== Matcher alias shift %d => %d", nidx, midx);
a61af66fc99e Initial load
duke
parents:
diff changeset
760 n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
761 m->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
762 }
a61af66fc99e Initial load
duke
parents:
diff changeset
763 assert(C->subsume_loads() && C->must_alias(nat, midx),
a61af66fc99e Initial load
duke
parents:
diff changeset
764 "must not lose alias info when matching");
a61af66fc99e Initial load
duke
parents:
diff changeset
765 }
a61af66fc99e Initial load
duke
parents:
diff changeset
766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
767 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
768
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 //------------------------------MStack-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // State and MStack class used in xform() and find_shared() iterative methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
772 enum Node_State { Pre_Visit, // node has to be pre-visited
a61af66fc99e Initial load
duke
parents:
diff changeset
773 Visit, // visit node
a61af66fc99e Initial load
duke
parents:
diff changeset
774 Post_Visit, // post-visit node
a61af66fc99e Initial load
duke
parents:
diff changeset
775 Alt_Post_Visit // alternative post-visit path
a61af66fc99e Initial load
duke
parents:
diff changeset
776 };
a61af66fc99e Initial load
duke
parents:
diff changeset
777
a61af66fc99e Initial load
duke
parents:
diff changeset
778 class MStack: public Node_Stack {
a61af66fc99e Initial load
duke
parents:
diff changeset
779 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
780 MStack(int size) : Node_Stack(size) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
781
a61af66fc99e Initial load
duke
parents:
diff changeset
782 void push(Node *n, Node_State ns) {
a61af66fc99e Initial load
duke
parents:
diff changeset
783 Node_Stack::push(n, (uint)ns);
a61af66fc99e Initial load
duke
parents:
diff changeset
784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
785 void push(Node *n, Node_State ns, Node *parent, int indx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
786 ++_inode_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
787 if ((_inode_top + 1) >= _inode_max) grow();
a61af66fc99e Initial load
duke
parents:
diff changeset
788 _inode_top->node = parent;
a61af66fc99e Initial load
duke
parents:
diff changeset
789 _inode_top->indx = (uint)indx;
a61af66fc99e Initial load
duke
parents:
diff changeset
790 ++_inode_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
791 _inode_top->node = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
792 _inode_top->indx = (uint)ns;
a61af66fc99e Initial load
duke
parents:
diff changeset
793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
794 Node *parent() {
a61af66fc99e Initial load
duke
parents:
diff changeset
795 pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
796 return node();
a61af66fc99e Initial load
duke
parents:
diff changeset
797 }
a61af66fc99e Initial load
duke
parents:
diff changeset
798 Node_State state() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
799 return (Node_State)index();
a61af66fc99e Initial load
duke
parents:
diff changeset
800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
801 void set_state(Node_State ns) {
a61af66fc99e Initial load
duke
parents:
diff changeset
802 set_index((uint)ns);
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804 };
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806
a61af66fc99e Initial load
duke
parents:
diff changeset
807 //------------------------------xform------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
808 // Given a Node in old-space, Match him (Label/Reduce) to produce a machine
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // Node in new-space. Given a new-space Node, recursively walk his children.
a61af66fc99e Initial load
duke
parents:
diff changeset
810 Node *Matcher::transform( Node *n ) { ShouldNotCallThis(); return n; }
a61af66fc99e Initial load
duke
parents:
diff changeset
811 Node *Matcher::xform( Node *n, int max_stack ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // Use one stack to keep both: child's node/state and parent's node/index
a61af66fc99e Initial load
duke
parents:
diff changeset
813 MStack mstack(max_stack * 2 * 2); // C->unique() * 2 * 2
a61af66fc99e Initial load
duke
parents:
diff changeset
814 mstack.push(n, Visit, NULL, -1); // set NULL as parent to indicate root
a61af66fc99e Initial load
duke
parents:
diff changeset
815
a61af66fc99e Initial load
duke
parents:
diff changeset
816 while (mstack.is_nonempty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
817 n = mstack.node(); // Leave node on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
818 Node_State nstate = mstack.state();
a61af66fc99e Initial load
duke
parents:
diff changeset
819 if (nstate == Visit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
820 mstack.set_state(Post_Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
821 Node *oldn = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
822 // Old-space or new-space check
a61af66fc99e Initial load
duke
parents:
diff changeset
823 if (!C->node_arena()->contains(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // Old space!
a61af66fc99e Initial load
duke
parents:
diff changeset
825 Node* m;
a61af66fc99e Initial load
duke
parents:
diff changeset
826 if (has_new_node(n)) { // Not yet Label/Reduced
a61af66fc99e Initial load
duke
parents:
diff changeset
827 m = new_node(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
828 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
829 if (!is_dontcare(n)) { // Matcher can match this guy
a61af66fc99e Initial load
duke
parents:
diff changeset
830 // Calls match special. They match alone with no children.
a61af66fc99e Initial load
duke
parents:
diff changeset
831 // Their children, the incoming arguments, match normally.
a61af66fc99e Initial load
duke
parents:
diff changeset
832 m = n->is_SafePoint() ? match_sfpt(n->as_SafePoint()):match_tree(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
833 if (C->failing()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
834 if (m == NULL) { Matcher::soft_match_failure(); return NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
835 } else { // Nothing the matcher cares about
a61af66fc99e Initial load
duke
parents:
diff changeset
836 if( n->is_Proj() && n->in(0)->is_Multi()) { // Projections?
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // Convert to machine-dependent projection
a61af66fc99e Initial load
duke
parents:
diff changeset
838 m = n->in(0)->as_Multi()->match( n->as_Proj(), this );
222
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
839 #ifdef ASSERT
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
840 _new2old_map.map(m->_idx, n);
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
841 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
842 if (m->in(0) != NULL) // m might be top
368
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
843 collect_null_checks(m, n);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
844 } else { // Else just a regular 'ol guy
a61af66fc99e Initial load
duke
parents:
diff changeset
845 m = n->clone(); // So just clone into new-space
222
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
846 #ifdef ASSERT
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
847 _new2old_map.map(m->_idx, n);
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
848 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
849 // Def-Use edges will be added incrementally as Uses
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // of this node are matched.
a61af66fc99e Initial load
duke
parents:
diff changeset
851 assert(m->outcnt() == 0, "no Uses of this clone yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
854
a61af66fc99e Initial load
duke
parents:
diff changeset
855 set_new_node(n, m); // Map old to new
a61af66fc99e Initial load
duke
parents:
diff changeset
856 if (_old_node_note_array != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
857 Node_Notes* nn = C->locate_node_notes(_old_node_note_array,
a61af66fc99e Initial load
duke
parents:
diff changeset
858 n->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
859 C->set_node_notes_at(m->_idx, nn);
a61af66fc99e Initial load
duke
parents:
diff changeset
860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
861 debug_only(match_alias_type(C, n, m));
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863 n = m; // n is now a new-space node
a61af66fc99e Initial load
duke
parents:
diff changeset
864 mstack.set_node(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
866
a61af66fc99e Initial load
duke
parents:
diff changeset
867 // New space!
a61af66fc99e Initial load
duke
parents:
diff changeset
868 if (_visited.test_set(n->_idx)) continue; // while(mstack.is_nonempty())
a61af66fc99e Initial load
duke
parents:
diff changeset
869
a61af66fc99e Initial load
duke
parents:
diff changeset
870 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // Put precedence edges on stack first (match them last).
a61af66fc99e Initial load
duke
parents:
diff changeset
872 for (i = oldn->req(); (uint)i < oldn->len(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
873 Node *m = oldn->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
874 if (m == NULL) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
875 // set -1 to call add_prec() instead of set_req() during Step1
a61af66fc99e Initial load
duke
parents:
diff changeset
876 mstack.push(m, Visit, n, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
878
a61af66fc99e Initial load
duke
parents:
diff changeset
879 // For constant debug info, I'd rather have unmatched constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
880 int cnt = n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
881 JVMState* jvms = n->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
882 int debug_cnt = jvms ? jvms->debug_start() : cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
883
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // Now do only debug info. Clone constants rather than matching.
a61af66fc99e Initial load
duke
parents:
diff changeset
885 // Constants are represented directly in the debug info without
a61af66fc99e Initial load
duke
parents:
diff changeset
886 // the need for executable machine instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
887 // Monitor boxes are also represented directly.
a61af66fc99e Initial load
duke
parents:
diff changeset
888 for (i = cnt - 1; i >= debug_cnt; --i) { // For all debug inputs do
a61af66fc99e Initial load
duke
parents:
diff changeset
889 Node *m = n->in(i); // Get input
a61af66fc99e Initial load
duke
parents:
diff changeset
890 int op = m->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
891 assert((op == Op_BoxLock) == jvms->is_monitor_use(i), "boxes only at monitor sites");
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
892 if( op == Op_ConI || op == Op_ConP || op == Op_ConN ||
0
a61af66fc99e Initial load
duke
parents:
diff changeset
893 op == Op_ConF || op == Op_ConD || op == Op_ConL
a61af66fc99e Initial load
duke
parents:
diff changeset
894 // || op == Op_BoxLock // %%%% enable this and remove (+++) in chaitin.cpp
a61af66fc99e Initial load
duke
parents:
diff changeset
895 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
896 m = m->clone();
222
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
897 #ifdef ASSERT
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
898 _new2old_map.map(m->_idx, n);
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
899 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
900 mstack.push(m, Post_Visit, n, i); // Don't neet to visit
a61af66fc99e Initial load
duke
parents:
diff changeset
901 mstack.push(m->in(0), Visit, m, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
902 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
903 mstack.push(m, Visit, n, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
905 }
a61af66fc99e Initial load
duke
parents:
diff changeset
906
a61af66fc99e Initial load
duke
parents:
diff changeset
907 // And now walk his children, and convert his inputs to new-space.
a61af66fc99e Initial load
duke
parents:
diff changeset
908 for( ; i >= 0; --i ) { // For all normal inputs do
a61af66fc99e Initial load
duke
parents:
diff changeset
909 Node *m = n->in(i); // Get input
a61af66fc99e Initial load
duke
parents:
diff changeset
910 if(m != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
911 mstack.push(m, Visit, n, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
913
a61af66fc99e Initial load
duke
parents:
diff changeset
914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
915 else if (nstate == Post_Visit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
916 // Set xformed input
a61af66fc99e Initial load
duke
parents:
diff changeset
917 Node *p = mstack.parent();
a61af66fc99e Initial load
duke
parents:
diff changeset
918 if (p != NULL) { // root doesn't have parent
a61af66fc99e Initial load
duke
parents:
diff changeset
919 int i = (int)mstack.index();
a61af66fc99e Initial load
duke
parents:
diff changeset
920 if (i >= 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
921 p->set_req(i, n); // required input
a61af66fc99e Initial load
duke
parents:
diff changeset
922 else if (i == -1)
a61af66fc99e Initial load
duke
parents:
diff changeset
923 p->add_prec(n); // precedence input
a61af66fc99e Initial load
duke
parents:
diff changeset
924 else
a61af66fc99e Initial load
duke
parents:
diff changeset
925 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
926 }
a61af66fc99e Initial load
duke
parents:
diff changeset
927 mstack.pop(); // remove processed node from stack
a61af66fc99e Initial load
duke
parents:
diff changeset
928 }
a61af66fc99e Initial load
duke
parents:
diff changeset
929 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
930 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
932 } // while (mstack.is_nonempty())
a61af66fc99e Initial load
duke
parents:
diff changeset
933 return n; // Return new-space Node
a61af66fc99e Initial load
duke
parents:
diff changeset
934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
935
a61af66fc99e Initial load
duke
parents:
diff changeset
936 //------------------------------warp_outgoing_stk_arg------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
937 OptoReg::Name Matcher::warp_outgoing_stk_arg( VMReg reg, OptoReg::Name begin_out_arg_area, OptoReg::Name &out_arg_limit_per_call ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
938 // Convert outgoing argument location to a pre-biased stack offset
a61af66fc99e Initial load
duke
parents:
diff changeset
939 if (reg->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
940 OptoReg::Name warped = reg->reg2stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
941 // Adjust the stack slot offset to be the register number used
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // by the allocator.
a61af66fc99e Initial load
duke
parents:
diff changeset
943 warped = OptoReg::add(begin_out_arg_area, warped);
a61af66fc99e Initial load
duke
parents:
diff changeset
944 // Keep track of the largest numbered stack slot used for an arg.
a61af66fc99e Initial load
duke
parents:
diff changeset
945 // Largest used slot per call-site indicates the amount of stack
a61af66fc99e Initial load
duke
parents:
diff changeset
946 // that is killed by the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
947 if( warped >= out_arg_limit_per_call )
a61af66fc99e Initial load
duke
parents:
diff changeset
948 out_arg_limit_per_call = OptoReg::add(warped,1);
a61af66fc99e Initial load
duke
parents:
diff changeset
949 if (!RegMask::can_represent(warped)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
950 C->record_method_not_compilable_all_tiers("unsupported calling sequence");
a61af66fc99e Initial load
duke
parents:
diff changeset
951 return OptoReg::Bad;
a61af66fc99e Initial load
duke
parents:
diff changeset
952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
953 return warped;
a61af66fc99e Initial load
duke
parents:
diff changeset
954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
955 return OptoReg::as_OptoReg(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
957
a61af66fc99e Initial load
duke
parents:
diff changeset
958
a61af66fc99e Initial load
duke
parents:
diff changeset
959 //------------------------------match_sfpt-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
960 // Helper function to match call instructions. Calls match special.
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // They match alone with no children. Their children, the incoming
a61af66fc99e Initial load
duke
parents:
diff changeset
962 // arguments, match normally.
a61af66fc99e Initial load
duke
parents:
diff changeset
963 MachNode *Matcher::match_sfpt( SafePointNode *sfpt ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
964 MachSafePointNode *msfpt = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
965 MachCallNode *mcall = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
966 uint cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
967 // Split out case for SafePoint vs Call
a61af66fc99e Initial load
duke
parents:
diff changeset
968 CallNode *call;
a61af66fc99e Initial load
duke
parents:
diff changeset
969 const TypeTuple *domain;
a61af66fc99e Initial load
duke
parents:
diff changeset
970 ciMethod* method = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
971 if( sfpt->is_Call() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
972 call = sfpt->as_Call();
a61af66fc99e Initial load
duke
parents:
diff changeset
973 domain = call->tf()->domain();
a61af66fc99e Initial load
duke
parents:
diff changeset
974 cnt = domain->cnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
975
a61af66fc99e Initial load
duke
parents:
diff changeset
976 // Match just the call, nothing else
a61af66fc99e Initial load
duke
parents:
diff changeset
977 MachNode *m = match_tree(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
978 if (C->failing()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
979 if( m == NULL ) { Matcher::soft_match_failure(); return NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
980
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // Copy data from the Ideal SafePoint to the machine version
a61af66fc99e Initial load
duke
parents:
diff changeset
982 mcall = m->as_MachCall();
a61af66fc99e Initial load
duke
parents:
diff changeset
983
a61af66fc99e Initial load
duke
parents:
diff changeset
984 mcall->set_tf( call->tf());
a61af66fc99e Initial load
duke
parents:
diff changeset
985 mcall->set_entry_point(call->entry_point());
a61af66fc99e Initial load
duke
parents:
diff changeset
986 mcall->set_cnt( call->cnt());
a61af66fc99e Initial load
duke
parents:
diff changeset
987
a61af66fc99e Initial load
duke
parents:
diff changeset
988 if( mcall->is_MachCallJava() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
989 MachCallJavaNode *mcall_java = mcall->as_MachCallJava();
a61af66fc99e Initial load
duke
parents:
diff changeset
990 const CallJavaNode *call_java = call->as_CallJava();
a61af66fc99e Initial load
duke
parents:
diff changeset
991 method = call_java->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
992 mcall_java->_method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
993 mcall_java->_bci = call_java->_bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
994 mcall_java->_optimized_virtual = call_java->is_optimized_virtual();
a61af66fc99e Initial load
duke
parents:
diff changeset
995 if( mcall_java->is_MachCallStaticJava() )
a61af66fc99e Initial load
duke
parents:
diff changeset
996 mcall_java->as_MachCallStaticJava()->_name =
a61af66fc99e Initial load
duke
parents:
diff changeset
997 call_java->as_CallStaticJava()->_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
998 if( mcall_java->is_MachCallDynamicJava() )
a61af66fc99e Initial load
duke
parents:
diff changeset
999 mcall_java->as_MachCallDynamicJava()->_vtable_index =
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 call_java->as_CallDynamicJava()->_vtable_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 else if( mcall->is_MachCallRuntime() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 mcall->as_MachCallRuntime()->_name = call->as_CallRuntime()->_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 msfpt = mcall;
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 // This is a non-call safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 call = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 domain = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 MachNode *mn = match_tree(sfpt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 if (C->failing()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 msfpt = mn->as_MachSafePoint();
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 cnt = TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1016
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 // Advertise the correct memory effects (for anti-dependence computation).
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 msfpt->set_adr_type(sfpt->adr_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1019
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 // Allocate a private array of RegMasks. These RegMasks are not shared.
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 msfpt->_in_rms = NEW_RESOURCE_ARRAY( RegMask, cnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // Empty them all.
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 memset( msfpt->_in_rms, 0, sizeof(RegMask)*cnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // Do all the pre-defined non-Empty register masks
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 msfpt->_in_rms[TypeFunc::ReturnAdr] = _return_addr_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 msfpt->_in_rms[TypeFunc::FramePtr ] = c_frame_ptr_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1028
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // Place first outgoing argument can possibly be put.
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 OptoReg::Name begin_out_arg_area = OptoReg::add(_new_SP, C->out_preserve_stack_slots());
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 assert( is_even(begin_out_arg_area), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 // Compute max outgoing register number per call site.
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 OptoReg::Name out_arg_limit_per_call = begin_out_arg_area;
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 // Calls to C may hammer extra stack slots above and beyond any arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 // These are usually backing store for register arguments for varargs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 if( call != NULL && call->is_CallRuntime() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 out_arg_limit_per_call = OptoReg::add(out_arg_limit_per_call,C->varargs_C_out_slots_killed());
a61af66fc99e Initial load
duke
parents:
diff changeset
1038
a61af66fc99e Initial load
duke
parents:
diff changeset
1039
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 // Do the normal argument list (parameters) register masks
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 int argcnt = cnt - TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 if( argcnt > 0 ) { // Skip it all if we have no args
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 BasicType *sig_bt = NEW_RESOURCE_ARRAY( BasicType, argcnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 VMRegPair *parm_regs = NEW_RESOURCE_ARRAY( VMRegPair, argcnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 for( i = 0; i < argcnt; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 sig_bt[i] = domain->field_at(i+TypeFunc::Parms)->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // V-call to pick proper calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 call->calling_convention( sig_bt, parm_regs, argcnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
1051
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // Sanity check users' calling convention. Really handy during
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 // the initial porting effort. Fairly expensive otherwise.
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 { for (int i = 0; i<argcnt; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 if( !parm_regs[i].first()->is_valid() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 !parm_regs[i].second()->is_valid() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 VMReg reg1 = parm_regs[i].first();
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 VMReg reg2 = parm_regs[i].second();
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 for (int j = 0; j < i; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 if( !parm_regs[j].first()->is_valid() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 !parm_regs[j].second()->is_valid() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 VMReg reg3 = parm_regs[j].first();
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 VMReg reg4 = parm_regs[j].second();
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 if( !reg1->is_valid() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 assert( !reg2->is_valid(), "valid halvsies" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 } else if( !reg3->is_valid() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 assert( !reg4->is_valid(), "valid halvsies" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 assert( reg1 != reg2, "calling conv. must produce distinct regs");
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 assert( reg1 != reg3, "calling conv. must produce distinct regs");
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 assert( reg1 != reg4, "calling conv. must produce distinct regs");
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 assert( reg2 != reg3, "calling conv. must produce distinct regs");
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 assert( reg2 != reg4 || !reg2->is_valid(), "calling conv. must produce distinct regs");
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 assert( reg3 != reg4, "calling conv. must produce distinct regs");
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1081
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 // Visit each argument. Compute its outgoing register mask.
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 // Return results now can have 2 bits returned.
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 // Compute max over all outgoing arguments both per call-site
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 // and over the entire method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 for( i = 0; i < argcnt; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 // Address of incoming argument mask to fill in
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 RegMask *rm = &mcall->_in_rms[i+TypeFunc::Parms];
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 if( !parm_regs[i].first()->is_valid() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 !parm_regs[i].second()->is_valid() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 continue; // Avoid Halves
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // Grab first register, adjust stack slots and insert in mask.
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 OptoReg::Name reg1 = warp_outgoing_stk_arg(parm_regs[i].first(), begin_out_arg_area, out_arg_limit_per_call );
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 if (OptoReg::is_valid(reg1))
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 rm->Insert( reg1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 // Grab second register (if any), adjust stack slots and insert in mask.
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 OptoReg::Name reg2 = warp_outgoing_stk_arg(parm_regs[i].second(), begin_out_arg_area, out_arg_limit_per_call );
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 if (OptoReg::is_valid(reg2))
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 rm->Insert( reg2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 } // End of for all arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1102
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 // Compute number of stack slots needed to restore stack in case of
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 // Pascal-style argument popping.
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 mcall->_argsize = out_arg_limit_per_call - begin_out_arg_area;
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1107
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // Compute the max stack slot killed by any call. These will not be
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // available for debug info, and will be used to adjust FIRST_STACK_mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // after all call sites have been visited.
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 if( _out_arg_limit < out_arg_limit_per_call)
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 _out_arg_limit = out_arg_limit_per_call;
a61af66fc99e Initial load
duke
parents:
diff changeset
1113
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 if (mcall) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 // Kill the outgoing argument area, including any non-argument holes and
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 // any legacy C-killed slots. Use Fat-Projections to do the killing.
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 // Since the max-per-method covers the max-per-call-site and debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 // is excluded on the max-per-method basis, debug info cannot land in
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 // this killed area.
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 uint r_cnt = mcall->tf()->range()->cnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 MachProjNode *proj = new (C, 1) MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj );
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 if (!RegMask::can_represent(OptoReg::Name(out_arg_limit_per_call-1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 C->record_method_not_compilable_all_tiers("unsupported outgoing calling sequence");
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 for (int i = begin_out_arg_area; i < out_arg_limit_per_call; i++)
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 proj->_rout.Insert(OptoReg::Name(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 if( proj->_rout.is_NotEmpty() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 _proj_list.push(proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // Transfer the safepoint information from the call to the mcall
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 // Move the JVMState list
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 msfpt->set_jvms(sfpt->jvms());
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 for (JVMState* jvms = msfpt->jvms(); jvms; jvms = jvms->caller()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 jvms->set_map(sfpt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1137
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // Debug inputs begin just after the last incoming parameter
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 assert( (mcall == NULL) || (mcall->jvms() == NULL) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 (mcall->jvms()->debug_start() + mcall->_jvmadj == mcall->tf()->domain()->cnt()), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1141
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // Move the OopMap
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 msfpt->_oop_map = sfpt->_oop_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1144
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 // Registers killed by the call are set in the local scheduling pass
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // of Global Code Motion.
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 return msfpt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1149
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 //---------------------------match_tree----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // Match a Ideal Node DAG - turn it into a tree; Label & Reduce. Used as part
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // of the whole-sale conversion from Ideal to Mach Nodes. Also used for
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // making GotoNodes while building the CFG and in init_spill_mask() to identify
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // a Load's result RegMask for memoization in idealreg2regmask[]
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 MachNode *Matcher::match_tree( const Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 assert( n->Opcode() != Op_Phi, "cannot match" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 assert( !n->is_block_start(), "cannot match" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 // Set the mark for all locally allocated State objects.
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 // When this call returns, the _states_arena arena will be reset
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 // freeing all State objects.
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 ResourceMark rm( &_states_arena );
a61af66fc99e Initial load
duke
parents:
diff changeset
1162
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 LabelRootDepth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1164
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // StoreNodes require their Memory input to match any LoadNodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 Node *mem = n->is_Store() ? n->in(MemNode::Memory) : (Node*)1 ;
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1167 #ifdef ASSERT
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1168 Node* save_mem_node = _mem_node;
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1169 _mem_node = n->is_Store() ? (Node*)n : NULL;
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1170 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // State object for root node of match tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 // Allocate it on _states_arena - stack allocation can cause stack overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 State *s = new (&_states_arena) State;
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 s->_kids[0] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 s->_kids[1] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 s->_leaf = (Node*)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // Label the input tree, allocating labels from top-level arena
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 Label_Root( n, s, n->in(0), mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 if (C->failing()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1180
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 // The minimum cost match for the whole tree is found at the root State
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 uint mincost = max_juint;
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 uint cost = max_juint;
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 for( i = 0; i < NUM_OPERANDS; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 if( s->valid(i) && // valid entry and
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 s->_cost[i] < cost && // low cost and
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 s->_rule[i] >= NUM_OPERANDS ) // not an operand
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 cost = s->_cost[mincost=i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 if (mincost == max_juint) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 tty->print("No matching rule for:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 s->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 Matcher::soft_match_failure();
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // Reduce input tree based upon the state labels to machine Nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 MachNode *m = ReduceInst( s, s->_rule[mincost], mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 _old2new_map.map(n->_idx, m);
222
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
1203 _new2old_map.map(m->_idx, (Node*)n);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1205
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 // Add any Matcher-ignored edges
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 uint cnt = n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 uint start = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 if( mem != (Node*)1 ) start = MemNode::Memory+1;
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1210 if( n->is_AddP() ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 assert( mem == (Node*)1, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 start = AddPNode::Base+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 for( i = start; i < cnt; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 if( !n->match_edge(i) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 if( i < m->req() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 m->ins_req( i, n->in(i) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 m->add_req( n->in(i) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1222
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1223 debug_only( _mem_node = save_mem_node; )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 return m;
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1226
a61af66fc99e Initial load
duke
parents:
diff changeset
1227
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 //------------------------------match_into_reg---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 // Choose to either match this Node in a register or part of the current
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 // match tree. Return true for requiring a register and false for matching
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 // as part of the current match tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 static bool match_into_reg( const Node *n, Node *m, Node *control, int i, bool shared ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1233
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 const Type *t = m->bottom_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1235
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 if( t->singleton() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 // Never force constants into registers. Allow them to match as
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // constants or registers. Copies of the same value will share
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1239 // the same register. See find_shared_node.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 } else { // Not a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 // Stop recursion if they have different Controls.
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 // Slot 0 of constants is not really a Control.
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 if( control && m->in(0) && control != m->in(0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1245
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 // Actually, we can live with the most conservative control we
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 // find, if it post-dominates the others. This allows us to
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 // pick up load/op/store trees where the load can float a little
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // above the store.
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 Node *x = control;
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 const uint max_scan = 6; // Arbitrary scan cutoff
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 uint j;
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 for( j=0; j<max_scan; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 if( x->is_Region() ) // Bail out at merge points
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 x = x->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 if( x == m->in(0) ) // Does 'control' post-dominate
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 break; // m->in(0)? If so, we can use it
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 if( j == max_scan ) // No post-domination before scan end?
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 return true; // Then break the match tree up
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 }
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1263 if (m->is_DecodeN() && Matcher::clone_shift_expressions) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
1264 // These are commonly used in address expressions and can
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1265 // efficiently fold into them on X64 in some cases.
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1266 return false;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
1267 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1269
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 // Not forceably cloning. If shared, put it into a register.
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 return shared;
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1273
a61af66fc99e Initial load
duke
parents:
diff changeset
1274
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 //------------------------------Instruction Selection--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 // Label method walks a "tree" of nodes, using the ADLC generated DFA to match
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // ideal nodes to machine instructions. Trees are delimited by shared Nodes,
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 // things the Matcher does not match (e.g., Memory), and things with different
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 // Controls (hence forced into different blocks). We pass in the Control
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 // selected for this entire State tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
1281
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // The Matcher works on Trees, but an Intel add-to-memory requires a DAG: the
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // Store and the Load must have identical Memories (as well as identical
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // pointers). Since the Matcher does not have anything for Memory (and
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // does not handle DAGs), I have to match the Memory input myself. If the
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 // Tree root is a Store, I require all Loads to have the identical memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 Node *Matcher::Label_Root( const Node *n, State *svec, Node *control, const Node *mem){
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // Since Label_Root is a recursive function, its possible that we might run
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 // out of stack space. See bugs 6272980 & 6227033 for more info.
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 LabelRootDepth++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 if (LabelRootDepth > MaxLabelRootDepth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 C->record_method_not_compilable_all_tiers("Out of stack space, increase MaxLabelRootDepth");
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 uint care = 0; // Edges matcher cares about
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 uint cnt = n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 uint i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1298
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // Examine children for memory state
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 // Can only subsume a child into your match-tree if that child's memory state
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 // is not modified along the path to another input.
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 // It is unsafe even if the other inputs are separate roots.
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 Node *input_mem = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 for( i = 1; i < cnt; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 if( !n->match_edge(i) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 Node *m = n->in(i); // Get ith input
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 assert( m, "expect non-null children" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 if( m->is_Load() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 if( input_mem == NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 input_mem = m->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 } else if( input_mem != m->in(MemNode::Memory) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 input_mem = NodeSentinel;
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1316
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 for( i = 1; i < cnt; i++ ){// For my children
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 if( !n->match_edge(i) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 Node *m = n->in(i); // Get ith input
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 // Allocate states out of a private arena
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 State *s = new (&_states_arena) State;
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 svec->_kids[care++] = s;
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 assert( care <= 2, "binary only for now" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1324
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 // Recursively label the State tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 s->_kids[0] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 s->_kids[1] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 s->_leaf = m;
a61af66fc99e Initial load
duke
parents:
diff changeset
1329
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 // Check for leaves of the State Tree; things that cannot be a part of
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 // the current tree. If it finds any, that value is matched as a
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 // register operand. If not, then the normal matching is used.
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 if( match_into_reg(n, m, control, i, is_shared(m)) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 // Stop recursion if this is LoadNode and the root of this tree is a
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 // StoreNode and the load & store have different memories.
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 ((mem!=(Node*)1) && m->is_Load() && m->in(MemNode::Memory) != mem) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 // Can NOT include the match of a subtree when its memory state
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 // is used by any of the other subtrees
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 (input_mem == NodeSentinel) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 // Print when we exclude matching due to different memory states at input-loads
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 if( PrintOpto && (Verbose && WizardMode) && (input_mem == NodeSentinel)
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 && !((mem!=(Node*)1) && m->is_Load() && m->in(MemNode::Memory) != mem) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 tty->print_cr("invalid input_mem");
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 // Switch to a register-only opcode; this value must be in a register
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 // and cannot be subsumed as part of a larger instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 s->DFA( m->ideal_reg(), m );
a61af66fc99e Initial load
duke
parents:
diff changeset
1351
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 // If match tree has no control and we do, adopt it for entire tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 if( control == NULL && m->in(0) != NULL && m->req() > 1 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 control = m->in(0); // Pick up control
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 // Else match as a normal part of the match tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 control = Label_Root(m,s,control,mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 if (C->failing()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1361
a61af66fc99e Initial load
duke
parents:
diff changeset
1362
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 // Call DFA to match this node, and return
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 svec->DFA( n->Opcode(), n );
a61af66fc99e Initial load
duke
parents:
diff changeset
1365
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 uint x;
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 for( x = 0; x < _LAST_MACH_OPER; x++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 if( svec->valid(x) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1371
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 if (x >= _LAST_MACH_OPER) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 svec->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 assert( false, "bad AD file" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 return control;
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1380
a61af66fc99e Initial load
duke
parents:
diff changeset
1381
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 // Con nodes reduced using the same rule can share their MachNode
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 // which reduces the number of copies of a constant in the final
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 // program. The register allocator is free to split uses later to
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // split live ranges.
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1386 MachNode* Matcher::find_shared_node(Node* leaf, uint rule) {
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1387 if (!leaf->is_Con() && !leaf->is_DecodeN()) return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1388
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 // See if this Con has already been reduced using this rule.
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1390 if (_shared_nodes.Size() <= leaf->_idx) return NULL;
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1391 MachNode* last = (MachNode*)_shared_nodes.at(leaf->_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 if (last != NULL && rule == last->rule()) {
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1393 // Don't expect control change for DecodeN
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1394 if (leaf->is_DecodeN())
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1395 return last;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 // Get the new space root.
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 Node* xroot = new_node(C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 if (xroot == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 // This shouldn't happen give the order of matching.
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1402
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 // Shared constants need to have their control be root so they
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 // can be scheduled properly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 Node* control = last->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 if (control != xroot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 if (control == NULL || control == C->root()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 last->set_req(0, xroot);
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 assert(false, "unexpected control");
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 return last;
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1418
a61af66fc99e Initial load
duke
parents:
diff changeset
1419
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 //------------------------------ReduceInst-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // Reduce a State tree (with given Control) into a tree of MachNodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 // This routine (and it's cohort ReduceOper) convert Ideal Nodes into
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 // complicated machine Nodes. Each MachNode covers some tree of Ideal Nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 // Each MachNode has a number of complicated MachOper operands; each
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 // MachOper also covers a further tree of Ideal Nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1426
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 // The root of the Ideal match tree is always an instruction, so we enter
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 // the recursion here. After building the MachNode, we need to recurse
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 // the tree checking for these cases:
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 // (1) Child is an instruction -
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 // Build the instruction (recursively), add it as an edge.
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 // Build a simple operand (register) to hold the result of the instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 // (2) Child is an interior part of an instruction -
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 // Skip over it (do nothing)
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 // (3) Child is the start of a operand -
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 // Build the operand, place it inside the instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 // Call ReduceOper.
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 assert( rule >= NUM_OPERANDS, "called with operand rule" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1440
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1441 MachNode* shared_node = find_shared_node(s->_leaf, rule);
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1442 if (shared_node != NULL) {
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1443 return shared_node;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1445
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // Build the object to represent this state & prepare for recursive calls
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 MachNode *mach = s->MachNodeGenerator( rule, C );
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 mach->_opnds[0] = s->MachOperGenerator( _reduceOp[rule], C );
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 assert( mach->_opnds[0] != NULL, "Missing result operand" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 Node *leaf = s->_leaf;
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // Check for instruction or instruction chain rule
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 if( rule >= _END_INST_CHAIN_RULE || rule < _BEGIN_INST_CHAIN_RULE ) {
309
eaf496ad4a14 6732698: crash with dead code from compressed oops in gcm
never
parents: 235
diff changeset
1453 assert(C->node_arena()->contains(s->_leaf) || !has_new_node(s->_leaf),
eaf496ad4a14 6732698: crash with dead code from compressed oops in gcm
never
parents: 235
diff changeset
1454 "duplicating node that's already been matched");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 // Instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 mach->add_req( leaf->in(0) ); // Set initial control
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 // Reduce interior of complex instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 ReduceInst_Interior( s, rule, mem, mach, 1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 // Instruction chain rules are data-dependent on their inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 mach->add_req(0); // Set initial control to none
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 ReduceInst_Chain_Rule( s, rule, mem, mach );
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1464
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 // If a Memory was used, insert a Memory edge
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1466 if( mem != (Node*)1 ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 mach->ins_req(MemNode::Memory,mem);
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1468 #ifdef ASSERT
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1469 // Verify adr type after matching memory operation
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1470 const MachOper* oper = mach->memory_operand();
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1471 if (oper != NULL && oper != (MachOper*)-1 &&
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1472 mach->adr_type() != TypeRawPtr::BOTTOM) { // non-direct addressing mode
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1473 // It has a unique memory operand. Find corresponding ideal mem node.
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1474 Node* m = NULL;
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1475 if (leaf->is_Mem()) {
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1476 m = leaf;
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1477 } else {
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1478 m = _mem_node;
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1479 assert(m != NULL && m->is_Mem(), "expecting memory node");
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1480 }
368
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
1481 const Type* mach_at = mach->adr_type();
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
1482 // DecodeN node consumed by an address may have different type
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
1483 // then its input. Don't compare types for such case.
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
1484 if (m->adr_type() != mach_at && m->in(MemNode::Address)->is_AddP() &&
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
1485 m->in(MemNode::Address)->in(AddPNode::Address)->is_DecodeN()) {
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
1486 mach_at = m->adr_type();
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
1487 }
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
1488 if (m->adr_type() != mach_at) {
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1489 m->dump();
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1490 tty->print_cr("mach:");
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1491 mach->dump(1);
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1492 }
368
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
1493 assert(m->adr_type() == mach_at, "matcher should not change adr type");
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1494 }
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1495 #endif
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1496 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1497
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 // If the _leaf is an AddP, insert the base edge
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1499 if( leaf->is_AddP() )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 mach->ins_req(AddPNode::Base,leaf->in(AddPNode::Base));
a61af66fc99e Initial load
duke
parents:
diff changeset
1501
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 uint num_proj = _proj_list.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1503
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 // Perform any 1-to-many expansions required
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 MachNode *ex = mach->Expand(s,_proj_list);
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 if( ex != mach ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 assert(ex->ideal_reg() == mach->ideal_reg(), "ideal types should match");
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 if( ex->in(1)->is_Con() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 ex->in(1)->set_req(0, C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 // Remove old node from the graph
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 for( uint i=0; i<mach->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 mach->set_req(i,NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 }
222
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
1514 #ifdef ASSERT
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
1515 _new2old_map.map(ex->_idx, s->_leaf);
2a1a77d3458f 6718676: putback for 6604014 is incomplete
never
parents: 221
diff changeset
1516 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1518
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 // PhaseChaitin::fixup_spills will sometimes generate spill code
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 // via the matcher. By the time, nodes have been wired into the CFG,
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 // and any further nodes generated by expand rules will be left hanging
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 // in space, and will not get emitted as output code. Catch this.
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 // Also, catch any new register allocation constraints ("projections")
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 // generated belatedly during spill code generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 if (_allocation_started) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 guarantee(ex == mach, "no expand rules during spill generation");
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 guarantee(_proj_list.size() == num_proj, "no allocation during spill generation");
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1529
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1530 if (leaf->is_Con() || leaf->is_DecodeN()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 // Record the con for sharing
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1532 _shared_nodes.map(leaf->_idx, ex);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1534
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 return ex;
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1537
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 void Matcher::ReduceInst_Chain_Rule( State *s, int rule, Node *&mem, MachNode *mach ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 // 'op' is what I am expecting to receive
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 int op = _leftOp[rule];
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 // Operand type to catch childs result
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 // This is what my child will give me.
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 int opnd_class_instance = s->_rule[op];
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 // Choose between operand class or not.
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 // This is what I will recieve.
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 int catch_op = (FIRST_OPERAND_CLASS <= op && op < NUM_OPERANDS) ? opnd_class_instance : op;
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 // New rule for child. Chase operand classes to get the actual rule.
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 int newrule = s->_rule[catch_op];
a61af66fc99e Initial load
duke
parents:
diff changeset
1549
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 if( newrule < NUM_OPERANDS ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 // Chain from operand or operand class, may be output of shared node
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 assert( 0 <= opnd_class_instance && opnd_class_instance < NUM_OPERANDS,
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 "Bad AD file: Instruction chain rule must chain from operand");
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 // Insert operand into array of operands for this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 mach->_opnds[1] = s->MachOperGenerator( opnd_class_instance, C );
a61af66fc99e Initial load
duke
parents:
diff changeset
1556
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 ReduceOper( s, newrule, mem, mach );
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 // Chain from the result of an instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 assert( newrule >= _LAST_MACH_OPER, "Do NOT chain from internal operand");
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 mach->_opnds[1] = s->MachOperGenerator( _reduceOp[catch_op], C );
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 Node *mem1 = (Node*)1;
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1563 debug_only(Node *save_mem_node = _mem_node;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 mach->add_req( ReduceInst(s, newrule, mem1) );
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1565 debug_only(_mem_node = save_mem_node;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1569
a61af66fc99e Initial load
duke
parents:
diff changeset
1570
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 uint Matcher::ReduceInst_Interior( State *s, int rule, Node *&mem, MachNode *mach, uint num_opnds ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 if( s->_leaf->is_Load() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 Node *mem2 = s->_leaf->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 assert( mem == (Node*)1 || mem == mem2, "multiple Memories being matched at once?" );
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1575 debug_only( if( mem == (Node*)1 ) _mem_node = s->_leaf;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 mem = mem2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 if( s->_leaf->in(0) != NULL && s->_leaf->req() > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 if( mach->in(0) == NULL )
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 mach->set_req(0, s->_leaf->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1582
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 // Now recursively walk the state tree & add operand list.
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 for( uint i=0; i<2; i++ ) { // binary tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 State *newstate = s->_kids[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 if( newstate == NULL ) break; // Might only have 1 child
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 // 'op' is what I am expecting to receive
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 int op;
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 if( i == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 op = _leftOp[rule];
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 op = _rightOp[rule];
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 // Operand type to catch childs result
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 // This is what my child will give me.
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 int opnd_class_instance = newstate->_rule[op];
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 // Choose between operand class or not.
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 // This is what I will receive.
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 int catch_op = (op >= FIRST_OPERAND_CLASS && op < NUM_OPERANDS) ? opnd_class_instance : op;
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 // New rule for child. Chase operand classes to get the actual rule.
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 int newrule = newstate->_rule[catch_op];
a61af66fc99e Initial load
duke
parents:
diff changeset
1602
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 if( newrule < NUM_OPERANDS ) { // Operand/operandClass or internalOp/instruction?
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 // Operand/operandClass
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 // Insert operand into array of operands for this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 mach->_opnds[num_opnds++] = newstate->MachOperGenerator( opnd_class_instance, C );
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 ReduceOper( newstate, newrule, mem, mach );
a61af66fc99e Initial load
duke
parents:
diff changeset
1608
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 } else { // Child is internal operand or new instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 if( newrule < _LAST_MACH_OPER ) { // internal operand or instruction?
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 // internal operand --> call ReduceInst_Interior
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 // Interior of complex instruction. Do nothing but recurse.
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 num_opnds = ReduceInst_Interior( newstate, newrule, mem, mach, num_opnds );
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 // instruction --> call build operand( ) to catch result
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 // --> ReduceInst( newrule )
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 mach->_opnds[num_opnds++] = s->MachOperGenerator( _reduceOp[catch_op], C );
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 Node *mem1 = (Node*)1;
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1619 debug_only(Node *save_mem_node = _mem_node;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 mach->add_req( ReduceInst( newstate, newrule, mem1 ) );
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1621 debug_only(_mem_node = save_mem_node;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 assert( mach->_opnds[num_opnds-1], "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 return num_opnds;
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1628
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 // This routine walks the interior of possible complex operands.
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 // At each point we check our children in the match tree:
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 // (1) No children -
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 // We are a leaf; add _leaf field as an input to the MachNode
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // (2) Child is an internal operand -
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 // Skip over it ( do nothing )
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // (3) Child is an instruction -
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 // Call ReduceInst recursively and
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 // and instruction as an input to the MachNode
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 void Matcher::ReduceOper( State *s, int rule, Node *&mem, MachNode *mach ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 assert( rule < _LAST_MACH_OPER, "called with operand rule" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 State *kid = s->_kids[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 assert( kid == NULL || s->_leaf->in(0) == NULL, "internal operands have no control" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1642
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 // Leaf? And not subsumed?
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 if( kid == NULL && !_swallowed[rule] ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 mach->add_req( s->_leaf ); // Add leaf pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 return; // Bail out
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1648
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 if( s->_leaf->is_Load() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 assert( mem == (Node*)1, "multiple Memories being matched at once?" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 mem = s->_leaf->in(MemNode::Memory);
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1652 debug_only(_mem_node = s->_leaf;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 if( s->_leaf->in(0) && s->_leaf->req() > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 if( !mach->in(0) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 mach->set_req(0,s->_leaf->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 assert( s->_leaf->in(0) == mach->in(0), "same instruction, differing controls?" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1661
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 for( uint i=0; kid != NULL && i<2; kid = s->_kids[1], i++ ) { // binary tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 int newrule;
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 if( i == 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 newrule = kid->_rule[_leftOp[rule]];
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 newrule = kid->_rule[_rightOp[rule]];
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 if( newrule < _LAST_MACH_OPER ) { // Operand or instruction?
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 // Internal operand; recurse but do nothing else
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 ReduceOper( kid, newrule, mem, mach );
a61af66fc99e Initial load
duke
parents:
diff changeset
1672
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 } else { // Child is a new instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 // Reduce the instruction, and add a direct pointer from this
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 // machine instruction to the newly reduced one.
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 Node *mem1 = (Node*)1;
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1677 debug_only(Node *save_mem_node = _mem_node;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 mach->add_req( ReduceInst( kid, newrule, mem1 ) );
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 169
diff changeset
1679 debug_only(_mem_node = save_mem_node;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1683
a61af66fc99e Initial load
duke
parents:
diff changeset
1684
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 // -------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 // Java-Java calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 // (what you use when Java calls Java)
a61af66fc99e Initial load
duke
parents:
diff changeset
1688
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 //------------------------------find_receiver----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 // For a given signature, return the OptoReg for parameter 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 OptoReg::Name Matcher::find_receiver( bool is_outgoing ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 VMRegPair regs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 BasicType sig_bt = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 calling_convention(&sig_bt, &regs, 1, is_outgoing);
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 // Return argument 0 register. In the LP64 build pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 // take 2 registers, but the VM wants only the 'main' name.
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 return OptoReg::as_OptoReg(regs.first());
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1699
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 // A method-klass-holder may be passed in the inline_cache_reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 // and then expanded into the inline_cache_reg and a method_oop register
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 // defined in ad_<arch>.cpp
a61af66fc99e Initial load
duke
parents:
diff changeset
1703
a61af66fc99e Initial load
duke
parents:
diff changeset
1704
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 //------------------------------find_shared------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 // Set bits if Node is shared or otherwise a root
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 void Matcher::find_shared( Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 // Allocate stack of size C->unique() * 2 to avoid frequent realloc
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 MStack mstack(C->unique() * 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 mstack.push(n, Visit); // Don't need to pre-visit root node
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 while (mstack.is_nonempty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 n = mstack.node(); // Leave node on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 Node_State nstate = mstack.state();
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 if (nstate == Pre_Visit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 if (is_visited(n)) { // Visited already?
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 // Node is shared and has no reason to clone. Flag it as shared.
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 // This causes it to match into a register for the sharing.
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 set_shared(n); // Flag as shared and
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 mstack.pop(); // remove node from stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 nstate = Visit; // Not already visited; so visit now
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 if (nstate == Visit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 mstack.set_state(Post_Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 set_visited(n); // Flag as visited now
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 bool mem_op = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1728
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 switch( n->Opcode() ) { // Handle some opcodes special
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 case Op_Phi: // Treat Phis as shared roots
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 case Op_Parm:
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 case Op_Proj: // All handled specially during matching
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 0
diff changeset
1733 case Op_SafePointScalarObject:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 set_shared(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 set_dontcare(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 case Op_If:
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 case Op_CountedLoopEnd:
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 mstack.set_state(Alt_Post_Visit); // Alternative way
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 // Convert (If (Bool (CmpX A B))) into (If (Bool) (CmpX A B)). Helps
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 // with matching cmp/branch in 1 instruction. The Matcher needs the
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 // Bool and CmpX side-by-side, because it can only get at constants
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 // that are at the leaves of Match trees, and the Bool's condition acts
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 // as a constant here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 mstack.push(n->in(1), Visit); // Clone the Bool
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 mstack.push(n->in(0), Pre_Visit); // Visit control input
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 continue; // while (mstack.is_nonempty())
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 case Op_ConvI2D: // These forms efficiently match with a prior
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 case Op_ConvI2F: // Load but not a following Store
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 if( n->in(1)->is_Load() && // Prior load
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 n->outcnt() == 1 && // Not already shared
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 n->unique_out()->is_Store() ) // Following store
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 set_shared(n); // Force it to be a root
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 case Op_ReverseBytesI:
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 case Op_ReverseBytesL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 if( n->in(1)->is_Load() && // Prior load
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 n->outcnt() == 1 ) // Not already shared
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 set_shared(n); // Force it to be a root
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 case Op_BoxLock: // Cant match until we get stack-regs in ADLC
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 case Op_IfFalse:
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 case Op_IfTrue:
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 case Op_MachProj:
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 case Op_MergeMem:
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 case Op_Catch:
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 case Op_CatchProj:
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 case Op_CProj:
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 case Op_JumpProj:
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 case Op_JProj:
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 case Op_NeverBranch:
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 set_dontcare(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 case Op_Jump:
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 mstack.push(n->in(1), Visit); // Switch Value
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 mstack.push(n->in(0), Pre_Visit); // Visit Control input
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 continue; // while (mstack.is_nonempty())
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 case Op_StrComp:
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 168
diff changeset
1779 case Op_AryEq:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 set_shared(n); // Force result into register (it will be anyways)
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 case Op_ConP: { // Convert pointers above the centerline to NUL
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 TypeNode *tn = n->as_Type(); // Constants derive from type nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 const TypePtr* tp = tn->type()->is_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 if (tp->_ptr == TypePtr::AnyNull) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 tn->set_type(TypePtr::NULL_PTR);
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 }
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
1790 case Op_ConN: { // Convert narrow pointers above the centerline to NUL
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
1791 TypeNode *tn = n->as_Type(); // Constants derive from type nodes
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 216
diff changeset
1792 const TypePtr* tp = tn->type()->make_ptr();
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 216
diff changeset
1793 if (tp && tp->_ptr == TypePtr::AnyNull) {
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
1794 tn->set_type(TypeNarrowOop::NULL_PTR);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
1795 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
1796 break;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
1797 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 case Op_Binary: // These are introduced in the Post_Visit state.
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 case Op_StoreB: // Do match these, despite no ideal reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 case Op_StoreC:
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 case Op_StoreCM:
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 case Op_StoreD:
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 case Op_StoreF:
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 case Op_StoreI:
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 case Op_StoreL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 case Op_StoreP:
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
1809 case Op_StoreN:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 case Op_Store16B:
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 case Op_Store8B:
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 case Op_Store4B:
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 case Op_Store8C:
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 case Op_Store4C:
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 case Op_Store2C:
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 case Op_Store4I:
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 case Op_Store2I:
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 case Op_Store2L:
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 case Op_Store4F:
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 case Op_Store2F:
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 case Op_Store2D:
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 case Op_ClearArray:
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 case Op_SafePoint:
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 mem_op = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 case Op_LoadB:
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 case Op_LoadC:
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 case Op_LoadD:
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 case Op_LoadF:
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 case Op_LoadI:
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 case Op_LoadKlass:
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1832 case Op_LoadNKlass:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 case Op_LoadL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 case Op_LoadS:
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 case Op_LoadP:
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
1836 case Op_LoadN:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 case Op_LoadRange:
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 case Op_LoadD_unaligned:
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 case Op_LoadL_unaligned:
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 case Op_Load16B:
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 case Op_Load8B:
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 case Op_Load4B:
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 case Op_Load4C:
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 case Op_Load2C:
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 case Op_Load8C:
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 case Op_Load8S:
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 case Op_Load4S:
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 case Op_Load2S:
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 case Op_Load4I:
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 case Op_Load2I:
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 case Op_Load2L:
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 case Op_Load4F:
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 case Op_Load2F:
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 case Op_Load2D:
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 mem_op = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 // Must be root of match tree due to prior load conflict
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 if( C->subsume_loads() == false ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 set_shared(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // Fall into default case
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 if( !n->ideal_reg() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 set_dontcare(n); // Unmatchable Nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 } // end_switch
a61af66fc99e Initial load
duke
parents:
diff changeset
1865
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 for(int i = n->req() - 1; i >= 0; --i) { // For my children
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 Node *m = n->in(i); // Get ith input
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 if (m == NULL) continue; // Ignore NULLs
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 uint mop = m->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1870
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 // Must clone all producers of flags, or we will not match correctly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 // Suppose a compare setting int-flags is shared (e.g., a switch-tree)
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 // then it will match into an ideal Op_RegFlags. Alas, the fp-flags
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 // are also there, so we may match a float-branch to int-flags and
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 // expect the allocator to haul the flags from the int-side to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 // fp-side. No can do.
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 if( _must_clone[mop] ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 mstack.push(m, Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 continue; // for(int i = ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1881
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 // Clone addressing expressions as they are "free" in most instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 if( mem_op && i == MemNode::Address && mop == Op_AddP ) {
309
eaf496ad4a14 6732698: crash with dead code from compressed oops in gcm
never
parents: 235
diff changeset
1884 if (m->in(AddPNode::Base)->Opcode() == Op_DecodeN) {
eaf496ad4a14 6732698: crash with dead code from compressed oops in gcm
never
parents: 235
diff changeset
1885 // Bases used in addresses must be shared but since
eaf496ad4a14 6732698: crash with dead code from compressed oops in gcm
never
parents: 235
diff changeset
1886 // they are shared through a DecodeN they may appear
eaf496ad4a14 6732698: crash with dead code from compressed oops in gcm
never
parents: 235
diff changeset
1887 // to have a single use so force sharing here.
eaf496ad4a14 6732698: crash with dead code from compressed oops in gcm
never
parents: 235
diff changeset
1888 set_shared(m->in(AddPNode::Base)->in(1));
eaf496ad4a14 6732698: crash with dead code from compressed oops in gcm
never
parents: 235
diff changeset
1889 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 Node *off = m->in(AddPNode::Offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 if( off->is_Con() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 set_visited(m); // Flag as visited now
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 Node *adr = m->in(AddPNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1894
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 // Intel, ARM and friends can handle 2 adds in addressing mode
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1896 if( clone_shift_expressions && adr->is_AddP() &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 // AtomicAdd is not an addressing expression.
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 // Cheap to find it by looking for screwy base.
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 !adr->in(AddPNode::Base)->is_top() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 set_visited(adr); // Flag as visited now
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 Node *shift = adr->in(AddPNode::Offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 // Check for shift by small constant as well
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 if( shift->Opcode() == Op_LShiftX && shift->in(2)->is_Con() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 shift->in(2)->get_int() <= 3 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 set_visited(shift); // Flag as visited now
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 mstack.push(shift->in(2), Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 // Allow Matcher to match the rule which bypass
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 // ConvI2L operation for an array index on LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 // if the index value is positive.
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 if( shift->in(1)->Opcode() == Op_ConvI2L &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 shift->in(1)->as_Type()->type()->is_long()->_lo >= 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 set_visited(shift->in(1)); // Flag as visited now
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 mstack.push(shift->in(1)->in(1), Pre_Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 mstack.push(shift->in(1), Pre_Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 mstack.push(shift, Pre_Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 mstack.push(adr->in(AddPNode::Address), Pre_Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 mstack.push(adr->in(AddPNode::Base), Pre_Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 } else { // Sparc, Alpha, PPC and friends
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 mstack.push(adr, Pre_Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1926
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 // Clone X+offset as it also folds into most addressing expressions
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 mstack.push(off, Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 mstack.push(m->in(AddPNode::Base), Pre_Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 continue; // for(int i = ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 } // if( off->is_Con() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 } // if( mem_op &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 mstack.push(m, Pre_Visit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 } // for(int i = ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 else if (nstate == Alt_Post_Visit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 mstack.pop(); // Remove node from stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 // We cannot remove the Cmp input from the Bool here, as the Bool may be
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 // shared and all users of the Bool need to move the Cmp in parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 // This leaves both the Bool and the If pointing at the Cmp. To
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 // prevent the Matcher from trying to Match the Cmp along both paths
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 // BoolNode::match_edge always returns a zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
1943
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 // We reorder the Op_If in a pre-order manner, so we can visit without
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 // accidently sharing the Cmp (the Bool and the If make 2 users).
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 n->add_req( n->in(1)->in(1) ); // Add the Cmp next to the Bool
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 else if (nstate == Post_Visit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 mstack.pop(); // Remove node from stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1950
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 // Now hack a few special opcodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 switch( n->Opcode() ) { // Handle some opcodes special
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 case Op_StorePConditional:
420
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 368
diff changeset
1954 case Op_StoreIConditional:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 case Op_StoreLConditional:
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 case Op_CompareAndSwapI:
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 case Op_CompareAndSwapL:
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
1958 case Op_CompareAndSwapP:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
1959 case Op_CompareAndSwapN: { // Convert trinary to binary-tree
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 Node *newval = n->in(MemNode::ValueIn );
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 Node *oldval = n->in(LoadStoreNode::ExpectedIn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 Node *pair = new (C, 3) BinaryNode( oldval, newval );
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 n->set_req(MemNode::ValueIn,pair);
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 n->del_req(LoadStoreNode::ExpectedIn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 case Op_CMoveD: // Convert trinary to binary-tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 case Op_CMoveF:
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 case Op_CMoveI:
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 case Op_CMoveL:
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1971 case Op_CMoveN:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 case Op_CMoveP: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 // Restructure into a binary tree for Matching. It's possible that
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 // we could move this code up next to the graph reshaping for IfNodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 // or vice-versa, but I do not want to debug this for Ladybird.
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 // 10/2/2000 CNC.
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 Node *pair1 = new (C, 3) BinaryNode(n->in(1),n->in(1)->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 n->set_req(1,pair1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 Node *pair2 = new (C, 3) BinaryNode(n->in(2),n->in(3));
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 n->set_req(2,pair2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 n->del_req(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 } // end of while (mstack.is_nonempty())
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1993
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 // machine-independent root to machine-dependent root
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 void Matcher::dump_old2new_map() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 _old2new_map.dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2000
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 //---------------------------collect_null_checks-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 // Find null checks in the ideal graph; write a machine-specific node for
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 // it. Used by later implicit-null-check handling. Actually collects
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 // either an IfTrue or IfFalse for the common NOT-null path, AND the ideal
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 // value being tested.
368
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2006 void Matcher::collect_null_checks( Node *proj, Node *orig_proj ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 Node *iff = proj->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 if( iff->Opcode() == Op_If ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 // During matching If's have Bool & Cmp side-by-side
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 BoolNode *b = iff->in(1)->as_Bool();
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 Node *cmp = iff->in(2);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2012 int opc = cmp->Opcode();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2013 if (opc != Op_CmpP && opc != Op_CmpN) return;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2014
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2015 const Type* ct = cmp->in(2)->bottom_type();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2016 if (ct == TypePtr::NULL_PTR ||
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2017 (opc == Op_CmpN && ct == TypeNarrowOop::NULL_PTR)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2018
368
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2019 bool push_it = false;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2020 if( proj->Opcode() == Op_IfTrue ) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2021 extern int all_null_checks_found;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2022 all_null_checks_found++;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2023 if( b->_test._test == BoolTest::ne ) {
368
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2024 push_it = true;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2025 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2026 } else {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2027 assert( proj->Opcode() == Op_IfFalse, "" );
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2028 if( b->_test._test == BoolTest::eq ) {
368
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2029 push_it = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 }
368
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2032 if( push_it ) {
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2033 _null_check_tests.push(proj);
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2034 Node* val = cmp->in(1);
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2035 #ifdef _LP64
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2036 if (UseCompressedOops && !Matcher::clone_shift_expressions &&
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2037 val->bottom_type()->isa_narrowoop()) {
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2038 //
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2039 // Look for DecodeN node which should be pinned to orig_proj.
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2040 // On platforms (Sparc) which can not handle 2 adds
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2041 // in addressing mode we have to keep a DecodeN node and
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2042 // use it to do implicit NULL check in address.
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2043 //
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2044 // DecodeN node was pinned to non-null path (orig_proj) during
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2045 // CastPP transformation in final_graph_reshaping_impl().
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2046 //
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2047 uint cnt = orig_proj->outcnt();
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2048 for (uint i = 0; i < orig_proj->outcnt(); i++) {
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2049 Node* d = orig_proj->raw_out(i);
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2050 if (d->is_DecodeN() && d->in(1) == val) {
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2051 val = d;
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2052 val->set_req(0, NULL); // Unpin now.
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2053 break;
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2054 }
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2055 }
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2056 }
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2057 #endif
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2058 _null_check_tests.push(val);
36ccc817fca4 6747051: Improve code and implicit null check generation for compressed oops
kvn
parents: 367
diff changeset
2059 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2063
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 //---------------------------validate_null_checks------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 // Its possible that the value being NULL checked is not the root of a match
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 // tree. If so, I cannot use the value in an implicit null check.
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 void Matcher::validate_null_checks( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 uint cnt = _null_check_tests.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 for( uint i=0; i < cnt; i+=2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 Node *test = _null_check_tests[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 Node *val = _null_check_tests[i+1];
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 if (has_new_node(val)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 // Is a match-tree root, so replace with the matched value
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 _null_check_tests.map(i+1, new_node(val));
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 // Yank from candidate list
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 _null_check_tests.map(i+1,_null_check_tests[--cnt]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 _null_check_tests.map(i,_null_check_tests[--cnt]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 _null_check_tests.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 _null_check_tests.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 i-=2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2085
a61af66fc99e Initial load
duke
parents:
diff changeset
2086
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 // Used by the DFA in dfa_sparc.cpp. Check for a prior FastLock
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 // acting as an Acquire and thus we don't need an Acquire here. We
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 // retain the Node to act as a compiler ordering barrier.
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 bool Matcher::prior_fast_lock( const Node *acq ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 Node *r = acq->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 if( !r->is_Region() || r->req() <= 1 ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 Node *proj = r->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 if( !proj->is_Proj() ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 Node *call = proj->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 if( !call->is_Call() || call->as_Call()->entry_point() != OptoRuntime::complete_monitor_locking_Java() )
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2098
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2101
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 // Used by the DFA in dfa_sparc.cpp. Check for a following FastUnLock
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 // acting as a Release and thus we don't need a Release here. We
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 // retain the Node to act as a compiler ordering barrier.
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 bool Matcher::post_fast_unlock( const Node *rel ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 Compile *C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 assert( rel->Opcode() == Op_MemBarRelease, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 const MemBarReleaseNode *mem = (const MemBarReleaseNode*)rel;
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 DUIterator_Fast imax, i = mem->fast_outs(imax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 Node *ctrl = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 while( true ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 ctrl = mem->fast_out(i); // Throw out-of-bounds if proj not found
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 assert( ctrl->is_Proj(), "only projections here" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 ProjNode *proj = (ProjNode*)ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 if( proj->_con == TypeFunc::Control &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 !C->node_arena()->contains(ctrl) ) // Unmatched old-space only
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 Node *iff = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 for( DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 Node *x = ctrl->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 if( x->is_If() && x->req() > 1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 !C->node_arena()->contains(x) ) { // Unmatched old-space only
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 iff = x;
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 if( !iff ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 Node *bol = iff->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 // The iff might be some random subclass of If or bol might be Con-Top
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 if (!bol->is_Bool()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 assert( bol->req() > 1, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 return (bol->in(1)->Opcode() == Op_FastUnlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2136
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 // Used by the DFA in dfa_xxx.cpp. Check for a following barrier or
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 // atomic instruction acting as a store_load barrier without any
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 // intervening volatile load, and thus we don't need a barrier here.
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 // We retain the Node to act as a compiler ordering barrier.
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 bool Matcher::post_store_load_barrier(const Node *vmb) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 Compile *C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 assert( vmb->is_MemBar(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 assert( vmb->Opcode() != Op_MemBarAcquire, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 const MemBarNode *mem = (const MemBarNode*)vmb;
a61af66fc99e Initial load
duke
parents:
diff changeset
2146
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 // Get the Proj node, ctrl, that can be used to iterate forward
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 Node *ctrl = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 DUIterator_Fast imax, i = mem->fast_outs(imax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 while( true ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 ctrl = mem->fast_out(i); // Throw out-of-bounds if proj not found
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 assert( ctrl->is_Proj(), "only projections here" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 ProjNode *proj = (ProjNode*)ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 if( proj->_con == TypeFunc::Control &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 !C->node_arena()->contains(ctrl) ) // Unmatched old-space only
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2159
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 for( DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 Node *x = ctrl->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 int xop = x->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
2163
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 // We don't need current barrier if we see another or a lock
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 // before seeing volatile load.
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // Op_Fastunlock previously appeared in the Op_* list below.
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 // With the advent of 1-0 lock operations we're no longer guaranteed
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 // that a monitor exit operation contains a serializing instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
2170
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 if (xop == Op_MemBarVolatile ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 xop == Op_FastLock ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 xop == Op_CompareAndSwapL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 xop == Op_CompareAndSwapP ||
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 63
diff changeset
2175 xop == Op_CompareAndSwapN ||
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 xop == Op_CompareAndSwapI)
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2178
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 if (x->is_MemBar()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 // We must retain this membar if there is an upcoming volatile
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 // load, which will be preceded by acquire membar.
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 if (xop == Op_MemBarAcquire)
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 // For other kinds of barriers, check by pretending we
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 // are them, and seeing if we can be removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 else
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 return post_store_load_barrier((const MemBarNode*)x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2189
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 // Delicate code to detect case of an upcoming fastlock block
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 if( x->is_If() && x->req() > 1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 !C->node_arena()->contains(x) ) { // Unmatched old-space only
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 Node *iff = x;
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 Node *bol = iff->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 // The iff might be some random subclass of If or bol might be Con-Top
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 if (!bol->is_Bool()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 assert( bol->req() > 1, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 return (bol->in(1)->Opcode() == Op_FastUnlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 // probably not necessary to check for these
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 if (x->is_Call() || x->is_SafePoint() || x->is_block_proj())
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2206
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 //---------------------------State---------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 State::State(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 _id = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 _kids[0] = _kids[1] = (State*)(intptr_t) CONST64(0xcafebabecafebabe);
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 _leaf = (Node*)(intptr_t) CONST64(0xbaadf00dbaadf00d);
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 //memset(_cost, -1, sizeof(_cost));
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 //memset(_rule, -1, sizeof(_rule));
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 memset(_valid, 0, sizeof(_valid));
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2219
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 State::~State() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 _id = 99;
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 _kids[0] = _kids[1] = (State*)(intptr_t) CONST64(0xcafebabecafebabe);
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 _leaf = (Node*)(intptr_t) CONST64(0xbaadf00dbaadf00d);
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 memset(_cost, -3, sizeof(_cost));
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 memset(_rule, -3, sizeof(_rule));
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2229
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 //---------------------------dump----------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 void State::dump() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 dump(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2236
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 void State::dump(int depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 for( int j = 0; j < depth; j++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 tty->print("--N: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 _leaf->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 for( i = 0; i < _LAST_MACH_OPER; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 // Check for valid entry
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 if( valid(i) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 for( int j = 0; j < depth; j++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 assert(_cost[i] != max_juint, "cost must be a valid value");
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 assert(_rule[i] < _last_Mach_Node, "rule[i] must be valid rule");
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 tty->print_cr("%s %d %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 ruleName[i], _cost[i], ruleName[_rule[i]] );
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
2254
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 for( i=0; i<2; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 if( _kids[i] )
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 _kids[i]->dump(depth+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 #endif