mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-21 16:59:41 +01:00
8314468: Improve Compiler loops
Reviewed-by: jwilhelm, epeter Backport-of: 86e71472aefc26175cfc00d44f255f64893e477b
This commit is contained in:
@@ -404,8 +404,11 @@ void RangeCheckEliminator::add_access_indexed_info(InstructionList &indices, int
|
||||
aii->_max = idx;
|
||||
aii->_list = new AccessIndexedList();
|
||||
} else if (idx >= aii->_min && idx <= aii->_max) {
|
||||
remove_range_check(ai);
|
||||
return;
|
||||
// Guard against underflow/overflow (see 'range_cond' check in RangeCheckEliminator::in_block_motion)
|
||||
if (aii->_max < 0 || (aii->_max + min_jint) <= aii->_min) {
|
||||
remove_range_check(ai);
|
||||
return;
|
||||
}
|
||||
}
|
||||
aii->_min = MIN2(aii->_min, idx);
|
||||
aii->_max = MAX2(aii->_max, idx);
|
||||
@@ -448,9 +451,9 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int last_integer = 0;
|
||||
jint last_integer = 0;
|
||||
Instruction *last_instruction = index;
|
||||
int base = 0;
|
||||
jint base = 0;
|
||||
ArithmeticOp *ao = index->as_ArithmeticOp();
|
||||
|
||||
while (ao != nullptr && (ao->x()->as_Constant() || ao->y()->as_Constant()) && (ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub)) {
|
||||
@@ -462,12 +465,12 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
|
||||
}
|
||||
|
||||
if (c) {
|
||||
int value = c->type()->as_IntConstant()->value();
|
||||
jint value = c->type()->as_IntConstant()->value();
|
||||
if (value != min_jint) {
|
||||
if (ao->op() == Bytecodes::_isub) {
|
||||
value = -value;
|
||||
}
|
||||
base += value;
|
||||
base = java_add(base, value);
|
||||
last_integer = base;
|
||||
last_instruction = other;
|
||||
}
|
||||
@@ -489,12 +492,12 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
|
||||
assert(info != nullptr, "Info must not be null");
|
||||
|
||||
// if idx < 0, max > 0, max + idx may fall between 0 and
|
||||
// length-1 and if min < 0, min + idx may overflow and be >=
|
||||
// length-1 and if min < 0, min + idx may underflow/overflow and be >=
|
||||
// 0. The predicate wouldn't trigger but some accesses could
|
||||
// be with a negative index. This test guarantees that for the
|
||||
// min and max value that are kept the predicate can't let
|
||||
// some incorrect accesses happen.
|
||||
bool range_cond = (info->_max < 0 || info->_max + min_jint <= info->_min);
|
||||
bool range_cond = (info->_max < 0 || (info->_max + min_jint) <= info->_min);
|
||||
|
||||
// Generate code only if more than 2 range checks can be eliminated because of that.
|
||||
// 2 because at least 2 comparisons are done
|
||||
@@ -843,7 +846,7 @@ void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, Block
|
||||
);
|
||||
|
||||
remove_range_check(ai);
|
||||
} else if (_optimistic && loop_header) {
|
||||
} else if (false && _optimistic && loop_header) {
|
||||
assert(ai->array(), "Array must not be null!");
|
||||
assert(ai->index(), "Index must not be null!");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user