comparison src/share/vm/c1/c1_Optimizer.cpp @ 1819:f02a8bbe6ed4

6986046: C1 valuestack cleanup Summary: fixes an historical oddity in C1 with inlining where all of the expression stacks are kept in the topmost ValueStack instead of being in their respective ValueStacks. Reviewed-by: never Contributed-by: Christian Wimmer <cwimmer@uci.edu>
author roland
date Tue, 29 Dec 2009 19:08:54 +0100
parents d5d065957597
children 42a10fc37986
comparison
equal deleted inserted replaced
1817:c40600e85311 1819:f02a8bbe6ed4
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());
703 // Mark instructions in this block as visitable as they are seen 703 // Mark instructions in this block as visitable as they are seen
704 // in the instruction list. This keeps the iteration from 704 // in the instruction list. This keeps the iteration from
705 // visiting instructions which are references in other blocks or 705 // visiting instructions which are references in other blocks or
706 // visiting instructions more than once. 706 // visiting instructions more than once.
707 mark_visitable(instr); 707 mark_visitable(instr);
708 if (instr->is_root() || instr->can_trap() || (instr->as_NullCheck() != NULL)) { 708 if (instr->is_pinned() || instr->can_trap() || (instr->as_NullCheck() != NULL)) {
709 mark_visited(instr); 709 mark_visited(instr);
710 instr->input_values_do(this); 710 instr->input_values_do(this);
711 instr->visit(&_visitor); 711 instr->visit(&_visitor);
712 } 712 }
713 } 713 }