| 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 #include "src/compiler/machine-operator.h" | 5 #include "src/compiler/machine-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 | 10 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 return base::hash_combine(rep.machine_type(), rep.write_barrier_kind()); | 61 return base::hash_combine(rep.machine_type(), rep.write_barrier_kind()); |
| 62 } | 62 } |
| 63 | 63 |
| 64 | 64 |
| 65 std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) { | 65 std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) { |
| 66 return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind() | 66 return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind() |
| 67 << ")"; | 67 << ")"; |
| 68 } | 68 } |
| 69 | 69 |
| 70 | 70 |
| 71 LoadRepresentation LoadRepresentationOf(Operator const* op) { |
| 72 DCHECK_EQ(IrOpcode::kLoad, op->opcode()); |
| 73 return OpParameter<LoadRepresentation>(op); |
| 74 } |
| 75 |
| 76 |
| 71 StoreRepresentation const& StoreRepresentationOf(Operator const* op) { | 77 StoreRepresentation const& StoreRepresentationOf(Operator const* op) { |
| 72 DCHECK_EQ(IrOpcode::kStore, op->opcode()); | 78 DCHECK_EQ(IrOpcode::kStore, op->opcode()); |
| 73 return OpParameter<StoreRepresentation>(op); | 79 return OpParameter<StoreRepresentation>(op); |
| 74 } | 80 } |
| 75 | 81 |
| 76 | 82 |
| 77 CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const* op) { | 83 CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const* op) { |
| 78 DCHECK_EQ(IrOpcode::kCheckedLoad, op->opcode()); | 84 DCHECK_EQ(IrOpcode::kCheckedLoad, op->opcode()); |
| 79 return OpParameter<CheckedLoadRepresentation>(op); | 85 return OpParameter<CheckedLoadRepresentation>(op); |
| 80 } | 86 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 V(Float32RoundUp, Operator::kNoProperties, 1, 0, 1) \ | 199 V(Float32RoundUp, Operator::kNoProperties, 1, 0, 1) \ |
| 194 V(Float64RoundUp, Operator::kNoProperties, 1, 0, 1) \ | 200 V(Float64RoundUp, Operator::kNoProperties, 1, 0, 1) \ |
| 195 V(Float32RoundTruncate, Operator::kNoProperties, 1, 0, 1) \ | 201 V(Float32RoundTruncate, Operator::kNoProperties, 1, 0, 1) \ |
| 196 V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \ | 202 V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \ |
| 197 V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \ | 203 V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \ |
| 198 V(Float32RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \ | 204 V(Float32RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \ |
| 199 V(Float64RoundTiesEven, Operator::kNoProperties, 1, 0, 1) | 205 V(Float64RoundTiesEven, Operator::kNoProperties, 1, 0, 1) |
| 200 | 206 |
| 201 | 207 |
| 202 #define MACHINE_TYPE_LIST(V) \ | 208 #define MACHINE_TYPE_LIST(V) \ |
| 203 V(MachFloat32) \ | 209 V(Float32) \ |
| 204 V(MachFloat64) \ | 210 V(Float64) \ |
| 205 V(MachInt8) \ | 211 V(Int8) \ |
| 206 V(MachUint8) \ | 212 V(Uint8) \ |
| 207 V(MachInt16) \ | 213 V(Int16) \ |
| 208 V(MachUint16) \ | 214 V(Uint16) \ |
| 209 V(MachInt32) \ | 215 V(Int32) \ |
| 210 V(MachUint32) \ | 216 V(Uint32) \ |
| 211 V(MachInt64) \ | 217 V(Int64) \ |
| 212 V(MachUint64) \ | 218 V(Uint64) \ |
| 213 V(MachPtr) \ | 219 V(Pointer) \ |
| 214 V(MachAnyTagged) | 220 V(AnyTagged) |
| 215 | 221 |
| 216 | 222 |
| 217 struct MachineOperatorGlobalCache { | 223 struct MachineOperatorGlobalCache { |
| 218 #define PURE(Name, properties, value_input_count, control_input_count, \ | 224 #define PURE(Name, properties, value_input_count, control_input_count, \ |
| 219 output_count) \ | 225 output_count) \ |
| 220 struct Name##Operator final : public Operator { \ | 226 struct Name##Operator final : public Operator { \ |
| 221 Name##Operator() \ | 227 Name##Operator() \ |
| 222 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ | 228 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ |
| 223 value_input_count, 0, control_input_count, output_count, 0, \ | 229 value_input_count, 0, control_input_count, output_count, 0, \ |
| 224 0) {} \ | 230 0) {} \ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 239 TruncateFloat64ToInt32Operator<TruncationMode::kJavaScript> | 245 TruncateFloat64ToInt32Operator<TruncationMode::kJavaScript> |
| 240 kTruncateFloat64ToInt32JavaScript; | 246 kTruncateFloat64ToInt32JavaScript; |
| 241 TruncateFloat64ToInt32Operator<TruncationMode::kRoundToZero> | 247 TruncateFloat64ToInt32Operator<TruncationMode::kRoundToZero> |
| 242 kTruncateFloat64ToInt32RoundToZero; | 248 kTruncateFloat64ToInt32RoundToZero; |
| 243 | 249 |
| 244 #define LOAD(Type) \ | 250 #define LOAD(Type) \ |
| 245 struct Load##Type##Operator final : public Operator1<LoadRepresentation> { \ | 251 struct Load##Type##Operator final : public Operator1<LoadRepresentation> { \ |
| 246 Load##Type##Operator() \ | 252 Load##Type##Operator() \ |
| 247 : Operator1<LoadRepresentation>( \ | 253 : Operator1<LoadRepresentation>( \ |
| 248 IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, \ | 254 IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, \ |
| 249 "Load", 2, 1, 1, 1, 1, 0, k##Type) {} \ | 255 "Load", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \ |
| 250 }; \ | 256 }; \ |
| 251 struct CheckedLoad##Type##Operator final \ | 257 struct CheckedLoad##Type##Operator final \ |
| 252 : public Operator1<CheckedLoadRepresentation> { \ | 258 : public Operator1<CheckedLoadRepresentation> { \ |
| 253 CheckedLoad##Type##Operator() \ | 259 CheckedLoad##Type##Operator() \ |
| 254 : Operator1<CheckedLoadRepresentation>( \ | 260 : Operator1<CheckedLoadRepresentation>( \ |
| 255 IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite, \ | 261 IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite, \ |
| 256 "CheckedLoad", 3, 1, 1, 1, 1, 0, k##Type) {} \ | 262 "CheckedLoad", 3, 1, 1, 1, 1, 0, MachineType::Type()) {} \ |
| 257 }; \ | 263 }; \ |
| 258 Load##Type##Operator kLoad##Type; \ | 264 Load##Type##Operator kLoad##Type; \ |
| 259 CheckedLoad##Type##Operator kCheckedLoad##Type; | 265 CheckedLoad##Type##Operator kCheckedLoad##Type; |
| 260 MACHINE_TYPE_LIST(LOAD) | 266 MACHINE_TYPE_LIST(LOAD) |
| 261 #undef LOAD | 267 #undef LOAD |
| 262 | 268 |
| 263 #define STORE(Type) \ | 269 #define STORE(Type) \ |
| 264 struct Store##Type##Operator : public Operator1<StoreRepresentation> { \ | 270 struct Store##Type##Operator : public Operator1<StoreRepresentation> { \ |
| 265 explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind) \ | 271 explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind) \ |
| 266 : Operator1<StoreRepresentation>( \ | 272 : Operator1<StoreRepresentation>( \ |
| 267 IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, \ | 273 IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, \ |
| 268 "Store", 3, 1, 1, 0, 1, 0, \ | 274 "Store", 3, 1, 1, 0, 1, 0, \ |
| 269 StoreRepresentation(k##Type, write_barrier_kind)) {} \ | 275 StoreRepresentation(MachineType::Type(), write_barrier_kind)) {} \ |
| 270 }; \ | 276 }; \ |
| 271 struct Store##Type##NoWriteBarrier##Operator final \ | 277 struct Store##Type##NoWriteBarrier##Operator final \ |
| 272 : public Store##Type##Operator { \ | 278 : public Store##Type##Operator { \ |
| 273 Store##Type##NoWriteBarrier##Operator() \ | 279 Store##Type##NoWriteBarrier##Operator() \ |
| 274 : Store##Type##Operator(kNoWriteBarrier) {} \ | 280 : Store##Type##Operator(kNoWriteBarrier) {} \ |
| 275 }; \ | 281 }; \ |
| 276 struct Store##Type##MapWriteBarrier##Operator final \ | 282 struct Store##Type##MapWriteBarrier##Operator final \ |
| 277 : public Store##Type##Operator { \ | 283 : public Store##Type##Operator { \ |
| 278 Store##Type##MapWriteBarrier##Operator() \ | 284 Store##Type##MapWriteBarrier##Operator() \ |
| 279 : Store##Type##Operator(kMapWriteBarrier) {} \ | 285 : Store##Type##Operator(kMapWriteBarrier) {} \ |
| 280 }; \ | 286 }; \ |
| 281 struct Store##Type##PointerWriteBarrier##Operator final \ | 287 struct Store##Type##PointerWriteBarrier##Operator final \ |
| 282 : public Store##Type##Operator { \ | 288 : public Store##Type##Operator { \ |
| 283 Store##Type##PointerWriteBarrier##Operator() \ | 289 Store##Type##PointerWriteBarrier##Operator() \ |
| 284 : Store##Type##Operator(kPointerWriteBarrier) {} \ | 290 : Store##Type##Operator(kPointerWriteBarrier) {} \ |
| 285 }; \ | 291 }; \ |
| 286 struct Store##Type##FullWriteBarrier##Operator final \ | 292 struct Store##Type##FullWriteBarrier##Operator final \ |
| 287 : public Store##Type##Operator { \ | 293 : public Store##Type##Operator { \ |
| 288 Store##Type##FullWriteBarrier##Operator() \ | 294 Store##Type##FullWriteBarrier##Operator() \ |
| 289 : Store##Type##Operator(kFullWriteBarrier) {} \ | 295 : Store##Type##Operator(kFullWriteBarrier) {} \ |
| 290 }; \ | 296 }; \ |
| 291 struct CheckedStore##Type##Operator final \ | 297 struct CheckedStore##Type##Operator final \ |
| 292 : public Operator1<CheckedStoreRepresentation> { \ | 298 : public Operator1<CheckedStoreRepresentation> { \ |
| 293 CheckedStore##Type##Operator() \ | 299 CheckedStore##Type##Operator() \ |
| 294 : Operator1<CheckedStoreRepresentation>( \ | 300 : Operator1<CheckedStoreRepresentation>( \ |
| 295 IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow, \ | 301 IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow, \ |
| 296 "CheckedStore", 4, 1, 1, 0, 1, 0, k##Type) {} \ | 302 "CheckedStore", 4, 1, 1, 0, 1, 0, MachineType::Type()) {} \ |
| 297 }; \ | 303 }; \ |
| 298 Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier; \ | 304 Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier; \ |
| 299 Store##Type##MapWriteBarrier##Operator kStore##Type##MapWriteBarrier; \ | 305 Store##Type##MapWriteBarrier##Operator kStore##Type##MapWriteBarrier; \ |
| 300 Store##Type##PointerWriteBarrier##Operator \ | 306 Store##Type##PointerWriteBarrier##Operator \ |
| 301 kStore##Type##PointerWriteBarrier; \ | 307 kStore##Type##PointerWriteBarrier; \ |
| 302 Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier; \ | 308 Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier; \ |
| 303 CheckedStore##Type##Operator kCheckedStore##Type; | 309 CheckedStore##Type##Operator kCheckedStore##Type; |
| 304 MACHINE_TYPE_LIST(STORE) | 310 MACHINE_TYPE_LIST(STORE) |
| 305 #undef STORE | 311 #undef STORE |
| 306 }; | 312 }; |
| 307 | 313 |
| 308 | 314 |
| 309 static base::LazyInstance<MachineOperatorGlobalCache>::type kCache = | 315 static base::LazyInstance<MachineOperatorGlobalCache>::type kCache = |
| 310 LAZY_INSTANCE_INITIALIZER; | 316 LAZY_INSTANCE_INITIALIZER; |
| 311 | 317 |
| 312 | 318 |
| 313 MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, MachineType word, | 319 MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, |
| 320 MachineRepresentation word, |
| 314 Flags flags) | 321 Flags flags) |
| 315 : cache_(kCache.Get()), word_(word), flags_(flags) { | 322 : cache_(kCache.Get()), word_(word), flags_(flags) { |
| 316 DCHECK(word == kRepWord32 || word == kRepWord64); | 323 DCHECK(word == MachineRepresentation::kWord32 || |
| 324 word == MachineRepresentation::kWord64); |
| 317 } | 325 } |
| 318 | 326 |
| 319 | 327 |
| 320 #define PURE(Name, properties, value_input_count, control_input_count, \ | 328 #define PURE(Name, properties, value_input_count, control_input_count, \ |
| 321 output_count) \ | 329 output_count) \ |
| 322 const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; } | 330 const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; } |
| 323 PURE_OP_LIST(PURE) | 331 PURE_OP_LIST(PURE) |
| 324 #undef PURE | 332 #undef PURE |
| 325 | 333 |
| 326 #define PURE(Name, properties, value_input_count, control_input_count, \ | 334 #define PURE(Name, properties, value_input_count, control_input_count, \ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 339 return &cache_.kTruncateFloat64ToInt32JavaScript; | 347 return &cache_.kTruncateFloat64ToInt32JavaScript; |
| 340 case TruncationMode::kRoundToZero: | 348 case TruncationMode::kRoundToZero: |
| 341 return &cache_.kTruncateFloat64ToInt32RoundToZero; | 349 return &cache_.kTruncateFloat64ToInt32RoundToZero; |
| 342 } | 350 } |
| 343 UNREACHABLE(); | 351 UNREACHABLE(); |
| 344 return nullptr; | 352 return nullptr; |
| 345 } | 353 } |
| 346 | 354 |
| 347 | 355 |
| 348 const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) { | 356 const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) { |
| 349 switch (rep) { | 357 #define LOAD(Type) \ |
| 350 #define LOAD(Type) \ | 358 if (rep == MachineType::Type()) { \ |
| 351 case k##Type: \ | 359 return &cache_.kLoad##Type; \ |
| 352 return &cache_.kLoad##Type; | 360 } |
| 353 MACHINE_TYPE_LIST(LOAD) | 361 MACHINE_TYPE_LIST(LOAD) |
| 354 #undef LOAD | 362 #undef LOAD |
| 355 default: | |
| 356 break; | |
| 357 } | |
| 358 UNREACHABLE(); | 363 UNREACHABLE(); |
| 359 return nullptr; | 364 return nullptr; |
| 360 } | 365 } |
| 361 | 366 |
| 362 | 367 |
| 363 const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) { | 368 const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) { |
| 364 switch (rep.machine_type()) { | 369 MachineType type = store_rep.machine_type(); |
| 365 #define STORE(Type) \ | 370 #define STORE(Type) \ |
| 366 case k##Type: \ | 371 if (type == MachineType::Type()) { \ |
| 367 switch (rep.write_barrier_kind()) { \ | 372 switch (store_rep.write_barrier_kind()) { \ |
| 368 case kNoWriteBarrier: \ | 373 case kNoWriteBarrier: \ |
| 369 return &cache_.k##Store##Type##NoWriteBarrier; \ | 374 return &cache_.k##Store##Type##NoWriteBarrier; \ |
| 370 case kMapWriteBarrier: \ | 375 case kMapWriteBarrier: \ |
| 371 return &cache_.k##Store##Type##MapWriteBarrier; \ | 376 return &cache_.k##Store##Type##MapWriteBarrier; \ |
| 372 case kPointerWriteBarrier: \ | 377 case kPointerWriteBarrier: \ |
| 373 return &cache_.k##Store##Type##PointerWriteBarrier; \ | 378 return &cache_.k##Store##Type##PointerWriteBarrier; \ |
| 374 case kFullWriteBarrier: \ | 379 case kFullWriteBarrier: \ |
| 375 return &cache_.k##Store##Type##FullWriteBarrier; \ | 380 return &cache_.k##Store##Type##FullWriteBarrier; \ |
| 376 } \ | 381 } \ |
| 377 break; | 382 } |
| 378 MACHINE_TYPE_LIST(STORE) | 383 MACHINE_TYPE_LIST(STORE) |
| 379 #undef STORE | 384 #undef STORE |
| 380 | |
| 381 default: | |
| 382 break; | |
| 383 } | |
| 384 UNREACHABLE(); | 385 UNREACHABLE(); |
| 385 return nullptr; | 386 return nullptr; |
| 386 } | 387 } |
| 387 | 388 |
| 388 | 389 |
| 389 const Operator* MachineOperatorBuilder::CheckedLoad( | 390 const Operator* MachineOperatorBuilder::CheckedLoad( |
| 390 CheckedLoadRepresentation rep) { | 391 CheckedLoadRepresentation rep) { |
| 391 switch (rep) { | 392 #define LOAD(Type) \ |
| 392 #define LOAD(Type) \ | 393 if (rep == MachineType::Type()) { \ |
| 393 case k##Type: \ | 394 return &cache_.kCheckedLoad##Type; \ |
| 394 return &cache_.kCheckedLoad##Type; | 395 } |
| 395 MACHINE_TYPE_LIST(LOAD) | 396 MACHINE_TYPE_LIST(LOAD) |
| 396 #undef LOAD | 397 #undef LOAD |
| 397 default: | |
| 398 break; | |
| 399 } | |
| 400 UNREACHABLE(); | 398 UNREACHABLE(); |
| 401 return nullptr; | 399 return nullptr; |
| 402 } | 400 } |
| 403 | 401 |
| 404 | 402 |
| 405 const Operator* MachineOperatorBuilder::CheckedStore( | 403 const Operator* MachineOperatorBuilder::CheckedStore( |
| 406 CheckedStoreRepresentation rep) { | 404 CheckedStoreRepresentation rep) { |
| 407 switch (rep) { | 405 #define STORE(Type) \ |
| 408 #define STORE(Type) \ | 406 if (rep == MachineType::Type()) { \ |
| 409 case k##Type: \ | 407 return &cache_.kCheckedStore##Type; \ |
| 410 return &cache_.kCheckedStore##Type; | 408 } |
| 411 MACHINE_TYPE_LIST(STORE) | 409 MACHINE_TYPE_LIST(STORE) |
| 412 #undef STORE | 410 #undef STORE |
| 413 default: | |
| 414 break; | |
| 415 } | |
| 416 UNREACHABLE(); | 411 UNREACHABLE(); |
| 417 return nullptr; | 412 return nullptr; |
| 418 } | 413 } |
| 419 | 414 |
| 420 } // namespace compiler | 415 } // namespace compiler |
| 421 } // namespace internal | 416 } // namespace internal |
| 422 } // namespace v8 | 417 } // namespace v8 |
| OLD | NEW |