Index: src/hydrogen-instructions.h |
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
index eac5173f7d00748bec37cba8a7bb68990113342c..d73c62f06789765d290de728113def041b26de6c 100644 |
--- a/src/hydrogen-instructions.h |
+++ b/src/hydrogen-instructions.h |
@@ -122,7 +122,6 @@ class LChunkBuilder; |
V(Goto) \ |
V(HasCachedArrayIndexAndBranch) \ |
V(HasInstanceTypeAndBranch) \ |
- V(InductionVariableAnnotation) \ |
V(InnerAllocatedObject) \ |
V(InstanceOf) \ |
V(InstanceOfKnownGlobal) \ |
@@ -151,7 +150,6 @@ class LChunkBuilder; |
V(MathMinMax) \ |
V(Mod) \ |
V(Mul) \ |
- V(NumericConstraint) \ |
V(OsrEntry) \ |
V(OuterContext) \ |
V(Parameter) \ |
@@ -542,158 +540,6 @@ enum GVNFlag { |
}; |
-class NumericRelation { |
- public: |
- enum Kind { NONE, EQ, GT, GE, LT, LE, NE }; |
- static const char* MnemonicFromKind(Kind kind) { |
- switch (kind) { |
- case NONE: return "NONE"; |
- case EQ: return "EQ"; |
- case GT: return "GT"; |
- case GE: return "GE"; |
- case LT: return "LT"; |
- case LE: return "LE"; |
- case NE: return "NE"; |
- } |
- UNREACHABLE(); |
- return NULL; |
- } |
- const char* Mnemonic() const { return MnemonicFromKind(kind_); } |
- |
- static NumericRelation None() { return NumericRelation(NONE); } |
- static NumericRelation Eq() { return NumericRelation(EQ); } |
- static NumericRelation Gt() { return NumericRelation(GT); } |
- static NumericRelation Ge() { return NumericRelation(GE); } |
- static NumericRelation Lt() { return NumericRelation(LT); } |
- static NumericRelation Le() { return NumericRelation(LE); } |
- static NumericRelation Ne() { return NumericRelation(NE); } |
- |
- bool IsNone() { return kind_ == NONE; } |
- |
- static NumericRelation FromToken(Token::Value token) { |
- switch (token) { |
- case Token::EQ: return Eq(); |
- case Token::EQ_STRICT: return Eq(); |
- case Token::LT: return Lt(); |
- case Token::GT: return Gt(); |
- case Token::LTE: return Le(); |
- case Token::GTE: return Ge(); |
- case Token::NE: return Ne(); |
- case Token::NE_STRICT: return Ne(); |
- default: return None(); |
- } |
- } |
- |
- // The semantics of "Reversed" is that if "x rel y" is true then also |
- // "y rel.Reversed() x" is true, and that rel.Reversed().Reversed() == rel. |
- NumericRelation Reversed() { |
- switch (kind_) { |
- case NONE: return None(); |
- case EQ: return Eq(); |
- case GT: return Lt(); |
- case GE: return Le(); |
- case LT: return Gt(); |
- case LE: return Ge(); |
- case NE: return Ne(); |
- } |
- UNREACHABLE(); |
- return None(); |
- } |
- |
- // The semantics of "Negated" is that if "x rel y" is true then also |
- // "!(x rel.Negated() y)" is true. |
- NumericRelation Negated() { |
- switch (kind_) { |
- case NONE: return None(); |
- case EQ: return Ne(); |
- case GT: return Le(); |
- case GE: return Lt(); |
- case LT: return Ge(); |
- case LE: return Gt(); |
- case NE: return Eq(); |
- } |
- UNREACHABLE(); |
- return None(); |
- } |
- |
- // The semantics of "Implies" is that if "x rel y" is true |
- // then also "x other_relation y" is true. |
- bool Implies(NumericRelation other_relation) { |
- switch (kind_) { |
- case NONE: return false; |
- case EQ: return (other_relation.kind_ == EQ) |
- || (other_relation.kind_ == GE) |
- || (other_relation.kind_ == LE); |
- case GT: return (other_relation.kind_ == GT) |
- || (other_relation.kind_ == GE) |
- || (other_relation.kind_ == NE); |
- case LT: return (other_relation.kind_ == LT) |
- || (other_relation.kind_ == LE) |
- || (other_relation.kind_ == NE); |
- case GE: return (other_relation.kind_ == GE); |
- case LE: return (other_relation.kind_ == LE); |
- case NE: return (other_relation.kind_ == NE); |
- } |
- UNREACHABLE(); |
- return false; |
- } |
- |
- // The semantics of "IsExtendable" is that if |
- // "rel.IsExtendable(direction)" is true then |
- // "x rel y" implies "(x + direction) rel y" . |
- bool IsExtendable(int direction) { |
- switch (kind_) { |
- case NONE: return false; |
- case EQ: return false; |
- case GT: return (direction >= 0); |
- case GE: return (direction >= 0); |
- case LT: return (direction <= 0); |
- case LE: return (direction <= 0); |
- case NE: return false; |
- } |
- UNREACHABLE(); |
- return false; |
- } |
- |
- // CompoundImplies returns true when |
- // "((x + my_offset) >> my_scale) rel y" implies |
- // "((x + other_offset) >> other_scale) other_relation y". |
- bool CompoundImplies(NumericRelation other_relation, |
- int my_offset, |
- int my_scale, |
- int other_offset = 0, |
- int other_scale = 0) { |
- return Implies(other_relation) && ComponentsImply( |
- my_offset, my_scale, other_offset, other_scale); |
- } |
- |
- private: |
- // ComponentsImply returns true when |
- // "((x + my_offset) >> my_scale) rel y" implies |
- // "((x + other_offset) >> other_scale) rel y". |
- bool ComponentsImply(int my_offset, |
- int my_scale, |
- int other_offset, |
- int other_scale) { |
- switch (kind_) { |
- case NONE: break; // Fall through to UNREACHABLE(). |
- case EQ: |
- case NE: return my_offset == other_offset && my_scale == other_scale; |
- case GT: |
- case GE: return my_offset <= other_offset && my_scale >= other_scale; |
- case LT: |
- case LE: return my_offset >= other_offset && my_scale <= other_scale; |
- } |
- UNREACHABLE(); |
- return false; |
- } |
- |
- explicit NumericRelation(Kind kind) : kind_(kind) {} |
- |
- Kind kind_; |
-}; |
- |
- |
class DecompositionResult BASE_EMBEDDED { |
public: |
DecompositionResult() : base_(NULL), offset_(0), scale_(0) {} |
@@ -739,46 +585,6 @@ class DecompositionResult BASE_EMBEDDED { |
}; |
-class RangeEvaluationContext BASE_EMBEDDED { |
- public: |
- RangeEvaluationContext(HValue* value, HValue* upper); |
- |
- HValue* lower_bound() { return lower_bound_; } |
- HValue* lower_bound_guarantee() { return lower_bound_guarantee_; } |
- HValue* candidate() { return candidate_; } |
- HValue* upper_bound() { return upper_bound_; } |
- HValue* upper_bound_guarantee() { return upper_bound_guarantee_; } |
- int offset() { return offset_; } |
- int scale() { return scale_; } |
- |
- bool is_range_satisfied() { |
- return lower_bound_guarantee() != NULL && upper_bound_guarantee() != NULL; |
- } |
- |
- void set_lower_bound_guarantee(HValue* guarantee) { |
- lower_bound_guarantee_ = ConvertGuarantee(guarantee); |
- } |
- void set_upper_bound_guarantee(HValue* guarantee) { |
- upper_bound_guarantee_ = ConvertGuarantee(guarantee); |
- } |
- |
- void swap_candidate(DecompositionResult* other_candicate) { |
- other_candicate->SwapValues(&candidate_, &offset_, &scale_); |
- } |
- |
- private: |
- HValue* ConvertGuarantee(HValue* guarantee); |
- |
- HValue* lower_bound_; |
- HValue* lower_bound_guarantee_; |
- HValue* candidate_; |
- HValue* upper_bound_; |
- HValue* upper_bound_guarantee_; |
- int offset_; |
- int scale_; |
-}; |
- |
- |
typedef EnumSet<GVNFlag> GVNFlagSet; |
@@ -816,12 +622,6 @@ class HValue: public ZoneObject { |
// HGraph::ComputeSafeUint32Operations is responsible for setting this |
// flag. |
kUint32, |
- // If a phi is involved in the evaluation of a numeric constraint the |
- // recursion can cause an endless cycle: we use this flag to exit the loop. |
- kNumericConstraintEvaluationInProgress, |
- // This flag is set to true after the SetupInformativeDefinitions() pass |
- // has processed this instruction. |
- kIDefsProcessingDone, |
kHasNoObservableSideEffects, |
// Indicates the instruction is live during dead code elimination. |
kIsLive, |
@@ -959,8 +759,8 @@ class HValue: public ZoneObject { |
return RedefinedOperandIndex() != kNoRedefinedOperand; |
} |
HValue* RedefinedOperand() { |
- return IsInformativeDefinition() ? OperandAt(RedefinedOperandIndex()) |
- : NULL; |
+ int index = RedefinedOperandIndex(); |
+ return index == kNoRedefinedOperand ? NULL : OperandAt(index); |
} |
// A purely informative definition is an idef that will not emit code and |
@@ -971,17 +771,8 @@ class HValue: public ZoneObject { |
// This method must always return the original HValue SSA definition |
// (regardless of any iDef of this value). |
HValue* ActualValue() { |
- return IsInformativeDefinition() ? RedefinedOperand()->ActualValue() |
- : this; |
- } |
- |
- virtual void AddInformativeDefinitions() {} |
- |
- void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() { |
- UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>(); |
- } |
- void UpdateRedefinedUses() { |
- UpdateRedefinedUsesInner<Dominates>(); |
+ int index = RedefinedOperandIndex(); |
+ return index == kNoRedefinedOperand ? this : OperandAt(index); |
} |
bool IsInteger32Constant(); |
@@ -1132,12 +923,6 @@ class HValue: public ZoneObject { |
virtual void Verify() = 0; |
#endif |
- bool IsRelationTrue(NumericRelation relation, |
- HValue* other, |
- int offset = 0, |
- int scale = 0); |
- |
- bool TryGuaranteeRange(HValue* upper_bound); |
virtual bool TryDecompose(DecompositionResult* decomposition) { |
if (RedefinedOperand() != NULL) { |
return RedefinedOperand()->TryDecompose(decomposition); |
@@ -1159,17 +944,6 @@ class HValue: public ZoneObject { |
} |
protected: |
- void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); |
- |
- enum RangeGuaranteeDirection { |
- DIRECTION_NONE = 0, |
- DIRECTION_UPPER = 1, |
- DIRECTION_LOWER = 2, |
- DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER |
- }; |
- virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} |
- virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {} |
- |
// This function must be overridden for instructions with flag kUseGVN, to |
// compare the non-Operand parts of the instruction. |
virtual bool DataEquals(HValue* other) { |
@@ -1203,47 +977,6 @@ class HValue: public ZoneObject { |
representation_ = r; |
} |
- // Signature of a function testing if a HValue properly dominates another. |
- typedef bool (*DominanceTest)(HValue*, HValue*); |
- |
- // Simple implementation of DominanceTest implemented walking the chain |
- // of Hinstructions (used in UpdateRedefinedUsesInner). |
- static bool Dominates(HValue* dominator, HValue* dominated); |
- |
- // A fast implementation of DominanceTest that works only for the |
- // "current" instruction in the SetupInformativeDefinitions() phase. |
- // During that phase we use a flag to mark processed instructions, and by |
- // checking the flag we can quickly test if an instruction comes before or |
- // after the "current" one. |
- static bool TestDominanceUsingProcessedFlag(HValue* dominator, |
- HValue* dominated); |
- |
- // If we are redefining an operand, update all its dominated uses (the |
- // function that checks if a use is dominated is the template argument). |
- template<DominanceTest TestDominance> |
- void UpdateRedefinedUsesInner() { |
- HValue* input = RedefinedOperand(); |
- if (input != NULL) { |
- for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) { |
- HValue* use = uses.value(); |
- if (TestDominance(this, use)) { |
- use->SetOperandAt(uses.index(), this); |
- } |
- } |
- } |
- } |
- |
- // Informative definitions can override this method to state any numeric |
- // relation they provide on the redefined value. |
- // Returns true if it is guaranteed that: |
- // ((this + offset) >> scale) relation other |
- virtual bool IsRelationTrueInternal(NumericRelation relation, |
- HValue* other, |
- int offset = 0, |
- int scale = 0) { |
- return false; |
- } |
- |
static GVNFlagSet AllDependsOnFlagSet() { |
GVNFlagSet result; |
// Create changes mask. |
@@ -1514,52 +1247,6 @@ 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); |
- |
- HValue* constrained_value() { return OperandAt(0); } |
- HValue* related_value() { return OperandAt(1); } |
- NumericRelation relation() { return relation_; } |
- |
- virtual int RedefinedOperandIndex() { return 0; } |
- virtual bool IsPurelyInformativeDefinition() { return true; } |
- |
- virtual Representation RequiredInputRepresentation(int index) { |
- return representation(); |
- } |
- |
- virtual void PrintDataTo(StringStream* stream); |
- |
- virtual bool IsRelationTrueInternal(NumericRelation other_relation, |
- HValue* other_related_value, |
- int offset = 0, |
- int scale = 0) { |
- if (related_value() == other_related_value) { |
- return relation().CompoundImplies(other_relation, offset, scale); |
- } else { |
- return false; |
- } |
- } |
- |
- DECLARE_CONCRETE_INSTRUCTION(NumericConstraint) |
- |
- private: |
- HNumericConstraint(HValue* constrained_value, |
- NumericRelation relation, |
- HValue* related_value) |
- : relation_(relation) { |
- SetOperandAt(0, constrained_value); |
- SetOperandAt(1, related_value); |
- } |
- |
- NumericRelation relation_; |
-}; |
- |
- |
class HDeoptimize: public HTemplateInstruction<0> { |
public: |
DECLARE_INSTRUCTION_FACTORY_P1(HDeoptimize, Deoptimizer::BailoutType); |
@@ -3480,8 +3167,6 @@ class HPhi: public HValue { |
induction_variable_data_ = InductionVariableData::ExaminePhi(this); |
} |
- virtual void AddInformativeDefinitions(); |
- |
virtual void PrintTo(StringStream* stream); |
#ifdef DEBUG |
@@ -3532,11 +3217,6 @@ class HPhi: public HValue { |
inputs_[index] = value; |
} |
- virtual bool IsRelationTrueInternal(NumericRelation relation, |
- HValue* other, |
- int offset = 0, |
- int scale = 0); |
- |
private: |
ZoneList<HValue*> inputs_; |
int merged_index_; |
@@ -3551,53 +3231,6 @@ class HPhi: public HValue { |
}; |
-class HInductionVariableAnnotation : public HUnaryOperation { |
- public: |
- static HInductionVariableAnnotation* AddToGraph(HPhi* phi, |
- NumericRelation relation, |
- int operand_index); |
- |
- NumericRelation relation() { return relation_; } |
- HValue* induction_base() { return phi_->OperandAt(operand_index_); } |
- |
- virtual int RedefinedOperandIndex() { return 0; } |
- virtual bool IsPurelyInformativeDefinition() { return true; } |
- virtual Representation RequiredInputRepresentation(int index) { |
- return representation(); |
- } |
- |
- virtual void PrintDataTo(StringStream* stream); |
- |
- virtual bool IsRelationTrueInternal(NumericRelation other_relation, |
- HValue* other_related_value, |
- int offset = 0, |
- int scale = 0) { |
- if (induction_base() == other_related_value) { |
- return relation().CompoundImplies(other_relation, offset, scale); |
- } else { |
- return false; |
- } |
- } |
- |
- DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation) |
- |
- private: |
- HInductionVariableAnnotation(HPhi* phi, |
- NumericRelation relation, |
- int operand_index) |
- : HUnaryOperation(phi), |
- phi_(phi), relation_(relation), operand_index_(operand_index) { |
- } |
- |
- // 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 |
- // and this instruction (inserting an idef updates every use). |
- HPhi* phi_; |
- NumericRelation relation_; |
- int operand_index_; |
-}; |
- |
- |
class HArgumentsObject: public HTemplateInstruction<0> { |
public: |
static HArgumentsObject* New(Zone* zone, |
@@ -4115,12 +3748,6 @@ class HBoundsCheck: public HTemplateInstruction<2> { |
HValue* base() { return base_; } |
int offset() { return offset_; } |
int scale() { return scale_; } |
- bool index_can_increase() { |
- return (responsibility_direction_ & DIRECTION_LOWER) == 0; |
- } |
- bool index_can_decrease() { |
- return (responsibility_direction_ & DIRECTION_UPPER) == 0; |
- } |
void ApplyIndexChange(); |
bool DetectCompoundIndex() { |
@@ -4144,11 +3771,6 @@ class HBoundsCheck: public HTemplateInstruction<2> { |
return representation(); |
} |
- virtual bool IsRelationTrueInternal(NumericRelation relation, |
- HValue* related_value, |
- int offset = 0, |
- int scale = 0); |
- |
virtual void PrintDataTo(StringStream* stream); |
virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
@@ -4159,25 +3781,17 @@ class HBoundsCheck: public HTemplateInstruction<2> { |
virtual int RedefinedOperandIndex() { return 0; } |
virtual bool IsPurelyInformativeDefinition() { return skip_check(); } |
- virtual void AddInformativeDefinitions(); |
DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) |
protected: |
friend class HBoundsCheckBaseIndexInformation; |
- virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) { |
- responsibility_direction_ = static_cast<RangeGuaranteeDirection>( |
- responsibility_direction_ | direction); |
- } |
- |
virtual bool DataEquals(HValue* other) { return true; } |
- virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); |
bool skip_check_; |
HValue* base_; |
int offset_; |
int scale_; |
- RangeGuaranteeDirection responsibility_direction_; |
bool allow_equality_; |
private: |
@@ -4188,7 +3802,6 @@ class HBoundsCheck: public HTemplateInstruction<2> { |
HBoundsCheck(HValue* index, HValue* length) |
: skip_check_(false), |
base_(NULL), offset_(0), scale_(0), |
- responsibility_direction_(DIRECTION_NONE), |
allow_equality_(false) { |
SetOperandAt(0, index); |
SetOperandAt(1, length); |
@@ -4223,22 +3836,10 @@ class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { |
return representation(); |
} |
- virtual bool IsRelationTrueInternal(NumericRelation relation, |
- HValue* related_value, |
- int offset = 0, |
- int scale = 0); |
virtual void PrintDataTo(StringStream* stream); |
virtual int RedefinedOperandIndex() { return 0; } |
virtual bool IsPurelyInformativeDefinition() { return true; } |
- |
- protected: |
- virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) { |
- bounds_check()->SetResponsibilityForRange(direction); |
- } |
- virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) { |
- bounds_check()->TryGuaranteeRangeChanging(context); |
- } |
}; |
@@ -4411,8 +4012,6 @@ class HCompareNumericAndBranch: public HTemplateControlInstruction<2, 2> { |
} |
virtual void PrintDataTo(StringStream* stream); |
- virtual void AddInformativeDefinitions(); |
- |
DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) |
private: |