// Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_ #define V8_COMPILER_REPRESENTATION_CHANGE_H_ #include "src/compiler/js-graph.h" #include "src/compiler/simplified-operator.h" namespace v8 { namespace internal { namespace compiler { class Truncation final { public: // 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); } static Truncation Generalize(Truncation t1, Truncation t2) { return Truncation(Generalize(t1.kind(), t2.kind())); } // Queries. bool TruncatesToWord32() const { return LessGeneral(kind_, TruncationKind::kWord32); } bool TruncatesNaNToZero() { return LessGeneral(kind_, TruncationKind::kWord32) || LessGeneral(kind_, TruncationKind::kBool); } bool TruncatesUndefinedToZeroOrNaN() { return LessGeneral(kind_, TruncationKind::kFloat64) || LessGeneral(kind_, TruncationKind::kWord64); } // Operators. bool operator==(Truncation other) const { return kind() == other.kind(); } bool operator!=(Truncation other) const { return !(*this == other); } // Debug utilities. const char* description() const; bool IsLessGeneralThan(Truncation other) { return LessGeneral(kind(), other.kind()); } 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); }; // 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) {} // 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 ? MachineType::AnyTagged() : MachineType::Pointer(); } MachineType TypeForBasePointer(const ElementAccess& access) { return access.tag() != 0 ? MachineType::AnyTagged() : MachineType::Pointer(); } private: JSGraph* jsgraph_; Isolate* isolate_; friend class RepresentationChangerTester; // accesses the below fields. bool testing_type_errors_; // If {true}, don't abort on a type error. bool type_error_; // Set when a type error is detected. 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, Truncation truncation); 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 jsgraph()->simplified(); } MachineOperatorBuilder* machine() { return jsgraph()->machine(); } }; } // namespace compiler } // namespace internal } // namespace v8 #endif // V8_COMPILER_REPRESENTATION_CHANGE_H_