138 |
138 |
139 // 2) substitute conditional expression |
139 // 2) substitute conditional expression |
140 // with an IfOp followed by a Goto |
140 // with an IfOp followed by a Goto |
141 // cut if_ away and get node before |
141 // cut if_ away and get node before |
142 Instruction* cur_end = if_->prev(block); |
142 Instruction* cur_end = if_->prev(block); |
143 int bci = if_->bci(); |
|
144 |
143 |
145 // append constants of true- and false-block if necessary |
144 // append constants of true- and false-block if necessary |
146 // clone constants because original block must not be destroyed |
145 // clone constants because original block must not be destroyed |
147 assert((t_value != f_const && f_value != t_const) || t_const == f_const, "mismatch"); |
146 assert((t_value != f_const && f_value != t_const) || t_const == f_const, "mismatch"); |
148 if (t_value == t_const) { |
147 if (t_value == t_const) { |
149 t_value = new Constant(t_const->type()); |
148 t_value = new Constant(t_const->type()); |
150 cur_end = cur_end->set_next(t_value, bci); |
149 NOT_PRODUCT(t_value->set_printable_bci(if_->printable_bci())); |
|
150 cur_end = cur_end->set_next(t_value); |
151 } |
151 } |
152 if (f_value == f_const) { |
152 if (f_value == f_const) { |
153 f_value = new Constant(f_const->type()); |
153 f_value = new Constant(f_const->type()); |
154 cur_end = cur_end->set_next(f_value, bci); |
154 NOT_PRODUCT(f_value->set_printable_bci(if_->printable_bci())); |
|
155 cur_end = cur_end->set_next(f_value); |
155 } |
156 } |
156 |
157 |
157 // it is very unlikely that the condition can be statically decided |
158 // it is very unlikely that the condition can be statically decided |
158 // (this was checked previously by the Canonicalizer), so always |
159 // (this was checked previously by the Canonicalizer), so always |
159 // append IfOp |
160 // append IfOp |
160 Value result = new IfOp(if_->x(), if_->cond(), if_->y(), t_value, f_value); |
161 Value result = new IfOp(if_->x(), if_->cond(), if_->y(), t_value, f_value); |
161 cur_end = cur_end->set_next(result, bci); |
162 NOT_PRODUCT(result->set_printable_bci(if_->printable_bci())); |
|
163 cur_end = cur_end->set_next(result); |
162 |
164 |
163 // append Goto to successor |
165 // append Goto to successor |
164 ValueStack* state_before = if_->is_safepoint() ? if_->state_before() : NULL; |
166 ValueStack* state_before = if_->is_safepoint() ? if_->state_before() : NULL; |
165 Goto* goto_ = new Goto(sux, state_before, if_->is_safepoint() || t_goto->is_safepoint() || f_goto->is_safepoint()); |
167 Goto* goto_ = new Goto(sux, state_before, if_->is_safepoint() || t_goto->is_safepoint() || f_goto->is_safepoint()); |
166 |
168 |
167 // prepare state for Goto |
169 // prepare state for Goto |
168 ValueStack* goto_state = if_->state(); |
170 ValueStack* goto_state = if_->state(); |
169 while (sux_state->scope() != goto_state->scope()) { |
171 while (sux_state->scope() != goto_state->scope()) { |
170 goto_state = goto_state->pop_scope(); |
172 goto_state = goto_state->caller_state(); |
171 assert(goto_state != NULL, "states do not match up"); |
173 assert(goto_state != NULL, "states do not match up"); |
172 } |
174 } |
173 goto_state = goto_state->copy(); |
175 goto_state = goto_state->copy(ValueStack::StateAfter, goto_state->bci()); |
174 goto_state->push(result->type(), result); |
176 goto_state->push(result->type(), result); |
175 assert(goto_state->is_same_across_scopes(sux_state), "states must match now"); |
177 assert(goto_state->is_same(sux_state), "states must match now"); |
176 goto_->set_state(goto_state); |
178 goto_->set_state(goto_state); |
177 |
179 |
178 // Steal the bci for the goto from the sux |
180 cur_end = cur_end->set_next(goto_, goto_state->bci()); |
179 cur_end = cur_end->set_next(goto_, sux->bci()); |
|
180 |
181 |
181 // Adjust control flow graph |
182 // Adjust control flow graph |
182 BlockBegin::disconnect_edge(block, t_block); |
183 BlockBegin::disconnect_edge(block, t_block); |
183 BlockBegin::disconnect_edge(block, f_block); |
184 BlockBegin::disconnect_edge(block, f_block); |
184 if (t_block->number_of_preds() == 0) { |
185 if (t_block->number_of_preds() == 0) { |
249 #ifdef ASSERT |
250 #ifdef ASSERT |
250 // verify that state at the end of block and at the beginning of sux are equal |
251 // verify that state at the end of block and at the beginning of sux are equal |
251 // no phi functions must be present at beginning of sux |
252 // no phi functions must be present at beginning of sux |
252 ValueStack* sux_state = sux->state(); |
253 ValueStack* sux_state = sux->state(); |
253 ValueStack* end_state = end->state(); |
254 ValueStack* end_state = end->state(); |
254 while (end_state->scope() != sux_state->scope()) { |
255 |
255 // match up inlining level |
256 assert(end_state->scope() == sux_state->scope(), "scopes must match"); |
256 end_state = end_state->pop_scope(); |
|
257 } |
|
258 assert(end_state->stack_size() == sux_state->stack_size(), "stack not equal"); |
257 assert(end_state->stack_size() == sux_state->stack_size(), "stack not equal"); |
259 assert(end_state->locals_size() == sux_state->locals_size(), "locals not equal"); |
258 assert(end_state->locals_size() == sux_state->locals_size(), "locals not equal"); |
260 |
259 |
261 int index; |
260 int index; |
262 Value sux_value; |
261 Value sux_value; |
271 |
270 |
272 // find instruction before end & append first instruction of sux block |
271 // find instruction before end & append first instruction of sux block |
273 Instruction* prev = end->prev(block); |
272 Instruction* prev = end->prev(block); |
274 Instruction* next = sux->next(); |
273 Instruction* next = sux->next(); |
275 assert(prev->as_BlockEnd() == NULL, "must not be a BlockEnd"); |
274 assert(prev->as_BlockEnd() == NULL, "must not be a BlockEnd"); |
276 prev->set_next(next, next->bci()); |
275 prev->set_next(next); |
277 sux->disconnect_from_graph(); |
276 sux->disconnect_from_graph(); |
278 block->set_end(sux->end()); |
277 block->set_end(sux->end()); |
279 // add exception handlers of deleted block, if any |
278 // add exception handlers of deleted block, if any |
280 for (int k = 0; k < sux->number_of_exception_handlers(); k++) { |
279 for (int k = 0; k < sux->number_of_exception_handlers(); k++) { |
281 BlockBegin* xhandler = sux->exception_handler_at(k); |
280 BlockBegin* xhandler = sux->exception_handler_at(k); |
335 If* newif = new If(ifop->x(), ifop->cond(), false, ifop->y(), |
334 If* newif = new If(ifop->x(), ifop->cond(), false, ifop->y(), |
336 tblock, fblock, if_->state_before(), if_->is_safepoint()); |
335 tblock, fblock, if_->state_before(), if_->is_safepoint()); |
337 newif->set_state(if_->state()->copy()); |
336 newif->set_state(if_->state()->copy()); |
338 |
337 |
339 assert(prev->next() == if_, "must be guaranteed by above search"); |
338 assert(prev->next() == if_, "must be guaranteed by above search"); |
340 prev->set_next(newif, if_->bci()); |
339 NOT_PRODUCT(newif->set_printable_bci(if_->printable_bci())); |
|
340 prev->set_next(newif); |
341 block->set_end(newif); |
341 block->set_end(newif); |
342 |
342 |
343 _merge_count++; |
343 _merge_count++; |
344 if (PrintBlockElimination) { |
344 if (PrintBlockElimination) { |
345 tty->print_cr("%d. replaced If and IfOp at end of B%d with single If", _merge_count, block->block_id()); |
345 tty->print_cr("%d. replaced If and IfOp at end of B%d with single If", _merge_count, block->block_id()); |