• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_
6 #define V8_COMPILER_REPRESENTATION_CHANGE_H_
7 
8 #include "src/compiler/js-graph.h"
9 #include "src/compiler/simplified-operator.h"
10 
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14 
15 class Truncation final {
16  public:
17   // Constructors.
None()18   static Truncation None() { return Truncation(TruncationKind::kNone); }
Bool()19   static Truncation Bool() { return Truncation(TruncationKind::kBool); }
Word32()20   static Truncation Word32() { return Truncation(TruncationKind::kWord32); }
Word64()21   static Truncation Word64() { return Truncation(TruncationKind::kWord64); }
Float32()22   static Truncation Float32() { return Truncation(TruncationKind::kFloat32); }
Float64()23   static Truncation Float64() { return Truncation(TruncationKind::kFloat64); }
Any()24   static Truncation Any() { return Truncation(TruncationKind::kAny); }
25 
Generalize(Truncation t1,Truncation t2)26   static Truncation Generalize(Truncation t1, Truncation t2) {
27     return Truncation(Generalize(t1.kind(), t2.kind()));
28   }
29 
30   // Queries.
TruncatesToWord32()31   bool TruncatesToWord32() const {
32     return LessGeneral(kind_, TruncationKind::kWord32);
33   }
TruncatesNaNToZero()34   bool TruncatesNaNToZero() {
35     return LessGeneral(kind_, TruncationKind::kWord32) ||
36            LessGeneral(kind_, TruncationKind::kBool);
37   }
TruncatesUndefinedToZeroOrNaN()38   bool TruncatesUndefinedToZeroOrNaN() {
39     return LessGeneral(kind_, TruncationKind::kFloat64) ||
40            LessGeneral(kind_, TruncationKind::kWord64);
41   }
42 
43   // Operators.
44   bool operator==(Truncation other) const { return kind() == other.kind(); }
45   bool operator!=(Truncation other) const { return !(*this == other); }
46 
47   // Debug utilities.
48   const char* description() const;
IsLessGeneralThan(Truncation other)49   bool IsLessGeneralThan(Truncation other) {
50     return LessGeneral(kind(), other.kind());
51   }
52 
53  private:
54   enum class TruncationKind : uint8_t {
55     kNone,
56     kBool,
57     kWord32,
58     kWord64,
59     kFloat32,
60     kFloat64,
61     kAny
62   };
63 
Truncation(TruncationKind kind)64   explicit Truncation(TruncationKind kind) : kind_(kind) {}
kind()65   TruncationKind kind() const { return kind_; }
66 
67   TruncationKind kind_;
68 
69   static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2);
70   static bool LessGeneral(TruncationKind rep1, TruncationKind rep2);
71 };
72 
73 
74 // Contains logic related to changing the representation of values for constants
75 // and other nodes, as well as lowering Simplified->Machine operators.
76 // Eagerly folds any representation changes for constants.
77 class RepresentationChanger final {
78  public:
RepresentationChanger(JSGraph * jsgraph,Isolate * isolate)79   RepresentationChanger(JSGraph* jsgraph, Isolate* isolate)
80       : jsgraph_(jsgraph),
81         isolate_(isolate),
82         testing_type_errors_(false),
83         type_error_(false) {}
84 
85   // Changes representation from {output_type} to {use_rep}. The {truncation}
86   // parameter is only used for sanity checking - if the changer cannot figure
87   // out signedness for the word32->float64 conversion, then we check that the
88   // uses truncate to word32 (so they do not care about signedness).
89   Node* GetRepresentationFor(Node* node, MachineRepresentation output_rep,
90                              Type* output_type, MachineRepresentation use_rep,
91                              Truncation truncation = Truncation::None());
92   const Operator* Int32OperatorFor(IrOpcode::Value opcode);
93   const Operator* Uint32OperatorFor(IrOpcode::Value opcode);
94   const Operator* Float64OperatorFor(IrOpcode::Value opcode);
95 
TypeForBasePointer(const FieldAccess & access)96   MachineType TypeForBasePointer(const FieldAccess& access) {
97     return access.tag() != 0 ? MachineType::AnyTagged()
98                              : MachineType::Pointer();
99   }
100 
TypeForBasePointer(const ElementAccess & access)101   MachineType TypeForBasePointer(const ElementAccess& access) {
102     return access.tag() != 0 ? MachineType::AnyTagged()
103                              : MachineType::Pointer();
104   }
105 
106  private:
107   JSGraph* jsgraph_;
108   Isolate* isolate_;
109 
110   friend class RepresentationChangerTester;  // accesses the below fields.
111 
112   bool testing_type_errors_;  // If {true}, don't abort on a type error.
113   bool type_error_;           // Set when a type error is detected.
114 
115   Node* GetTaggedRepresentationFor(Node* node, MachineRepresentation output_rep,
116                                    Type* output_type);
117   Node* GetFloat32RepresentationFor(Node* node,
118                                     MachineRepresentation output_rep,
119                                     Type* output_type, Truncation truncation);
120   Node* GetFloat64RepresentationFor(Node* node,
121                                     MachineRepresentation output_rep,
122                                     Type* output_type, Truncation truncation);
123   Node* GetWord32RepresentationFor(Node* node, MachineRepresentation output_rep,
124                                    Type* output_type);
125   Node* GetBitRepresentationFor(Node* node, MachineRepresentation output_rep,
126                                 Type* output_type);
127   Node* GetWord64RepresentationFor(Node* node, MachineRepresentation output_rep,
128                                    Type* output_type);
129   Node* TypeError(Node* node, MachineRepresentation output_rep,
130                   Type* output_type, MachineRepresentation use);
131   Node* MakeTruncatedInt32Constant(double value);
132   Node* InsertChangeFloat32ToFloat64(Node* node);
133   Node* InsertChangeTaggedToFloat64(Node* node);
134 
jsgraph()135   JSGraph* jsgraph() const { return jsgraph_; }
isolate()136   Isolate* isolate() const { return isolate_; }
factory()137   Factory* factory() const { return isolate()->factory(); }
simplified()138   SimplifiedOperatorBuilder* simplified() { return jsgraph()->simplified(); }
machine()139   MachineOperatorBuilder* machine() { return jsgraph()->machine(); }
140 };
141 
142 }  // namespace compiler
143 }  // namespace internal
144 }  // namespace v8
145 
146 #endif  // V8_COMPILER_REPRESENTATION_CHANGE_H_
147