diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-01-25 11:39:07 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-01-25 15:20:42 +0000 |
commit | 6c91641271e536ffaa88a1dff5127e42ee99a91e (patch) | |
tree | 703d9dd49602377ddc90cbf886aad37913f2496b /chromium/v8/src/compiler/representation-change.h | |
parent | b145b7fafd36f0c260d6a768c81fc14e32578099 (diff) | |
download | qtwebengine-chromium-6c91641271e536ffaa88a1dff5127e42ee99a91e.tar.gz |
BASELINE: Update Chromium to 49.0.2623.23
Also adds missing printing sources.
Change-Id: I3726b8f0c7d6751c9fc846096c571fadca7108cd
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/v8/src/compiler/representation-change.h')
-rw-r--r-- | chromium/v8/src/compiler/representation-change.h | 498 |
1 files changed, 90 insertions, 408 deletions
diff --git a/chromium/v8/src/compiler/representation-change.h b/chromium/v8/src/compiler/representation-change.h index 0c38e020add..62ea3b4684b 100644 --- a/chromium/v8/src/compiler/representation-change.h +++ b/chromium/v8/src/compiler/representation-change.h @@ -5,415 +5,106 @@ #ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_ #define V8_COMPILER_REPRESENTATION_CHANGE_H_ -#include <sstream> - -#include "src/base/bits.h" #include "src/compiler/js-graph.h" -#include "src/compiler/machine-operator.h" #include "src/compiler/simplified-operator.h" namespace v8 { namespace internal { namespace compiler { -// Contains logic related to changing the representation of values for constants -// and other nodes, as well as lowering Simplified->Machine operators. -// Eagerly folds any representation changes for constants. -class RepresentationChanger { +class Truncation final { public: - RepresentationChanger(JSGraph* jsgraph, SimplifiedOperatorBuilder* simplified, - Isolate* isolate) - : jsgraph_(jsgraph), - simplified_(simplified), - isolate_(isolate), - testing_type_errors_(false), - type_error_(false) {} - - // TODO(titzer): should Word64 also be implicitly convertable to others? - static bool IsWord(MachineTypeUnion type) { - return (type & (kRepWord8 | kRepWord16 | kRepWord32)) != 0; - } + // Constructors. + static Truncation None() { return Truncation(TruncationKind::kNone); } + static Truncation Bool() { return Truncation(TruncationKind::kBool); } + static Truncation Word32() { return Truncation(TruncationKind::kWord32); } + static Truncation Word64() { return Truncation(TruncationKind::kWord64); } + static Truncation Float32() { return Truncation(TruncationKind::kFloat32); } + static Truncation Float64() { return Truncation(TruncationKind::kFloat64); } + static Truncation Any() { return Truncation(TruncationKind::kAny); } - Node* GetRepresentationFor(Node* node, MachineTypeUnion output_type, - MachineTypeUnion use_type) { - if (!base::bits::IsPowerOfTwo32(output_type & kRepMask)) { - // There should be only one output representation. - return TypeError(node, output_type, use_type); - } - if ((use_type & kRepMask) == (output_type & kRepMask)) { - // Representations are the same. That's a no-op. - return node; - } - if (IsWord(use_type) && IsWord(output_type)) { - // Both are words less than or equal to 32-bits. - // Since loads of integers from memory implicitly sign or zero extend the - // value to the full machine word size and stores implicitly truncate, - // no representation change is necessary. - return node; - } - if (use_type & kRepTagged) { - return GetTaggedRepresentationFor(node, output_type); - } else if (use_type & kRepFloat32) { - return GetFloat32RepresentationFor(node, output_type); - } else if (use_type & kRepFloat64) { - return GetFloat64RepresentationFor(node, output_type); - } else if (use_type & kRepBit) { - return GetBitRepresentationFor(node, output_type); - } else if (IsWord(use_type)) { - return GetWord32RepresentationFor(node, output_type, - use_type & kTypeUint32); - } else if (use_type & kRepWord64) { - return GetWord64RepresentationFor(node, output_type); - } else { - return node; - } + static Truncation Generalize(Truncation t1, Truncation t2) { + return Truncation(Generalize(t1.kind(), t2.kind())); } - Node* GetTaggedRepresentationFor(Node* node, MachineTypeUnion output_type) { - // Eagerly fold representation changes for constants. - switch (node->opcode()) { - case IrOpcode::kNumberConstant: - case IrOpcode::kHeapConstant: - return node; // No change necessary. - case IrOpcode::kInt32Constant: - if (output_type & kTypeUint32) { - uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); - return jsgraph()->Constant(static_cast<double>(value)); - } else if (output_type & kTypeInt32) { - int32_t value = OpParameter<int32_t>(node); - return jsgraph()->Constant(value); - } else if (output_type & kRepBit) { - return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant() - : jsgraph()->TrueConstant(); - } else { - return TypeError(node, output_type, kRepTagged); - } - case IrOpcode::kFloat64Constant: - return jsgraph()->Constant(OpParameter<double>(node)); - case IrOpcode::kFloat32Constant: - return jsgraph()->Constant(OpParameter<float>(node)); - default: - break; - } - // Select the correct X -> Tagged operator. - const Operator* op; - if (output_type & kRepBit) { - op = simplified()->ChangeBitToBool(); - } else if (IsWord(output_type)) { - if (output_type & kTypeUint32) { - op = simplified()->ChangeUint32ToTagged(); - } else if (output_type & kTypeInt32) { - op = simplified()->ChangeInt32ToTagged(); - } else { - return TypeError(node, output_type, kRepTagged); - } - } else if (output_type & kRepFloat32) { // float32 -> float64 -> tagged - node = InsertChangeFloat32ToFloat64(node); - op = simplified()->ChangeFloat64ToTagged(); - } else if (output_type & kRepFloat64) { - op = simplified()->ChangeFloat64ToTagged(); - } else { - return TypeError(node, output_type, kRepTagged); - } - return jsgraph()->graph()->NewNode(op, node); + // Queries. + bool TruncatesToWord32() const { + return LessGeneral(kind_, TruncationKind::kWord32); } - - Node* GetFloat32RepresentationFor(Node* node, MachineTypeUnion output_type) { - // Eagerly fold representation changes for constants. - switch (node->opcode()) { - case IrOpcode::kFloat64Constant: - case IrOpcode::kNumberConstant: - return jsgraph()->Float32Constant( - DoubleToFloat32(OpParameter<double>(node))); - case IrOpcode::kInt32Constant: - if (output_type & kTypeUint32) { - uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); - return jsgraph()->Float32Constant(static_cast<float>(value)); - } else { - int32_t value = OpParameter<int32_t>(node); - return jsgraph()->Float32Constant(static_cast<float>(value)); - } - case IrOpcode::kFloat32Constant: - return node; // No change necessary. - default: - break; - } - // Select the correct X -> Float32 operator. - const Operator* op; - if (output_type & kRepBit) { - return TypeError(node, output_type, kRepFloat32); - } else if (IsWord(output_type)) { - if (output_type & kTypeUint32) { - op = machine()->ChangeUint32ToFloat64(); - } else { - op = machine()->ChangeInt32ToFloat64(); - } - // int32 -> float64 -> float32 - node = jsgraph()->graph()->NewNode(op, node); - op = machine()->TruncateFloat64ToFloat32(); - } else if (output_type & kRepTagged) { - op = simplified() - ->ChangeTaggedToFloat64(); // tagged -> float64 -> float32 - node = jsgraph()->graph()->NewNode(op, node); - op = machine()->TruncateFloat64ToFloat32(); - } else if (output_type & kRepFloat64) { - op = machine()->TruncateFloat64ToFloat32(); - } else { - return TypeError(node, output_type, kRepFloat32); - } - return jsgraph()->graph()->NewNode(op, node); - } - - Node* GetFloat64RepresentationFor(Node* node, MachineTypeUnion output_type) { - // Eagerly fold representation changes for constants. - switch (node->opcode()) { - case IrOpcode::kNumberConstant: - return jsgraph()->Float64Constant(OpParameter<double>(node)); - case IrOpcode::kInt32Constant: - if (output_type & kTypeUint32) { - uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); - return jsgraph()->Float64Constant(static_cast<double>(value)); - } else { - int32_t value = OpParameter<int32_t>(node); - return jsgraph()->Float64Constant(value); - } - case IrOpcode::kFloat64Constant: - return node; // No change necessary. - case IrOpcode::kFloat32Constant: - return jsgraph()->Float64Constant(OpParameter<float>(node)); - default: - break; - } - // Select the correct X -> Float64 operator. - const Operator* op; - if (output_type & kRepBit) { - return TypeError(node, output_type, kRepFloat64); - } else if (IsWord(output_type)) { - if (output_type & kTypeUint32) { - op = machine()->ChangeUint32ToFloat64(); - } else { - op = machine()->ChangeInt32ToFloat64(); - } - } else if (output_type & kRepTagged) { - op = simplified()->ChangeTaggedToFloat64(); - } else if (output_type & kRepFloat32) { - op = machine()->ChangeFloat32ToFloat64(); - } else { - return TypeError(node, output_type, kRepFloat64); - } - return jsgraph()->graph()->NewNode(op, node); - } - - Node* MakeInt32Constant(double value) { - if (value < 0) { - DCHECK(IsInt32Double(value)); - int32_t iv = static_cast<int32_t>(value); - return jsgraph()->Int32Constant(iv); - } else { - DCHECK(IsUint32Double(value)); - int32_t iv = static_cast<int32_t>(static_cast<uint32_t>(value)); - return jsgraph()->Int32Constant(iv); - } + bool TruncatesNaNToZero() { + return LessGeneral(kind_, TruncationKind::kWord32) || + LessGeneral(kind_, TruncationKind::kBool); } - - Node* GetTruncatedWord32For(Node* node, MachineTypeUnion output_type) { - // Eagerly fold truncations for constants. - switch (node->opcode()) { - case IrOpcode::kInt32Constant: - return node; // No change necessary. - case IrOpcode::kFloat32Constant: - return jsgraph()->Int32Constant( - DoubleToInt32(OpParameter<float>(node))); - case IrOpcode::kNumberConstant: - case IrOpcode::kFloat64Constant: - return jsgraph()->Int32Constant( - DoubleToInt32(OpParameter<double>(node))); - default: - break; - } - // Select the correct X -> Word32 truncation operator. - const Operator* op = NULL; - if (output_type & kRepFloat64) { - op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); - } else if (output_type & kRepFloat32) { - node = InsertChangeFloat32ToFloat64(node); - op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); - } else if (output_type & kRepTagged) { - node = InsertChangeTaggedToFloat64(node); - op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); - } else { - return TypeError(node, output_type, kRepWord32); - } - return jsgraph()->graph()->NewNode(op, node); + bool TruncatesUndefinedToZeroOrNaN() { + return LessGeneral(kind_, TruncationKind::kFloat64) || + LessGeneral(kind_, TruncationKind::kWord64); } - Node* GetWord32RepresentationFor(Node* node, MachineTypeUnion output_type, - bool use_unsigned) { - // Eagerly fold representation changes for constants. - switch (node->opcode()) { - case IrOpcode::kInt32Constant: - return node; // No change necessary. - case IrOpcode::kFloat32Constant: - return MakeInt32Constant(OpParameter<float>(node)); - case IrOpcode::kNumberConstant: - case IrOpcode::kFloat64Constant: - return MakeInt32Constant(OpParameter<double>(node)); - default: - break; - } - // Select the correct X -> Word32 operator. - const Operator* op; - if (output_type & kRepBit) { - return node; // Sloppy comparison -> word32 - } else if (output_type & kRepFloat64) { - if (output_type & kTypeUint32 || use_unsigned) { - op = machine()->ChangeFloat64ToUint32(); - } else { - op = machine()->ChangeFloat64ToInt32(); - } - } else if (output_type & kRepFloat32) { - node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32 - if (output_type & kTypeUint32 || use_unsigned) { - op = machine()->ChangeFloat64ToUint32(); - } else { - op = machine()->ChangeFloat64ToInt32(); - } - } else if (output_type & kRepTagged) { - if (output_type & kTypeUint32 || use_unsigned) { - op = simplified()->ChangeTaggedToUint32(); - } else { - op = simplified()->ChangeTaggedToInt32(); - } - } else { - return TypeError(node, output_type, kRepWord32); - } - return jsgraph()->graph()->NewNode(op, node); - } + // Operators. + bool operator==(Truncation other) const { return kind() == other.kind(); } + bool operator!=(Truncation other) const { return !(*this == other); } - Node* GetBitRepresentationFor(Node* node, MachineTypeUnion output_type) { - // Eagerly fold representation changes for constants. - switch (node->opcode()) { - case IrOpcode::kHeapConstant: { - Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node); - DCHECK(value.is_identical_to(factory()->true_value()) || - value.is_identical_to(factory()->false_value())); - return jsgraph()->Int32Constant( - value.is_identical_to(factory()->true_value()) ? 1 : 0); - } - default: - break; - } - // Select the correct X -> Bit operator. - const Operator* op; - if (output_type & kRepTagged) { - op = simplified()->ChangeBoolToBit(); - } else { - return TypeError(node, output_type, kRepBit); - } - return jsgraph()->graph()->NewNode(op, node); + // Debug utilities. + const char* description() const; + bool IsLessGeneralThan(Truncation other) { + return LessGeneral(kind(), other.kind()); } - Node* GetWord64RepresentationFor(Node* node, MachineTypeUnion output_type) { - if (output_type & kRepBit) { - return node; // Sloppy comparison -> word64 - } - // Can't really convert Word64 to anything else. Purported to be internal. - return TypeError(node, output_type, kRepWord64); - } + private: + enum class TruncationKind : uint8_t { + kNone, + kBool, + kWord32, + kWord64, + kFloat32, + kFloat64, + kAny + }; + + explicit Truncation(TruncationKind kind) : kind_(kind) {} + TruncationKind kind() const { return kind_; } + + TruncationKind kind_; + + static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2); + static bool LessGeneral(TruncationKind rep1, TruncationKind rep2); +}; - const Operator* Int32OperatorFor(IrOpcode::Value opcode) { - switch (opcode) { - case IrOpcode::kNumberAdd: - return machine()->Int32Add(); - case IrOpcode::kNumberSubtract: - return machine()->Int32Sub(); - case IrOpcode::kNumberMultiply: - return machine()->Int32Mul(); - case IrOpcode::kNumberDivide: - return machine()->Int32Div(); - case IrOpcode::kNumberModulus: - return machine()->Int32Mod(); - case IrOpcode::kNumberEqual: - return machine()->Word32Equal(); - case IrOpcode::kNumberLessThan: - return machine()->Int32LessThan(); - case IrOpcode::kNumberLessThanOrEqual: - return machine()->Int32LessThanOrEqual(); - default: - UNREACHABLE(); - return NULL; - } - } - const Operator* Uint32OperatorFor(IrOpcode::Value opcode) { - switch (opcode) { - case IrOpcode::kNumberAdd: - return machine()->Int32Add(); - case IrOpcode::kNumberSubtract: - return machine()->Int32Sub(); - case IrOpcode::kNumberMultiply: - return machine()->Int32Mul(); - case IrOpcode::kNumberDivide: - return machine()->Uint32Div(); - case IrOpcode::kNumberModulus: - return machine()->Uint32Mod(); - case IrOpcode::kNumberEqual: - return machine()->Word32Equal(); - case IrOpcode::kNumberLessThan: - return machine()->Uint32LessThan(); - case IrOpcode::kNumberLessThanOrEqual: - return machine()->Uint32LessThanOrEqual(); - default: - UNREACHABLE(); - return NULL; - } - } +// Contains logic related to changing the representation of values for constants +// and other nodes, as well as lowering Simplified->Machine operators. +// Eagerly folds any representation changes for constants. +class RepresentationChanger final { + public: + RepresentationChanger(JSGraph* jsgraph, Isolate* isolate) + : jsgraph_(jsgraph), + isolate_(isolate), + testing_type_errors_(false), + type_error_(false) {} - const Operator* Float64OperatorFor(IrOpcode::Value opcode) { - switch (opcode) { - case IrOpcode::kNumberAdd: - return machine()->Float64Add(); - case IrOpcode::kNumberSubtract: - return machine()->Float64Sub(); - case IrOpcode::kNumberMultiply: - return machine()->Float64Mul(); - case IrOpcode::kNumberDivide: - return machine()->Float64Div(); - case IrOpcode::kNumberModulus: - return machine()->Float64Mod(); - case IrOpcode::kNumberEqual: - return machine()->Float64Equal(); - case IrOpcode::kNumberLessThan: - return machine()->Float64LessThan(); - case IrOpcode::kNumberLessThanOrEqual: - return machine()->Float64LessThanOrEqual(); - default: - UNREACHABLE(); - return NULL; - } - } + // Changes representation from {output_type} to {use_rep}. The {truncation} + // parameter is only used for sanity checking - if the changer cannot figure + // out signedness for the word32->float64 conversion, then we check that the + // uses truncate to word32 (so they do not care about signedness). + Node* GetRepresentationFor(Node* node, MachineRepresentation output_rep, + Type* output_type, MachineRepresentation use_rep, + Truncation truncation = Truncation::None()); + const Operator* Int32OperatorFor(IrOpcode::Value opcode); + const Operator* Uint32OperatorFor(IrOpcode::Value opcode); + const Operator* Float64OperatorFor(IrOpcode::Value opcode); MachineType TypeForBasePointer(const FieldAccess& access) { - return access.tag() != 0 ? kMachAnyTagged : kMachPtr; + return access.tag() != 0 ? MachineType::AnyTagged() + : MachineType::Pointer(); } MachineType TypeForBasePointer(const ElementAccess& access) { - return access.tag() != 0 ? kMachAnyTagged : kMachPtr; - } - - MachineType TypeFromUpperBound(Type* type) { - if (type->Is(Type::None())) - return kTypeAny; // TODO(titzer): should be an error - if (type->Is(Type::Signed32())) return kTypeInt32; - if (type->Is(Type::Unsigned32())) return kTypeUint32; - if (type->Is(Type::Number())) return kTypeNumber; - if (type->Is(Type::Boolean())) return kTypeBool; - return kTypeAny; + return access.tag() != 0 ? MachineType::AnyTagged() + : MachineType::Pointer(); } private: JSGraph* jsgraph_; - SimplifiedOperatorBuilder* simplified_; Isolate* isolate_; friend class RepresentationChangerTester; // accesses the below fields. @@ -421,39 +112,30 @@ class RepresentationChanger { bool testing_type_errors_; // If {true}, don't abort on a type error. bool type_error_; // Set when a type error is detected. - Node* TypeError(Node* node, MachineTypeUnion output_type, - MachineTypeUnion use) { - type_error_ = true; - if (!testing_type_errors_) { - std::ostringstream out_str; - out_str << static_cast<MachineType>(output_type); - - std::ostringstream use_str; - use_str << static_cast<MachineType>(use); - - V8_Fatal(__FILE__, __LINE__, - "RepresentationChangerError: node #%d:%s of " - "%s cannot be changed to %s", - node->id(), node->op()->mnemonic(), out_str.str().c_str(), - use_str.str().c_str()); - } - return node; - } - - Node* InsertChangeFloat32ToFloat64(Node* node) { - return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), - node); - } - - Node* InsertChangeTaggedToFloat64(Node* node) { - return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), - node); - } + Node* GetTaggedRepresentationFor(Node* node, MachineRepresentation output_rep, + Type* output_type); + Node* GetFloat32RepresentationFor(Node* node, + MachineRepresentation output_rep, + Type* output_type, Truncation truncation); + Node* GetFloat64RepresentationFor(Node* node, + MachineRepresentation output_rep, + Type* output_type, Truncation truncation); + Node* GetWord32RepresentationFor(Node* node, MachineRepresentation output_rep, + Type* output_type); + Node* GetBitRepresentationFor(Node* node, MachineRepresentation output_rep, + Type* output_type); + Node* GetWord64RepresentationFor(Node* node, MachineRepresentation output_rep, + Type* output_type); + Node* TypeError(Node* node, MachineRepresentation output_rep, + Type* output_type, MachineRepresentation use); + Node* MakeTruncatedInt32Constant(double value); + Node* InsertChangeFloat32ToFloat64(Node* node); + Node* InsertChangeTaggedToFloat64(Node* node); JSGraph* jsgraph() const { return jsgraph_; } Isolate* isolate() const { return isolate_; } Factory* factory() const { return isolate()->factory(); } - SimplifiedOperatorBuilder* simplified() { return simplified_; } + SimplifiedOperatorBuilder* simplified() { return jsgraph()->simplified(); } MachineOperatorBuilder* machine() { return jsgraph()->machine(); } }; |