Index: src/hydrogen-instructions.h |
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
index d11835452c72d7024f2a38bb49a854eba7ce45f1..e5290783d5a858aef51c860bb5fdc2e19d220401 100644 |
--- a/src/hydrogen-instructions.h |
+++ b/src/hydrogen-instructions.h |
@@ -45,6 +45,7 @@ namespace internal { |
// Forward declarations. |
class HBasicBlock; |
class HEnvironment; |
+class HInferRepresentation; |
class HInstruction; |
class HLoopInformation; |
class HValue; |
@@ -308,9 +309,9 @@ class Representation { |
public: |
enum Kind { |
kNone, |
- kTagged, |
- kDouble, |
kInteger32, |
+ kDouble, |
+ kTagged, |
kExternal, |
kNumRepresentations |
}; |
@@ -323,10 +324,18 @@ class Representation { |
static Representation Double() { return Representation(kDouble); } |
static Representation External() { return Representation(kExternal); } |
+ static Representation FromKind(Kind kind) { return Representation(kind); } |
+ |
bool Equals(const Representation& other) { |
return kind_ == other.kind_; |
} |
+ bool is_more_general_than(const Representation& other) { |
+ ASSERT(kind_ != kExternal); |
+ ASSERT(other.kind_ != kExternal); |
+ return kind_ > other.kind_; |
+ } |
+ |
Kind kind() const { return static_cast<Kind>(kind_); } |
bool IsNone() const { return kind_ == kNone; } |
bool IsTagged() const { return kind_ == kTagged; } |
@@ -629,13 +638,15 @@ class HValue: public ZoneObject { |
virtual bool EmitAtUses() { return false; } |
Representation representation() const { return representation_; } |
void ChangeRepresentation(Representation r) { |
- // Representation was already set and is allowed to be changed. |
- ASSERT(!r.IsNone()); |
ASSERT(CheckFlag(kFlexibleRepresentation)); |
RepresentationChanged(r); |
representation_ = r; |
+ if (r.IsTagged()) { |
+ // Tagged is the bottom of the lattice, don't go any further. |
+ ClearFlag(kFlexibleRepresentation); |
+ } |
} |
- void AssumeRepresentation(Representation r); |
+ virtual void AssumeRepresentation(Representation r); |
virtual bool IsConvertibleToInteger() const { return true; } |
@@ -733,16 +744,11 @@ class HValue: public ZoneObject { |
void ComputeInitialRange(Zone* zone); |
// Representation helpers. |
- virtual Representation RequiredInputRepresentation(int index) = 0; |
- |
- virtual Representation InferredRepresentation() { |
- return representation(); |
- } |
- |
- // Type feedback access. |
- virtual Representation ObservedInputRepresentation(int index) { |
- return RequiredInputRepresentation(index); |
+ virtual Representation observed_input_representation(int index) { |
+ return Representation::None(); |
} |
+ virtual Representation RequiredInputRepresentation(int index) = 0; |
+ virtual void InferRepresentation(HInferRepresentation* h_infer); |
// This gives the instruction an opportunity to replace itself with an |
// instruction that does the same in some better way. To replace an |
@@ -790,7 +796,18 @@ class HValue: public ZoneObject { |
UNREACHABLE(); |
return false; |
} |
+ |
+ virtual Representation RepresentationFromInputs() { |
+ return representation(); |
+ } |
+ Representation RepresentationFromUses(); |
+ virtual void UpdateRepresentation(Representation new_rep, |
+ HInferRepresentation* h_infer, |
+ const char* reason); |
+ void AddDependantsToWorklist(HInferRepresentation* h_infer); |
+ |
virtual void RepresentationChanged(Representation to) { } |
+ |
virtual Range* InferRange(Zone* zone); |
virtual void DeleteFromGraph() = 0; |
virtual void InternalSetOperandAt(int index, HValue* value) = 0; |
@@ -800,7 +817,6 @@ class HValue: public ZoneObject { |
} |
void set_representation(Representation r) { |
- // Representation is set-once. |
ASSERT(representation_.IsNone() && !r.IsNone()); |
representation_ = r; |
} |
@@ -1113,6 +1129,7 @@ class HBranch: public HUnaryControlInstruction { |
virtual Representation RequiredInputRepresentation(int index) { |
return Representation::None(); |
} |
+ virtual Representation observed_input_representation(int index); |
ToBooleanStub::Types expected_input_types() const { |
return expected_input_types_; |
@@ -1317,14 +1334,24 @@ class HClampToUint8: public HUnaryOperation { |
}; |
+enum RemovableSimulate { |
+ REMOVABLE_SIMULATE, |
+ FIXED_SIMULATE |
+}; |
+ |
+ |
class HSimulate: public HInstruction { |
public: |
- HSimulate(BailoutId ast_id, int pop_count, Zone* zone) |
+ HSimulate(BailoutId ast_id, |
+ int pop_count, |
+ Zone* zone, |
+ RemovableSimulate removable) |
: ast_id_(ast_id), |
pop_count_(pop_count), |
values_(2, zone), |
assigned_indexes_(2, zone), |
- zone_(zone) {} |
+ zone_(zone), |
+ removable_(removable) {} |
virtual ~HSimulate() {} |
virtual void PrintDataTo(StringStream* stream); |
@@ -1358,6 +1385,9 @@ class HSimulate: public HInstruction { |
return Representation::None(); |
} |
+ void MergeInto(HSimulate* other); |
+ bool is_candidate_for_removal() { return removable_ == REMOVABLE_SIMULATE; } |
+ |
DECLARE_CONCRETE_INSTRUCTION(Simulate) |
#ifdef DEBUG |
@@ -1384,6 +1414,7 @@ class HSimulate: public HInstruction { |
ZoneList<HValue*> values_; |
ZoneList<int> assigned_indexes_; |
Zone* zone_; |
+ RemovableSimulate removable_; |
}; |
@@ -2010,6 +2041,9 @@ class HBitNot: public HUnaryOperation { |
virtual Representation RequiredInputRepresentation(int index) { |
return Representation::Integer32(); |
} |
+ virtual Representation observed_input_representation(int index) { |
+ return Representation::Integer32(); |
+ } |
virtual HType CalculateInferredType(); |
virtual HValue* Canonicalize(); |
@@ -2037,7 +2071,7 @@ class HUnaryMathOperation: public HTemplateInstruction<2> { |
set_representation(Representation::Integer32()); |
break; |
case kMathAbs: |
- set_representation(Representation::Tagged()); |
+ // Not setting representation here: it is None intentionally. |
SetFlag(kFlexibleRepresentation); |
SetGVNFlag(kChangesNewSpacePromotion); |
break; |
@@ -2217,6 +2251,7 @@ class HCheckMaps: public HTemplateInstruction<2> { |
virtual Representation RequiredInputRepresentation(int index) { |
return Representation::Tagged(); |
} |
+ |
virtual void PrintDataTo(StringStream* stream); |
virtual HType CalculateInferredType(); |
@@ -2444,13 +2479,15 @@ class HPhi: public HValue { |
indirect_uses_[i] = 0; |
} |
ASSERT(merged_index >= 0); |
- set_representation(Representation::Tagged()); |
SetFlag(kFlexibleRepresentation); |
} |
- virtual Representation InferredRepresentation(); |
+ virtual Representation RepresentationFromInputs(); |
virtual Range* InferRange(Zone* zone); |
+ virtual void InferRepresentation(HInferRepresentation* h_infer); |
+ Representation RepresentationObservedByAllNonPhiUses(); |
+ Representation RepresentationFromUseRequirements(); |
virtual Representation RequiredInputRepresentation(int index) { |
return representation(); |
} |
@@ -2514,14 +2551,17 @@ class HPhi: public HValue { |
bool AllOperandsConvertibleToInteger() { |
for (int i = 0; i < OperandCount(); ++i) { |
if (!OperandAt(i)->IsConvertibleToInteger()) { |
+ if (FLAG_trace_representation) { |
+ HValue* input = OperandAt(i); |
+ PrintF("#%d %s: Input #%d %s at %d is NCTI\n", |
+ id(), Mnemonic(), input->id(), input->Mnemonic(), i); |
+ } |
return false; |
} |
} |
return true; |
} |
- void ResetInteger32Uses(); |
- |
protected: |
virtual void DeleteFromGraph(); |
virtual void InternalSetOperandAt(int index, HValue* value) { |
@@ -2704,11 +2744,14 @@ class HConstant: public HTemplateInstruction<0> { |
class HBinaryOperation: public HTemplateInstruction<3> { |
public: |
- HBinaryOperation(HValue* context, HValue* left, HValue* right) { |
+ HBinaryOperation(HValue* context, HValue* left, HValue* right) |
+ : observed_output_representation_(Representation::None()) { |
ASSERT(left != NULL && right != NULL); |
SetOperandAt(0, context); |
SetOperandAt(1, left); |
SetOperandAt(2, right); |
+ observed_input_representation_[0] = Representation::None(); |
+ observed_input_representation_[1] = Representation::None(); |
} |
HValue* context() { return OperandAt(0); } |
@@ -2727,11 +2770,34 @@ class HBinaryOperation: public HTemplateInstruction<3> { |
return right(); |
} |
+ void set_observed_input_representation(Representation left, |
+ Representation right) { |
+ observed_input_representation_[0] = left; |
+ observed_input_representation_[1] = right; |
+ } |
+ |
+ virtual void initialize_output_representation(Representation observed) { |
+ observed_output_representation_ = observed; |
+ } |
+ |
+ virtual Representation observed_input_representation(int index) { |
+ if (index == 0) return Representation::Tagged(); |
+ return observed_input_representation_[index - 1]; |
+ } |
+ |
+ virtual void InferRepresentation(HInferRepresentation* h_infer); |
+ virtual Representation RepresentationFromInputs(); |
+ virtual void AssumeRepresentation(Representation r); |
+ |
virtual bool IsCommutative() const { return false; } |
virtual void PrintDataTo(StringStream* stream); |
DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) |
+ |
+ private: |
+ Representation observed_input_representation_[2]; |
+ Representation observed_output_representation_; |
}; |
@@ -2901,6 +2967,9 @@ class HBoundsCheck: public HTemplateInstruction<2> { |
} |
return Representation::Integer32(); |
} |
+ virtual Representation observed_input_representation(int index) { |
+ return Representation::Integer32(); |
+ } |
virtual void PrintDataTo(StringStream* stream); |
@@ -2919,12 +2988,9 @@ class HBitwiseBinaryOperation: public HBinaryOperation { |
public: |
HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) |
: HBinaryOperation(context, left, right) { |
- set_representation(Representation::Tagged()); |
SetFlag(kFlexibleRepresentation); |
+ SetFlag(kTruncatingToInt32); |
SetAllSideEffects(); |
- observed_input_representation_[0] = Representation::Tagged(); |
- observed_input_representation_[1] = Representation::None(); |
- observed_input_representation_[2] = Representation::None(); |
} |
virtual Representation RequiredInputRepresentation(int index) { |
@@ -2937,28 +3003,32 @@ class HBitwiseBinaryOperation: public HBinaryOperation { |
if (!to.IsTagged()) { |
ASSERT(to.IsInteger32()); |
ClearAllSideEffects(); |
- SetFlag(kTruncatingToInt32); |
SetFlag(kUseGVN); |
+ } else { |
+ SetAllSideEffects(); |
+ ClearFlag(kUseGVN); |
} |
} |
- virtual HType CalculateInferredType(); |
- |
- virtual Representation ObservedInputRepresentation(int index) { |
- return observed_input_representation_[index]; |
+ virtual void UpdateRepresentation(Representation new_rep, |
+ HInferRepresentation* h_infer, |
+ const char* reason) { |
+ // We only generate either int32 or generic tagged bitwise operations. |
+ if (new_rep.IsDouble()) new_rep = Representation::Integer32(); |
+ HValue::UpdateRepresentation(new_rep, h_infer, reason); |
} |
- void InitializeObservedInputRepresentation(Representation r) { |
- observed_input_representation_[1] = r; |
- observed_input_representation_[2] = r; |
+ virtual void initialize_output_representation(Representation observed) { |
+ if (observed.IsDouble()) observed = Representation::Integer32(); |
+ HBinaryOperation::initialize_output_representation(observed); |
} |
+ virtual HType CalculateInferredType(); |
+ |
DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) |
private: |
virtual bool IsDeletable() const { return true; } |
- |
- Representation observed_input_representation_[3]; |
}; |
@@ -2991,13 +3061,15 @@ class HArithmeticBinaryOperation: public HBinaryOperation { |
public: |
HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right) |
: HBinaryOperation(context, left, right) { |
- set_representation(Representation::Tagged()); |
- SetFlag(kFlexibleRepresentation); |
SetAllSideEffects(); |
+ SetFlag(kFlexibleRepresentation); |
} |
virtual void RepresentationChanged(Representation to) { |
- if (!to.IsTagged()) { |
+ if (to.IsTagged()) { |
+ SetAllSideEffects(); |
+ ClearFlag(kUseGVN); |
+ } else { |
ClearAllSideEffects(); |
SetFlag(kUseGVN); |
} |
@@ -3010,13 +3082,6 @@ class HArithmeticBinaryOperation: public HBinaryOperation { |
: representation(); |
} |
- virtual Representation InferredRepresentation() { |
- if (left()->representation().Equals(right()->representation())) { |
- return left()->representation(); |
- } |
- return HValue::InferredRepresentation(); |
- } |
- |
private: |
virtual bool IsDeletable() const { return true; } |
}; |
@@ -3035,11 +3100,9 @@ class HCompareGeneric: public HBinaryOperation { |
} |
virtual Representation RequiredInputRepresentation(int index) { |
- return Representation::Tagged(); |
- } |
- |
- Representation GetInputRepresentation() const { |
- return Representation::Tagged(); |
+ return index == 0 |
+ ? Representation::Tagged() |
+ : representation(); |
} |
Token::Value token() const { return token_; } |
@@ -3058,6 +3121,7 @@ class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> { |
public: |
HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token) |
: token_(token) { |
+ SetFlag(kFlexibleRepresentation); |
ASSERT(Token::IsCompareOp(token)); |
SetOperandAt(0, left); |
SetOperandAt(1, right); |
@@ -3067,20 +3131,26 @@ class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> { |
HValue* right() { return OperandAt(1); } |
Token::Value token() const { return token_; } |
- void SetInputRepresentation(Representation r); |
- Representation GetInputRepresentation() const { |
- return input_representation_; |
+ void set_observed_input_representation(Representation left, |
+ Representation right) { |
+ observed_input_representation_[0] = left; |
+ observed_input_representation_[1] = right; |
} |
+ virtual void InferRepresentation(HInferRepresentation* h_infer); |
+ |
virtual Representation RequiredInputRepresentation(int index) { |
- return input_representation_; |
+ return representation(); |
+ } |
+ virtual Representation observed_input_representation(int index) { |
+ return observed_input_representation_[index]; |
} |
virtual void PrintDataTo(StringStream* stream); |
DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch) |
private: |
- Representation input_representation_; |
+ Representation observed_input_representation_[2]; |
Token::Value token_; |
}; |
@@ -3141,6 +3211,9 @@ class HIsNilAndBranch: public HUnaryControlInstruction { |
virtual Representation RequiredInputRepresentation(int index) { |
return Representation::Tagged(); |
} |
+ virtual Representation observed_input_representation(int index) { |
+ return Representation::Tagged(); |
+ } |
DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch) |
@@ -3418,6 +3491,9 @@ class HPower: public HTemplateInstruction<2> { |
? Representation::Double() |
: Representation::None(); |
} |
+ virtual Representation observed_input_representation(int index) { |
+ return RequiredInputRepresentation(index); |
+ } |
DECLARE_CONCRETE_INSTRUCTION(Power) |
@@ -3603,14 +3679,19 @@ class HMathMinMax: public HArithmeticBinaryOperation { |
operation_(op) { } |
virtual Representation RequiredInputRepresentation(int index) { |
- return index == 0 |
- ? Representation::Tagged() |
- : representation(); |
- } |
+ return index == 0 ? Representation::Tagged() |
+ : representation(); |
+ } |
- virtual Representation InferredRepresentation() { |
- if (left()->representation().IsInteger32() && |
- right()->representation().IsInteger32()) { |
+ virtual Representation observed_input_representation(int index) { |
+ return RequiredInputRepresentation(index); |
+ } |
+ |
+ virtual Representation RepresentationFromInputs() { |
+ Representation left_rep = left()->representation(); |
+ Representation right_rep = right()->representation(); |
+ if ((left_rep.IsNone() || left_rep.IsInteger32()) && |
+ (right_rep.IsNone() || right_rep.IsInteger32())) { |
return Representation::Integer32(); |
} |
return Representation::Double(); |
@@ -4336,6 +4417,10 @@ class HLoadKeyed |
return Representation::None(); |
} |
+ virtual Representation observed_input_representation(int index) { |
+ return RequiredInputRepresentation(index); |
+ } |
+ |
virtual void PrintDataTo(StringStream* stream); |
bool RequiresHoleCheck() const; |
@@ -4527,6 +4612,12 @@ class HStoreKeyed |
} else { |
SetGVNFlag(kChangesArrayElements); |
} |
+ |
+ // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
+ if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && |
+ elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
+ SetFlag(kTruncatingToInt32); |
+ } |
} |
virtual Representation RequiredInputRepresentation(int index) { |
@@ -4552,6 +4643,19 @@ class HStoreKeyed |
bool is_external() const { |
return IsExternalArrayElementsKind(elements_kind()); |
} |
+ |
+ virtual Representation observed_input_representation(int index) { |
+ if (index < 2) return RequiredInputRepresentation(index); |
+ if (IsDoubleOrFloatElementsKind(elements_kind())) { |
+ return Representation::Double(); |
+ } |
+ if (is_external()) { |
+ return Representation::Integer32(); |
+ } |
+ // For fast object elements kinds, don't assume anything. |
+ return Representation::None(); |
+ } |
+ |
HValue* elements() { return OperandAt(0); } |
HValue* key() { return OperandAt(1); } |
HValue* value() { return OperandAt(2); } |