1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/c1/c1_Optimizer.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,1206 @@ 1.4 +/* 1.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "c1/c1_Canonicalizer.hpp" 1.30 +#include "c1/c1_Optimizer.hpp" 1.31 +#include "c1/c1_ValueMap.hpp" 1.32 +#include "c1/c1_ValueSet.hpp" 1.33 +#include "c1/c1_ValueStack.hpp" 1.34 +#include "utilities/bitMap.inline.hpp" 1.35 +#include "compiler/compileLog.hpp" 1.36 + 1.37 +define_array(ValueSetArray, ValueSet*); 1.38 +define_stack(ValueSetList, ValueSetArray); 1.39 + 1.40 + 1.41 +Optimizer::Optimizer(IR* ir) { 1.42 + assert(ir->is_valid(), "IR must be valid"); 1.43 + _ir = ir; 1.44 +} 1.45 + 1.46 +class CE_Eliminator: public BlockClosure { 1.47 + private: 1.48 + IR* _hir; 1.49 + int _cee_count; // the number of CEs successfully eliminated 1.50 + int _ifop_count; // the number of IfOps successfully simplified 1.51 + int _has_substitution; 1.52 + 1.53 + public: 1.54 + CE_Eliminator(IR* hir) : _cee_count(0), _ifop_count(0), _hir(hir) { 1.55 + _has_substitution = false; 1.56 + _hir->iterate_preorder(this); 1.57 + if (_has_substitution) { 1.58 + // substituted some ifops/phis, so resolve the substitution 1.59 + SubstitutionResolver sr(_hir); 1.60 + } 1.61 + 1.62 + CompileLog* log = _hir->compilation()->log(); 1.63 + if (log != NULL) 1.64 + log->set_context("optimize name='cee'"); 1.65 + } 1.66 + 1.67 + ~CE_Eliminator() { 1.68 + CompileLog* log = _hir->compilation()->log(); 1.69 + if (log != NULL) 1.70 + log->clear_context(); // skip marker if nothing was printed 1.71 + } 1.72 + 1.73 + int cee_count() const { return _cee_count; } 1.74 + int ifop_count() const { return _ifop_count; } 1.75 + 1.76 + void adjust_exception_edges(BlockBegin* block, BlockBegin* sux) { 1.77 + int e = sux->number_of_exception_handlers(); 1.78 + for (int i = 0; i < e; i++) { 1.79 + BlockBegin* xhandler = sux->exception_handler_at(i); 1.80 + block->add_exception_handler(xhandler); 1.81 + 1.82 + assert(xhandler->is_predecessor(sux), "missing predecessor"); 1.83 + if (sux->number_of_preds() == 0) { 1.84 + // sux is disconnected from graph so disconnect from exception handlers 1.85 + xhandler->remove_predecessor(sux); 1.86 + } 1.87 + if (!xhandler->is_predecessor(block)) { 1.88 + xhandler->add_predecessor(block); 1.89 + } 1.90 + } 1.91 + } 1.92 + 1.93 + virtual void block_do(BlockBegin* block); 1.94 + 1.95 + private: 1.96 + Value make_ifop(Value x, Instruction::Condition cond, Value y, Value tval, Value fval); 1.97 +}; 1.98 + 1.99 +void CE_Eliminator::block_do(BlockBegin* block) { 1.100 + // 1) find conditional expression 1.101 + // check if block ends with an If 1.102 + If* if_ = block->end()->as_If(); 1.103 + if (if_ == NULL) return; 1.104 + 1.105 + // check if If works on int or object types 1.106 + // (we cannot handle If's working on long, float or doubles yet, 1.107 + // since IfOp doesn't support them - these If's show up if cmp 1.108 + // operations followed by If's are eliminated) 1.109 + ValueType* if_type = if_->x()->type(); 1.110 + if (!if_type->is_int() && !if_type->is_object()) return; 1.111 + 1.112 + BlockBegin* t_block = if_->tsux(); 1.113 + BlockBegin* f_block = if_->fsux(); 1.114 + Instruction* t_cur = t_block->next(); 1.115 + Instruction* f_cur = f_block->next(); 1.116 + 1.117 + // one Constant may be present between BlockBegin and BlockEnd 1.118 + Value t_const = NULL; 1.119 + Value f_const = NULL; 1.120 + if (t_cur->as_Constant() != NULL && !t_cur->can_trap()) { 1.121 + t_const = t_cur; 1.122 + t_cur = t_cur->next(); 1.123 + } 1.124 + if (f_cur->as_Constant() != NULL && !f_cur->can_trap()) { 1.125 + f_const = f_cur; 1.126 + f_cur = f_cur->next(); 1.127 + } 1.128 + 1.129 + // check if both branches end with a goto 1.130 + Goto* t_goto = t_cur->as_Goto(); 1.131 + if (t_goto == NULL) return; 1.132 + Goto* f_goto = f_cur->as_Goto(); 1.133 + if (f_goto == NULL) return; 1.134 + 1.135 + // check if both gotos merge into the same block 1.136 + BlockBegin* sux = t_goto->default_sux(); 1.137 + if (sux != f_goto->default_sux()) return; 1.138 + 1.139 + // check if at least one word was pushed on sux_state 1.140 + // inlining depths must match 1.141 + ValueStack* if_state = if_->state(); 1.142 + ValueStack* sux_state = sux->state(); 1.143 + if (if_state->scope()->level() > sux_state->scope()->level()) { 1.144 + while (sux_state->scope() != if_state->scope()) { 1.145 + if_state = if_state->caller_state(); 1.146 + assert(if_state != NULL, "states do not match up"); 1.147 + } 1.148 + } else if (if_state->scope()->level() < sux_state->scope()->level()) { 1.149 + while (sux_state->scope() != if_state->scope()) { 1.150 + sux_state = sux_state->caller_state(); 1.151 + assert(sux_state != NULL, "states do not match up"); 1.152 + } 1.153 + } 1.154 + 1.155 + if (sux_state->stack_size() <= if_state->stack_size()) return; 1.156 + 1.157 + // check if phi function is present at end of successor stack and that 1.158 + // only this phi was pushed on the stack 1.159 + Value sux_phi = sux_state->stack_at(if_state->stack_size()); 1.160 + if (sux_phi == NULL || sux_phi->as_Phi() == NULL || sux_phi->as_Phi()->block() != sux) return; 1.161 + if (sux_phi->type()->size() != sux_state->stack_size() - if_state->stack_size()) return; 1.162 + 1.163 + // get the values that were pushed in the true- and false-branch 1.164 + Value t_value = t_goto->state()->stack_at(if_state->stack_size()); 1.165 + Value f_value = f_goto->state()->stack_at(if_state->stack_size()); 1.166 + 1.167 + // backend does not support floats 1.168 + assert(t_value->type()->base() == f_value->type()->base(), "incompatible types"); 1.169 + if (t_value->type()->is_float_kind()) return; 1.170 + 1.171 + // check that successor has no other phi functions but sux_phi 1.172 + // this can happen when t_block or f_block contained additonal stores to local variables 1.173 + // that are no longer represented by explicit instructions 1.174 + for_each_phi_fun(sux, phi, 1.175 + if (phi != sux_phi) return; 1.176 + ); 1.177 + // true and false blocks can't have phis 1.178 + for_each_phi_fun(t_block, phi, return; ); 1.179 + for_each_phi_fun(f_block, phi, return; ); 1.180 + 1.181 + // 2) substitute conditional expression 1.182 + // with an IfOp followed by a Goto 1.183 + // cut if_ away and get node before 1.184 + Instruction* cur_end = if_->prev(); 1.185 + 1.186 + // append constants of true- and false-block if necessary 1.187 + // clone constants because original block must not be destroyed 1.188 + assert((t_value != f_const && f_value != t_const) || t_const == f_const, "mismatch"); 1.189 + if (t_value == t_const) { 1.190 + t_value = new Constant(t_const->type()); 1.191 + NOT_PRODUCT(t_value->set_printable_bci(if_->printable_bci())); 1.192 + cur_end = cur_end->set_next(t_value); 1.193 + } 1.194 + if (f_value == f_const) { 1.195 + f_value = new Constant(f_const->type()); 1.196 + NOT_PRODUCT(f_value->set_printable_bci(if_->printable_bci())); 1.197 + cur_end = cur_end->set_next(f_value); 1.198 + } 1.199 + 1.200 + Value result = make_ifop(if_->x(), if_->cond(), if_->y(), t_value, f_value); 1.201 + assert(result != NULL, "make_ifop must return a non-null instruction"); 1.202 + if (!result->is_linked() && result->can_be_linked()) { 1.203 + NOT_PRODUCT(result->set_printable_bci(if_->printable_bci())); 1.204 + cur_end = cur_end->set_next(result); 1.205 + } 1.206 + 1.207 + // append Goto to successor 1.208 + ValueStack* state_before = if_->state_before(); 1.209 + Goto* goto_ = new Goto(sux, state_before, if_->is_safepoint() || t_goto->is_safepoint() || f_goto->is_safepoint()); 1.210 + 1.211 + // prepare state for Goto 1.212 + ValueStack* goto_state = if_state; 1.213 + goto_state = goto_state->copy(ValueStack::StateAfter, goto_state->bci()); 1.214 + goto_state->push(result->type(), result); 1.215 + assert(goto_state->is_same(sux_state), "states must match now"); 1.216 + goto_->set_state(goto_state); 1.217 + 1.218 + cur_end = cur_end->set_next(goto_, goto_state->bci()); 1.219 + 1.220 + // Adjust control flow graph 1.221 + BlockBegin::disconnect_edge(block, t_block); 1.222 + BlockBegin::disconnect_edge(block, f_block); 1.223 + if (t_block->number_of_preds() == 0) { 1.224 + BlockBegin::disconnect_edge(t_block, sux); 1.225 + } 1.226 + adjust_exception_edges(block, t_block); 1.227 + if (f_block->number_of_preds() == 0) { 1.228 + BlockBegin::disconnect_edge(f_block, sux); 1.229 + } 1.230 + adjust_exception_edges(block, f_block); 1.231 + 1.232 + // update block end 1.233 + block->set_end(goto_); 1.234 + 1.235 + // substitute the phi if possible 1.236 + if (sux_phi->as_Phi()->operand_count() == 1) { 1.237 + assert(sux_phi->as_Phi()->operand_at(0) == result, "screwed up phi"); 1.238 + sux_phi->set_subst(result); 1.239 + _has_substitution = true; 1.240 + } 1.241 + 1.242 + // 3) successfully eliminated a conditional expression 1.243 + _cee_count++; 1.244 + if (PrintCEE) { 1.245 + tty->print_cr("%d. CEE in B%d (B%d B%d)", cee_count(), block->block_id(), t_block->block_id(), f_block->block_id()); 1.246 + tty->print_cr("%d. IfOp in B%d", ifop_count(), block->block_id()); 1.247 + } 1.248 + 1.249 + _hir->verify(); 1.250 +} 1.251 + 1.252 +Value CE_Eliminator::make_ifop(Value x, Instruction::Condition cond, Value y, Value tval, Value fval) { 1.253 + if (!OptimizeIfOps) { 1.254 + return new IfOp(x, cond, y, tval, fval); 1.255 + } 1.256 + 1.257 + tval = tval->subst(); 1.258 + fval = fval->subst(); 1.259 + if (tval == fval) { 1.260 + _ifop_count++; 1.261 + return tval; 1.262 + } 1.263 + 1.264 + x = x->subst(); 1.265 + y = y->subst(); 1.266 + 1.267 + Constant* y_const = y->as_Constant(); 1.268 + if (y_const != NULL) { 1.269 + IfOp* x_ifop = x->as_IfOp(); 1.270 + if (x_ifop != NULL) { // x is an ifop, y is a constant 1.271 + Constant* x_tval_const = x_ifop->tval()->subst()->as_Constant(); 1.272 + Constant* x_fval_const = x_ifop->fval()->subst()->as_Constant(); 1.273 + 1.274 + if (x_tval_const != NULL && x_fval_const != NULL) { 1.275 + Instruction::Condition x_ifop_cond = x_ifop->cond(); 1.276 + 1.277 + Constant::CompareResult t_compare_res = x_tval_const->compare(cond, y_const); 1.278 + Constant::CompareResult f_compare_res = x_fval_const->compare(cond, y_const); 1.279 + 1.280 + // not_comparable here is a valid return in case we're comparing unloaded oop constants 1.281 + if (t_compare_res != Constant::not_comparable && f_compare_res != Constant::not_comparable) { 1.282 + Value new_tval = t_compare_res == Constant::cond_true ? tval : fval; 1.283 + Value new_fval = f_compare_res == Constant::cond_true ? tval : fval; 1.284 + 1.285 + _ifop_count++; 1.286 + if (new_tval == new_fval) { 1.287 + return new_tval; 1.288 + } else { 1.289 + return new IfOp(x_ifop->x(), x_ifop_cond, x_ifop->y(), new_tval, new_fval); 1.290 + } 1.291 + } 1.292 + } 1.293 + } else { 1.294 + Constant* x_const = x->as_Constant(); 1.295 + if (x_const != NULL) { // x and y are constants 1.296 + Constant::CompareResult x_compare_res = x_const->compare(cond, y_const); 1.297 + // not_comparable here is a valid return in case we're comparing unloaded oop constants 1.298 + if (x_compare_res != Constant::not_comparable) { 1.299 + _ifop_count++; 1.300 + return x_compare_res == Constant::cond_true ? tval : fval; 1.301 + } 1.302 + } 1.303 + } 1.304 + } 1.305 + return new IfOp(x, cond, y, tval, fval); 1.306 +} 1.307 + 1.308 +void Optimizer::eliminate_conditional_expressions() { 1.309 + // find conditional expressions & replace them with IfOps 1.310 + CE_Eliminator ce(ir()); 1.311 +} 1.312 + 1.313 +class BlockMerger: public BlockClosure { 1.314 + private: 1.315 + IR* _hir; 1.316 + int _merge_count; // the number of block pairs successfully merged 1.317 + 1.318 + public: 1.319 + BlockMerger(IR* hir) 1.320 + : _hir(hir) 1.321 + , _merge_count(0) 1.322 + { 1.323 + _hir->iterate_preorder(this); 1.324 + CompileLog* log = _hir->compilation()->log(); 1.325 + if (log != NULL) 1.326 + log->set_context("optimize name='eliminate_blocks'"); 1.327 + } 1.328 + 1.329 + ~BlockMerger() { 1.330 + CompileLog* log = _hir->compilation()->log(); 1.331 + if (log != NULL) 1.332 + log->clear_context(); // skip marker if nothing was printed 1.333 + } 1.334 + 1.335 + bool try_merge(BlockBegin* block) { 1.336 + BlockEnd* end = block->end(); 1.337 + if (end->as_Goto() != NULL) { 1.338 + assert(end->number_of_sux() == 1, "end must have exactly one successor"); 1.339 + // Note: It would be sufficient to check for the number of successors (= 1) 1.340 + // in order to decide if this block can be merged potentially. That 1.341 + // would then also include switch statements w/ only a default case. 1.342 + // However, in that case we would need to make sure the switch tag 1.343 + // expression is executed if it can produce observable side effects. 1.344 + // We should probably have the canonicalizer simplifying such switch 1.345 + // statements and then we are sure we don't miss these merge opportunities 1.346 + // here (was bug - gri 7/7/99). 1.347 + BlockBegin* sux = end->default_sux(); 1.348 + if (sux->number_of_preds() == 1 && !sux->is_entry_block() && !end->is_safepoint()) { 1.349 + // merge the two blocks 1.350 + 1.351 +#ifdef ASSERT 1.352 + // verify that state at the end of block and at the beginning of sux are equal 1.353 + // no phi functions must be present at beginning of sux 1.354 + ValueStack* sux_state = sux->state(); 1.355 + ValueStack* end_state = end->state(); 1.356 + 1.357 + assert(end_state->scope() == sux_state->scope(), "scopes must match"); 1.358 + assert(end_state->stack_size() == sux_state->stack_size(), "stack not equal"); 1.359 + assert(end_state->locals_size() == sux_state->locals_size(), "locals not equal"); 1.360 + 1.361 + int index; 1.362 + Value sux_value; 1.363 + for_each_stack_value(sux_state, index, sux_value) { 1.364 + assert(sux_value == end_state->stack_at(index), "stack not equal"); 1.365 + } 1.366 + for_each_local_value(sux_state, index, sux_value) { 1.367 + assert(sux_value == end_state->local_at(index), "locals not equal"); 1.368 + } 1.369 + assert(sux_state->caller_state() == end_state->caller_state(), "caller not equal"); 1.370 +#endif 1.371 + 1.372 + // find instruction before end & append first instruction of sux block 1.373 + Instruction* prev = end->prev(); 1.374 + Instruction* next = sux->next(); 1.375 + assert(prev->as_BlockEnd() == NULL, "must not be a BlockEnd"); 1.376 + prev->set_next(next); 1.377 + prev->fixup_block_pointers(); 1.378 + sux->disconnect_from_graph(); 1.379 + block->set_end(sux->end()); 1.380 + // add exception handlers of deleted block, if any 1.381 + for (int k = 0; k < sux->number_of_exception_handlers(); k++) { 1.382 + BlockBegin* xhandler = sux->exception_handler_at(k); 1.383 + block->add_exception_handler(xhandler); 1.384 + 1.385 + // also substitute predecessor of exception handler 1.386 + assert(xhandler->is_predecessor(sux), "missing predecessor"); 1.387 + xhandler->remove_predecessor(sux); 1.388 + if (!xhandler->is_predecessor(block)) { 1.389 + xhandler->add_predecessor(block); 1.390 + } 1.391 + } 1.392 + 1.393 + // debugging output 1.394 + _merge_count++; 1.395 + if (PrintBlockElimination) { 1.396 + tty->print_cr("%d. merged B%d & B%d (stack size = %d)", 1.397 + _merge_count, block->block_id(), sux->block_id(), sux->state()->stack_size()); 1.398 + } 1.399 + 1.400 + _hir->verify(); 1.401 + 1.402 + If* if_ = block->end()->as_If(); 1.403 + if (if_) { 1.404 + IfOp* ifop = if_->x()->as_IfOp(); 1.405 + Constant* con = if_->y()->as_Constant(); 1.406 + bool swapped = false; 1.407 + if (!con || !ifop) { 1.408 + ifop = if_->y()->as_IfOp(); 1.409 + con = if_->x()->as_Constant(); 1.410 + swapped = true; 1.411 + } 1.412 + if (con && ifop) { 1.413 + Constant* tval = ifop->tval()->as_Constant(); 1.414 + Constant* fval = ifop->fval()->as_Constant(); 1.415 + if (tval && fval) { 1.416 + // Find the instruction before if_, starting with ifop. 1.417 + // When if_ and ifop are not in the same block, prev 1.418 + // becomes NULL In such (rare) cases it is not 1.419 + // profitable to perform the optimization. 1.420 + Value prev = ifop; 1.421 + while (prev != NULL && prev->next() != if_) { 1.422 + prev = prev->next(); 1.423 + } 1.424 + 1.425 + if (prev != NULL) { 1.426 + Instruction::Condition cond = if_->cond(); 1.427 + BlockBegin* tsux = if_->tsux(); 1.428 + BlockBegin* fsux = if_->fsux(); 1.429 + if (swapped) { 1.430 + cond = Instruction::mirror(cond); 1.431 + } 1.432 + 1.433 + BlockBegin* tblock = tval->compare(cond, con, tsux, fsux); 1.434 + BlockBegin* fblock = fval->compare(cond, con, tsux, fsux); 1.435 + if (tblock != fblock && !if_->is_safepoint()) { 1.436 + If* newif = new If(ifop->x(), ifop->cond(), false, ifop->y(), 1.437 + tblock, fblock, if_->state_before(), if_->is_safepoint()); 1.438 + newif->set_state(if_->state()->copy()); 1.439 + 1.440 + assert(prev->next() == if_, "must be guaranteed by above search"); 1.441 + NOT_PRODUCT(newif->set_printable_bci(if_->printable_bci())); 1.442 + prev->set_next(newif); 1.443 + block->set_end(newif); 1.444 + 1.445 + _merge_count++; 1.446 + if (PrintBlockElimination) { 1.447 + tty->print_cr("%d. replaced If and IfOp at end of B%d with single If", _merge_count, block->block_id()); 1.448 + } 1.449 + 1.450 + _hir->verify(); 1.451 + } 1.452 + } 1.453 + } 1.454 + } 1.455 + } 1.456 + 1.457 + return true; 1.458 + } 1.459 + } 1.460 + return false; 1.461 + } 1.462 + 1.463 + virtual void block_do(BlockBegin* block) { 1.464 + _hir->verify(); 1.465 + // repeat since the same block may merge again 1.466 + while (try_merge(block)) { 1.467 + _hir->verify(); 1.468 + } 1.469 + } 1.470 +}; 1.471 + 1.472 + 1.473 +void Optimizer::eliminate_blocks() { 1.474 + // merge blocks if possible 1.475 + BlockMerger bm(ir()); 1.476 +} 1.477 + 1.478 + 1.479 +class NullCheckEliminator; 1.480 +class NullCheckVisitor: public InstructionVisitor { 1.481 +private: 1.482 + NullCheckEliminator* _nce; 1.483 + NullCheckEliminator* nce() { return _nce; } 1.484 + 1.485 +public: 1.486 + NullCheckVisitor() {} 1.487 + 1.488 + void set_eliminator(NullCheckEliminator* nce) { _nce = nce; } 1.489 + 1.490 + void do_Phi (Phi* x); 1.491 + void do_Local (Local* x); 1.492 + void do_Constant (Constant* x); 1.493 + void do_LoadField (LoadField* x); 1.494 + void do_StoreField (StoreField* x); 1.495 + void do_ArrayLength (ArrayLength* x); 1.496 + void do_LoadIndexed (LoadIndexed* x); 1.497 + void do_StoreIndexed (StoreIndexed* x); 1.498 + void do_NegateOp (NegateOp* x); 1.499 + void do_ArithmeticOp (ArithmeticOp* x); 1.500 + void do_ShiftOp (ShiftOp* x); 1.501 + void do_LogicOp (LogicOp* x); 1.502 + void do_CompareOp (CompareOp* x); 1.503 + void do_IfOp (IfOp* x); 1.504 + void do_Convert (Convert* x); 1.505 + void do_NullCheck (NullCheck* x); 1.506 + void do_TypeCast (TypeCast* x); 1.507 + void do_Invoke (Invoke* x); 1.508 + void do_NewInstance (NewInstance* x); 1.509 + void do_NewTypeArray (NewTypeArray* x); 1.510 + void do_NewObjectArray (NewObjectArray* x); 1.511 + void do_NewMultiArray (NewMultiArray* x); 1.512 + void do_CheckCast (CheckCast* x); 1.513 + void do_InstanceOf (InstanceOf* x); 1.514 + void do_MonitorEnter (MonitorEnter* x); 1.515 + void do_MonitorExit (MonitorExit* x); 1.516 + void do_Intrinsic (Intrinsic* x); 1.517 + void do_BlockBegin (BlockBegin* x); 1.518 + void do_Goto (Goto* x); 1.519 + void do_If (If* x); 1.520 + void do_IfInstanceOf (IfInstanceOf* x); 1.521 + void do_TableSwitch (TableSwitch* x); 1.522 + void do_LookupSwitch (LookupSwitch* x); 1.523 + void do_Return (Return* x); 1.524 + void do_Throw (Throw* x); 1.525 + void do_Base (Base* x); 1.526 + void do_OsrEntry (OsrEntry* x); 1.527 + void do_ExceptionObject(ExceptionObject* x); 1.528 + void do_RoundFP (RoundFP* x); 1.529 + void do_UnsafeGetRaw (UnsafeGetRaw* x); 1.530 + void do_UnsafePutRaw (UnsafePutRaw* x); 1.531 + void do_UnsafeGetObject(UnsafeGetObject* x); 1.532 + void do_UnsafePutObject(UnsafePutObject* x); 1.533 + void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x); 1.534 + void do_UnsafePrefetchRead (UnsafePrefetchRead* x); 1.535 + void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); 1.536 + void do_ProfileCall (ProfileCall* x); 1.537 + void do_ProfileReturnType (ProfileReturnType* x); 1.538 + void do_ProfileInvoke (ProfileInvoke* x); 1.539 + void do_RuntimeCall (RuntimeCall* x); 1.540 + void do_MemBar (MemBar* x); 1.541 + void do_RangeCheckPredicate(RangeCheckPredicate* x); 1.542 +#ifdef ASSERT 1.543 + void do_Assert (Assert* x); 1.544 +#endif 1.545 +}; 1.546 + 1.547 + 1.548 +// Because of a static contained within (for the purpose of iteration 1.549 +// over instructions), it is only valid to have one of these active at 1.550 +// a time 1.551 +class NullCheckEliminator: public ValueVisitor { 1.552 + private: 1.553 + Optimizer* _opt; 1.554 + 1.555 + ValueSet* _visitable_instructions; // Visit each instruction only once per basic block 1.556 + BlockList* _work_list; // Basic blocks to visit 1.557 + 1.558 + bool visitable(Value x) { 1.559 + assert(_visitable_instructions != NULL, "check"); 1.560 + return _visitable_instructions->contains(x); 1.561 + } 1.562 + void mark_visited(Value x) { 1.563 + assert(_visitable_instructions != NULL, "check"); 1.564 + _visitable_instructions->remove(x); 1.565 + } 1.566 + void mark_visitable(Value x) { 1.567 + assert(_visitable_instructions != NULL, "check"); 1.568 + _visitable_instructions->put(x); 1.569 + } 1.570 + void clear_visitable_state() { 1.571 + assert(_visitable_instructions != NULL, "check"); 1.572 + _visitable_instructions->clear(); 1.573 + } 1.574 + 1.575 + ValueSet* _set; // current state, propagated to subsequent BlockBegins 1.576 + ValueSetList _block_states; // BlockBegin null-check states for all processed blocks 1.577 + NullCheckVisitor _visitor; 1.578 + NullCheck* _last_explicit_null_check; 1.579 + 1.580 + bool set_contains(Value x) { assert(_set != NULL, "check"); return _set->contains(x); } 1.581 + void set_put (Value x) { assert(_set != NULL, "check"); _set->put(x); } 1.582 + void set_remove (Value x) { assert(_set != NULL, "check"); _set->remove(x); } 1.583 + 1.584 + BlockList* work_list() { return _work_list; } 1.585 + 1.586 + void iterate_all(); 1.587 + void iterate_one(BlockBegin* block); 1.588 + 1.589 + ValueSet* state() { return _set; } 1.590 + void set_state_from (ValueSet* state) { _set->set_from(state); } 1.591 + ValueSet* state_for (BlockBegin* block) { return _block_states[block->block_id()]; } 1.592 + void set_state_for (BlockBegin* block, ValueSet* stack) { _block_states[block->block_id()] = stack; } 1.593 + // Returns true if caused a change in the block's state. 1.594 + bool merge_state_for(BlockBegin* block, 1.595 + ValueSet* incoming_state); 1.596 + 1.597 + public: 1.598 + // constructor 1.599 + NullCheckEliminator(Optimizer* opt) 1.600 + : _opt(opt) 1.601 + , _set(new ValueSet()) 1.602 + , _last_explicit_null_check(NULL) 1.603 + , _block_states(BlockBegin::number_of_blocks(), NULL) 1.604 + , _work_list(new BlockList()) { 1.605 + _visitable_instructions = new ValueSet(); 1.606 + _visitor.set_eliminator(this); 1.607 + CompileLog* log = _opt->ir()->compilation()->log(); 1.608 + if (log != NULL) 1.609 + log->set_context("optimize name='null_check_elimination'"); 1.610 + } 1.611 + 1.612 + ~NullCheckEliminator() { 1.613 + CompileLog* log = _opt->ir()->compilation()->log(); 1.614 + if (log != NULL) 1.615 + log->clear_context(); // skip marker if nothing was printed 1.616 + } 1.617 + 1.618 + Optimizer* opt() { return _opt; } 1.619 + IR* ir () { return opt()->ir(); } 1.620 + 1.621 + // Process a graph 1.622 + void iterate(BlockBegin* root); 1.623 + 1.624 + void visit(Value* f); 1.625 + 1.626 + // In some situations (like NullCheck(x); getfield(x)) the debug 1.627 + // information from the explicit NullCheck can be used to populate 1.628 + // the getfield, even if the two instructions are in different 1.629 + // scopes; this allows implicit null checks to be used but the 1.630 + // correct exception information to be generated. We must clear the 1.631 + // last-traversed NullCheck when we reach a potentially-exception- 1.632 + // throwing instruction, as well as in some other cases. 1.633 + void set_last_explicit_null_check(NullCheck* check) { _last_explicit_null_check = check; } 1.634 + NullCheck* last_explicit_null_check() { return _last_explicit_null_check; } 1.635 + Value last_explicit_null_check_obj() { return (_last_explicit_null_check 1.636 + ? _last_explicit_null_check->obj() 1.637 + : NULL); } 1.638 + NullCheck* consume_last_explicit_null_check() { 1.639 + _last_explicit_null_check->unpin(Instruction::PinExplicitNullCheck); 1.640 + _last_explicit_null_check->set_can_trap(false); 1.641 + return _last_explicit_null_check; 1.642 + } 1.643 + void clear_last_explicit_null_check() { _last_explicit_null_check = NULL; } 1.644 + 1.645 + // Handlers for relevant instructions 1.646 + // (separated out from NullCheckVisitor for clarity) 1.647 + 1.648 + // The basic contract is that these must leave the instruction in 1.649 + // the desired state; must not assume anything about the state of 1.650 + // the instruction. We make multiple passes over some basic blocks 1.651 + // and the last pass is the only one whose result is valid. 1.652 + void handle_AccessField (AccessField* x); 1.653 + void handle_ArrayLength (ArrayLength* x); 1.654 + void handle_LoadIndexed (LoadIndexed* x); 1.655 + void handle_StoreIndexed (StoreIndexed* x); 1.656 + void handle_NullCheck (NullCheck* x); 1.657 + void handle_Invoke (Invoke* x); 1.658 + void handle_NewInstance (NewInstance* x); 1.659 + void handle_NewArray (NewArray* x); 1.660 + void handle_AccessMonitor (AccessMonitor* x); 1.661 + void handle_Intrinsic (Intrinsic* x); 1.662 + void handle_ExceptionObject (ExceptionObject* x); 1.663 + void handle_Phi (Phi* x); 1.664 + void handle_ProfileCall (ProfileCall* x); 1.665 + void handle_ProfileReturnType (ProfileReturnType* x); 1.666 +}; 1.667 + 1.668 + 1.669 +// NEEDS_CLEANUP 1.670 +// There may be other instructions which need to clear the last 1.671 +// explicit null check. Anything across which we can not hoist the 1.672 +// debug information for a NullCheck instruction must clear it. It 1.673 +// might be safer to pattern match "NullCheck ; {AccessField, 1.674 +// ArrayLength, LoadIndexed}" but it is more easily structured this way. 1.675 +// Should test to see performance hit of clearing it for all handlers 1.676 +// with empty bodies below. If it is negligible then we should leave 1.677 +// that in for safety, otherwise should think more about it. 1.678 +void NullCheckVisitor::do_Phi (Phi* x) { nce()->handle_Phi(x); } 1.679 +void NullCheckVisitor::do_Local (Local* x) {} 1.680 +void NullCheckVisitor::do_Constant (Constant* x) { /* FIXME: handle object constants */ } 1.681 +void NullCheckVisitor::do_LoadField (LoadField* x) { nce()->handle_AccessField(x); } 1.682 +void NullCheckVisitor::do_StoreField (StoreField* x) { nce()->handle_AccessField(x); } 1.683 +void NullCheckVisitor::do_ArrayLength (ArrayLength* x) { nce()->handle_ArrayLength(x); } 1.684 +void NullCheckVisitor::do_LoadIndexed (LoadIndexed* x) { nce()->handle_LoadIndexed(x); } 1.685 +void NullCheckVisitor::do_StoreIndexed (StoreIndexed* x) { nce()->handle_StoreIndexed(x); } 1.686 +void NullCheckVisitor::do_NegateOp (NegateOp* x) {} 1.687 +void NullCheckVisitor::do_ArithmeticOp (ArithmeticOp* x) { if (x->can_trap()) nce()->clear_last_explicit_null_check(); } 1.688 +void NullCheckVisitor::do_ShiftOp (ShiftOp* x) {} 1.689 +void NullCheckVisitor::do_LogicOp (LogicOp* x) {} 1.690 +void NullCheckVisitor::do_CompareOp (CompareOp* x) {} 1.691 +void NullCheckVisitor::do_IfOp (IfOp* x) {} 1.692 +void NullCheckVisitor::do_Convert (Convert* x) {} 1.693 +void NullCheckVisitor::do_NullCheck (NullCheck* x) { nce()->handle_NullCheck(x); } 1.694 +void NullCheckVisitor::do_TypeCast (TypeCast* x) {} 1.695 +void NullCheckVisitor::do_Invoke (Invoke* x) { nce()->handle_Invoke(x); } 1.696 +void NullCheckVisitor::do_NewInstance (NewInstance* x) { nce()->handle_NewInstance(x); } 1.697 +void NullCheckVisitor::do_NewTypeArray (NewTypeArray* x) { nce()->handle_NewArray(x); } 1.698 +void NullCheckVisitor::do_NewObjectArray (NewObjectArray* x) { nce()->handle_NewArray(x); } 1.699 +void NullCheckVisitor::do_NewMultiArray (NewMultiArray* x) { nce()->handle_NewArray(x); } 1.700 +void NullCheckVisitor::do_CheckCast (CheckCast* x) { nce()->clear_last_explicit_null_check(); } 1.701 +void NullCheckVisitor::do_InstanceOf (InstanceOf* x) {} 1.702 +void NullCheckVisitor::do_MonitorEnter (MonitorEnter* x) { nce()->handle_AccessMonitor(x); } 1.703 +void NullCheckVisitor::do_MonitorExit (MonitorExit* x) { nce()->handle_AccessMonitor(x); } 1.704 +void NullCheckVisitor::do_Intrinsic (Intrinsic* x) { nce()->handle_Intrinsic(x); } 1.705 +void NullCheckVisitor::do_BlockBegin (BlockBegin* x) {} 1.706 +void NullCheckVisitor::do_Goto (Goto* x) {} 1.707 +void NullCheckVisitor::do_If (If* x) {} 1.708 +void NullCheckVisitor::do_IfInstanceOf (IfInstanceOf* x) {} 1.709 +void NullCheckVisitor::do_TableSwitch (TableSwitch* x) {} 1.710 +void NullCheckVisitor::do_LookupSwitch (LookupSwitch* x) {} 1.711 +void NullCheckVisitor::do_Return (Return* x) {} 1.712 +void NullCheckVisitor::do_Throw (Throw* x) { nce()->clear_last_explicit_null_check(); } 1.713 +void NullCheckVisitor::do_Base (Base* x) {} 1.714 +void NullCheckVisitor::do_OsrEntry (OsrEntry* x) {} 1.715 +void NullCheckVisitor::do_ExceptionObject(ExceptionObject* x) { nce()->handle_ExceptionObject(x); } 1.716 +void NullCheckVisitor::do_RoundFP (RoundFP* x) {} 1.717 +void NullCheckVisitor::do_UnsafeGetRaw (UnsafeGetRaw* x) {} 1.718 +void NullCheckVisitor::do_UnsafePutRaw (UnsafePutRaw* x) {} 1.719 +void NullCheckVisitor::do_UnsafeGetObject(UnsafeGetObject* x) {} 1.720 +void NullCheckVisitor::do_UnsafePutObject(UnsafePutObject* x) {} 1.721 +void NullCheckVisitor::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {} 1.722 +void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {} 1.723 +void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} 1.724 +void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); 1.725 + nce()->handle_ProfileCall(x); } 1.726 +void NullCheckVisitor::do_ProfileReturnType (ProfileReturnType* x) { nce()->handle_ProfileReturnType(x); } 1.727 +void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {} 1.728 +void NullCheckVisitor::do_RuntimeCall (RuntimeCall* x) {} 1.729 +void NullCheckVisitor::do_MemBar (MemBar* x) {} 1.730 +void NullCheckVisitor::do_RangeCheckPredicate(RangeCheckPredicate* x) {} 1.731 +#ifdef ASSERT 1.732 +void NullCheckVisitor::do_Assert (Assert* x) {} 1.733 +#endif 1.734 + 1.735 +void NullCheckEliminator::visit(Value* p) { 1.736 + assert(*p != NULL, "should not find NULL instructions"); 1.737 + if (visitable(*p)) { 1.738 + mark_visited(*p); 1.739 + (*p)->visit(&_visitor); 1.740 + } 1.741 +} 1.742 + 1.743 +bool NullCheckEliminator::merge_state_for(BlockBegin* block, ValueSet* incoming_state) { 1.744 + ValueSet* state = state_for(block); 1.745 + if (state == NULL) { 1.746 + state = incoming_state->copy(); 1.747 + set_state_for(block, state); 1.748 + return true; 1.749 + } else { 1.750 + bool changed = state->set_intersect(incoming_state); 1.751 + if (PrintNullCheckElimination && changed) { 1.752 + tty->print_cr("Block %d's null check state changed", block->block_id()); 1.753 + } 1.754 + return changed; 1.755 + } 1.756 +} 1.757 + 1.758 + 1.759 +void NullCheckEliminator::iterate_all() { 1.760 + while (work_list()->length() > 0) { 1.761 + iterate_one(work_list()->pop()); 1.762 + } 1.763 +} 1.764 + 1.765 + 1.766 +void NullCheckEliminator::iterate_one(BlockBegin* block) { 1.767 + clear_visitable_state(); 1.768 + // clear out an old explicit null checks 1.769 + set_last_explicit_null_check(NULL); 1.770 + 1.771 + if (PrintNullCheckElimination) { 1.772 + tty->print_cr(" ...iterating block %d in null check elimination for %s::%s%s", 1.773 + block->block_id(), 1.774 + ir()->method()->holder()->name()->as_utf8(), 1.775 + ir()->method()->name()->as_utf8(), 1.776 + ir()->method()->signature()->as_symbol()->as_utf8()); 1.777 + } 1.778 + 1.779 + // Create new state if none present (only happens at root) 1.780 + if (state_for(block) == NULL) { 1.781 + ValueSet* tmp_state = new ValueSet(); 1.782 + set_state_for(block, tmp_state); 1.783 + // Initial state is that local 0 (receiver) is non-null for 1.784 + // non-static methods 1.785 + ValueStack* stack = block->state(); 1.786 + IRScope* scope = stack->scope(); 1.787 + ciMethod* method = scope->method(); 1.788 + if (!method->is_static()) { 1.789 + Local* local0 = stack->local_at(0)->as_Local(); 1.790 + assert(local0 != NULL, "must be"); 1.791 + assert(local0->type() == objectType, "invalid type of receiver"); 1.792 + 1.793 + if (local0 != NULL) { 1.794 + // Local 0 is used in this scope 1.795 + tmp_state->put(local0); 1.796 + if (PrintNullCheckElimination) { 1.797 + tty->print_cr("Local 0 (value %d) proven non-null upon entry", local0->id()); 1.798 + } 1.799 + } 1.800 + } 1.801 + } 1.802 + 1.803 + // Must copy block's state to avoid mutating it during iteration 1.804 + // through the block -- otherwise "not-null" states can accidentally 1.805 + // propagate "up" through the block during processing of backward 1.806 + // branches and algorithm is incorrect (and does not converge) 1.807 + set_state_from(state_for(block)); 1.808 + 1.809 + // allow visiting of Phis belonging to this block 1.810 + for_each_phi_fun(block, phi, 1.811 + mark_visitable(phi); 1.812 + ); 1.813 + 1.814 + BlockEnd* e = block->end(); 1.815 + assert(e != NULL, "incomplete graph"); 1.816 + int i; 1.817 + 1.818 + // Propagate the state before this block into the exception 1.819 + // handlers. They aren't true successors since we aren't guaranteed 1.820 + // to execute the whole block before executing them. Also putting 1.821 + // them on first seems to help reduce the amount of iteration to 1.822 + // reach a fixed point. 1.823 + for (i = 0; i < block->number_of_exception_handlers(); i++) { 1.824 + BlockBegin* next = block->exception_handler_at(i); 1.825 + if (merge_state_for(next, state())) { 1.826 + if (!work_list()->contains(next)) { 1.827 + work_list()->push(next); 1.828 + } 1.829 + } 1.830 + } 1.831 + 1.832 + // Iterate through block, updating state. 1.833 + for (Instruction* instr = block; instr != NULL; instr = instr->next()) { 1.834 + // Mark instructions in this block as visitable as they are seen 1.835 + // in the instruction list. This keeps the iteration from 1.836 + // visiting instructions which are references in other blocks or 1.837 + // visiting instructions more than once. 1.838 + mark_visitable(instr); 1.839 + if (instr->is_pinned() || instr->can_trap() || (instr->as_NullCheck() != NULL)) { 1.840 + mark_visited(instr); 1.841 + instr->input_values_do(this); 1.842 + instr->visit(&_visitor); 1.843 + } 1.844 + } 1.845 + 1.846 + // Propagate state to successors if necessary 1.847 + for (i = 0; i < e->number_of_sux(); i++) { 1.848 + BlockBegin* next = e->sux_at(i); 1.849 + if (merge_state_for(next, state())) { 1.850 + if (!work_list()->contains(next)) { 1.851 + work_list()->push(next); 1.852 + } 1.853 + } 1.854 + } 1.855 +} 1.856 + 1.857 + 1.858 +void NullCheckEliminator::iterate(BlockBegin* block) { 1.859 + work_list()->push(block); 1.860 + iterate_all(); 1.861 +} 1.862 + 1.863 +void NullCheckEliminator::handle_AccessField(AccessField* x) { 1.864 + if (x->is_static()) { 1.865 + if (x->as_LoadField() != NULL) { 1.866 + // If the field is a non-null static final object field (as is 1.867 + // often the case for sun.misc.Unsafe), put this LoadField into 1.868 + // the non-null map 1.869 + ciField* field = x->field(); 1.870 + if (field->is_constant()) { 1.871 + ciConstant field_val = field->constant_value(); 1.872 + BasicType field_type = field_val.basic_type(); 1.873 + if (field_type == T_OBJECT || field_type == T_ARRAY) { 1.874 + ciObject* obj_val = field_val.as_object(); 1.875 + if (!obj_val->is_null_object()) { 1.876 + if (PrintNullCheckElimination) { 1.877 + tty->print_cr("AccessField %d proven non-null by static final non-null oop check", 1.878 + x->id()); 1.879 + } 1.880 + set_put(x); 1.881 + } 1.882 + } 1.883 + } 1.884 + } 1.885 + // Be conservative 1.886 + clear_last_explicit_null_check(); 1.887 + return; 1.888 + } 1.889 + 1.890 + Value obj = x->obj(); 1.891 + if (set_contains(obj)) { 1.892 + // Value is non-null => update AccessField 1.893 + if (last_explicit_null_check_obj() == obj && !x->needs_patching()) { 1.894 + x->set_explicit_null_check(consume_last_explicit_null_check()); 1.895 + x->set_needs_null_check(true); 1.896 + if (PrintNullCheckElimination) { 1.897 + tty->print_cr("Folded NullCheck %d into AccessField %d's null check for value %d", 1.898 + x->explicit_null_check()->id(), x->id(), obj->id()); 1.899 + } 1.900 + } else { 1.901 + x->set_explicit_null_check(NULL); 1.902 + x->set_needs_null_check(false); 1.903 + if (PrintNullCheckElimination) { 1.904 + tty->print_cr("Eliminated AccessField %d's null check for value %d", x->id(), obj->id()); 1.905 + } 1.906 + } 1.907 + } else { 1.908 + set_put(obj); 1.909 + if (PrintNullCheckElimination) { 1.910 + tty->print_cr("AccessField %d of value %d proves value to be non-null", x->id(), obj->id()); 1.911 + } 1.912 + // Ensure previous passes do not cause wrong state 1.913 + x->set_needs_null_check(true); 1.914 + x->set_explicit_null_check(NULL); 1.915 + } 1.916 + clear_last_explicit_null_check(); 1.917 +} 1.918 + 1.919 + 1.920 +void NullCheckEliminator::handle_ArrayLength(ArrayLength* x) { 1.921 + Value array = x->array(); 1.922 + if (set_contains(array)) { 1.923 + // Value is non-null => update AccessArray 1.924 + if (last_explicit_null_check_obj() == array) { 1.925 + x->set_explicit_null_check(consume_last_explicit_null_check()); 1.926 + x->set_needs_null_check(true); 1.927 + if (PrintNullCheckElimination) { 1.928 + tty->print_cr("Folded NullCheck %d into ArrayLength %d's null check for value %d", 1.929 + x->explicit_null_check()->id(), x->id(), array->id()); 1.930 + } 1.931 + } else { 1.932 + x->set_explicit_null_check(NULL); 1.933 + x->set_needs_null_check(false); 1.934 + if (PrintNullCheckElimination) { 1.935 + tty->print_cr("Eliminated ArrayLength %d's null check for value %d", x->id(), array->id()); 1.936 + } 1.937 + } 1.938 + } else { 1.939 + set_put(array); 1.940 + if (PrintNullCheckElimination) { 1.941 + tty->print_cr("ArrayLength %d of value %d proves value to be non-null", x->id(), array->id()); 1.942 + } 1.943 + // Ensure previous passes do not cause wrong state 1.944 + x->set_needs_null_check(true); 1.945 + x->set_explicit_null_check(NULL); 1.946 + } 1.947 + clear_last_explicit_null_check(); 1.948 +} 1.949 + 1.950 + 1.951 +void NullCheckEliminator::handle_LoadIndexed(LoadIndexed* x) { 1.952 + Value array = x->array(); 1.953 + if (set_contains(array)) { 1.954 + // Value is non-null => update AccessArray 1.955 + if (last_explicit_null_check_obj() == array) { 1.956 + x->set_explicit_null_check(consume_last_explicit_null_check()); 1.957 + x->set_needs_null_check(true); 1.958 + if (PrintNullCheckElimination) { 1.959 + tty->print_cr("Folded NullCheck %d into LoadIndexed %d's null check for value %d", 1.960 + x->explicit_null_check()->id(), x->id(), array->id()); 1.961 + } 1.962 + } else { 1.963 + x->set_explicit_null_check(NULL); 1.964 + x->set_needs_null_check(false); 1.965 + if (PrintNullCheckElimination) { 1.966 + tty->print_cr("Eliminated LoadIndexed %d's null check for value %d", x->id(), array->id()); 1.967 + } 1.968 + } 1.969 + } else { 1.970 + set_put(array); 1.971 + if (PrintNullCheckElimination) { 1.972 + tty->print_cr("LoadIndexed %d of value %d proves value to be non-null", x->id(), array->id()); 1.973 + } 1.974 + // Ensure previous passes do not cause wrong state 1.975 + x->set_needs_null_check(true); 1.976 + x->set_explicit_null_check(NULL); 1.977 + } 1.978 + clear_last_explicit_null_check(); 1.979 +} 1.980 + 1.981 + 1.982 +void NullCheckEliminator::handle_StoreIndexed(StoreIndexed* x) { 1.983 + Value array = x->array(); 1.984 + if (set_contains(array)) { 1.985 + // Value is non-null => update AccessArray 1.986 + if (PrintNullCheckElimination) { 1.987 + tty->print_cr("Eliminated StoreIndexed %d's null check for value %d", x->id(), array->id()); 1.988 + } 1.989 + x->set_needs_null_check(false); 1.990 + } else { 1.991 + set_put(array); 1.992 + if (PrintNullCheckElimination) { 1.993 + tty->print_cr("StoreIndexed %d of value %d proves value to be non-null", x->id(), array->id()); 1.994 + } 1.995 + // Ensure previous passes do not cause wrong state 1.996 + x->set_needs_null_check(true); 1.997 + } 1.998 + clear_last_explicit_null_check(); 1.999 +} 1.1000 + 1.1001 + 1.1002 +void NullCheckEliminator::handle_NullCheck(NullCheck* x) { 1.1003 + Value obj = x->obj(); 1.1004 + if (set_contains(obj)) { 1.1005 + // Already proven to be non-null => this NullCheck is useless 1.1006 + if (PrintNullCheckElimination) { 1.1007 + tty->print_cr("Eliminated NullCheck %d for value %d", x->id(), obj->id()); 1.1008 + } 1.1009 + // Don't unpin since that may shrink obj's live range and make it unavailable for debug info. 1.1010 + // The code generator won't emit LIR for a NullCheck that cannot trap. 1.1011 + x->set_can_trap(false); 1.1012 + } else { 1.1013 + // May be null => add to map and set last explicit NullCheck 1.1014 + x->set_can_trap(true); 1.1015 + // make sure it's pinned if it can trap 1.1016 + x->pin(Instruction::PinExplicitNullCheck); 1.1017 + set_put(obj); 1.1018 + set_last_explicit_null_check(x); 1.1019 + if (PrintNullCheckElimination) { 1.1020 + tty->print_cr("NullCheck %d of value %d proves value to be non-null", x->id(), obj->id()); 1.1021 + } 1.1022 + } 1.1023 +} 1.1024 + 1.1025 + 1.1026 +void NullCheckEliminator::handle_Invoke(Invoke* x) { 1.1027 + if (!x->has_receiver()) { 1.1028 + // Be conservative 1.1029 + clear_last_explicit_null_check(); 1.1030 + return; 1.1031 + } 1.1032 + 1.1033 + Value recv = x->receiver(); 1.1034 + if (!set_contains(recv)) { 1.1035 + set_put(recv); 1.1036 + if (PrintNullCheckElimination) { 1.1037 + tty->print_cr("Invoke %d of value %d proves value to be non-null", x->id(), recv->id()); 1.1038 + } 1.1039 + } 1.1040 + clear_last_explicit_null_check(); 1.1041 +} 1.1042 + 1.1043 + 1.1044 +void NullCheckEliminator::handle_NewInstance(NewInstance* x) { 1.1045 + set_put(x); 1.1046 + if (PrintNullCheckElimination) { 1.1047 + tty->print_cr("NewInstance %d is non-null", x->id()); 1.1048 + } 1.1049 +} 1.1050 + 1.1051 + 1.1052 +void NullCheckEliminator::handle_NewArray(NewArray* x) { 1.1053 + set_put(x); 1.1054 + if (PrintNullCheckElimination) { 1.1055 + tty->print_cr("NewArray %d is non-null", x->id()); 1.1056 + } 1.1057 +} 1.1058 + 1.1059 + 1.1060 +void NullCheckEliminator::handle_ExceptionObject(ExceptionObject* x) { 1.1061 + set_put(x); 1.1062 + if (PrintNullCheckElimination) { 1.1063 + tty->print_cr("ExceptionObject %d is non-null", x->id()); 1.1064 + } 1.1065 +} 1.1066 + 1.1067 + 1.1068 +void NullCheckEliminator::handle_AccessMonitor(AccessMonitor* x) { 1.1069 + Value obj = x->obj(); 1.1070 + if (set_contains(obj)) { 1.1071 + // Value is non-null => update AccessMonitor 1.1072 + if (PrintNullCheckElimination) { 1.1073 + tty->print_cr("Eliminated AccessMonitor %d's null check for value %d", x->id(), obj->id()); 1.1074 + } 1.1075 + x->set_needs_null_check(false); 1.1076 + } else { 1.1077 + set_put(obj); 1.1078 + if (PrintNullCheckElimination) { 1.1079 + tty->print_cr("AccessMonitor %d of value %d proves value to be non-null", x->id(), obj->id()); 1.1080 + } 1.1081 + // Ensure previous passes do not cause wrong state 1.1082 + x->set_needs_null_check(true); 1.1083 + } 1.1084 + clear_last_explicit_null_check(); 1.1085 +} 1.1086 + 1.1087 + 1.1088 +void NullCheckEliminator::handle_Intrinsic(Intrinsic* x) { 1.1089 + if (!x->has_receiver()) { 1.1090 + if (x->id() == vmIntrinsics::_arraycopy) { 1.1091 + for (int i = 0; i < x->number_of_arguments(); i++) { 1.1092 + x->set_arg_needs_null_check(i, !set_contains(x->argument_at(i))); 1.1093 + } 1.1094 + } 1.1095 + 1.1096 + // Be conservative 1.1097 + clear_last_explicit_null_check(); 1.1098 + return; 1.1099 + } 1.1100 + 1.1101 + Value recv = x->receiver(); 1.1102 + if (set_contains(recv)) { 1.1103 + // Value is non-null => update Intrinsic 1.1104 + if (PrintNullCheckElimination) { 1.1105 + tty->print_cr("Eliminated Intrinsic %d's null check for value %d", x->id(), recv->id()); 1.1106 + } 1.1107 + x->set_needs_null_check(false); 1.1108 + } else { 1.1109 + set_put(recv); 1.1110 + if (PrintNullCheckElimination) { 1.1111 + tty->print_cr("Intrinsic %d of value %d proves value to be non-null", x->id(), recv->id()); 1.1112 + } 1.1113 + // Ensure previous passes do not cause wrong state 1.1114 + x->set_needs_null_check(true); 1.1115 + } 1.1116 + clear_last_explicit_null_check(); 1.1117 +} 1.1118 + 1.1119 + 1.1120 +void NullCheckEliminator::handle_Phi(Phi* x) { 1.1121 + int i; 1.1122 + bool all_non_null = true; 1.1123 + if (x->is_illegal()) { 1.1124 + all_non_null = false; 1.1125 + } else { 1.1126 + for (i = 0; i < x->operand_count(); i++) { 1.1127 + Value input = x->operand_at(i); 1.1128 + if (!set_contains(input)) { 1.1129 + all_non_null = false; 1.1130 + } 1.1131 + } 1.1132 + } 1.1133 + 1.1134 + if (all_non_null) { 1.1135 + // Value is non-null => update Phi 1.1136 + if (PrintNullCheckElimination) { 1.1137 + tty->print_cr("Eliminated Phi %d's null check for phifun because all inputs are non-null", x->id()); 1.1138 + } 1.1139 + x->set_needs_null_check(false); 1.1140 + } else if (set_contains(x)) { 1.1141 + set_remove(x); 1.1142 + } 1.1143 +} 1.1144 + 1.1145 +void NullCheckEliminator::handle_ProfileCall(ProfileCall* x) { 1.1146 + for (int i = 0; i < x->nb_profiled_args(); i++) { 1.1147 + x->set_arg_needs_null_check(i, !set_contains(x->profiled_arg_at(i))); 1.1148 + } 1.1149 +} 1.1150 + 1.1151 +void NullCheckEliminator::handle_ProfileReturnType(ProfileReturnType* x) { 1.1152 + x->set_needs_null_check(!set_contains(x->ret())); 1.1153 +} 1.1154 + 1.1155 +void Optimizer::eliminate_null_checks() { 1.1156 + ResourceMark rm; 1.1157 + 1.1158 + NullCheckEliminator nce(this); 1.1159 + 1.1160 + if (PrintNullCheckElimination) { 1.1161 + tty->print_cr("Starting null check elimination for method %s::%s%s", 1.1162 + ir()->method()->holder()->name()->as_utf8(), 1.1163 + ir()->method()->name()->as_utf8(), 1.1164 + ir()->method()->signature()->as_symbol()->as_utf8()); 1.1165 + } 1.1166 + 1.1167 + // Apply to graph 1.1168 + nce.iterate(ir()->start()); 1.1169 + 1.1170 + // walk over the graph looking for exception 1.1171 + // handlers and iterate over them as well 1.1172 + int nblocks = BlockBegin::number_of_blocks(); 1.1173 + BlockList blocks(nblocks); 1.1174 + boolArray visited_block(nblocks, false); 1.1175 + 1.1176 + blocks.push(ir()->start()); 1.1177 + visited_block[ir()->start()->block_id()] = true; 1.1178 + for (int i = 0; i < blocks.length(); i++) { 1.1179 + BlockBegin* b = blocks[i]; 1.1180 + // exception handlers need to be treated as additional roots 1.1181 + for (int e = b->number_of_exception_handlers(); e-- > 0; ) { 1.1182 + BlockBegin* excp = b->exception_handler_at(e); 1.1183 + int id = excp->block_id(); 1.1184 + if (!visited_block[id]) { 1.1185 + blocks.push(excp); 1.1186 + visited_block[id] = true; 1.1187 + nce.iterate(excp); 1.1188 + } 1.1189 + } 1.1190 + // traverse successors 1.1191 + BlockEnd *end = b->end(); 1.1192 + for (int s = end->number_of_sux(); s-- > 0; ) { 1.1193 + BlockBegin* next = end->sux_at(s); 1.1194 + int id = next->block_id(); 1.1195 + if (!visited_block[id]) { 1.1196 + blocks.push(next); 1.1197 + visited_block[id] = true; 1.1198 + } 1.1199 + } 1.1200 + } 1.1201 + 1.1202 + 1.1203 + if (PrintNullCheckElimination) { 1.1204 + tty->print_cr("Done with null check elimination for method %s::%s%s", 1.1205 + ir()->method()->holder()->name()->as_utf8(), 1.1206 + ir()->method()->name()->as_utf8(), 1.1207 + ir()->method()->signature()->as_symbol()->as_utf8()); 1.1208 + } 1.1209 +}