7153771: array bound check elimination for c1

When possible optimize out array bound checks, inserting predicates when needed.

Reviewed-by: never, kvn, twisti
This commit is contained in:
Thomas Wuerthinger 2013-03-21 09:27:54 +01:00 committed by Roland Westrelin
parent 2f4ecb86a2
commit 06ef4cddf7
40 changed files with 2861 additions and 153 deletions

View file

@ -947,7 +947,9 @@ void GraphBuilder::store_local(ValueStack* state, Value x, int index) {
void GraphBuilder::load_indexed(BasicType type) {
ValueStack* state_before = copy_state_for_exception();
// In case of in block code motion in range check elimination
ValueStack* state_before = copy_state_indexed_access();
compilation()->set_has_access_indexed(true);
Value index = ipop();
Value array = apop();
Value length = NULL;
@ -961,7 +963,9 @@ void GraphBuilder::load_indexed(BasicType type) {
void GraphBuilder::store_indexed(BasicType type) {
ValueStack* state_before = copy_state_for_exception();
// In case of in block code motion in range check elimination
ValueStack* state_before = copy_state_indexed_access();
compilation()->set_has_access_indexed(true);
Value value = pop(as_ValueType(type));
Value index = ipop();
Value array = apop();
@ -1179,7 +1183,9 @@ void GraphBuilder::if_node(Value x, If::Condition cond, Value y, ValueStack* sta
BlockBegin* tsux = block_at(stream()->get_dest());
BlockBegin* fsux = block_at(stream()->next_bci());
bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci();
Instruction *i = append(new If(x, cond, false, y, tsux, fsux, is_bb ? state_before : NULL, is_bb));
// In case of loop invariant code motion or predicate insertion
// before the body of a loop the state is needed
Instruction *i = append(new If(x, cond, false, y, tsux, fsux, (is_bb || compilation()->is_optimistic()) ? state_before : NULL, is_bb));
assert(i->as_Goto() == NULL ||
(i->as_Goto()->sux_at(0) == tsux && i->as_Goto()->is_safepoint() == tsux->bci() < stream()->cur_bci()) ||
@ -1294,7 +1300,9 @@ void GraphBuilder::table_switch() {
BlockBegin* tsux = block_at(bci() + sw.dest_offset_at(0));
BlockBegin* fsux = block_at(bci() + sw.default_offset());
bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
ValueStack* state_before = is_bb ? copy_state_before() : NULL;
// In case of loop invariant code motion or predicate insertion
// before the body of a loop the state is needed
ValueStack* state_before = copy_state_if_bb(is_bb);
append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
} else {
// collect successors
@ -1308,7 +1316,9 @@ void GraphBuilder::table_switch() {
// add default successor
if (sw.default_offset() < 0) has_bb = true;
sux->at_put(i, block_at(bci() + sw.default_offset()));
ValueStack* state_before = has_bb ? copy_state_before() : NULL;
// In case of loop invariant code motion or predicate insertion
// before the body of a loop the state is needed
ValueStack* state_before = copy_state_if_bb(has_bb);
Instruction* res = append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb));
#ifdef ASSERT
if (res->as_Goto()) {
@ -1336,7 +1346,9 @@ void GraphBuilder::lookup_switch() {
BlockBegin* tsux = block_at(bci() + pair.offset());
BlockBegin* fsux = block_at(bci() + sw.default_offset());
bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
ValueStack* state_before = is_bb ? copy_state_before() : NULL;
// In case of loop invariant code motion or predicate insertion
// before the body of a loop the state is needed
ValueStack* state_before = copy_state_if_bb(is_bb);;
append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
} else {
// collect successors & keys
@ -1353,7 +1365,9 @@ void GraphBuilder::lookup_switch() {
// add default successor
if (sw.default_offset() < 0) has_bb = true;
sux->at_put(i, block_at(bci() + sw.default_offset()));
ValueStack* state_before = has_bb ? copy_state_before() : NULL;
// In case of loop invariant code motion or predicate insertion
// before the body of a loop the state is needed
ValueStack* state_before = copy_state_if_bb(has_bb);
Instruction* res = append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
#ifdef ASSERT
if (res->as_Goto()) {