src/share/vm/c1/c1_RangeCheckElimination.cpp

Tue, 24 Feb 2015 15:04:52 -0500

author
dlong
date
Tue, 24 Feb 2015 15:04:52 -0500
changeset 7598
ddce0b7cee93
parent 6680
78bbf4d43a14
child 6876
710a3c8b516e
permissions
-rw-r--r--

8072383: resolve conflicts between open and closed ports
Summary: refactor close to remove references to closed ports
Reviewed-by: kvn, simonis, sgehwolf, dholmes

roland@4860 1 /*
drchase@6680 2 * Copyright (c) 2012, 2014, 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(
drchase@6680 65 tty->cr();
roland@4860 66 tty->print_cr("Range check elimination");
roland@4860 67 ir->method()->print_name(tty);
drchase@6680 68 tty->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@4972 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 }
roland@4860 535
roland@4860 536 if (list_constant.length() > 1) {
roland@4860 537 AccessIndexed *first = list_constant.at(0);
roland@4860 538 Instruction *insert_position = first->prev();
roland@4860 539 ValueStack *state = first->state_before();
roland@4860 540 // Load max Constant
roland@4860 541 Constant *constant = new Constant(new IntConstant(max_constant));
roland@4860 542 NOT_PRODUCT(constant->set_printable_bci(first->printable_bci()));
roland@4860 543 insert_position = insert_position->insert_after(constant);
roland@4860 544 Instruction *compare_instr = constant;
roland@4860 545 Value length_instr = first->length();
roland@4860 546 if (!length_instr) {
roland@4860 547 ArrayLength *length = new ArrayLength(array, state->copy());
roland@4860 548 length->set_exception_state(length->state_before());
roland@4860 549 length->set_flag(Instruction::DeoptimizeOnException, true);
roland@4860 550 insert_position = insert_position->insert_after_same_bci(length);
roland@4860 551 length_instr = length;
roland@4860 552 }
roland@4860 553 // Compare for greater or equal to array length
roland@4860 554 insert_position = predicate(compare_instr, Instruction::geq, length_instr, state, insert_position);
roland@4860 555 for (int j = 0; j<list_constant.length(); j++) {
roland@4860 556 AccessIndexed *ai = list_constant.at(j);
roland@4860 557 remove_range_check(ai);
roland@4860 558 }
roland@4860 559 }
roland@4860 560 }
roland@4972 561
roland@4972 562 // Clear data structures for next array
roland@4972 563 for (int i = 0; i < indices.length(); i++) {
roland@4972 564 Instruction *index_instruction = indices.at(i);
roland@4972 565 _access_indexed_info[index_instruction->id()] = NULL;
roland@4972 566 }
roland@4972 567 indices.clear();
roland@4860 568 }
roland@4860 569 }
roland@4860 570
roland@4860 571 bool RangeCheckEliminator::set_process_block_flags(BlockBegin *block) {
roland@4860 572 Instruction *cur = block;
roland@4860 573 bool process = false;
roland@4860 574
roland@4860 575 while (cur) {
roland@4860 576 process |= (cur->as_AccessIndexed() != NULL);
roland@4860 577 cur = cur->next();
roland@4860 578 }
roland@4860 579
roland@4860 580 BlockList *dominates = block->dominates();
roland@4860 581 for (int i=0; i<dominates->length(); i++) {
roland@4860 582 BlockBegin *next = dominates->at(i);
roland@4860 583 process |= set_process_block_flags(next);
roland@4860 584 }
roland@4860 585
roland@4860 586 if (!process) {
roland@4860 587 block->set(BlockBegin::donot_eliminate_range_checks);
roland@4860 588 }
roland@4860 589 return process;
roland@4860 590 }
roland@4860 591
roland@4860 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) {
roland@4860 593 bool upper_check = true;
roland@4860 594 assert(lower_instr || lower >= 0, "If no lower_instr present, lower must be greater 0");
roland@4860 595 assert(!lower_instr || lower_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
roland@4860 596 assert(!upper_instr || upper_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
roland@4860 597 assert(array_instr, "Array instruction must exist");
roland@4860 598 assert(array_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
roland@4860 599 assert(!length_instr || length_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
roland@4860 600
roland@4860 601 if (upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr) {
roland@4860 602 // static check
roland@4860 603 if (upper >= 0) return false; // would always trigger a deopt:
roland@4860 604 // array_length + x >= array_length, x >= 0 is always true
roland@4860 605 upper_check = false;
roland@4860 606 }
roland@4860 607 if (lower_instr && lower_instr->as_ArrayLength() && lower_instr->as_ArrayLength()->array() == array_instr) {
roland@4860 608 if (lower > 0) return false;
roland@4860 609 }
roland@4860 610 // No upper check required -> skip
roland@4860 611 if (upper_check && upper_instr && upper_instr->type()->as_ObjectType() && upper_instr == array_instr) {
roland@4860 612 // upper_instr is object means that the upper bound is the length
roland@4860 613 // of the upper_instr.
roland@4860 614 return false;
roland@4860 615 }
roland@4860 616 return true;
roland@4860 617 }
roland@4860 618
roland@4860 619 Instruction* RangeCheckEliminator::insert_after(Instruction* insert_position, Instruction* instr, int bci) {
roland@4860 620 if (bci != -1) {
roland@4860 621 NOT_PRODUCT(instr->set_printable_bci(bci));
roland@4860 622 return insert_position->insert_after(instr);
roland@4860 623 } else {
roland@4860 624 return insert_position->insert_after_same_bci(instr);
roland@4860 625 }
roland@4860 626 }
roland@4860 627
roland@4860 628 Instruction* RangeCheckEliminator::predicate(Instruction* left, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {
roland@4860 629 RangeCheckPredicate *deoptimize = new RangeCheckPredicate(left, cond, true, right, state->copy());
roland@4860 630 return insert_after(insert_position, deoptimize, bci);
roland@4860 631 }
roland@4860 632
roland@4860 633 Instruction* RangeCheckEliminator::predicate_cmp_with_const(Instruction* instr, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) {
roland@4860 634 Constant *const_instr = new Constant(new IntConstant(constant));
roland@4860 635 insert_position = insert_after(insert_position, const_instr, bci);
roland@4860 636 return predicate(instr, cond, const_instr, state, insert_position);
roland@4860 637 }
roland@4860 638
roland@4860 639 Instruction* RangeCheckEliminator::predicate_add(Instruction* left, int left_const, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {
roland@4860 640 Constant *constant = new Constant(new IntConstant(left_const));
roland@4860 641 insert_position = insert_after(insert_position, constant, bci);
roland@4860 642 ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, left, false, NULL);
roland@4860 643 insert_position = insert_position->insert_after_same_bci(ao);
roland@4860 644 return predicate(ao, cond, right, state, insert_position);
roland@4860 645 }
roland@4860 646
roland@4860 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) {
roland@4860 648 Constant *const_instr = new Constant(new IntConstant(constant));
roland@4860 649 insert_position = insert_after(insert_position, const_instr, bci);
roland@4860 650 return predicate_add(left, left_const, cond, const_instr, state, insert_position);
roland@4860 651 }
roland@4860 652
roland@4869 653 // Insert deoptimization
roland@4860 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) {
roland@4860 655 assert(is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, lower, upper_instr, upper), "should have been tested before");
roland@4860 656 bool upper_check = !(upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr);
roland@4860 657
roland@4860 658 int bci = NOT_PRODUCT(ai->printable_bci()) PRODUCT_ONLY(-1);
roland@4860 659 if (lower_instr) {
roland@4860 660 assert(!lower_instr->type()->as_ObjectType(), "Must not be object type");
roland@4860 661 if (lower == 0) {
roland@4860 662 // Compare for less than 0
roland@4860 663 insert_position = predicate_cmp_with_const(lower_instr, Instruction::lss, 0, state, insert_position, bci);
roland@4860 664 } else if (lower > 0) {
roland@4860 665 // Compare for smaller 0
roland@4860 666 insert_position = predicate_add_cmp_with_const(lower_instr, lower, Instruction::lss, 0, state, insert_position, bci);
roland@4860 667 } else {
roland@4860 668 assert(lower < 0, "");
roland@4860 669 // Add 1
roland@4860 670 lower++;
roland@4860 671 lower = -lower;
roland@4860 672 // Compare for smaller or equal 0
roland@4860 673 insert_position = predicate_cmp_with_const(lower_instr, Instruction::leq, lower, state, insert_position, bci);
roland@4860 674 }
roland@4860 675 }
roland@4860 676
roland@4869 677 // No upper check required -> skip
roland@4869 678 if (!upper_check) return;
roland@4869 679
roland@4860 680 // We need to know length of array
roland@4860 681 if (!length_instr) {
roland@4860 682 // Load length if necessary
roland@4860 683 ArrayLength *length = new ArrayLength(array_instr, state->copy());
roland@4860 684 NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));
roland@4860 685 length->set_exception_state(length->state_before());
roland@4860 686 length->set_flag(Instruction::DeoptimizeOnException, true);
roland@4860 687 insert_position = insert_position->insert_after(length);
roland@4860 688 length_instr = length;
roland@4860 689 }
roland@4860 690
roland@4860 691 if (!upper_instr) {
roland@4860 692 // Compare for geq array.length
roland@4860 693 insert_position = predicate_cmp_with_const(length_instr, Instruction::leq, upper, state, insert_position, bci);
roland@4860 694 } else {
roland@4860 695 if (upper_instr->type()->as_ObjectType()) {
roland@4860 696 assert(state, "must not be null");
roland@4860 697 assert(upper_instr != array_instr, "should be");
roland@4860 698 ArrayLength *length = new ArrayLength(upper_instr, state->copy());
roland@4860 699 NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));
roland@4860 700 length->set_flag(Instruction::DeoptimizeOnException, true);
roland@4860 701 length->set_exception_state(length->state_before());
roland@4860 702 insert_position = insert_position->insert_after(length);
roland@4860 703 upper_instr = length;
roland@4860 704 }
roland@4860 705 assert(upper_instr->type()->as_IntType(), "Must not be object type!");
roland@4860 706
roland@4860 707 if (upper == 0) {
roland@4860 708 // Compare for geq array.length
roland@4860 709 insert_position = predicate(upper_instr, Instruction::geq, length_instr, state, insert_position, bci);
roland@4860 710 } else if (upper < 0) {
roland@4860 711 // Compare for geq array.length
roland@4860 712 insert_position = predicate_add(upper_instr, upper, Instruction::geq, length_instr, state, insert_position, bci);
roland@4860 713 } else {
roland@4860 714 assert(upper > 0, "");
roland@4860 715 upper = -upper;
roland@4860 716 // Compare for geq array.length
roland@4860 717 insert_position = predicate_add(length_instr, upper, Instruction::leq, upper_instr, state, insert_position, bci);
roland@4860 718 }
roland@4860 719 }
roland@4860 720 }
roland@4860 721
roland@4860 722 // Add if condition
roland@4860 723 void RangeCheckEliminator::add_if_condition(IntegerStack &pushed, Value x, Value y, Instruction::Condition condition) {
roland@4860 724 if (y->as_Constant()) return;
roland@4860 725
roland@4860 726 int const_value = 0;
roland@4860 727 Value instr_value = x;
roland@4860 728 Constant *c = x->as_Constant();
roland@4860 729 ArithmeticOp *ao = x->as_ArithmeticOp();
roland@4860 730
roland@4860 731 if (c != NULL) {
roland@4860 732 const_value = c->type()->as_IntConstant()->value();
roland@4860 733 instr_value = NULL;
roland@4860 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)) {
roland@4860 735 assert(!ao->x()->as_Constant() || !ao->y()->as_Constant(), "At least one operator must be non-constant!");
roland@4860 736 assert(ao->op() == Bytecodes::_isub || ao->op() == Bytecodes::_iadd, "Operation has to be add or sub!");
roland@4860 737 c = ao->x()->as_Constant();
roland@4860 738 if (c != NULL) {
roland@4860 739 const_value = c->type()->as_IntConstant()->value();
roland@4860 740 instr_value = ao->y();
roland@4860 741 } else {
roland@4860 742 c = ao->y()->as_Constant();
roland@4860 743 if (c != NULL) {
roland@4860 744 const_value = c->type()->as_IntConstant()->value();
roland@4860 745 instr_value = ao->x();
roland@4860 746 }
roland@4860 747 }
roland@4860 748 if (ao->op() == Bytecodes::_isub) {
roland@4860 749 assert(ao->y()->as_Constant(), "1 - x not supported, only x - 1 is valid!");
roland@4860 750 if (const_value > min_jint) {
roland@4860 751 const_value = -const_value;
roland@4860 752 } else {
roland@4860 753 const_value = 0;
roland@4860 754 instr_value = x;
roland@4860 755 }
roland@4860 756 }
roland@4860 757 }
roland@4860 758
roland@4860 759 update_bound(pushed, y, condition, instr_value, const_value);
roland@4860 760 }
roland@4860 761
roland@4860 762 // Process If
roland@4860 763 void RangeCheckEliminator::process_if(IntegerStack &pushed, BlockBegin *block, If *cond) {
roland@4860 764 // Only if we are direct true / false successor and NOT both ! (even this may occur)
roland@4860 765 if ((cond->tsux() == block || cond->fsux() == block) && cond->tsux() != cond->fsux()) {
roland@4860 766 Instruction::Condition condition = cond->cond();
roland@4860 767 if (cond->fsux() == block) {
roland@4860 768 condition = Instruction::negate(condition);
roland@4860 769 }
roland@4860 770 Value x = cond->x();
roland@4860 771 Value y = cond->y();
roland@4860 772 if (x->type()->as_IntType() && y->type()->as_IntType()) {
roland@4860 773 add_if_condition(pushed, y, x, condition);
roland@4860 774 add_if_condition(pushed, x, y, Instruction::mirror(condition));
roland@4860 775 }
roland@4860 776 }
roland@4860 777 }
roland@4860 778
roland@4860 779 // Process access indexed
roland@4860 780 void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai) {
roland@4860 781 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 782 tty->fill_to(block->dominator_depth()*2)
roland@4860 783 );
roland@4860 784 TRACE_RANGE_CHECK_ELIMINATION(
roland@4869 785 tty->print_cr("Access indexed: index=%d length=%d", ai->index()->id(), (ai->length() != NULL ? ai->length()->id() :-1 ))
roland@4860 786 );
roland@4860 787
roland@4860 788 if (ai->check_flag(Instruction::NeedsRangeCheckFlag)) {
roland@4860 789 Bound *index_bound = get_bound(ai->index());
roland@4860 790 if (!index_bound->has_lower() || !index_bound->has_upper()) {
roland@4860 791 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 792 tty->fill_to(block->dominator_depth()*2);
roland@4860 793 tty->print_cr("Index instruction %d has no lower and/or no upper bound!", ai->index()->id())
roland@4860 794 );
roland@4860 795 return;
roland@4860 796 }
roland@4860 797
roland@4860 798 Bound *array_bound;
roland@4860 799 if (ai->length()) {
roland@4860 800 array_bound = get_bound(ai->length());
roland@4860 801 } else {
roland@4860 802 array_bound = get_bound(ai->array());
roland@4860 803 }
roland@4860 804
roland@4860 805 if (in_array_bound(index_bound, ai->array()) ||
roland@4860 806 (index_bound && array_bound && index_bound->is_smaller(array_bound) && !index_bound->lower_instr() && index_bound->lower() >= 0)) {
roland@4860 807 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 808 tty->fill_to(block->dominator_depth()*2);
roland@4860 809 tty->print_cr("Bounds check for instruction %d in block B%d can be fully eliminated!", ai->id(), ai->block()->block_id())
roland@4860 810 );
roland@4860 811
roland@4860 812 remove_range_check(ai);
roland@4860 813 } else if (_optimistic && loop_header) {
roland@4860 814 assert(ai->array(), "Array must not be null!");
roland@4860 815 assert(ai->index(), "Index must not be null!");
roland@4860 816
roland@4860 817 // Array instruction
roland@4860 818 Instruction *array_instr = ai->array();
roland@4860 819 if (!loop_invariant(loop_header, array_instr)) {
roland@4860 820 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 821 tty->fill_to(block->dominator_depth()*2);
roland@4860 822 tty->print_cr("Array %d is not loop invariant to header B%d", ai->array()->id(), loop_header->block_id())
roland@4860 823 );
roland@4860 824 return;
roland@4860 825 }
roland@4860 826
roland@4860 827 // Lower instruction
roland@4860 828 Value index_instr = ai->index();
roland@4860 829 Value lower_instr = index_bound->lower_instr();
roland@4860 830 if (!loop_invariant(loop_header, lower_instr)) {
roland@4860 831 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 832 tty->fill_to(block->dominator_depth()*2);
roland@4860 833 tty->print_cr("Lower instruction %d not loop invariant!", lower_instr->id())
roland@4860 834 );
roland@4860 835 return;
roland@4860 836 }
roland@4860 837 if (!lower_instr && index_bound->lower() < 0) {
roland@4860 838 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 839 tty->fill_to(block->dominator_depth()*2);
roland@4860 840 tty->print_cr("Lower bound smaller than 0 (%d)!", index_bound->lower())
roland@4860 841 );
roland@4860 842 return;
roland@4860 843 }
roland@4860 844
roland@4860 845 // Upper instruction
roland@4860 846 Value upper_instr = index_bound->upper_instr();
roland@4860 847 if (!loop_invariant(loop_header, upper_instr)) {
roland@4860 848 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 849 tty->fill_to(block->dominator_depth()*2);
roland@4860 850 tty->print_cr("Upper instruction %d not loop invariant!", upper_instr->id())
roland@4860 851 );
roland@4860 852 return;
roland@4860 853 }
roland@4860 854
roland@4860 855 // Length instruction
roland@4860 856 Value length_instr = ai->length();
roland@4860 857 if (!loop_invariant(loop_header, length_instr)) {
roland@4860 858 // Generate length instruction yourself!
roland@4860 859 length_instr = NULL;
roland@4860 860 }
roland@4860 861
roland@4860 862 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 863 tty->fill_to(block->dominator_depth()*2);
roland@4860 864 tty->print_cr("LOOP INVARIANT access indexed %d found in block B%d!", ai->id(), ai->block()->block_id())
roland@4860 865 );
roland@4860 866
roland@4860 867 BlockBegin *pred_block = loop_header->dominator();
roland@4860 868 assert(pred_block != NULL, "Every loop header has a dominator!");
roland@4860 869 BlockEnd *pred_block_end = pred_block->end();
roland@4860 870 Instruction *insert_position = pred_block_end->prev();
roland@4860 871 ValueStack *state = pred_block_end->state_before();
roland@4860 872 if (pred_block_end->as_Goto() && state == NULL) state = pred_block_end->state();
roland@4860 873 assert(state, "State must not be null");
roland@4860 874
roland@4860 875 // Add deoptimization to dominator of loop header
roland@4860 876 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 877 tty->fill_to(block->dominator_depth()*2);
roland@4860 878 tty->print_cr("Inserting deopt at bci %d in block B%d!", state->bci(), insert_position->block()->block_id())
roland@4860 879 );
roland@4860 880
roland@4860 881 if (!is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper())) {
roland@4860 882 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 883 tty->fill_to(block->dominator_depth()*2);
roland@4860 884 tty->print_cr("Could not eliminate because of static analysis!")
roland@4860 885 );
roland@4860 886 return;
roland@4860 887 }
roland@4860 888
roland@4860 889 insert_deoptimization(state, insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper(), ai);
roland@4860 890
roland@4860 891 // Finally remove the range check!
roland@4860 892 remove_range_check(ai);
roland@4860 893 }
roland@4860 894 }
roland@4860 895 }
roland@4860 896
roland@4860 897 void RangeCheckEliminator::remove_range_check(AccessIndexed *ai) {
roland@4860 898 ai->set_flag(Instruction::NeedsRangeCheckFlag, false);
roland@4860 899 // no range check, no need for the length instruction anymore
roland@4860 900 ai->clear_length();
roland@4860 901
roland@4860 902 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 903 tty->fill_to(ai->dominator_depth()*2);
roland@4860 904 tty->print_cr("Range check for instruction %d eliminated!", ai->id());
roland@4860 905 );
roland@4860 906
roland@4860 907 ASSERT_RANGE_CHECK_ELIMINATION(
roland@4860 908 Value array_length = ai->length();
roland@4860 909 if (!array_length) {
roland@4860 910 array_length = ai->array();
roland@4860 911 assert(array_length->type()->as_ObjectType(), "Has to be object type!");
roland@4860 912 }
roland@4860 913 int cur_constant = -1;
roland@4860 914 Value cur_value = array_length;
roland@4860 915 if (cur_value->type()->as_IntConstant()) {
roland@4860 916 cur_constant += cur_value->type()->as_IntConstant()->value();
roland@4860 917 cur_value = NULL;
roland@4860 918 }
roland@4860 919 Bound *new_index_bound = new Bound(0, NULL, cur_constant, cur_value);
roland@4860 920 add_assertions(new_index_bound, ai->index(), ai);
roland@4860 921 );
roland@4860 922 }
roland@4860 923
roland@4860 924 // Calculate bounds for instruction in this block and children blocks in the dominator tree
roland@4860 925 void RangeCheckEliminator::calc_bounds(BlockBegin *block, BlockBegin *loop_header) {
roland@4860 926 // Ensures a valid loop_header
roland@4860 927 assert(!loop_header || loop_header->is_set(BlockBegin::linear_scan_loop_header_flag), "Loop header has to be real !");
roland@4860 928
roland@4860 929 // Tracing output
roland@4860 930 TRACE_RANGE_CHECK_ELIMINATION(
roland@4860 931 tty->fill_to(block->dominator_depth()*2);
roland@4860 932 tty->print_cr("Block B%d", block->block_id());
roland@4860 933 );
roland@4860 934
roland@4860 935 // Pushed stack for conditions
roland@4860 936 IntegerStack pushed;
roland@4860 937 // Process If
roland@4860 938 BlockBegin *parent = block->dominator();
roland@4860 939 if (parent != NULL) {
roland@4860 940 If *cond = parent->end()->as_If();
roland@4860 941 if (cond != NULL) {
roland@4860 942 process_if(pushed, block, cond);
roland@4860 943 }
roland@4860 944 }
roland@4860 945
roland@4860 946 // Interate over current block
roland@4860 947 InstructionList arrays;
roland@4860 948 AccessIndexedList accessIndexed;
roland@4860 949 Instruction *cur = block;
roland@4860 950
roland@4860 951 while (cur) {
roland@4860 952 // Ensure cur wasn't inserted during the elimination
roland@4860 953 if (cur->id() < this->_bounds.length()) {
roland@4860 954 // Process only if it is an access indexed instruction
roland@4860 955 AccessIndexed *ai = cur->as_AccessIndexed();
roland@4860 956 if (ai != NULL) {
roland@4860 957 process_access_indexed(loop_header, block, ai);
roland@4860 958 accessIndexed.append(ai);
roland@4860 959 if (!arrays.contains(ai->array())) {
roland@4860 960 arrays.append(ai->array());
roland@4860 961 }
roland@4860 962 Bound *b = get_bound(ai->index());
roland@4860 963 if (!b->lower_instr()) {
roland@4860 964 // Lower bound is constant
roland@4860 965 update_bound(pushed, ai->index(), Instruction::geq, NULL, 0);
roland@4860 966 }
roland@4860 967 if (!b->has_upper()) {
roland@4860 968 if (ai->length() && ai->length()->type()->as_IntConstant()) {
roland@4860 969 int value = ai->length()->type()->as_IntConstant()->value();
roland@4860 970 update_bound(pushed, ai->index(), Instruction::lss, NULL, value);
roland@4860 971 } else {
roland@4860 972 // Has no upper bound
roland@4860 973 Instruction *instr = ai->length();
roland@4860 974 if (instr != NULL) instr = ai->array();
roland@4860 975 update_bound(pushed, ai->index(), Instruction::lss, instr, 0);
roland@4860 976 }
roland@4860 977 }
roland@4860 978 }
roland@4860 979 }
roland@4860 980 cur = cur->next();
roland@4860 981 }
roland@4860 982
roland@4860 983 // Output current condition stack
roland@4860 984 TRACE_RANGE_CHECK_ELIMINATION(dump_condition_stack(block));
roland@4860 985
roland@4860 986 // Do in block motion of range checks
roland@4860 987 in_block_motion(block, accessIndexed, arrays);
roland@4860 988
roland@4860 989 // Call all dominated blocks
roland@4860 990 for (int i=0; i<block->dominates()->length(); i++) {
roland@4860 991 BlockBegin *next = block->dominates()->at(i);
roland@4860 992 if (!next->is_set(BlockBegin::donot_eliminate_range_checks)) {
roland@4860 993 // if current block is a loop header and:
roland@4860 994 // - next block belongs to the same loop
roland@4860 995 // or
roland@4860 996 // - next block belongs to an inner loop
roland@4860 997 // then current block is the loop header for next block
roland@4860 998 if (block->is_set(BlockBegin::linear_scan_loop_header_flag) && (block->loop_index() == next->loop_index() || next->loop_depth() > block->loop_depth())) {
roland@4860 999 calc_bounds(next, block);
roland@4860 1000 } else {
roland@4860 1001 calc_bounds(next, loop_header);
roland@4860 1002 }
roland@4860 1003 }
roland@4860 1004 }
roland@4860 1005
roland@4860 1006 // Reset stack
roland@4860 1007 for (int i=0; i<pushed.length(); i++) {
roland@4860 1008 _bounds[pushed[i]]->pop();
roland@4860 1009 }
roland@4860 1010 }
roland@4860 1011
roland@4860 1012 #ifndef PRODUCT
roland@4860 1013 // Dump condition stack
roland@4860 1014 void RangeCheckEliminator::dump_condition_stack(BlockBegin *block) {
roland@4860 1015 for (int i=0; i<_ir->linear_scan_order()->length(); i++) {
roland@4860 1016 BlockBegin *cur_block = _ir->linear_scan_order()->at(i);
roland@4860 1017 Instruction *instr = cur_block;
roland@4860 1018 for_each_phi_fun(cur_block, phi,
roland@4860 1019 BoundStack *bound_stack = _bounds.at(phi->id());
roland@4860 1020 if (bound_stack && bound_stack->length() > 0) {
roland@4860 1021 Bound *bound = bound_stack->top();
roland@4860 1022 if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != phi || bound->upper_instr() != phi || bound->lower() != 0 || bound->upper() != 0)) {
roland@4860 1023 TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());
roland@4860 1024 tty->print("i%d", phi->id());
roland@4860 1025 tty->print(": ");
roland@4860 1026 bound->print();
drchase@6680 1027 tty->cr();
roland@4860 1028 );
roland@4860 1029 }
roland@4860 1030 });
roland@4860 1031
roland@4860 1032 while (!instr->as_BlockEnd()) {
roland@4860 1033 if (instr->id() < _bounds.length()) {
roland@4860 1034 BoundStack *bound_stack = _bounds.at(instr->id());
roland@4860 1035 if (bound_stack && bound_stack->length() > 0) {
roland@4860 1036 Bound *bound = bound_stack->top();
roland@4860 1037 if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != instr || bound->upper_instr() != instr || bound->lower() != 0 || bound->upper() != 0)) {
roland@4860 1038 TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());
roland@4860 1039 tty->print("i%d", instr->id());
roland@4860 1040 tty->print(": ");
roland@4860 1041 bound->print();
drchase@6680 1042 tty->cr();
roland@4860 1043 );
roland@4860 1044 }
roland@4860 1045 }
roland@4860 1046 }
roland@4860 1047 instr = instr->next();
roland@4860 1048 }
roland@4860 1049 }
roland@4860 1050 }
roland@4860 1051 #endif
roland@4860 1052
roland@4860 1053 // Verification or the IR
roland@4860 1054 RangeCheckEliminator::Verification::Verification(IR *ir) : _used(BlockBegin::number_of_blocks(), false) {
roland@4860 1055 this->_ir = ir;
roland@4860 1056 ir->iterate_linear_scan_order(this);
roland@4860 1057 }
roland@4860 1058
roland@4860 1059 // Verify this block
roland@4860 1060 void RangeCheckEliminator::Verification::block_do(BlockBegin *block) {
roland@4860 1061 If *cond = block->end()->as_If();
roland@4860 1062 // Watch out: tsux and fsux can be the same!
roland@4860 1063 if (block->number_of_sux() > 1) {
roland@4860 1064 for (int i=0; i<block->number_of_sux(); i++) {
roland@4860 1065 BlockBegin *sux = block->sux_at(i);
roland@4860 1066 BlockBegin *pred = NULL;
roland@4860 1067 for (int j=0; j<sux->number_of_preds(); j++) {
roland@4860 1068 BlockBegin *cur = sux->pred_at(j);
roland@4860 1069 assert(cur != NULL, "Predecessor must not be null");
roland@4860 1070 if (!pred) {
roland@4860 1071 pred = cur;
roland@4860 1072 }
roland@4860 1073 assert(cur == pred, "Block must not have more than one predecessor if its predecessor has more than one successor");
roland@4860 1074 }
roland@4860 1075 assert(sux->number_of_preds() >= 1, "Block must have at least one predecessor");
roland@4860 1076 assert(sux->pred_at(0) == block, "Wrong successor");
roland@4860 1077 }
roland@4860 1078 }
roland@4860 1079
roland@4860 1080 BlockBegin *dominator = block->dominator();
roland@4860 1081 if (dominator) {
roland@4860 1082 assert(block != _ir->start(), "Start block must not have a dominator!");
roland@4860 1083 assert(can_reach(dominator, block), "Dominator can't reach his block !");
roland@4860 1084 assert(can_reach(_ir->start(), dominator), "Dominator is unreachable !");
roland@4860 1085 assert(!can_reach(_ir->start(), block, dominator), "Wrong dominator ! Block can be reached anyway !");
roland@4860 1086 BlockList *all_blocks = _ir->linear_scan_order();
roland@4860 1087 for (int i=0; i<all_blocks->length(); i++) {
roland@4860 1088 BlockBegin *cur = all_blocks->at(i);
roland@4860 1089 if (cur != dominator && cur != block) {
roland@4860 1090 assert(can_reach(dominator, block, cur), "There has to be another dominator!");
roland@4860 1091 }
roland@4860 1092 }
roland@4860 1093 } else {
roland@4860 1094 assert(block == _ir->start(), "Only start block must not have a dominator");
roland@4860 1095 }
roland@4860 1096
roland@4860 1097 if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) {
roland@4860 1098 int loop_index = block->loop_index();
roland@4860 1099 BlockList *all_blocks = _ir->linear_scan_order();
roland@4860 1100 assert(block->number_of_preds() >= 1, "Block must have at least one predecessor");
roland@4860 1101 assert(!block->is_set(BlockBegin::exception_entry_flag), "Loop header must not be exception handler!");
roland@4860 1102 // Sometimes, the backbranch comes from an exception handler. In
roland@4860 1103 // this case, loop indexes/loop depths may not appear correct.
roland@4860 1104 bool loop_through_xhandler = false;
roland@4860 1105 for (int i = 0; i < block->number_of_exception_handlers(); i++) {
roland@4860 1106 BlockBegin *xhandler = block->exception_handler_at(i);
roland@4860 1107 for (int j = 0; j < block->number_of_preds(); j++) {
roland@4860 1108 if (dominates(xhandler, block->pred_at(j)) || xhandler == block->pred_at(j)) {
roland@4860 1109 loop_through_xhandler = true;
roland@4860 1110 }
roland@4860 1111 }
roland@4860 1112 }
roland@4860 1113
roland@4860 1114 for (int i=0; i<block->number_of_sux(); i++) {
roland@4860 1115 BlockBegin *sux = block->sux_at(i);
roland@4860 1116 assert(sux->loop_depth() != block->loop_depth() || sux->loop_index() == block->loop_index() || loop_through_xhandler, "Loop index has to be same");
roland@4860 1117 assert(sux->loop_depth() == block->loop_depth() || sux->loop_index() != block->loop_index(), "Loop index has to be different");
roland@4860 1118 }
roland@4860 1119
roland@4860 1120 for (int i=0; i<all_blocks->length(); i++) {
roland@4860 1121 BlockBegin *cur = all_blocks->at(i);
roland@4860 1122 if (cur->loop_index() == loop_index && cur != block) {
roland@4860 1123 assert(dominates(block->dominator(), cur), "Dominator of loop header must dominate all loop blocks");
roland@4860 1124 }
roland@4860 1125 }
roland@4860 1126 }
roland@4860 1127
roland@4860 1128 Instruction *cur = block;
roland@4860 1129 while (cur) {
roland@4860 1130 assert(cur->block() == block, "Block begin has to be set correctly!");
roland@4860 1131 cur = cur->next();
roland@4860 1132 }
roland@4860 1133 }
roland@4860 1134
roland@4860 1135 // Loop header must dominate all loop blocks
roland@4860 1136 bool RangeCheckEliminator::Verification::dominates(BlockBegin *dominator, BlockBegin *block) {
roland@4860 1137 BlockBegin *cur = block->dominator();
roland@4860 1138 while (cur && cur != dominator) {
roland@4860 1139 cur = cur->dominator();
roland@4860 1140 }
roland@4860 1141 return cur == dominator;
roland@4860 1142 }
roland@4860 1143
roland@4860 1144 // Try to reach Block end beginning in Block start and not using Block dont_use
roland@4860 1145 bool RangeCheckEliminator::Verification::can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use /* = NULL */) {
roland@4860 1146 if (start == end) return start != dont_use;
roland@4860 1147 // Simple BSF from start to end
roland@4860 1148 // BlockBeginList _current;
roland@4860 1149 for (int i=0; i<_used.length(); i++) {
roland@4860 1150 _used[i] = false;
roland@4860 1151 }
roland@4860 1152 _current.truncate(0);
roland@4860 1153 _successors.truncate(0);
roland@4860 1154 if (start != dont_use) {
roland@4860 1155 _current.push(start);
roland@4860 1156 _used[start->block_id()] = true;
roland@4860 1157 }
roland@4860 1158
roland@4860 1159 // BlockBeginList _successors;
roland@4860 1160 while (_current.length() > 0) {
roland@4860 1161 BlockBegin *cur = _current.pop();
roland@4860 1162 // Add exception handlers to list
roland@4860 1163 for (int i=0; i<cur->number_of_exception_handlers(); i++) {
roland@4860 1164 BlockBegin *xhandler = cur->exception_handler_at(i);
roland@4860 1165 _successors.push(xhandler);
roland@4860 1166 // Add exception handlers of _successors to list
roland@4860 1167 for (int j=0; j<xhandler->number_of_exception_handlers(); j++) {
roland@4860 1168 BlockBegin *sux_xhandler = xhandler->exception_handler_at(j);
roland@4860 1169 _successors.push(sux_xhandler);
roland@4860 1170 }
roland@4860 1171 }
roland@4860 1172 // Add normal _successors to list
roland@4860 1173 for (int i=0; i<cur->number_of_sux(); i++) {
roland@4860 1174 BlockBegin *sux = cur->sux_at(i);
roland@4860 1175 _successors.push(sux);
roland@4860 1176 // Add exception handlers of _successors to list
roland@4860 1177 for (int j=0; j<sux->number_of_exception_handlers(); j++) {
roland@4860 1178 BlockBegin *xhandler = sux->exception_handler_at(j);
roland@4860 1179 _successors.push(xhandler);
roland@4860 1180 }
roland@4860 1181 }
roland@4860 1182 for (int i=0; i<_successors.length(); i++) {
roland@4860 1183 BlockBegin *sux = _successors[i];
roland@4860 1184 assert(sux != NULL, "Successor must not be NULL!");
roland@4860 1185 if (sux == end) {
roland@4860 1186 return true;
roland@4860 1187 }
roland@4860 1188 if (sux != dont_use && !_used[sux->block_id()]) {
roland@4860 1189 _used[sux->block_id()] = true;
roland@4860 1190 _current.push(sux);
roland@4860 1191 }
roland@4860 1192 }
roland@4860 1193 _successors.truncate(0);
roland@4860 1194 }
roland@4860 1195
roland@4860 1196 return false;
roland@4860 1197 }
roland@4860 1198
roland@4860 1199 // Bound
roland@4860 1200 RangeCheckEliminator::Bound::~Bound() {
roland@4860 1201 }
roland@4860 1202
roland@4860 1203 // Bound constructor
roland@4860 1204 RangeCheckEliminator::Bound::Bound() {
roland@4860 1205 init();
roland@4860 1206 this->_lower = min_jint;
roland@4860 1207 this->_upper = max_jint;
roland@4860 1208 this->_lower_instr = NULL;
roland@4860 1209 this->_upper_instr = NULL;
roland@4860 1210 }
roland@4860 1211
roland@4860 1212 // Bound constructor
roland@4860 1213 RangeCheckEliminator::Bound::Bound(int lower, Value lower_instr, int upper, Value upper_instr) {
roland@4860 1214 init();
roland@4860 1215 assert(!lower_instr || !lower_instr->as_Constant() || !lower_instr->type()->as_IntConstant(), "Must not be constant!");
roland@4860 1216 assert(!upper_instr || !upper_instr->as_Constant() || !upper_instr->type()->as_IntConstant(), "Must not be constant!");
roland@4860 1217 this->_lower = lower;
roland@4860 1218 this->_upper = upper;
roland@4860 1219 this->_lower_instr = lower_instr;
roland@4860 1220 this->_upper_instr = upper_instr;
roland@4860 1221 }
roland@4860 1222
roland@4860 1223 // Bound constructor
roland@4860 1224 RangeCheckEliminator::Bound::Bound(Instruction::Condition cond, Value v, int constant) {
roland@4860 1225 assert(!v || (v->type() && (v->type()->as_IntType() || v->type()->as_ObjectType())), "Type must be array or integer!");
roland@4860 1226 assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");
roland@4860 1227
roland@4860 1228 init();
roland@4860 1229 if (cond == Instruction::eql) {
roland@4860 1230 _lower = constant;
roland@4860 1231 _lower_instr = v;
roland@4860 1232 _upper = constant;
roland@4860 1233 _upper_instr = v;
roland@4860 1234 } else if (cond == Instruction::neq) {
roland@4860 1235 _lower = min_jint;
roland@4860 1236 _upper = max_jint;
roland@4860 1237 _lower_instr = NULL;
roland@4860 1238 _upper_instr = NULL;
roland@4860 1239 if (v == NULL) {
roland@4860 1240 if (constant == min_jint) {
roland@4860 1241 _lower++;
roland@4860 1242 }
roland@4860 1243 if (constant == max_jint) {
roland@4860 1244 _upper--;
roland@4860 1245 }
roland@4860 1246 }
roland@4860 1247 } else if (cond == Instruction::geq) {
roland@4860 1248 _lower = constant;
roland@4860 1249 _lower_instr = v;
roland@4860 1250 _upper = max_jint;
roland@4860 1251 _upper_instr = NULL;
roland@4860 1252 } else if (cond == Instruction::leq) {
roland@4860 1253 _lower = min_jint;
roland@4860 1254 _lower_instr = NULL;
roland@4860 1255 _upper = constant;
roland@4860 1256 _upper_instr = v;
roland@4860 1257 } else {
roland@4860 1258 ShouldNotReachHere();
roland@4860 1259 }
roland@4860 1260 }
roland@4860 1261
roland@4860 1262 // Set lower
roland@4860 1263 void RangeCheckEliminator::Bound::set_lower(int value, Value v) {
roland@4860 1264 assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");
roland@4860 1265 this->_lower = value;
roland@4860 1266 this->_lower_instr = v;
roland@4860 1267 }
roland@4860 1268
roland@4860 1269 // Set upper
roland@4860 1270 void RangeCheckEliminator::Bound::set_upper(int value, Value v) {
roland@4860 1271 assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");
roland@4860 1272 this->_upper = value;
roland@4860 1273 this->_upper_instr = v;
roland@4860 1274 }
roland@4860 1275
roland@4860 1276 // Add constant -> no overflow may occur
roland@4860 1277 void RangeCheckEliminator::Bound::add_constant(int value) {
roland@4860 1278 this->_lower += value;
roland@4860 1279 this->_upper += value;
roland@4860 1280 }
roland@4860 1281
roland@4860 1282 // Init
roland@4860 1283 void RangeCheckEliminator::Bound::init() {
roland@4860 1284 }
roland@4860 1285
roland@4860 1286 // or
roland@4860 1287 void RangeCheckEliminator::Bound::or_op(Bound *b) {
roland@4860 1288 // Watch out, bound is not guaranteed not to overflow!
roland@4860 1289 // Update lower bound
roland@4860 1290 if (_lower_instr != b->_lower_instr || (_lower_instr && _lower != b->_lower)) {
roland@4860 1291 _lower_instr = NULL;
roland@4860 1292 _lower = min_jint;
roland@4860 1293 } else {
roland@4860 1294 _lower = MIN2(_lower, b->_lower);
roland@4860 1295 }
roland@4860 1296 // Update upper bound
roland@4860 1297 if (_upper_instr != b->_upper_instr || (_upper_instr && _upper != b->_upper)) {
roland@4860 1298 _upper_instr = NULL;
roland@4860 1299 _upper = max_jint;
roland@4860 1300 } else {
roland@4860 1301 _upper = MAX2(_upper, b->_upper);
roland@4860 1302 }
roland@4860 1303 }
roland@4860 1304
roland@4860 1305 // and
roland@4860 1306 void RangeCheckEliminator::Bound::and_op(Bound *b) {
roland@4860 1307 // Update lower bound
roland@4860 1308 if (_lower_instr == b->_lower_instr) {
roland@4860 1309 _lower = MAX2(_lower, b->_lower);
roland@4860 1310 }
roland@4860 1311 if (b->has_lower()) {
roland@4860 1312 bool set = true;
roland@4860 1313 if (_lower_instr != NULL && b->_lower_instr != NULL) {
roland@4860 1314 set = (_lower_instr->dominator_depth() > b->_lower_instr->dominator_depth());
roland@4860 1315 }
roland@4860 1316 if (set) {
roland@4860 1317 _lower = b->_lower;
roland@4860 1318 _lower_instr = b->_lower_instr;
roland@4860 1319 }
roland@4860 1320 }
roland@4860 1321 // Update upper bound
roland@4860 1322 if (_upper_instr == b->_upper_instr) {
roland@4860 1323 _upper = MIN2(_upper, b->_upper);
roland@4860 1324 }
roland@4860 1325 if (b->has_upper()) {
roland@4860 1326 bool set = true;
roland@4860 1327 if (_upper_instr != NULL && b->_upper_instr != NULL) {
roland@4860 1328 set = (_upper_instr->dominator_depth() > b->_upper_instr->dominator_depth());
roland@4860 1329 }
roland@4860 1330 if (set) {
roland@4860 1331 _upper = b->_upper;
roland@4860 1332 _upper_instr = b->_upper_instr;
roland@4860 1333 }
roland@4860 1334 }
roland@4860 1335 }
roland@4860 1336
roland@4860 1337 // has_upper
roland@4860 1338 bool RangeCheckEliminator::Bound::has_upper() {
roland@4860 1339 return _upper_instr != NULL || _upper < max_jint;
roland@4860 1340 }
roland@4860 1341
roland@4860 1342 // is_smaller
roland@4860 1343 bool RangeCheckEliminator::Bound::is_smaller(Bound *b) {
roland@4860 1344 if (b->_lower_instr != _upper_instr) {
roland@4860 1345 return false;
roland@4860 1346 }
roland@4860 1347 return _upper < b->_lower;
roland@4860 1348 }
roland@4860 1349
roland@4860 1350 // has_lower
roland@4860 1351 bool RangeCheckEliminator::Bound::has_lower() {
roland@4860 1352 return _lower_instr != NULL || _lower > min_jint;
roland@4860 1353 }
roland@4860 1354
roland@4860 1355 // in_array_bound
roland@4860 1356 bool RangeCheckEliminator::in_array_bound(Bound *bound, Value array){
roland@4860 1357 if (!bound) return false;
roland@4860 1358 assert(array != NULL, "Must not be null!");
roland@4860 1359 assert(bound != NULL, "Must not be null!");
roland@4860 1360 if (bound->lower() >=0 && bound->lower_instr() == NULL && bound->upper() < 0 && bound->upper_instr() != NULL) {
roland@4860 1361 ArrayLength *len = bound->upper_instr()->as_ArrayLength();
roland@4860 1362 if (bound->upper_instr() == array || (len != NULL && len->array() == array)) {
roland@4860 1363 return true;
roland@4860 1364 }
roland@4860 1365 }
roland@4860 1366 return false;
roland@4860 1367 }
roland@4860 1368
roland@4860 1369 // remove_lower
roland@4860 1370 void RangeCheckEliminator::Bound::remove_lower() {
roland@4860 1371 _lower = min_jint;
roland@4860 1372 _lower_instr = NULL;
roland@4860 1373 }
roland@4860 1374
roland@4860 1375 // remove_upper
roland@4860 1376 void RangeCheckEliminator::Bound::remove_upper() {
roland@4860 1377 _upper = max_jint;
roland@4860 1378 _upper_instr = NULL;
roland@4860 1379 }
roland@4860 1380
roland@4860 1381 // upper
roland@4860 1382 int RangeCheckEliminator::Bound::upper() {
roland@4860 1383 return _upper;
roland@4860 1384 }
roland@4860 1385
roland@4860 1386 // lower
roland@4860 1387 int RangeCheckEliminator::Bound::lower() {
roland@4860 1388 return _lower;
roland@4860 1389 }
roland@4860 1390
roland@4860 1391 // upper_instr
roland@4860 1392 Value RangeCheckEliminator::Bound::upper_instr() {
roland@4860 1393 return _upper_instr;
roland@4860 1394 }
roland@4860 1395
roland@4860 1396 // lower_instr
roland@4860 1397 Value RangeCheckEliminator::Bound::lower_instr() {
roland@4860 1398 return _lower_instr;
roland@4860 1399 }
roland@4860 1400
roland@4860 1401 // print
roland@4860 1402 void RangeCheckEliminator::Bound::print() {
drchase@6680 1403 tty->print("%s", "");
roland@4860 1404 if (this->_lower_instr || this->_lower != min_jint) {
roland@4860 1405 if (this->_lower_instr) {
roland@4860 1406 tty->print("i%d", this->_lower_instr->id());
roland@4860 1407 if (this->_lower > 0) {
roland@4860 1408 tty->print("+%d", _lower);
roland@4860 1409 }
roland@4860 1410 if (this->_lower < 0) {
roland@4860 1411 tty->print("%d", _lower);
roland@4860 1412 }
roland@4860 1413 } else {
roland@4860 1414 tty->print("%d", _lower);
roland@4860 1415 }
roland@4860 1416 tty->print(" <= ");
roland@4860 1417 }
roland@4860 1418 tty->print("x");
roland@4860 1419 if (this->_upper_instr || this->_upper != max_jint) {
roland@4860 1420 tty->print(" <= ");
roland@4860 1421 if (this->_upper_instr) {
roland@4860 1422 tty->print("i%d", this->_upper_instr->id());
roland@4860 1423 if (this->_upper > 0) {
roland@4860 1424 tty->print("+%d", _upper);
roland@4860 1425 }
roland@4860 1426 if (this->_upper < 0) {
roland@4860 1427 tty->print("%d", _upper);
roland@4860 1428 }
roland@4860 1429 } else {
roland@4860 1430 tty->print("%d", _upper);
roland@4860 1431 }
roland@4860 1432 }
roland@4860 1433 }
roland@4860 1434
roland@4860 1435 // Copy
roland@4860 1436 RangeCheckEliminator::Bound *RangeCheckEliminator::Bound::copy() {
roland@4860 1437 Bound *b = new Bound();
roland@4860 1438 b->_lower = _lower;
roland@4860 1439 b->_lower_instr = _lower_instr;
roland@4860 1440 b->_upper = _upper;
roland@4860 1441 b->_upper_instr = _upper_instr;
roland@4860 1442 return b;
roland@4860 1443 }
roland@4860 1444
roland@4860 1445 #ifdef ASSERT
roland@4860 1446 // Add assertion
roland@4860 1447 void RangeCheckEliminator::Bound::add_assertion(Instruction *instruction, Instruction *position, int i, Value instr, Instruction::Condition cond) {
roland@4860 1448 Instruction *result = position;
roland@4860 1449 Instruction *compare_with = NULL;
roland@4860 1450 ValueStack *state = position->state_before();
roland@4860 1451 if (position->as_BlockEnd() && !position->as_Goto()) {
roland@4860 1452 state = position->as_BlockEnd()->state_before();
roland@4860 1453 }
roland@4860 1454 Instruction *instruction_before = position->prev();
roland@4860 1455 if (position->as_Return() && Compilation::current()->method()->is_synchronized() && instruction_before->as_MonitorExit()) {
roland@4860 1456 instruction_before = instruction_before->prev();
roland@4860 1457 }
roland@4860 1458 result = instruction_before;
roland@4860 1459 // Load constant only if needed
roland@4860 1460 Constant *constant = NULL;
roland@4860 1461 if (i != 0 || !instr) {
roland@4860 1462 constant = new Constant(new IntConstant(i));
roland@4860 1463 NOT_PRODUCT(constant->set_printable_bci(position->printable_bci()));
roland@4860 1464 result = result->insert_after(constant);
roland@4860 1465 compare_with = constant;
roland@4860 1466 }
roland@4860 1467
roland@4860 1468 if (instr) {
roland@4860 1469 assert(instr->type()->as_ObjectType() || instr->type()->as_IntType(), "Type must be array or integer!");
roland@4860 1470 compare_with = instr;
roland@4860 1471 // Load array length if necessary
roland@4860 1472 Instruction *op = instr;
roland@4860 1473 if (instr->type()->as_ObjectType()) {
roland@4860 1474 assert(state, "must not be null");
roland@4860 1475 ArrayLength *length = new ArrayLength(instr, state->copy());
roland@4860 1476 NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));
roland@4860 1477 length->set_exception_state(length->state_before());
roland@4860 1478 result = result->insert_after(length);
roland@4860 1479 op = length;
roland@4860 1480 compare_with = length;
roland@4860 1481 }
roland@4860 1482 // Add operation only if necessary
roland@4860 1483 if (constant) {
roland@4860 1484 ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, op, false, NULL);
roland@4860 1485 NOT_PRODUCT(ao->set_printable_bci(position->printable_bci()));
roland@4860 1486 result = result->insert_after(ao);
roland@4860 1487 compare_with = ao;
roland@4860 1488 // TODO: Check that add operation does not overflow!
roland@4860 1489 }
roland@4860 1490 }
roland@4860 1491 assert(compare_with != NULL, "You have to compare with something!");
roland@4860 1492 assert(instruction != NULL, "Instruction must not be null!");
roland@4860 1493
roland@4860 1494 if (instruction->type()->as_ObjectType()) {
roland@4860 1495 // Load array length if necessary
roland@4860 1496 Instruction *op = instruction;
roland@4860 1497 assert(state, "must not be null");
roland@4860 1498 ArrayLength *length = new ArrayLength(instruction, state->copy());
roland@4860 1499 length->set_exception_state(length->state_before());
roland@4860 1500 NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));
roland@4860 1501 result = result->insert_after(length);
roland@4860 1502 instruction = length;
roland@4860 1503 }
roland@4860 1504
roland@4860 1505 Assert *assert = new Assert(instruction, cond, false, compare_with);
roland@4860 1506 NOT_PRODUCT(assert->set_printable_bci(position->printable_bci()));
roland@4860 1507 result->insert_after(assert);
roland@4860 1508 }
roland@4860 1509
roland@4860 1510 // Add assertions
roland@4860 1511 void RangeCheckEliminator::add_assertions(Bound *bound, Instruction *instruction, Instruction *position) {
roland@4860 1512 // Add lower bound assertion
roland@4860 1513 if (bound->has_lower()) {
roland@4860 1514 bound->add_assertion(instruction, position, bound->lower(), bound->lower_instr(), Instruction::geq);
roland@4860 1515 }
roland@4860 1516 // Add upper bound assertion
roland@4860 1517 if (bound->has_upper()) {
roland@4860 1518 bound->add_assertion(instruction, position, bound->upper(), bound->upper_instr(), Instruction::leq);
roland@4860 1519 }
roland@4860 1520 }
roland@4860 1521 #endif
roland@4860 1522

mercurial