annotate src/share/vm/opto/matcher.cpp @ 1145:e018e6884bd8

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