annotate src/share/vm/opto/idealKit.cpp @ 1994:6cd6d394f280

7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed()) 7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages. Reviewed-by: johnc, tonyp
author ysr
date Tue, 07 Dec 2010 21:55:53 -0800
parents f95d63e2154a
children 9dc311b8473e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1000
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1000
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: 1000
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: 1552
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #include "opto/addnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27 #include "opto/callnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "opto/cfgnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "opto/idealKit.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "opto/runtime.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
31
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // Static initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // This declares the position where vars are kept in the cvstate
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // For some degree of consistency we use the TypeFunc enum to
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // soak up spots in the inputs even though we only use early Control
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // and Memory slots. (So far.)
a61af66fc99e Initial load
duke
parents:
diff changeset
38 const uint IdealKit::first_var = TypeFunc::Parms + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40 //----------------------------IdealKit-----------------------------------------
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
41 IdealKit::IdealKit(PhaseGVN &gvn, Node* control, Node* mem, bool delay_all_transforms, bool has_declarations) :
0
a61af66fc99e Initial load
duke
parents:
diff changeset
42 _gvn(gvn), C(gvn.C) {
a61af66fc99e Initial load
duke
parents:
diff changeset
43 _initial_ctrl = control;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 _initial_memory = mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 _delay_all_transforms = delay_all_transforms;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 _var_ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
47 _cvstate = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // We can go memory state free or else we need the entire memory state
a61af66fc99e Initial load
duke
parents:
diff changeset
49 assert(mem == NULL || mem->Opcode() == Op_MergeMem, "memory must be pre-split");
a61af66fc99e Initial load
duke
parents:
diff changeset
50 int init_size = 5;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 _pending_cvstates = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
52 _delay_transform = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
53 DEBUG_ONLY(_state = new (C->node_arena()) GrowableArray<int>(C->node_arena(), init_size, 0, 0));
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
54 if (!has_declarations) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
55 declarations_done();
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
56 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
57 }
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 //-------------------------------if_then-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // Create: if(left relop right)
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // / \
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // iffalse iftrue
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // Push the iffalse cvstate onto the stack. The iftrue becomes the current cvstate.
a61af66fc99e Initial load
duke
parents:
diff changeset
64 void IdealKit::if_then(Node* left, BoolTest::mask relop,
a61af66fc99e Initial load
duke
parents:
diff changeset
65 Node* right, float prob, float cnt, bool push_new_state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
66 assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new If");
a61af66fc99e Initial load
duke
parents:
diff changeset
67 Node* bol;
a61af66fc99e Initial load
duke
parents:
diff changeset
68 if (left->bottom_type()->isa_ptr() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 if (left->bottom_type()->isa_int() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
70 bol = Bool(CmpI(left, right), relop);
a61af66fc99e Initial load
duke
parents:
diff changeset
71 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
72 assert(left->bottom_type()->isa_long() != NULL, "what else?");
a61af66fc99e Initial load
duke
parents:
diff changeset
73 bol = Bool(CmpL(left, right), relop);
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
77 bol = Bool(CmpP(left, right), relop);
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // Delay gvn.tranform on if-nodes until construction is finished
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // to prevent a constant bool input from discarding a control output.
a61af66fc99e Initial load
duke
parents:
diff changeset
81 IfNode* iff = delay_transform(new (C, 2) IfNode(ctrl(), bol, prob, cnt))->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
82 Node* then = IfTrue(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
83 Node* elsen = IfFalse(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
84 Node* else_cvstate = copy_cvstate();
a61af66fc99e Initial load
duke
parents:
diff changeset
85 else_cvstate->set_req(TypeFunc::Control, elsen);
a61af66fc99e Initial load
duke
parents:
diff changeset
86 _pending_cvstates->push(else_cvstate);
a61af66fc99e Initial load
duke
parents:
diff changeset
87 DEBUG_ONLY(if (push_new_state) _state->push(IfThenS));
a61af66fc99e Initial load
duke
parents:
diff changeset
88 set_ctrl(then);
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 //-------------------------------else_-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // Pop the else cvstate off the stack, and push the (current) then cvstate.
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // The else cvstate becomes the current cvstate.
a61af66fc99e Initial load
duke
parents:
diff changeset
94 void IdealKit::else_() {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 assert(state() == IfThenS, "bad state for new Else");
a61af66fc99e Initial load
duke
parents:
diff changeset
96 Node* else_cvstate = _pending_cvstates->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
97 DEBUG_ONLY(_state->pop());
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // save current (then) cvstate for later use at endif
a61af66fc99e Initial load
duke
parents:
diff changeset
99 _pending_cvstates->push(_cvstate);
a61af66fc99e Initial load
duke
parents:
diff changeset
100 DEBUG_ONLY(_state->push(ElseS));
a61af66fc99e Initial load
duke
parents:
diff changeset
101 _cvstate = else_cvstate;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 //-------------------------------end_if-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // Merge the "then" and "else" cvstates.
a61af66fc99e Initial load
duke
parents:
diff changeset
106 //
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
107 // The if_then() pushed a copy of the current state for later use
0
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // as the initial state for a future "else" clause. The
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // current state then became the initial state for the
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // then clause. If an "else" clause was encountered, it will
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // pop the top state and use it for it's initial state.
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // It will also push the current state (the state at the end of
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // the "then" clause) for latter use at the end_if.
a61af66fc99e Initial load
duke
parents:
diff changeset
114 //
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // At the endif, the states are:
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // 1) else exists a) current state is end of "else" clause
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // b) top stack state is end of "then" clause
a61af66fc99e Initial load
duke
parents:
diff changeset
118 //
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // 2) no else: a) current state is end of "then" clause
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // b) top stack state is from the "if_then" which
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // would have been the initial state of the else.
a61af66fc99e Initial load
duke
parents:
diff changeset
122 //
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // Merging the states is accomplished by:
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // 1) make a label for the merge
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // 2) terminate the current state with a goto to the label
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // 3) pop the top state from the stack and make it the
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // current state
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // 4) bind the label at the current state. Binding a label
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // terminates the current state with a goto to the
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // label and makes the label's state the current state.
a61af66fc99e Initial load
duke
parents:
diff changeset
131 //
a61af66fc99e Initial load
duke
parents:
diff changeset
132 void IdealKit::end_if() {
a61af66fc99e Initial load
duke
parents:
diff changeset
133 assert(state() & (IfThenS|ElseS), "bad state for new Endif");
a61af66fc99e Initial load
duke
parents:
diff changeset
134 Node* lab = make_label(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // Node* join_state = _pending_cvstates->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
137 /* merging, join */
a61af66fc99e Initial load
duke
parents:
diff changeset
138 goto_(lab);
a61af66fc99e Initial load
duke
parents:
diff changeset
139 _cvstate = _pending_cvstates->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 bind(lab);
a61af66fc99e Initial load
duke
parents:
diff changeset
142 DEBUG_ONLY(_state->pop());
a61af66fc99e Initial load
duke
parents:
diff changeset
143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 //-------------------------------loop-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // Create the loop head portion (*) of:
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // * iv = init
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // * top: (region node)
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // * if (iv relop limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // loop body
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // i = i + 1
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // goto top
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // * } else // exits loop
a61af66fc99e Initial load
duke
parents:
diff changeset
154 //
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // Pushes the loop top cvstate first, then the else (loop exit) cvstate
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // onto the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
157 void IdealKit::loop(IdealVariable& iv, Node* init, BoolTest::mask relop, Node* limit, float prob, float cnt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new loop");
a61af66fc99e Initial load
duke
parents:
diff changeset
159 set(iv, init);
a61af66fc99e Initial load
duke
parents:
diff changeset
160 Node* head = make_label(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
161 bind(head);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 _pending_cvstates->push(head); // push for use at end_loop
a61af66fc99e Initial load
duke
parents:
diff changeset
163 _cvstate = copy_cvstate();
a61af66fc99e Initial load
duke
parents:
diff changeset
164 if_then(value(iv), relop, limit, prob, cnt, false /* no new state */);
a61af66fc99e Initial load
duke
parents:
diff changeset
165 DEBUG_ONLY(_state->push(LoopS));
a61af66fc99e Initial load
duke
parents:
diff changeset
166 assert(ctrl()->is_IfTrue(), "true branch stays in loop");
a61af66fc99e Initial load
duke
parents:
diff changeset
167 assert(_pending_cvstates->top()->in(TypeFunc::Control)->is_IfFalse(), "false branch exits loop");
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 //-------------------------------end_loop-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Creates the goto top label.
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Expects the else (loop exit) cvstate to be on top of the
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // stack, and the loop top cvstate to be 2nd.
a61af66fc99e Initial load
duke
parents:
diff changeset
174 void IdealKit::end_loop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 assert((state() == LoopS), "bad state for new end_loop");
a61af66fc99e Initial load
duke
parents:
diff changeset
176 Node* exit = _pending_cvstates->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
177 Node* head = _pending_cvstates->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
178 goto_(head);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 clear(head);
a61af66fc99e Initial load
duke
parents:
diff changeset
180 DEBUG_ONLY(_state->pop());
a61af66fc99e Initial load
duke
parents:
diff changeset
181 _cvstate = exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 //-------------------------------make_label-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // Creates a label. The number of goto's
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // must be specified (which should be 1 less than
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // the number of precedessors.)
a61af66fc99e Initial load
duke
parents:
diff changeset
188 Node* IdealKit::make_label(int goto_ct) {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 assert(_cvstate != NULL, "must declare variables before labels");
a61af66fc99e Initial load
duke
parents:
diff changeset
190 Node* lab = new_cvstate();
a61af66fc99e Initial load
duke
parents:
diff changeset
191 int sz = 1 + goto_ct + 1 /* fall thru */;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 Node* reg = delay_transform(new (C, sz) RegionNode(sz));
a61af66fc99e Initial load
duke
parents:
diff changeset
193 lab->init_req(TypeFunc::Control, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 return lab;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 //-------------------------------bind-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // Bind a label at the current cvstate by simulating
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // a goto to the label.
a61af66fc99e Initial load
duke
parents:
diff changeset
200 void IdealKit::bind(Node* lab) {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 goto_(lab, true /* bind */);
a61af66fc99e Initial load
duke
parents:
diff changeset
202 _cvstate = lab;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 //-------------------------------goto_-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // Make the current cvstate a predecessor of the label,
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // creating phi's to merge values. If bind is true and
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // this is not the last control edge, then ensure that
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // all live values have phis created. Used to create phis
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // at loop-top regions.
a61af66fc99e Initial load
duke
parents:
diff changeset
211 void IdealKit::goto_(Node* lab, bool bind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 Node* reg = lab->in(TypeFunc::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // find next empty slot in region
a61af66fc99e Initial load
duke
parents:
diff changeset
214 uint slot = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 while (slot < reg->req() && reg->in(slot) != NULL) slot++;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 assert(slot < reg->req(), "too many gotos");
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // If this is last predecessor, then don't force phi creation
a61af66fc99e Initial load
duke
parents:
diff changeset
218 if (slot == reg->req() - 1) bind = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 reg->init_req(slot, ctrl());
a61af66fc99e Initial load
duke
parents:
diff changeset
220 assert(first_var + _var_ct == _cvstate->req(), "bad _cvstate size");
a61af66fc99e Initial load
duke
parents:
diff changeset
221 for (uint i = first_var; i < _cvstate->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 // l is the value of var reaching the label. Could be a single value
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // reaching the label, or a phi that merges multiples values reaching
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // the label. The latter is true if the label's input: in(..) is
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // a phi whose control input is the region node for the label.
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 Node* l = lab->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // Get the current value of the var
a61af66fc99e Initial load
duke
parents:
diff changeset
230 Node* m = _cvstate->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // If the var went unused no need for a phi
a61af66fc99e Initial load
duke
parents:
diff changeset
232 if (m == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 } else if (l == NULL || m == l) {
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // Only one unique value "m" is known to reach this label so a phi
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // is not yet necessary unless:
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // the label is being bound and all predecessors have not been seen,
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // in which case "bind" will be true.
a61af66fc99e Initial load
duke
parents:
diff changeset
239 if (bind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 m = promote_to_phi(m, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // Record the phi/value used for this var in the label's cvstate
a61af66fc99e Initial load
duke
parents:
diff changeset
243 lab->set_req(i, m);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // More than one value for the variable reaches this label so
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // a create a phi if one does not already exist.
a61af66fc99e Initial load
duke
parents:
diff changeset
247 if (!was_promoted_to_phi(l, reg)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 l = promote_to_phi(l, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
249 lab->set_req(i, l);
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // Record in the phi, the var's value from the current state
a61af66fc99e Initial load
duke
parents:
diff changeset
252 l->set_req(slot, m);
a61af66fc99e Initial load
duke
parents:
diff changeset
253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
255 do_memory_merge(_cvstate, lab);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258
a61af66fc99e Initial load
duke
parents:
diff changeset
259 //-----------------------------promote_to_phi-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
260 Node* IdealKit::promote_to_phi(Node* n, Node* reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 assert(!was_promoted_to_phi(n, reg), "n already promoted to phi on this region");
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // Get a conservative type for the phi
a61af66fc99e Initial load
duke
parents:
diff changeset
263 const BasicType bt = n->bottom_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
264 const Type* ct = Type::get_const_basic_type(bt);
a61af66fc99e Initial load
duke
parents:
diff changeset
265 return delay_transform(PhiNode::make(reg, n, ct));
a61af66fc99e Initial load
duke
parents:
diff changeset
266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
267
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
268 //-----------------------------declarations_done-------------------------------
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
269 void IdealKit::declarations_done() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
270 _cvstate = new_cvstate(); // initialize current cvstate
a61af66fc99e Initial load
duke
parents:
diff changeset
271 set_ctrl(_initial_ctrl); // initialize control in current cvstate
a61af66fc99e Initial load
duke
parents:
diff changeset
272 set_all_memory(_initial_memory);// initialize memory in current cvstate
a61af66fc99e Initial load
duke
parents:
diff changeset
273 DEBUG_ONLY(_state->push(BlockS));
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 //-----------------------------transform-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
277 Node* IdealKit::transform(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
278 if (_delay_all_transforms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 return delay_transform(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 return gvn().transform(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 //-----------------------------delay_transform-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
286 Node* IdealKit::delay_transform(Node* n) {
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
287 if (!gvn().is_IterGVN() || !gvn().is_IterGVN()->delay_transform()) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
288 gvn().set_type(n, n->bottom_type());
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
289 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
290 _delay_transform->push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
291 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 //-----------------------------new_cvstate-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
295 Node* IdealKit::new_cvstate() {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 uint sz = _var_ct + first_var;
a61af66fc99e Initial load
duke
parents:
diff changeset
297 return new (C, sz) Node(sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
299
a61af66fc99e Initial load
duke
parents:
diff changeset
300 //-----------------------------copy_cvstate-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
301 Node* IdealKit::copy_cvstate() {
a61af66fc99e Initial load
duke
parents:
diff changeset
302 Node* ns = new_cvstate();
a61af66fc99e Initial load
duke
parents:
diff changeset
303 for (uint i = 0; i < ns->req(); i++) ns->init_req(i, _cvstate->in(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // We must clone memory since it will be updated as we do stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
305 ns->set_req(TypeFunc::Memory, MergeMemNode::make(C, ns->in(TypeFunc::Memory)));
a61af66fc99e Initial load
duke
parents:
diff changeset
306 return ns;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 //-----------------------------clear-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
310 void IdealKit::clear(Node* m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 for (uint i = 0; i < m->req(); i++) m->set_req(i, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 //-----------------------------drain_delay_transform----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
315 void IdealKit::drain_delay_transform() {
a61af66fc99e Initial load
duke
parents:
diff changeset
316 while (_delay_transform->length() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 Node* n = _delay_transform->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
318 gvn().transform(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
319 if (!gvn().is_IterGVN()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 C->record_for_igvn(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 //-----------------------------IdealVariable----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
326 IdealVariable::IdealVariable(IdealKit &k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 k.declare(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
329
a61af66fc99e Initial load
duke
parents:
diff changeset
330 Node* IdealKit::memory(uint alias_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
331 MergeMemNode* mem = merged_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
332 Node* p = mem->memory_at(alias_idx);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
333 if (!gvn().is_IterGVN() || !gvn().is_IterGVN()->delay_transform()) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
334 _gvn.set_type(p, Type::MEMORY); // must be mapped
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 196
diff changeset
335 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
336 return p;
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 void IdealKit::set_memory(Node* mem, uint alias_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
340 merged_memory()->set_memory_at(alias_idx, mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 //----------------------------- make_load ----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
344 Node* IdealKit::load(Node* ctl,
a61af66fc99e Initial load
duke
parents:
diff changeset
345 Node* adr,
a61af66fc99e Initial load
duke
parents:
diff changeset
346 const Type* t,
a61af66fc99e Initial load
duke
parents:
diff changeset
347 BasicType bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
348 int adr_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
349 bool require_atomic_access) {
a61af66fc99e Initial load
duke
parents:
diff changeset
350
a61af66fc99e Initial load
duke
parents:
diff changeset
351 assert(adr_idx != Compile::AliasIdxTop, "use other make_load factory" );
a61af66fc99e Initial load
duke
parents:
diff changeset
352 const TypePtr* adr_type = NULL; // debug-mode-only argument
a61af66fc99e Initial load
duke
parents:
diff changeset
353 debug_only(adr_type = C->get_adr_type(adr_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
354 Node* mem = memory(adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
355 Node* ld;
a61af66fc99e Initial load
duke
parents:
diff changeset
356 if (require_atomic_access && bt == T_LONG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
357 ld = LoadLNode::make_atomic(C, ctl, mem, adr, adr_type, t);
a61af66fc99e Initial load
duke
parents:
diff changeset
358 } else {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
359 ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361 return transform(ld);
a61af66fc99e Initial load
duke
parents:
diff changeset
362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 Node* IdealKit::store(Node* ctl, Node* adr, Node *val, BasicType bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
365 int adr_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
366 bool require_atomic_access) {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
a61af66fc99e Initial load
duke
parents:
diff changeset
368 const TypePtr* adr_type = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
369 debug_only(adr_type = C->get_adr_type(adr_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
370 Node *mem = memory(adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
371 Node* st;
a61af66fc99e Initial load
duke
parents:
diff changeset
372 if (require_atomic_access && bt == T_LONG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 st = StoreLNode::make_atomic(C, ctl, mem, adr, adr_type, val);
a61af66fc99e Initial load
duke
parents:
diff changeset
374 } else {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
375 st = StoreNode::make(_gvn, ctl, mem, adr, adr_type, val, bt);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377 st = transform(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
378 set_memory(st, adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 return st;
a61af66fc99e Initial load
duke
parents:
diff changeset
381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
382
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // Card mark store. Must be ordered so that it will come after the store of
a61af66fc99e Initial load
duke
parents:
diff changeset
384 // the oop.
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 851
diff changeset
385 Node* IdealKit::storeCM(Node* ctl, Node* adr, Node *val, Node* oop_store, int oop_adr_idx,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
386 BasicType bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
387 int adr_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
a61af66fc99e Initial load
duke
parents:
diff changeset
389 const TypePtr* adr_type = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
390 debug_only(adr_type = C->get_adr_type(adr_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
391 Node *mem = memory(adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // Add required edge to oop_store, optimizer does not support precedence edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // Convert required edge to precedence edge before allocation.
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 851
diff changeset
395 Node* st = new (C, 5) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store, oop_adr_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 st = transform(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
398 set_memory(st, adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 return st;
a61af66fc99e Initial load
duke
parents:
diff changeset
401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
402
a61af66fc99e Initial load
duke
parents:
diff changeset
403 //---------------------------- do_memory_merge --------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // The memory from one merging cvstate needs to be merged with the memory for another
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // join cvstate. If the join cvstate doesn't have a merged memory yet then we
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // can just copy the state from the merging cvstate
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // Merge one slow path into the rest of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
409 void IdealKit::do_memory_merge(Node* merging, Node* join) {
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // Get the region for the join state
a61af66fc99e Initial load
duke
parents:
diff changeset
412 Node* join_region = join->in(TypeFunc::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
413 assert(join_region != NULL, "join region must exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
414 if (join->in(TypeFunc::Memory) == NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 join->set_req(TypeFunc::Memory, merging->in(TypeFunc::Memory));
a61af66fc99e Initial load
duke
parents:
diff changeset
416 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // The control flow for merging must have already been attached to the join region
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // we need its index for the phis.
a61af66fc99e Initial load
duke
parents:
diff changeset
421 uint slot;
a61af66fc99e Initial load
duke
parents:
diff changeset
422 for (slot = 1; slot < join_region->req() ; slot ++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
423 if (join_region->in(slot) == merging->in(TypeFunc::Control)) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
425 assert(slot != join_region->req(), "edge must already exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 MergeMemNode* join_m = join->in(TypeFunc::Memory)->as_MergeMem();
a61af66fc99e Initial load
duke
parents:
diff changeset
428 MergeMemNode* merging_m = merging->in(TypeFunc::Memory)->as_MergeMem();
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // join_m should be an ancestor mergemem of merging
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // Slow path memory comes from the current map (which is from a slow call)
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // Fast path/null path memory comes from the call's input
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // Merge the other fast-memory inputs with the new slow-default memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // for (MergeMemStream mms(merged_memory(), fast_mem->as_MergeMem()); mms.next_non_empty2(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
436 for (MergeMemStream mms(join_m, merging_m); mms.next_non_empty2(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 Node* join_slice = mms.force_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
438 Node* merging_slice = mms.memory2();
a61af66fc99e Initial load
duke
parents:
diff changeset
439 if (join_slice != merging_slice) {
a61af66fc99e Initial load
duke
parents:
diff changeset
440 PhiNode* phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // bool new_phi = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // Is the phi for this slice one that we created for this join region or simply
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // one we copied? If it is ours then add
a61af66fc99e Initial load
duke
parents:
diff changeset
444 if (join_slice->is_Phi() && join_slice->as_Phi()->region() == join_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
445 phi = join_slice->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
446 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // create the phi with join_slice filling supplying memory for all of the
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // control edges to the join region
a61af66fc99e Initial load
duke
parents:
diff changeset
449 phi = PhiNode::make(join_region, join_slice, Type::MEMORY, mms.adr_type(C));
a61af66fc99e Initial load
duke
parents:
diff changeset
450 phi = (PhiNode*) delay_transform(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // gvn().set_type(phi, Type::MEMORY);
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // new_phi = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // Now update the phi with the slice for the merging slice
a61af66fc99e Initial load
duke
parents:
diff changeset
455 phi->set_req(slot, merging_slice/* slow_path, slow_slice */);
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // this updates join_m with the phi
a61af66fc99e Initial load
duke
parents:
diff changeset
457 mms.set_memory(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462
a61af66fc99e Initial load
duke
parents:
diff changeset
463 //----------------------------- make_call ----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // Trivial runtime call
a61af66fc99e Initial load
duke
parents:
diff changeset
465 void IdealKit::make_leaf_call(const TypeFunc *slow_call_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
466 address slow_call,
a61af66fc99e Initial load
duke
parents:
diff changeset
467 const char *leaf_name,
a61af66fc99e Initial load
duke
parents:
diff changeset
468 Node* parm0,
a61af66fc99e Initial load
duke
parents:
diff changeset
469 Node* parm1,
a61af66fc99e Initial load
duke
parents:
diff changeset
470 Node* parm2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
471
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // We only handle taking in RawMem and modifying RawMem
a61af66fc99e Initial load
duke
parents:
diff changeset
473 const TypePtr* adr_type = TypeRawPtr::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
474 uint adr_idx = C->get_alias_index(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
475
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // Slow-path leaf call
a61af66fc99e Initial load
duke
parents:
diff changeset
477 int size = slow_call_type->domain()->cnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
478 CallNode *call = (CallNode*)new (C, size) CallLeafNode( slow_call_type, slow_call, leaf_name, adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // Set fixed predefined input arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
481 call->init_req( TypeFunc::Control, ctrl() );
a61af66fc99e Initial load
duke
parents:
diff changeset
482 call->init_req( TypeFunc::I_O , top() ) ; // does no i/o
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // Narrow memory as only memory input
a61af66fc99e Initial load
duke
parents:
diff changeset
484 call->init_req( TypeFunc::Memory , memory(adr_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
485 call->init_req( TypeFunc::FramePtr, top() /* frameptr() */ );
a61af66fc99e Initial load
duke
parents:
diff changeset
486 call->init_req( TypeFunc::ReturnAdr, top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 if (parm0 != NULL) call->init_req(TypeFunc::Parms+0, parm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
489 if (parm1 != NULL) call->init_req(TypeFunc::Parms+1, parm1);
a61af66fc99e Initial load
duke
parents:
diff changeset
490 if (parm2 != NULL) call->init_req(TypeFunc::Parms+2, parm2);
a61af66fc99e Initial load
duke
parents:
diff changeset
491
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // Node *c = _gvn.transform(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
493 call = (CallNode *) _gvn.transform(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
494 Node *c = call; // dbx gets confused with call call->dump()
a61af66fc99e Initial load
duke
parents:
diff changeset
495
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // Slow leaf call has no side-effects, sets few values
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 set_ctrl(transform( new (C, 1) ProjNode(call,TypeFunc::Control) ));
a61af66fc99e Initial load
duke
parents:
diff changeset
499
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // Make memory for the call
a61af66fc99e Initial load
duke
parents:
diff changeset
501 Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) );
a61af66fc99e Initial load
duke
parents:
diff changeset
502
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // Set the RawPtr memory state only.
a61af66fc99e Initial load
duke
parents:
diff changeset
504 set_memory(mem, adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
505
a61af66fc99e Initial load
duke
parents:
diff changeset
506 assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type),
a61af66fc99e Initial load
duke
parents:
diff changeset
507 "call node must be constructed correctly");
a61af66fc99e Initial load
duke
parents:
diff changeset
508 }