OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #include "src/compiler/simplified-operator.h" | 5 #include "src/compiler/simplified-operator.h" |
6 | 6 |
7 #include "src/base/lazy-instance.h" | 7 #include "src/base/lazy-instance.h" |
8 #include "src/compiler/opcodes.h" | 8 #include "src/compiler/opcodes.h" |
9 #include "src/compiler/operator.h" | 9 #include "src/compiler/operator.h" |
10 #include "src/types-inl.h" | 10 #include "src/types-inl.h" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 namespace compiler { | 14 namespace compiler { |
15 | 15 |
16 std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) { | 16 std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) { |
17 switch (base_taggedness) { | 17 switch (base_taggedness) { |
18 case kUntaggedBase: | 18 case kUntaggedBase: |
19 return os << "untagged base"; | 19 return os << "untagged base"; |
20 case kTaggedBase: | 20 case kTaggedBase: |
21 return os << "tagged base"; | 21 return os << "tagged base"; |
22 } | 22 } |
23 UNREACHABLE(); | 23 UNREACHABLE(); |
24 return os; | 24 return os; |
25 } | 25 } |
26 | 26 |
27 | 27 |
| 28 MachineType BufferAccess::machine_type() const { |
| 29 switch (external_array_type_) { |
| 30 case kExternalUint8Array: |
| 31 return kMachUint8; |
| 32 case kExternalInt8Array: |
| 33 return kMachInt8; |
| 34 case kExternalUint16Array: |
| 35 return kMachUint16; |
| 36 case kExternalInt16Array: |
| 37 return kMachInt16; |
| 38 case kExternalUint32Array: |
| 39 return kMachUint32; |
| 40 case kExternalInt32Array: |
| 41 return kMachInt32; |
| 42 case kExternalFloat32Array: |
| 43 return kMachFloat32; |
| 44 case kExternalFloat64Array: |
| 45 return kMachFloat64; |
| 46 case kExternalUint8ClampedArray: |
| 47 break; |
| 48 } |
| 49 UNREACHABLE(); |
| 50 return kMachNone; |
| 51 } |
| 52 |
| 53 |
| 54 bool operator==(BufferAccess lhs, BufferAccess rhs) { |
| 55 return lhs.external_array_type() == rhs.external_array_type(); |
| 56 } |
| 57 |
| 58 |
| 59 bool operator!=(BufferAccess lhs, BufferAccess rhs) { return !(lhs == rhs); } |
| 60 |
| 61 |
| 62 size_t hash_value(BufferAccess access) { |
| 63 return base::hash<ExternalArrayType>()(access.external_array_type()); |
| 64 } |
| 65 |
| 66 |
| 67 std::ostream& operator<<(std::ostream& os, BufferAccess access) { |
| 68 switch (access.external_array_type()) { |
| 69 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 70 case kExternal##Type##Array: \ |
| 71 return os << #Type; |
| 72 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 73 #undef TYPED_ARRAY_CASE |
| 74 } |
| 75 UNREACHABLE(); |
| 76 return os; |
| 77 } |
| 78 |
| 79 |
| 80 BufferAccess const BufferAccessOf(const Operator* op) { |
| 81 DCHECK(op->opcode() == IrOpcode::kLoadBuffer || |
| 82 op->opcode() == IrOpcode::kStoreBuffer); |
| 83 return OpParameter<BufferAccess>(op); |
| 84 } |
| 85 |
| 86 |
28 bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) { | 87 bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) { |
29 return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset && | 88 return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset && |
30 lhs.machine_type == rhs.machine_type; | 89 lhs.machine_type == rhs.machine_type; |
31 } | 90 } |
32 | 91 |
33 | 92 |
34 bool operator!=(FieldAccess const& lhs, FieldAccess const& rhs) { | 93 bool operator!=(FieldAccess const& lhs, FieldAccess const& rhs) { |
35 return !(lhs == rhs); | 94 return !(lhs == rhs); |
36 } | 95 } |
37 | 96 |
(...skipping 12 matching lines...) Expand all Loading... |
50 name->Print(os); | 109 name->Print(os); |
51 os << ", "; | 110 os << ", "; |
52 } | 111 } |
53 #endif | 112 #endif |
54 access.type->PrintTo(os); | 113 access.type->PrintTo(os); |
55 os << ", " << access.machine_type << "]"; | 114 os << ", " << access.machine_type << "]"; |
56 return os; | 115 return os; |
57 } | 116 } |
58 | 117 |
59 | 118 |
60 std::ostream& operator<<(std::ostream& os, BoundsCheckMode bounds_check_mode) { | |
61 switch (bounds_check_mode) { | |
62 case kNoBoundsCheck: | |
63 return os << "no bounds check"; | |
64 case kTypedArrayBoundsCheck: | |
65 return os << "ignore out of bounds"; | |
66 } | |
67 UNREACHABLE(); | |
68 return os; | |
69 } | |
70 | |
71 | |
72 bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) { | 119 bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) { |
73 return lhs.base_is_tagged == rhs.base_is_tagged && | 120 return lhs.base_is_tagged == rhs.base_is_tagged && |
74 lhs.header_size == rhs.header_size && | 121 lhs.header_size == rhs.header_size && |
75 lhs.machine_type == rhs.machine_type; | 122 lhs.machine_type == rhs.machine_type; |
76 } | 123 } |
77 | 124 |
78 | 125 |
79 bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs) { | 126 bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs) { |
80 return !(lhs == rhs); | 127 return !(lhs == rhs); |
81 } | 128 } |
82 | 129 |
83 | 130 |
84 size_t hash_value(ElementAccess const& access) { | 131 size_t hash_value(ElementAccess const& access) { |
85 return base::hash_combine(access.base_is_tagged, access.header_size, | 132 return base::hash_combine(access.base_is_tagged, access.header_size, |
86 access.machine_type); | 133 access.machine_type); |
87 } | 134 } |
88 | 135 |
89 | 136 |
90 std::ostream& operator<<(std::ostream& os, ElementAccess const& access) { | 137 std::ostream& operator<<(std::ostream& os, ElementAccess const& access) { |
91 os << access.base_is_tagged << ", " << access.header_size << ", "; | 138 os << access.base_is_tagged << ", " << access.header_size << ", "; |
92 access.type->PrintTo(os); | 139 access.type->PrintTo(os); |
93 os << ", " << access.machine_type << ", " << access.bounds_check; | 140 os << ", " << access.machine_type; |
94 return os; | 141 return os; |
95 } | 142 } |
96 | 143 |
97 | 144 |
98 const FieldAccess& FieldAccessOf(const Operator* op) { | 145 const FieldAccess& FieldAccessOf(const Operator* op) { |
99 DCHECK_NOT_NULL(op); | 146 DCHECK_NOT_NULL(op); |
100 DCHECK(op->opcode() == IrOpcode::kLoadField || | 147 DCHECK(op->opcode() == IrOpcode::kLoadField || |
101 op->opcode() == IrOpcode::kStoreField); | 148 op->opcode() == IrOpcode::kStoreField); |
102 return OpParameter<FieldAccess>(op); | 149 return OpParameter<FieldAccess>(op); |
103 } | 150 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 struct SimplifiedOperatorGlobalCache FINAL { | 190 struct SimplifiedOperatorGlobalCache FINAL { |
144 #define PURE(Name, properties, input_count) \ | 191 #define PURE(Name, properties, input_count) \ |
145 struct Name##Operator FINAL : public Operator { \ | 192 struct Name##Operator FINAL : public Operator { \ |
146 Name##Operator() \ | 193 Name##Operator() \ |
147 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ | 194 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ |
148 input_count, 0, 0, 1, 0, 0) {} \ | 195 input_count, 0, 0, 1, 0, 0) {} \ |
149 }; \ | 196 }; \ |
150 Name##Operator k##Name; | 197 Name##Operator k##Name; |
151 PURE_OP_LIST(PURE) | 198 PURE_OP_LIST(PURE) |
152 #undef PURE | 199 #undef PURE |
| 200 |
| 201 #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ |
| 202 struct LoadBuffer##Type##Operator FINAL : public Operator1<BufferAccess> { \ |
| 203 LoadBuffer##Type##Operator() \ |
| 204 : Operator1<BufferAccess>(IrOpcode::kLoadBuffer, \ |
| 205 Operator::kNoThrow | Operator::kNoWrite, \ |
| 206 "LoadBuffer", 3, 1, 1, 1, 1, 0, \ |
| 207 BufferAccess(kExternal##Type##Array)) {} \ |
| 208 }; \ |
| 209 struct StoreBuffer##Type##Operator FINAL : public Operator1<BufferAccess> { \ |
| 210 StoreBuffer##Type##Operator() \ |
| 211 : Operator1<BufferAccess>(IrOpcode::kStoreBuffer, \ |
| 212 Operator::kNoRead | Operator::kNoThrow, \ |
| 213 "StoreBuffer", 4, 1, 1, 0, 1, 0, \ |
| 214 BufferAccess(kExternal##Type##Array)) {} \ |
| 215 }; \ |
| 216 LoadBuffer##Type##Operator kLoadBuffer##Type; \ |
| 217 StoreBuffer##Type##Operator kStoreBuffer##Type; |
| 218 TYPED_ARRAYS(BUFFER_ACCESS) |
| 219 #undef BUFFER_ACCESS |
153 }; | 220 }; |
154 | 221 |
155 | 222 |
156 static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache = | 223 static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache = |
157 LAZY_INSTANCE_INITIALIZER; | 224 LAZY_INSTANCE_INITIALIZER; |
158 | 225 |
159 | 226 |
160 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone) | 227 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone) |
161 : cache_(kCache.Get()), zone_(zone) {} | 228 : cache_(kCache.Get()), zone_(zone) {} |
162 | 229 |
163 | 230 |
164 #define PURE(Name, properties, input_count) \ | 231 #define PURE(Name, properties, input_count) \ |
165 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } | 232 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } |
166 PURE_OP_LIST(PURE) | 233 PURE_OP_LIST(PURE) |
167 #undef PURE | 234 #undef PURE |
168 | 235 |
169 | 236 |
170 const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) { | 237 const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) { |
171 // TODO(titzer): What about the type parameter? | 238 // TODO(titzer): What about the type parameter? |
172 return new (zone()) Operator(IrOpcode::kReferenceEqual, | 239 return new (zone()) Operator(IrOpcode::kReferenceEqual, |
173 Operator::kCommutative | Operator::kPure, | 240 Operator::kCommutative | Operator::kPure, |
174 "ReferenceEqual", 2, 0, 0, 1, 0, 0); | 241 "ReferenceEqual", 2, 0, 0, 1, 0, 0); |
175 } | 242 } |
176 | 243 |
177 | 244 |
| 245 const Operator* SimplifiedOperatorBuilder::LoadBuffer(BufferAccess access) { |
| 246 switch (access.external_array_type()) { |
| 247 #define LOAD_BUFFER(Type, type, TYPE, ctype, size) \ |
| 248 case kExternal##Type##Array: \ |
| 249 return &cache_.kLoadBuffer##Type; |
| 250 TYPED_ARRAYS(LOAD_BUFFER) |
| 251 #undef LOAD_BUFFER |
| 252 } |
| 253 UNREACHABLE(); |
| 254 return nullptr; |
| 255 } |
| 256 |
| 257 |
| 258 const Operator* SimplifiedOperatorBuilder::StoreBuffer(BufferAccess access) { |
| 259 switch (access.external_array_type()) { |
| 260 #define STORE_BUFFER(Type, type, TYPE, ctype, size) \ |
| 261 case kExternal##Type##Array: \ |
| 262 return &cache_.kStoreBuffer##Type; |
| 263 TYPED_ARRAYS(STORE_BUFFER) |
| 264 #undef STORE_BUFFER |
| 265 } |
| 266 UNREACHABLE(); |
| 267 return nullptr; |
| 268 } |
| 269 |
| 270 |
178 #define ACCESS_OP_LIST(V) \ | 271 #define ACCESS_OP_LIST(V) \ |
179 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ | 272 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ |
180 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ | 273 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ |
181 V(LoadElement, ElementAccess, Operator::kNoWrite, 3, 0, 1) \ | 274 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ |
182 V(StoreElement, ElementAccess, Operator::kNoRead, 4, 1, 0) | 275 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) |
183 | 276 |
184 | 277 |
185 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ | 278 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ |
186 output_count) \ | 279 output_count) \ |
187 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ | 280 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ |
188 return new (zone()) \ | 281 return new (zone()) \ |
189 Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties, \ | 282 Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties, \ |
190 #Name, value_input_count, 1, control_input_count, \ | 283 #Name, value_input_count, 1, control_input_count, \ |
191 output_count, 1, 0, access); \ | 284 output_count, 1, 0, access); \ |
192 } | 285 } |
193 ACCESS_OP_LIST(ACCESS) | 286 ACCESS_OP_LIST(ACCESS) |
194 #undef ACCESS | 287 #undef ACCESS |
195 | 288 |
196 } // namespace compiler | 289 } // namespace compiler |
197 } // namespace internal | 290 } // namespace internal |
198 } // namespace v8 | 291 } // namespace v8 |
OLD | NEW |