Path: blob/master/src/hotspot/share/c1/c1_RangeCheckElimination.cpp
40930 views
/*1* Copyright (c) 2012, 2021, 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_ValueStack.hpp"26#include "c1/c1_RangeCheckElimination.hpp"27#include "c1/c1_IR.hpp"28#include "c1/c1_Canonicalizer.hpp"29#include "c1/c1_ValueMap.hpp"30#include "ci/ciMethodData.hpp"31#include "runtime/deoptimization.hpp"32#ifdef ASSERT33#include "utilities/bitMap.inline.hpp"34#endif3536// Macros for the Trace and the Assertion flag37#ifdef ASSERT38#define TRACE_RANGE_CHECK_ELIMINATION(code) if (TraceRangeCheckElimination) { code; }39#define ASSERT_RANGE_CHECK_ELIMINATION(code) if (AssertRangeCheckElimination) { code; }40#define TRACE_OR_ASSERT_RANGE_CHECK_ELIMINATION(code) if (TraceRangeCheckElimination || AssertRangeCheckElimination) { code; }41#else42#define TRACE_RANGE_CHECK_ELIMINATION(code)43#define ASSERT_RANGE_CHECK_ELIMINATION(code)44#define TRACE_OR_ASSERT_RANGE_CHECK_ELIMINATION(code)45#endif4647// Entry point for the optimization48void RangeCheckElimination::eliminate(IR *ir) {49bool do_elimination = ir->compilation()->has_access_indexed();50ASSERT_RANGE_CHECK_ELIMINATION(do_elimination = true);51if (do_elimination) {52RangeCheckEliminator rce(ir);53}54}5556// Constructor57RangeCheckEliminator::RangeCheckEliminator(IR *ir) :58_bounds(Instruction::number_of_instructions(), Instruction::number_of_instructions(), NULL),59_access_indexed_info(Instruction::number_of_instructions(), Instruction::number_of_instructions(), NULL)60{61_visitor.set_range_check_eliminator(this);62_ir = ir;63_number_of_instructions = Instruction::number_of_instructions();64_optimistic = ir->compilation()->is_optimistic();6566TRACE_RANGE_CHECK_ELIMINATION(67tty->cr();68tty->print_cr("Range check elimination");69ir->method()->print_name(tty);70tty->cr();71);7273TRACE_RANGE_CHECK_ELIMINATION(74tty->print_cr("optimistic=%d", (int)_optimistic);75);7677#ifdef ASSERT78// Verifies several conditions that must be true on the IR-input. Only used for debugging purposes.79TRACE_RANGE_CHECK_ELIMINATION(80tty->print_cr("Verification of IR . . .");81);82Verification verification(ir);83#endif8485// Set process block flags86// Optimization so a blocks is only processed if it contains an access indexed instruction or if87// one of its children in the dominator tree contains an access indexed instruction.88set_process_block_flags(ir->start());8990// Pass over instructions in the dominator tree91TRACE_RANGE_CHECK_ELIMINATION(92tty->print_cr("Starting pass over dominator tree . . .")93);94calc_bounds(ir->start(), NULL);9596TRACE_RANGE_CHECK_ELIMINATION(97tty->print_cr("Finished!")98);99}100101// Instruction specific work for some instructions102// Constant103void RangeCheckEliminator::Visitor::do_Constant(Constant *c) {104IntConstant *ic = c->type()->as_IntConstant();105if (ic != NULL) {106int value = ic->value();107_bound = new Bound(value, NULL, value, NULL);108}109}110111// LogicOp112void RangeCheckEliminator::Visitor::do_LogicOp(LogicOp *lo) {113if (lo->type()->as_IntType() && lo->op() == Bytecodes::_iand && (lo->x()->as_Constant() || lo->y()->as_Constant())) {114int constant = 0;115Constant *c = lo->x()->as_Constant();116if (c != NULL) {117constant = c->type()->as_IntConstant()->value();118} else {119constant = lo->y()->as_Constant()->type()->as_IntConstant()->value();120}121if (constant >= 0) {122_bound = new Bound(0, NULL, constant, NULL);123}124}125}126127// Phi128void RangeCheckEliminator::Visitor::do_Phi(Phi *phi) {129if (!phi->type()->as_IntType() && !phi->type()->as_ObjectType()) return;130131BlockBegin *block = phi->block();132int op_count = phi->operand_count();133bool has_upper = true;134bool has_lower = true;135assert(phi, "Phi must not be null");136Bound *bound = NULL;137138// TODO: support more difficult phis139for (int i=0; i<op_count; i++) {140Value v = phi->operand_at(i);141142if (v == phi) continue;143144// Check if instruction is connected with phi itself145Op2 *op2 = v->as_Op2();146if (op2 != NULL) {147Value x = op2->x();148Value y = op2->y();149if ((x == phi || y == phi)) {150Value other = x;151if (other == phi) {152other = y;153}154ArithmeticOp *ao = v->as_ArithmeticOp();155if (ao != NULL && ao->op() == Bytecodes::_iadd) {156assert(ao->op() == Bytecodes::_iadd, "Has to be add!");157if (ao->type()->as_IntType()) {158Constant *c = other->as_Constant();159if (c != NULL) {160assert(c->type()->as_IntConstant(), "Constant has to be of type integer");161int value = c->type()->as_IntConstant()->value();162if (value == 1) {163has_upper = false;164} else if (value > 1) {165// Overflow not guaranteed166has_upper = false;167has_lower = false;168} else if (value < 0) {169has_lower = false;170}171continue;172}173}174}175}176}177178// No connection -> new bound179Bound *v_bound = _rce->get_bound(v);180Bound *cur_bound;181int cur_constant = 0;182Value cur_value = v;183184if (v->type()->as_IntConstant()) {185cur_constant = v->type()->as_IntConstant()->value();186cur_value = NULL;187}188if (!v_bound->has_upper() || !v_bound->has_lower()) {189cur_bound = new Bound(cur_constant, cur_value, cur_constant, cur_value);190} else {191cur_bound = v_bound;192}193if (cur_bound) {194if (!bound) {195bound = cur_bound->copy();196} else {197bound->or_op(cur_bound);198}199} else {200// No bound!201bound = NULL;202break;203}204}205206if (bound) {207if (!has_upper) {208bound->remove_upper();209}210if (!has_lower) {211bound->remove_lower();212}213_bound = bound;214} else {215_bound = new Bound();216}217}218219220// ArithmeticOp221void RangeCheckEliminator::Visitor::do_ArithmeticOp(ArithmeticOp *ao) {222Value x = ao->x();223Value y = ao->y();224225if (ao->op() == Bytecodes::_irem) {226Bound* x_bound = _rce->get_bound(x);227Bound* y_bound = _rce->get_bound(y);228if (x_bound->lower() >= 0 && x_bound->lower_instr() == NULL && y->as_ArrayLength() != NULL) {229_bound = new Bound(0, NULL, -1, y);230} else if (y->type()->as_IntConstant() && y->type()->as_IntConstant()->value() != 0) {231// The binary % operator is said to yield the remainder of its operands from an implied division; the232// left-hand operand is the dividend and the right-hand operand is the divisor.233//234// % operator follows from this rule that the result of the remainder operation can be negative only235// if the dividend is negative, and can be positive only if the dividend is positive. Moreover, the236// magnitude of the result is always less than the magnitude of the divisor(See JLS 15.17.3).237//238// So if y is a constant integer and not equal to 0, then we can deduce the bound of remainder operation:239// x % -y ==> [0, y - 1] Apply RCE240// x % y ==> [0, y - 1] Apply RCE241// -x % y ==> [-y + 1, 0]242// -x % -y ==> [-y + 1, 0]243if (x_bound->has_lower() && x_bound->lower() >= 0) {244_bound = new Bound(0, NULL, y->type()->as_IntConstant()->value() - 1, NULL);245} else {246_bound = new Bound();247}248} else {249_bound = new Bound();250}251} else if (!x->as_Constant() || !y->as_Constant()) {252assert(!x->as_Constant() || !y->as_Constant(), "One of the operands must be non-constant!");253if (((x->as_Constant() || y->as_Constant()) && (ao->op() == Bytecodes::_iadd)) || (y->as_Constant() && ao->op() == Bytecodes::_isub)) {254assert(ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub, "Operand must be iadd or isub");255256if (y->as_Constant()) {257Value tmp = x;258x = y;259y = tmp;260}261assert(x->as_Constant()->type()->as_IntConstant(), "Constant must be int constant!");262263// Constant now in x264int const_value = x->as_Constant()->type()->as_IntConstant()->value();265if (ao->op() == Bytecodes::_iadd || const_value != min_jint) {266if (ao->op() == Bytecodes::_isub) {267const_value = -const_value;268}269270Bound * bound = _rce->get_bound(y);271if (bound->has_upper() && bound->has_lower()) {272int new_lower = bound->lower() + const_value;273jlong new_lowerl = ((jlong)bound->lower()) + const_value;274int new_upper = bound->upper() + const_value;275jlong new_upperl = ((jlong)bound->upper()) + const_value;276277if (((jlong)new_lower) == new_lowerl && ((jlong)new_upper == new_upperl)) {278Bound *newBound = new Bound(new_lower, bound->lower_instr(), new_upper, bound->upper_instr());279_bound = newBound;280} else {281// overflow282_bound = new Bound();283}284} else {285_bound = new Bound();286}287} else {288_bound = new Bound();289}290} else {291Bound *bound = _rce->get_bound(x);292if (ao->op() == Bytecodes::_isub) {293if (bound->lower_instr() == y) {294_bound = new Bound(Instruction::geq, NULL, bound->lower());295} else {296_bound = new Bound();297}298} else {299_bound = new Bound();300}301}302}303}304305// IfOp306void RangeCheckEliminator::Visitor::do_IfOp(IfOp *ifOp)307{308if (ifOp->tval()->type()->as_IntConstant() && ifOp->fval()->type()->as_IntConstant()) {309int min = ifOp->tval()->type()->as_IntConstant()->value();310int max = ifOp->fval()->type()->as_IntConstant()->value();311if (min > max) {312// min ^= max ^= min ^= max;313int tmp = min;314min = max;315max = tmp;316}317_bound = new Bound(min, NULL, max, NULL);318}319}320321// Get bound. Returns the current bound on Value v. Normally this is the topmost element on the bound stack.322RangeCheckEliminator::Bound *RangeCheckEliminator::get_bound(Value v) {323// Wrong type or NULL -> No bound324if (!v || (!v->type()->as_IntType() && !v->type()->as_ObjectType())) return NULL;325326if (!_bounds.at(v->id())) {327// First (default) bound is calculated328// Create BoundStack329_bounds.at_put(v->id(), new BoundStack());330_visitor.clear_bound();331Value visit_value = v;332visit_value->visit(&_visitor);333Bound *bound = _visitor.bound();334if (bound) {335_bounds.at(v->id())->push(bound);336}337if (_bounds.at(v->id())->length() == 0) {338assert(!(v->as_Constant() && v->type()->as_IntConstant()), "constants not handled here");339_bounds.at(v->id())->push(new Bound());340}341} else if (_bounds.at(v->id())->length() == 0) {342// To avoid endless loops, bound is currently in calculation -> nothing known about it343return new Bound();344}345346// Return bound347return _bounds.at(v->id())->top();348}349350// Update bound351void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Instruction::Condition cond, Value value, int constant) {352if (cond == Instruction::gtr) {353cond = Instruction::geq;354constant++;355} else if (cond == Instruction::lss) {356cond = Instruction::leq;357constant--;358}359Bound *bound = new Bound(cond, value, constant);360update_bound(pushed, v, bound);361}362363// Checks for loop invariance. Returns true if the instruction is outside of the loop which is identified by loop_header.364bool RangeCheckEliminator::loop_invariant(BlockBegin *loop_header, Instruction *instruction) {365assert(loop_header, "Loop header must not be null!");366if (!instruction) return true;367return instruction->dominator_depth() < loop_header->dominator_depth();368}369370// Update bound. Pushes a new bound onto the stack. Tries to do a conjunction with the current bound.371void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Bound *bound) {372if (v->as_Constant()) {373// No bound update for constants374return;375}376if (!_bounds.at(v->id())) {377get_bound(v);378assert(_bounds.at(v->id()), "Now Stack must exist");379}380Bound *top = NULL;381if (_bounds.at(v->id())->length() > 0) {382top = _bounds.at(v->id())->top();383}384if (top) {385bound->and_op(top);386}387_bounds.at(v->id())->push(bound);388pushed.append(v->id());389}390391// Add instruction + idx for in block motion392void RangeCheckEliminator::add_access_indexed_info(InstructionList &indices, int idx, Value instruction, AccessIndexed *ai) {393int id = instruction->id();394AccessIndexedInfo *aii = _access_indexed_info.at(id);395if (aii == NULL) {396aii = new AccessIndexedInfo();397_access_indexed_info.at_put(id, aii);398indices.append(instruction);399aii->_min = idx;400aii->_max = idx;401aii->_list = new AccessIndexedList();402} else if (idx >= aii->_min && idx <= aii->_max) {403remove_range_check(ai);404return;405}406aii->_min = MIN2(aii->_min, idx);407aii->_max = MAX2(aii->_max, idx);408aii->_list->append(ai);409}410411// In block motion. Tries to reorder checks in order to reduce some of them.412// Example:413// a[i] = 0;414// a[i+2] = 0;415// a[i+1] = 0;416// In this example the check for a[i+1] would be considered as unnecessary during the first iteration.417// After this i is only checked once for i >= 0 and i+2 < a.length before the first array access. If this418// check fails, deoptimization is called.419void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList &accessIndexed, InstructionList &arrays) {420InstructionList indices;421422// Now iterate over all arrays423for (int i=0; i<arrays.length(); i++) {424int max_constant = -1;425AccessIndexedList list_constant;426Value array = arrays.at(i);427428// For all AccessIndexed-instructions in this block concerning the current array.429for(int j=0; j<accessIndexed.length(); j++) {430AccessIndexed *ai = accessIndexed.at(j);431if (ai->array() != array || !ai->check_flag(Instruction::NeedsRangeCheckFlag)) continue;432433Value index = ai->index();434Constant *c = index->as_Constant();435if (c != NULL) {436int constant_value = c->type()->as_IntConstant()->value();437if (constant_value >= 0) {438if (constant_value <= max_constant) {439// No range check needed for this440remove_range_check(ai);441} else {442max_constant = constant_value;443list_constant.append(ai);444}445}446} else {447int last_integer = 0;448Instruction *last_instruction = index;449int base = 0;450ArithmeticOp *ao = index->as_ArithmeticOp();451452while (ao != NULL && (ao->x()->as_Constant() || ao->y()->as_Constant()) && (ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub)) {453c = ao->y()->as_Constant();454Instruction *other = ao->x();455if (!c && ao->op() == Bytecodes::_iadd) {456c = ao->x()->as_Constant();457other = ao->y();458}459460if (c) {461int value = c->type()->as_IntConstant()->value();462if (value != min_jint) {463if (ao->op() == Bytecodes::_isub) {464value = -value;465}466base += value;467last_integer = base;468last_instruction = other;469}470index = other;471} else {472break;473}474ao = index->as_ArithmeticOp();475}476add_access_indexed_info(indices, last_integer, last_instruction, ai);477}478}479480// Iterate over all different indices481if (_optimistic) {482for (int i = 0; i < indices.length(); i++) {483Instruction *index_instruction = indices.at(i);484AccessIndexedInfo *info = _access_indexed_info.at(index_instruction->id());485assert(info != NULL, "Info must not be null");486487// if idx < 0, max > 0, max + idx may fall between 0 and488// length-1 and if min < 0, min + idx may overflow and be >=489// 0. The predicate wouldn't trigger but some accesses could490// be with a negative index. This test guarantees that for the491// min and max value that are kept the predicate can't let492// some incorrect accesses happen.493bool range_cond = (info->_max < 0 || info->_max + min_jint <= info->_min);494495// Generate code only if more than 2 range checks can be eliminated because of that.496// 2 because at least 2 comparisons are done497if (info->_list->length() > 2 && range_cond) {498AccessIndexed *first = info->_list->at(0);499Instruction *insert_position = first->prev();500assert(insert_position->next() == first, "prev was calculated");501ValueStack *state = first->state_before();502503// Load min Constant504Constant *min_constant = NULL;505if (info->_min != 0) {506min_constant = new Constant(new IntConstant(info->_min));507NOT_PRODUCT(min_constant->set_printable_bci(first->printable_bci()));508insert_position = insert_position->insert_after(min_constant);509}510511// Load max Constant512Constant *max_constant = NULL;513if (info->_max != 0) {514max_constant = new Constant(new IntConstant(info->_max));515NOT_PRODUCT(max_constant->set_printable_bci(first->printable_bci()));516insert_position = insert_position->insert_after(max_constant);517}518519// Load array length520Value length_instr = first->length();521if (!length_instr) {522ArrayLength *length = new ArrayLength(array, first->state_before()->copy());523length->set_exception_state(length->state_before());524length->set_flag(Instruction::DeoptimizeOnException, true);525insert_position = insert_position->insert_after_same_bci(length);526length_instr = length;527}528529// Calculate lower bound530Instruction *lower_compare = index_instruction;531if (min_constant) {532ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, min_constant, lower_compare, NULL);533insert_position = insert_position->insert_after_same_bci(ao);534lower_compare = ao;535}536537// Calculate upper bound538Instruction *upper_compare = index_instruction;539if (max_constant) {540ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, max_constant, upper_compare, NULL);541insert_position = insert_position->insert_after_same_bci(ao);542upper_compare = ao;543}544545// Trick with unsigned compare is done546int bci = NOT_PRODUCT(first->printable_bci()) PRODUCT_ONLY(-1);547insert_position = predicate(upper_compare, Instruction::aeq, length_instr, state, insert_position, bci);548insert_position = predicate_cmp_with_const(lower_compare, Instruction::leq, -1, state, insert_position);549for (int j = 0; j<info->_list->length(); j++) {550AccessIndexed *ai = info->_list->at(j);551remove_range_check(ai);552}553}554}555556if (list_constant.length() > 1) {557AccessIndexed *first = list_constant.at(0);558Instruction *insert_position = first->prev();559ValueStack *state = first->state_before();560// Load max Constant561Constant *constant = new Constant(new IntConstant(max_constant));562NOT_PRODUCT(constant->set_printable_bci(first->printable_bci()));563insert_position = insert_position->insert_after(constant);564Instruction *compare_instr = constant;565Value length_instr = first->length();566if (!length_instr) {567ArrayLength *length = new ArrayLength(array, state->copy());568length->set_exception_state(length->state_before());569length->set_flag(Instruction::DeoptimizeOnException, true);570insert_position = insert_position->insert_after_same_bci(length);571length_instr = length;572}573// Compare for greater or equal to array length574insert_position = predicate(compare_instr, Instruction::geq, length_instr, state, insert_position);575for (int j = 0; j<list_constant.length(); j++) {576AccessIndexed *ai = list_constant.at(j);577remove_range_check(ai);578}579}580}581582// Clear data structures for next array583for (int i = 0; i < indices.length(); i++) {584Instruction *index_instruction = indices.at(i);585_access_indexed_info.at_put(index_instruction->id(), NULL);586}587indices.clear();588}589}590591bool RangeCheckEliminator::set_process_block_flags(BlockBegin *block) {592Instruction *cur = block;593bool process = false;594595while (cur) {596process |= (cur->as_AccessIndexed() != NULL);597cur = cur->next();598}599600BlockList *dominates = block->dominates();601for (int i=0; i<dominates->length(); i++) {602BlockBegin *next = dominates->at(i);603process |= set_process_block_flags(next);604}605606if (!process) {607block->set(BlockBegin::donot_eliminate_range_checks);608}609return process;610}611612bool RangeCheckEliminator::is_ok_for_deoptimization(Instruction *insert_position, Instruction *array_instr, Instruction *length_instr, Instruction *lower_instr, int lower, Instruction *upper_instr, int upper) {613bool upper_check = true;614assert(lower_instr || lower >= 0, "If no lower_instr present, lower must be greater 0");615assert(!lower_instr || lower_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");616assert(!upper_instr || upper_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");617assert(array_instr, "Array instruction must exist");618assert(array_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");619assert(!length_instr || length_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");620621if (upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr) {622// static check623if (upper >= 0) return false; // would always trigger a deopt:624// array_length + x >= array_length, x >= 0 is always true625upper_check = false;626}627if (lower_instr && lower_instr->as_ArrayLength() && lower_instr->as_ArrayLength()->array() == array_instr) {628if (lower > 0) return false;629}630// No upper check required -> skip631if (upper_check && upper_instr && upper_instr->type()->as_ObjectType() && upper_instr == array_instr) {632// upper_instr is object means that the upper bound is the length633// of the upper_instr.634return false;635}636return true;637}638639Instruction* RangeCheckEliminator::insert_after(Instruction* insert_position, Instruction* instr, int bci) {640if (bci != -1) {641NOT_PRODUCT(instr->set_printable_bci(bci));642return insert_position->insert_after(instr);643} else {644return insert_position->insert_after_same_bci(instr);645}646}647648Instruction* RangeCheckEliminator::predicate(Instruction* left, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {649RangeCheckPredicate *deoptimize = new RangeCheckPredicate(left, cond, true, right, state->copy());650return insert_after(insert_position, deoptimize, bci);651}652653Instruction* RangeCheckEliminator::predicate_cmp_with_const(Instruction* instr, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) {654Constant *const_instr = new Constant(new IntConstant(constant));655insert_position = insert_after(insert_position, const_instr, bci);656return predicate(instr, cond, const_instr, state, insert_position);657}658659Instruction* RangeCheckEliminator::predicate_add(Instruction* left, int left_const, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {660Constant *constant = new Constant(new IntConstant(left_const));661insert_position = insert_after(insert_position, constant, bci);662ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, left, NULL);663insert_position = insert_position->insert_after_same_bci(ao);664return predicate(ao, cond, right, state, insert_position);665}666667Instruction* RangeCheckEliminator::predicate_add_cmp_with_const(Instruction* left, int left_const, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) {668Constant *const_instr = new Constant(new IntConstant(constant));669insert_position = insert_after(insert_position, const_instr, bci);670return predicate_add(left, left_const, cond, const_instr, state, insert_position);671}672673// Insert deoptimization674void RangeCheckEliminator::insert_deoptimization(ValueStack *state, Instruction *insert_position, Instruction *array_instr, Instruction *length_instr, Instruction *lower_instr, int lower, Instruction *upper_instr, int upper, AccessIndexed *ai) {675assert(is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, lower, upper_instr, upper), "should have been tested before");676bool upper_check = !(upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr);677678int bci = NOT_PRODUCT(ai->printable_bci()) PRODUCT_ONLY(-1);679if (lower_instr) {680assert(!lower_instr->type()->as_ObjectType(), "Must not be object type");681if (lower == 0) {682// Compare for less than 0683insert_position = predicate_cmp_with_const(lower_instr, Instruction::lss, 0, state, insert_position, bci);684} else if (lower > 0) {685// Compare for smaller 0686insert_position = predicate_add_cmp_with_const(lower_instr, lower, Instruction::lss, 0, state, insert_position, bci);687} else {688assert(lower < 0, "");689// Add 1690lower++;691lower = -lower;692// Compare for smaller or equal 0693insert_position = predicate_cmp_with_const(lower_instr, Instruction::leq, lower, state, insert_position, bci);694}695}696697// No upper check required -> skip698if (!upper_check) return;699700// We need to know length of array701if (!length_instr) {702// Load length if necessary703ArrayLength *length = new ArrayLength(array_instr, state->copy());704NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));705length->set_exception_state(length->state_before());706length->set_flag(Instruction::DeoptimizeOnException, true);707insert_position = insert_position->insert_after(length);708length_instr = length;709}710711if (!upper_instr) {712// Compare for geq array.length713insert_position = predicate_cmp_with_const(length_instr, Instruction::leq, upper, state, insert_position, bci);714} else {715if (upper_instr->type()->as_ObjectType()) {716assert(state, "must not be null");717assert(upper_instr != array_instr, "should be");718ArrayLength *length = new ArrayLength(upper_instr, state->copy());719NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));720length->set_flag(Instruction::DeoptimizeOnException, true);721length->set_exception_state(length->state_before());722insert_position = insert_position->insert_after(length);723upper_instr = length;724}725assert(upper_instr->type()->as_IntType(), "Must not be object type!");726727if (upper == 0) {728// Compare for geq array.length729insert_position = predicate(upper_instr, Instruction::geq, length_instr, state, insert_position, bci);730} else if (upper < 0) {731// Compare for geq array.length732insert_position = predicate_add(upper_instr, upper, Instruction::geq, length_instr, state, insert_position, bci);733} else {734assert(upper > 0, "");735upper = -upper;736// Compare for geq array.length737insert_position = predicate_add(length_instr, upper, Instruction::leq, upper_instr, state, insert_position, bci);738}739}740}741742// Add if condition743void RangeCheckEliminator::add_if_condition(IntegerStack &pushed, Value x, Value y, Instruction::Condition condition) {744if (y->as_Constant()) return;745746int const_value = 0;747Value instr_value = x;748Constant *c = x->as_Constant();749ArithmeticOp *ao = x->as_ArithmeticOp();750751if (c != NULL) {752const_value = c->type()->as_IntConstant()->value();753instr_value = NULL;754} else if (ao != NULL && (!ao->x()->as_Constant() || !ao->y()->as_Constant()) && ((ao->op() == Bytecodes::_isub && ao->y()->as_Constant()) || ao->op() == Bytecodes::_iadd)) {755assert(!ao->x()->as_Constant() || !ao->y()->as_Constant(), "At least one operator must be non-constant!");756assert(ao->op() == Bytecodes::_isub || ao->op() == Bytecodes::_iadd, "Operation has to be add or sub!");757c = ao->x()->as_Constant();758if (c != NULL) {759const_value = c->type()->as_IntConstant()->value();760instr_value = ao->y();761} else {762c = ao->y()->as_Constant();763if (c != NULL) {764const_value = c->type()->as_IntConstant()->value();765instr_value = ao->x();766}767}768if (ao->op() == Bytecodes::_isub) {769assert(ao->y()->as_Constant(), "1 - x not supported, only x - 1 is valid!");770if (const_value > min_jint) {771const_value = -const_value;772} else {773const_value = 0;774instr_value = x;775}776}777}778779update_bound(pushed, y, condition, instr_value, const_value);780}781782// Process If783void RangeCheckEliminator::process_if(IntegerStack &pushed, BlockBegin *block, If *cond) {784// Only if we are direct true / false successor and NOT both ! (even this may occur)785if ((cond->tsux() == block || cond->fsux() == block) && cond->tsux() != cond->fsux()) {786Instruction::Condition condition = cond->cond();787if (cond->fsux() == block) {788condition = Instruction::negate(condition);789}790Value x = cond->x();791Value y = cond->y();792if (x->type()->as_IntType() && y->type()->as_IntType()) {793add_if_condition(pushed, y, x, condition);794add_if_condition(pushed, x, y, Instruction::mirror(condition));795}796}797}798799// Process access indexed800void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai) {801TRACE_RANGE_CHECK_ELIMINATION(802tty->fill_to(block->dominator_depth()*2)803);804TRACE_RANGE_CHECK_ELIMINATION(805tty->print_cr("Access indexed: index=%d length=%d", ai->index()->id(), (ai->length() != NULL ? ai->length()->id() :-1 ))806);807808if (ai->check_flag(Instruction::NeedsRangeCheckFlag)) {809Bound *index_bound = get_bound(ai->index());810if (!index_bound->has_lower() || !index_bound->has_upper()) {811TRACE_RANGE_CHECK_ELIMINATION(812tty->fill_to(block->dominator_depth()*2);813tty->print_cr("Index instruction %d has no lower and/or no upper bound!", ai->index()->id())814);815return;816}817818Bound *array_bound;819if (ai->length()) {820array_bound = get_bound(ai->length());821} else {822array_bound = get_bound(ai->array());823}824825TRACE_RANGE_CHECK_ELIMINATION(826tty->fill_to(block->dominator_depth()*2);827tty->print("Index bound: ");828index_bound->print();829tty->print(", Array bound: ");830array_bound->print();831tty->cr();832);833834if (in_array_bound(index_bound, ai->array()) ||835(index_bound && array_bound && index_bound->is_smaller(array_bound) && !index_bound->lower_instr() && index_bound->lower() >= 0)) {836TRACE_RANGE_CHECK_ELIMINATION(837tty->fill_to(block->dominator_depth()*2);838tty->print_cr("Bounds check for instruction %d in block B%d can be fully eliminated!", ai->id(), ai->block()->block_id())839);840841remove_range_check(ai);842} else if (_optimistic && loop_header) {843assert(ai->array(), "Array must not be null!");844assert(ai->index(), "Index must not be null!");845846// Array instruction847Instruction *array_instr = ai->array();848if (!loop_invariant(loop_header, array_instr)) {849TRACE_RANGE_CHECK_ELIMINATION(850tty->fill_to(block->dominator_depth()*2);851tty->print_cr("Array %d is not loop invariant to header B%d", ai->array()->id(), loop_header->block_id())852);853return;854}855856// Lower instruction857Value index_instr = ai->index();858Value lower_instr = index_bound->lower_instr();859if (!loop_invariant(loop_header, lower_instr)) {860TRACE_RANGE_CHECK_ELIMINATION(861tty->fill_to(block->dominator_depth()*2);862tty->print_cr("Lower instruction %d not loop invariant!", lower_instr->id())863);864return;865}866if (!lower_instr && index_bound->lower() < 0) {867TRACE_RANGE_CHECK_ELIMINATION(868tty->fill_to(block->dominator_depth()*2);869tty->print_cr("Lower bound smaller than 0 (%d)!", index_bound->lower())870);871return;872}873874// Upper instruction875Value upper_instr = index_bound->upper_instr();876if (!loop_invariant(loop_header, upper_instr)) {877TRACE_RANGE_CHECK_ELIMINATION(878tty->fill_to(block->dominator_depth()*2);879tty->print_cr("Upper instruction %d not loop invariant!", upper_instr->id())880);881return;882}883884// Length instruction885Value length_instr = ai->length();886if (!loop_invariant(loop_header, length_instr)) {887// Generate length instruction yourself!888length_instr = NULL;889}890891TRACE_RANGE_CHECK_ELIMINATION(892tty->fill_to(block->dominator_depth()*2);893tty->print_cr("LOOP INVARIANT access indexed %d found in block B%d!", ai->id(), ai->block()->block_id())894);895896BlockBegin *pred_block = loop_header->dominator();897assert(pred_block != NULL, "Every loop header has a dominator!");898BlockEnd *pred_block_end = pred_block->end();899Instruction *insert_position = pred_block_end->prev();900ValueStack *state = pred_block_end->state_before();901if (pred_block_end->as_Goto() && state == NULL) state = pred_block_end->state();902assert(state, "State must not be null");903904// Add deoptimization to dominator of loop header905TRACE_RANGE_CHECK_ELIMINATION(906tty->fill_to(block->dominator_depth()*2);907tty->print_cr("Inserting deopt at bci %d in block B%d!", state->bci(), insert_position->block()->block_id())908);909910if (!is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper())) {911TRACE_RANGE_CHECK_ELIMINATION(912tty->fill_to(block->dominator_depth()*2);913tty->print_cr("Could not eliminate because of static analysis!")914);915return;916}917918insert_deoptimization(state, insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper(), ai);919920// Finally remove the range check!921remove_range_check(ai);922}923}924}925926void RangeCheckEliminator::remove_range_check(AccessIndexed *ai) {927ai->set_flag(Instruction::NeedsRangeCheckFlag, false);928// no range check, no need for the length instruction anymore929ai->clear_length();930931TRACE_RANGE_CHECK_ELIMINATION(932tty->fill_to(ai->dominator_depth()*2);933tty->print_cr("Range check for instruction %d eliminated!", ai->id());934);935936ASSERT_RANGE_CHECK_ELIMINATION(937Value array_length = ai->length();938if (!array_length) {939array_length = ai->array();940assert(array_length->type()->as_ObjectType(), "Has to be object type!");941}942int cur_constant = -1;943Value cur_value = array_length;944if (cur_value->type()->as_IntConstant()) {945cur_constant += cur_value->type()->as_IntConstant()->value();946cur_value = NULL;947}948Bound *new_index_bound = new Bound(0, NULL, cur_constant, cur_value);949add_assertions(new_index_bound, ai->index(), ai);950);951}952953// Calculate bounds for instruction in this block and children blocks in the dominator tree954void RangeCheckEliminator::calc_bounds(BlockBegin *block, BlockBegin *loop_header) {955// Ensures a valid loop_header956assert(!loop_header || loop_header->is_set(BlockBegin::linear_scan_loop_header_flag), "Loop header has to be real !");957958// Tracing output959TRACE_RANGE_CHECK_ELIMINATION(960tty->fill_to(block->dominator_depth()*2);961tty->print_cr("Block B%d", block->block_id());962);963964// Pushed stack for conditions965IntegerStack pushed;966// Process If967BlockBegin *parent = block->dominator();968if (parent != NULL) {969If *cond = parent->end()->as_If();970if (cond != NULL) {971process_if(pushed, block, cond);972}973}974975// Interate over current block976InstructionList arrays;977AccessIndexedList accessIndexed;978Instruction *cur = block;979980while (cur) {981// Ensure cur wasn't inserted during the elimination982if (cur->id() < this->_bounds.length()) {983// Process only if it is an access indexed instruction984AccessIndexed *ai = cur->as_AccessIndexed();985if (ai != NULL) {986process_access_indexed(loop_header, block, ai);987accessIndexed.append(ai);988if (!arrays.contains(ai->array())) {989arrays.append(ai->array());990}991Bound *b = get_bound(ai->index());992if (!b->lower_instr()) {993// Lower bound is constant994update_bound(pushed, ai->index(), Instruction::geq, NULL, 0);995}996if (!b->has_upper()) {997if (ai->length() && ai->length()->type()->as_IntConstant()) {998int value = ai->length()->type()->as_IntConstant()->value();999update_bound(pushed, ai->index(), Instruction::lss, NULL, value);1000} else {1001// Has no upper bound1002Instruction *instr = ai->length();1003if (instr != NULL) instr = ai->array();1004update_bound(pushed, ai->index(), Instruction::lss, instr, 0);1005}1006}1007}1008}1009cur = cur->next();1010}10111012// Output current condition stack1013TRACE_RANGE_CHECK_ELIMINATION(dump_condition_stack(block));10141015// Do in block motion of range checks1016in_block_motion(block, accessIndexed, arrays);10171018// Call all dominated blocks1019for (int i=0; i<block->dominates()->length(); i++) {1020BlockBegin *next = block->dominates()->at(i);1021if (!next->is_set(BlockBegin::donot_eliminate_range_checks)) {1022// if current block is a loop header and:1023// - next block belongs to the same loop1024// or1025// - next block belongs to an inner loop1026// then current block is the loop header for next block1027if (block->is_set(BlockBegin::linear_scan_loop_header_flag) && (block->loop_index() == next->loop_index() || next->loop_depth() > block->loop_depth())) {1028calc_bounds(next, block);1029} else {1030calc_bounds(next, loop_header);1031}1032}1033}10341035// Reset stack1036for (int i=0; i<pushed.length(); i++) {1037_bounds.at(pushed.at(i))->pop();1038}1039}10401041#ifndef PRODUCT1042// Dump condition stack1043void RangeCheckEliminator::dump_condition_stack(BlockBegin *block) {1044for (int i=0; i<_ir->linear_scan_order()->length(); i++) {1045BlockBegin *cur_block = _ir->linear_scan_order()->at(i);1046Instruction *instr = cur_block;1047for_each_phi_fun(cur_block, phi,1048BoundStack *bound_stack = _bounds.at(phi->id());1049if (bound_stack && bound_stack->length() > 0) {1050Bound *bound = bound_stack->top();1051if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != phi || bound->upper_instr() != phi || bound->lower() != 0 || bound->upper() != 0)) {1052TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());1053tty->print("i%d", phi->id());1054tty->print(": ");1055bound->print();1056tty->cr();1057);1058}1059});10601061while (!instr->as_BlockEnd()) {1062if (instr->id() < _bounds.length()) {1063BoundStack *bound_stack = _bounds.at(instr->id());1064if (bound_stack && bound_stack->length() > 0) {1065Bound *bound = bound_stack->top();1066if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != instr || bound->upper_instr() != instr || bound->lower() != 0 || bound->upper() != 0)) {1067TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());1068tty->print("i%d", instr->id());1069tty->print(": ");1070bound->print();1071tty->cr();1072);1073}1074}1075}1076instr = instr->next();1077}1078}1079}1080#endif10811082#ifdef ASSERT1083// Verification or the IR1084RangeCheckEliminator::Verification::Verification(IR *ir) : _used(BlockBegin::number_of_blocks(), BlockBegin::number_of_blocks(), false) {1085this->_ir = ir;1086ir->iterate_linear_scan_order(this);1087}10881089// Verify this block1090void RangeCheckEliminator::Verification::block_do(BlockBegin *block) {1091If *cond = block->end()->as_If();1092// Watch out: tsux and fsux can be the same!1093if (block->number_of_sux() > 1) {1094for (int i=0; i<block->number_of_sux(); i++) {1095BlockBegin *sux = block->sux_at(i);1096BlockBegin *pred = NULL;1097for (int j=0; j<sux->number_of_preds(); j++) {1098BlockBegin *cur = sux->pred_at(j);1099assert(cur != NULL, "Predecessor must not be null");1100if (!pred) {1101pred = cur;1102}1103assert(cur == pred, "Block must not have more than one predecessor if its predecessor has more than one successor");1104}1105assert(sux->number_of_preds() >= 1, "Block must have at least one predecessor");1106assert(sux->pred_at(0) == block, "Wrong successor");1107}1108}11091110BlockBegin *dominator = block->dominator();1111if (dominator) {1112assert(block != _ir->start(), "Start block must not have a dominator!");1113assert(can_reach(dominator, block), "Dominator can't reach his block !");1114assert(can_reach(_ir->start(), dominator), "Dominator is unreachable !");1115assert(!can_reach(_ir->start(), block, dominator), "Wrong dominator ! Block can be reached anyway !");1116BlockList *all_blocks = _ir->linear_scan_order();1117for (int i=0; i<all_blocks->length(); i++) {1118BlockBegin *cur = all_blocks->at(i);1119if (cur != dominator && cur != block) {1120assert(can_reach(dominator, block, cur), "There has to be another dominator!");1121}1122}1123} else {1124assert(block == _ir->start(), "Only start block must not have a dominator");1125}11261127if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) {1128int loop_index = block->loop_index();1129BlockList *all_blocks = _ir->linear_scan_order();1130assert(block->number_of_preds() >= 1, "Block must have at least one predecessor");1131assert(!block->is_set(BlockBegin::exception_entry_flag), "Loop header must not be exception handler!");11321133bool loop_through_xhandler = false;1134for (int i=0; i<block->number_of_sux(); i++) {1135BlockBegin *sux = block->sux_at(i);1136if (!loop_through_xhandler) {1137if (sux->loop_depth() == block->loop_depth() && sux->loop_index() != block->loop_index()) {1138loop_through_xhandler = is_backbranch_from_xhandler(block);1139assert(loop_through_xhandler, "Loop indices have to be the same if same depths but no backbranch from xhandler");1140}1141}1142assert(sux->loop_depth() == block->loop_depth() || sux->loop_index() != block->loop_index(), "Loop index has to be different");1143}11441145for (int i=0; i<all_blocks->length(); i++) {1146BlockBegin *cur = all_blocks->at(i);1147if (cur->loop_index() == loop_index && cur != block) {1148assert(dominates(block->dominator(), cur), "Dominator of loop header must dominate all loop blocks");1149}1150}1151}11521153Instruction *cur = block;1154while (cur) {1155assert(cur->block() == block, "Block begin has to be set correctly!");1156cur = cur->next();1157}1158}11591160// Called when a successor of a block has the same loop depth but a different loop index. This can happen if a backbranch comes from1161// an exception handler of a loop head block, for example, when a loop is only executed once on the non-exceptional path but is1162// repeated in case of an exception. In this case, the edge block->sux is not critical and was not split before.1163// Check if there is such a backbranch from an xhandler of 'block'.1164bool RangeCheckEliminator::Verification::is_backbranch_from_xhandler(BlockBegin* block) {1165for (int i = 0; i < block->number_of_exception_handlers(); i++) {1166BlockBegin *xhandler = block->exception_handler_at(i);1167for (int j = 0; j < block->number_of_preds(); j++) {1168if (dominates(xhandler, block->pred_at(j)) || xhandler == block->pred_at(j)) {1169return true;1170}1171}1172}11731174// In case of nested xhandlers, we need to walk through the loop (and all blocks belonging to exception handlers)1175// to find an xhandler of 'block'.1176if (block->number_of_exception_handlers() > 0) {1177for (int i = 0; i < block->number_of_preds(); i++) {1178BlockBegin* pred = block->pred_at(i);1179if (pred->loop_index() == block->loop_index()) {1180// Only check blocks that belong to the loop1181// Do a BFS to find an xhandler block of 'block' starting from 'pred'1182ResourceMark rm;1183ResourceBitMap visited(BlockBegin::number_of_blocks());1184BlockBeginList list;1185list.push(pred);1186while (!list.is_empty()) {1187BlockBegin* next = list.pop();1188if (!visited.at(next->block_id())) {1189visited.set_bit(next->block_id());1190for (int j = 0; j < block->number_of_exception_handlers(); j++) {1191if (next == block->exception_handler_at(j)) {1192return true;1193}1194}1195for (int j = 0; j < next->number_of_preds(); j++) {1196if (next->pred_at(j) != block) {1197list.push(next->pred_at(j));1198}1199}1200}1201}1202}1203}1204}1205return false;1206}12071208// Loop header must dominate all loop blocks1209bool RangeCheckEliminator::Verification::dominates(BlockBegin *dominator, BlockBegin *block) {1210BlockBegin *cur = block->dominator();1211while (cur && cur != dominator) {1212cur = cur->dominator();1213}1214return cur == dominator;1215}12161217// Try to reach Block end beginning in Block start and not using Block dont_use1218bool RangeCheckEliminator::Verification::can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use /* = NULL */) {1219if (start == end) return start != dont_use;1220// Simple BSF from start to end1221// BlockBeginList _current;1222for (int i=0; i < _used.length(); i++) {1223_used.at_put(i, false);1224}1225_current.trunc_to(0);1226_successors.trunc_to(0);1227if (start != dont_use) {1228_current.push(start);1229_used.at_put(start->block_id(), true);1230}12311232// BlockBeginList _successors;1233while (_current.length() > 0) {1234BlockBegin *cur = _current.pop();1235// Add exception handlers to list1236for (int i=0; i<cur->number_of_exception_handlers(); i++) {1237BlockBegin *xhandler = cur->exception_handler_at(i);1238_successors.push(xhandler);1239// Add exception handlers of _successors to list1240for (int j=0; j<xhandler->number_of_exception_handlers(); j++) {1241BlockBegin *sux_xhandler = xhandler->exception_handler_at(j);1242_successors.push(sux_xhandler);1243}1244}1245// Add normal _successors to list1246for (int i=0; i<cur->number_of_sux(); i++) {1247BlockBegin *sux = cur->sux_at(i);1248_successors.push(sux);1249// Add exception handlers of _successors to list1250for (int j=0; j<sux->number_of_exception_handlers(); j++) {1251BlockBegin *xhandler = sux->exception_handler_at(j);1252_successors.push(xhandler);1253}1254}1255for (int i=0; i<_successors.length(); i++) {1256BlockBegin *sux = _successors.at(i);1257assert(sux != NULL, "Successor must not be NULL!");1258if (sux == end) {1259return true;1260}1261if (sux != dont_use && !_used.at(sux->block_id())) {1262_used.at_put(sux->block_id(), true);1263_current.push(sux);1264}1265}1266_successors.trunc_to(0);1267}12681269return false;1270}1271#endif // ASSERT12721273// Bound1274RangeCheckEliminator::Bound::~Bound() {1275}12761277// Bound constructor1278RangeCheckEliminator::Bound::Bound() {1279this->_lower = min_jint;1280this->_upper = max_jint;1281this->_lower_instr = NULL;1282this->_upper_instr = NULL;1283}12841285// Bound constructor1286RangeCheckEliminator::Bound::Bound(int lower, Value lower_instr, int upper, Value upper_instr) {1287assert(!lower_instr || !lower_instr->as_Constant() || !lower_instr->type()->as_IntConstant(), "Must not be constant!");1288assert(!upper_instr || !upper_instr->as_Constant() || !upper_instr->type()->as_IntConstant(), "Must not be constant!");1289this->_lower = lower;1290this->_upper = upper;1291this->_lower_instr = lower_instr;1292this->_upper_instr = upper_instr;1293}12941295// Bound constructor1296RangeCheckEliminator::Bound::Bound(Instruction::Condition cond, Value v, int constant) {1297assert(!v || (v->type() && (v->type()->as_IntType() || v->type()->as_ObjectType())), "Type must be array or integer!");1298assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");12991300if (cond == Instruction::eql) {1301_lower = constant;1302_lower_instr = v;1303_upper = constant;1304_upper_instr = v;1305} else if (cond == Instruction::neq) {1306_lower = min_jint;1307_upper = max_jint;1308_lower_instr = NULL;1309_upper_instr = NULL;1310if (v == NULL) {1311if (constant == min_jint) {1312_lower++;1313}1314if (constant == max_jint) {1315_upper--;1316}1317}1318} else if (cond == Instruction::geq) {1319_lower = constant;1320_lower_instr = v;1321_upper = max_jint;1322_upper_instr = NULL;1323} else if (cond == Instruction::leq) {1324_lower = min_jint;1325_lower_instr = NULL;1326_upper = constant;1327_upper_instr = v;1328} else {1329ShouldNotReachHere();1330}1331}13321333// Set lower1334void RangeCheckEliminator::Bound::set_lower(int value, Value v) {1335assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");1336this->_lower = value;1337this->_lower_instr = v;1338}13391340// Set upper1341void RangeCheckEliminator::Bound::set_upper(int value, Value v) {1342assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");1343this->_upper = value;1344this->_upper_instr = v;1345}13461347// Add constant -> no overflow may occur1348void RangeCheckEliminator::Bound::add_constant(int value) {1349this->_lower += value;1350this->_upper += value;1351}13521353// or1354void RangeCheckEliminator::Bound::or_op(Bound *b) {1355// Watch out, bound is not guaranteed not to overflow!1356// Update lower bound1357if (_lower_instr != b->_lower_instr || (_lower_instr && _lower != b->_lower)) {1358_lower_instr = NULL;1359_lower = min_jint;1360} else {1361_lower = MIN2(_lower, b->_lower);1362}1363// Update upper bound1364if (_upper_instr != b->_upper_instr || (_upper_instr && _upper != b->_upper)) {1365_upper_instr = NULL;1366_upper = max_jint;1367} else {1368_upper = MAX2(_upper, b->_upper);1369}1370}13711372// and1373void RangeCheckEliminator::Bound::and_op(Bound *b) {1374// Update lower bound1375if (_lower_instr == b->_lower_instr) {1376_lower = MAX2(_lower, b->_lower);1377}1378if (b->has_lower()) {1379bool set = true;1380if (_lower_instr != NULL && b->_lower_instr != NULL) {1381set = (_lower_instr->dominator_depth() > b->_lower_instr->dominator_depth());1382}1383if (set) {1384_lower = b->_lower;1385_lower_instr = b->_lower_instr;1386}1387}1388// Update upper bound1389if (_upper_instr == b->_upper_instr) {1390_upper = MIN2(_upper, b->_upper);1391}1392if (b->has_upper()) {1393bool set = true;1394if (_upper_instr != NULL && b->_upper_instr != NULL) {1395set = (_upper_instr->dominator_depth() > b->_upper_instr->dominator_depth());1396}1397if (set) {1398_upper = b->_upper;1399_upper_instr = b->_upper_instr;1400}1401}1402}14031404// has_upper1405bool RangeCheckEliminator::Bound::has_upper() {1406return _upper_instr != NULL || _upper < max_jint;1407}14081409// is_smaller1410bool RangeCheckEliminator::Bound::is_smaller(Bound *b) {1411if (b->_lower_instr != _upper_instr) {1412return false;1413}1414return _upper < b->_lower;1415}14161417// has_lower1418bool RangeCheckEliminator::Bound::has_lower() {1419return _lower_instr != NULL || _lower > min_jint;1420}14211422// in_array_bound1423bool RangeCheckEliminator::in_array_bound(Bound *bound, Value array){1424if (!bound) return false;1425assert(array != NULL, "Must not be null!");1426assert(bound != NULL, "Must not be null!");1427if (bound->lower() >=0 && bound->lower_instr() == NULL && bound->upper() < 0 && bound->upper_instr() != NULL) {1428ArrayLength *len = bound->upper_instr()->as_ArrayLength();1429if (bound->upper_instr() == array || (len != NULL && len->array() == array)) {1430return true;1431}1432}1433return false;1434}14351436// remove_lower1437void RangeCheckEliminator::Bound::remove_lower() {1438_lower = min_jint;1439_lower_instr = NULL;1440}14411442// remove_upper1443void RangeCheckEliminator::Bound::remove_upper() {1444_upper = max_jint;1445_upper_instr = NULL;1446}14471448// upper1449int RangeCheckEliminator::Bound::upper() {1450return _upper;1451}14521453// lower1454int RangeCheckEliminator::Bound::lower() {1455return _lower;1456}14571458// upper_instr1459Value RangeCheckEliminator::Bound::upper_instr() {1460return _upper_instr;1461}14621463// lower_instr1464Value RangeCheckEliminator::Bound::lower_instr() {1465return _lower_instr;1466}146714681469void RangeCheckEliminator::Bound::print() {1470tty->print("%s", "");1471if (this->_lower_instr || this->_lower != min_jint) {1472if (this->_lower_instr) {1473tty->print("i%d", this->_lower_instr->id());1474if (this->_lower > 0) {1475tty->print("+%d", _lower);1476}1477if (this->_lower < 0) {1478tty->print("%d", _lower);1479}1480} else {1481tty->print("%d", _lower);1482}1483tty->print(" <= ");1484}1485tty->print("x");1486if (this->_upper_instr || this->_upper != max_jint) {1487tty->print(" <= ");1488if (this->_upper_instr) {1489tty->print("i%d", this->_upper_instr->id());1490if (this->_upper > 0) {1491tty->print("+%d", _upper);1492}1493if (this->_upper < 0) {1494tty->print("%d", _upper);1495}1496} else {1497tty->print("%d", _upper);1498}1499}1500}15011502// Copy1503RangeCheckEliminator::Bound *RangeCheckEliminator::Bound::copy() {1504Bound *b = new Bound();1505b->_lower = _lower;1506b->_lower_instr = _lower_instr;1507b->_upper = _upper;1508b->_upper_instr = _upper_instr;1509return b;1510}15111512#ifdef ASSERT1513// Add assertion1514void RangeCheckEliminator::Bound::add_assertion(Instruction *instruction, Instruction *position, int i, Value instr, Instruction::Condition cond) {1515Instruction *result = position;1516Instruction *compare_with = NULL;1517ValueStack *state = position->state_before();1518if (position->as_BlockEnd() && !position->as_Goto()) {1519state = position->as_BlockEnd()->state_before();1520}1521Instruction *instruction_before = position->prev();1522if (position->as_Return() && Compilation::current()->method()->is_synchronized() && instruction_before->as_MonitorExit()) {1523instruction_before = instruction_before->prev();1524}1525result = instruction_before;1526// Load constant only if needed1527Constant *constant = NULL;1528if (i != 0 || !instr) {1529constant = new Constant(new IntConstant(i));1530NOT_PRODUCT(constant->set_printable_bci(position->printable_bci()));1531result = result->insert_after(constant);1532compare_with = constant;1533}15341535if (instr) {1536assert(instr->type()->as_ObjectType() || instr->type()->as_IntType(), "Type must be array or integer!");1537compare_with = instr;1538// Load array length if necessary1539Instruction *op = instr;1540if (instr->type()->as_ObjectType()) {1541assert(state, "must not be null");1542ArrayLength *length = new ArrayLength(instr, state->copy());1543NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));1544length->set_exception_state(length->state_before());1545result = result->insert_after(length);1546op = length;1547compare_with = length;1548}1549// Add operation only if necessary1550if (constant) {1551ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, op, NULL);1552NOT_PRODUCT(ao->set_printable_bci(position->printable_bci()));1553result = result->insert_after(ao);1554compare_with = ao;1555// TODO: Check that add operation does not overflow!1556}1557}1558assert(compare_with != NULL, "You have to compare with something!");1559assert(instruction != NULL, "Instruction must not be null!");15601561if (instruction->type()->as_ObjectType()) {1562// Load array length if necessary1563Instruction *op = instruction;1564assert(state, "must not be null");1565ArrayLength *length = new ArrayLength(instruction, state->copy());1566length->set_exception_state(length->state_before());1567NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));1568result = result->insert_after(length);1569instruction = length;1570}15711572Assert *assert = new Assert(instruction, cond, false, compare_with);1573NOT_PRODUCT(assert->set_printable_bci(position->printable_bci()));1574result->insert_after(assert);1575}15761577// Add assertions1578void RangeCheckEliminator::add_assertions(Bound *bound, Instruction *instruction, Instruction *position) {1579// Add lower bound assertion1580if (bound->has_lower()) {1581bound->add_assertion(instruction, position, bound->lower(), bound->lower_instr(), Instruction::geq);1582}1583// Add upper bound assertion1584if (bound->has_upper()) {1585bound->add_assertion(instruction, position, bound->upper(), bound->upper_instr(), Instruction::leq);1586}1587}1588#endif158915901591