annotate src/share/vm/opto/matcher.cpp @ 1721:413ad0331a0c

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