diff --git a/src/share/vm/c1/c1_IR.cpp b/src/share/vm/c1/c1_IR.cpp --- a/src/share/vm/c1/c1_IR.cpp +++ b/src/share/vm/c1/c1_IR.cpp @@ -273,6 +273,13 @@ void IR::optimize_blocks() { Optimizer opt(this); + if (OptimizeInstanceOf) { + opt.optimize_instance_of(); +#ifndef PRODUCT + if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after instanceof optimization"); print(true); } + if (PrintIR || PrintIR1 ) { tty->print_cr("IR after instanceof optimization"); print(false); } +#endif + } if (!compilation()->profile_branches()) { if (DoCEE) { opt.eliminate_conditional_expressions(); diff --git a/src/share/vm/c1/c1_Optimizer.cpp b/src/share/vm/c1/c1_Optimizer.cpp --- a/src/share/vm/c1/c1_Optimizer.cpp +++ b/src/share/vm/c1/c1_Optimizer.cpp @@ -40,6 +40,56 @@ _ir = ir; } +class InstanceOfOptimizer : public BlockClosure { + IR* _hir; + bool _has_substitution; + +public: + InstanceOfOptimizer(IR* hir) : _hir(hir), _has_substitution(false) { + _hir->iterate_preorder(this); + if (_has_substitution) { + SubstitutionResolver sr(_hir); + } + CompileLog* log = _hir->compilation()->log(); + if (log != NULL) + log->set_context("optimize name='instanceof'"); + } + + ~InstanceOfOptimizer() { + CompileLog* log = _hir->compilation()->log(); + if (log != NULL) + log->clear_context(); // skip marker if nothing was printed + } + + virtual void block_do(BlockBegin* block) { + for (Instruction* n = block; n != NULL; n = n->next()) { + InstanceOf *x = n->as_InstanceOf(); + if (x != NULL && !x->should_profile() && x->klass()->equals(_hir->compilation()->env()->Object_klass())) { + Instruction* cur_end = x->prev(); + Constant* null_obj_constant = new Constant(objectNull); + NOT_PRODUCT(null_obj_constant->set_printable_bci(x->printable_bci())); + cur_end = cur_end->set_next(null_obj_constant); + + Constant* zero_constant = new Constant(new IntConstant(0)); + NOT_PRODUCT(zero_constant->set_printable_bci(x->printable_bci())); + cur_end = cur_end->set_next(zero_constant); + + Constant* one_constant = new Constant(new IntConstant(1)); + NOT_PRODUCT(one_constant->set_printable_bci(x->printable_bci())); + cur_end = cur_end->set_next(one_constant); + + IfOp* ifop = new IfOp(x->obj(), IfOp::eql, null_obj_constant, zero_constant, one_constant); + NOT_PRODUCT(ifop->set_printable_bci(x->printable_bci())); + cur_end = cur_end->set_next(ifop); + + x->set_subst(ifop); + cur_end->set_next(x); + _has_substitution = true; + } + } + } +}; + class CE_Eliminator: public BlockClosure { private: IR* _hir; @@ -307,6 +357,10 @@ CE_Eliminator ce(ir()); } +void Optimizer::optimize_instance_of() { + InstanceOfOptimizer instanceof_opt(ir()); +} + class BlockMerger: public BlockClosure { private: IR* _hir; diff --git a/src/share/vm/c1/c1_Optimizer.hpp b/src/share/vm/c1/c1_Optimizer.hpp --- a/src/share/vm/c1/c1_Optimizer.hpp +++ b/src/share/vm/c1/c1_Optimizer.hpp @@ -41,6 +41,7 @@ void eliminate_conditional_expressions(); void eliminate_blocks(); void eliminate_null_checks(); + void optimize_instance_of(); }; #endif // SHARE_VM_C1_C1_OPTIMIZER_HPP diff --git a/src/share/vm/c1/c1_globals.hpp b/src/share/vm/c1/c1_globals.hpp --- a/src/share/vm/c1/c1_globals.hpp +++ b/src/share/vm/c1/c1_globals.hpp @@ -113,6 +113,9 @@ develop(bool, OptimizeIfOps, true, \ "Optimize multiple IfOps") \ \ + develop(bool, OptimizeInstanceOf, true, \ + "Optimize some instance of patterns") \ + \ develop(bool, DoCEE, true, \ "Do Conditional Expression Elimination to simplify CFG") \ \