OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_ | 5 #ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_ |
6 #define V8_COMPILER_SIMPLIFIED_OPERATOR_H_ | 6 #define V8_COMPILER_SIMPLIFIED_OPERATOR_H_ |
7 | 7 |
8 #include "src/compiler/machine-operator.h" | 8 #include "src/compiler/machine-type.h" |
9 #include "src/compiler/opcodes.h" | |
10 #include "src/compiler/operator.h" | |
11 #include "src/handles.h" | 9 #include "src/handles.h" |
12 #include "src/zone.h" | |
13 | 10 |
14 namespace v8 { | 11 namespace v8 { |
15 namespace internal { | 12 namespace internal { |
16 | 13 |
17 // Forward declarations. | 14 // Forward declarations. |
18 template <class> | 15 template <class> |
19 class TypeImpl; | 16 class TypeImpl; |
20 struct ZoneTypeConfig; | 17 struct ZoneTypeConfig; |
21 typedef TypeImpl<ZoneTypeConfig> Type; | 18 typedef TypeImpl<ZoneTypeConfig> Type; |
| 19 class Zone; |
22 | 20 |
23 | 21 |
24 namespace compiler { | 22 namespace compiler { |
25 | 23 |
| 24 // Forward declarations. |
| 25 class Operator; |
| 26 struct SimplifiedOperatorBuilderImpl; |
| 27 |
| 28 |
26 enum BaseTaggedness { kUntaggedBase, kTaggedBase }; | 29 enum BaseTaggedness { kUntaggedBase, kTaggedBase }; |
27 | 30 |
28 // An access descriptor for loads/stores of fixed structures like field | 31 // An access descriptor for loads/stores of fixed structures like field |
29 // accesses of heap objects. Accesses from either tagged or untagged base | 32 // accesses of heap objects. Accesses from either tagged or untagged base |
30 // pointers are supported; untagging is done automatically during lowering. | 33 // pointers are supported; untagging is done automatically during lowering. |
31 struct FieldAccess { | 34 struct FieldAccess { |
32 BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged. | 35 BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged. |
33 int offset; // offset of the field, without tag. | 36 int offset; // offset of the field, without tag. |
34 Handle<Name> name; // debugging only. | 37 Handle<Name> name; // debugging only. |
35 Type* type; // type of the field. | 38 Type* type; // type of the field. |
(...skipping 14 matching lines...) Expand all Loading... |
50 MachineType machine_type; // machine type of the element. | 53 MachineType machine_type; // machine type of the element. |
51 | 54 |
52 int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; } | 55 int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; } |
53 }; | 56 }; |
54 | 57 |
55 | 58 |
56 // If the accessed object is not a heap object, add this to the header_size. | 59 // If the accessed object is not a heap object, add this to the header_size. |
57 static const int kNonHeapObjectHeaderSize = kHeapObjectTag; | 60 static const int kNonHeapObjectHeaderSize = kHeapObjectTag; |
58 | 61 |
59 | 62 |
60 // Specialization for static parameters of type {FieldAccess}. | 63 const FieldAccess& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT; |
61 template <> | 64 const ElementAccess& ElementAccessOf(const Operator* op) WARN_UNUSED_RESULT; |
62 struct StaticParameterTraits<FieldAccess> { | |
63 static OStream& PrintTo(OStream& os, const FieldAccess& val) { // NOLINT | |
64 return os << val.offset; | |
65 } | |
66 static int HashCode(const FieldAccess& val) { | |
67 return (val.offset < 16) | (val.machine_type & 0xffff); | |
68 } | |
69 static bool Equals(const FieldAccess& lhs, const FieldAccess& rhs); | |
70 }; | |
71 | |
72 | |
73 // Specialization for static parameters of type {ElementAccess}. | |
74 template <> | |
75 struct StaticParameterTraits<ElementAccess> { | |
76 static OStream& PrintTo(OStream& os, const ElementAccess& val) { // NOLINT | |
77 return os << val.header_size; | |
78 } | |
79 static int HashCode(const ElementAccess& val) { | |
80 return (val.header_size < 16) | (val.machine_type & 0xffff); | |
81 } | |
82 static bool Equals(const ElementAccess& lhs, const ElementAccess& rhs); | |
83 }; | |
84 | |
85 | |
86 inline const FieldAccess FieldAccessOf(const Operator* op) { | |
87 DCHECK(op->opcode() == IrOpcode::kLoadField || | |
88 op->opcode() == IrOpcode::kStoreField); | |
89 return OpParameter<FieldAccess>(op); | |
90 } | |
91 | |
92 | |
93 inline const ElementAccess ElementAccessOf(const Operator* op) { | |
94 DCHECK(op->opcode() == IrOpcode::kLoadElement || | |
95 op->opcode() == IrOpcode::kStoreElement); | |
96 return OpParameter<ElementAccess>(op); | |
97 } | |
98 | 65 |
99 | 66 |
100 // Interface for building simplified operators, which represent the | 67 // Interface for building simplified operators, which represent the |
101 // medium-level operations of V8, including adding numbers, allocating objects, | 68 // medium-level operations of V8, including adding numbers, allocating objects, |
102 // indexing into objects and arrays, etc. | 69 // indexing into objects and arrays, etc. |
103 // All operators are typed but many are representation independent. | 70 // All operators are typed but many are representation independent. |
104 | 71 |
105 // Number values from JS can be in one of these representations: | 72 // Number values from JS can be in one of these representations: |
106 // - Tagged: word-sized integer that is either | 73 // - Tagged: word-sized integer that is either |
107 // - a signed small integer (31 or 32 bits plus a tag) | 74 // - a signed small integer (31 or 32 bits plus a tag) |
108 // - a tagged pointer to a HeapNumber object that has a float64 field | 75 // - a tagged pointer to a HeapNumber object that has a float64 field |
109 // - Int32: an untagged signed 32-bit integer | 76 // - Int32: an untagged signed 32-bit integer |
110 // - Uint32: an untagged unsigned 32-bit integer | 77 // - Uint32: an untagged unsigned 32-bit integer |
111 // - Float64: an untagged float64 | 78 // - Float64: an untagged float64 |
112 | 79 |
113 // Additional representations for intermediate code or non-JS code: | 80 // Additional representations for intermediate code or non-JS code: |
114 // - Int64: an untagged signed 64-bit integer | 81 // - Int64: an untagged signed 64-bit integer |
115 // - Uint64: an untagged unsigned 64-bit integer | 82 // - Uint64: an untagged unsigned 64-bit integer |
116 // - Float32: an untagged float32 | 83 // - Float32: an untagged float32 |
117 | 84 |
118 // Boolean values can be: | 85 // Boolean values can be: |
119 // - Bool: a tagged pointer to either the canonical JS #false or | 86 // - Bool: a tagged pointer to either the canonical JS #false or |
120 // the canonical JS #true object | 87 // the canonical JS #true object |
121 // - Bit: an untagged integer 0 or 1, but word-sized | 88 // - Bit: an untagged integer 0 or 1, but word-sized |
122 class SimplifiedOperatorBuilder { | 89 class SimplifiedOperatorBuilder FINAL { |
123 public: | 90 public: |
124 explicit inline SimplifiedOperatorBuilder(Zone* zone) : zone_(zone) {} | 91 explicit SimplifiedOperatorBuilder(Zone* zone); |
125 | 92 |
126 #define SIMPLE(name, properties, inputs, outputs) \ | 93 const Operator* BooleanNot() const WARN_UNUSED_RESULT; |
127 return new (zone_) \ | |
128 SimpleOperator(IrOpcode::k##name, properties, inputs, outputs, #name); | |
129 | 94 |
130 #define OP1(name, ptype, pname, properties, inputs, outputs) \ | 95 const Operator* NumberEqual() const WARN_UNUSED_RESULT; |
131 return new (zone_) \ | 96 const Operator* NumberLessThan() const WARN_UNUSED_RESULT; |
132 Operator1<ptype>(IrOpcode::k##name, properties | Operator::kNoThrow, \ | 97 const Operator* NumberLessThanOrEqual() const WARN_UNUSED_RESULT; |
133 inputs, outputs, #name, pname) | 98 const Operator* NumberAdd() const WARN_UNUSED_RESULT; |
| 99 const Operator* NumberSubtract() const WARN_UNUSED_RESULT; |
| 100 const Operator* NumberMultiply() const WARN_UNUSED_RESULT; |
| 101 const Operator* NumberDivide() const WARN_UNUSED_RESULT; |
| 102 const Operator* NumberModulus() const WARN_UNUSED_RESULT; |
| 103 const Operator* NumberToInt32() const WARN_UNUSED_RESULT; |
| 104 const Operator* NumberToUint32() const WARN_UNUSED_RESULT; |
134 | 105 |
135 #define UNOP(name) SIMPLE(name, Operator::kPure, 1, 1) | 106 const Operator* ReferenceEqual(Type* type) const WARN_UNUSED_RESULT; |
136 #define BINOP(name) SIMPLE(name, Operator::kPure, 2, 1) | |
137 | 107 |
138 const Operator* BooleanNot() const { UNOP(BooleanNot); } | 108 const Operator* StringEqual() const WARN_UNUSED_RESULT; |
| 109 const Operator* StringLessThan() const WARN_UNUSED_RESULT; |
| 110 const Operator* StringLessThanOrEqual() const WARN_UNUSED_RESULT; |
| 111 const Operator* StringAdd() const WARN_UNUSED_RESULT; |
139 | 112 |
140 const Operator* NumberEqual() const { BINOP(NumberEqual); } | 113 const Operator* ChangeTaggedToInt32() const WARN_UNUSED_RESULT; |
141 const Operator* NumberLessThan() const { BINOP(NumberLessThan); } | 114 const Operator* ChangeTaggedToUint32() const WARN_UNUSED_RESULT; |
142 const Operator* NumberLessThanOrEqual() const { | 115 const Operator* ChangeTaggedToFloat64() const WARN_UNUSED_RESULT; |
143 BINOP(NumberLessThanOrEqual); | 116 const Operator* ChangeInt32ToTagged() const WARN_UNUSED_RESULT; |
144 } | 117 const Operator* ChangeUint32ToTagged() const WARN_UNUSED_RESULT; |
145 const Operator* NumberAdd() const { BINOP(NumberAdd); } | 118 const Operator* ChangeFloat64ToTagged() const WARN_UNUSED_RESULT; |
146 const Operator* NumberSubtract() const { BINOP(NumberSubtract); } | 119 const Operator* ChangeBoolToBit() const WARN_UNUSED_RESULT; |
147 const Operator* NumberMultiply() const { BINOP(NumberMultiply); } | 120 const Operator* ChangeBitToBool() const WARN_UNUSED_RESULT; |
148 const Operator* NumberDivide() const { BINOP(NumberDivide); } | |
149 const Operator* NumberModulus() const { BINOP(NumberModulus); } | |
150 const Operator* NumberToInt32() const { UNOP(NumberToInt32); } | |
151 const Operator* NumberToUint32() const { UNOP(NumberToUint32); } | |
152 | 121 |
153 const Operator* ReferenceEqual(Type* type) const { BINOP(ReferenceEqual); } | 122 const Operator* LoadField(const FieldAccess&) const WARN_UNUSED_RESULT; |
154 | 123 const Operator* StoreField(const FieldAccess&) const WARN_UNUSED_RESULT; |
155 const Operator* StringEqual() const { BINOP(StringEqual); } | 124 const Operator* LoadElement(const ElementAccess&) const WARN_UNUSED_RESULT; |
156 const Operator* StringLessThan() const { BINOP(StringLessThan); } | 125 const Operator* StoreElement(const ElementAccess&) const WARN_UNUSED_RESULT; |
157 const Operator* StringLessThanOrEqual() const { | |
158 BINOP(StringLessThanOrEqual); | |
159 } | |
160 const Operator* StringAdd() const { BINOP(StringAdd); } | |
161 | |
162 const Operator* ChangeTaggedToInt32() const { UNOP(ChangeTaggedToInt32); } | |
163 const Operator* ChangeTaggedToUint32() const { UNOP(ChangeTaggedToUint32); } | |
164 const Operator* ChangeTaggedToFloat64() const { UNOP(ChangeTaggedToFloat64); } | |
165 const Operator* ChangeInt32ToTagged() const { UNOP(ChangeInt32ToTagged); } | |
166 const Operator* ChangeUint32ToTagged() const { UNOP(ChangeUint32ToTagged); } | |
167 const Operator* ChangeFloat64ToTagged() const { UNOP(ChangeFloat64ToTagged); } | |
168 const Operator* ChangeBoolToBit() const { UNOP(ChangeBoolToBit); } | |
169 const Operator* ChangeBitToBool() const { UNOP(ChangeBitToBool); } | |
170 | |
171 const Operator* LoadField(const FieldAccess& access) const { | |
172 OP1(LoadField, FieldAccess, access, Operator::kNoWrite, 1, 1); | |
173 } | |
174 const Operator* StoreField(const FieldAccess& access) const { | |
175 OP1(StoreField, FieldAccess, access, Operator::kNoRead, 2, 0); | |
176 } | |
177 const Operator* LoadElement(const ElementAccess& access) const { | |
178 OP1(LoadElement, ElementAccess, access, Operator::kNoWrite, 2, 1); | |
179 } | |
180 const Operator* StoreElement(const ElementAccess& access) const { | |
181 OP1(StoreElement, ElementAccess, access, Operator::kNoRead, 3, 0); | |
182 } | |
183 | |
184 #undef BINOP | |
185 #undef UNOP | |
186 #undef OP1 | |
187 #undef SIMPLE | |
188 | 126 |
189 private: | 127 private: |
190 Zone* zone_; | 128 Zone* zone() const { return zone_; } |
| 129 |
| 130 const SimplifiedOperatorBuilderImpl& impl_; |
| 131 Zone* const zone_; |
| 132 |
| 133 DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorBuilder); |
191 }; | 134 }; |
192 } | 135 |
193 } | 136 } // namespace compiler |
194 } // namespace v8::internal::compiler | 137 } // namespace internal |
| 138 } // namespace v8 |
195 | 139 |
196 #endif // V8_COMPILER_SIMPLIFIED_OPERATOR_H_ | 140 #endif // V8_COMPILER_SIMPLIFIED_OPERATOR_H_ |
OLD | NEW |