Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/c1/c1_Optimizer.cpp
32285 views
/*1* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "c1/c1_Canonicalizer.hpp"26#include "c1/c1_Optimizer.hpp"27#include "c1/c1_ValueMap.hpp"28#include "c1/c1_ValueSet.hpp"29#include "c1/c1_ValueStack.hpp"30#include "utilities/bitMap.inline.hpp"31#include "compiler/compileLog.hpp"3233define_array(ValueSetArray, ValueSet*);34define_stack(ValueSetList, ValueSetArray);353637Optimizer::Optimizer(IR* ir) {38assert(ir->is_valid(), "IR must be valid");39_ir = ir;40}4142class CE_Eliminator: public BlockClosure {43private:44IR* _hir;45int _cee_count; // the number of CEs successfully eliminated46int _ifop_count; // the number of IfOps successfully simplified47int _has_substitution;4849public:50CE_Eliminator(IR* hir) : _cee_count(0), _ifop_count(0), _hir(hir) {51_has_substitution = false;52_hir->iterate_preorder(this);53if (_has_substitution) {54// substituted some ifops/phis, so resolve the substitution55SubstitutionResolver sr(_hir);56}5758CompileLog* log = _hir->compilation()->log();59if (log != NULL)60log->set_context("optimize name='cee'");61}6263~CE_Eliminator() {64CompileLog* log = _hir->compilation()->log();65if (log != NULL)66log->clear_context(); // skip marker if nothing was printed67}6869int cee_count() const { return _cee_count; }70int ifop_count() const { return _ifop_count; }7172void adjust_exception_edges(BlockBegin* block, BlockBegin* sux) {73int e = sux->number_of_exception_handlers();74for (int i = 0; i < e; i++) {75BlockBegin* xhandler = sux->exception_handler_at(i);76block->add_exception_handler(xhandler);7778assert(xhandler->is_predecessor(sux), "missing predecessor");79if (sux->number_of_preds() == 0) {80// sux is disconnected from graph so disconnect from exception handlers81xhandler->remove_predecessor(sux);82}83if (!xhandler->is_predecessor(block)) {84xhandler->add_predecessor(block);85}86}87}8889virtual void block_do(BlockBegin* block);9091private:92Value make_ifop(Value x, Instruction::Condition cond, Value y, Value tval, Value fval);93};9495void CE_Eliminator::block_do(BlockBegin* block) {96// 1) find conditional expression97// check if block ends with an If98If* if_ = block->end()->as_If();99if (if_ == NULL) return;100101// check if If works on int or object types102// (we cannot handle If's working on long, float or doubles yet,103// since IfOp doesn't support them - these If's show up if cmp104// operations followed by If's are eliminated)105ValueType* if_type = if_->x()->type();106if (!if_type->is_int() && !if_type->is_object()) return;107108BlockBegin* t_block = if_->tsux();109BlockBegin* f_block = if_->fsux();110Instruction* t_cur = t_block->next();111Instruction* f_cur = f_block->next();112113// one Constant may be present between BlockBegin and BlockEnd114Value t_const = NULL;115Value f_const = NULL;116if (t_cur->as_Constant() != NULL && !t_cur->can_trap()) {117t_const = t_cur;118t_cur = t_cur->next();119}120if (f_cur->as_Constant() != NULL && !f_cur->can_trap()) {121f_const = f_cur;122f_cur = f_cur->next();123}124125// check if both branches end with a goto126Goto* t_goto = t_cur->as_Goto();127if (t_goto == NULL) return;128Goto* f_goto = f_cur->as_Goto();129if (f_goto == NULL) return;130131// check if both gotos merge into the same block132BlockBegin* sux = t_goto->default_sux();133if (sux != f_goto->default_sux()) return;134135// check if at least one word was pushed on sux_state136// inlining depths must match137ValueStack* if_state = if_->state();138ValueStack* sux_state = sux->state();139if (if_state->scope()->level() > sux_state->scope()->level()) {140while (sux_state->scope() != if_state->scope()) {141if_state = if_state->caller_state();142assert(if_state != NULL, "states do not match up");143}144} else if (if_state->scope()->level() < sux_state->scope()->level()) {145while (sux_state->scope() != if_state->scope()) {146sux_state = sux_state->caller_state();147assert(sux_state != NULL, "states do not match up");148}149}150151if (sux_state->stack_size() <= if_state->stack_size()) return;152153// check if phi function is present at end of successor stack and that154// only this phi was pushed on the stack155Value sux_phi = sux_state->stack_at(if_state->stack_size());156if (sux_phi == NULL || sux_phi->as_Phi() == NULL || sux_phi->as_Phi()->block() != sux) return;157if (sux_phi->type()->size() != sux_state->stack_size() - if_state->stack_size()) return;158159// get the values that were pushed in the true- and false-branch160Value t_value = t_goto->state()->stack_at(if_state->stack_size());161Value f_value = f_goto->state()->stack_at(if_state->stack_size());162163// backend does not support floats164assert(t_value->type()->base() == f_value->type()->base(), "incompatible types");165if (t_value->type()->is_float_kind()) return;166167// check that successor has no other phi functions but sux_phi168// this can happen when t_block or f_block contained additonal stores to local variables169// that are no longer represented by explicit instructions170for_each_phi_fun(sux, phi,171if (phi != sux_phi) return;172);173// true and false blocks can't have phis174for_each_phi_fun(t_block, phi, return; );175for_each_phi_fun(f_block, phi, return; );176177// Only replace safepoint gotos if state_before information is available (if is a safepoint)178bool is_safepoint = if_->is_safepoint();179if (!is_safepoint && (t_goto->is_safepoint() || f_goto->is_safepoint())) {180return;181}182183// 2) substitute conditional expression184// with an IfOp followed by a Goto185// cut if_ away and get node before186Instruction* cur_end = if_->prev();187188// append constants of true- and false-block if necessary189// clone constants because original block must not be destroyed190assert((t_value != f_const && f_value != t_const) || t_const == f_const, "mismatch");191if (t_value == t_const) {192t_value = new Constant(t_const->type());193NOT_PRODUCT(t_value->set_printable_bci(if_->printable_bci()));194cur_end = cur_end->set_next(t_value);195}196if (f_value == f_const) {197f_value = new Constant(f_const->type());198NOT_PRODUCT(f_value->set_printable_bci(if_->printable_bci()));199cur_end = cur_end->set_next(f_value);200}201202Value result = make_ifop(if_->x(), if_->cond(), if_->y(), t_value, f_value);203assert(result != NULL, "make_ifop must return a non-null instruction");204if (!result->is_linked() && result->can_be_linked()) {205NOT_PRODUCT(result->set_printable_bci(if_->printable_bci()));206cur_end = cur_end->set_next(result);207}208209// append Goto to successor210ValueStack* state_before = if_->state_before();211Goto* goto_ = new Goto(sux, state_before, is_safepoint);212213// prepare state for Goto214ValueStack* goto_state = if_state;215goto_state = goto_state->copy(ValueStack::StateAfter, goto_state->bci());216goto_state->push(result->type(), result);217assert(goto_state->is_same(sux_state), "states must match now");218goto_->set_state(goto_state);219220cur_end = cur_end->set_next(goto_, goto_state->bci());221222// Adjust control flow graph223BlockBegin::disconnect_edge(block, t_block);224BlockBegin::disconnect_edge(block, f_block);225if (t_block->number_of_preds() == 0) {226BlockBegin::disconnect_edge(t_block, sux);227}228adjust_exception_edges(block, t_block);229if (f_block->number_of_preds() == 0) {230BlockBegin::disconnect_edge(f_block, sux);231}232adjust_exception_edges(block, f_block);233234// update block end235block->set_end(goto_);236237// substitute the phi if possible238if (sux_phi->as_Phi()->operand_count() == 1) {239assert(sux_phi->as_Phi()->operand_at(0) == result, "screwed up phi");240sux_phi->set_subst(result);241_has_substitution = true;242}243244// 3) successfully eliminated a conditional expression245_cee_count++;246if (PrintCEE) {247tty->print_cr("%d. CEE in B%d (B%d B%d)", cee_count(), block->block_id(), t_block->block_id(), f_block->block_id());248tty->print_cr("%d. IfOp in B%d", ifop_count(), block->block_id());249}250251_hir->verify();252}253254Value CE_Eliminator::make_ifop(Value x, Instruction::Condition cond, Value y, Value tval, Value fval) {255if (!OptimizeIfOps) {256return new IfOp(x, cond, y, tval, fval);257}258259tval = tval->subst();260fval = fval->subst();261if (tval == fval) {262_ifop_count++;263return tval;264}265266x = x->subst();267y = y->subst();268269Constant* y_const = y->as_Constant();270if (y_const != NULL) {271IfOp* x_ifop = x->as_IfOp();272if (x_ifop != NULL) { // x is an ifop, y is a constant273Constant* x_tval_const = x_ifop->tval()->subst()->as_Constant();274Constant* x_fval_const = x_ifop->fval()->subst()->as_Constant();275276if (x_tval_const != NULL && x_fval_const != NULL) {277Instruction::Condition x_ifop_cond = x_ifop->cond();278279Constant::CompareResult t_compare_res = x_tval_const->compare(cond, y_const);280Constant::CompareResult f_compare_res = x_fval_const->compare(cond, y_const);281282// not_comparable here is a valid return in case we're comparing unloaded oop constants283if (t_compare_res != Constant::not_comparable && f_compare_res != Constant::not_comparable) {284Value new_tval = t_compare_res == Constant::cond_true ? tval : fval;285Value new_fval = f_compare_res == Constant::cond_true ? tval : fval;286287_ifop_count++;288if (new_tval == new_fval) {289return new_tval;290} else {291return new IfOp(x_ifop->x(), x_ifop_cond, x_ifop->y(), new_tval, new_fval);292}293}294}295} else {296Constant* x_const = x->as_Constant();297if (x_const != NULL) { // x and y are constants298Constant::CompareResult x_compare_res = x_const->compare(cond, y_const);299// not_comparable here is a valid return in case we're comparing unloaded oop constants300if (x_compare_res != Constant::not_comparable) {301_ifop_count++;302return x_compare_res == Constant::cond_true ? tval : fval;303}304}305}306}307return new IfOp(x, cond, y, tval, fval);308}309310void Optimizer::eliminate_conditional_expressions() {311// find conditional expressions & replace them with IfOps312CE_Eliminator ce(ir());313}314315class BlockMerger: public BlockClosure {316private:317IR* _hir;318int _merge_count; // the number of block pairs successfully merged319320public:321BlockMerger(IR* hir)322: _hir(hir)323, _merge_count(0)324{325_hir->iterate_preorder(this);326CompileLog* log = _hir->compilation()->log();327if (log != NULL)328log->set_context("optimize name='eliminate_blocks'");329}330331~BlockMerger() {332CompileLog* log = _hir->compilation()->log();333if (log != NULL)334log->clear_context(); // skip marker if nothing was printed335}336337bool try_merge(BlockBegin* block) {338BlockEnd* end = block->end();339if (end->as_Goto() != NULL) {340assert(end->number_of_sux() == 1, "end must have exactly one successor");341// Note: It would be sufficient to check for the number of successors (= 1)342// in order to decide if this block can be merged potentially. That343// would then also include switch statements w/ only a default case.344// However, in that case we would need to make sure the switch tag345// expression is executed if it can produce observable side effects.346// We should probably have the canonicalizer simplifying such switch347// statements and then we are sure we don't miss these merge opportunities348// here (was bug - gri 7/7/99).349BlockBegin* sux = end->default_sux();350if (sux->number_of_preds() == 1 && !sux->is_entry_block() && !end->is_safepoint()) {351// merge the two blocks352353#ifdef ASSERT354// verify that state at the end of block and at the beginning of sux are equal355// no phi functions must be present at beginning of sux356ValueStack* sux_state = sux->state();357ValueStack* end_state = end->state();358359assert(end_state->scope() == sux_state->scope(), "scopes must match");360assert(end_state->stack_size() == sux_state->stack_size(), "stack not equal");361assert(end_state->locals_size() == sux_state->locals_size(), "locals not equal");362363int index;364Value sux_value;365for_each_stack_value(sux_state, index, sux_value) {366assert(sux_value == end_state->stack_at(index), "stack not equal");367}368for_each_local_value(sux_state, index, sux_value) {369assert(sux_value == end_state->local_at(index), "locals not equal");370}371assert(sux_state->caller_state() == end_state->caller_state(), "caller not equal");372#endif373374// find instruction before end & append first instruction of sux block375Instruction* prev = end->prev();376Instruction* next = sux->next();377assert(prev->as_BlockEnd() == NULL, "must not be a BlockEnd");378prev->set_next(next);379prev->fixup_block_pointers();380sux->disconnect_from_graph();381block->set_end(sux->end());382// add exception handlers of deleted block, if any383for (int k = 0; k < sux->number_of_exception_handlers(); k++) {384BlockBegin* xhandler = sux->exception_handler_at(k);385block->add_exception_handler(xhandler);386387// also substitute predecessor of exception handler388assert(xhandler->is_predecessor(sux), "missing predecessor");389xhandler->remove_predecessor(sux);390if (!xhandler->is_predecessor(block)) {391xhandler->add_predecessor(block);392}393}394395// debugging output396_merge_count++;397if (PrintBlockElimination) {398tty->print_cr("%d. merged B%d & B%d (stack size = %d)",399_merge_count, block->block_id(), sux->block_id(), sux->state()->stack_size());400}401402_hir->verify();403404If* if_ = block->end()->as_If();405if (if_) {406IfOp* ifop = if_->x()->as_IfOp();407Constant* con = if_->y()->as_Constant();408bool swapped = false;409if (!con || !ifop) {410ifop = if_->y()->as_IfOp();411con = if_->x()->as_Constant();412swapped = true;413}414if (con && ifop) {415Constant* tval = ifop->tval()->as_Constant();416Constant* fval = ifop->fval()->as_Constant();417if (tval && fval) {418// Find the instruction before if_, starting with ifop.419// When if_ and ifop are not in the same block, prev420// becomes NULL In such (rare) cases it is not421// profitable to perform the optimization.422Value prev = ifop;423while (prev != NULL && prev->next() != if_) {424prev = prev->next();425}426427if (prev != NULL) {428Instruction::Condition cond = if_->cond();429BlockBegin* tsux = if_->tsux();430BlockBegin* fsux = if_->fsux();431if (swapped) {432cond = Instruction::mirror(cond);433}434435BlockBegin* tblock = tval->compare(cond, con, tsux, fsux);436BlockBegin* fblock = fval->compare(cond, con, tsux, fsux);437if (tblock != fblock && !if_->is_safepoint()) {438If* newif = new If(ifop->x(), ifop->cond(), false, ifop->y(),439tblock, fblock, if_->state_before(), if_->is_safepoint());440newif->set_state(if_->state()->copy());441442assert(prev->next() == if_, "must be guaranteed by above search");443NOT_PRODUCT(newif->set_printable_bci(if_->printable_bci()));444prev->set_next(newif);445block->set_end(newif);446447_merge_count++;448if (PrintBlockElimination) {449tty->print_cr("%d. replaced If and IfOp at end of B%d with single If", _merge_count, block->block_id());450}451452_hir->verify();453}454}455}456}457}458459return true;460}461}462return false;463}464465virtual void block_do(BlockBegin* block) {466_hir->verify();467// repeat since the same block may merge again468while (try_merge(block)) {469_hir->verify();470}471}472};473474475void Optimizer::eliminate_blocks() {476// merge blocks if possible477BlockMerger bm(ir());478}479480481class NullCheckEliminator;482class NullCheckVisitor: public InstructionVisitor {483private:484NullCheckEliminator* _nce;485NullCheckEliminator* nce() { return _nce; }486487public:488NullCheckVisitor() {}489490void set_eliminator(NullCheckEliminator* nce) { _nce = nce; }491492void do_Phi (Phi* x);493void do_Local (Local* x);494void do_Constant (Constant* x);495void do_LoadField (LoadField* x);496void do_StoreField (StoreField* x);497void do_ArrayLength (ArrayLength* x);498void do_LoadIndexed (LoadIndexed* x);499void do_StoreIndexed (StoreIndexed* x);500void do_NegateOp (NegateOp* x);501void do_ArithmeticOp (ArithmeticOp* x);502void do_ShiftOp (ShiftOp* x);503void do_LogicOp (LogicOp* x);504void do_CompareOp (CompareOp* x);505void do_IfOp (IfOp* x);506void do_Convert (Convert* x);507void do_NullCheck (NullCheck* x);508void do_TypeCast (TypeCast* x);509void do_Invoke (Invoke* x);510void do_NewInstance (NewInstance* x);511void do_NewTypeArray (NewTypeArray* x);512void do_NewObjectArray (NewObjectArray* x);513void do_NewMultiArray (NewMultiArray* x);514void do_CheckCast (CheckCast* x);515void do_InstanceOf (InstanceOf* x);516void do_MonitorEnter (MonitorEnter* x);517void do_MonitorExit (MonitorExit* x);518void do_Intrinsic (Intrinsic* x);519void do_BlockBegin (BlockBegin* x);520void do_Goto (Goto* x);521void do_If (If* x);522void do_IfInstanceOf (IfInstanceOf* x);523void do_TableSwitch (TableSwitch* x);524void do_LookupSwitch (LookupSwitch* x);525void do_Return (Return* x);526void do_Throw (Throw* x);527void do_Base (Base* x);528void do_OsrEntry (OsrEntry* x);529void do_ExceptionObject(ExceptionObject* x);530void do_RoundFP (RoundFP* x);531void do_UnsafeGetRaw (UnsafeGetRaw* x);532void do_UnsafePutRaw (UnsafePutRaw* x);533void do_UnsafeGetObject(UnsafeGetObject* x);534void do_UnsafePutObject(UnsafePutObject* x);535void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x);536void do_UnsafePrefetchRead (UnsafePrefetchRead* x);537void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);538void do_ProfileCall (ProfileCall* x);539void do_ProfileReturnType (ProfileReturnType* x);540void do_ProfileInvoke (ProfileInvoke* x);541void do_RuntimeCall (RuntimeCall* x);542void do_MemBar (MemBar* x);543void do_RangeCheckPredicate(RangeCheckPredicate* x);544#ifdef ASSERT545void do_Assert (Assert* x);546#endif547};548549550// Because of a static contained within (for the purpose of iteration551// over instructions), it is only valid to have one of these active at552// a time553class NullCheckEliminator: public ValueVisitor {554private:555Optimizer* _opt;556557ValueSet* _visitable_instructions; // Visit each instruction only once per basic block558BlockList* _work_list; // Basic blocks to visit559560bool visitable(Value x) {561assert(_visitable_instructions != NULL, "check");562return _visitable_instructions->contains(x);563}564void mark_visited(Value x) {565assert(_visitable_instructions != NULL, "check");566_visitable_instructions->remove(x);567}568void mark_visitable(Value x) {569assert(_visitable_instructions != NULL, "check");570_visitable_instructions->put(x);571}572void clear_visitable_state() {573assert(_visitable_instructions != NULL, "check");574_visitable_instructions->clear();575}576577ValueSet* _set; // current state, propagated to subsequent BlockBegins578ValueSetList _block_states; // BlockBegin null-check states for all processed blocks579NullCheckVisitor _visitor;580NullCheck* _last_explicit_null_check;581582bool set_contains(Value x) { assert(_set != NULL, "check"); return _set->contains(x); }583void set_put (Value x) { assert(_set != NULL, "check"); _set->put(x); }584void set_remove (Value x) { assert(_set != NULL, "check"); _set->remove(x); }585586BlockList* work_list() { return _work_list; }587588void iterate_all();589void iterate_one(BlockBegin* block);590591ValueSet* state() { return _set; }592void set_state_from (ValueSet* state) { _set->set_from(state); }593ValueSet* state_for (BlockBegin* block) { return _block_states[block->block_id()]; }594void set_state_for (BlockBegin* block, ValueSet* stack) { _block_states[block->block_id()] = stack; }595// Returns true if caused a change in the block's state.596bool merge_state_for(BlockBegin* block,597ValueSet* incoming_state);598599public:600// constructor601NullCheckEliminator(Optimizer* opt)602: _opt(opt)603, _set(new ValueSet())604, _last_explicit_null_check(NULL)605, _block_states(BlockBegin::number_of_blocks(), NULL)606, _work_list(new BlockList()) {607_visitable_instructions = new ValueSet();608_visitor.set_eliminator(this);609CompileLog* log = _opt->ir()->compilation()->log();610if (log != NULL)611log->set_context("optimize name='null_check_elimination'");612}613614~NullCheckEliminator() {615CompileLog* log = _opt->ir()->compilation()->log();616if (log != NULL)617log->clear_context(); // skip marker if nothing was printed618}619620Optimizer* opt() { return _opt; }621IR* ir () { return opt()->ir(); }622623// Process a graph624void iterate(BlockBegin* root);625626void visit(Value* f);627628// In some situations (like NullCheck(x); getfield(x)) the debug629// information from the explicit NullCheck can be used to populate630// the getfield, even if the two instructions are in different631// scopes; this allows implicit null checks to be used but the632// correct exception information to be generated. We must clear the633// last-traversed NullCheck when we reach a potentially-exception-634// throwing instruction, as well as in some other cases.635void set_last_explicit_null_check(NullCheck* check) { _last_explicit_null_check = check; }636NullCheck* last_explicit_null_check() { return _last_explicit_null_check; }637Value last_explicit_null_check_obj() { return (_last_explicit_null_check638? _last_explicit_null_check->obj()639: NULL); }640NullCheck* consume_last_explicit_null_check() {641_last_explicit_null_check->unpin(Instruction::PinExplicitNullCheck);642_last_explicit_null_check->set_can_trap(false);643return _last_explicit_null_check;644}645void clear_last_explicit_null_check() { _last_explicit_null_check = NULL; }646647// Handlers for relevant instructions648// (separated out from NullCheckVisitor for clarity)649650// The basic contract is that these must leave the instruction in651// the desired state; must not assume anything about the state of652// the instruction. We make multiple passes over some basic blocks653// and the last pass is the only one whose result is valid.654void handle_AccessField (AccessField* x);655void handle_ArrayLength (ArrayLength* x);656void handle_LoadIndexed (LoadIndexed* x);657void handle_StoreIndexed (StoreIndexed* x);658void handle_NullCheck (NullCheck* x);659void handle_Invoke (Invoke* x);660void handle_NewInstance (NewInstance* x);661void handle_NewArray (NewArray* x);662void handle_AccessMonitor (AccessMonitor* x);663void handle_Intrinsic (Intrinsic* x);664void handle_ExceptionObject (ExceptionObject* x);665void handle_Phi (Phi* x);666void handle_ProfileCall (ProfileCall* x);667void handle_ProfileReturnType (ProfileReturnType* x);668};669670671// NEEDS_CLEANUP672// There may be other instructions which need to clear the last673// explicit null check. Anything across which we can not hoist the674// debug information for a NullCheck instruction must clear it. It675// might be safer to pattern match "NullCheck ; {AccessField,676// ArrayLength, LoadIndexed}" but it is more easily structured this way.677// Should test to see performance hit of clearing it for all handlers678// with empty bodies below. If it is negligible then we should leave679// that in for safety, otherwise should think more about it.680void NullCheckVisitor::do_Phi (Phi* x) { nce()->handle_Phi(x); }681void NullCheckVisitor::do_Local (Local* x) {}682void NullCheckVisitor::do_Constant (Constant* x) { /* FIXME: handle object constants */ }683void NullCheckVisitor::do_LoadField (LoadField* x) { nce()->handle_AccessField(x); }684void NullCheckVisitor::do_StoreField (StoreField* x) { nce()->handle_AccessField(x); }685void NullCheckVisitor::do_ArrayLength (ArrayLength* x) { nce()->handle_ArrayLength(x); }686void NullCheckVisitor::do_LoadIndexed (LoadIndexed* x) { nce()->handle_LoadIndexed(x); }687void NullCheckVisitor::do_StoreIndexed (StoreIndexed* x) { nce()->handle_StoreIndexed(x); }688void NullCheckVisitor::do_NegateOp (NegateOp* x) {}689void NullCheckVisitor::do_ArithmeticOp (ArithmeticOp* x) { if (x->can_trap()) nce()->clear_last_explicit_null_check(); }690void NullCheckVisitor::do_ShiftOp (ShiftOp* x) {}691void NullCheckVisitor::do_LogicOp (LogicOp* x) {}692void NullCheckVisitor::do_CompareOp (CompareOp* x) {}693void NullCheckVisitor::do_IfOp (IfOp* x) {}694void NullCheckVisitor::do_Convert (Convert* x) {}695void NullCheckVisitor::do_NullCheck (NullCheck* x) { nce()->handle_NullCheck(x); }696void NullCheckVisitor::do_TypeCast (TypeCast* x) {}697void NullCheckVisitor::do_Invoke (Invoke* x) { nce()->handle_Invoke(x); }698void NullCheckVisitor::do_NewInstance (NewInstance* x) { nce()->handle_NewInstance(x); }699void NullCheckVisitor::do_NewTypeArray (NewTypeArray* x) { nce()->handle_NewArray(x); }700void NullCheckVisitor::do_NewObjectArray (NewObjectArray* x) { nce()->handle_NewArray(x); }701void NullCheckVisitor::do_NewMultiArray (NewMultiArray* x) { nce()->handle_NewArray(x); }702void NullCheckVisitor::do_CheckCast (CheckCast* x) { nce()->clear_last_explicit_null_check(); }703void NullCheckVisitor::do_InstanceOf (InstanceOf* x) {}704void NullCheckVisitor::do_MonitorEnter (MonitorEnter* x) { nce()->handle_AccessMonitor(x); }705void NullCheckVisitor::do_MonitorExit (MonitorExit* x) { nce()->handle_AccessMonitor(x); }706void NullCheckVisitor::do_Intrinsic (Intrinsic* x) { nce()->handle_Intrinsic(x); }707void NullCheckVisitor::do_BlockBegin (BlockBegin* x) {}708void NullCheckVisitor::do_Goto (Goto* x) {}709void NullCheckVisitor::do_If (If* x) {}710void NullCheckVisitor::do_IfInstanceOf (IfInstanceOf* x) {}711void NullCheckVisitor::do_TableSwitch (TableSwitch* x) {}712void NullCheckVisitor::do_LookupSwitch (LookupSwitch* x) {}713void NullCheckVisitor::do_Return (Return* x) {}714void NullCheckVisitor::do_Throw (Throw* x) { nce()->clear_last_explicit_null_check(); }715void NullCheckVisitor::do_Base (Base* x) {}716void NullCheckVisitor::do_OsrEntry (OsrEntry* x) {}717void NullCheckVisitor::do_ExceptionObject(ExceptionObject* x) { nce()->handle_ExceptionObject(x); }718void NullCheckVisitor::do_RoundFP (RoundFP* x) {}719void NullCheckVisitor::do_UnsafeGetRaw (UnsafeGetRaw* x) {}720void NullCheckVisitor::do_UnsafePutRaw (UnsafePutRaw* x) {}721void NullCheckVisitor::do_UnsafeGetObject(UnsafeGetObject* x) {}722void NullCheckVisitor::do_UnsafePutObject(UnsafePutObject* x) {}723void NullCheckVisitor::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {}724void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {}725void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}726void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check();727nce()->handle_ProfileCall(x); }728void NullCheckVisitor::do_ProfileReturnType (ProfileReturnType* x) { nce()->handle_ProfileReturnType(x); }729void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {}730void NullCheckVisitor::do_RuntimeCall (RuntimeCall* x) {}731void NullCheckVisitor::do_MemBar (MemBar* x) {}732void NullCheckVisitor::do_RangeCheckPredicate(RangeCheckPredicate* x) {}733#ifdef ASSERT734void NullCheckVisitor::do_Assert (Assert* x) {}735#endif736737void NullCheckEliminator::visit(Value* p) {738assert(*p != NULL, "should not find NULL instructions");739if (visitable(*p)) {740mark_visited(*p);741(*p)->visit(&_visitor);742}743}744745bool NullCheckEliminator::merge_state_for(BlockBegin* block, ValueSet* incoming_state) {746ValueSet* state = state_for(block);747if (state == NULL) {748state = incoming_state->copy();749set_state_for(block, state);750return true;751} else {752bool changed = state->set_intersect(incoming_state);753if (PrintNullCheckElimination && changed) {754tty->print_cr("Block %d's null check state changed", block->block_id());755}756return changed;757}758}759760761void NullCheckEliminator::iterate_all() {762while (work_list()->length() > 0) {763iterate_one(work_list()->pop());764}765}766767768void NullCheckEliminator::iterate_one(BlockBegin* block) {769clear_visitable_state();770// clear out an old explicit null checks771set_last_explicit_null_check(NULL);772773if (PrintNullCheckElimination) {774tty->print_cr(" ...iterating block %d in null check elimination for %s::%s%s",775block->block_id(),776ir()->method()->holder()->name()->as_utf8(),777ir()->method()->name()->as_utf8(),778ir()->method()->signature()->as_symbol()->as_utf8());779}780781// Create new state if none present (only happens at root)782if (state_for(block) == NULL) {783ValueSet* tmp_state = new ValueSet();784set_state_for(block, tmp_state);785// Initial state is that local 0 (receiver) is non-null for786// non-static methods787ValueStack* stack = block->state();788IRScope* scope = stack->scope();789ciMethod* method = scope->method();790if (!method->is_static()) {791Local* local0 = stack->local_at(0)->as_Local();792assert(local0 != NULL, "must be");793assert(local0->type() == objectType, "invalid type of receiver");794795if (local0 != NULL) {796// Local 0 is used in this scope797tmp_state->put(local0);798if (PrintNullCheckElimination) {799tty->print_cr("Local 0 (value %d) proven non-null upon entry", local0->id());800}801}802}803}804805// Must copy block's state to avoid mutating it during iteration806// through the block -- otherwise "not-null" states can accidentally807// propagate "up" through the block during processing of backward808// branches and algorithm is incorrect (and does not converge)809set_state_from(state_for(block));810811// allow visiting of Phis belonging to this block812for_each_phi_fun(block, phi,813mark_visitable(phi);814);815816BlockEnd* e = block->end();817assert(e != NULL, "incomplete graph");818int i;819820// Propagate the state before this block into the exception821// handlers. They aren't true successors since we aren't guaranteed822// to execute the whole block before executing them. Also putting823// them on first seems to help reduce the amount of iteration to824// reach a fixed point.825for (i = 0; i < block->number_of_exception_handlers(); i++) {826BlockBegin* next = block->exception_handler_at(i);827if (merge_state_for(next, state())) {828if (!work_list()->contains(next)) {829work_list()->push(next);830}831}832}833834// Iterate through block, updating state.835for (Instruction* instr = block; instr != NULL; instr = instr->next()) {836// Mark instructions in this block as visitable as they are seen837// in the instruction list. This keeps the iteration from838// visiting instructions which are references in other blocks or839// visiting instructions more than once.840mark_visitable(instr);841if (instr->is_pinned() || instr->can_trap() || (instr->as_NullCheck() != NULL)) {842mark_visited(instr);843instr->input_values_do(this);844instr->visit(&_visitor);845}846}847848// Propagate state to successors if necessary849for (i = 0; i < e->number_of_sux(); i++) {850BlockBegin* next = e->sux_at(i);851if (merge_state_for(next, state())) {852if (!work_list()->contains(next)) {853work_list()->push(next);854}855}856}857}858859860void NullCheckEliminator::iterate(BlockBegin* block) {861work_list()->push(block);862iterate_all();863}864865void NullCheckEliminator::handle_AccessField(AccessField* x) {866if (x->is_static()) {867if (x->as_LoadField() != NULL) {868// If the field is a non-null static final object field (as is869// often the case for sun.misc.Unsafe), put this LoadField into870// the non-null map871ciField* field = x->field();872if (field->is_constant()) {873ciConstant field_val = field->constant_value();874BasicType field_type = field_val.basic_type();875if (field_type == T_OBJECT || field_type == T_ARRAY) {876ciObject* obj_val = field_val.as_object();877if (!obj_val->is_null_object()) {878if (PrintNullCheckElimination) {879tty->print_cr("AccessField %d proven non-null by static final non-null oop check",880x->id());881}882set_put(x);883}884}885}886}887// Be conservative888clear_last_explicit_null_check();889return;890}891892Value obj = x->obj();893if (set_contains(obj)) {894// Value is non-null => update AccessField895if (last_explicit_null_check_obj() == obj && !x->needs_patching()) {896x->set_explicit_null_check(consume_last_explicit_null_check());897x->set_needs_null_check(true);898if (PrintNullCheckElimination) {899tty->print_cr("Folded NullCheck %d into AccessField %d's null check for value %d",900x->explicit_null_check()->id(), x->id(), obj->id());901}902} else {903x->set_explicit_null_check(NULL);904x->set_needs_null_check(false);905if (PrintNullCheckElimination) {906tty->print_cr("Eliminated AccessField %d's null check for value %d", x->id(), obj->id());907}908}909} else {910set_put(obj);911if (PrintNullCheckElimination) {912tty->print_cr("AccessField %d of value %d proves value to be non-null", x->id(), obj->id());913}914// Ensure previous passes do not cause wrong state915x->set_needs_null_check(true);916x->set_explicit_null_check(NULL);917}918clear_last_explicit_null_check();919}920921922void NullCheckEliminator::handle_ArrayLength(ArrayLength* x) {923Value array = x->array();924if (set_contains(array)) {925// Value is non-null => update AccessArray926if (last_explicit_null_check_obj() == array) {927x->set_explicit_null_check(consume_last_explicit_null_check());928x->set_needs_null_check(true);929if (PrintNullCheckElimination) {930tty->print_cr("Folded NullCheck %d into ArrayLength %d's null check for value %d",931x->explicit_null_check()->id(), x->id(), array->id());932}933} else {934x->set_explicit_null_check(NULL);935x->set_needs_null_check(false);936if (PrintNullCheckElimination) {937tty->print_cr("Eliminated ArrayLength %d's null check for value %d", x->id(), array->id());938}939}940} else {941set_put(array);942if (PrintNullCheckElimination) {943tty->print_cr("ArrayLength %d of value %d proves value to be non-null", x->id(), array->id());944}945// Ensure previous passes do not cause wrong state946x->set_needs_null_check(true);947x->set_explicit_null_check(NULL);948}949clear_last_explicit_null_check();950}951952953void NullCheckEliminator::handle_LoadIndexed(LoadIndexed* x) {954Value array = x->array();955if (set_contains(array)) {956// Value is non-null => update AccessArray957if (last_explicit_null_check_obj() == array) {958x->set_explicit_null_check(consume_last_explicit_null_check());959x->set_needs_null_check(true);960if (PrintNullCheckElimination) {961tty->print_cr("Folded NullCheck %d into LoadIndexed %d's null check for value %d",962x->explicit_null_check()->id(), x->id(), array->id());963}964} else {965x->set_explicit_null_check(NULL);966x->set_needs_null_check(false);967if (PrintNullCheckElimination) {968tty->print_cr("Eliminated LoadIndexed %d's null check for value %d", x->id(), array->id());969}970}971} else {972set_put(array);973if (PrintNullCheckElimination) {974tty->print_cr("LoadIndexed %d of value %d proves value to be non-null", x->id(), array->id());975}976// Ensure previous passes do not cause wrong state977x->set_needs_null_check(true);978x->set_explicit_null_check(NULL);979}980clear_last_explicit_null_check();981}982983984void NullCheckEliminator::handle_StoreIndexed(StoreIndexed* x) {985Value array = x->array();986if (set_contains(array)) {987// Value is non-null => update AccessArray988if (PrintNullCheckElimination) {989tty->print_cr("Eliminated StoreIndexed %d's null check for value %d", x->id(), array->id());990}991x->set_needs_null_check(false);992} else {993set_put(array);994if (PrintNullCheckElimination) {995tty->print_cr("StoreIndexed %d of value %d proves value to be non-null", x->id(), array->id());996}997// Ensure previous passes do not cause wrong state998x->set_needs_null_check(true);999}1000clear_last_explicit_null_check();1001}100210031004void NullCheckEliminator::handle_NullCheck(NullCheck* x) {1005Value obj = x->obj();1006if (set_contains(obj)) {1007// Already proven to be non-null => this NullCheck is useless1008if (PrintNullCheckElimination) {1009tty->print_cr("Eliminated NullCheck %d for value %d", x->id(), obj->id());1010}1011// Don't unpin since that may shrink obj's live range and make it unavailable for debug info.1012// The code generator won't emit LIR for a NullCheck that cannot trap.1013x->set_can_trap(false);1014} else {1015// May be null => add to map and set last explicit NullCheck1016x->set_can_trap(true);1017// make sure it's pinned if it can trap1018x->pin(Instruction::PinExplicitNullCheck);1019set_put(obj);1020set_last_explicit_null_check(x);1021if (PrintNullCheckElimination) {1022tty->print_cr("NullCheck %d of value %d proves value to be non-null", x->id(), obj->id());1023}1024}1025}102610271028void NullCheckEliminator::handle_Invoke(Invoke* x) {1029if (!x->has_receiver()) {1030// Be conservative1031clear_last_explicit_null_check();1032return;1033}10341035Value recv = x->receiver();1036if (!set_contains(recv)) {1037set_put(recv);1038if (PrintNullCheckElimination) {1039tty->print_cr("Invoke %d of value %d proves value to be non-null", x->id(), recv->id());1040}1041}1042clear_last_explicit_null_check();1043}104410451046void NullCheckEliminator::handle_NewInstance(NewInstance* x) {1047set_put(x);1048if (PrintNullCheckElimination) {1049tty->print_cr("NewInstance %d is non-null", x->id());1050}1051}105210531054void NullCheckEliminator::handle_NewArray(NewArray* x) {1055set_put(x);1056if (PrintNullCheckElimination) {1057tty->print_cr("NewArray %d is non-null", x->id());1058}1059}106010611062void NullCheckEliminator::handle_ExceptionObject(ExceptionObject* x) {1063set_put(x);1064if (PrintNullCheckElimination) {1065tty->print_cr("ExceptionObject %d is non-null", x->id());1066}1067}106810691070void NullCheckEliminator::handle_AccessMonitor(AccessMonitor* x) {1071Value obj = x->obj();1072if (set_contains(obj)) {1073// Value is non-null => update AccessMonitor1074if (PrintNullCheckElimination) {1075tty->print_cr("Eliminated AccessMonitor %d's null check for value %d", x->id(), obj->id());1076}1077x->set_needs_null_check(false);1078} else {1079set_put(obj);1080if (PrintNullCheckElimination) {1081tty->print_cr("AccessMonitor %d of value %d proves value to be non-null", x->id(), obj->id());1082}1083// Ensure previous passes do not cause wrong state1084x->set_needs_null_check(true);1085}1086clear_last_explicit_null_check();1087}108810891090void NullCheckEliminator::handle_Intrinsic(Intrinsic* x) {1091if (!x->has_receiver()) {1092if (x->id() == vmIntrinsics::_arraycopy) {1093for (int i = 0; i < x->number_of_arguments(); i++) {1094x->set_arg_needs_null_check(i, !set_contains(x->argument_at(i)));1095}1096}10971098// Be conservative1099clear_last_explicit_null_check();1100return;1101}11021103Value recv = x->receiver();1104if (set_contains(recv)) {1105// Value is non-null => update Intrinsic1106if (PrintNullCheckElimination) {1107tty->print_cr("Eliminated Intrinsic %d's null check for value %d", x->id(), recv->id());1108}1109x->set_needs_null_check(false);1110} else {1111set_put(recv);1112if (PrintNullCheckElimination) {1113tty->print_cr("Intrinsic %d of value %d proves value to be non-null", x->id(), recv->id());1114}1115// Ensure previous passes do not cause wrong state1116x->set_needs_null_check(true);1117}1118clear_last_explicit_null_check();1119}112011211122void NullCheckEliminator::handle_Phi(Phi* x) {1123int i;1124bool all_non_null = true;1125if (x->is_illegal()) {1126all_non_null = false;1127} else {1128for (i = 0; i < x->operand_count(); i++) {1129Value input = x->operand_at(i);1130if (!set_contains(input)) {1131all_non_null = false;1132}1133}1134}11351136if (all_non_null) {1137// Value is non-null => update Phi1138if (PrintNullCheckElimination) {1139tty->print_cr("Eliminated Phi %d's null check for phifun because all inputs are non-null", x->id());1140}1141x->set_needs_null_check(false);1142} else if (set_contains(x)) {1143set_remove(x);1144}1145}11461147void NullCheckEliminator::handle_ProfileCall(ProfileCall* x) {1148for (int i = 0; i < x->nb_profiled_args(); i++) {1149x->set_arg_needs_null_check(i, !set_contains(x->profiled_arg_at(i)));1150}1151}11521153void NullCheckEliminator::handle_ProfileReturnType(ProfileReturnType* x) {1154x->set_needs_null_check(!set_contains(x->ret()));1155}11561157void Optimizer::eliminate_null_checks() {1158ResourceMark rm;11591160NullCheckEliminator nce(this);11611162if (PrintNullCheckElimination) {1163tty->print_cr("Starting null check elimination for method %s::%s%s",1164ir()->method()->holder()->name()->as_utf8(),1165ir()->method()->name()->as_utf8(),1166ir()->method()->signature()->as_symbol()->as_utf8());1167}11681169// Apply to graph1170nce.iterate(ir()->start());11711172// walk over the graph looking for exception1173// handlers and iterate over them as well1174int nblocks = BlockBegin::number_of_blocks();1175BlockList blocks(nblocks);1176boolArray visited_block(nblocks, false);11771178blocks.push(ir()->start());1179visited_block[ir()->start()->block_id()] = true;1180for (int i = 0; i < blocks.length(); i++) {1181BlockBegin* b = blocks[i];1182// exception handlers need to be treated as additional roots1183for (int e = b->number_of_exception_handlers(); e-- > 0; ) {1184BlockBegin* excp = b->exception_handler_at(e);1185int id = excp->block_id();1186if (!visited_block[id]) {1187blocks.push(excp);1188visited_block[id] = true;1189nce.iterate(excp);1190}1191}1192// traverse successors1193BlockEnd *end = b->end();1194for (int s = end->number_of_sux(); s-- > 0; ) {1195BlockBegin* next = end->sux_at(s);1196int id = next->block_id();1197if (!visited_block[id]) {1198blocks.push(next);1199visited_block[id] = true;1200}1201}1202}120312041205if (PrintNullCheckElimination) {1206tty->print_cr("Done with null check elimination for method %s::%s%s",1207ir()->method()->holder()->name()->as_utf8(),1208ir()->method()->name()->as_utf8(),1209ir()->method()->signature()->as_symbol()->as_utf8());1210}1211}121212131214