Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(353)

Unified Diff: src/hydrogen-instructions.cc

Issue 14046017: Abcd for performance check. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/hydrogen-instructions.cc
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 36d1e11edab37c49aea9aa725866799eb28b83c6..ebff4de62fb55962358c1e35e00adc612e562be7 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -173,7 +173,7 @@ bool HValue::IsRelationTrue(NumericRelation relation,
HValue* other,
int offset,
int scale) {
- if (this == other) {
+ if (ActualValue() == other->ActualValue()) {
return scale == 0 && relation.IsExtendable(offset);
}
@@ -187,14 +187,54 @@ bool HValue::IsRelationTrue(NumericRelation relation,
return true;
}
- // Try decomposition (but do not accept scaled compounds).
+ // Try decomposition, but only if we are not scaled.
DecompositionResult decomposition;
- if (TryDecompose(&decomposition) &&
- decomposition.scale() == 0 &&
- decomposition.base()->IsRelationTrue(relation, other,
- offset + decomposition.offset(),
- scale)) {
- return true;
+ if (scale == 0 && TryDecompose(&decomposition)) {
+ // Check if the compound is scaled.
+ if (decomposition.scale() == 0) {
+ // Non-scaled compounds can be handled normally.
+ if (decomposition.base()->IsRelationTrue(
+ relation, other, offset + decomposition.offset(), scale)) {
+ return true;
+ }
+ } else if (decomposition.offset() == 0 && offset == 0) {
+ // We only have a scale value which means that we can apply chaining
+ // using relation extensibility: negative scales grow values (positive
+ // direction), positive scales make them smaller (negative direction).
+ // As a concrete example: "(x << 1) <= 0" <== "x <= 0".
+ int direction = decomposition.scale() > 0 ? -1 : 1;
Jakob Kummerow 2013/04/17 11:34:15 why not just "int direction = -decomposition.scale
Massi 2013/05/07 11:32:03 Done.
+ if (relation.IsExtendable(direction)
+ && decomposition.base()->IsRelationTrue(
Jakob Kummerow 2013/04/17 11:34:15 nit: '&&' on the previous line please
Massi 2013/05/07 11:32:03 Done.
+ relation, other, 0, 0)) {
Jakob Kummerow 2013/04/17 11:34:15 nit: fits on last line?
Massi 2013/05/07 11:32:03 Done.
+ return true;
+ }
+
+ } else {
+ // Just test for "same value" relation extensibility.
+
+ if (decomposition.base() == other) {
+ // The direction of the extensibility test is determined by scale and
+ // offset, but we can not handle all combinations.
+ int direction = 0;
+ // Do not accept left shifts greater than 1.
+ if (decomposition.scale() <= -1) {
+ if (decomposition.offset() == 0) {
+ // A positive scale makes values smaller.
+ direction = -decomposition.scale();
+ } else {
+ // If offset and scale have different signs they both go in the
+ // same direction, otherwise we cannot handle the combination.
+ if (decomposition.offset() * decomposition.scale() < 0) {
+ direction = offset;
+ }
+ }
+ }
+
+ if (direction != 0 && relation.IsExtendable(direction)) {
+ return true;
+ }
+ }
+ }
}
// Pass the request to the redefined value.
@@ -204,8 +244,13 @@ bool HValue::IsRelationTrue(NumericRelation relation,
}
-bool HValue::TryGuaranteeRange(HValue* upper_bound) {
- RangeEvaluationContext context = RangeEvaluationContext(this, upper_bound);
+bool HValue::TryGuaranteeRange(HValue* upper_bound,
+ HBasicBlock* starting_block_for_hoisting) {
+ if (starting_block_for_hoisting == NULL) {
+ starting_block_for_hoisting = block();
+ }
+ RangeEvaluationContext context = RangeEvaluationContext(
+ this, upper_bound, starting_block_for_hoisting);
TryGuaranteeRangeRecursive(&context);
bool result = context.is_range_satisfied();
if (result) {
@@ -259,8 +304,11 @@ void HValue::TryGuaranteeRangeRecursive(RangeEvaluationContext* context) {
}
-RangeEvaluationContext::RangeEvaluationContext(HValue* value, HValue* upper)
- : lower_bound_(upper->block()->graph()->GetConstant0()),
+RangeEvaluationContext::RangeEvaluationContext(HValue* value,
+ HValue* upper,
+ HBasicBlock* starting_block)
+ : starting_block_(starting_block),
+ lower_bound_(upper->block()->graph()->GetConstant0()),
lower_bound_guarantee_(NULL),
candidate_(value),
upper_bound_(upper),
@@ -932,7 +980,8 @@ HNumericConstraint* HNumericConstraint::AddToGraph(
HValue* constrained_value,
NumericRelation relation,
HValue* related_value,
- HInstruction* insertion_point) {
+ HInstruction* insertion_point,
+ HBasicBlock* other_block) {
if (insertion_point == NULL) {
if (constrained_value->IsInstruction()) {
insertion_point = HInstruction::cast(constrained_value);
@@ -944,7 +993,7 @@ HNumericConstraint* HNumericConstraint::AddToGraph(
}
HNumericConstraint* result =
new(insertion_point->block()->zone()) HNumericConstraint(
- constrained_value, relation, related_value);
+ constrained_value, relation, related_value, other_block);
result->InsertAfter(insertion_point);
return result;
}
@@ -963,14 +1012,104 @@ HInductionVariableAnnotation* HInductionVariableAnnotation::AddToGraph(
HPhi* phi,
NumericRelation relation,
int operand_index) {
- HInductionVariableAnnotation* result =
- new(phi->block()->zone()) HInductionVariableAnnotation(phi, relation,
- operand_index);
+ HInductionVariableAnnotation* result = new(phi->block()->zone())
+ HInductionVariableAnnotation(phi, relation, operand_index,
+ phi->block()->zone());
result->InsertAfter(phi->block()->first());
return result;
}
+void HInductionVariableAnnotation::AddHoistedCheck(HBoundsCheck* check) {
+ hoisted_checks_.Add(check, block()->zone());
+}
+
+
+HInductionVariableAnnotation::HInductionVariableAnnotation(
+ HPhi* phi,
+ NumericRelation relation,
+ int operand_index,
+ Zone* zone)
+ : HUnaryOperation(phi), phi_(phi), relation_(relation),
Jakob Kummerow 2013/04/17 11:34:15 nit: one line per initializer, please
Massi 2013/05/07 11:32:03 Done.
+ operand_index_(operand_index), hoisted_checks_(4, zone) {
+}
+
+
+void HInductionVariableAnnotation::TryGuaranteeRangeChanging(
+ RangeEvaluationContext* context) {
+ if (relation().IsExtendable(1)) {
+ if (context->lower_bound_guarantee() == NULL) return;
+ } else {
+ return;
+ }
+
+ for (int i = 0; i < hoisted_checks()->length(); i++) {
+ HBoundsCheck* hoisted_check = hoisted_checks()->at(i);
+ if (hoisted_check->length()->ActualValue()
+ == context->upper_bound()->ActualValue()) {
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
+ context->set_upper_bound_guarantee(hoisted_check);
+ return;
+ }
+ }
+
+ HBasicBlock* starting_block = context->starting_block();
+ HLoopInformation* starting_loop = starting_block->current_loop();
+ if (starting_loop == NULL) return;
+ HLoopInformation* my_loop = block()->current_loop();
+ if (my_loop == NULL) return;
+ if (my_loop->exits_count() > 1
+ && !block()->graph()->use_optimistic_licm()) return;
Jakob Kummerow 2013/04/17 11:34:15 If it doesn't make a significant difference, I'd r
+
+ bool starting_loop_is_nested_in_my_loop = false;
Jakob Kummerow 2013/04/17 11:34:15 we can make this loop a little simpler: // See
+ while (starting_loop != NULL) {
+ if (starting_loop == my_loop) {
+ starting_loop_is_nested_in_my_loop = true;
+ break;
+ }
+ starting_loop = starting_loop->parent_loop();
+ }
+ if (!starting_loop_is_nested_in_my_loop) return;
+ starting_loop = starting_block->current_loop();
+
+ for (HValue* candidate = context->candidate();
+ candidate != NULL;
+ candidate = candidate->RedefinedOperand()) {
+ if (candidate->IsNumericConstraint()) {
Jakob Kummerow 2013/04/17 11:34:15 for consistency with code below, I'd transform thi
Massi 2013/05/07 11:32:03 Done.
+ HNumericConstraint* constraint = HNumericConstraint::cast(candidate);
+ if (!constraint->relation().IsExtendable(-1)) continue;
+ HLoopInformation* other_loop = constraint->other_block()->current_loop();
+ if (other_loop == my_loop) continue;
+
+ HBasicBlock* my_header = my_loop->loop_header();
+ HBasicBlock* my_pre_header = my_header->predecessors()->at(0);
+
+ HValue* induction_limit = constraint->related_value()->ActualValue();
+ HValue* upper_bound = context->upper_bound()->ActualValue();
+
+ if (induction_limit->block() != my_pre_header
+ && !induction_limit->block()->Dominates(my_pre_header)) continue;
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
+ if (upper_bound->block() != my_pre_header
+ && !upper_bound->block()->Dominates(my_pre_header)) continue;
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
+
+ if (!(induction_limit->representation().Equals(
+ upper_bound->representation())
+ || induction_limit->IsInteger32Constant())) {
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
+ continue;
+ }
+
+ HBoundsCheck* check = new(block()->zone()) HBoundsCheck(
+ induction_limit, upper_bound);
+ check->InsertBefore(my_pre_header->end());
+ check->set_allow_equality(true);
+ check->UpdateRedefinedUses();
+ AddHoistedCheck(check);
+ context->set_upper_bound_guarantee(check);
+ return;
+ }
+ }
+}
+
+
void HInductionVariableAnnotation::PrintDataTo(StringStream* stream) {
stream->Add("(");
RedefinedOperand()->PrintNameTo(stream);
@@ -1007,13 +1146,37 @@ void HBoundsCheck::TryGuaranteeRangeChanging(RangeEvaluationContext* context) {
return;
}
+ if (context->lower_bound_guarantee() != NULL &&
+ context->lower_bound_guarantee() != this) {
+ if (context->lower_bound_guarantee()->IsBoundsCheck()) {
+ HBoundsCheck* guarantee = HBoundsCheck::cast(
+ context->lower_bound_guarantee());
+ if (guarantee->base()->ActualValue() == base()->ActualValue()
+ && guarantee->scale() == scale()
+ && guarantee->offset() > offset()) {
+ context->set_lower_bound_guarantee(this);
+ }
+ }
+ } else if (context->upper_bound_guarantee() != NULL &&
Jakob Kummerow 2013/04/17 11:34:15 I think the "else" needs to be removed.
Massi 2013/05/07 11:32:03 Done.
Massi 2013/05/07 11:32:03 Done.
+ context->upper_bound_guarantee() != this) {
+ if (context->upper_bound_guarantee()->IsBoundsCheck()) {
+ HBoundsCheck* guarantee = HBoundsCheck::cast(
+ context->upper_bound_guarantee());
+ if (guarantee->base()->ActualValue() == base()->ActualValue()
+ && guarantee->scale() == scale()
+ && guarantee->offset() < offset()) {
+ context->set_upper_bound_guarantee(this);
+ }
+ }
+ }
+
// TODO(mmassi)
// Instead of checking for "same basic block" we should check for
// "dominates and postdominates".
if (context->upper_bound() == length() &&
context->lower_bound_guarantee() != NULL &&
context->lower_bound_guarantee() != this &&
- context->lower_bound_guarantee()->block() != block() &&
+ context->lower_bound_guarantee()->block() == block() &&
offset() < context->offset() &&
index_can_increase() &&
context->upper_bound_guarantee() == NULL) {
@@ -1022,7 +1185,7 @@ void HBoundsCheck::TryGuaranteeRangeChanging(RangeEvaluationContext* context) {
context->set_upper_bound_guarantee(this);
} else if (context->upper_bound_guarantee() != NULL &&
context->upper_bound_guarantee() != this &&
- context->upper_bound_guarantee()->block() != block() &&
+ context->upper_bound_guarantee()->block() == block() &&
offset() > context->offset() &&
index_can_decrease() &&
context->lower_bound_guarantee() == NULL) {
@@ -1034,7 +1197,7 @@ void HBoundsCheck::TryGuaranteeRangeChanging(RangeEvaluationContext* context) {
void HBoundsCheck::ApplyIndexChange() {
- if (skip_check()) return;
+ if (skip_check() || base() == NULL) return;
DecompositionResult decomposition;
bool index_is_decomposable = index()->TryDecompose(&decomposition);
@@ -1049,12 +1212,10 @@ void HBoundsCheck::ApplyIndexChange() {
ReplaceAllUsesWith(index());
HValue* current_index = decomposition.base();
- int actual_offset = decomposition.offset() + offset();
- int actual_scale = decomposition.scale() + scale();
- if (actual_offset != 0) {
+ if (offset() != 0) {
HConstant* add_offset = new(block()->graph()->zone()) HConstant(
- actual_offset, index()->representation());
+ offset(), index()->representation());
add_offset->InsertBefore(this);
HInstruction* add = HAdd::New(block()->graph()->zone(),
block()->graph()->GetInvalidContext(), current_index, add_offset);
@@ -1063,9 +1224,9 @@ void HBoundsCheck::ApplyIndexChange() {
current_index = add;
}
- if (actual_scale != 0) {
+ if (scale() != 0) {
HConstant* sar_scale = new(block()->graph()->zone()) HConstant(
- actual_scale, index()->representation());
+ scale(), index()->representation());
sar_scale->InsertBefore(this);
HInstruction* sar = HSar::New(block()->graph()->zone(),
block()->graph()->GetInvalidContext(), current_index, sar_scale);
@@ -1087,7 +1248,7 @@ void HBoundsCheck::AddInformativeDefinitions() {
// TODO(mmassi): Executing this code during AddInformativeDefinitions
// is a hack. Move it to some other HPhase.
if (FLAG_array_bounds_checks_elimination) {
- if (index()->TryGuaranteeRange(length())) {
+ if (index()->TryGuaranteeRange(length(), block())) {
set_skip_check(true);
}
if (DetectCompoundIndex()) {
@@ -1163,6 +1324,8 @@ bool HBoundsCheckBaseIndexInformation::IsRelationTrueInternal(
HValue* related_value,
int offset,
int scale) {
+ if (bounds_check() == NULL) return false;
+
if (related_value == bounds_check()->length()) {
return NumericRelation::Lt().CompoundImplies(
relation,
@@ -1181,7 +1344,12 @@ void HBoundsCheckBaseIndexInformation::PrintDataTo(StringStream* stream) {
stream->Add("base: ");
base_index()->PrintNameTo(stream);
stream->Add(", check: ");
- base_index()->PrintNameTo(stream);
+ if (bounds_check() != NULL) {
+ bounds_check()->PrintNameTo(stream);
+ } else {
+ stream->Add("DISCONNECTED ");
+ OperandAt(1)->PrintNameTo(stream);
+ }
}
@@ -2344,9 +2512,10 @@ void HCompareIDAndBranch::AddInformativeDefinitions() {
NumericRelation r = NumericRelation::FromToken(token());
if (r.IsNone()) return;
- HNumericConstraint::AddToGraph(left(), r, right(), SuccessorAt(0)->first());
HNumericConstraint::AddToGraph(
- left(), r.Negated(), right(), SuccessorAt(1)->first());
+ left(), r, right(), SuccessorAt(0)->first(), SuccessorAt(1));
+ HNumericConstraint::AddToGraph(
+ left(), r.Negated(), right(), SuccessorAt(1)->first(), SuccessorAt(0));
}
@@ -3038,6 +3207,40 @@ HValue* HAdd::EnsureAndPropagateNotMinusZero(BitVector* visited) {
}
+bool HAdd::IsRelationTrueInternal(NumericRelation relation,
+ HValue* other,
+ int offset,
+ int scale) {
+ if (offset != 0 || scale != 0) return false;
+
+ // We look for a pattern like "x + delta rel x", where we should return
+ // true if "delta >= 0 && rel.IsExtendable(1)" or
+ // "delta <= 0 && rel.IsExtendable(-1)".
+ HValue* delta = NULL;
+ if (left()->ActualValue() == other->ActualValue()) {
+ delta = right();
+ } else if (right()->ActualValue() == other->ActualValue()) {
+ delta = left();
+ } else {
+ return false;
+ }
+
+ if (relation.IsExtendable(1)
+ && delta->IsRelationTrue(NumericRelation::Ge(),
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
+ block()->graph()->GetConstant0())) {
+ return true;
+ }
+
+ if (relation.IsExtendable(-1)
+ && delta->IsRelationTrue(NumericRelation::Le(),
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
+ block()->graph()->GetConstant0())) {
+ return true;
+ }
+
+ return false;
+}
+
+
bool HStoreKeyed::NeedsCanonicalization() {
// If value is an integer or smi or comes from the result of a keyed load or
// constant then it is either be a non-hole value or in the case of a constant

Powered by Google App Engine
This is Rietveld 408576698