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

Unified Diff: src/hydrogen-instructions.h

Issue 14046017: Abcd for performance check. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes and speedups in induction variable detection. Created 7 years, 7 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.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 7acec8bcd5ebc3e2e0757d312ee591f5e5174e72..b99437e13f8c09e74aa154811af88e5290623a5b 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -649,6 +649,23 @@ class NumericRelation {
return false;
}
+ // The semantics of "ImpliedByEquality" is that if
+ // "rel.ImpliedByEquality(offset)" is true then
+ // "x == y" implies "(x + offset) rel y" .
+ bool ImpliedByEquality(int offset) {
+ switch (kind_) {
+ case NONE: return false;
+ case EQ: return (offset == 0);
+ case GT: return (offset > 0);
+ case GE: return (offset >= 0);
+ case LT: return (offset < 0);
+ case LE: return (offset <= 0);
+ case NE: return false;
+ }
+ UNREACHABLE();
+ return false;
+ }
+
// The semantics of "IsExtendable" is that if
// "rel.IsExtendable(direction)" is true then
// "x rel y" implies "(x + direction) rel y" .
@@ -678,6 +695,47 @@ class NumericRelation {
my_offset, my_scale, other_offset, other_scale);
}
+ // CanBeChained returns true when
+ // "((x + offset) >> scale) rel limit" and "x other_relation y" imply
+ // "((y + offset) >> scale) rel limit".
+ // In other words, rel and other_relation go "in the same direction"
+ // and therefore can be "chained".
+ bool CanBeChained(NumericRelation other_relation) {
+ switch (kind_) {
+ case NONE: return false;
+ case EQ: return (other_relation.kind_ == EQ);
+ case GT:
+ case GE:
+ return (other_relation.kind_ == GT) || (other_relation.kind_ == GE);
+ case LT:
+ case LE:
+ return (other_relation.kind_ == LT) || (other_relation.kind_ == LE);
+ case NE: return false;
+ }
+ UNREACHABLE();
+ return false;
+ }
+
+ bool ApplyToValues(int32_t value, int32_t other_value) {
+ switch (kind_) {
+ case NONE: return false;
+ case EQ: return value == other_value;
+ case GT: return value > other_value;
+ case GE: return value >= other_value;
+ case LT: return value < other_value;
+ case LE: return value <= other_value;
+ case NE: return value != other_value;
+ }
+ UNREACHABLE();
+ return false;
+ }
+
+ int Compare(NumericRelation other) {
+ int my_value = static_cast<int>(kind_);
+ int other_value = static_cast<int>(other.kind_);
+ return my_value - other_value;
+ }
+
private:
// ComponentsImply returns true when
// "((x + my_offset) >> my_scale) rel y" implies
@@ -752,8 +810,11 @@ class DecompositionResult BASE_EMBEDDED {
class RangeEvaluationContext BASE_EMBEDDED {
public:
- RangeEvaluationContext(HValue* value, HValue* upper);
+ RangeEvaluationContext(HValue* value,
+ HValue* upper,
+ HBasicBlock* starting_block);
+ HBasicBlock* starting_block() { return starting_block_; }
HValue* lower_bound() { return lower_bound_; }
HValue* lower_bound_guarantee() { return lower_bound_guarantee_; }
HValue* candidate() { return candidate_; }
@@ -780,6 +841,7 @@ class RangeEvaluationContext BASE_EMBEDDED {
private:
HValue* ConvertGuarantee(HValue* guarantee);
+ HBasicBlock* starting_block_;
HValue* lower_bound_;
HValue* lower_bound_guarantee_;
HValue* candidate_;
@@ -790,6 +852,101 @@ class RangeEvaluationContext BASE_EMBEDDED {
};
+class NumericRelationTableElement {
+ public:
+ int value_id() const { return value_id_; }
+ NumericRelation relation() const { return relation_; }
+ int other_value_id() const { return other_value_id_; }
+ int offset() const { return offset_; }
+ int scale() const { return scale_; }
+ int block_id() const { return block_id_; }
+ bool result() const { return result_; }
+
+ NumericRelationTableElement(int value_id,
+ NumericRelation relation,
+ int other_value_id,
+ int offset,
+ int scale,
+ int block_id,
+ bool result) :
Jakob Kummerow 2013/05/15 12:56:35 nit: colon goes on the next line, with 4 spaces of
Massi 2013/05/21 12:49:56 Done.
+ value_id_(value_id),
+ relation_(relation),
+ other_value_id_(other_value_id),
+ offset_(offset),
+ scale_(scale),
+ block_id_(block_id),
+ result_(result) {}
+
+ NumericRelationTableElement(const NumericRelationTableElement& other) :
Jakob Kummerow 2013/05/15 12:56:35 nit: same here
Massi 2013/05/21 12:49:56 Done.
+ value_id_(other.value_id()),
+ relation_(other.relation()),
+ other_value_id_(other.other_value_id()),
+ offset_(other.offset()),
+ scale_(other.scale()),
+ block_id_(other.block_id()),
+ result_(other.result()) {}
+
+ int Compare(const NumericRelationTableElement& other) const {
+ int result = Comparator(value_id(), other.value_id());
+ if (result != 0) return result;
+ result = relation().Compare(other.relation());
+ if (result != 0) return result;
+ result = Comparator(other_value_id(), other.other_value_id());
+ if (result != 0) return result;
+ result = Comparator(offset(), other.offset());
+ if (result != 0) return result;
+ result = Comparator(block_id(), other.block_id());
+ if (result != 0) return result;
+ return Comparator(scale(), other.scale());
+ }
+
+ private:
+ static int Comparator(int value, int other_value) {
+ return value - other_value;
+ }
+
+ int value_id_;
+ NumericRelation relation_;
+ int other_value_id_;
+ int offset_;
+ int scale_;
+ int block_id_;
+ bool result_;
+};
+
+
+class NumericRelationTable {
+ public:
+ bool IsInTable(int value_id,
+ NumericRelation relation,
+ int other_value_id,
+ int offset,
+ int scale,
+ int block_id,
+ bool* result);
+
+ void AddToTable(int value_id,
+ NumericRelation relation,
+ int other_value_id,
+ int offset,
+ int scale,
+ int block_id,
+ bool result);
+
+ void Clear();
+
+ explicit NumericRelationTable(Zone* zone) : table_(8, zone), zone_(zone) {}
+
+ private:
+ int FindInsertionPoint(const NumericRelationTableElement& element,
+ bool* result);
+ void Insert(const NumericRelationTableElement& element, int index);
+
+ ZoneList<NumericRelationTableElement> table_;
+ Zone* zone_;
+};
+
+
typedef EnumSet<GVNFlag> GVNFlagSet;
@@ -1100,7 +1257,8 @@ class HValue: public ZoneObject {
int offset = 0,
int scale = 0);
- bool TryGuaranteeRange(HValue* upper_bound);
+ bool TryGuaranteeRange(HValue* upper_bound,
+ HBasicBlock* starting_block_for_hoisting = NULL);
virtual bool TryDecompose(DecompositionResult* decomposition) {
if (RedefinedOperand() != NULL) {
return RedefinedOperand()->TryDecompose(decomposition);
@@ -1110,6 +1268,10 @@ class HValue: public ZoneObject {
}
protected:
+ bool EvaluateRelationRecursively(NumericRelation relation,
+ HValue* other,
+ int offset = 0,
+ int scale = 0);
void TryGuaranteeRangeRecursive(RangeEvaluationContext* context);
enum RangeGuaranteeDirection {
@@ -1419,14 +1581,17 @@ class HDummyUse: public HTemplateInstruction<1> {
class HNumericConstraint : public HTemplateInstruction<2> {
public:
- static HNumericConstraint* AddToGraph(HValue* constrained_value,
- NumericRelation relation,
- HValue* related_value,
- HInstruction* insertion_point = NULL);
+ static HNumericConstraint* AddToGraph(
+ HValue* constrained_value,
+ NumericRelation relation,
+ HValue* related_value,
+ HInstruction* insertion_point = NULL,
+ HBasicBlock* jump_target_when_false = NULL);
HValue* constrained_value() { return OperandAt(0); }
HValue* related_value() { return OperandAt(1); }
NumericRelation relation() { return relation_; }
+ HBasicBlock* jump_target_when_false() { return jump_target_when_false_; }
virtual int RedefinedOperandIndex() { return 0; }
virtual bool IsPurelyInformativeDefinition() { return true; }
@@ -1444,7 +1609,12 @@ class HNumericConstraint : public HTemplateInstruction<2> {
if (related_value() == other_related_value) {
return relation().CompoundImplies(other_relation, offset, scale);
} else {
- return false;
+ if (relation().CanBeChained(other_relation)) {
+ return related_value()->IsRelationTrue(
+ other_relation, other_related_value, offset, scale);
+ } else {
+ return false;
+ }
}
}
@@ -1453,13 +1623,15 @@ class HNumericConstraint : public HTemplateInstruction<2> {
private:
HNumericConstraint(HValue* constrained_value,
NumericRelation relation,
- HValue* related_value)
- : relation_(relation) {
+ HValue* related_value,
+ HBasicBlock* jump_target_when_false)
+ : relation_(relation), jump_target_when_false_(jump_target_when_false) {
SetOperandAt(0, constrained_value);
SetOperandAt(1, related_value);
}
NumericRelation relation_;
+ HBasicBlock* jump_target_when_false_;
};
@@ -3101,6 +3273,9 @@ class HPhi: public HValue {
};
+class HBoundsCheck;
+
+
class HInductionVariableAnnotation : public HUnaryOperation {
public:
static HInductionVariableAnnotation* AddToGraph(HPhi* phi,
@@ -3116,6 +3291,7 @@ class HInductionVariableAnnotation : public HUnaryOperation {
return representation();
}
+ virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
virtual void PrintDataTo(StringStream* stream);
virtual bool IsRelationTrueInternal(NumericRelation other_relation,
@@ -3125,19 +3301,27 @@ class HInductionVariableAnnotation : public HUnaryOperation {
if (induction_base() == other_related_value) {
return relation().CompoundImplies(other_relation, offset, scale);
} else {
- return false;
+ if (relation().CanBeChained(other_relation)) {
+ return induction_base()->IsRelationTrue(
+ other_relation, other_related_value, offset, scale);
+ } else {
+ return false;
+ }
}
}
+ const ZoneList<HBoundsCheck*>* hoisted_checks() const {
+ return &hoisted_checks_;
+ }
+ void AddHoistedCheck(HBoundsCheck* check);
+
DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation)
private:
HInductionVariableAnnotation(HPhi* phi,
NumericRelation relation,
- int operand_index)
- : HUnaryOperation(phi),
- phi_(phi), relation_(relation), operand_index_(operand_index) {
- }
+ int operand_index,
+ Zone* zone);
// We need to store the phi both here and in the instruction operand because
// the operand can change if a new idef of the phi is added between the phi
@@ -3145,6 +3329,7 @@ class HInductionVariableAnnotation : public HUnaryOperation {
HPhi* phi_;
NumericRelation relation_;
int operand_index_;
+ ZoneList<HBoundsCheck*> hoisted_checks_;
};
@@ -3292,6 +3477,20 @@ class HConstant: public HTemplateInstruction<0> {
return HasInteger32Value() && (Integer32Value() >= 0);
}
+ virtual bool IsRelationTrueInternal(NumericRelation relation,
+ HValue* related_value,
+ int offset = 0,
+ int scale = 0) {
+ if (HasInteger32Value() &&
+ related_value->IsInteger32Constant()) {
+ int32_t value = (Integer32Value() + offset) >> scale;
+ int32_t other_value = related_value->GetInteger32Constant();
+ return relation.ApplyToValues(value, other_value);
+ } else {
+ return false;
+ }
+ }
+
virtual intptr_t Hashcode() {
ASSERT_ALLOCATION_DISABLED;
intptr_t hash;
@@ -3575,7 +3774,8 @@ class HBoundsCheck: public HTemplateInstruction<2> {
Representation r = Representation::None())
: key_mode_(key_mode), skip_check_(false),
base_(NULL), offset_(0), scale_(0),
- responsibility_direction_(DIRECTION_NONE) {
+ responsibility_direction_(DIRECTION_NONE),
+ allow_equality_(false) {
SetOperandAt(0, index);
SetOperandAt(1, length);
if (r.IsNone()) {
@@ -3590,8 +3790,11 @@ class HBoundsCheck: public HTemplateInstruction<2> {
SetFlag(kUseGVN);
}
- bool skip_check() { return skip_check_; }
- void set_skip_check(bool skip_check) { skip_check_ = skip_check; }
+ bool skip_check() const { return skip_check_; }
+ void set_skip_check() {
+ isolate()->counters()->bounds_checks_removed()->Increment();
+ skip_check_ = true;
+ }
HValue* base() { return base_; }
int offset() { return offset_; }
int scale() { return scale_; }
@@ -3626,6 +3829,9 @@ class HBoundsCheck: public HTemplateInstruction<2> {
virtual Representation observed_input_representation(int index) {
return Representation::Integer32();
}
+ virtual bool IsDeletable() const {
+ return skip_check();
+ }
virtual bool IsRelationTrueInternal(NumericRelation relation,
HValue* related_value,
@@ -3637,6 +3843,8 @@ class HBoundsCheck: public HTemplateInstruction<2> {
HValue* index() { return OperandAt(0); }
HValue* length() { return OperandAt(1); }
+ bool allow_equality() { return allow_equality_; }
+ void set_allow_equality(bool v) { allow_equality_ = v; }
virtual int RedefinedOperandIndex() { return 0; }
virtual bool IsPurelyInformativeDefinition() { return skip_check(); }
@@ -3660,6 +3868,7 @@ class HBoundsCheck: public HTemplateInstruction<2> {
int offset_;
int scale_;
RangeGuaranteeDirection responsibility_direction_;
+ bool allow_equality_;
};
@@ -3676,7 +3885,10 @@ class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> {
}
HValue* base_index() { return OperandAt(0); }
- HBoundsCheck* bounds_check() { return HBoundsCheck::cast(OperandAt(1)); }
+ HBoundsCheck* bounds_check() {
+ return OperandAt(1)->IsBoundsCheck()
+ ? HBoundsCheck::cast(OperandAt(1)) : NULL;
+ }
DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation)
@@ -4304,6 +4516,11 @@ class HAdd: public HArithmeticBinaryOperation {
}
}
+ virtual bool IsRelationTrueInternal(NumericRelation relation,
+ HValue* other,
+ int offset = 0,
+ int scale = 0);
+
DECLARE_CONCRETE_INSTRUCTION(Add)
protected:
@@ -4548,6 +4765,20 @@ class HShl: public HBitwiseBinaryOperation {
HValue* left,
HValue* right);
+ virtual bool TryDecompose(DecompositionResult* decomposition) {
+ if (right()->IsInteger32Constant() &&
+ right()->GetInteger32Constant() <= 1 &&
+ right()->GetInteger32Constant() >= 0) {
+ if (decomposition->Apply(left(), 0, - right()->GetInteger32Constant())) {
+ // This is intended to look for HAdd and HSub, to handle compounds
+ // like ((base + offset) << scale) with one single decomposition.
+ left()->TryDecompose(decomposition);
+ return true;
+ }
+ }
+ return false;
+ }
+
virtual Range* InferRange(Zone* zone);
DECLARE_CONCRETE_INSTRUCTION(Shl)
@@ -4569,7 +4800,8 @@ class HShr: public HBitwiseBinaryOperation {
HValue* right);
virtual bool TryDecompose(DecompositionResult* decomposition) {
- if (right()->IsInteger32Constant()) {
+ if (right()->IsInteger32Constant() &&
+ right()->GetInteger32Constant() >= 0) {
if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
// This is intended to look for HAdd and HSub, to handle compounds
// like ((base + offset) >> scale) with one single decomposition.
@@ -4601,7 +4833,8 @@ class HSar: public HBitwiseBinaryOperation {
HValue* right);
virtual bool TryDecompose(DecompositionResult* decomposition) {
- if (right()->IsInteger32Constant()) {
+ if (right()->IsInteger32Constant() &&
+ right()->GetInteger32Constant() >= 0) {
if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
// This is intended to look for HAdd and HSub, to handle compounds
// like ((base + offset) >> scale) with one single decomposition.
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | src/hydrogen-instructions.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698