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.h" | 10 #include "src/types.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 DCHECK(op->opcode() == IrOpcode::kLoadElement || | 170 DCHECK(op->opcode() == IrOpcode::kLoadElement || |
171 op->opcode() == IrOpcode::kStoreElement); | 171 op->opcode() == IrOpcode::kStoreElement); |
172 return OpParameter<ElementAccess>(op); | 172 return OpParameter<ElementAccess>(op); |
173 } | 173 } |
174 | 174 |
175 Type* TypeOf(const Operator* op) { | 175 Type* TypeOf(const Operator* op) { |
176 DCHECK_EQ(IrOpcode::kTypeGuard, op->opcode()); | 176 DCHECK_EQ(IrOpcode::kTypeGuard, op->opcode()); |
177 return OpParameter<Type*>(op); | 177 return OpParameter<Type*>(op); |
178 } | 178 } |
179 | 179 |
| 180 BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op) { |
| 181 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd || |
| 182 op->opcode() == IrOpcode::kSpeculativeNumberSubtract); |
| 183 return OpParameter<BinaryOperationHints::Hint>(op); |
| 184 } |
| 185 |
180 #define PURE_OP_LIST(V) \ | 186 #define PURE_OP_LIST(V) \ |
181 V(BooleanNot, Operator::kNoProperties, 1) \ | 187 V(BooleanNot, Operator::kNoProperties, 1) \ |
182 V(BooleanToNumber, Operator::kNoProperties, 1) \ | 188 V(BooleanToNumber, Operator::kNoProperties, 1) \ |
183 V(NumberEqual, Operator::kCommutative, 2) \ | 189 V(NumberEqual, Operator::kCommutative, 2) \ |
184 V(NumberLessThan, Operator::kNoProperties, 2) \ | 190 V(NumberLessThan, Operator::kNoProperties, 2) \ |
185 V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \ | 191 V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \ |
186 V(NumberAdd, Operator::kCommutative, 2) \ | 192 V(NumberAdd, Operator::kCommutative, 2) \ |
187 V(NumberSubtract, Operator::kNoProperties, 2) \ | 193 V(NumberSubtract, Operator::kNoProperties, 2) \ |
188 V(NumberMultiply, Operator::kCommutative, 2) \ | 194 V(NumberMultiply, Operator::kCommutative, 2) \ |
189 V(NumberDivide, Operator::kNoProperties, 2) \ | 195 V(NumberDivide, Operator::kNoProperties, 2) \ |
(...skipping 28 matching lines...) Expand all Loading... |
218 V(ObjectIsCallable, Operator::kNoProperties, 1) \ | 224 V(ObjectIsCallable, Operator::kNoProperties, 1) \ |
219 V(ObjectIsNumber, Operator::kNoProperties, 1) \ | 225 V(ObjectIsNumber, Operator::kNoProperties, 1) \ |
220 V(ObjectIsReceiver, Operator::kNoProperties, 1) \ | 226 V(ObjectIsReceiver, Operator::kNoProperties, 1) \ |
221 V(ObjectIsSmi, Operator::kNoProperties, 1) \ | 227 V(ObjectIsSmi, Operator::kNoProperties, 1) \ |
222 V(ObjectIsString, Operator::kNoProperties, 1) \ | 228 V(ObjectIsString, Operator::kNoProperties, 1) \ |
223 V(ObjectIsUndetectable, Operator::kNoProperties, 1) \ | 229 V(ObjectIsUndetectable, Operator::kNoProperties, 1) \ |
224 V(StringEqual, Operator::kCommutative, 2) \ | 230 V(StringEqual, Operator::kCommutative, 2) \ |
225 V(StringLessThan, Operator::kNoProperties, 2) \ | 231 V(StringLessThan, Operator::kNoProperties, 2) \ |
226 V(StringLessThanOrEqual, Operator::kNoProperties, 2) | 232 V(StringLessThanOrEqual, Operator::kNoProperties, 2) |
227 | 233 |
| 234 #define CHECKED_OP_LIST(V) \ |
| 235 V(CheckedUint32ToInt32) \ |
| 236 V(CheckedFloat64ToInt32) \ |
| 237 V(CheckedTaggedToInt32) \ |
| 238 V(CheckedTaggedToFloat64) |
| 239 |
228 struct SimplifiedOperatorGlobalCache final { | 240 struct SimplifiedOperatorGlobalCache final { |
229 #define PURE(Name, properties, input_count) \ | 241 #define PURE(Name, properties, input_count) \ |
230 struct Name##Operator final : public Operator { \ | 242 struct Name##Operator final : public Operator { \ |
231 Name##Operator() \ | 243 Name##Operator() \ |
232 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ | 244 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ |
233 input_count, 0, 0, 1, 0, 0) {} \ | 245 input_count, 0, 0, 1, 0, 0) {} \ |
234 }; \ | 246 }; \ |
235 Name##Operator k##Name; | 247 Name##Operator k##Name; |
236 PURE_OP_LIST(PURE) | 248 PURE_OP_LIST(PURE) |
237 #undef PURE | 249 #undef PURE |
238 | 250 |
| 251 #define CHECKED(Name) \ |
| 252 struct Name##Operator final : public Operator { \ |
| 253 Name##Operator() \ |
| 254 : Operator(IrOpcode::k##Name, Operator::kNoThrow, #Name, 1, 1, 1, 1, \ |
| 255 1, 1) {} \ |
| 256 }; \ |
| 257 Name##Operator k##Name; |
| 258 CHECKED_OP_LIST(CHECKED) |
| 259 #undef CHECKED |
| 260 |
239 template <PretenureFlag kPretenure> | 261 template <PretenureFlag kPretenure> |
240 struct AllocateOperator final : public Operator1<PretenureFlag> { | 262 struct AllocateOperator final : public Operator1<PretenureFlag> { |
241 AllocateOperator() | 263 AllocateOperator() |
242 : Operator1<PretenureFlag>(IrOpcode::kAllocate, Operator::kNoThrow, | 264 : Operator1<PretenureFlag>(IrOpcode::kAllocate, Operator::kNoThrow, |
243 "Allocate", 1, 1, 1, 1, 1, 0, kPretenure) {} | 265 "Allocate", 1, 1, 1, 1, 1, 0, kPretenure) {} |
244 }; | 266 }; |
245 AllocateOperator<NOT_TENURED> kAllocateNotTenuredOperator; | 267 AllocateOperator<NOT_TENURED> kAllocateNotTenuredOperator; |
246 AllocateOperator<TENURED> kAllocateTenuredOperator; | 268 AllocateOperator<TENURED> kAllocateTenuredOperator; |
247 | 269 |
248 #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ | 270 #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ |
(...skipping 18 matching lines...) Expand all Loading... |
267 }; | 289 }; |
268 | 290 |
269 | 291 |
270 static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache = | 292 static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache = |
271 LAZY_INSTANCE_INITIALIZER; | 293 LAZY_INSTANCE_INITIALIZER; |
272 | 294 |
273 | 295 |
274 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone) | 296 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone) |
275 : cache_(kCache.Get()), zone_(zone) {} | 297 : cache_(kCache.Get()), zone_(zone) {} |
276 | 298 |
277 | |
278 #define GET_FROM_CACHE(Name, properties, input_count) \ | 299 #define GET_FROM_CACHE(Name, properties, input_count) \ |
279 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } | 300 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } |
280 PURE_OP_LIST(GET_FROM_CACHE) | 301 PURE_OP_LIST(GET_FROM_CACHE) |
281 #undef GET_FROM_CACHE | 302 #undef GET_FROM_CACHE |
282 | 303 |
| 304 #define GET_FROM_CACHE(Name) \ |
| 305 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } |
| 306 CHECKED_OP_LIST(GET_FROM_CACHE) |
| 307 #undef GET_FROM_CACHE |
283 | 308 |
284 const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) { | 309 const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) { |
285 return new (zone()) Operator(IrOpcode::kReferenceEqual, | 310 return new (zone()) Operator(IrOpcode::kReferenceEqual, |
286 Operator::kCommutative | Operator::kPure, | 311 Operator::kCommutative | Operator::kPure, |
287 "ReferenceEqual", 2, 0, 0, 1, 0, 0); | 312 "ReferenceEqual", 2, 0, 0, 1, 0, 0); |
288 } | 313 } |
289 | 314 |
290 const Operator* SimplifiedOperatorBuilder::TypeGuard(Type* type) { | 315 const Operator* SimplifiedOperatorBuilder::TypeGuard(Type* type) { |
291 class TypeGuardOperator final : public Operator1<Type*> { | 316 class TypeGuardOperator final : public Operator1<Type*> { |
292 public: | 317 public: |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 #define STORE_BUFFER(Type, type, TYPE, ctype, size) \ | 359 #define STORE_BUFFER(Type, type, TYPE, ctype, size) \ |
335 case kExternal##Type##Array: \ | 360 case kExternal##Type##Array: \ |
336 return &cache_.kStoreBuffer##Type; | 361 return &cache_.kStoreBuffer##Type; |
337 TYPED_ARRAYS(STORE_BUFFER) | 362 TYPED_ARRAYS(STORE_BUFFER) |
338 #undef STORE_BUFFER | 363 #undef STORE_BUFFER |
339 } | 364 } |
340 UNREACHABLE(); | 365 UNREACHABLE(); |
341 return nullptr; | 366 return nullptr; |
342 } | 367 } |
343 | 368 |
| 369 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberAdd( |
| 370 BinaryOperationHints::Hint hint) { |
| 371 return new (zone()) Operator1<BinaryOperationHints::Hint>( |
| 372 IrOpcode::kSpeculativeNumberAdd, Operator::kNoThrow, |
| 373 "SpeculativeNumberAdd", 2, 1, 1, 1, 1, 1, hint); |
| 374 } |
| 375 |
| 376 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberSubtract( |
| 377 BinaryOperationHints::Hint hint) { |
| 378 return new (zone()) Operator1<BinaryOperationHints::Hint>( |
| 379 IrOpcode::kSpeculativeNumberSubtract, Operator::kNoThrow, |
| 380 "SpeculativeNumberSubtract", 2, 1, 1, 1, 1, 1, hint); |
| 381 } |
344 | 382 |
345 #define ACCESS_OP_LIST(V) \ | 383 #define ACCESS_OP_LIST(V) \ |
346 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ | 384 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ |
347 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ | 385 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ |
348 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ | 386 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ |
349 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) | 387 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) |
350 | 388 |
351 | 389 |
352 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ | 390 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ |
353 output_count) \ | 391 output_count) \ |
354 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ | 392 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ |
355 return new (zone()) \ | 393 return new (zone()) \ |
356 Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties, \ | 394 Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties, \ |
357 #Name, value_input_count, 1, control_input_count, \ | 395 #Name, value_input_count, 1, control_input_count, \ |
358 output_count, 1, 0, access); \ | 396 output_count, 1, 0, access); \ |
359 } | 397 } |
360 ACCESS_OP_LIST(ACCESS) | 398 ACCESS_OP_LIST(ACCESS) |
361 #undef ACCESS | 399 #undef ACCESS |
362 | 400 |
363 } // namespace compiler | 401 } // namespace compiler |
364 } // namespace internal | 402 } // namespace internal |
365 } // namespace v8 | 403 } // namespace v8 |
OLD | NEW |