VM: Fix issue with optimizing compiler's range analysis.

Narrowing of ranges should only occur if the new range is actually
narrower than the old range. It can happen that a symbolic range
is worse than the already computed one. Ignore the new range in this
case.

BUG=dartbug.com/23693
R=vegorov@google.com

Review URL: https://codereview.chromium.org//1219623004.
This commit is contained in:
Florian Schneider 2015-06-29 16:14:06 +02:00
parent 4f8d7b42d2
commit 5daa5646ef
2 changed files with 5 additions and 11 deletions

View file

@ -27,9 +27,7 @@ namespace dart {
DEFINE_FLAG(int, getter_setter_ratio, 13,
"Ratio of getter/setter usage used for double field unboxing heuristics");
// Setting 'guess_other_cid' to true causes issue 23693 crash.
// TODO(srdjan): Evaluate if that optimization is wrong.
DEFINE_FLAG(bool, guess_other_cid, false,
DEFINE_FLAG(bool, guess_other_cid, true,
"Artificially create type feedback for arithmetic etc. operations"
" by guessing the other unknown argument cid");
DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination.");
@ -197,8 +195,6 @@ bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) {
Token::IsBinaryOperator(op_kind)) {
// Guess cid: if one of the inputs is a number assume that the other
// is a number of same type.
// Issue 23693. It is potentially wrong to assign types here that may
// conflict with other graph analysis.
if (FLAG_guess_other_cid) {
const intptr_t cid_0 = class_ids[0];
const intptr_t cid_1 = class_ids[1];

View file

@ -621,11 +621,10 @@ static RangeBoundary WidenMax(const Range* range,
static RangeBoundary NarrowMin(const Range* range,
const Range* new_range,
RangeBoundary::RangeSize size) {
#ifdef DEBUG
const RangeBoundary min = Range::ConstantMin(range, size);
const RangeBoundary new_min = Range::ConstantMin(new_range, size);
ASSERT(min.ConstantValue() <= new_min.ConstantValue());
#endif
if (min.ConstantValue() > new_min.ConstantValue()) return range->min();
// TODO(vegorov): consider using negative infinity to indicate widened bound.
return range->min().IsMinimumOrBelow(size) ? new_range->min() : range->min();
}
@ -640,11 +639,10 @@ static RangeBoundary NarrowMin(const Range* range,
static RangeBoundary NarrowMax(const Range* range,
const Range* new_range,
RangeBoundary::RangeSize size) {
#ifdef DEBUG
const RangeBoundary max = Range::ConstantMax(range, size);
const RangeBoundary new_max = Range::ConstantMax(new_range, size);
ASSERT(max.ConstantValue() >= new_max.ConstantValue());
#endif
if (max.ConstantValue() < new_max.ConstantValue()) return range->max();
// TODO(vegorov): consider using positive infinity to indicate widened bound.
return range->max().IsMaximumOrAbove(size) ? new_range->max() : range->max();
}