| Index: src/hydrogen-instructions.h
|
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
|
| index e32a09c7202a1c0396602156fef9abe82c744173..cbaa296aaff92b07cfebcde2bebac8ab8fbe1216 100644
|
| --- a/src/hydrogen-instructions.h
|
| +++ b/src/hydrogen-instructions.h
|
| @@ -258,18 +258,37 @@ class Representation {
|
| enum Kind {
|
| kNone,
|
| kTagged,
|
| - kDouble,
|
| + // Specializations
|
| + kTruncatedInteger32,
|
| + kClampedRoundedUInteger8,
|
| + // Terminal specializations
|
| kInteger32,
|
| + kDouble,
|
| kExternal,
|
| - kNumRepresentations
|
| + // Derived
|
| + kNumRepresentations,
|
| + kFirstSpecialization = kTruncatedInteger32,
|
| + kLastSpecialization = kExternal,
|
| + kNumberOfSpecialization = kLastSpecialization -
|
| + kFirstSpecialization + 1,
|
| + kFirstTerminalSpecialization = kInteger32,
|
| + kLastTerminalSpecialization = kExternal,
|
| + kNumberOfTerminalSpecialization =
|
| + kLastTerminalSpecialization - kFirstTerminalSpecialization + 1
|
| };
|
|
|
| Representation() : kind_(kNone) { }
|
|
|
| static Representation None() { return Representation(kNone); }
|
| static Representation Tagged() { return Representation(kTagged); }
|
| - static Representation Integer32() { return Representation(kInteger32); }
|
| static Representation Double() { return Representation(kDouble); }
|
| + static Representation Integer32() { return Representation(kInteger32); }
|
| + static Representation TruncatedInteger32() {
|
| + return Representation(kTruncatedInteger32);
|
| + }
|
| + static Representation ClampedRoundedUInteger8() {
|
| + return Representation(kClampedRoundedUInteger8);
|
| + }
|
| static Representation External() { return Representation(kExternal); }
|
|
|
| bool Equals(const Representation& other) {
|
| @@ -279,11 +298,18 @@ class Representation {
|
| Kind kind() const { return static_cast<Kind>(kind_); }
|
| bool IsNone() const { return kind_ == kNone; }
|
| bool IsTagged() const { return kind_ == kTagged; }
|
| - bool IsInteger32() const { return kind_ == kInteger32; }
|
| + bool IsInteger32X() const { return kind_ == kInteger32; }
|
| + bool IsTruncatedInteger32() const { return kind_ == kTruncatedInteger32; }
|
| + bool IsClampedRoundedInteger8() const {
|
| + return kind_ == kClampedRoundedUInteger8;
|
| + }
|
| + bool IsInteger() const { return IsInteger32X() || IsTruncatedInteger32() ||
|
| + IsClampedRoundedInteger8(); }
|
| bool IsDouble() const { return kind_ == kDouble; }
|
| bool IsExternal() const { return kind_ == kExternal; }
|
| - bool IsSpecialization() const {
|
| - return kind_ == kInteger32 || kind_ == kDouble;
|
| + bool IsTerminalSpecialization() const {
|
| + return kind_ >= kFirstTerminalSpecialization &&
|
| + kind_ <= kLastTerminalSpecialization;
|
| }
|
| const char* Mnemonic() const;
|
|
|
| @@ -297,6 +323,24 @@ class Representation {
|
| };
|
|
|
|
|
| +enum ToIRoundingMode {
|
| + kNoRoundingMode = 0,
|
| + kTruncatingRoundingMode,
|
| + k8BitClampedRoundingMode
|
| +};
|
| +
|
| +
|
| +inline static ToIRoundingMode RepresentationToRoundingMode(Representation r) {
|
| + if (r.IsClampedRoundedInteger8()) {
|
| + return k8BitClampedRoundingMode;
|
| + } else if (r.IsTruncatedInteger32()) {
|
| + return kTruncatingRoundingMode;
|
| + } else {
|
| + return kNoRoundingMode;
|
| + }
|
| +}
|
| +
|
| +
|
| class HType {
|
| public:
|
| HType() : type_(kUninitialized) { }
|
| @@ -427,8 +471,7 @@ class HValue: public ZoneObject {
|
| kBailoutOnMinusZero,
|
| kCanBeDivByZero,
|
| kIsArguments,
|
| - kTruncatingToInt32,
|
| - kLastFlag = kTruncatingToInt32
|
| + kLastFlag = kIsArguments
|
| };
|
|
|
| STATIC_ASSERT(kLastFlag < kBitsPerInt);
|
| @@ -939,15 +982,13 @@ class HChange: public HUnaryOperation {
|
| public:
|
| HChange(HValue* value,
|
| Representation from,
|
| - Representation to,
|
| - bool is_truncating)
|
| + Representation to)
|
| : HUnaryOperation(value), from_(from) {
|
| ASSERT(!from.IsNone() && !to.IsNone());
|
| ASSERT(!from.Equals(to));
|
| set_representation(to);
|
| SetFlag(kUseGVN);
|
| - if (is_truncating) SetFlag(kTruncatingToInt32);
|
| - if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
|
| + if (from.IsInteger() && to.IsTagged() && value->range() != NULL &&
|
| value->range()->IsInSmiRange()) {
|
| set_type(HType::Smi());
|
| }
|
| @@ -961,12 +1002,14 @@ class HChange: public HUnaryOperation {
|
| return from_;
|
| }
|
|
|
| - bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
|
| -
|
| virtual void PrintDataTo(StringStream* stream);
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Change,
|
| - CanTruncateToInt32() ? "truncate" : "change")
|
| + representation().IsTruncatedInteger32()
|
| + ? "truncate"
|
| + : (representation().IsClampedRoundedInteger8()
|
| + ? "clamp"
|
| + : "change"))
|
|
|
| protected:
|
| virtual bool DataEquals(HValue* other) {
|
| @@ -1492,11 +1535,10 @@ class HBitNot: public HUnaryOperation {
|
| explicit HBitNot(HValue* value) : HUnaryOperation(value) {
|
| set_representation(Representation::Integer32());
|
| SetFlag(kUseGVN);
|
| - SetFlag(kTruncatingToInt32);
|
| }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| - return Representation::Integer32();
|
| + return Representation::TruncatedInteger32();
|
| }
|
| virtual HType CalculateInferredType();
|
|
|
| @@ -1564,7 +1606,7 @@ class HUnaryMathOperation: public HUnaryOperation {
|
| // with its inputs. This happens before the representation changes are
|
| // introduced.
|
| if (op() == kMathFloor) {
|
| - if (value()->representation().IsInteger32()) return value();
|
| + if (value()->representation().IsInteger()) return value();
|
| }
|
| return this;
|
| }
|
| @@ -1882,16 +1924,28 @@ class HPhi: public HValue {
|
|
|
| virtual Representation InferredRepresentation() {
|
| bool double_occurred = false;
|
| - bool int32_occurred = false;
|
| + bool int_occurred = false;
|
| + Representation int_representation(Representation::None());
|
| for (int i = 0; i < OperandCount(); ++i) {
|
| HValue* value = OperandAt(i);
|
| if (value->representation().IsDouble()) double_occurred = true;
|
| - if (value->representation().IsInteger32()) int32_occurred = true;
|
| + if (value->representation().IsInteger()) {
|
| + int_occurred = true;
|
| + if (int_representation.IsNone()) {
|
| + int_representation = value->representation();
|
| + } else if (!int_representation.Equals(value->representation())) {
|
| + int_representation = Representation::Integer32();
|
| + } else {
|
| + int_representation = value->representation();
|
| + }
|
| + }
|
| if (value->representation().IsTagged()) return Representation::Tagged();
|
| }
|
|
|
| if (double_occurred) return Representation::Double();
|
| - if (int32_occurred) return Representation::Integer32();
|
| + if (!int_representation.IsNone()) {
|
| + return int_representation;
|
| + }
|
| return Representation::None();
|
| }
|
|
|
| @@ -1996,6 +2050,7 @@ class HConstant: public HTemplateInstruction<0> {
|
| bool IsInteger() const { return handle_->IsSmi(); }
|
| HConstant* CopyToRepresentation(Representation r) const;
|
| HConstant* CopyToTruncatedInt32() const;
|
| + HConstant* CopyToClampedRoundedUInt8() const;
|
| bool HasInteger32Value() const { return has_int32_value_; }
|
| int32_t Integer32Value() const {
|
| ASSERT(HasInteger32Value());
|
| @@ -2211,9 +2266,8 @@ class HBitwiseBinaryOperation: public HBinaryOperation {
|
|
|
| virtual void RepresentationChanged(Representation to) {
|
| if (!to.IsTagged()) {
|
| - ASSERT(to.IsInteger32());
|
| + ASSERT(to.IsInteger());
|
| ClearAllSideEffects();
|
| - SetFlag(kTruncatingToInt32);
|
| SetFlag(kUseGVN);
|
| }
|
| }
|
| @@ -3393,12 +3447,16 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| if (index == 0) {
|
| return Representation::External();
|
| - } else {
|
| - if (index == 2 && array_type() == kExternalFloatArray) {
|
| + } else if (index == 2) {
|
| + if (array_type_ == kExternalFloatArray) {
|
| return Representation::Double();
|
| + } else if (array_type_ == kExternalPixelArray) {
|
| + return Representation::ClampedRoundedUInteger8();
|
| } else {
|
| - return Representation::Integer32();
|
| + return Representation::TruncatedInteger32();
|
| }
|
| + } else {
|
| + return Representation::Integer32();
|
| }
|
| }
|
|
|
|
|