Path: blob/master/src/hotspot/share/c1/c1_RangeCheckElimination.cpp
64440 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;367for (BlockBegin *d = loop_header->dominator(); d != NULL; d = d->dominator()) {368if (d == instruction->block()) {369return true;370}371}372return false;373}374375// Update bound. Pushes a new bound onto the stack. Tries to do a conjunction with the current bound.376void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Bound *bound) {377if (v->as_Constant()) {378// No bound update for constants379return;380}381if (!_bounds.at(v->id())) {382get_bound(v);383assert(_bounds.at(v->id()), "Now Stack must exist");384}385Bound *top = NULL;386if (_bounds.at(v->id())->length() > 0) {387top = _bounds.at(v->id())->top();388}389if (top) {390bound->and_op(top);391}392_bounds.at(v->id())->push(bound);393pushed.append(v->id());394}395396// Add instruction + idx for in block motion397void RangeCheckEliminator::add_access_indexed_info(InstructionList &indices, int idx, Value instruction, AccessIndexed *ai) {398int id = instruction->id();399AccessIndexedInfo *aii = _access_indexed_info.at(id);400if (aii == NULL) {401aii = new AccessIndexedInfo();402_access_indexed_info.at_put(id, aii);403indices.append(instruction);404aii->_min = idx;405aii->_max = idx;406aii->_list = new AccessIndexedList();407} else if (idx >= aii->_min && idx <= aii->_max) {408remove_range_check(ai);409return;410}411aii->_min = MIN2(aii->_min, idx);412aii->_max = MAX2(aii->_max, idx);413aii->_list->append(ai);414}415416// In block motion. Tries to reorder checks in order to reduce some of them.417// Example:418// a[i] = 0;419// a[i+2] = 0;420// a[i+1] = 0;421// In this example the check for a[i+1] would be considered as unnecessary during the first iteration.422// After this i is only checked once for i >= 0 and i+2 < a.length before the first array access. If this423// check fails, deoptimization is called.424void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList &accessIndexed, InstructionList &arrays) {425InstructionList indices;426427// Now iterate over all arrays428for (int i=0; i<arrays.length(); i++) {429int max_constant = -1;430AccessIndexedList list_constant;431Value array = arrays.at(i);432433// For all AccessIndexed-instructions in this block concerning the current array.434for(int j=0; j<accessIndexed.length(); j++) {435AccessIndexed *ai = accessIndexed.at(j);436if (ai->array() != array || !ai->check_flag(Instruction::NeedsRangeCheckFlag)) continue;437438Value index = ai->index();439Constant *c = index->as_Constant();440if (c != NULL) {441int constant_value = c->type()->as_IntConstant()->value();442if (constant_value >= 0) {443if (constant_value <= max_constant) {444// No range check needed for this445remove_range_check(ai);446} else {447max_constant = constant_value;448list_constant.append(ai);449}450}451} else {452int last_integer = 0;453Instruction *last_instruction = index;454int base = 0;455ArithmeticOp *ao = index->as_ArithmeticOp();456457while (ao != NULL && (ao->x()->as_Constant() || ao->y()->as_Constant()) && (ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub)) {458c = ao->y()->as_Constant();459Instruction *other = ao->x();460if (!c && ao->op() == Bytecodes::_iadd) {461c = ao->x()->as_Constant();462other = ao->y();463}464465if (c) {466int value = c->type()->as_IntConstant()->value();467if (value != min_jint) {468if (ao->op() == Bytecodes::_isub) {469value = -value;470}471base += value;472last_integer = base;473last_instruction = other;474}475index = other;476} else {477break;478}479ao = index->as_ArithmeticOp();480}481add_access_indexed_info(indices, last_integer, last_instruction, ai);482}483}484485// Iterate over all different indices486if (_optimistic) {487for (int i = 0; i < indices.length(); i++) {488Instruction *index_instruction = indices.at(i);489AccessIndexedInfo *info = _access_indexed_info.at(index_instruction->id());490assert(info != NULL, "Info must not be null");491492// if idx < 0, max > 0, max + idx may fall between 0 and493// length-1 and if min < 0, min + idx may overflow and be >=494// 0. The predicate wouldn't trigger but some accesses could495// be with a negative index. This test guarantees that for the496// min and max value that are kept the predicate can't let497// some incorrect accesses happen.498bool range_cond = (info->_max < 0 || info->_max + min_jint <= info->_min);499500// Generate code only if more than 2 range checks can be eliminated because of that.501// 2 because at least 2 comparisons are done502if (info->_list->length() > 2 && range_cond) {503AccessIndexed *first = info->_list->at(0);504Instruction *insert_position = first->prev();505assert(insert_position->next() == first, "prev was calculated");506ValueStack *state = first->state_before();507508// Load min Constant509Constant *min_constant = NULL;510if (info->_min != 0) {511min_constant = new Constant(new IntConstant(info->_min));512NOT_PRODUCT(min_constant->set_printable_bci(first->printable_bci()));513insert_position = insert_position->insert_after(min_constant);514}515516// Load max Constant517Constant *max_constant = NULL;518if (info->_max != 0) {519max_constant = new Constant(new IntConstant(info->_max));520NOT_PRODUCT(max_constant->set_printable_bci(first->printable_bci()));521insert_position = insert_position->insert_after(max_constant);522}523524// Load array length525Value length_instr = first->length();526if (!length_instr) {527ArrayLength *length = new ArrayLength(array, first->state_before()->copy());528length->set_exception_state(length->state_before());529length->set_flag(Instruction::DeoptimizeOnException, true);530insert_position = insert_position->insert_after_same_bci(length);531length_instr = length;532}533534// Calculate lower bound535Instruction *lower_compare = index_instruction;536if (min_constant) {537ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, min_constant, lower_compare, NULL);538insert_position = insert_position->insert_after_same_bci(ao);539lower_compare = ao;540}541542// Calculate upper bound543Instruction *upper_compare = index_instruction;544if (max_constant) {545ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, max_constant, upper_compare, NULL);546insert_position = insert_position->insert_after_same_bci(ao);547upper_compare = ao;548}549550// Trick with unsigned compare is done551int bci = NOT_PRODUCT(first->printable_bci()) PRODUCT_ONLY(-1);552insert_position = predicate(upper_compare, Instruction::aeq, length_instr, state, insert_position, bci);553insert_position = predicate_cmp_with_const(lower_compare, Instruction::leq, -1, state, insert_position);554for (int j = 0; j<info->_list->length(); j++) {555AccessIndexed *ai = info->_list->at(j);556remove_range_check(ai);557}558}559}560561if (list_constant.length() > 1) {562AccessIndexed *first = list_constant.at(0);563Instruction *insert_position = first->prev();564ValueStack *state = first->state_before();565// Load max Constant566Constant *constant = new Constant(new IntConstant(max_constant));567NOT_PRODUCT(constant->set_printable_bci(first->printable_bci()));568insert_position = insert_position->insert_after(constant);569Instruction *compare_instr = constant;570Value length_instr = first->length();571if (!length_instr) {572ArrayLength *length = new ArrayLength(array, state->copy());573length->set_exception_state(length->state_before());574length->set_flag(Instruction::DeoptimizeOnException, true);575insert_position = insert_position->insert_after_same_bci(length);576length_instr = length;577}578// Compare for greater or equal to array length579insert_position = predicate(compare_instr, Instruction::geq, length_instr, state, insert_position);580for (int j = 0; j<list_constant.length(); j++) {581AccessIndexed *ai = list_constant.at(j);582remove_range_check(ai);583}584}585}586587// Clear data structures for next array588for (int i = 0; i < indices.length(); i++) {589Instruction *index_instruction = indices.at(i);590_access_indexed_info.at_put(index_instruction->id(), NULL);591}592indices.clear();593}594}595596bool RangeCheckEliminator::set_process_block_flags(BlockBegin *block) {597Instruction *cur = block;598bool process = false;599600while (cur) {601process |= (cur->as_AccessIndexed() != NULL);602cur = cur->next();603}604605BlockList *dominates = block->dominates();606for (int i=0; i<dominates->length(); i++) {607BlockBegin *next = dominates->at(i);608process |= set_process_block_flags(next);609}610611if (!process) {612block->set(BlockBegin::donot_eliminate_range_checks);613}614return process;615}616617bool RangeCheckEliminator::is_ok_for_deoptimization(Instruction *insert_position, Instruction *array_instr, Instruction *length_instr, Instruction *lower_instr, int lower, Instruction *upper_instr, int upper) {618bool upper_check = true;619assert(lower_instr || lower >= 0, "If no lower_instr present, lower must be greater 0");620assert(!lower_instr || lower_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");621assert(!upper_instr || upper_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");622assert(array_instr, "Array instruction must exist");623assert(array_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");624assert(!length_instr || length_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");625626if (upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr) {627// static check628if (upper >= 0) return false; // would always trigger a deopt:629// array_length + x >= array_length, x >= 0 is always true630upper_check = false;631}632if (lower_instr && lower_instr->as_ArrayLength() && lower_instr->as_ArrayLength()->array() == array_instr) {633if (lower > 0) return false;634}635// No upper check required -> skip636if (upper_check && upper_instr && upper_instr->type()->as_ObjectType() && upper_instr == array_instr) {637// upper_instr is object means that the upper bound is the length638// of the upper_instr.639return false;640}641return true;642}643644Instruction* RangeCheckEliminator::insert_after(Instruction* insert_position, Instruction* instr, int bci) {645if (bci != -1) {646NOT_PRODUCT(instr->set_printable_bci(bci));647return insert_position->insert_after(instr);648} else {649return insert_position->insert_after_same_bci(instr);650}651}652653Instruction* RangeCheckEliminator::predicate(Instruction* left, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {654RangeCheckPredicate *deoptimize = new RangeCheckPredicate(left, cond, true, right, state->copy());655return insert_after(insert_position, deoptimize, bci);656}657658Instruction* RangeCheckEliminator::predicate_cmp_with_const(Instruction* instr, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) {659Constant *const_instr = new Constant(new IntConstant(constant));660insert_position = insert_after(insert_position, const_instr, bci);661return predicate(instr, cond, const_instr, state, insert_position);662}663664Instruction* RangeCheckEliminator::predicate_add(Instruction* left, int left_const, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {665Constant *constant = new Constant(new IntConstant(left_const));666insert_position = insert_after(insert_position, constant, bci);667ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, left, NULL);668insert_position = insert_position->insert_after_same_bci(ao);669return predicate(ao, cond, right, state, insert_position);670}671672Instruction* RangeCheckEliminator::predicate_add_cmp_with_const(Instruction* left, int left_const, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) {673Constant *const_instr = new Constant(new IntConstant(constant));674insert_position = insert_after(insert_position, const_instr, bci);675return predicate_add(left, left_const, cond, const_instr, state, insert_position);676}677678// Insert deoptimization679void 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) {680assert(is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, lower, upper_instr, upper), "should have been tested before");681bool upper_check = !(upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr);682683int bci = NOT_PRODUCT(ai->printable_bci()) PRODUCT_ONLY(-1);684if (lower_instr) {685assert(!lower_instr->type()->as_ObjectType(), "Must not be object type");686if (lower == 0) {687// Compare for less than 0688insert_position = predicate_cmp_with_const(lower_instr, Instruction::lss, 0, state, insert_position, bci);689} else if (lower > 0) {690// Compare for smaller 0691insert_position = predicate_add_cmp_with_const(lower_instr, lower, Instruction::lss, 0, state, insert_position, bci);692} else {693assert(lower < 0, "");694// Add 1695lower++;696lower = -lower;697// Compare for smaller or equal 0698insert_position = predicate_cmp_with_const(lower_instr, Instruction::leq, lower, state, insert_position, bci);699}700}701702// No upper check required -> skip703if (!upper_check) return;704705// We need to know length of array706if (!length_instr) {707// Load length if necessary708ArrayLength *length = new ArrayLength(array_instr, state->copy());709NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));710length->set_exception_state(length->state_before());711length->set_flag(Instruction::DeoptimizeOnException, true);712insert_position = insert_position->insert_after(length);713length_instr = length;714}715716if (!upper_instr) {717// Compare for geq array.length718insert_position = predicate_cmp_with_const(length_instr, Instruction::leq, upper, state, insert_position, bci);719} else {720if (upper_instr->type()->as_ObjectType()) {721assert(state, "must not be null");722assert(upper_instr != array_instr, "should be");723ArrayLength *length = new ArrayLength(upper_instr, state->copy());724NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));725length->set_flag(Instruction::DeoptimizeOnException, true);726length->set_exception_state(length->state_before());727insert_position = insert_position->insert_after(length);728upper_instr = length;729}730assert(upper_instr->type()->as_IntType(), "Must not be object type!");731732if (upper == 0) {733// Compare for geq array.length734insert_position = predicate(upper_instr, Instruction::geq, length_instr, state, insert_position, bci);735} else if (upper < 0) {736// Compare for geq array.length737insert_position = predicate_add(upper_instr, upper, Instruction::geq, length_instr, state, insert_position, bci);738} else {739assert(upper > 0, "");740upper = -upper;741// Compare for geq array.length742insert_position = predicate_add(length_instr, upper, Instruction::leq, upper_instr, state, insert_position, bci);743}744}745}746747// Add if condition748void RangeCheckEliminator::add_if_condition(IntegerStack &pushed, Value x, Value y, Instruction::Condition condition) {749if (y->as_Constant()) return;750751int const_value = 0;752Value instr_value = x;753Constant *c = x->as_Constant();754ArithmeticOp *ao = x->as_ArithmeticOp();755756if (c != NULL) {757const_value = c->type()->as_IntConstant()->value();758instr_value = NULL;759} else if (ao != NULL && (!ao->x()->as_Constant() || !ao->y()->as_Constant()) && ((ao->op() == Bytecodes::_isub && ao->y()->as_Constant()) || ao->op() == Bytecodes::_iadd)) {760assert(!ao->x()->as_Constant() || !ao->y()->as_Constant(), "At least one operator must be non-constant!");761assert(ao->op() == Bytecodes::_isub || ao->op() == Bytecodes::_iadd, "Operation has to be add or sub!");762c = ao->x()->as_Constant();763if (c != NULL) {764const_value = c->type()->as_IntConstant()->value();765instr_value = ao->y();766} else {767c = ao->y()->as_Constant();768if (c != NULL) {769const_value = c->type()->as_IntConstant()->value();770instr_value = ao->x();771}772}773if (ao->op() == Bytecodes::_isub) {774assert(ao->y()->as_Constant(), "1 - x not supported, only x - 1 is valid!");775if (const_value > min_jint) {776const_value = -const_value;777} else {778const_value = 0;779instr_value = x;780}781}782}783784update_bound(pushed, y, condition, instr_value, const_value);785}786787// Process If788void RangeCheckEliminator::process_if(IntegerStack &pushed, BlockBegin *block, If *cond) {789// Only if we are direct true / false successor and NOT both ! (even this may occur)790if ((cond->tsux() == block || cond->fsux() == block) && cond->tsux() != cond->fsux()) {791Instruction::Condition condition = cond->cond();792if (cond->fsux() == block) {793condition = Instruction::negate(condition);794}795Value x = cond->x();796Value y = cond->y();797if (x->type()->as_IntType() && y->type()->as_IntType()) {798add_if_condition(pushed, y, x, condition);799add_if_condition(pushed, x, y, Instruction::mirror(condition));800}801}802}803804// Process access indexed805void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai) {806TRACE_RANGE_CHECK_ELIMINATION(807tty->fill_to(block->dominator_depth()*2)808);809TRACE_RANGE_CHECK_ELIMINATION(810tty->print_cr("Access indexed: index=%d length=%d", ai->index()->id(), (ai->length() != NULL ? ai->length()->id() :-1 ))811);812813if (ai->check_flag(Instruction::NeedsRangeCheckFlag)) {814Bound *index_bound = get_bound(ai->index());815if (!index_bound->has_lower() || !index_bound->has_upper()) {816TRACE_RANGE_CHECK_ELIMINATION(817tty->fill_to(block->dominator_depth()*2);818tty->print_cr("Index instruction %d has no lower and/or no upper bound!", ai->index()->id())819);820return;821}822823Bound *array_bound;824if (ai->length()) {825array_bound = get_bound(ai->length());826} else {827array_bound = get_bound(ai->array());828}829830TRACE_RANGE_CHECK_ELIMINATION(831tty->fill_to(block->dominator_depth()*2);832tty->print("Index bound: ");833index_bound->print();834tty->print(", Array bound: ");835array_bound->print();836tty->cr();837);838839if (in_array_bound(index_bound, ai->array()) ||840(index_bound && array_bound && index_bound->is_smaller(array_bound) && !index_bound->lower_instr() && index_bound->lower() >= 0)) {841TRACE_RANGE_CHECK_ELIMINATION(842tty->fill_to(block->dominator_depth()*2);843tty->print_cr("Bounds check for instruction %d in block B%d can be fully eliminated!", ai->id(), ai->block()->block_id())844);845846remove_range_check(ai);847} else if (_optimistic && loop_header) {848assert(ai->array(), "Array must not be null!");849assert(ai->index(), "Index must not be null!");850851// Array instruction852Instruction *array_instr = ai->array();853if (!loop_invariant(loop_header, array_instr)) {854TRACE_RANGE_CHECK_ELIMINATION(855tty->fill_to(block->dominator_depth()*2);856tty->print_cr("Array %d is not loop invariant to header B%d", ai->array()->id(), loop_header->block_id())857);858return;859}860861// Lower instruction862Value index_instr = ai->index();863Value lower_instr = index_bound->lower_instr();864if (!loop_invariant(loop_header, lower_instr)) {865TRACE_RANGE_CHECK_ELIMINATION(866tty->fill_to(block->dominator_depth()*2);867tty->print_cr("Lower instruction %d not loop invariant!", lower_instr->id())868);869return;870}871if (!lower_instr && index_bound->lower() < 0) {872TRACE_RANGE_CHECK_ELIMINATION(873tty->fill_to(block->dominator_depth()*2);874tty->print_cr("Lower bound smaller than 0 (%d)!", index_bound->lower())875);876return;877}878879// Upper instruction880Value upper_instr = index_bound->upper_instr();881if (!loop_invariant(loop_header, upper_instr)) {882TRACE_RANGE_CHECK_ELIMINATION(883tty->fill_to(block->dominator_depth()*2);884tty->print_cr("Upper instruction %d not loop invariant!", upper_instr->id())885);886return;887}888889// Length instruction890Value length_instr = ai->length();891if (!loop_invariant(loop_header, length_instr)) {892// Generate length instruction yourself!893length_instr = NULL;894}895896TRACE_RANGE_CHECK_ELIMINATION(897tty->fill_to(block->dominator_depth()*2);898tty->print_cr("LOOP INVARIANT access indexed %d found in block B%d!", ai->id(), ai->block()->block_id())899);900901BlockBegin *pred_block = loop_header->dominator();902assert(pred_block != NULL, "Every loop header has a dominator!");903BlockEnd *pred_block_end = pred_block->end();904Instruction *insert_position = pred_block_end->prev();905ValueStack *state = pred_block_end->state_before();906if (pred_block_end->as_Goto() && state == NULL) state = pred_block_end->state();907assert(state, "State must not be null");908909// Add deoptimization to dominator of loop header910TRACE_RANGE_CHECK_ELIMINATION(911tty->fill_to(block->dominator_depth()*2);912tty->print_cr("Inserting deopt at bci %d in block B%d!", state->bci(), insert_position->block()->block_id())913);914915if (!is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper())) {916TRACE_RANGE_CHECK_ELIMINATION(917tty->fill_to(block->dominator_depth()*2);918tty->print_cr("Could not eliminate because of static analysis!")919);920return;921}922923insert_deoptimization(state, insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper(), ai);924925// Finally remove the range check!926remove_range_check(ai);927}928}929}930931void RangeCheckEliminator::remove_range_check(AccessIndexed *ai) {932ai->set_flag(Instruction::NeedsRangeCheckFlag, false);933// no range check, no need for the length instruction anymore934ai->clear_length();935936TRACE_RANGE_CHECK_ELIMINATION(937tty->fill_to(ai->dominator_depth()*2);938tty->print_cr("Range check for instruction %d eliminated!", ai->id());939);940941ASSERT_RANGE_CHECK_ELIMINATION(942Value array_length = ai->length();943if (!array_length) {944array_length = ai->array();945assert(array_length->type()->as_ObjectType(), "Has to be object type!");946}947int cur_constant = -1;948Value cur_value = array_length;949if (cur_value->type()->as_IntConstant()) {950cur_constant += cur_value->type()->as_IntConstant()->value();951cur_value = NULL;952}953Bound *new_index_bound = new Bound(0, NULL, cur_constant, cur_value);954add_assertions(new_index_bound, ai->index(), ai);955);956}957958// Calculate bounds for instruction in this block and children blocks in the dominator tree959void RangeCheckEliminator::calc_bounds(BlockBegin *block, BlockBegin *loop_header) {960// Ensures a valid loop_header961assert(!loop_header || loop_header->is_set(BlockBegin::linear_scan_loop_header_flag), "Loop header has to be real !");962963// Tracing output964TRACE_RANGE_CHECK_ELIMINATION(965tty->fill_to(block->dominator_depth()*2);966tty->print_cr("Block B%d", block->block_id());967);968969// Pushed stack for conditions970IntegerStack pushed;971// Process If972BlockBegin *parent = block->dominator();973if (parent != NULL) {974If *cond = parent->end()->as_If();975if (cond != NULL) {976process_if(pushed, block, cond);977}978}979980// Interate over current block981InstructionList arrays;982AccessIndexedList accessIndexed;983Instruction *cur = block;984985while (cur) {986// Ensure cur wasn't inserted during the elimination987if (cur->id() < this->_bounds.length()) {988// Process only if it is an access indexed instruction989AccessIndexed *ai = cur->as_AccessIndexed();990if (ai != NULL) {991process_access_indexed(loop_header, block, ai);992accessIndexed.append(ai);993if (!arrays.contains(ai->array())) {994arrays.append(ai->array());995}996Bound *b = get_bound(ai->index());997if (!b->lower_instr()) {998// Lower bound is constant999update_bound(pushed, ai->index(), Instruction::geq, NULL, 0);1000}1001if (!b->has_upper()) {1002if (ai->length() && ai->length()->type()->as_IntConstant()) {1003int value = ai->length()->type()->as_IntConstant()->value();1004update_bound(pushed, ai->index(), Instruction::lss, NULL, value);1005} else {1006// Has no upper bound1007Instruction *instr = ai->length();1008if (instr == NULL) instr = ai->array();1009update_bound(pushed, ai->index(), Instruction::lss, instr, 0);1010}1011}1012}1013}1014cur = cur->next();1015}10161017// Output current condition stack1018TRACE_RANGE_CHECK_ELIMINATION(dump_condition_stack(block));10191020// Do in block motion of range checks1021in_block_motion(block, accessIndexed, arrays);10221023// Call all dominated blocks1024for (int i=0; i<block->dominates()->length(); i++) {1025BlockBegin *next = block->dominates()->at(i);1026if (!next->is_set(BlockBegin::donot_eliminate_range_checks)) {1027// if current block is a loop header and:1028// - next block belongs to the same loop1029// or1030// - next block belongs to an inner loop1031// then current block is the loop header for next block1032if (block->is_set(BlockBegin::linear_scan_loop_header_flag) && (block->loop_index() == next->loop_index() || next->loop_depth() > block->loop_depth())) {1033calc_bounds(next, block);1034} else {1035calc_bounds(next, loop_header);1036}1037}1038}10391040// Reset stack1041for (int i=0; i<pushed.length(); i++) {1042_bounds.at(pushed.at(i))->pop();1043}1044}10451046#ifndef PRODUCT1047// Dump condition stack1048void RangeCheckEliminator::dump_condition_stack(BlockBegin *block) {1049for (int i=0; i<_ir->linear_scan_order()->length(); i++) {1050BlockBegin *cur_block = _ir->linear_scan_order()->at(i);1051Instruction *instr = cur_block;1052for_each_phi_fun(cur_block, phi,1053BoundStack *bound_stack = _bounds.at(phi->id());1054if (bound_stack && bound_stack->length() > 0) {1055Bound *bound = bound_stack->top();1056if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != phi || bound->upper_instr() != phi || bound->lower() != 0 || bound->upper() != 0)) {1057TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());1058tty->print("i%d", phi->id());1059tty->print(": ");1060bound->print();1061tty->cr();1062);1063}1064});10651066while (!instr->as_BlockEnd()) {1067if (instr->id() < _bounds.length()) {1068BoundStack *bound_stack = _bounds.at(instr->id());1069if (bound_stack && bound_stack->length() > 0) {1070Bound *bound = bound_stack->top();1071if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != instr || bound->upper_instr() != instr || bound->lower() != 0 || bound->upper() != 0)) {1072TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());1073tty->print("i%d", instr->id());1074tty->print(": ");1075bound->print();1076tty->cr();1077);1078}1079}1080}1081instr = instr->next();1082}1083}1084}1085#endif10861087#ifdef ASSERT1088// Verification or the IR1089RangeCheckEliminator::Verification::Verification(IR *ir) : _used(BlockBegin::number_of_blocks(), BlockBegin::number_of_blocks(), false) {1090this->_ir = ir;1091ir->iterate_linear_scan_order(this);1092}10931094// Verify this block1095void RangeCheckEliminator::Verification::block_do(BlockBegin *block) {1096If *cond = block->end()->as_If();1097// Watch out: tsux and fsux can be the same!1098if (block->number_of_sux() > 1) {1099for (int i=0; i<block->number_of_sux(); i++) {1100BlockBegin *sux = block->sux_at(i);1101BlockBegin *pred = NULL;1102for (int j=0; j<sux->number_of_preds(); j++) {1103BlockBegin *cur = sux->pred_at(j);1104assert(cur != NULL, "Predecessor must not be null");1105if (!pred) {1106pred = cur;1107}1108assert(cur == pred, "Block must not have more than one predecessor if its predecessor has more than one successor");1109}1110assert(sux->number_of_preds() >= 1, "Block must have at least one predecessor");1111assert(sux->pred_at(0) == block, "Wrong successor");1112}1113}11141115BlockBegin *dominator = block->dominator();1116if (dominator) {1117assert(block != _ir->start(), "Start block must not have a dominator!");1118assert(can_reach(dominator, block), "Dominator can't reach his block !");1119assert(can_reach(_ir->start(), dominator), "Dominator is unreachable !");1120assert(!can_reach(_ir->start(), block, dominator), "Wrong dominator ! Block can be reached anyway !");1121BlockList *all_blocks = _ir->linear_scan_order();1122for (int i=0; i<all_blocks->length(); i++) {1123BlockBegin *cur = all_blocks->at(i);1124if (cur != dominator && cur != block) {1125assert(can_reach(dominator, block, cur), "There has to be another dominator!");1126}1127}1128} else {1129assert(block == _ir->start(), "Only start block must not have a dominator");1130}11311132if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) {1133int loop_index = block->loop_index();1134BlockList *all_blocks = _ir->linear_scan_order();1135assert(block->number_of_preds() >= 1, "Block must have at least one predecessor");1136assert(!block->is_set(BlockBegin::exception_entry_flag), "Loop header must not be exception handler!");11371138bool loop_through_xhandler = false;1139for (int i=0; i<block->number_of_sux(); i++) {1140BlockBegin *sux = block->sux_at(i);1141if (!loop_through_xhandler) {1142if (sux->loop_depth() == block->loop_depth() && sux->loop_index() != block->loop_index()) {1143loop_through_xhandler = is_backbranch_from_xhandler(block);1144assert(loop_through_xhandler, "Loop indices have to be the same if same depths but no backbranch from xhandler");1145}1146}1147assert(sux->loop_depth() == block->loop_depth() || sux->loop_index() != block->loop_index(), "Loop index has to be different");1148}11491150for (int i=0; i<all_blocks->length(); i++) {1151BlockBegin *cur = all_blocks->at(i);1152if (cur->loop_index() == loop_index && cur != block) {1153assert(dominates(block->dominator(), cur), "Dominator of loop header must dominate all loop blocks");1154}1155}1156}11571158Instruction *cur = block;1159while (cur) {1160assert(cur->block() == block, "Block begin has to be set correctly!");1161cur = cur->next();1162}1163}11641165// Called when a successor of a block has the same loop depth but a different loop index. This can happen if a backbranch comes from1166// an exception handler of a loop head block, for example, when a loop is only executed once on the non-exceptional path but is1167// repeated in case of an exception. In this case, the edge block->sux is not critical and was not split before.1168// Check if there is such a backbranch from an xhandler of 'block'.1169bool RangeCheckEliminator::Verification::is_backbranch_from_xhandler(BlockBegin* block) {1170for (int i = 0; i < block->number_of_exception_handlers(); i++) {1171BlockBegin *xhandler = block->exception_handler_at(i);1172for (int j = 0; j < block->number_of_preds(); j++) {1173if (dominates(xhandler, block->pred_at(j)) || xhandler == block->pred_at(j)) {1174return true;1175}1176}1177}11781179// In case of nested xhandlers, we need to walk through the loop (and all blocks belonging to exception handlers)1180// to find an xhandler of 'block'.1181if (block->number_of_exception_handlers() > 0) {1182for (int i = 0; i < block->number_of_preds(); i++) {1183BlockBegin* pred = block->pred_at(i);1184if (pred->loop_index() == block->loop_index()) {1185// Only check blocks that belong to the loop1186// Do a BFS to find an xhandler block of 'block' starting from 'pred'1187ResourceMark rm;1188ResourceBitMap visited(BlockBegin::number_of_blocks());1189BlockBeginList list;1190list.push(pred);1191while (!list.is_empty()) {1192BlockBegin* next = list.pop();1193if (!visited.at(next->block_id())) {1194visited.set_bit(next->block_id());1195for (int j = 0; j < block->number_of_exception_handlers(); j++) {1196if (next == block->exception_handler_at(j)) {1197return true;1198}1199}1200for (int j = 0; j < next->number_of_preds(); j++) {1201if (next->pred_at(j) != block) {1202list.push(next->pred_at(j));1203}1204}1205}1206}1207}1208}1209}1210return false;1211}12121213// Loop header must dominate all loop blocks1214bool RangeCheckEliminator::Verification::dominates(BlockBegin *dominator, BlockBegin *block) {1215BlockBegin *cur = block->dominator();1216while (cur && cur != dominator) {1217cur = cur->dominator();1218}1219return cur == dominator;1220}12211222// Try to reach Block end beginning in Block start and not using Block dont_use1223bool RangeCheckEliminator::Verification::can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use /* = NULL */) {1224if (start == end) return start != dont_use;1225// Simple BSF from start to end1226// BlockBeginList _current;1227for (int i=0; i < _used.length(); i++) {1228_used.at_put(i, false);1229}1230_current.trunc_to(0);1231_successors.trunc_to(0);1232if (start != dont_use) {1233_current.push(start);1234_used.at_put(start->block_id(), true);1235}12361237// BlockBeginList _successors;1238while (_current.length() > 0) {1239BlockBegin *cur = _current.pop();1240// Add exception handlers to list1241for (int i=0; i<cur->number_of_exception_handlers(); i++) {1242BlockBegin *xhandler = cur->exception_handler_at(i);1243_successors.push(xhandler);1244// Add exception handlers of _successors to list1245for (int j=0; j<xhandler->number_of_exception_handlers(); j++) {1246BlockBegin *sux_xhandler = xhandler->exception_handler_at(j);1247_successors.push(sux_xhandler);1248}1249}1250// Add normal _successors to list1251for (int i=0; i<cur->number_of_sux(); i++) {1252BlockBegin *sux = cur->sux_at(i);1253_successors.push(sux);1254// Add exception handlers of _successors to list1255for (int j=0; j<sux->number_of_exception_handlers(); j++) {1256BlockBegin *xhandler = sux->exception_handler_at(j);1257_successors.push(xhandler);1258}1259}1260for (int i=0; i<_successors.length(); i++) {1261BlockBegin *sux = _successors.at(i);1262assert(sux != NULL, "Successor must not be NULL!");1263if (sux == end) {1264return true;1265}1266if (sux != dont_use && !_used.at(sux->block_id())) {1267_used.at_put(sux->block_id(), true);1268_current.push(sux);1269}1270}1271_successors.trunc_to(0);1272}12731274return false;1275}1276#endif // ASSERT12771278// Bound1279RangeCheckEliminator::Bound::~Bound() {1280}12811282// Bound constructor1283RangeCheckEliminator::Bound::Bound() {1284this->_lower = min_jint;1285this->_upper = max_jint;1286this->_lower_instr = NULL;1287this->_upper_instr = NULL;1288}12891290// Bound constructor1291RangeCheckEliminator::Bound::Bound(int lower, Value lower_instr, int upper, Value upper_instr) {1292assert(!lower_instr || !lower_instr->as_Constant() || !lower_instr->type()->as_IntConstant(), "Must not be constant!");1293assert(!upper_instr || !upper_instr->as_Constant() || !upper_instr->type()->as_IntConstant(), "Must not be constant!");1294this->_lower = lower;1295this->_upper = upper;1296this->_lower_instr = lower_instr;1297this->_upper_instr = upper_instr;1298}12991300// Bound constructor1301RangeCheckEliminator::Bound::Bound(Instruction::Condition cond, Value v, int constant) {1302assert(!v || (v->type() && (v->type()->as_IntType() || v->type()->as_ObjectType())), "Type must be array or integer!");1303assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");13041305if (cond == Instruction::eql) {1306_lower = constant;1307_lower_instr = v;1308_upper = constant;1309_upper_instr = v;1310} else if (cond == Instruction::neq) {1311_lower = min_jint;1312_upper = max_jint;1313_lower_instr = NULL;1314_upper_instr = NULL;1315if (v == NULL) {1316if (constant == min_jint) {1317_lower++;1318}1319if (constant == max_jint) {1320_upper--;1321}1322}1323} else if (cond == Instruction::geq) {1324_lower = constant;1325_lower_instr = v;1326_upper = max_jint;1327_upper_instr = NULL;1328} else if (cond == Instruction::leq) {1329_lower = min_jint;1330_lower_instr = NULL;1331_upper = constant;1332_upper_instr = v;1333} else {1334ShouldNotReachHere();1335}1336}13371338// Set lower1339void RangeCheckEliminator::Bound::set_lower(int value, Value v) {1340assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");1341this->_lower = value;1342this->_lower_instr = v;1343}13441345// Set upper1346void RangeCheckEliminator::Bound::set_upper(int value, Value v) {1347assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");1348this->_upper = value;1349this->_upper_instr = v;1350}13511352// Add constant -> no overflow may occur1353void RangeCheckEliminator::Bound::add_constant(int value) {1354this->_lower += value;1355this->_upper += value;1356}13571358// or1359void RangeCheckEliminator::Bound::or_op(Bound *b) {1360// Watch out, bound is not guaranteed not to overflow!1361// Update lower bound1362if (_lower_instr != b->_lower_instr || (_lower_instr && _lower != b->_lower)) {1363_lower_instr = NULL;1364_lower = min_jint;1365} else {1366_lower = MIN2(_lower, b->_lower);1367}1368// Update upper bound1369if (_upper_instr != b->_upper_instr || (_upper_instr && _upper != b->_upper)) {1370_upper_instr = NULL;1371_upper = max_jint;1372} else {1373_upper = MAX2(_upper, b->_upper);1374}1375}13761377// and1378void RangeCheckEliminator::Bound::and_op(Bound *b) {1379// Update lower bound1380if (_lower_instr == b->_lower_instr) {1381_lower = MAX2(_lower, b->_lower);1382}1383if (b->has_lower()) {1384bool set = true;1385if (_lower_instr != NULL && b->_lower_instr != NULL) {1386set = (_lower_instr->dominator_depth() > b->_lower_instr->dominator_depth());1387}1388if (set) {1389_lower = b->_lower;1390_lower_instr = b->_lower_instr;1391}1392}1393// Update upper bound1394if (_upper_instr == b->_upper_instr) {1395_upper = MIN2(_upper, b->_upper);1396}1397if (b->has_upper()) {1398bool set = true;1399if (_upper_instr != NULL && b->_upper_instr != NULL) {1400set = (_upper_instr->dominator_depth() > b->_upper_instr->dominator_depth());1401}1402if (set) {1403_upper = b->_upper;1404_upper_instr = b->_upper_instr;1405}1406}1407}14081409// has_upper1410bool RangeCheckEliminator::Bound::has_upper() {1411return _upper_instr != NULL || _upper < max_jint;1412}14131414// is_smaller1415bool RangeCheckEliminator::Bound::is_smaller(Bound *b) {1416if (b->_lower_instr != _upper_instr) {1417return false;1418}1419return _upper < b->_lower;1420}14211422// has_lower1423bool RangeCheckEliminator::Bound::has_lower() {1424return _lower_instr != NULL || _lower > min_jint;1425}14261427// in_array_bound1428bool RangeCheckEliminator::in_array_bound(Bound *bound, Value array){1429if (!bound) return false;1430assert(array != NULL, "Must not be null!");1431assert(bound != NULL, "Must not be null!");1432if (bound->lower() >=0 && bound->lower_instr() == NULL && bound->upper() < 0 && bound->upper_instr() != NULL) {1433ArrayLength *len = bound->upper_instr()->as_ArrayLength();1434if (bound->upper_instr() == array || (len != NULL && len->array() == array)) {1435return true;1436}1437}1438return false;1439}14401441// remove_lower1442void RangeCheckEliminator::Bound::remove_lower() {1443_lower = min_jint;1444_lower_instr = NULL;1445}14461447// remove_upper1448void RangeCheckEliminator::Bound::remove_upper() {1449_upper = max_jint;1450_upper_instr = NULL;1451}14521453// upper1454int RangeCheckEliminator::Bound::upper() {1455return _upper;1456}14571458// lower1459int RangeCheckEliminator::Bound::lower() {1460return _lower;1461}14621463// upper_instr1464Value RangeCheckEliminator::Bound::upper_instr() {1465return _upper_instr;1466}14671468// lower_instr1469Value RangeCheckEliminator::Bound::lower_instr() {1470return _lower_instr;1471}147214731474void RangeCheckEliminator::Bound::print() {1475tty->print("%s", "");1476if (this->_lower_instr || this->_lower != min_jint) {1477if (this->_lower_instr) {1478tty->print("i%d", this->_lower_instr->id());1479if (this->_lower > 0) {1480tty->print("+%d", _lower);1481}1482if (this->_lower < 0) {1483tty->print("%d", _lower);1484}1485} else {1486tty->print("%d", _lower);1487}1488tty->print(" <= ");1489}1490tty->print("x");1491if (this->_upper_instr || this->_upper != max_jint) {1492tty->print(" <= ");1493if (this->_upper_instr) {1494tty->print("i%d", this->_upper_instr->id());1495if (this->_upper > 0) {1496tty->print("+%d", _upper);1497}1498if (this->_upper < 0) {1499tty->print("%d", _upper);1500}1501} else {1502tty->print("%d", _upper);1503}1504}1505}15061507// Copy1508RangeCheckEliminator::Bound *RangeCheckEliminator::Bound::copy() {1509Bound *b = new Bound();1510b->_lower = _lower;1511b->_lower_instr = _lower_instr;1512b->_upper = _upper;1513b->_upper_instr = _upper_instr;1514return b;1515}15161517#ifdef ASSERT1518// Add assertion1519void RangeCheckEliminator::Bound::add_assertion(Instruction *instruction, Instruction *position, int i, Value instr, Instruction::Condition cond) {1520Instruction *result = position;1521Instruction *compare_with = NULL;1522ValueStack *state = position->state_before();1523if (position->as_BlockEnd() && !position->as_Goto()) {1524state = position->as_BlockEnd()->state_before();1525}1526Instruction *instruction_before = position->prev();1527if (position->as_Return() && Compilation::current()->method()->is_synchronized() && instruction_before->as_MonitorExit()) {1528instruction_before = instruction_before->prev();1529}1530result = instruction_before;1531// Load constant only if needed1532Constant *constant = NULL;1533if (i != 0 || !instr) {1534constant = new Constant(new IntConstant(i));1535NOT_PRODUCT(constant->set_printable_bci(position->printable_bci()));1536result = result->insert_after(constant);1537compare_with = constant;1538}15391540if (instr) {1541assert(instr->type()->as_ObjectType() || instr->type()->as_IntType(), "Type must be array or integer!");1542compare_with = instr;1543// Load array length if necessary1544Instruction *op = instr;1545if (instr->type()->as_ObjectType()) {1546assert(state, "must not be null");1547ArrayLength *length = new ArrayLength(instr, state->copy());1548NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));1549length->set_exception_state(length->state_before());1550result = result->insert_after(length);1551op = length;1552compare_with = length;1553}1554// Add operation only if necessary1555if (constant) {1556ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, op, NULL);1557NOT_PRODUCT(ao->set_printable_bci(position->printable_bci()));1558result = result->insert_after(ao);1559compare_with = ao;1560// TODO: Check that add operation does not overflow!1561}1562}1563assert(compare_with != NULL, "You have to compare with something!");1564assert(instruction != NULL, "Instruction must not be null!");15651566if (instruction->type()->as_ObjectType()) {1567// Load array length if necessary1568Instruction *op = instruction;1569assert(state, "must not be null");1570ArrayLength *length = new ArrayLength(instruction, state->copy());1571length->set_exception_state(length->state_before());1572NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));1573result = result->insert_after(length);1574instruction = length;1575}15761577Assert *assert = new Assert(instruction, cond, false, compare_with);1578NOT_PRODUCT(assert->set_printable_bci(position->printable_bci()));1579result->insert_after(assert);1580}15811582// Add assertions1583void RangeCheckEliminator::add_assertions(Bound *bound, Instruction *instruction, Instruction *position) {1584// Add lower bound assertion1585if (bound->has_lower()) {1586bound->add_assertion(instruction, position, bound->lower(), bound->lower_instr(), Instruction::geq);1587}1588// Add upper bound assertion1589if (bound->has_upper()) {1590bound->add_assertion(instruction, position, bound->upper(), bound->upper_instr(), Instruction::leq);1591}1592}1593#endif159415951596