src/share/vm/c1/c1_Instruction.cpp

```rev 4136 : 7153771: array bound check elimination for c1
Summary: when possible optimize out array bound checks, inserting predicates when needed.
Reviewed-by:```
```*** 32,49 ****
--- 32,60 ----

// Implementation of Instruction

+ int Instruction::dominator_depth() {
+   int result = -1;
+   if (block()) {
+     result = block()->dominator_depth();
+   }
+   assert(result != -1 || this->as_Local(), "Only locals have dominator depth -1");
+   return result;
+ }
+
Instruction::Condition Instruction::mirror(Condition cond) {
switch (cond) {
case eql: return eql;
case neq: return neq;
case lss: return gtr;
case leq: return geq;
case gtr: return lss;
case geq: return leq;
+     case aeq: return beq;
+     case beq: return aeq;
}
ShouldNotReachHere();
return eql;
}

*** 54,63 ****
--- 65,76 ----
case neq: return eql;
case lss: return geq;
case leq: return gtr;
case gtr: return leq;
case geq: return lss;
+     case aeq: assert(false, "Above equal cannot be negated");
+     case beq: assert(false, "Below equal cannot be negated");
}
ShouldNotReachHere();
return eql;
}

*** 68,81 ****
} else {
_exception_state = NULL;
}
}

!
! Instruction* Instruction::prev(BlockBegin* block) {
Instruction* p = NULL;
!   Instruction* q = block;
while (q != this) {
assert(q != NULL, "this is not in the block's instruction list");
p = q; q = q->next();
}
return p;
--- 81,94 ----
} else {
_exception_state = NULL;
}
}

! // Prev without need to have BlockBegin
! Instruction* Instruction::prev() {
Instruction* p = NULL;
!   Instruction* q = block();
while (q != this) {
assert(q != NULL, "this is not in the block's instruction list");
p = q; q = q->next();
}
return p;
*** 120,138 ****
--- 133,160 ----
#endif // PRODUCT

// perform constant and interval tests on index value
bool AccessIndexed::compute_needs_range_check() {
+
+   if (length()) {
+
Constant* clength = length()->as_Constant();
Constant* cindex = index()->as_Constant();
if (clength && cindex) {
IntConstant* l = clength->type()->as_IntConstant();
IntConstant* i = cindex->type()->as_IntConstant();
if (l && i && i->value() < l->value() && i->value() >= 0) {
return false;
}
}
+   }
+
+   if (!this->check_flag(NeedsRangeCheckFlag)) {
+     return false;
+   }
+
return true;
}

ciType* Local::exact_type() const {
*** 629,651 ****

// In general it is not possible to calculate a value for the field "depth_first_number"
// of the inserted block, without recomputing the values of the other blocks
// in the CFG. Therefore the value of "depth_first_number" in BlockBegin becomes meaningless.
BlockBegin* BlockBegin::insert_block_between(BlockBegin* sux) {
!   BlockBegin* new_sux = new BlockBegin(end()->state()->bci());

// mark this block (special treatment when block order is computed)
new_sux->set(critical_edge_split_flag);

// This goto is not a safepoint.
Goto* e = new Goto(sux, false);
!   new_sux->set_next(e, end()->state()->bci());
new_sux->set_end(e);
// setup states
ValueStack* s = end()->state();
!   new_sux->set_state(s->copy());
!   e->set_state(s->copy());
assert(new_sux->state()->locals_size() == s->locals_size(), "local size mismatch!");
assert(new_sux->state()->stack_size() == s->stack_size(), "stack size mismatch!");
assert(new_sux->state()->locks_size() == s->locks_size(), "locks size mismatch!");

// link predecessor to new block
--- 651,679 ----

// In general it is not possible to calculate a value for the field "depth_first_number"
// of the inserted block, without recomputing the values of the other blocks
// in the CFG. Therefore the value of "depth_first_number" in BlockBegin becomes meaningless.
BlockBegin* BlockBegin::insert_block_between(BlockBegin* sux) {
!   int bci = sux->bci();
!   // critical edge splitting may introduce a goto after a if and array
!   // bound check elimination may insert a predicate between the if and
!   // goto. The bci of the goto can't be the one of the if otherwise
!   // the state and bci are inconsistent and a deoptimization triggered
!   // by the predicate would lead to incorrect execution/a crash.
!   BlockBegin* new_sux = new BlockBegin(bci);

// mark this block (special treatment when block order is computed)
new_sux->set(critical_edge_split_flag);

// This goto is not a safepoint.
Goto* e = new Goto(sux, false);
!   new_sux->set_next(e, bci);
new_sux->set_end(e);
// setup states
ValueStack* s = end()->state();
!   new_sux->set_state(s->copy(s->kind(), bci));
!   e->set_state(s->copy(s->kind(), bci));
assert(new_sux->state()->locals_size() == s->locals_size(), "local size mismatch!");
assert(new_sux->state()->stack_size() == s->stack_size(), "stack size mismatch!");
assert(new_sux->state()->locks_size() == s->locks_size(), "locks size mismatch!");

// link predecessor to new block
*** 958,976 ****

void BlockEnd::set_begin(BlockBegin* begin) {
BlockList* sux = NULL;
if (begin != NULL) {
sux = begin->successors();
!   } else if (_begin != NULL) {
// copy our sux list
!     BlockList* sux = new BlockList(_begin->number_of_sux());
!     for (int i = 0; i < _begin->number_of_sux(); i++) {
!       sux->append(_begin->sux_at(i));
}
}
_sux = sux;
-   _begin = begin;
}

void BlockEnd::substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux) {
substitute(*_sux, old_sux, new_sux);
--- 986,1003 ----

void BlockEnd::set_begin(BlockBegin* begin) {
BlockList* sux = NULL;
if (begin != NULL) {
sux = begin->successors();
!   } else if (this->begin() != NULL) {
// copy our sux list
!     BlockList* sux = new BlockList(this->begin()->number_of_sux());
!     for (int i = 0; i < this->begin()->number_of_sux(); i++) {
!       sux->append(this->begin()->sux_at(i));
}
}
_sux = sux;
}

void BlockEnd::substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux) {
substitute(*_sux, old_sux, new_sux);
*** 1006,1015 ****
--- 1033,1073 ----
} else {
return _block->number_of_preds();
}
}

+ #ifndef PRODUCT

+ // Constructor of Assert
+ Assert::Assert(Value x, Condition cond, bool unordered_is_true, Value y) : Instruction(illegalType)
+   , _x(x)
+   , _cond(cond)
+   , _y(y)
+ {
+   set_flag(UnorderedIsTrueFlag, unordered_is_true);
+   assert(x->type()->tag() == y->type()->tag(), "types must match");
+   pin();
+
+   stringStream strStream;
+   Compilation::current()->method()->print_name(&strStream);
+
+   stringStream strStream1;
+   InstructionPrinter ip1(1, &strStream1);
+   ip1.print_instr(x);
+
+   stringStream strStream2;
+   InstructionPrinter ip2(1, &strStream2);
+   ip2.print_instr(y);
+
+   _message = new char[1024];
+   snprintf(_message, 1024, "Assertion %s %s %s in method %s", strStream1.as_string(), ip2.cond_name(cond), strStream2.as_string(), strStream.as_string());
+ }
+
+ #endif
+
+ void RangeCheckPredicate::check_state() {
+   assert(state()->kind() != ValueStack::EmptyExceptionState && state()->kind() != ValueStack::ExceptionState, "will deopt with empty state");
+ }

void ProfileInvoke::state_values_do(ValueVisitor* f) {
if (state() != NULL) state()->values_do(f);
}
```