annotate src/share/vm/opto/matcher.cpp @ 4710:41406797186b

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