annotate src/share/vm/opto/idealKit.cpp @ 1941:79d04223b8a5

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