src/share/vm/c1/c1_RangeCheckElimination.cpp

Fri, 19 Apr 2013 03:13:04 -0400

author
bharadwaj
date
Fri, 19 Apr 2013 03:13:04 -0400
changeset 4954
2a9d97b57920
parent 4869
d595e8ddadd9
child 4972
6a3629cf7075
permissions
-rw-r--r--

Merge

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

mercurial