src/share/vm/c1/c1_RangeCheckElimination.cpp

Thu, 24 May 2018 18:41:44 +0800

author
aoqi
date
Thu, 24 May 2018 18:41:44 +0800
changeset 8856
ac27a9c85bea
parent 6876
710a3c8b516e
permissions
-rw-r--r--

Merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "c1/c1_ValueStack.hpp"
aoqi@0 27 #include "c1/c1_RangeCheckElimination.hpp"
aoqi@0 28 #include "c1/c1_IR.hpp"
aoqi@0 29 #include "c1/c1_Canonicalizer.hpp"
aoqi@0 30 #include "c1/c1_ValueMap.hpp"
aoqi@0 31 #include "ci/ciMethodData.hpp"
aoqi@0 32 #include "runtime/deoptimization.hpp"
aoqi@0 33
aoqi@0 34 // Macros for the Trace and the Assertion flag
aoqi@0 35 #ifdef ASSERT
aoqi@0 36 #define TRACE_RANGE_CHECK_ELIMINATION(code) if (TraceRangeCheckElimination) { code; }
aoqi@0 37 #define ASSERT_RANGE_CHECK_ELIMINATION(code) if (AssertRangeCheckElimination) { code; }
aoqi@0 38 #define TRACE_OR_ASSERT_RANGE_CHECK_ELIMINATION(code) if (TraceRangeCheckElimination || AssertRangeCheckElimination) { code; }
aoqi@0 39 #else
aoqi@0 40 #define TRACE_RANGE_CHECK_ELIMINATION(code)
aoqi@0 41 #define ASSERT_RANGE_CHECK_ELIMINATION(code)
aoqi@0 42 #define TRACE_OR_ASSERT_RANGE_CHECK_ELIMINATION(code)
aoqi@0 43 #endif
aoqi@0 44
aoqi@0 45 // Entry point for the optimization
aoqi@0 46 void RangeCheckElimination::eliminate(IR *ir) {
aoqi@0 47 bool do_elimination = ir->compilation()->has_access_indexed();
aoqi@0 48 ASSERT_RANGE_CHECK_ELIMINATION(do_elimination = true);
aoqi@0 49 if (do_elimination) {
aoqi@0 50 RangeCheckEliminator rce(ir);
aoqi@0 51 }
aoqi@0 52 }
aoqi@0 53
aoqi@0 54 // Constructor
aoqi@0 55 RangeCheckEliminator::RangeCheckEliminator(IR *ir) :
aoqi@0 56 _bounds(Instruction::number_of_instructions(), NULL),
aoqi@0 57 _access_indexed_info(Instruction::number_of_instructions(), NULL)
aoqi@0 58 {
aoqi@0 59 _visitor.set_range_check_eliminator(this);
aoqi@0 60 _ir = ir;
aoqi@0 61 _number_of_instructions = Instruction::number_of_instructions();
aoqi@0 62 _optimistic = ir->compilation()->is_optimistic();
aoqi@0 63
aoqi@0 64 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 65 tty->cr();
aoqi@0 66 tty->print_cr("Range check elimination");
aoqi@0 67 ir->method()->print_name(tty);
aoqi@0 68 tty->cr();
aoqi@0 69 );
aoqi@0 70
aoqi@0 71 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 72 tty->print_cr("optimistic=%d", (int)_optimistic);
aoqi@0 73 );
aoqi@0 74
aoqi@0 75 #ifdef ASSERT
aoqi@0 76 // Verifies several conditions that must be true on the IR-input. Only used for debugging purposes.
aoqi@0 77 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 78 tty->print_cr("Verification of IR . . .");
aoqi@0 79 );
aoqi@0 80 Verification verification(ir);
aoqi@0 81 #endif
aoqi@0 82
aoqi@0 83 // Set process block flags
aoqi@0 84 // Optimization so a blocks is only processed if it contains an access indexed instruction or if
aoqi@0 85 // one of its children in the dominator tree contains an access indexed instruction.
aoqi@0 86 set_process_block_flags(ir->start());
aoqi@0 87
aoqi@0 88 // Pass over instructions in the dominator tree
aoqi@0 89 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 90 tty->print_cr("Starting pass over dominator tree . . .")
aoqi@0 91 );
aoqi@0 92 calc_bounds(ir->start(), NULL);
aoqi@0 93
aoqi@0 94 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 95 tty->print_cr("Finished!")
aoqi@0 96 );
aoqi@0 97 }
aoqi@0 98
aoqi@0 99 // Instruction specific work for some instructions
aoqi@0 100 // Constant
aoqi@0 101 void RangeCheckEliminator::Visitor::do_Constant(Constant *c) {
aoqi@0 102 IntConstant *ic = c->type()->as_IntConstant();
aoqi@0 103 if (ic != NULL) {
aoqi@0 104 int value = ic->value();
aoqi@0 105 _bound = new Bound(value, NULL, value, NULL);
aoqi@0 106 }
aoqi@0 107 }
aoqi@0 108
aoqi@0 109 // LogicOp
aoqi@0 110 void RangeCheckEliminator::Visitor::do_LogicOp(LogicOp *lo) {
aoqi@0 111 if (lo->type()->as_IntType() && lo->op() == Bytecodes::_iand && (lo->x()->as_Constant() || lo->y()->as_Constant())) {
aoqi@0 112 int constant = 0;
aoqi@0 113 Constant *c = lo->x()->as_Constant();
aoqi@0 114 if (c != NULL) {
aoqi@0 115 constant = c->type()->as_IntConstant()->value();
aoqi@0 116 } else {
aoqi@0 117 constant = lo->y()->as_Constant()->type()->as_IntConstant()->value();
aoqi@0 118 }
aoqi@0 119 if (constant >= 0) {
aoqi@0 120 _bound = new Bound(0, NULL, constant, NULL);
aoqi@0 121 }
aoqi@0 122 }
aoqi@0 123 }
aoqi@0 124
aoqi@0 125 // Phi
aoqi@0 126 void RangeCheckEliminator::Visitor::do_Phi(Phi *phi) {
aoqi@0 127 if (!phi->type()->as_IntType() && !phi->type()->as_ObjectType()) return;
aoqi@0 128
aoqi@0 129 BlockBegin *block = phi->block();
aoqi@0 130 int op_count = phi->operand_count();
aoqi@0 131 bool has_upper = true;
aoqi@0 132 bool has_lower = true;
aoqi@0 133 assert(phi, "Phi must not be null");
aoqi@0 134 Bound *bound = NULL;
aoqi@0 135
aoqi@0 136 // TODO: support more difficult phis
aoqi@0 137 for (int i=0; i<op_count; i++) {
aoqi@0 138 Value v = phi->operand_at(i);
aoqi@0 139
aoqi@0 140 if (v == phi) continue;
aoqi@0 141
aoqi@0 142 // Check if instruction is connected with phi itself
aoqi@0 143 Op2 *op2 = v->as_Op2();
aoqi@0 144 if (op2 != NULL) {
aoqi@0 145 Value x = op2->x();
aoqi@0 146 Value y = op2->y();
aoqi@0 147 if ((x == phi || y == phi)) {
aoqi@0 148 Value other = x;
aoqi@0 149 if (other == phi) {
aoqi@0 150 other = y;
aoqi@0 151 }
aoqi@0 152 ArithmeticOp *ao = v->as_ArithmeticOp();
aoqi@0 153 if (ao != NULL && ao->op() == Bytecodes::_iadd) {
aoqi@0 154 assert(ao->op() == Bytecodes::_iadd, "Has to be add!");
aoqi@0 155 if (ao->type()->as_IntType()) {
aoqi@0 156 Constant *c = other->as_Constant();
aoqi@0 157 if (c != NULL) {
aoqi@0 158 assert(c->type()->as_IntConstant(), "Constant has to be of type integer");
aoqi@0 159 int value = c->type()->as_IntConstant()->value();
aoqi@0 160 if (value == 1) {
aoqi@0 161 has_upper = false;
aoqi@0 162 } else if (value > 1) {
aoqi@0 163 // Overflow not guaranteed
aoqi@0 164 has_upper = false;
aoqi@0 165 has_lower = false;
aoqi@0 166 } else if (value < 0) {
aoqi@0 167 has_lower = false;
aoqi@0 168 }
aoqi@0 169 continue;
aoqi@0 170 }
aoqi@0 171 }
aoqi@0 172 }
aoqi@0 173 }
aoqi@0 174 }
aoqi@0 175
aoqi@0 176 // No connection -> new bound
aoqi@0 177 Bound *v_bound = _rce->get_bound(v);
aoqi@0 178 Bound *cur_bound;
aoqi@0 179 int cur_constant = 0;
aoqi@0 180 Value cur_value = v;
aoqi@0 181
aoqi@0 182 if (v->type()->as_IntConstant()) {
aoqi@0 183 cur_constant = v->type()->as_IntConstant()->value();
aoqi@0 184 cur_value = NULL;
aoqi@0 185 }
aoqi@0 186 if (!v_bound->has_upper() || !v_bound->has_lower()) {
aoqi@0 187 cur_bound = new Bound(cur_constant, cur_value, cur_constant, cur_value);
aoqi@0 188 } else {
aoqi@0 189 cur_bound = v_bound;
aoqi@0 190 }
aoqi@0 191 if (cur_bound) {
aoqi@0 192 if (!bound) {
aoqi@0 193 bound = cur_bound->copy();
aoqi@0 194 } else {
aoqi@0 195 bound->or_op(cur_bound);
aoqi@0 196 }
aoqi@0 197 } else {
aoqi@0 198 // No bound!
aoqi@0 199 bound = NULL;
aoqi@0 200 break;
aoqi@0 201 }
aoqi@0 202 }
aoqi@0 203
aoqi@0 204 if (bound) {
aoqi@0 205 if (!has_upper) {
aoqi@0 206 bound->remove_upper();
aoqi@0 207 }
aoqi@0 208 if (!has_lower) {
aoqi@0 209 bound->remove_lower();
aoqi@0 210 }
aoqi@0 211 _bound = bound;
aoqi@0 212 } else {
aoqi@0 213 _bound = new Bound();
aoqi@0 214 }
aoqi@0 215 }
aoqi@0 216
aoqi@0 217
aoqi@0 218 // ArithmeticOp
aoqi@0 219 void RangeCheckEliminator::Visitor::do_ArithmeticOp(ArithmeticOp *ao) {
aoqi@0 220 Value x = ao->x();
aoqi@0 221 Value y = ao->y();
aoqi@0 222
aoqi@0 223 if (ao->op() == Bytecodes::_irem) {
aoqi@0 224 Bound* x_bound = _rce->get_bound(x);
aoqi@0 225 Bound* y_bound = _rce->get_bound(y);
aoqi@0 226 if (x_bound->lower() >= 0 && x_bound->lower_instr() == NULL && y->as_ArrayLength() != NULL) {
aoqi@0 227 _bound = new Bound(0, NULL, -1, y);
aoqi@0 228 } else {
aoqi@0 229 _bound = new Bound();
aoqi@0 230 }
aoqi@0 231 } else if (!x->as_Constant() || !y->as_Constant()) {
aoqi@0 232 assert(!x->as_Constant() || !y->as_Constant(), "One of the operands must be non-constant!");
aoqi@0 233 if (((x->as_Constant() || y->as_Constant()) && (ao->op() == Bytecodes::_iadd)) || (y->as_Constant() && ao->op() == Bytecodes::_isub)) {
aoqi@0 234 assert(ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub, "Operand must be iadd or isub");
aoqi@0 235
aoqi@0 236 if (y->as_Constant()) {
aoqi@0 237 Value tmp = x;
aoqi@0 238 x = y;
aoqi@0 239 y = tmp;
aoqi@0 240 }
aoqi@0 241 assert(x->as_Constant()->type()->as_IntConstant(), "Constant must be int constant!");
aoqi@0 242
aoqi@0 243 // Constant now in x
aoqi@0 244 int const_value = x->as_Constant()->type()->as_IntConstant()->value();
aoqi@0 245 if (ao->op() == Bytecodes::_iadd || const_value != min_jint) {
aoqi@0 246 if (ao->op() == Bytecodes::_isub) {
aoqi@0 247 const_value = -const_value;
aoqi@0 248 }
aoqi@0 249
aoqi@0 250 Bound * bound = _rce->get_bound(y);
aoqi@0 251 if (bound->has_upper() && bound->has_lower()) {
aoqi@0 252 int new_lower = bound->lower() + const_value;
aoqi@0 253 jlong new_lowerl = ((jlong)bound->lower()) + const_value;
aoqi@0 254 int new_upper = bound->upper() + const_value;
aoqi@0 255 jlong new_upperl = ((jlong)bound->upper()) + const_value;
aoqi@0 256
aoqi@0 257 if (((jlong)new_lower) == new_lowerl && ((jlong)new_upper == new_upperl)) {
aoqi@0 258 Bound *newBound = new Bound(new_lower, bound->lower_instr(), new_upper, bound->upper_instr());
aoqi@0 259 _bound = newBound;
aoqi@0 260 } else {
aoqi@0 261 // overflow
aoqi@0 262 _bound = new Bound();
aoqi@0 263 }
aoqi@0 264 } else {
aoqi@0 265 _bound = new Bound();
aoqi@0 266 }
aoqi@0 267 } else {
aoqi@0 268 _bound = new Bound();
aoqi@0 269 }
aoqi@0 270 } else {
aoqi@0 271 Bound *bound = _rce->get_bound(x);
aoqi@0 272 if (ao->op() == Bytecodes::_isub) {
aoqi@0 273 if (bound->lower_instr() == y) {
aoqi@0 274 _bound = new Bound(Instruction::geq, NULL, bound->lower());
aoqi@0 275 } else {
aoqi@0 276 _bound = new Bound();
aoqi@0 277 }
aoqi@0 278 } else {
aoqi@0 279 _bound = new Bound();
aoqi@0 280 }
aoqi@0 281 }
aoqi@0 282 }
aoqi@0 283 }
aoqi@0 284
aoqi@0 285 // IfOp
aoqi@0 286 void RangeCheckEliminator::Visitor::do_IfOp(IfOp *ifOp)
aoqi@0 287 {
aoqi@0 288 if (ifOp->tval()->type()->as_IntConstant() && ifOp->fval()->type()->as_IntConstant()) {
aoqi@0 289 int min = ifOp->tval()->type()->as_IntConstant()->value();
aoqi@0 290 int max = ifOp->fval()->type()->as_IntConstant()->value();
aoqi@0 291 if (min > max) {
aoqi@0 292 // min ^= max ^= min ^= max;
aoqi@0 293 int tmp = min;
aoqi@0 294 min = max;
aoqi@0 295 max = tmp;
aoqi@0 296 }
aoqi@0 297 _bound = new Bound(min, NULL, max, NULL);
aoqi@0 298 }
aoqi@0 299 }
aoqi@0 300
aoqi@0 301 // Get bound. Returns the current bound on Value v. Normally this is the topmost element on the bound stack.
aoqi@0 302 RangeCheckEliminator::Bound *RangeCheckEliminator::get_bound(Value v) {
aoqi@0 303 // Wrong type or NULL -> No bound
aoqi@0 304 if (!v || (!v->type()->as_IntType() && !v->type()->as_ObjectType())) return NULL;
aoqi@0 305
aoqi@0 306 if (!_bounds[v->id()]) {
aoqi@0 307 // First (default) bound is calculated
aoqi@0 308 // Create BoundStack
aoqi@0 309 _bounds[v->id()] = new BoundStack();
aoqi@0 310 _visitor.clear_bound();
aoqi@0 311 Value visit_value = v;
aoqi@0 312 visit_value->visit(&_visitor);
aoqi@0 313 Bound *bound = _visitor.bound();
aoqi@0 314 if (bound) {
aoqi@0 315 _bounds[v->id()]->push(bound);
aoqi@0 316 }
aoqi@0 317 if (_bounds[v->id()]->length() == 0) {
aoqi@0 318 assert(!(v->as_Constant() && v->type()->as_IntConstant()), "constants not handled here");
aoqi@0 319 _bounds[v->id()]->push(new Bound());
aoqi@0 320 }
aoqi@0 321 } else if (_bounds[v->id()]->length() == 0) {
aoqi@0 322 // To avoid endless loops, bound is currently in calculation -> nothing known about it
aoqi@0 323 return new Bound();
aoqi@0 324 }
aoqi@0 325
aoqi@0 326 // Return bound
aoqi@0 327 return _bounds[v->id()]->top();
aoqi@0 328 }
aoqi@0 329
aoqi@0 330 // Update bound
aoqi@0 331 void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Instruction::Condition cond, Value value, int constant) {
aoqi@0 332 if (cond == Instruction::gtr) {
aoqi@0 333 cond = Instruction::geq;
aoqi@0 334 constant++;
aoqi@0 335 } else if (cond == Instruction::lss) {
aoqi@0 336 cond = Instruction::leq;
aoqi@0 337 constant--;
aoqi@0 338 }
aoqi@0 339 Bound *bound = new Bound(cond, value, constant);
aoqi@0 340 update_bound(pushed, v, bound);
aoqi@0 341 }
aoqi@0 342
aoqi@0 343 // Checks for loop invariance. Returns true if the instruction is outside of the loop which is identified by loop_header.
aoqi@0 344 bool RangeCheckEliminator::loop_invariant(BlockBegin *loop_header, Instruction *instruction) {
aoqi@0 345 assert(loop_header, "Loop header must not be null!");
aoqi@0 346 if (!instruction) return true;
aoqi@0 347 return instruction->dominator_depth() < loop_header->dominator_depth();
aoqi@0 348 }
aoqi@0 349
aoqi@0 350 // Update bound. Pushes a new bound onto the stack. Tries to do a conjunction with the current bound.
aoqi@0 351 void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Bound *bound) {
aoqi@0 352 if (v->as_Constant()) {
aoqi@0 353 // No bound update for constants
aoqi@0 354 return;
aoqi@0 355 }
aoqi@0 356 if (!_bounds[v->id()]) {
aoqi@0 357 get_bound(v);
aoqi@0 358 assert(_bounds[v->id()], "Now Stack must exist");
aoqi@0 359 }
aoqi@0 360 Bound *top = NULL;
aoqi@0 361 if (_bounds[v->id()]->length() > 0) {
aoqi@0 362 top = _bounds[v->id()]->top();
aoqi@0 363 }
aoqi@0 364 if (top) {
aoqi@0 365 bound->and_op(top);
aoqi@0 366 }
aoqi@0 367 _bounds[v->id()]->push(bound);
aoqi@0 368 pushed.append(v->id());
aoqi@0 369 }
aoqi@0 370
aoqi@0 371 // Add instruction + idx for in block motion
aoqi@0 372 void RangeCheckEliminator::add_access_indexed_info(InstructionList &indices, int idx, Value instruction, AccessIndexed *ai) {
aoqi@0 373 int id = instruction->id();
aoqi@0 374 AccessIndexedInfo *aii = _access_indexed_info[id];
aoqi@0 375 if (aii == NULL) {
aoqi@0 376 aii = new AccessIndexedInfo();
aoqi@0 377 _access_indexed_info[id] = aii;
aoqi@0 378 indices.append(instruction);
aoqi@0 379 aii->_min = idx;
aoqi@0 380 aii->_max = idx;
aoqi@0 381 aii->_list = new AccessIndexedList();
aoqi@0 382 } else if (idx >= aii->_min && idx <= aii->_max) {
aoqi@0 383 remove_range_check(ai);
aoqi@0 384 return;
aoqi@0 385 }
aoqi@0 386 aii->_min = MIN2(aii->_min, idx);
aoqi@0 387 aii->_max = MAX2(aii->_max, idx);
aoqi@0 388 aii->_list->append(ai);
aoqi@0 389 }
aoqi@0 390
aoqi@0 391 // In block motion. Tries to reorder checks in order to reduce some of them.
aoqi@0 392 // Example:
aoqi@0 393 // a[i] = 0;
aoqi@0 394 // a[i+2] = 0;
aoqi@0 395 // a[i+1] = 0;
aoqi@0 396 // In this example the check for a[i+1] would be considered as unnecessary during the first iteration.
aoqi@0 397 // After this i is only checked once for i >= 0 and i+2 < a.length before the first array access. If this
aoqi@0 398 // check fails, deoptimization is called.
aoqi@0 399 void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList &accessIndexed, InstructionList &arrays) {
aoqi@0 400 InstructionList indices;
aoqi@0 401
aoqi@0 402 // Now iterate over all arrays
aoqi@0 403 for (int i=0; i<arrays.length(); i++) {
aoqi@0 404 int max_constant = -1;
aoqi@0 405 AccessIndexedList list_constant;
aoqi@0 406 Value array = arrays.at(i);
aoqi@0 407
aoqi@0 408 // For all AccessIndexed-instructions in this block concerning the current array.
aoqi@0 409 for(int j=0; j<accessIndexed.length(); j++) {
aoqi@0 410 AccessIndexed *ai = accessIndexed.at(j);
aoqi@0 411 if (ai->array() != array || !ai->check_flag(Instruction::NeedsRangeCheckFlag)) continue;
aoqi@0 412
aoqi@0 413 Value index = ai->index();
aoqi@0 414 Constant *c = index->as_Constant();
aoqi@0 415 if (c != NULL) {
aoqi@0 416 int constant_value = c->type()->as_IntConstant()->value();
aoqi@0 417 if (constant_value >= 0) {
aoqi@0 418 if (constant_value <= max_constant) {
aoqi@0 419 // No range check needed for this
aoqi@0 420 remove_range_check(ai);
aoqi@0 421 } else {
aoqi@0 422 max_constant = constant_value;
aoqi@0 423 list_constant.append(ai);
aoqi@0 424 }
aoqi@0 425 }
aoqi@0 426 } else {
aoqi@0 427 int last_integer = 0;
aoqi@0 428 Instruction *last_instruction = index;
aoqi@0 429 int base = 0;
aoqi@0 430 ArithmeticOp *ao = index->as_ArithmeticOp();
aoqi@0 431
aoqi@0 432 while (ao != NULL && (ao->x()->as_Constant() || ao->y()->as_Constant()) && (ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub)) {
aoqi@0 433 c = ao->y()->as_Constant();
aoqi@0 434 Instruction *other = ao->x();
aoqi@0 435 if (!c && ao->op() == Bytecodes::_iadd) {
aoqi@0 436 c = ao->x()->as_Constant();
aoqi@0 437 other = ao->y();
aoqi@0 438 }
aoqi@0 439
aoqi@0 440 if (c) {
aoqi@0 441 int value = c->type()->as_IntConstant()->value();
aoqi@0 442 if (value != min_jint) {
aoqi@0 443 if (ao->op() == Bytecodes::_isub) {
aoqi@0 444 value = -value;
aoqi@0 445 }
aoqi@0 446 base += value;
aoqi@0 447 last_integer = base;
aoqi@0 448 last_instruction = other;
aoqi@0 449 }
aoqi@0 450 index = other;
aoqi@0 451 } else {
aoqi@0 452 break;
aoqi@0 453 }
aoqi@0 454 ao = index->as_ArithmeticOp();
aoqi@0 455 }
aoqi@0 456 add_access_indexed_info(indices, last_integer, last_instruction, ai);
aoqi@0 457 }
aoqi@0 458 }
aoqi@0 459
aoqi@0 460 // Iterate over all different indices
aoqi@0 461 if (_optimistic) {
aoqi@0 462 for (int i = 0; i < indices.length(); i++) {
aoqi@0 463 Instruction *index_instruction = indices.at(i);
aoqi@0 464 AccessIndexedInfo *info = _access_indexed_info[index_instruction->id()];
aoqi@0 465 assert(info != NULL, "Info must not be null");
aoqi@0 466
aoqi@0 467 // if idx < 0, max > 0, max + idx may fall between 0 and
aoqi@0 468 // length-1 and if min < 0, min + idx may overflow and be >=
aoqi@0 469 // 0. The predicate wouldn't trigger but some accesses could
aoqi@0 470 // be with a negative index. This test guarantees that for the
aoqi@0 471 // min and max value that are kept the predicate can't let
aoqi@0 472 // some incorrect accesses happen.
aoqi@0 473 bool range_cond = (info->_max < 0 || info->_max + min_jint <= info->_min);
aoqi@0 474
aoqi@0 475 // Generate code only if more than 2 range checks can be eliminated because of that.
aoqi@0 476 // 2 because at least 2 comparisons are done
aoqi@0 477 if (info->_list->length() > 2 && range_cond) {
aoqi@0 478 AccessIndexed *first = info->_list->at(0);
aoqi@0 479 Instruction *insert_position = first->prev();
aoqi@0 480 assert(insert_position->next() == first, "prev was calculated");
aoqi@0 481 ValueStack *state = first->state_before();
aoqi@0 482
aoqi@0 483 // Load min Constant
aoqi@0 484 Constant *min_constant = NULL;
aoqi@0 485 if (info->_min != 0) {
aoqi@0 486 min_constant = new Constant(new IntConstant(info->_min));
aoqi@0 487 NOT_PRODUCT(min_constant->set_printable_bci(first->printable_bci()));
aoqi@0 488 insert_position = insert_position->insert_after(min_constant);
aoqi@0 489 }
aoqi@0 490
aoqi@0 491 // Load max Constant
aoqi@0 492 Constant *max_constant = NULL;
aoqi@0 493 if (info->_max != 0) {
aoqi@0 494 max_constant = new Constant(new IntConstant(info->_max));
aoqi@0 495 NOT_PRODUCT(max_constant->set_printable_bci(first->printable_bci()));
aoqi@0 496 insert_position = insert_position->insert_after(max_constant);
aoqi@0 497 }
aoqi@0 498
aoqi@0 499 // Load array length
aoqi@0 500 Value length_instr = first->length();
aoqi@0 501 if (!length_instr) {
aoqi@0 502 ArrayLength *length = new ArrayLength(array, first->state_before()->copy());
aoqi@0 503 length->set_exception_state(length->state_before());
aoqi@0 504 length->set_flag(Instruction::DeoptimizeOnException, true);
aoqi@0 505 insert_position = insert_position->insert_after_same_bci(length);
aoqi@0 506 length_instr = length;
aoqi@0 507 }
aoqi@0 508
aoqi@0 509 // Calculate lower bound
aoqi@0 510 Instruction *lower_compare = index_instruction;
aoqi@0 511 if (min_constant) {
aoqi@0 512 ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, min_constant, lower_compare, false, NULL);
aoqi@0 513 insert_position = insert_position->insert_after_same_bci(ao);
aoqi@0 514 lower_compare = ao;
aoqi@0 515 }
aoqi@0 516
aoqi@0 517 // Calculate upper bound
aoqi@0 518 Instruction *upper_compare = index_instruction;
aoqi@0 519 if (max_constant) {
aoqi@0 520 ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, max_constant, upper_compare, false, NULL);
aoqi@0 521 insert_position = insert_position->insert_after_same_bci(ao);
aoqi@0 522 upper_compare = ao;
aoqi@0 523 }
aoqi@0 524
aoqi@0 525 // Trick with unsigned compare is done
aoqi@0 526 int bci = NOT_PRODUCT(first->printable_bci()) PRODUCT_ONLY(-1);
aoqi@0 527 insert_position = predicate(upper_compare, Instruction::aeq, length_instr, state, insert_position, bci);
aoqi@0 528 insert_position = predicate_cmp_with_const(lower_compare, Instruction::leq, -1, state, insert_position);
aoqi@0 529 for (int j = 0; j<info->_list->length(); j++) {
aoqi@0 530 AccessIndexed *ai = info->_list->at(j);
aoqi@0 531 remove_range_check(ai);
aoqi@0 532 }
aoqi@0 533 }
aoqi@0 534 }
aoqi@0 535
aoqi@0 536 if (list_constant.length() > 1) {
aoqi@0 537 AccessIndexed *first = list_constant.at(0);
aoqi@0 538 Instruction *insert_position = first->prev();
aoqi@0 539 ValueStack *state = first->state_before();
aoqi@0 540 // Load max Constant
aoqi@0 541 Constant *constant = new Constant(new IntConstant(max_constant));
aoqi@0 542 NOT_PRODUCT(constant->set_printable_bci(first->printable_bci()));
aoqi@0 543 insert_position = insert_position->insert_after(constant);
aoqi@0 544 Instruction *compare_instr = constant;
aoqi@0 545 Value length_instr = first->length();
aoqi@0 546 if (!length_instr) {
aoqi@0 547 ArrayLength *length = new ArrayLength(array, state->copy());
aoqi@0 548 length->set_exception_state(length->state_before());
aoqi@0 549 length->set_flag(Instruction::DeoptimizeOnException, true);
aoqi@0 550 insert_position = insert_position->insert_after_same_bci(length);
aoqi@0 551 length_instr = length;
aoqi@0 552 }
aoqi@0 553 // Compare for greater or equal to array length
aoqi@0 554 insert_position = predicate(compare_instr, Instruction::geq, length_instr, state, insert_position);
aoqi@0 555 for (int j = 0; j<list_constant.length(); j++) {
aoqi@0 556 AccessIndexed *ai = list_constant.at(j);
aoqi@0 557 remove_range_check(ai);
aoqi@0 558 }
aoqi@0 559 }
aoqi@0 560 }
aoqi@0 561
aoqi@0 562 // Clear data structures for next array
aoqi@0 563 for (int i = 0; i < indices.length(); i++) {
aoqi@0 564 Instruction *index_instruction = indices.at(i);
aoqi@0 565 _access_indexed_info[index_instruction->id()] = NULL;
aoqi@0 566 }
aoqi@0 567 indices.clear();
aoqi@0 568 }
aoqi@0 569 }
aoqi@0 570
aoqi@0 571 bool RangeCheckEliminator::set_process_block_flags(BlockBegin *block) {
aoqi@0 572 Instruction *cur = block;
aoqi@0 573 bool process = false;
aoqi@0 574
aoqi@0 575 while (cur) {
aoqi@0 576 process |= (cur->as_AccessIndexed() != NULL);
aoqi@0 577 cur = cur->next();
aoqi@0 578 }
aoqi@0 579
aoqi@0 580 BlockList *dominates = block->dominates();
aoqi@0 581 for (int i=0; i<dominates->length(); i++) {
aoqi@0 582 BlockBegin *next = dominates->at(i);
aoqi@0 583 process |= set_process_block_flags(next);
aoqi@0 584 }
aoqi@0 585
aoqi@0 586 if (!process) {
aoqi@0 587 block->set(BlockBegin::donot_eliminate_range_checks);
aoqi@0 588 }
aoqi@0 589 return process;
aoqi@0 590 }
aoqi@0 591
aoqi@0 592 bool RangeCheckEliminator::is_ok_for_deoptimization(Instruction *insert_position, Instruction *array_instr, Instruction *length_instr, Instruction *lower_instr, int lower, Instruction *upper_instr, int upper) {
aoqi@0 593 bool upper_check = true;
aoqi@0 594 assert(lower_instr || lower >= 0, "If no lower_instr present, lower must be greater 0");
aoqi@0 595 assert(!lower_instr || lower_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
aoqi@0 596 assert(!upper_instr || upper_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
aoqi@0 597 assert(array_instr, "Array instruction must exist");
aoqi@0 598 assert(array_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
aoqi@0 599 assert(!length_instr || length_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
aoqi@0 600
aoqi@0 601 if (upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr) {
aoqi@0 602 // static check
aoqi@0 603 if (upper >= 0) return false; // would always trigger a deopt:
aoqi@0 604 // array_length + x >= array_length, x >= 0 is always true
aoqi@0 605 upper_check = false;
aoqi@0 606 }
aoqi@0 607 if (lower_instr && lower_instr->as_ArrayLength() && lower_instr->as_ArrayLength()->array() == array_instr) {
aoqi@0 608 if (lower > 0) return false;
aoqi@0 609 }
aoqi@0 610 // No upper check required -> skip
aoqi@0 611 if (upper_check && upper_instr && upper_instr->type()->as_ObjectType() && upper_instr == array_instr) {
aoqi@0 612 // upper_instr is object means that the upper bound is the length
aoqi@0 613 // of the upper_instr.
aoqi@0 614 return false;
aoqi@0 615 }
aoqi@0 616 return true;
aoqi@0 617 }
aoqi@0 618
aoqi@0 619 Instruction* RangeCheckEliminator::insert_after(Instruction* insert_position, Instruction* instr, int bci) {
aoqi@0 620 if (bci != -1) {
aoqi@0 621 NOT_PRODUCT(instr->set_printable_bci(bci));
aoqi@0 622 return insert_position->insert_after(instr);
aoqi@0 623 } else {
aoqi@0 624 return insert_position->insert_after_same_bci(instr);
aoqi@0 625 }
aoqi@0 626 }
aoqi@0 627
aoqi@0 628 Instruction* RangeCheckEliminator::predicate(Instruction* left, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {
aoqi@0 629 RangeCheckPredicate *deoptimize = new RangeCheckPredicate(left, cond, true, right, state->copy());
aoqi@0 630 return insert_after(insert_position, deoptimize, bci);
aoqi@0 631 }
aoqi@0 632
aoqi@0 633 Instruction* RangeCheckEliminator::predicate_cmp_with_const(Instruction* instr, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) {
aoqi@0 634 Constant *const_instr = new Constant(new IntConstant(constant));
aoqi@0 635 insert_position = insert_after(insert_position, const_instr, bci);
aoqi@0 636 return predicate(instr, cond, const_instr, state, insert_position);
aoqi@0 637 }
aoqi@0 638
aoqi@0 639 Instruction* RangeCheckEliminator::predicate_add(Instruction* left, int left_const, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {
aoqi@0 640 Constant *constant = new Constant(new IntConstant(left_const));
aoqi@0 641 insert_position = insert_after(insert_position, constant, bci);
aoqi@0 642 ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, left, false, NULL);
aoqi@0 643 insert_position = insert_position->insert_after_same_bci(ao);
aoqi@0 644 return predicate(ao, cond, right, state, insert_position);
aoqi@0 645 }
aoqi@0 646
aoqi@0 647 Instruction* RangeCheckEliminator::predicate_add_cmp_with_const(Instruction* left, int left_const, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) {
aoqi@0 648 Constant *const_instr = new Constant(new IntConstant(constant));
aoqi@0 649 insert_position = insert_after(insert_position, const_instr, bci);
aoqi@0 650 return predicate_add(left, left_const, cond, const_instr, state, insert_position);
aoqi@0 651 }
aoqi@0 652
aoqi@0 653 // Insert deoptimization
aoqi@0 654 void 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) {
aoqi@0 655 assert(is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, lower, upper_instr, upper), "should have been tested before");
aoqi@0 656 bool upper_check = !(upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr);
aoqi@0 657
aoqi@0 658 int bci = NOT_PRODUCT(ai->printable_bci()) PRODUCT_ONLY(-1);
aoqi@0 659 if (lower_instr) {
aoqi@0 660 assert(!lower_instr->type()->as_ObjectType(), "Must not be object type");
aoqi@0 661 if (lower == 0) {
aoqi@0 662 // Compare for less than 0
aoqi@0 663 insert_position = predicate_cmp_with_const(lower_instr, Instruction::lss, 0, state, insert_position, bci);
aoqi@0 664 } else if (lower > 0) {
aoqi@0 665 // Compare for smaller 0
aoqi@0 666 insert_position = predicate_add_cmp_with_const(lower_instr, lower, Instruction::lss, 0, state, insert_position, bci);
aoqi@0 667 } else {
aoqi@0 668 assert(lower < 0, "");
aoqi@0 669 // Add 1
aoqi@0 670 lower++;
aoqi@0 671 lower = -lower;
aoqi@0 672 // Compare for smaller or equal 0
aoqi@0 673 insert_position = predicate_cmp_with_const(lower_instr, Instruction::leq, lower, state, insert_position, bci);
aoqi@0 674 }
aoqi@0 675 }
aoqi@0 676
aoqi@0 677 // No upper check required -> skip
aoqi@0 678 if (!upper_check) return;
aoqi@0 679
aoqi@0 680 // We need to know length of array
aoqi@0 681 if (!length_instr) {
aoqi@0 682 // Load length if necessary
aoqi@0 683 ArrayLength *length = new ArrayLength(array_instr, state->copy());
aoqi@0 684 NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));
aoqi@0 685 length->set_exception_state(length->state_before());
aoqi@0 686 length->set_flag(Instruction::DeoptimizeOnException, true);
aoqi@0 687 insert_position = insert_position->insert_after(length);
aoqi@0 688 length_instr = length;
aoqi@0 689 }
aoqi@0 690
aoqi@0 691 if (!upper_instr) {
aoqi@0 692 // Compare for geq array.length
aoqi@0 693 insert_position = predicate_cmp_with_const(length_instr, Instruction::leq, upper, state, insert_position, bci);
aoqi@0 694 } else {
aoqi@0 695 if (upper_instr->type()->as_ObjectType()) {
aoqi@0 696 assert(state, "must not be null");
aoqi@0 697 assert(upper_instr != array_instr, "should be");
aoqi@0 698 ArrayLength *length = new ArrayLength(upper_instr, state->copy());
aoqi@0 699 NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));
aoqi@0 700 length->set_flag(Instruction::DeoptimizeOnException, true);
aoqi@0 701 length->set_exception_state(length->state_before());
aoqi@0 702 insert_position = insert_position->insert_after(length);
aoqi@0 703 upper_instr = length;
aoqi@0 704 }
aoqi@0 705 assert(upper_instr->type()->as_IntType(), "Must not be object type!");
aoqi@0 706
aoqi@0 707 if (upper == 0) {
aoqi@0 708 // Compare for geq array.length
aoqi@0 709 insert_position = predicate(upper_instr, Instruction::geq, length_instr, state, insert_position, bci);
aoqi@0 710 } else if (upper < 0) {
aoqi@0 711 // Compare for geq array.length
aoqi@0 712 insert_position = predicate_add(upper_instr, upper, Instruction::geq, length_instr, state, insert_position, bci);
aoqi@0 713 } else {
aoqi@0 714 assert(upper > 0, "");
aoqi@0 715 upper = -upper;
aoqi@0 716 // Compare for geq array.length
aoqi@0 717 insert_position = predicate_add(length_instr, upper, Instruction::leq, upper_instr, state, insert_position, bci);
aoqi@0 718 }
aoqi@0 719 }
aoqi@0 720 }
aoqi@0 721
aoqi@0 722 // Add if condition
aoqi@0 723 void RangeCheckEliminator::add_if_condition(IntegerStack &pushed, Value x, Value y, Instruction::Condition condition) {
aoqi@0 724 if (y->as_Constant()) return;
aoqi@0 725
aoqi@0 726 int const_value = 0;
aoqi@0 727 Value instr_value = x;
aoqi@0 728 Constant *c = x->as_Constant();
aoqi@0 729 ArithmeticOp *ao = x->as_ArithmeticOp();
aoqi@0 730
aoqi@0 731 if (c != NULL) {
aoqi@0 732 const_value = c->type()->as_IntConstant()->value();
aoqi@0 733 instr_value = NULL;
aoqi@0 734 } else if (ao != NULL && (!ao->x()->as_Constant() || !ao->y()->as_Constant()) && ((ao->op() == Bytecodes::_isub && ao->y()->as_Constant()) || ao->op() == Bytecodes::_iadd)) {
aoqi@0 735 assert(!ao->x()->as_Constant() || !ao->y()->as_Constant(), "At least one operator must be non-constant!");
aoqi@0 736 assert(ao->op() == Bytecodes::_isub || ao->op() == Bytecodes::_iadd, "Operation has to be add or sub!");
aoqi@0 737 c = ao->x()->as_Constant();
aoqi@0 738 if (c != NULL) {
aoqi@0 739 const_value = c->type()->as_IntConstant()->value();
aoqi@0 740 instr_value = ao->y();
aoqi@0 741 } else {
aoqi@0 742 c = ao->y()->as_Constant();
aoqi@0 743 if (c != NULL) {
aoqi@0 744 const_value = c->type()->as_IntConstant()->value();
aoqi@0 745 instr_value = ao->x();
aoqi@0 746 }
aoqi@0 747 }
aoqi@0 748 if (ao->op() == Bytecodes::_isub) {
aoqi@0 749 assert(ao->y()->as_Constant(), "1 - x not supported, only x - 1 is valid!");
aoqi@0 750 if (const_value > min_jint) {
aoqi@0 751 const_value = -const_value;
aoqi@0 752 } else {
aoqi@0 753 const_value = 0;
aoqi@0 754 instr_value = x;
aoqi@0 755 }
aoqi@0 756 }
aoqi@0 757 }
aoqi@0 758
aoqi@0 759 update_bound(pushed, y, condition, instr_value, const_value);
aoqi@0 760 }
aoqi@0 761
aoqi@0 762 // Process If
aoqi@0 763 void RangeCheckEliminator::process_if(IntegerStack &pushed, BlockBegin *block, If *cond) {
aoqi@0 764 // Only if we are direct true / false successor and NOT both ! (even this may occur)
aoqi@0 765 if ((cond->tsux() == block || cond->fsux() == block) && cond->tsux() != cond->fsux()) {
aoqi@0 766 Instruction::Condition condition = cond->cond();
aoqi@0 767 if (cond->fsux() == block) {
aoqi@0 768 condition = Instruction::negate(condition);
aoqi@0 769 }
aoqi@0 770 Value x = cond->x();
aoqi@0 771 Value y = cond->y();
aoqi@0 772 if (x->type()->as_IntType() && y->type()->as_IntType()) {
aoqi@0 773 add_if_condition(pushed, y, x, condition);
aoqi@0 774 add_if_condition(pushed, x, y, Instruction::mirror(condition));
aoqi@0 775 }
aoqi@0 776 }
aoqi@0 777 }
aoqi@0 778
aoqi@0 779 // Process access indexed
aoqi@0 780 void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai) {
aoqi@0 781 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 782 tty->fill_to(block->dominator_depth()*2)
aoqi@0 783 );
aoqi@0 784 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 785 tty->print_cr("Access indexed: index=%d length=%d", ai->index()->id(), (ai->length() != NULL ? ai->length()->id() :-1 ))
aoqi@0 786 );
aoqi@0 787
aoqi@0 788 if (ai->check_flag(Instruction::NeedsRangeCheckFlag)) {
aoqi@0 789 Bound *index_bound = get_bound(ai->index());
aoqi@0 790 if (!index_bound->has_lower() || !index_bound->has_upper()) {
aoqi@0 791 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 792 tty->fill_to(block->dominator_depth()*2);
aoqi@0 793 tty->print_cr("Index instruction %d has no lower and/or no upper bound!", ai->index()->id())
aoqi@0 794 );
aoqi@0 795 return;
aoqi@0 796 }
aoqi@0 797
aoqi@0 798 Bound *array_bound;
aoqi@0 799 if (ai->length()) {
aoqi@0 800 array_bound = get_bound(ai->length());
aoqi@0 801 } else {
aoqi@0 802 array_bound = get_bound(ai->array());
aoqi@0 803 }
aoqi@0 804
aoqi@0 805 if (in_array_bound(index_bound, ai->array()) ||
aoqi@0 806 (index_bound && array_bound && index_bound->is_smaller(array_bound) && !index_bound->lower_instr() && index_bound->lower() >= 0)) {
aoqi@0 807 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 808 tty->fill_to(block->dominator_depth()*2);
aoqi@0 809 tty->print_cr("Bounds check for instruction %d in block B%d can be fully eliminated!", ai->id(), ai->block()->block_id())
aoqi@0 810 );
aoqi@0 811
aoqi@0 812 remove_range_check(ai);
aoqi@0 813 } else if (_optimistic && loop_header) {
aoqi@0 814 assert(ai->array(), "Array must not be null!");
aoqi@0 815 assert(ai->index(), "Index must not be null!");
aoqi@0 816
aoqi@0 817 // Array instruction
aoqi@0 818 Instruction *array_instr = ai->array();
aoqi@0 819 if (!loop_invariant(loop_header, array_instr)) {
aoqi@0 820 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 821 tty->fill_to(block->dominator_depth()*2);
aoqi@0 822 tty->print_cr("Array %d is not loop invariant to header B%d", ai->array()->id(), loop_header->block_id())
aoqi@0 823 );
aoqi@0 824 return;
aoqi@0 825 }
aoqi@0 826
aoqi@0 827 // Lower instruction
aoqi@0 828 Value index_instr = ai->index();
aoqi@0 829 Value lower_instr = index_bound->lower_instr();
aoqi@0 830 if (!loop_invariant(loop_header, lower_instr)) {
aoqi@0 831 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 832 tty->fill_to(block->dominator_depth()*2);
aoqi@0 833 tty->print_cr("Lower instruction %d not loop invariant!", lower_instr->id())
aoqi@0 834 );
aoqi@0 835 return;
aoqi@0 836 }
aoqi@0 837 if (!lower_instr && index_bound->lower() < 0) {
aoqi@0 838 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 839 tty->fill_to(block->dominator_depth()*2);
aoqi@0 840 tty->print_cr("Lower bound smaller than 0 (%d)!", index_bound->lower())
aoqi@0 841 );
aoqi@0 842 return;
aoqi@0 843 }
aoqi@0 844
aoqi@0 845 // Upper instruction
aoqi@0 846 Value upper_instr = index_bound->upper_instr();
aoqi@0 847 if (!loop_invariant(loop_header, upper_instr)) {
aoqi@0 848 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 849 tty->fill_to(block->dominator_depth()*2);
aoqi@0 850 tty->print_cr("Upper instruction %d not loop invariant!", upper_instr->id())
aoqi@0 851 );
aoqi@0 852 return;
aoqi@0 853 }
aoqi@0 854
aoqi@0 855 // Length instruction
aoqi@0 856 Value length_instr = ai->length();
aoqi@0 857 if (!loop_invariant(loop_header, length_instr)) {
aoqi@0 858 // Generate length instruction yourself!
aoqi@0 859 length_instr = NULL;
aoqi@0 860 }
aoqi@0 861
aoqi@0 862 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 863 tty->fill_to(block->dominator_depth()*2);
aoqi@0 864 tty->print_cr("LOOP INVARIANT access indexed %d found in block B%d!", ai->id(), ai->block()->block_id())
aoqi@0 865 );
aoqi@0 866
aoqi@0 867 BlockBegin *pred_block = loop_header->dominator();
aoqi@0 868 assert(pred_block != NULL, "Every loop header has a dominator!");
aoqi@0 869 BlockEnd *pred_block_end = pred_block->end();
aoqi@0 870 Instruction *insert_position = pred_block_end->prev();
aoqi@0 871 ValueStack *state = pred_block_end->state_before();
aoqi@0 872 if (pred_block_end->as_Goto() && state == NULL) state = pred_block_end->state();
aoqi@0 873 assert(state, "State must not be null");
aoqi@0 874
aoqi@0 875 // Add deoptimization to dominator of loop header
aoqi@0 876 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 877 tty->fill_to(block->dominator_depth()*2);
aoqi@0 878 tty->print_cr("Inserting deopt at bci %d in block B%d!", state->bci(), insert_position->block()->block_id())
aoqi@0 879 );
aoqi@0 880
aoqi@0 881 if (!is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper())) {
aoqi@0 882 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 883 tty->fill_to(block->dominator_depth()*2);
aoqi@0 884 tty->print_cr("Could not eliminate because of static analysis!")
aoqi@0 885 );
aoqi@0 886 return;
aoqi@0 887 }
aoqi@0 888
aoqi@0 889 insert_deoptimization(state, insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper(), ai);
aoqi@0 890
aoqi@0 891 // Finally remove the range check!
aoqi@0 892 remove_range_check(ai);
aoqi@0 893 }
aoqi@0 894 }
aoqi@0 895 }
aoqi@0 896
aoqi@0 897 void RangeCheckEliminator::remove_range_check(AccessIndexed *ai) {
aoqi@0 898 ai->set_flag(Instruction::NeedsRangeCheckFlag, false);
aoqi@0 899 // no range check, no need for the length instruction anymore
aoqi@0 900 ai->clear_length();
aoqi@0 901
aoqi@0 902 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 903 tty->fill_to(ai->dominator_depth()*2);
aoqi@0 904 tty->print_cr("Range check for instruction %d eliminated!", ai->id());
aoqi@0 905 );
aoqi@0 906
aoqi@0 907 ASSERT_RANGE_CHECK_ELIMINATION(
aoqi@0 908 Value array_length = ai->length();
aoqi@0 909 if (!array_length) {
aoqi@0 910 array_length = ai->array();
aoqi@0 911 assert(array_length->type()->as_ObjectType(), "Has to be object type!");
aoqi@0 912 }
aoqi@0 913 int cur_constant = -1;
aoqi@0 914 Value cur_value = array_length;
aoqi@0 915 if (cur_value->type()->as_IntConstant()) {
aoqi@0 916 cur_constant += cur_value->type()->as_IntConstant()->value();
aoqi@0 917 cur_value = NULL;
aoqi@0 918 }
aoqi@0 919 Bound *new_index_bound = new Bound(0, NULL, cur_constant, cur_value);
aoqi@0 920 add_assertions(new_index_bound, ai->index(), ai);
aoqi@0 921 );
aoqi@0 922 }
aoqi@0 923
aoqi@0 924 // Calculate bounds for instruction in this block and children blocks in the dominator tree
aoqi@0 925 void RangeCheckEliminator::calc_bounds(BlockBegin *block, BlockBegin *loop_header) {
aoqi@0 926 // Ensures a valid loop_header
aoqi@0 927 assert(!loop_header || loop_header->is_set(BlockBegin::linear_scan_loop_header_flag), "Loop header has to be real !");
aoqi@0 928
aoqi@0 929 // Tracing output
aoqi@0 930 TRACE_RANGE_CHECK_ELIMINATION(
aoqi@0 931 tty->fill_to(block->dominator_depth()*2);
aoqi@0 932 tty->print_cr("Block B%d", block->block_id());
aoqi@0 933 );
aoqi@0 934
aoqi@0 935 // Pushed stack for conditions
aoqi@0 936 IntegerStack pushed;
aoqi@0 937 // Process If
aoqi@0 938 BlockBegin *parent = block->dominator();
aoqi@0 939 if (parent != NULL) {
aoqi@0 940 If *cond = parent->end()->as_If();
aoqi@0 941 if (cond != NULL) {
aoqi@0 942 process_if(pushed, block, cond);
aoqi@0 943 }
aoqi@0 944 }
aoqi@0 945
aoqi@0 946 // Interate over current block
aoqi@0 947 InstructionList arrays;
aoqi@0 948 AccessIndexedList accessIndexed;
aoqi@0 949 Instruction *cur = block;
aoqi@0 950
aoqi@0 951 while (cur) {
aoqi@0 952 // Ensure cur wasn't inserted during the elimination
aoqi@0 953 if (cur->id() < this->_bounds.length()) {
aoqi@0 954 // Process only if it is an access indexed instruction
aoqi@0 955 AccessIndexed *ai = cur->as_AccessIndexed();
aoqi@0 956 if (ai != NULL) {
aoqi@0 957 process_access_indexed(loop_header, block, ai);
aoqi@0 958 accessIndexed.append(ai);
aoqi@0 959 if (!arrays.contains(ai->array())) {
aoqi@0 960 arrays.append(ai->array());
aoqi@0 961 }
aoqi@0 962 Bound *b = get_bound(ai->index());
aoqi@0 963 if (!b->lower_instr()) {
aoqi@0 964 // Lower bound is constant
aoqi@0 965 update_bound(pushed, ai->index(), Instruction::geq, NULL, 0);
aoqi@0 966 }
aoqi@0 967 if (!b->has_upper()) {
aoqi@0 968 if (ai->length() && ai->length()->type()->as_IntConstant()) {
aoqi@0 969 int value = ai->length()->type()->as_IntConstant()->value();
aoqi@0 970 update_bound(pushed, ai->index(), Instruction::lss, NULL, value);
aoqi@0 971 } else {
aoqi@0 972 // Has no upper bound
aoqi@0 973 Instruction *instr = ai->length();
aoqi@0 974 if (instr != NULL) instr = ai->array();
aoqi@0 975 update_bound(pushed, ai->index(), Instruction::lss, instr, 0);
aoqi@0 976 }
aoqi@0 977 }
aoqi@0 978 }
aoqi@0 979 }
aoqi@0 980 cur = cur->next();
aoqi@0 981 }
aoqi@0 982
aoqi@0 983 // Output current condition stack
aoqi@0 984 TRACE_RANGE_CHECK_ELIMINATION(dump_condition_stack(block));
aoqi@0 985
aoqi@0 986 // Do in block motion of range checks
aoqi@0 987 in_block_motion(block, accessIndexed, arrays);
aoqi@0 988
aoqi@0 989 // Call all dominated blocks
aoqi@0 990 for (int i=0; i<block->dominates()->length(); i++) {
aoqi@0 991 BlockBegin *next = block->dominates()->at(i);
aoqi@0 992 if (!next->is_set(BlockBegin::donot_eliminate_range_checks)) {
aoqi@0 993 // if current block is a loop header and:
aoqi@0 994 // - next block belongs to the same loop
aoqi@0 995 // or
aoqi@0 996 // - next block belongs to an inner loop
aoqi@0 997 // then current block is the loop header for next block
aoqi@0 998 if (block->is_set(BlockBegin::linear_scan_loop_header_flag) && (block->loop_index() == next->loop_index() || next->loop_depth() > block->loop_depth())) {
aoqi@0 999 calc_bounds(next, block);
aoqi@0 1000 } else {
aoqi@0 1001 calc_bounds(next, loop_header);
aoqi@0 1002 }
aoqi@0 1003 }
aoqi@0 1004 }
aoqi@0 1005
aoqi@0 1006 // Reset stack
aoqi@0 1007 for (int i=0; i<pushed.length(); i++) {
aoqi@0 1008 _bounds[pushed[i]]->pop();
aoqi@0 1009 }
aoqi@0 1010 }
aoqi@0 1011
aoqi@0 1012 #ifndef PRODUCT
aoqi@0 1013 // Dump condition stack
aoqi@0 1014 void RangeCheckEliminator::dump_condition_stack(BlockBegin *block) {
aoqi@0 1015 for (int i=0; i<_ir->linear_scan_order()->length(); i++) {
aoqi@0 1016 BlockBegin *cur_block = _ir->linear_scan_order()->at(i);
aoqi@0 1017 Instruction *instr = cur_block;
aoqi@0 1018 for_each_phi_fun(cur_block, phi,
aoqi@0 1019 BoundStack *bound_stack = _bounds.at(phi->id());
aoqi@0 1020 if (bound_stack && bound_stack->length() > 0) {
aoqi@0 1021 Bound *bound = bound_stack->top();
aoqi@0 1022 if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != phi || bound->upper_instr() != phi || bound->lower() != 0 || bound->upper() != 0)) {
aoqi@0 1023 TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());
aoqi@0 1024 tty->print("i%d", phi->id());
aoqi@0 1025 tty->print(": ");
aoqi@0 1026 bound->print();
aoqi@0 1027 tty->cr();
aoqi@0 1028 );
aoqi@0 1029 }
aoqi@0 1030 });
aoqi@0 1031
aoqi@0 1032 while (!instr->as_BlockEnd()) {
aoqi@0 1033 if (instr->id() < _bounds.length()) {
aoqi@0 1034 BoundStack *bound_stack = _bounds.at(instr->id());
aoqi@0 1035 if (bound_stack && bound_stack->length() > 0) {
aoqi@0 1036 Bound *bound = bound_stack->top();
aoqi@0 1037 if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != instr || bound->upper_instr() != instr || bound->lower() != 0 || bound->upper() != 0)) {
aoqi@0 1038 TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());
aoqi@0 1039 tty->print("i%d", instr->id());
aoqi@0 1040 tty->print(": ");
aoqi@0 1041 bound->print();
aoqi@0 1042 tty->cr();
aoqi@0 1043 );
aoqi@0 1044 }
aoqi@0 1045 }
aoqi@0 1046 }
aoqi@0 1047 instr = instr->next();
aoqi@0 1048 }
aoqi@0 1049 }
aoqi@0 1050 }
aoqi@0 1051 #endif
aoqi@0 1052
aoqi@0 1053 // Verification or the IR
aoqi@0 1054 RangeCheckEliminator::Verification::Verification(IR *ir) : _used(BlockBegin::number_of_blocks(), false) {
aoqi@0 1055 this->_ir = ir;
aoqi@0 1056 ir->iterate_linear_scan_order(this);
aoqi@0 1057 }
aoqi@0 1058
aoqi@0 1059 // Verify this block
aoqi@0 1060 void RangeCheckEliminator::Verification::block_do(BlockBegin *block) {
aoqi@0 1061 If *cond = block->end()->as_If();
aoqi@0 1062 // Watch out: tsux and fsux can be the same!
aoqi@0 1063 if (block->number_of_sux() > 1) {
aoqi@0 1064 for (int i=0; i<block->number_of_sux(); i++) {
aoqi@0 1065 BlockBegin *sux = block->sux_at(i);
aoqi@0 1066 BlockBegin *pred = NULL;
aoqi@0 1067 for (int j=0; j<sux->number_of_preds(); j++) {
aoqi@0 1068 BlockBegin *cur = sux->pred_at(j);
aoqi@0 1069 assert(cur != NULL, "Predecessor must not be null");
aoqi@0 1070 if (!pred) {
aoqi@0 1071 pred = cur;
aoqi@0 1072 }
aoqi@0 1073 assert(cur == pred, "Block must not have more than one predecessor if its predecessor has more than one successor");
aoqi@0 1074 }
aoqi@0 1075 assert(sux->number_of_preds() >= 1, "Block must have at least one predecessor");
aoqi@0 1076 assert(sux->pred_at(0) == block, "Wrong successor");
aoqi@0 1077 }
aoqi@0 1078 }
aoqi@0 1079
aoqi@0 1080 BlockBegin *dominator = block->dominator();
aoqi@0 1081 if (dominator) {
aoqi@0 1082 assert(block != _ir->start(), "Start block must not have a dominator!");
aoqi@0 1083 assert(can_reach(dominator, block), "Dominator can't reach his block !");
aoqi@0 1084 assert(can_reach(_ir->start(), dominator), "Dominator is unreachable !");
aoqi@0 1085 assert(!can_reach(_ir->start(), block, dominator), "Wrong dominator ! Block can be reached anyway !");
aoqi@0 1086 BlockList *all_blocks = _ir->linear_scan_order();
aoqi@0 1087 for (int i=0; i<all_blocks->length(); i++) {
aoqi@0 1088 BlockBegin *cur = all_blocks->at(i);
aoqi@0 1089 if (cur != dominator && cur != block) {
aoqi@0 1090 assert(can_reach(dominator, block, cur), "There has to be another dominator!");
aoqi@0 1091 }
aoqi@0 1092 }
aoqi@0 1093 } else {
aoqi@0 1094 assert(block == _ir->start(), "Only start block must not have a dominator");
aoqi@0 1095 }
aoqi@0 1096
aoqi@0 1097 if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) {
aoqi@0 1098 int loop_index = block->loop_index();
aoqi@0 1099 BlockList *all_blocks = _ir->linear_scan_order();
aoqi@0 1100 assert(block->number_of_preds() >= 1, "Block must have at least one predecessor");
aoqi@0 1101 assert(!block->is_set(BlockBegin::exception_entry_flag), "Loop header must not be exception handler!");
aoqi@0 1102 // Sometimes, the backbranch comes from an exception handler. In
aoqi@0 1103 // this case, loop indexes/loop depths may not appear correct.
aoqi@0 1104 bool loop_through_xhandler = false;
aoqi@0 1105 for (int i = 0; i < block->number_of_exception_handlers(); i++) {
aoqi@0 1106 BlockBegin *xhandler = block->exception_handler_at(i);
aoqi@0 1107 for (int j = 0; j < block->number_of_preds(); j++) {
aoqi@0 1108 if (dominates(xhandler, block->pred_at(j)) || xhandler == block->pred_at(j)) {
aoqi@0 1109 loop_through_xhandler = true;
aoqi@0 1110 }
aoqi@0 1111 }
aoqi@0 1112 }
aoqi@0 1113
aoqi@0 1114 for (int i=0; i<block->number_of_sux(); i++) {
aoqi@0 1115 BlockBegin *sux = block->sux_at(i);
aoqi@0 1116 assert(sux->loop_depth() != block->loop_depth() || sux->loop_index() == block->loop_index() || loop_through_xhandler, "Loop index has to be same");
aoqi@0 1117 assert(sux->loop_depth() == block->loop_depth() || sux->loop_index() != block->loop_index(), "Loop index has to be different");
aoqi@0 1118 }
aoqi@0 1119
aoqi@0 1120 for (int i=0; i<all_blocks->length(); i++) {
aoqi@0 1121 BlockBegin *cur = all_blocks->at(i);
aoqi@0 1122 if (cur->loop_index() == loop_index && cur != block) {
aoqi@0 1123 assert(dominates(block->dominator(), cur), "Dominator of loop header must dominate all loop blocks");
aoqi@0 1124 }
aoqi@0 1125 }
aoqi@0 1126 }
aoqi@0 1127
aoqi@0 1128 Instruction *cur = block;
aoqi@0 1129 while (cur) {
aoqi@0 1130 assert(cur->block() == block, "Block begin has to be set correctly!");
aoqi@0 1131 cur = cur->next();
aoqi@0 1132 }
aoqi@0 1133 }
aoqi@0 1134
aoqi@0 1135 // Loop header must dominate all loop blocks
aoqi@0 1136 bool RangeCheckEliminator::Verification::dominates(BlockBegin *dominator, BlockBegin *block) {
aoqi@0 1137 BlockBegin *cur = block->dominator();
aoqi@0 1138 while (cur && cur != dominator) {
aoqi@0 1139 cur = cur->dominator();
aoqi@0 1140 }
aoqi@0 1141 return cur == dominator;
aoqi@0 1142 }
aoqi@0 1143
aoqi@0 1144 // Try to reach Block end beginning in Block start and not using Block dont_use
aoqi@0 1145 bool RangeCheckEliminator::Verification::can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use /* = NULL */) {
aoqi@0 1146 if (start == end) return start != dont_use;
aoqi@0 1147 // Simple BSF from start to end
aoqi@0 1148 // BlockBeginList _current;
aoqi@0 1149 for (int i=0; i<_used.length(); i++) {
aoqi@0 1150 _used[i] = false;
aoqi@0 1151 }
aoqi@0 1152 _current.truncate(0);
aoqi@0 1153 _successors.truncate(0);
aoqi@0 1154 if (start != dont_use) {
aoqi@0 1155 _current.push(start);
aoqi@0 1156 _used[start->block_id()] = true;
aoqi@0 1157 }
aoqi@0 1158
aoqi@0 1159 // BlockBeginList _successors;
aoqi@0 1160 while (_current.length() > 0) {
aoqi@0 1161 BlockBegin *cur = _current.pop();
aoqi@0 1162 // Add exception handlers to list
aoqi@0 1163 for (int i=0; i<cur->number_of_exception_handlers(); i++) {
aoqi@0 1164 BlockBegin *xhandler = cur->exception_handler_at(i);
aoqi@0 1165 _successors.push(xhandler);
aoqi@0 1166 // Add exception handlers of _successors to list
aoqi@0 1167 for (int j=0; j<xhandler->number_of_exception_handlers(); j++) {
aoqi@0 1168 BlockBegin *sux_xhandler = xhandler->exception_handler_at(j);
aoqi@0 1169 _successors.push(sux_xhandler);
aoqi@0 1170 }
aoqi@0 1171 }
aoqi@0 1172 // Add normal _successors to list
aoqi@0 1173 for (int i=0; i<cur->number_of_sux(); i++) {
aoqi@0 1174 BlockBegin *sux = cur->sux_at(i);
aoqi@0 1175 _successors.push(sux);
aoqi@0 1176 // Add exception handlers of _successors to list
aoqi@0 1177 for (int j=0; j<sux->number_of_exception_handlers(); j++) {
aoqi@0 1178 BlockBegin *xhandler = sux->exception_handler_at(j);
aoqi@0 1179 _successors.push(xhandler);
aoqi@0 1180 }
aoqi@0 1181 }
aoqi@0 1182 for (int i=0; i<_successors.length(); i++) {
aoqi@0 1183 BlockBegin *sux = _successors[i];
aoqi@0 1184 assert(sux != NULL, "Successor must not be NULL!");
aoqi@0 1185 if (sux == end) {
aoqi@0 1186 return true;
aoqi@0 1187 }
aoqi@0 1188 if (sux != dont_use && !_used[sux->block_id()]) {
aoqi@0 1189 _used[sux->block_id()] = true;
aoqi@0 1190 _current.push(sux);
aoqi@0 1191 }
aoqi@0 1192 }
aoqi@0 1193 _successors.truncate(0);
aoqi@0 1194 }
aoqi@0 1195
aoqi@0 1196 return false;
aoqi@0 1197 }
aoqi@0 1198
aoqi@0 1199 // Bound
aoqi@0 1200 RangeCheckEliminator::Bound::~Bound() {
aoqi@0 1201 }
aoqi@0 1202
aoqi@0 1203 // Bound constructor
aoqi@0 1204 RangeCheckEliminator::Bound::Bound() {
aoqi@0 1205 init();
aoqi@0 1206 this->_lower = min_jint;
aoqi@0 1207 this->_upper = max_jint;
aoqi@0 1208 this->_lower_instr = NULL;
aoqi@0 1209 this->_upper_instr = NULL;
aoqi@0 1210 }
aoqi@0 1211
aoqi@0 1212 // Bound constructor
aoqi@0 1213 RangeCheckEliminator::Bound::Bound(int lower, Value lower_instr, int upper, Value upper_instr) {
aoqi@0 1214 init();
aoqi@0 1215 assert(!lower_instr || !lower_instr->as_Constant() || !lower_instr->type()->as_IntConstant(), "Must not be constant!");
aoqi@0 1216 assert(!upper_instr || !upper_instr->as_Constant() || !upper_instr->type()->as_IntConstant(), "Must not be constant!");
aoqi@0 1217 this->_lower = lower;
aoqi@0 1218 this->_upper = upper;
aoqi@0 1219 this->_lower_instr = lower_instr;
aoqi@0 1220 this->_upper_instr = upper_instr;
aoqi@0 1221 }
aoqi@0 1222
aoqi@0 1223 // Bound constructor
aoqi@0 1224 RangeCheckEliminator::Bound::Bound(Instruction::Condition cond, Value v, int constant) {
aoqi@0 1225 assert(!v || (v->type() && (v->type()->as_IntType() || v->type()->as_ObjectType())), "Type must be array or integer!");
aoqi@0 1226 assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");
aoqi@0 1227
aoqi@0 1228 init();
aoqi@0 1229 if (cond == Instruction::eql) {
aoqi@0 1230 _lower = constant;
aoqi@0 1231 _lower_instr = v;
aoqi@0 1232 _upper = constant;
aoqi@0 1233 _upper_instr = v;
aoqi@0 1234 } else if (cond == Instruction::neq) {
aoqi@0 1235 _lower = min_jint;
aoqi@0 1236 _upper = max_jint;
aoqi@0 1237 _lower_instr = NULL;
aoqi@0 1238 _upper_instr = NULL;
aoqi@0 1239 if (v == NULL) {
aoqi@0 1240 if (constant == min_jint) {
aoqi@0 1241 _lower++;
aoqi@0 1242 }
aoqi@0 1243 if (constant == max_jint) {
aoqi@0 1244 _upper--;
aoqi@0 1245 }
aoqi@0 1246 }
aoqi@0 1247 } else if (cond == Instruction::geq) {
aoqi@0 1248 _lower = constant;
aoqi@0 1249 _lower_instr = v;
aoqi@0 1250 _upper = max_jint;
aoqi@0 1251 _upper_instr = NULL;
aoqi@0 1252 } else if (cond == Instruction::leq) {
aoqi@0 1253 _lower = min_jint;
aoqi@0 1254 _lower_instr = NULL;
aoqi@0 1255 _upper = constant;
aoqi@0 1256 _upper_instr = v;
aoqi@0 1257 } else {
aoqi@0 1258 ShouldNotReachHere();
aoqi@0 1259 }
aoqi@0 1260 }
aoqi@0 1261
aoqi@0 1262 // Set lower
aoqi@0 1263 void RangeCheckEliminator::Bound::set_lower(int value, Value v) {
aoqi@0 1264 assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");
aoqi@0 1265 this->_lower = value;
aoqi@0 1266 this->_lower_instr = v;
aoqi@0 1267 }
aoqi@0 1268
aoqi@0 1269 // Set upper
aoqi@0 1270 void RangeCheckEliminator::Bound::set_upper(int value, Value v) {
aoqi@0 1271 assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");
aoqi@0 1272 this->_upper = value;
aoqi@0 1273 this->_upper_instr = v;
aoqi@0 1274 }
aoqi@0 1275
aoqi@0 1276 // Add constant -> no overflow may occur
aoqi@0 1277 void RangeCheckEliminator::Bound::add_constant(int value) {
aoqi@0 1278 this->_lower += value;
aoqi@0 1279 this->_upper += value;
aoqi@0 1280 }
aoqi@0 1281
aoqi@0 1282 // Init
aoqi@0 1283 void RangeCheckEliminator::Bound::init() {
aoqi@0 1284 }
aoqi@0 1285
aoqi@0 1286 // or
aoqi@0 1287 void RangeCheckEliminator::Bound::or_op(Bound *b) {
aoqi@0 1288 // Watch out, bound is not guaranteed not to overflow!
aoqi@0 1289 // Update lower bound
aoqi@0 1290 if (_lower_instr != b->_lower_instr || (_lower_instr && _lower != b->_lower)) {
aoqi@0 1291 _lower_instr = NULL;
aoqi@0 1292 _lower = min_jint;
aoqi@0 1293 } else {
aoqi@0 1294 _lower = MIN2(_lower, b->_lower);
aoqi@0 1295 }
aoqi@0 1296 // Update upper bound
aoqi@0 1297 if (_upper_instr != b->_upper_instr || (_upper_instr && _upper != b->_upper)) {
aoqi@0 1298 _upper_instr = NULL;
aoqi@0 1299 _upper = max_jint;
aoqi@0 1300 } else {
aoqi@0 1301 _upper = MAX2(_upper, b->_upper);
aoqi@0 1302 }
aoqi@0 1303 }
aoqi@0 1304
aoqi@0 1305 // and
aoqi@0 1306 void RangeCheckEliminator::Bound::and_op(Bound *b) {
aoqi@0 1307 // Update lower bound
aoqi@0 1308 if (_lower_instr == b->_lower_instr) {
aoqi@0 1309 _lower = MAX2(_lower, b->_lower);
aoqi@0 1310 }
aoqi@0 1311 if (b->has_lower()) {
aoqi@0 1312 bool set = true;
aoqi@0 1313 if (_lower_instr != NULL && b->_lower_instr != NULL) {
aoqi@0 1314 set = (_lower_instr->dominator_depth() > b->_lower_instr->dominator_depth());
aoqi@0 1315 }
aoqi@0 1316 if (set) {
aoqi@0 1317 _lower = b->_lower;
aoqi@0 1318 _lower_instr = b->_lower_instr;
aoqi@0 1319 }
aoqi@0 1320 }
aoqi@0 1321 // Update upper bound
aoqi@0 1322 if (_upper_instr == b->_upper_instr) {
aoqi@0 1323 _upper = MIN2(_upper, b->_upper);
aoqi@0 1324 }
aoqi@0 1325 if (b->has_upper()) {
aoqi@0 1326 bool set = true;
aoqi@0 1327 if (_upper_instr != NULL && b->_upper_instr != NULL) {
aoqi@0 1328 set = (_upper_instr->dominator_depth() > b->_upper_instr->dominator_depth());
aoqi@0 1329 }
aoqi@0 1330 if (set) {
aoqi@0 1331 _upper = b->_upper;
aoqi@0 1332 _upper_instr = b->_upper_instr;
aoqi@0 1333 }
aoqi@0 1334 }
aoqi@0 1335 }
aoqi@0 1336
aoqi@0 1337 // has_upper
aoqi@0 1338 bool RangeCheckEliminator::Bound::has_upper() {
aoqi@0 1339 return _upper_instr != NULL || _upper < max_jint;
aoqi@0 1340 }
aoqi@0 1341
aoqi@0 1342 // is_smaller
aoqi@0 1343 bool RangeCheckEliminator::Bound::is_smaller(Bound *b) {
aoqi@0 1344 if (b->_lower_instr != _upper_instr) {
aoqi@0 1345 return false;
aoqi@0 1346 }
aoqi@0 1347 return _upper < b->_lower;
aoqi@0 1348 }
aoqi@0 1349
aoqi@0 1350 // has_lower
aoqi@0 1351 bool RangeCheckEliminator::Bound::has_lower() {
aoqi@0 1352 return _lower_instr != NULL || _lower > min_jint;
aoqi@0 1353 }
aoqi@0 1354
aoqi@0 1355 // in_array_bound
aoqi@0 1356 bool RangeCheckEliminator::in_array_bound(Bound *bound, Value array){
aoqi@0 1357 if (!bound) return false;
aoqi@0 1358 assert(array != NULL, "Must not be null!");
aoqi@0 1359 assert(bound != NULL, "Must not be null!");
aoqi@0 1360 if (bound->lower() >=0 && bound->lower_instr() == NULL && bound->upper() < 0 && bound->upper_instr() != NULL) {
aoqi@0 1361 ArrayLength *len = bound->upper_instr()->as_ArrayLength();
aoqi@0 1362 if (bound->upper_instr() == array || (len != NULL && len->array() == array)) {
aoqi@0 1363 return true;
aoqi@0 1364 }
aoqi@0 1365 }
aoqi@0 1366 return false;
aoqi@0 1367 }
aoqi@0 1368
aoqi@0 1369 // remove_lower
aoqi@0 1370 void RangeCheckEliminator::Bound::remove_lower() {
aoqi@0 1371 _lower = min_jint;
aoqi@0 1372 _lower_instr = NULL;
aoqi@0 1373 }
aoqi@0 1374
aoqi@0 1375 // remove_upper
aoqi@0 1376 void RangeCheckEliminator::Bound::remove_upper() {
aoqi@0 1377 _upper = max_jint;
aoqi@0 1378 _upper_instr = NULL;
aoqi@0 1379 }
aoqi@0 1380
aoqi@0 1381 // upper
aoqi@0 1382 int RangeCheckEliminator::Bound::upper() {
aoqi@0 1383 return _upper;
aoqi@0 1384 }
aoqi@0 1385
aoqi@0 1386 // lower
aoqi@0 1387 int RangeCheckEliminator::Bound::lower() {
aoqi@0 1388 return _lower;
aoqi@0 1389 }
aoqi@0 1390
aoqi@0 1391 // upper_instr
aoqi@0 1392 Value RangeCheckEliminator::Bound::upper_instr() {
aoqi@0 1393 return _upper_instr;
aoqi@0 1394 }
aoqi@0 1395
aoqi@0 1396 // lower_instr
aoqi@0 1397 Value RangeCheckEliminator::Bound::lower_instr() {
aoqi@0 1398 return _lower_instr;
aoqi@0 1399 }
aoqi@0 1400
aoqi@0 1401 // print
aoqi@0 1402 void RangeCheckEliminator::Bound::print() {
aoqi@0 1403 tty->print("%s", "");
aoqi@0 1404 if (this->_lower_instr || this->_lower != min_jint) {
aoqi@0 1405 if (this->_lower_instr) {
aoqi@0 1406 tty->print("i%d", this->_lower_instr->id());
aoqi@0 1407 if (this->_lower > 0) {
aoqi@0 1408 tty->print("+%d", _lower);
aoqi@0 1409 }
aoqi@0 1410 if (this->_lower < 0) {
aoqi@0 1411 tty->print("%d", _lower);
aoqi@0 1412 }
aoqi@0 1413 } else {
aoqi@0 1414 tty->print("%d", _lower);
aoqi@0 1415 }
aoqi@0 1416 tty->print(" <= ");
aoqi@0 1417 }
aoqi@0 1418 tty->print("x");
aoqi@0 1419 if (this->_upper_instr || this->_upper != max_jint) {
aoqi@0 1420 tty->print(" <= ");
aoqi@0 1421 if (this->_upper_instr) {
aoqi@0 1422 tty->print("i%d", this->_upper_instr->id());
aoqi@0 1423 if (this->_upper > 0) {
aoqi@0 1424 tty->print("+%d", _upper);
aoqi@0 1425 }
aoqi@0 1426 if (this->_upper < 0) {
aoqi@0 1427 tty->print("%d", _upper);
aoqi@0 1428 }
aoqi@0 1429 } else {
aoqi@0 1430 tty->print("%d", _upper);
aoqi@0 1431 }
aoqi@0 1432 }
aoqi@0 1433 }
aoqi@0 1434
aoqi@0 1435 // Copy
aoqi@0 1436 RangeCheckEliminator::Bound *RangeCheckEliminator::Bound::copy() {
aoqi@0 1437 Bound *b = new Bound();
aoqi@0 1438 b->_lower = _lower;
aoqi@0 1439 b->_lower_instr = _lower_instr;
aoqi@0 1440 b->_upper = _upper;
aoqi@0 1441 b->_upper_instr = _upper_instr;
aoqi@0 1442 return b;
aoqi@0 1443 }
aoqi@0 1444
aoqi@0 1445 #ifdef ASSERT
aoqi@0 1446 // Add assertion
aoqi@0 1447 void RangeCheckEliminator::Bound::add_assertion(Instruction *instruction, Instruction *position, int i, Value instr, Instruction::Condition cond) {
aoqi@0 1448 Instruction *result = position;
aoqi@0 1449 Instruction *compare_with = NULL;
aoqi@0 1450 ValueStack *state = position->state_before();
aoqi@0 1451 if (position->as_BlockEnd() && !position->as_Goto()) {
aoqi@0 1452 state = position->as_BlockEnd()->state_before();
aoqi@0 1453 }
aoqi@0 1454 Instruction *instruction_before = position->prev();
aoqi@0 1455 if (position->as_Return() && Compilation::current()->method()->is_synchronized() && instruction_before->as_MonitorExit()) {
aoqi@0 1456 instruction_before = instruction_before->prev();
aoqi@0 1457 }
aoqi@0 1458 result = instruction_before;
aoqi@0 1459 // Load constant only if needed
aoqi@0 1460 Constant *constant = NULL;
aoqi@0 1461 if (i != 0 || !instr) {
aoqi@0 1462 constant = new Constant(new IntConstant(i));
aoqi@0 1463 NOT_PRODUCT(constant->set_printable_bci(position->printable_bci()));
aoqi@0 1464 result = result->insert_after(constant);
aoqi@0 1465 compare_with = constant;
aoqi@0 1466 }
aoqi@0 1467
aoqi@0 1468 if (instr) {
aoqi@0 1469 assert(instr->type()->as_ObjectType() || instr->type()->as_IntType(), "Type must be array or integer!");
aoqi@0 1470 compare_with = instr;
aoqi@0 1471 // Load array length if necessary
aoqi@0 1472 Instruction *op = instr;
aoqi@0 1473 if (instr->type()->as_ObjectType()) {
aoqi@0 1474 assert(state, "must not be null");
aoqi@0 1475 ArrayLength *length = new ArrayLength(instr, state->copy());
aoqi@0 1476 NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));
aoqi@0 1477 length->set_exception_state(length->state_before());
aoqi@0 1478 result = result->insert_after(length);
aoqi@0 1479 op = length;
aoqi@0 1480 compare_with = length;
aoqi@0 1481 }
aoqi@0 1482 // Add operation only if necessary
aoqi@0 1483 if (constant) {
aoqi@0 1484 ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, op, false, NULL);
aoqi@0 1485 NOT_PRODUCT(ao->set_printable_bci(position->printable_bci()));
aoqi@0 1486 result = result->insert_after(ao);
aoqi@0 1487 compare_with = ao;
aoqi@0 1488 // TODO: Check that add operation does not overflow!
aoqi@0 1489 }
aoqi@0 1490 }
aoqi@0 1491 assert(compare_with != NULL, "You have to compare with something!");
aoqi@0 1492 assert(instruction != NULL, "Instruction must not be null!");
aoqi@0 1493
aoqi@0 1494 if (instruction->type()->as_ObjectType()) {
aoqi@0 1495 // Load array length if necessary
aoqi@0 1496 Instruction *op = instruction;
aoqi@0 1497 assert(state, "must not be null");
aoqi@0 1498 ArrayLength *length = new ArrayLength(instruction, state->copy());
aoqi@0 1499 length->set_exception_state(length->state_before());
aoqi@0 1500 NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));
aoqi@0 1501 result = result->insert_after(length);
aoqi@0 1502 instruction = length;
aoqi@0 1503 }
aoqi@0 1504
aoqi@0 1505 Assert *assert = new Assert(instruction, cond, false, compare_with);
aoqi@0 1506 NOT_PRODUCT(assert->set_printable_bci(position->printable_bci()));
aoqi@0 1507 result->insert_after(assert);
aoqi@0 1508 }
aoqi@0 1509
aoqi@0 1510 // Add assertions
aoqi@0 1511 void RangeCheckEliminator::add_assertions(Bound *bound, Instruction *instruction, Instruction *position) {
aoqi@0 1512 // Add lower bound assertion
aoqi@0 1513 if (bound->has_lower()) {
aoqi@0 1514 bound->add_assertion(instruction, position, bound->lower(), bound->lower_instr(), Instruction::geq);
aoqi@0 1515 }
aoqi@0 1516 // Add upper bound assertion
aoqi@0 1517 if (bound->has_upper()) {
aoqi@0 1518 bound->add_assertion(instruction, position, bound->upper(), bound->upper_instr(), Instruction::leq);
aoqi@0 1519 }
aoqi@0 1520 }
aoqi@0 1521 #endif
aoqi@0 1522

mercurial