Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/c1/c1_RangeCheckElimination.cpp
32285 views
/*1* Copyright (c) 2012, 2014, 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"3233// Macros for the Trace and the Assertion flag34#ifdef ASSERT35#define TRACE_RANGE_CHECK_ELIMINATION(code) if (TraceRangeCheckElimination) { code; }36#define ASSERT_RANGE_CHECK_ELIMINATION(code) if (AssertRangeCheckElimination) { code; }37#define TRACE_OR_ASSERT_RANGE_CHECK_ELIMINATION(code) if (TraceRangeCheckElimination || AssertRangeCheckElimination) { code; }38#else39#define TRACE_RANGE_CHECK_ELIMINATION(code)40#define ASSERT_RANGE_CHECK_ELIMINATION(code)41#define TRACE_OR_ASSERT_RANGE_CHECK_ELIMINATION(code)42#endif4344// Entry point for the optimization45void RangeCheckElimination::eliminate(IR *ir) {46bool do_elimination = ir->compilation()->has_access_indexed();47ASSERT_RANGE_CHECK_ELIMINATION(do_elimination = true);48if (do_elimination) {49RangeCheckEliminator rce(ir);50}51}5253// Constructor54RangeCheckEliminator::RangeCheckEliminator(IR *ir) :55_bounds(Instruction::number_of_instructions(), NULL),56_access_indexed_info(Instruction::number_of_instructions(), NULL)57{58_visitor.set_range_check_eliminator(this);59_ir = ir;60_number_of_instructions = Instruction::number_of_instructions();61_optimistic = ir->compilation()->is_optimistic();6263TRACE_RANGE_CHECK_ELIMINATION(64tty->cr();65tty->print_cr("Range check elimination");66ir->method()->print_name(tty);67tty->cr();68);6970TRACE_RANGE_CHECK_ELIMINATION(71tty->print_cr("optimistic=%d", (int)_optimistic);72);7374#ifdef ASSERT75// Verifies several conditions that must be true on the IR-input. Only used for debugging purposes.76TRACE_RANGE_CHECK_ELIMINATION(77tty->print_cr("Verification of IR . . .");78);79Verification verification(ir);80#endif8182// Set process block flags83// Optimization so a blocks is only processed if it contains an access indexed instruction or if84// one of its children in the dominator tree contains an access indexed instruction.85set_process_block_flags(ir->start());8687// Pass over instructions in the dominator tree88TRACE_RANGE_CHECK_ELIMINATION(89tty->print_cr("Starting pass over dominator tree . . .")90);91calc_bounds(ir->start(), NULL);9293TRACE_RANGE_CHECK_ELIMINATION(94tty->print_cr("Finished!")95);96}9798// Instruction specific work for some instructions99// Constant100void RangeCheckEliminator::Visitor::do_Constant(Constant *c) {101IntConstant *ic = c->type()->as_IntConstant();102if (ic != NULL) {103int value = ic->value();104_bound = new Bound(value, NULL, value, NULL);105}106}107108// LogicOp109void RangeCheckEliminator::Visitor::do_LogicOp(LogicOp *lo) {110if (lo->type()->as_IntType() && lo->op() == Bytecodes::_iand && (lo->x()->as_Constant() || lo->y()->as_Constant())) {111int constant = 0;112Constant *c = lo->x()->as_Constant();113if (c != NULL) {114constant = c->type()->as_IntConstant()->value();115} else {116constant = lo->y()->as_Constant()->type()->as_IntConstant()->value();117}118if (constant >= 0) {119_bound = new Bound(0, NULL, constant, NULL);120}121}122}123124// Phi125void RangeCheckEliminator::Visitor::do_Phi(Phi *phi) {126if (!phi->type()->as_IntType() && !phi->type()->as_ObjectType()) return;127128BlockBegin *block = phi->block();129int op_count = phi->operand_count();130bool has_upper = true;131bool has_lower = true;132assert(phi, "Phi must not be null");133Bound *bound = NULL;134135// TODO: support more difficult phis136for (int i=0; i<op_count; i++) {137Value v = phi->operand_at(i);138139if (v == phi) continue;140141// Check if instruction is connected with phi itself142Op2 *op2 = v->as_Op2();143if (op2 != NULL) {144Value x = op2->x();145Value y = op2->y();146if ((x == phi || y == phi)) {147Value other = x;148if (other == phi) {149other = y;150}151ArithmeticOp *ao = v->as_ArithmeticOp();152if (ao != NULL && ao->op() == Bytecodes::_iadd) {153assert(ao->op() == Bytecodes::_iadd, "Has to be add!");154if (ao->type()->as_IntType()) {155Constant *c = other->as_Constant();156if (c != NULL) {157assert(c->type()->as_IntConstant(), "Constant has to be of type integer");158int value = c->type()->as_IntConstant()->value();159if (value == 1) {160has_upper = false;161} else if (value > 1) {162// Overflow not guaranteed163has_upper = false;164has_lower = false;165} else if (value < 0) {166has_lower = false;167}168continue;169}170}171}172}173}174175// No connection -> new bound176Bound *v_bound = _rce->get_bound(v);177Bound *cur_bound;178int cur_constant = 0;179Value cur_value = v;180181if (v->type()->as_IntConstant()) {182cur_constant = v->type()->as_IntConstant()->value();183cur_value = NULL;184}185if (!v_bound->has_upper() || !v_bound->has_lower()) {186cur_bound = new Bound(cur_constant, cur_value, cur_constant, cur_value);187} else {188cur_bound = v_bound;189}190if (cur_bound) {191if (!bound) {192bound = cur_bound->copy();193} else {194bound->or_op(cur_bound);195}196} else {197// No bound!198bound = NULL;199break;200}201}202203if (bound) {204if (!has_upper) {205bound->remove_upper();206}207if (!has_lower) {208bound->remove_lower();209}210_bound = bound;211} else {212_bound = new Bound();213}214}215216217// ArithmeticOp218void RangeCheckEliminator::Visitor::do_ArithmeticOp(ArithmeticOp *ao) {219Value x = ao->x();220Value y = ao->y();221222if (ao->op() == Bytecodes::_irem) {223Bound* x_bound = _rce->get_bound(x);224Bound* y_bound = _rce->get_bound(y);225if (x_bound->lower() >= 0 && x_bound->lower_instr() == NULL && y->as_ArrayLength() != NULL) {226_bound = new Bound(0, NULL, -1, y);227} else {228_bound = new Bound();229}230} else if (!x->as_Constant() || !y->as_Constant()) {231assert(!x->as_Constant() || !y->as_Constant(), "One of the operands must be non-constant!");232if (((x->as_Constant() || y->as_Constant()) && (ao->op() == Bytecodes::_iadd)) || (y->as_Constant() && ao->op() == Bytecodes::_isub)) {233assert(ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub, "Operand must be iadd or isub");234235if (y->as_Constant()) {236Value tmp = x;237x = y;238y = tmp;239}240assert(x->as_Constant()->type()->as_IntConstant(), "Constant must be int constant!");241242// Constant now in x243int const_value = x->as_Constant()->type()->as_IntConstant()->value();244if (ao->op() == Bytecodes::_iadd || const_value != min_jint) {245if (ao->op() == Bytecodes::_isub) {246const_value = -const_value;247}248249Bound * bound = _rce->get_bound(y);250if (bound->has_upper() && bound->has_lower()) {251int new_lower = bound->lower() + const_value;252jlong new_lowerl = ((jlong)bound->lower()) + const_value;253int new_upper = bound->upper() + const_value;254jlong new_upperl = ((jlong)bound->upper()) + const_value;255256if (((jlong)new_lower) == new_lowerl && ((jlong)new_upper == new_upperl)) {257Bound *newBound = new Bound(new_lower, bound->lower_instr(), new_upper, bound->upper_instr());258_bound = newBound;259} else {260// overflow261_bound = new Bound();262}263} else {264_bound = new Bound();265}266} else {267_bound = new Bound();268}269} else {270Bound *bound = _rce->get_bound(x);271if (ao->op() == Bytecodes::_isub) {272if (bound->lower_instr() == y) {273_bound = new Bound(Instruction::geq, NULL, bound->lower());274} else {275_bound = new Bound();276}277} else {278_bound = new Bound();279}280}281}282}283284// IfOp285void RangeCheckEliminator::Visitor::do_IfOp(IfOp *ifOp)286{287if (ifOp->tval()->type()->as_IntConstant() && ifOp->fval()->type()->as_IntConstant()) {288int min = ifOp->tval()->type()->as_IntConstant()->value();289int max = ifOp->fval()->type()->as_IntConstant()->value();290if (min > max) {291// min ^= max ^= min ^= max;292int tmp = min;293min = max;294max = tmp;295}296_bound = new Bound(min, NULL, max, NULL);297}298}299300// Get bound. Returns the current bound on Value v. Normally this is the topmost element on the bound stack.301RangeCheckEliminator::Bound *RangeCheckEliminator::get_bound(Value v) {302// Wrong type or NULL -> No bound303if (!v || (!v->type()->as_IntType() && !v->type()->as_ObjectType())) return NULL;304305if (!_bounds[v->id()]) {306// First (default) bound is calculated307// Create BoundStack308_bounds[v->id()] = new BoundStack();309_visitor.clear_bound();310Value visit_value = v;311visit_value->visit(&_visitor);312Bound *bound = _visitor.bound();313if (bound) {314_bounds[v->id()]->push(bound);315}316if (_bounds[v->id()]->length() == 0) {317assert(!(v->as_Constant() && v->type()->as_IntConstant()), "constants not handled here");318_bounds[v->id()]->push(new Bound());319}320} else if (_bounds[v->id()]->length() == 0) {321// To avoid endless loops, bound is currently in calculation -> nothing known about it322return new Bound();323}324325// Return bound326return _bounds[v->id()]->top();327}328329// Update bound330void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Instruction::Condition cond, Value value, int constant) {331if (cond == Instruction::gtr) {332cond = Instruction::geq;333constant++;334} else if (cond == Instruction::lss) {335cond = Instruction::leq;336constant--;337}338Bound *bound = new Bound(cond, value, constant);339update_bound(pushed, v, bound);340}341342// Checks for loop invariance. Returns true if the instruction is outside of the loop which is identified by loop_header.343bool RangeCheckEliminator::loop_invariant(BlockBegin *loop_header, Instruction *instruction) {344assert(loop_header, "Loop header must not be null!");345if (!instruction) return true;346return instruction->dominator_depth() < loop_header->dominator_depth();347}348349// Update bound. Pushes a new bound onto the stack. Tries to do a conjunction with the current bound.350void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Bound *bound) {351if (v->as_Constant()) {352// No bound update for constants353return;354}355if (!_bounds[v->id()]) {356get_bound(v);357assert(_bounds[v->id()], "Now Stack must exist");358}359Bound *top = NULL;360if (_bounds[v->id()]->length() > 0) {361top = _bounds[v->id()]->top();362}363if (top) {364bound->and_op(top);365}366_bounds[v->id()]->push(bound);367pushed.append(v->id());368}369370// Add instruction + idx for in block motion371void RangeCheckEliminator::add_access_indexed_info(InstructionList &indices, int idx, Value instruction, AccessIndexed *ai) {372int id = instruction->id();373AccessIndexedInfo *aii = _access_indexed_info[id];374if (aii == NULL) {375aii = new AccessIndexedInfo();376_access_indexed_info[id] = aii;377indices.append(instruction);378aii->_min = idx;379aii->_max = idx;380aii->_list = new AccessIndexedList();381} else if (idx >= aii->_min && idx <= aii->_max) {382remove_range_check(ai);383return;384}385aii->_min = MIN2(aii->_min, idx);386aii->_max = MAX2(aii->_max, idx);387aii->_list->append(ai);388}389390// In block motion. Tries to reorder checks in order to reduce some of them.391// Example:392// a[i] = 0;393// a[i+2] = 0;394// a[i+1] = 0;395// In this example the check for a[i+1] would be considered as unnecessary during the first iteration.396// After this i is only checked once for i >= 0 and i+2 < a.length before the first array access. If this397// check fails, deoptimization is called.398void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList &accessIndexed, InstructionList &arrays) {399InstructionList indices;400401// Now iterate over all arrays402for (int i=0; i<arrays.length(); i++) {403int max_constant = -1;404AccessIndexedList list_constant;405Value array = arrays.at(i);406407// For all AccessIndexed-instructions in this block concerning the current array.408for(int j=0; j<accessIndexed.length(); j++) {409AccessIndexed *ai = accessIndexed.at(j);410if (ai->array() != array || !ai->check_flag(Instruction::NeedsRangeCheckFlag)) continue;411412Value index = ai->index();413Constant *c = index->as_Constant();414if (c != NULL) {415int constant_value = c->type()->as_IntConstant()->value();416if (constant_value >= 0) {417if (constant_value <= max_constant) {418// No range check needed for this419remove_range_check(ai);420} else {421max_constant = constant_value;422list_constant.append(ai);423}424}425} else {426int last_integer = 0;427Instruction *last_instruction = index;428int base = 0;429ArithmeticOp *ao = index->as_ArithmeticOp();430431while (ao != NULL && (ao->x()->as_Constant() || ao->y()->as_Constant()) && (ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub)) {432c = ao->y()->as_Constant();433Instruction *other = ao->x();434if (!c && ao->op() == Bytecodes::_iadd) {435c = ao->x()->as_Constant();436other = ao->y();437}438439if (c) {440int value = c->type()->as_IntConstant()->value();441if (value != min_jint) {442if (ao->op() == Bytecodes::_isub) {443value = -value;444}445base += value;446last_integer = base;447last_instruction = other;448}449index = other;450} else {451break;452}453ao = index->as_ArithmeticOp();454}455add_access_indexed_info(indices, last_integer, last_instruction, ai);456}457}458459// Iterate over all different indices460if (_optimistic) {461for (int i = 0; i < indices.length(); i++) {462Instruction *index_instruction = indices.at(i);463AccessIndexedInfo *info = _access_indexed_info[index_instruction->id()];464assert(info != NULL, "Info must not be null");465466// if idx < 0, max > 0, max + idx may fall between 0 and467// length-1 and if min < 0, min + idx may overflow and be >=468// 0. The predicate wouldn't trigger but some accesses could469// be with a negative index. This test guarantees that for the470// min and max value that are kept the predicate can't let471// some incorrect accesses happen.472bool range_cond = (info->_max < 0 || info->_max + min_jint <= info->_min);473474// Generate code only if more than 2 range checks can be eliminated because of that.475// 2 because at least 2 comparisons are done476if (info->_list->length() > 2 && range_cond) {477AccessIndexed *first = info->_list->at(0);478Instruction *insert_position = first->prev();479assert(insert_position->next() == first, "prev was calculated");480ValueStack *state = first->state_before();481482// Load min Constant483Constant *min_constant = NULL;484if (info->_min != 0) {485min_constant = new Constant(new IntConstant(info->_min));486NOT_PRODUCT(min_constant->set_printable_bci(first->printable_bci()));487insert_position = insert_position->insert_after(min_constant);488}489490// Load max Constant491Constant *max_constant = NULL;492if (info->_max != 0) {493max_constant = new Constant(new IntConstant(info->_max));494NOT_PRODUCT(max_constant->set_printable_bci(first->printable_bci()));495insert_position = insert_position->insert_after(max_constant);496}497498// Load array length499Value length_instr = first->length();500if (!length_instr) {501ArrayLength *length = new ArrayLength(array, first->state_before()->copy());502length->set_exception_state(length->state_before());503length->set_flag(Instruction::DeoptimizeOnException, true);504insert_position = insert_position->insert_after_same_bci(length);505length_instr = length;506}507508// Calculate lower bound509Instruction *lower_compare = index_instruction;510if (min_constant) {511ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, min_constant, lower_compare, false, NULL);512insert_position = insert_position->insert_after_same_bci(ao);513lower_compare = ao;514}515516// Calculate upper bound517Instruction *upper_compare = index_instruction;518if (max_constant) {519ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, max_constant, upper_compare, false, NULL);520insert_position = insert_position->insert_after_same_bci(ao);521upper_compare = ao;522}523524// Trick with unsigned compare is done525int bci = NOT_PRODUCT(first->printable_bci()) PRODUCT_ONLY(-1);526insert_position = predicate(upper_compare, Instruction::aeq, length_instr, state, insert_position, bci);527insert_position = predicate_cmp_with_const(lower_compare, Instruction::leq, -1, state, insert_position);528for (int j = 0; j<info->_list->length(); j++) {529AccessIndexed *ai = info->_list->at(j);530remove_range_check(ai);531}532}533}534535if (list_constant.length() > 1) {536AccessIndexed *first = list_constant.at(0);537Instruction *insert_position = first->prev();538ValueStack *state = first->state_before();539// Load max Constant540Constant *constant = new Constant(new IntConstant(max_constant));541NOT_PRODUCT(constant->set_printable_bci(first->printable_bci()));542insert_position = insert_position->insert_after(constant);543Instruction *compare_instr = constant;544Value length_instr = first->length();545if (!length_instr) {546ArrayLength *length = new ArrayLength(array, state->copy());547length->set_exception_state(length->state_before());548length->set_flag(Instruction::DeoptimizeOnException, true);549insert_position = insert_position->insert_after_same_bci(length);550length_instr = length;551}552// Compare for greater or equal to array length553insert_position = predicate(compare_instr, Instruction::geq, length_instr, state, insert_position);554for (int j = 0; j<list_constant.length(); j++) {555AccessIndexed *ai = list_constant.at(j);556remove_range_check(ai);557}558}559}560561// Clear data structures for next array562for (int i = 0; i < indices.length(); i++) {563Instruction *index_instruction = indices.at(i);564_access_indexed_info[index_instruction->id()] = NULL;565}566indices.clear();567}568}569570bool RangeCheckEliminator::set_process_block_flags(BlockBegin *block) {571Instruction *cur = block;572bool process = false;573574while (cur) {575process |= (cur->as_AccessIndexed() != NULL);576cur = cur->next();577}578579BlockList *dominates = block->dominates();580for (int i=0; i<dominates->length(); i++) {581BlockBegin *next = dominates->at(i);582process |= set_process_block_flags(next);583}584585if (!process) {586block->set(BlockBegin::donot_eliminate_range_checks);587}588return process;589}590591bool RangeCheckEliminator::is_ok_for_deoptimization(Instruction *insert_position, Instruction *array_instr, Instruction *length_instr, Instruction *lower_instr, int lower, Instruction *upper_instr, int upper) {592bool upper_check = true;593assert(lower_instr || lower >= 0, "If no lower_instr present, lower must be greater 0");594assert(!lower_instr || lower_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");595assert(!upper_instr || upper_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");596assert(array_instr, "Array instruction must exist");597assert(array_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");598assert(!length_instr || length_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");599600if (upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr) {601// static check602if (upper >= 0) return false; // would always trigger a deopt:603// array_length + x >= array_length, x >= 0 is always true604upper_check = false;605}606if (lower_instr && lower_instr->as_ArrayLength() && lower_instr->as_ArrayLength()->array() == array_instr) {607if (lower > 0) return false;608}609// No upper check required -> skip610if (upper_check && upper_instr && upper_instr->type()->as_ObjectType() && upper_instr == array_instr) {611// upper_instr is object means that the upper bound is the length612// of the upper_instr.613return false;614}615return true;616}617618Instruction* RangeCheckEliminator::insert_after(Instruction* insert_position, Instruction* instr, int bci) {619if (bci != -1) {620NOT_PRODUCT(instr->set_printable_bci(bci));621return insert_position->insert_after(instr);622} else {623return insert_position->insert_after_same_bci(instr);624}625}626627Instruction* RangeCheckEliminator::predicate(Instruction* left, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {628RangeCheckPredicate *deoptimize = new RangeCheckPredicate(left, cond, true, right, state->copy());629return insert_after(insert_position, deoptimize, bci);630}631632Instruction* RangeCheckEliminator::predicate_cmp_with_const(Instruction* instr, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) {633Constant *const_instr = new Constant(new IntConstant(constant));634insert_position = insert_after(insert_position, const_instr, bci);635return predicate(instr, cond, const_instr, state, insert_position);636}637638Instruction* RangeCheckEliminator::predicate_add(Instruction* left, int left_const, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {639Constant *constant = new Constant(new IntConstant(left_const));640insert_position = insert_after(insert_position, constant, bci);641ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, left, false, NULL);642insert_position = insert_position->insert_after_same_bci(ao);643return predicate(ao, cond, right, state, insert_position);644}645646Instruction* RangeCheckEliminator::predicate_add_cmp_with_const(Instruction* left, int left_const, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) {647Constant *const_instr = new Constant(new IntConstant(constant));648insert_position = insert_after(insert_position, const_instr, bci);649return predicate_add(left, left_const, cond, const_instr, state, insert_position);650}651652// Insert deoptimization653void 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) {654assert(is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, lower, upper_instr, upper), "should have been tested before");655bool upper_check = !(upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr);656657int bci = NOT_PRODUCT(ai->printable_bci()) PRODUCT_ONLY(-1);658if (lower_instr) {659assert(!lower_instr->type()->as_ObjectType(), "Must not be object type");660if (lower == 0) {661// Compare for less than 0662insert_position = predicate_cmp_with_const(lower_instr, Instruction::lss, 0, state, insert_position, bci);663} else if (lower > 0) {664// Compare for smaller 0665insert_position = predicate_add_cmp_with_const(lower_instr, lower, Instruction::lss, 0, state, insert_position, bci);666} else {667assert(lower < 0, "");668// Add 1669lower++;670lower = -lower;671// Compare for smaller or equal 0672insert_position = predicate_cmp_with_const(lower_instr, Instruction::leq, lower, state, insert_position, bci);673}674}675676// No upper check required -> skip677if (!upper_check) return;678679// We need to know length of array680if (!length_instr) {681// Load length if necessary682ArrayLength *length = new ArrayLength(array_instr, state->copy());683NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));684length->set_exception_state(length->state_before());685length->set_flag(Instruction::DeoptimizeOnException, true);686insert_position = insert_position->insert_after(length);687length_instr = length;688}689690if (!upper_instr) {691// Compare for geq array.length692insert_position = predicate_cmp_with_const(length_instr, Instruction::leq, upper, state, insert_position, bci);693} else {694if (upper_instr->type()->as_ObjectType()) {695assert(state, "must not be null");696assert(upper_instr != array_instr, "should be");697ArrayLength *length = new ArrayLength(upper_instr, state->copy());698NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));699length->set_flag(Instruction::DeoptimizeOnException, true);700length->set_exception_state(length->state_before());701insert_position = insert_position->insert_after(length);702upper_instr = length;703}704assert(upper_instr->type()->as_IntType(), "Must not be object type!");705706if (upper == 0) {707// Compare for geq array.length708insert_position = predicate(upper_instr, Instruction::geq, length_instr, state, insert_position, bci);709} else if (upper < 0) {710// Compare for geq array.length711insert_position = predicate_add(upper_instr, upper, Instruction::geq, length_instr, state, insert_position, bci);712} else {713assert(upper > 0, "");714upper = -upper;715// Compare for geq array.length716insert_position = predicate_add(length_instr, upper, Instruction::leq, upper_instr, state, insert_position, bci);717}718}719}720721// Add if condition722void RangeCheckEliminator::add_if_condition(IntegerStack &pushed, Value x, Value y, Instruction::Condition condition) {723if (y->as_Constant()) return;724725int const_value = 0;726Value instr_value = x;727Constant *c = x->as_Constant();728ArithmeticOp *ao = x->as_ArithmeticOp();729730if (c != NULL) {731const_value = c->type()->as_IntConstant()->value();732instr_value = NULL;733} else if (ao != NULL && (!ao->x()->as_Constant() || !ao->y()->as_Constant()) && ((ao->op() == Bytecodes::_isub && ao->y()->as_Constant()) || ao->op() == Bytecodes::_iadd)) {734assert(!ao->x()->as_Constant() || !ao->y()->as_Constant(), "At least one operator must be non-constant!");735assert(ao->op() == Bytecodes::_isub || ao->op() == Bytecodes::_iadd, "Operation has to be add or sub!");736c = ao->x()->as_Constant();737if (c != NULL) {738const_value = c->type()->as_IntConstant()->value();739instr_value = ao->y();740} else {741c = ao->y()->as_Constant();742if (c != NULL) {743const_value = c->type()->as_IntConstant()->value();744instr_value = ao->x();745}746}747if (ao->op() == Bytecodes::_isub) {748assert(ao->y()->as_Constant(), "1 - x not supported, only x - 1 is valid!");749if (const_value > min_jint) {750const_value = -const_value;751} else {752const_value = 0;753instr_value = x;754}755}756}757758update_bound(pushed, y, condition, instr_value, const_value);759}760761// Process If762void RangeCheckEliminator::process_if(IntegerStack &pushed, BlockBegin *block, If *cond) {763// Only if we are direct true / false successor and NOT both ! (even this may occur)764if ((cond->tsux() == block || cond->fsux() == block) && cond->tsux() != cond->fsux()) {765Instruction::Condition condition = cond->cond();766if (cond->fsux() == block) {767condition = Instruction::negate(condition);768}769Value x = cond->x();770Value y = cond->y();771if (x->type()->as_IntType() && y->type()->as_IntType()) {772add_if_condition(pushed, y, x, condition);773add_if_condition(pushed, x, y, Instruction::mirror(condition));774}775}776}777778// Process access indexed779void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai) {780TRACE_RANGE_CHECK_ELIMINATION(781tty->fill_to(block->dominator_depth()*2)782);783TRACE_RANGE_CHECK_ELIMINATION(784tty->print_cr("Access indexed: index=%d length=%d", ai->index()->id(), (ai->length() != NULL ? ai->length()->id() :-1 ))785);786787if (ai->check_flag(Instruction::NeedsRangeCheckFlag)) {788Bound *index_bound = get_bound(ai->index());789if (!index_bound->has_lower() || !index_bound->has_upper()) {790TRACE_RANGE_CHECK_ELIMINATION(791tty->fill_to(block->dominator_depth()*2);792tty->print_cr("Index instruction %d has no lower and/or no upper bound!", ai->index()->id())793);794return;795}796797Bound *array_bound;798if (ai->length()) {799array_bound = get_bound(ai->length());800} else {801array_bound = get_bound(ai->array());802}803804if (in_array_bound(index_bound, ai->array()) ||805(index_bound && array_bound && index_bound->is_smaller(array_bound) && !index_bound->lower_instr() && index_bound->lower() >= 0)) {806TRACE_RANGE_CHECK_ELIMINATION(807tty->fill_to(block->dominator_depth()*2);808tty->print_cr("Bounds check for instruction %d in block B%d can be fully eliminated!", ai->id(), ai->block()->block_id())809);810811remove_range_check(ai);812} else if (_optimistic && loop_header) {813assert(ai->array(), "Array must not be null!");814assert(ai->index(), "Index must not be null!");815816// Array instruction817Instruction *array_instr = ai->array();818if (!loop_invariant(loop_header, array_instr)) {819TRACE_RANGE_CHECK_ELIMINATION(820tty->fill_to(block->dominator_depth()*2);821tty->print_cr("Array %d is not loop invariant to header B%d", ai->array()->id(), loop_header->block_id())822);823return;824}825826// Lower instruction827Value index_instr = ai->index();828Value lower_instr = index_bound->lower_instr();829if (!loop_invariant(loop_header, lower_instr)) {830TRACE_RANGE_CHECK_ELIMINATION(831tty->fill_to(block->dominator_depth()*2);832tty->print_cr("Lower instruction %d not loop invariant!", lower_instr->id())833);834return;835}836if (!lower_instr && index_bound->lower() < 0) {837TRACE_RANGE_CHECK_ELIMINATION(838tty->fill_to(block->dominator_depth()*2);839tty->print_cr("Lower bound smaller than 0 (%d)!", index_bound->lower())840);841return;842}843844// Upper instruction845Value upper_instr = index_bound->upper_instr();846if (!loop_invariant(loop_header, upper_instr)) {847TRACE_RANGE_CHECK_ELIMINATION(848tty->fill_to(block->dominator_depth()*2);849tty->print_cr("Upper instruction %d not loop invariant!", upper_instr->id())850);851return;852}853854// Length instruction855Value length_instr = ai->length();856if (!loop_invariant(loop_header, length_instr)) {857// Generate length instruction yourself!858length_instr = NULL;859}860861TRACE_RANGE_CHECK_ELIMINATION(862tty->fill_to(block->dominator_depth()*2);863tty->print_cr("LOOP INVARIANT access indexed %d found in block B%d!", ai->id(), ai->block()->block_id())864);865866BlockBegin *pred_block = loop_header->dominator();867assert(pred_block != NULL, "Every loop header has a dominator!");868BlockEnd *pred_block_end = pred_block->end();869Instruction *insert_position = pred_block_end->prev();870ValueStack *state = pred_block_end->state_before();871if (pred_block_end->as_Goto() && state == NULL) state = pred_block_end->state();872assert(state, "State must not be null");873874// Add deoptimization to dominator of loop header875TRACE_RANGE_CHECK_ELIMINATION(876tty->fill_to(block->dominator_depth()*2);877tty->print_cr("Inserting deopt at bci %d in block B%d!", state->bci(), insert_position->block()->block_id())878);879880if (!is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper())) {881TRACE_RANGE_CHECK_ELIMINATION(882tty->fill_to(block->dominator_depth()*2);883tty->print_cr("Could not eliminate because of static analysis!")884);885return;886}887888insert_deoptimization(state, insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper(), ai);889890// Finally remove the range check!891remove_range_check(ai);892}893}894}895896void RangeCheckEliminator::remove_range_check(AccessIndexed *ai) {897ai->set_flag(Instruction::NeedsRangeCheckFlag, false);898// no range check, no need for the length instruction anymore899ai->clear_length();900901TRACE_RANGE_CHECK_ELIMINATION(902tty->fill_to(ai->dominator_depth()*2);903tty->print_cr("Range check for instruction %d eliminated!", ai->id());904);905906ASSERT_RANGE_CHECK_ELIMINATION(907Value array_length = ai->length();908if (!array_length) {909array_length = ai->array();910assert(array_length->type()->as_ObjectType(), "Has to be object type!");911}912int cur_constant = -1;913Value cur_value = array_length;914if (cur_value->type()->as_IntConstant()) {915cur_constant += cur_value->type()->as_IntConstant()->value();916cur_value = NULL;917}918Bound *new_index_bound = new Bound(0, NULL, cur_constant, cur_value);919add_assertions(new_index_bound, ai->index(), ai);920);921}922923// Calculate bounds for instruction in this block and children blocks in the dominator tree924void RangeCheckEliminator::calc_bounds(BlockBegin *block, BlockBegin *loop_header) {925// Ensures a valid loop_header926assert(!loop_header || loop_header->is_set(BlockBegin::linear_scan_loop_header_flag), "Loop header has to be real !");927928// Tracing output929TRACE_RANGE_CHECK_ELIMINATION(930tty->fill_to(block->dominator_depth()*2);931tty->print_cr("Block B%d", block->block_id());932);933934// Pushed stack for conditions935IntegerStack pushed;936// Process If937BlockBegin *parent = block->dominator();938if (parent != NULL) {939If *cond = parent->end()->as_If();940if (cond != NULL) {941process_if(pushed, block, cond);942}943}944945// Interate over current block946InstructionList arrays;947AccessIndexedList accessIndexed;948Instruction *cur = block;949950while (cur) {951// Ensure cur wasn't inserted during the elimination952if (cur->id() < this->_bounds.length()) {953// Process only if it is an access indexed instruction954AccessIndexed *ai = cur->as_AccessIndexed();955if (ai != NULL) {956process_access_indexed(loop_header, block, ai);957accessIndexed.append(ai);958if (!arrays.contains(ai->array())) {959arrays.append(ai->array());960}961Bound *b = get_bound(ai->index());962if (!b->lower_instr()) {963// Lower bound is constant964update_bound(pushed, ai->index(), Instruction::geq, NULL, 0);965}966if (!b->has_upper()) {967if (ai->length() && ai->length()->type()->as_IntConstant()) {968int value = ai->length()->type()->as_IntConstant()->value();969update_bound(pushed, ai->index(), Instruction::lss, NULL, value);970} else {971// Has no upper bound972Instruction *instr = ai->length();973if (instr != NULL) instr = ai->array();974update_bound(pushed, ai->index(), Instruction::lss, instr, 0);975}976}977}978}979cur = cur->next();980}981982// Output current condition stack983TRACE_RANGE_CHECK_ELIMINATION(dump_condition_stack(block));984985// Do in block motion of range checks986in_block_motion(block, accessIndexed, arrays);987988// Call all dominated blocks989for (int i=0; i<block->dominates()->length(); i++) {990BlockBegin *next = block->dominates()->at(i);991if (!next->is_set(BlockBegin::donot_eliminate_range_checks)) {992// if current block is a loop header and:993// - next block belongs to the same loop994// or995// - next block belongs to an inner loop996// then current block is the loop header for next block997if (block->is_set(BlockBegin::linear_scan_loop_header_flag) && (block->loop_index() == next->loop_index() || next->loop_depth() > block->loop_depth())) {998calc_bounds(next, block);999} else {1000calc_bounds(next, loop_header);1001}1002}1003}10041005// Reset stack1006for (int i=0; i<pushed.length(); i++) {1007_bounds[pushed[i]]->pop();1008}1009}10101011#ifndef PRODUCT1012// Dump condition stack1013void RangeCheckEliminator::dump_condition_stack(BlockBegin *block) {1014for (int i=0; i<_ir->linear_scan_order()->length(); i++) {1015BlockBegin *cur_block = _ir->linear_scan_order()->at(i);1016Instruction *instr = cur_block;1017for_each_phi_fun(cur_block, phi,1018BoundStack *bound_stack = _bounds.at(phi->id());1019if (bound_stack && bound_stack->length() > 0) {1020Bound *bound = bound_stack->top();1021if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != phi || bound->upper_instr() != phi || bound->lower() != 0 || bound->upper() != 0)) {1022TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());1023tty->print("i%d", phi->id());1024tty->print(": ");1025bound->print();1026tty->cr();1027);1028}1029});10301031while (!instr->as_BlockEnd()) {1032if (instr->id() < _bounds.length()) {1033BoundStack *bound_stack = _bounds.at(instr->id());1034if (bound_stack && bound_stack->length() > 0) {1035Bound *bound = bound_stack->top();1036if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != instr || bound->upper_instr() != instr || bound->lower() != 0 || bound->upper() != 0)) {1037TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());1038tty->print("i%d", instr->id());1039tty->print(": ");1040bound->print();1041tty->cr();1042);1043}1044}1045}1046instr = instr->next();1047}1048}1049}1050#endif10511052// Verification or the IR1053RangeCheckEliminator::Verification::Verification(IR *ir) : _used(BlockBegin::number_of_blocks(), false) {1054this->_ir = ir;1055ir->iterate_linear_scan_order(this);1056}10571058// Verify this block1059void RangeCheckEliminator::Verification::block_do(BlockBegin *block) {1060If *cond = block->end()->as_If();1061// Watch out: tsux and fsux can be the same!1062if (block->number_of_sux() > 1) {1063for (int i=0; i<block->number_of_sux(); i++) {1064BlockBegin *sux = block->sux_at(i);1065BlockBegin *pred = NULL;1066for (int j=0; j<sux->number_of_preds(); j++) {1067BlockBegin *cur = sux->pred_at(j);1068assert(cur != NULL, "Predecessor must not be null");1069if (!pred) {1070pred = cur;1071}1072assert(cur == pred, "Block must not have more than one predecessor if its predecessor has more than one successor");1073}1074assert(sux->number_of_preds() >= 1, "Block must have at least one predecessor");1075assert(sux->pred_at(0) == block, "Wrong successor");1076}1077}10781079BlockBegin *dominator = block->dominator();1080if (dominator) {1081assert(block != _ir->start(), "Start block must not have a dominator!");1082assert(can_reach(dominator, block), "Dominator can't reach his block !");1083assert(can_reach(_ir->start(), dominator), "Dominator is unreachable !");1084assert(!can_reach(_ir->start(), block, dominator), "Wrong dominator ! Block can be reached anyway !");1085BlockList *all_blocks = _ir->linear_scan_order();1086for (int i=0; i<all_blocks->length(); i++) {1087BlockBegin *cur = all_blocks->at(i);1088if (cur != dominator && cur != block) {1089assert(can_reach(dominator, block, cur), "There has to be another dominator!");1090}1091}1092} else {1093assert(block == _ir->start(), "Only start block must not have a dominator");1094}10951096if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) {1097int loop_index = block->loop_index();1098BlockList *all_blocks = _ir->linear_scan_order();1099assert(block->number_of_preds() >= 1, "Block must have at least one predecessor");1100assert(!block->is_set(BlockBegin::exception_entry_flag), "Loop header must not be exception handler!");1101// Sometimes, the backbranch comes from an exception handler. In1102// this case, loop indexes/loop depths may not appear correct.1103bool loop_through_xhandler = false;1104for (int i = 0; i < block->number_of_exception_handlers(); i++) {1105BlockBegin *xhandler = block->exception_handler_at(i);1106for (int j = 0; j < block->number_of_preds(); j++) {1107if (dominates(xhandler, block->pred_at(j)) || xhandler == block->pred_at(j)) {1108loop_through_xhandler = true;1109}1110}1111}11121113for (int i=0; i<block->number_of_sux(); i++) {1114BlockBegin *sux = block->sux_at(i);1115assert(sux->loop_depth() != block->loop_depth() || sux->loop_index() == block->loop_index() || loop_through_xhandler, "Loop index has to be same");1116assert(sux->loop_depth() == block->loop_depth() || sux->loop_index() != block->loop_index(), "Loop index has to be different");1117}11181119for (int i=0; i<all_blocks->length(); i++) {1120BlockBegin *cur = all_blocks->at(i);1121if (cur->loop_index() == loop_index && cur != block) {1122assert(dominates(block->dominator(), cur), "Dominator of loop header must dominate all loop blocks");1123}1124}1125}11261127Instruction *cur = block;1128while (cur) {1129assert(cur->block() == block, "Block begin has to be set correctly!");1130cur = cur->next();1131}1132}11331134// Loop header must dominate all loop blocks1135bool RangeCheckEliminator::Verification::dominates(BlockBegin *dominator, BlockBegin *block) {1136BlockBegin *cur = block->dominator();1137while (cur && cur != dominator) {1138cur = cur->dominator();1139}1140return cur == dominator;1141}11421143// Try to reach Block end beginning in Block start and not using Block dont_use1144bool RangeCheckEliminator::Verification::can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use /* = NULL */) {1145if (start == end) return start != dont_use;1146// Simple BSF from start to end1147// BlockBeginList _current;1148for (int i=0; i<_used.length(); i++) {1149_used[i] = false;1150}1151_current.truncate(0);1152_successors.truncate(0);1153if (start != dont_use) {1154_current.push(start);1155_used[start->block_id()] = true;1156}11571158// BlockBeginList _successors;1159while (_current.length() > 0) {1160BlockBegin *cur = _current.pop();1161// Add exception handlers to list1162for (int i=0; i<cur->number_of_exception_handlers(); i++) {1163BlockBegin *xhandler = cur->exception_handler_at(i);1164_successors.push(xhandler);1165// Add exception handlers of _successors to list1166for (int j=0; j<xhandler->number_of_exception_handlers(); j++) {1167BlockBegin *sux_xhandler = xhandler->exception_handler_at(j);1168_successors.push(sux_xhandler);1169}1170}1171// Add normal _successors to list1172for (int i=0; i<cur->number_of_sux(); i++) {1173BlockBegin *sux = cur->sux_at(i);1174_successors.push(sux);1175// Add exception handlers of _successors to list1176for (int j=0; j<sux->number_of_exception_handlers(); j++) {1177BlockBegin *xhandler = sux->exception_handler_at(j);1178_successors.push(xhandler);1179}1180}1181for (int i=0; i<_successors.length(); i++) {1182BlockBegin *sux = _successors[i];1183assert(sux != NULL, "Successor must not be NULL!");1184if (sux == end) {1185return true;1186}1187if (sux != dont_use && !_used[sux->block_id()]) {1188_used[sux->block_id()] = true;1189_current.push(sux);1190}1191}1192_successors.truncate(0);1193}11941195return false;1196}11971198// Bound1199RangeCheckEliminator::Bound::~Bound() {1200}12011202// Bound constructor1203RangeCheckEliminator::Bound::Bound() {1204init();1205this->_lower = min_jint;1206this->_upper = max_jint;1207this->_lower_instr = NULL;1208this->_upper_instr = NULL;1209}12101211// Bound constructor1212RangeCheckEliminator::Bound::Bound(int lower, Value lower_instr, int upper, Value upper_instr) {1213init();1214assert(!lower_instr || !lower_instr->as_Constant() || !lower_instr->type()->as_IntConstant(), "Must not be constant!");1215assert(!upper_instr || !upper_instr->as_Constant() || !upper_instr->type()->as_IntConstant(), "Must not be constant!");1216this->_lower = lower;1217this->_upper = upper;1218this->_lower_instr = lower_instr;1219this->_upper_instr = upper_instr;1220}12211222// Bound constructor1223RangeCheckEliminator::Bound::Bound(Instruction::Condition cond, Value v, int constant) {1224assert(!v || (v->type() && (v->type()->as_IntType() || v->type()->as_ObjectType())), "Type must be array or integer!");1225assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");12261227init();1228if (cond == Instruction::eql) {1229_lower = constant;1230_lower_instr = v;1231_upper = constant;1232_upper_instr = v;1233} else if (cond == Instruction::neq) {1234_lower = min_jint;1235_upper = max_jint;1236_lower_instr = NULL;1237_upper_instr = NULL;1238if (v == NULL) {1239if (constant == min_jint) {1240_lower++;1241}1242if (constant == max_jint) {1243_upper--;1244}1245}1246} else if (cond == Instruction::geq) {1247_lower = constant;1248_lower_instr = v;1249_upper = max_jint;1250_upper_instr = NULL;1251} else if (cond == Instruction::leq) {1252_lower = min_jint;1253_lower_instr = NULL;1254_upper = constant;1255_upper_instr = v;1256} else {1257ShouldNotReachHere();1258}1259}12601261// Set lower1262void RangeCheckEliminator::Bound::set_lower(int value, Value v) {1263assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");1264this->_lower = value;1265this->_lower_instr = v;1266}12671268// Set upper1269void RangeCheckEliminator::Bound::set_upper(int value, Value v) {1270assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");1271this->_upper = value;1272this->_upper_instr = v;1273}12741275// Add constant -> no overflow may occur1276void RangeCheckEliminator::Bound::add_constant(int value) {1277this->_lower += value;1278this->_upper += value;1279}12801281// Init1282void RangeCheckEliminator::Bound::init() {1283}12841285// or1286void RangeCheckEliminator::Bound::or_op(Bound *b) {1287// Watch out, bound is not guaranteed not to overflow!1288// Update lower bound1289if (_lower_instr != b->_lower_instr || (_lower_instr && _lower != b->_lower)) {1290_lower_instr = NULL;1291_lower = min_jint;1292} else {1293_lower = MIN2(_lower, b->_lower);1294}1295// Update upper bound1296if (_upper_instr != b->_upper_instr || (_upper_instr && _upper != b->_upper)) {1297_upper_instr = NULL;1298_upper = max_jint;1299} else {1300_upper = MAX2(_upper, b->_upper);1301}1302}13031304// and1305void RangeCheckEliminator::Bound::and_op(Bound *b) {1306// Update lower bound1307if (_lower_instr == b->_lower_instr) {1308_lower = MAX2(_lower, b->_lower);1309}1310if (b->has_lower()) {1311bool set = true;1312if (_lower_instr != NULL && b->_lower_instr != NULL) {1313set = (_lower_instr->dominator_depth() > b->_lower_instr->dominator_depth());1314}1315if (set) {1316_lower = b->_lower;1317_lower_instr = b->_lower_instr;1318}1319}1320// Update upper bound1321if (_upper_instr == b->_upper_instr) {1322_upper = MIN2(_upper, b->_upper);1323}1324if (b->has_upper()) {1325bool set = true;1326if (_upper_instr != NULL && b->_upper_instr != NULL) {1327set = (_upper_instr->dominator_depth() > b->_upper_instr->dominator_depth());1328}1329if (set) {1330_upper = b->_upper;1331_upper_instr = b->_upper_instr;1332}1333}1334}13351336// has_upper1337bool RangeCheckEliminator::Bound::has_upper() {1338return _upper_instr != NULL || _upper < max_jint;1339}13401341// is_smaller1342bool RangeCheckEliminator::Bound::is_smaller(Bound *b) {1343if (b->_lower_instr != _upper_instr) {1344return false;1345}1346return _upper < b->_lower;1347}13481349// has_lower1350bool RangeCheckEliminator::Bound::has_lower() {1351return _lower_instr != NULL || _lower > min_jint;1352}13531354// in_array_bound1355bool RangeCheckEliminator::in_array_bound(Bound *bound, Value array){1356if (!bound) return false;1357assert(array != NULL, "Must not be null!");1358assert(bound != NULL, "Must not be null!");1359if (bound->lower() >=0 && bound->lower_instr() == NULL && bound->upper() < 0 && bound->upper_instr() != NULL) {1360ArrayLength *len = bound->upper_instr()->as_ArrayLength();1361if (bound->upper_instr() == array || (len != NULL && len->array() == array)) {1362return true;1363}1364}1365return false;1366}13671368// remove_lower1369void RangeCheckEliminator::Bound::remove_lower() {1370_lower = min_jint;1371_lower_instr = NULL;1372}13731374// remove_upper1375void RangeCheckEliminator::Bound::remove_upper() {1376_upper = max_jint;1377_upper_instr = NULL;1378}13791380// upper1381int RangeCheckEliminator::Bound::upper() {1382return _upper;1383}13841385// lower1386int RangeCheckEliminator::Bound::lower() {1387return _lower;1388}13891390// upper_instr1391Value RangeCheckEliminator::Bound::upper_instr() {1392return _upper_instr;1393}13941395// lower_instr1396Value RangeCheckEliminator::Bound::lower_instr() {1397return _lower_instr;1398}139914001401void RangeCheckEliminator::Bound::print() {1402tty->print("%s", "");1403if (this->_lower_instr || this->_lower != min_jint) {1404if (this->_lower_instr) {1405tty->print("i%d", this->_lower_instr->id());1406if (this->_lower > 0) {1407tty->print("+%d", _lower);1408}1409if (this->_lower < 0) {1410tty->print("%d", _lower);1411}1412} else {1413tty->print("%d", _lower);1414}1415tty->print(" <= ");1416}1417tty->print("x");1418if (this->_upper_instr || this->_upper != max_jint) {1419tty->print(" <= ");1420if (this->_upper_instr) {1421tty->print("i%d", this->_upper_instr->id());1422if (this->_upper > 0) {1423tty->print("+%d", _upper);1424}1425if (this->_upper < 0) {1426tty->print("%d", _upper);1427}1428} else {1429tty->print("%d", _upper);1430}1431}1432}14331434// Copy1435RangeCheckEliminator::Bound *RangeCheckEliminator::Bound::copy() {1436Bound *b = new Bound();1437b->_lower = _lower;1438b->_lower_instr = _lower_instr;1439b->_upper = _upper;1440b->_upper_instr = _upper_instr;1441return b;1442}14431444#ifdef ASSERT1445// Add assertion1446void RangeCheckEliminator::Bound::add_assertion(Instruction *instruction, Instruction *position, int i, Value instr, Instruction::Condition cond) {1447Instruction *result = position;1448Instruction *compare_with = NULL;1449ValueStack *state = position->state_before();1450if (position->as_BlockEnd() && !position->as_Goto()) {1451state = position->as_BlockEnd()->state_before();1452}1453Instruction *instruction_before = position->prev();1454if (position->as_Return() && Compilation::current()->method()->is_synchronized() && instruction_before->as_MonitorExit()) {1455instruction_before = instruction_before->prev();1456}1457result = instruction_before;1458// Load constant only if needed1459Constant *constant = NULL;1460if (i != 0 || !instr) {1461constant = new Constant(new IntConstant(i));1462NOT_PRODUCT(constant->set_printable_bci(position->printable_bci()));1463result = result->insert_after(constant);1464compare_with = constant;1465}14661467if (instr) {1468assert(instr->type()->as_ObjectType() || instr->type()->as_IntType(), "Type must be array or integer!");1469compare_with = instr;1470// Load array length if necessary1471Instruction *op = instr;1472if (instr->type()->as_ObjectType()) {1473assert(state, "must not be null");1474ArrayLength *length = new ArrayLength(instr, state->copy());1475NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));1476length->set_exception_state(length->state_before());1477result = result->insert_after(length);1478op = length;1479compare_with = length;1480}1481// Add operation only if necessary1482if (constant) {1483ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, op, false, NULL);1484NOT_PRODUCT(ao->set_printable_bci(position->printable_bci()));1485result = result->insert_after(ao);1486compare_with = ao;1487// TODO: Check that add operation does not overflow!1488}1489}1490assert(compare_with != NULL, "You have to compare with something!");1491assert(instruction != NULL, "Instruction must not be null!");14921493if (instruction->type()->as_ObjectType()) {1494// Load array length if necessary1495Instruction *op = instruction;1496assert(state, "must not be null");1497ArrayLength *length = new ArrayLength(instruction, state->copy());1498length->set_exception_state(length->state_before());1499NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));1500result = result->insert_after(length);1501instruction = length;1502}15031504Assert *assert = new Assert(instruction, cond, false, compare_with);1505NOT_PRODUCT(assert->set_printable_bci(position->printable_bci()));1506result->insert_after(assert);1507}15081509// Add assertions1510void RangeCheckEliminator::add_assertions(Bound *bound, Instruction *instruction, Instruction *position) {1511// Add lower bound assertion1512if (bound->has_lower()) {1513bound->add_assertion(instruction, position, bound->lower(), bound->lower_instr(), Instruction::geq);1514}1515// Add upper bound assertion1516if (bound->has_upper()) {1517bound->add_assertion(instruction, position, bound->upper(), bound->upper_instr(), Instruction::leq);1518}1519}1520#endif1521152215231524