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 #include "src/compiler/common-operator.h" 6 7 #include "src/assembler.h" 8 #include "src/base/lazy-instance.h" 9 #include "src/compiler/linkage.h" 10 #include "src/compiler/node.h" 11 #include "src/compiler/opcodes.h" 12 #include "src/compiler/operator.h" 13 #include "src/handles-inl.h" 14 #include "src/objects-inl.h" 15 #include "src/zone/zone.h" 16 17 namespace v8 { 18 namespace internal { 19 namespace compiler { 20 21 std::ostream& operator<<(std::ostream& os, BranchHint hint) { 22 switch (hint) { 23 case BranchHint::kNone: 24 return os << "None"; 25 case BranchHint::kTrue: 26 return os << "True"; 27 case BranchHint::kFalse: 28 return os << "False"; 29 } 30 UNREACHABLE(); 31 return os; 32 } 33 34 35 BranchHint BranchHintOf(const Operator* const op) { 36 DCHECK_EQ(IrOpcode::kBranch, op->opcode()); 37 return OpParameter<BranchHint>(op); 38 } 39 40 int ValueInputCountOfReturn(Operator const* const op) { 41 DCHECK(op->opcode() == IrOpcode::kReturn); 42 // Return nodes have a hidden input at index 0 which we ignore in the value 43 // input count. 44 return op->ValueInputCount() - 1; 45 } 46 47 bool operator==(DeoptimizeParameters lhs, DeoptimizeParameters rhs) { 48 return lhs.kind() == rhs.kind() && lhs.reason() == rhs.reason(); 49 } 50 51 bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) { 52 return !(lhs == rhs); 53 } 54 55 size_t hash_value(DeoptimizeParameters p) { 56 return base::hash_combine(p.kind(), p.reason()); 57 } 58 59 std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) { 60 return os << p.kind() << ":" << p.reason(); 61 } 62 63 DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const op) { 64 DCHECK(op->opcode() == IrOpcode::kDeoptimize || 65 op->opcode() == IrOpcode::kDeoptimizeIf || 66 op->opcode() == IrOpcode::kDeoptimizeUnless); 67 return OpParameter<DeoptimizeParameters>(op); 68 } 69 70 71 bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) { 72 return lhs.representation() == rhs.representation() && 73 lhs.hint() == rhs.hint(); 74 } 75 76 77 bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) { 78 return !(lhs == rhs); 79 } 80 81 82 size_t hash_value(SelectParameters const& p) { 83 return base::hash_combine(p.representation(), p.hint()); 84 } 85 86 87 std::ostream& operator<<(std::ostream& os, SelectParameters const& p) { 88 return os << p.representation() << "|" << p.hint(); 89 } 90 91 92 SelectParameters const& SelectParametersOf(const Operator* const op) { 93 DCHECK_EQ(IrOpcode::kSelect, op->opcode()); 94 return OpParameter<SelectParameters>(op); 95 } 96 97 CallDescriptor const* CallDescriptorOf(const Operator* const op) { 98 DCHECK(op->opcode() == IrOpcode::kCall || 99 op->opcode() == IrOpcode::kTailCall); 100 return OpParameter<CallDescriptor const*>(op); 101 } 102 103 size_t ProjectionIndexOf(const Operator* const op) { 104 DCHECK_EQ(IrOpcode::kProjection, op->opcode()); 105 return OpParameter<size_t>(op); 106 } 107 108 109 MachineRepresentation PhiRepresentationOf(const Operator* const op) { 110 DCHECK_EQ(IrOpcode::kPhi, op->opcode()); 111 return OpParameter<MachineRepresentation>(op); 112 } 113 114 115 int ParameterIndexOf(const Operator* const op) { 116 DCHECK_EQ(IrOpcode::kParameter, op->opcode()); 117 return OpParameter<ParameterInfo>(op).index(); 118 } 119 120 121 const ParameterInfo& ParameterInfoOf(const Operator* const op) { 122 DCHECK_EQ(IrOpcode::kParameter, op->opcode()); 123 return OpParameter<ParameterInfo>(op); 124 } 125 126 127 bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) { 128 return lhs.index() == rhs.index(); 129 } 130 131 132 bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) { 133 return !(lhs == rhs); 134 } 135 136 137 size_t hash_value(ParameterInfo const& p) { return p.index(); } 138 139 140 std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) { 141 if (i.debug_name()) os << i.debug_name() << '#'; 142 os << i.index(); 143 return os; 144 } 145 146 bool operator==(RelocatablePtrConstantInfo const& lhs, 147 RelocatablePtrConstantInfo const& rhs) { 148 return lhs.rmode() == rhs.rmode() && lhs.value() == rhs.value() && 149 lhs.type() == rhs.type(); 150 } 151 152 bool operator!=(RelocatablePtrConstantInfo const& lhs, 153 RelocatablePtrConstantInfo const& rhs) { 154 return !(lhs == rhs); 155 } 156 157 size_t hash_value(RelocatablePtrConstantInfo const& p) { 158 return base::hash_combine(p.value(), p.rmode(), p.type()); 159 } 160 161 std::ostream& operator<<(std::ostream& os, 162 RelocatablePtrConstantInfo const& p) { 163 return os << p.value() << "|" << p.rmode() << "|" << p.type(); 164 } 165 166 SparseInputMask::InputIterator::InputIterator( 167 SparseInputMask::BitMaskType bit_mask, Node* parent) 168 : bit_mask_(bit_mask), parent_(parent), real_index_(0) { 169 #if DEBUG 170 if (bit_mask_ != SparseInputMask::kDenseBitMask) { 171 DCHECK_EQ(base::bits::CountPopulation(bit_mask_) - 172 base::bits::CountPopulation(kEndMarker), 173 parent->InputCount()); 174 } 175 #endif 176 } 177 178 void SparseInputMask::InputIterator::Advance() { 179 DCHECK(!IsEnd()); 180 181 if (IsReal()) { 182 ++real_index_; 183 } 184 bit_mask_ >>= 1; 185 } 186 187 Node* SparseInputMask::InputIterator::GetReal() const { 188 DCHECK(IsReal()); 189 return parent_->InputAt(real_index_); 190 } 191 192 bool SparseInputMask::InputIterator::IsReal() const { 193 return bit_mask_ == SparseInputMask::kDenseBitMask || 194 (bit_mask_ & kEntryMask); 195 } 196 197 bool SparseInputMask::InputIterator::IsEnd() const { 198 return (bit_mask_ == kEndMarker) || 199 (bit_mask_ == SparseInputMask::kDenseBitMask && 200 real_index_ >= parent_->InputCount()); 201 } 202 203 int SparseInputMask::CountReal() const { 204 DCHECK(!IsDense()); 205 return base::bits::CountPopulation(bit_mask_) - 206 base::bits::CountPopulation(kEndMarker); 207 } 208 209 SparseInputMask::InputIterator SparseInputMask::IterateOverInputs(Node* node) { 210 DCHECK(IsDense() || CountReal() == node->InputCount()); 211 return InputIterator(bit_mask_, node); 212 } 213 214 bool operator==(SparseInputMask const& lhs, SparseInputMask const& rhs) { 215 return lhs.mask() == rhs.mask(); 216 } 217 218 bool operator!=(SparseInputMask const& lhs, SparseInputMask const& rhs) { 219 return !(lhs == rhs); 220 } 221 222 size_t hash_value(SparseInputMask const& p) { 223 return base::hash_value(p.mask()); 224 } 225 226 std::ostream& operator<<(std::ostream& os, SparseInputMask const& p) { 227 if (p.IsDense()) { 228 return os << "dense"; 229 } else { 230 SparseInputMask::BitMaskType mask = p.mask(); 231 DCHECK_NE(mask, SparseInputMask::kDenseBitMask); 232 233 os << "sparse:"; 234 235 while (mask != SparseInputMask::kEndMarker) { 236 if (mask & SparseInputMask::kEntryMask) { 237 os << "^"; 238 } else { 239 os << "."; 240 } 241 mask >>= 1; 242 } 243 return os; 244 } 245 } 246 247 bool operator==(TypedStateValueInfo const& lhs, 248 TypedStateValueInfo const& rhs) { 249 return lhs.machine_types() == rhs.machine_types() && 250 lhs.sparse_input_mask() == rhs.sparse_input_mask(); 251 } 252 253 bool operator!=(TypedStateValueInfo const& lhs, 254 TypedStateValueInfo const& rhs) { 255 return !(lhs == rhs); 256 } 257 258 size_t hash_value(TypedStateValueInfo const& p) { 259 return base::hash_combine(p.machine_types(), p.sparse_input_mask()); 260 } 261 262 std::ostream& operator<<(std::ostream& os, TypedStateValueInfo const& p) { 263 return os << p.machine_types() << "|" << p.sparse_input_mask(); 264 } 265 266 size_t hash_value(RegionObservability observability) { 267 return static_cast<size_t>(observability); 268 } 269 270 std::ostream& operator<<(std::ostream& os, RegionObservability observability) { 271 switch (observability) { 272 case RegionObservability::kObservable: 273 return os << "observable"; 274 case RegionObservability::kNotObservable: 275 return os << "not-observable"; 276 } 277 UNREACHABLE(); 278 return os; 279 } 280 281 RegionObservability RegionObservabilityOf(Operator const* op) { 282 DCHECK_EQ(IrOpcode::kBeginRegion, op->opcode()); 283 return OpParameter<RegionObservability>(op); 284 } 285 286 Type* TypeGuardTypeOf(Operator const* op) { 287 DCHECK_EQ(IrOpcode::kTypeGuard, op->opcode()); 288 return OpParameter<Type*>(op); 289 } 290 291 std::ostream& operator<<(std::ostream& os, 292 const ZoneVector<MachineType>* types) { 293 // Print all the MachineTypes, separated by commas. 294 bool first = true; 295 for (MachineType elem : *types) { 296 if (!first) { 297 os << ", "; 298 } 299 first = false; 300 os << elem; 301 } 302 return os; 303 } 304 305 int OsrValueIndexOf(Operator const* op) { 306 DCHECK_EQ(IrOpcode::kOsrValue, op->opcode()); 307 return OpParameter<int>(op); 308 } 309 310 size_t hash_value(OsrGuardType type) { return static_cast<size_t>(type); } 311 312 std::ostream& operator<<(std::ostream& os, OsrGuardType type) { 313 switch (type) { 314 case OsrGuardType::kUninitialized: 315 return os << "Uninitialized"; 316 case OsrGuardType::kSignedSmall: 317 return os << "SignedSmall"; 318 case OsrGuardType::kAny: 319 return os << "Any"; 320 } 321 UNREACHABLE(); 322 return os; 323 } 324 325 OsrGuardType OsrGuardTypeOf(Operator const* op) { 326 DCHECK_EQ(IrOpcode::kOsrGuard, op->opcode()); 327 return OpParameter<OsrGuardType>(op); 328 } 329 330 SparseInputMask SparseInputMaskOf(Operator const* op) { 331 DCHECK(op->opcode() == IrOpcode::kStateValues || 332 op->opcode() == IrOpcode::kTypedStateValues); 333 334 if (op->opcode() == IrOpcode::kTypedStateValues) { 335 return OpParameter<TypedStateValueInfo>(op).sparse_input_mask(); 336 } 337 return OpParameter<SparseInputMask>(op); 338 } 339 340 ZoneVector<MachineType> const* MachineTypesOf(Operator const* op) { 341 DCHECK(op->opcode() == IrOpcode::kTypedObjectState || 342 op->opcode() == IrOpcode::kTypedStateValues); 343 344 if (op->opcode() == IrOpcode::kTypedStateValues) { 345 return OpParameter<TypedStateValueInfo>(op).machine_types(); 346 } 347 return OpParameter<const ZoneVector<MachineType>*>(op); 348 } 349 350 #define CACHED_OP_LIST(V) \ 351 V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \ 352 V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ 353 V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ 354 V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ 355 V(IfException, Operator::kKontrol, 0, 1, 1, 1, 1, 1) \ 356 V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ 357 V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1) \ 358 V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \ 359 V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \ 360 V(OsrLoopEntry, Operator::kFoldable | Operator::kNoThrow, 0, 1, 1, 0, 1, 1) \ 361 V(LoopExit, Operator::kKontrol, 0, 0, 2, 0, 0, 1) \ 362 V(LoopExitValue, Operator::kPure, 1, 0, 1, 1, 0, 0) \ 363 V(LoopExitEffect, Operator::kNoThrow, 0, 1, 1, 0, 1, 0) \ 364 V(Checkpoint, Operator::kKontrol, 0, 1, 1, 0, 1, 0) \ 365 V(FinishRegion, Operator::kKontrol, 1, 1, 0, 1, 1, 0) \ 366 V(Retain, Operator::kKontrol, 1, 1, 0, 0, 1, 0) 367 368 #define CACHED_RETURN_LIST(V) \ 369 V(1) \ 370 V(2) \ 371 V(3) \ 372 V(4) 373 374 #define CACHED_END_LIST(V) \ 375 V(1) \ 376 V(2) \ 377 V(3) \ 378 V(4) \ 379 V(5) \ 380 V(6) \ 381 V(7) \ 382 V(8) 383 384 385 #define CACHED_EFFECT_PHI_LIST(V) \ 386 V(1) \ 387 V(2) \ 388 V(3) \ 389 V(4) \ 390 V(5) \ 391 V(6) 392 393 #define CACHED_INDUCTION_VARIABLE_PHI_LIST(V) \ 394 V(4) \ 395 V(5) \ 396 V(6) \ 397 V(7) 398 399 #define CACHED_LOOP_LIST(V) \ 400 V(1) \ 401 V(2) 402 403 404 #define CACHED_MERGE_LIST(V) \ 405 V(1) \ 406 V(2) \ 407 V(3) \ 408 V(4) \ 409 V(5) \ 410 V(6) \ 411 V(7) \ 412 V(8) 413 414 #define CACHED_DEOPTIMIZE_LIST(V) \ 415 V(Eager, MinusZero) \ 416 V(Eager, NoReason) \ 417 V(Eager, WrongMap) \ 418 V(Soft, InsufficientTypeFeedbackForGenericKeyedAccess) \ 419 V(Soft, InsufficientTypeFeedbackForGenericNamedAccess) 420 421 #define CACHED_DEOPTIMIZE_IF_LIST(V) \ 422 V(Eager, DivisionByZero) \ 423 V(Eager, Hole) \ 424 V(Eager, MinusZero) \ 425 V(Eager, Overflow) \ 426 V(Eager, Smi) 427 428 #define CACHED_DEOPTIMIZE_UNLESS_LIST(V) \ 429 V(Eager, LostPrecision) \ 430 V(Eager, LostPrecisionOrNaN) \ 431 V(Eager, NoReason) \ 432 V(Eager, NotAHeapNumber) \ 433 V(Eager, NotANumberOrOddball) \ 434 V(Eager, NotASmi) \ 435 V(Eager, OutOfBounds) \ 436 V(Eager, WrongInstanceType) \ 437 V(Eager, WrongMap) 438 439 #define CACHED_TRAP_IF_LIST(V) \ 440 V(TrapDivUnrepresentable) \ 441 V(TrapFloatUnrepresentable) 442 443 // The reason for a trap. 444 #define CACHED_TRAP_UNLESS_LIST(V) \ 445 V(TrapUnreachable) \ 446 V(TrapMemOutOfBounds) \ 447 V(TrapDivByZero) \ 448 V(TrapDivUnrepresentable) \ 449 V(TrapRemByZero) \ 450 V(TrapFloatUnrepresentable) \ 451 V(TrapFuncInvalid) \ 452 V(TrapFuncSigMismatch) 453 454 #define CACHED_PARAMETER_LIST(V) \ 455 V(0) \ 456 V(1) \ 457 V(2) \ 458 V(3) \ 459 V(4) \ 460 V(5) \ 461 V(6) 462 463 464 #define CACHED_PHI_LIST(V) \ 465 V(kTagged, 1) \ 466 V(kTagged, 2) \ 467 V(kTagged, 3) \ 468 V(kTagged, 4) \ 469 V(kTagged, 5) \ 470 V(kTagged, 6) \ 471 V(kBit, 2) \ 472 V(kFloat64, 2) \ 473 V(kWord32, 2) 474 475 476 #define CACHED_PROJECTION_LIST(V) \ 477 V(0) \ 478 V(1) 479 480 481 #define CACHED_STATE_VALUES_LIST(V) \ 482 V(0) \ 483 V(1) \ 484 V(2) \ 485 V(3) \ 486 V(4) \ 487 V(5) \ 488 V(6) \ 489 V(7) \ 490 V(8) \ 491 V(10) \ 492 V(11) \ 493 V(12) \ 494 V(13) \ 495 V(14) 496 497 498 struct CommonOperatorGlobalCache final { 499 #define CACHED(Name, properties, value_input_count, effect_input_count, \ 500 control_input_count, value_output_count, effect_output_count, \ 501 control_output_count) \ 502 struct Name##Operator final : public Operator { \ 503 Name##Operator() \ 504 : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \ 505 effect_input_count, control_input_count, \ 506 value_output_count, effect_output_count, \ 507 control_output_count) {} \ 508 }; \ 509 Name##Operator k##Name##Operator; 510 CACHED_OP_LIST(CACHED) 511 #undef CACHED 512 513 template <size_t kInputCount> 514 struct EndOperator final : public Operator { 515 EndOperator() 516 : Operator( // -- 517 IrOpcode::kEnd, Operator::kKontrol, // opcode 518 "End", // name 519 0, 0, kInputCount, 0, 0, 0) {} // counts 520 }; 521 #define CACHED_END(input_count) \ 522 EndOperator<input_count> kEnd##input_count##Operator; 523 CACHED_END_LIST(CACHED_END) 524 #undef CACHED_END 525 526 template <size_t kValueInputCount> 527 struct ReturnOperator final : public Operator { 528 ReturnOperator() 529 : Operator( // -- 530 IrOpcode::kReturn, Operator::kNoThrow, // opcode 531 "Return", // name 532 kValueInputCount + 1, 1, 1, 0, 0, 1) {} // counts 533 }; 534 #define CACHED_RETURN(value_input_count) \ 535 ReturnOperator<value_input_count> kReturn##value_input_count##Operator; 536 CACHED_RETURN_LIST(CACHED_RETURN) 537 #undef CACHED_RETURN 538 539 template <BranchHint kBranchHint> 540 struct BranchOperator final : public Operator1<BranchHint> { 541 BranchOperator() 542 : Operator1<BranchHint>( // -- 543 IrOpcode::kBranch, Operator::kKontrol, // opcode 544 "Branch", // name 545 1, 0, 1, 0, 0, 2, // counts 546 kBranchHint) {} // parameter 547 }; 548 BranchOperator<BranchHint::kNone> kBranchNoneOperator; 549 BranchOperator<BranchHint::kTrue> kBranchTrueOperator; 550 BranchOperator<BranchHint::kFalse> kBranchFalseOperator; 551 552 template <int kEffectInputCount> 553 struct EffectPhiOperator final : public Operator { 554 EffectPhiOperator() 555 : Operator( // -- 556 IrOpcode::kEffectPhi, Operator::kKontrol, // opcode 557 "EffectPhi", // name 558 0, kEffectInputCount, 1, 0, 1, 0) {} // counts 559 }; 560 #define CACHED_EFFECT_PHI(input_count) \ 561 EffectPhiOperator<input_count> kEffectPhi##input_count##Operator; 562 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI) 563 #undef CACHED_EFFECT_PHI 564 565 template <RegionObservability kRegionObservability> 566 struct BeginRegionOperator final : public Operator1<RegionObservability> { 567 BeginRegionOperator() 568 : Operator1<RegionObservability>( // -- 569 IrOpcode::kBeginRegion, Operator::kKontrol, // opcode 570 "BeginRegion", // name 571 0, 1, 0, 0, 1, 0, // counts 572 kRegionObservability) {} // parameter 573 }; 574 BeginRegionOperator<RegionObservability::kObservable> 575 kBeginRegionObservableOperator; 576 BeginRegionOperator<RegionObservability::kNotObservable> 577 kBeginRegionNotObservableOperator; 578 579 template <size_t kInputCount> 580 struct LoopOperator final : public Operator { 581 LoopOperator() 582 : Operator( // -- 583 IrOpcode::kLoop, Operator::kKontrol, // opcode 584 "Loop", // name 585 0, 0, kInputCount, 0, 0, 1) {} // counts 586 }; 587 #define CACHED_LOOP(input_count) \ 588 LoopOperator<input_count> kLoop##input_count##Operator; 589 CACHED_LOOP_LIST(CACHED_LOOP) 590 #undef CACHED_LOOP 591 592 template <size_t kInputCount> 593 struct MergeOperator final : public Operator { 594 MergeOperator() 595 : Operator( // -- 596 IrOpcode::kMerge, Operator::kKontrol, // opcode 597 "Merge", // name 598 0, 0, kInputCount, 0, 0, 1) {} // counts 599 }; 600 #define CACHED_MERGE(input_count) \ 601 MergeOperator<input_count> kMerge##input_count##Operator; 602 CACHED_MERGE_LIST(CACHED_MERGE) 603 #undef CACHED_MERGE 604 605 template <DeoptimizeKind kKind, DeoptimizeReason kReason> 606 struct DeoptimizeOperator final : public Operator1<DeoptimizeParameters> { 607 DeoptimizeOperator() 608 : Operator1<DeoptimizeParameters>( // -- 609 IrOpcode::kDeoptimize, // opcode 610 Operator::kFoldable | Operator::kNoThrow, // properties 611 "Deoptimize", // name 612 1, 1, 1, 0, 0, 1, // counts 613 DeoptimizeParameters(kKind, kReason)) {} // parameter 614 }; 615 #define CACHED_DEOPTIMIZE(Kind, Reason) \ 616 DeoptimizeOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \ 617 kDeoptimize##Kind##Reason##Operator; 618 CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE) 619 #undef CACHED_DEOPTIMIZE 620 621 template <DeoptimizeKind kKind, DeoptimizeReason kReason> 622 struct DeoptimizeIfOperator final : public Operator1<DeoptimizeParameters> { 623 DeoptimizeIfOperator() 624 : Operator1<DeoptimizeParameters>( // -- 625 IrOpcode::kDeoptimizeIf, // opcode 626 Operator::kFoldable | Operator::kNoThrow, // properties 627 "DeoptimizeIf", // name 628 2, 1, 1, 0, 1, 1, // counts 629 DeoptimizeParameters(kKind, kReason)) {} // parameter 630 }; 631 #define CACHED_DEOPTIMIZE_IF(Kind, Reason) \ 632 DeoptimizeIfOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \ 633 kDeoptimizeIf##Kind##Reason##Operator; 634 CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF) 635 #undef CACHED_DEOPTIMIZE_IF 636 637 template <DeoptimizeKind kKind, DeoptimizeReason kReason> 638 struct DeoptimizeUnlessOperator final 639 : public Operator1<DeoptimizeParameters> { 640 DeoptimizeUnlessOperator() 641 : Operator1<DeoptimizeParameters>( // -- 642 IrOpcode::kDeoptimizeUnless, // opcode 643 Operator::kFoldable | Operator::kNoThrow, // properties 644 "DeoptimizeUnless", // name 645 2, 1, 1, 0, 1, 1, // counts 646 DeoptimizeParameters(kKind, kReason)) {} // parameter 647 }; 648 #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \ 649 DeoptimizeUnlessOperator<DeoptimizeKind::k##Kind, \ 650 DeoptimizeReason::k##Reason> \ 651 kDeoptimizeUnless##Kind##Reason##Operator; 652 CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS) 653 #undef CACHED_DEOPTIMIZE_UNLESS 654 655 template <int32_t trap_id> 656 struct TrapIfOperator final : public Operator1<int32_t> { 657 TrapIfOperator() 658 : Operator1<int32_t>( // -- 659 IrOpcode::kTrapIf, // opcode 660 Operator::kFoldable | Operator::kNoThrow, // properties 661 "TrapIf", // name 662 1, 1, 1, 0, 0, 1, // counts 663 trap_id) {} // parameter 664 }; 665 #define CACHED_TRAP_IF(Trap) \ 666 TrapIfOperator<static_cast<int32_t>(Builtins::kThrowWasm##Trap)> \ 667 kTrapIf##Trap##Operator; 668 CACHED_TRAP_IF_LIST(CACHED_TRAP_IF) 669 #undef CACHED_TRAP_IF 670 671 template <int32_t trap_id> 672 struct TrapUnlessOperator final : public Operator1<int32_t> { 673 TrapUnlessOperator() 674 : Operator1<int32_t>( // -- 675 IrOpcode::kTrapUnless, // opcode 676 Operator::kFoldable | Operator::kNoThrow, // properties 677 "TrapUnless", // name 678 1, 1, 1, 0, 0, 1, // counts 679 trap_id) {} // parameter 680 }; 681 #define CACHED_TRAP_UNLESS(Trap) \ 682 TrapUnlessOperator<static_cast<int32_t>(Builtins::kThrowWasm##Trap)> \ 683 kTrapUnless##Trap##Operator; 684 CACHED_TRAP_UNLESS_LIST(CACHED_TRAP_UNLESS) 685 #undef CACHED_TRAP_UNLESS 686 687 template <MachineRepresentation kRep, int kInputCount> 688 struct PhiOperator final : public Operator1<MachineRepresentation> { 689 PhiOperator() 690 : Operator1<MachineRepresentation>( //-- 691 IrOpcode::kPhi, Operator::kPure, // opcode 692 "Phi", // name 693 kInputCount, 0, 1, 1, 0, 0, // counts 694 kRep) {} // parameter 695 }; 696 #define CACHED_PHI(rep, input_count) \ 697 PhiOperator<MachineRepresentation::rep, input_count> \ 698 kPhi##rep##input_count##Operator; 699 CACHED_PHI_LIST(CACHED_PHI) 700 #undef CACHED_PHI 701 702 template <int kInputCount> 703 struct InductionVariablePhiOperator final : public Operator { 704 InductionVariablePhiOperator() 705 : Operator( //-- 706 IrOpcode::kInductionVariablePhi, Operator::kPure, // opcode 707 "InductionVariablePhi", // name 708 kInputCount, 0, 1, 1, 0, 0) {} // counts 709 }; 710 #define CACHED_INDUCTION_VARIABLE_PHI(input_count) \ 711 InductionVariablePhiOperator<input_count> \ 712 kInductionVariablePhi##input_count##Operator; 713 CACHED_INDUCTION_VARIABLE_PHI_LIST(CACHED_INDUCTION_VARIABLE_PHI) 714 #undef CACHED_INDUCTION_VARIABLE_PHI 715 716 template <int kIndex> 717 struct ParameterOperator final : public Operator1<ParameterInfo> { 718 ParameterOperator() 719 : Operator1<ParameterInfo>( // -- 720 IrOpcode::kParameter, Operator::kPure, // opcode 721 "Parameter", // name 722 1, 0, 0, 1, 0, 0, // counts, 723 ParameterInfo(kIndex, nullptr)) {} // parameter and name 724 }; 725 #define CACHED_PARAMETER(index) \ 726 ParameterOperator<index> kParameter##index##Operator; 727 CACHED_PARAMETER_LIST(CACHED_PARAMETER) 728 #undef CACHED_PARAMETER 729 730 template <size_t kIndex> 731 struct ProjectionOperator final : public Operator1<size_t> { 732 ProjectionOperator() 733 : Operator1<size_t>( // -- 734 IrOpcode::kProjection, // opcode 735 Operator::kPure, // flags 736 "Projection", // name 737 1, 0, 1, 1, 0, 0, // counts, 738 kIndex) {} // parameter 739 }; 740 #define CACHED_PROJECTION(index) \ 741 ProjectionOperator<index> kProjection##index##Operator; 742 CACHED_PROJECTION_LIST(CACHED_PROJECTION) 743 #undef CACHED_PROJECTION 744 745 template <int kInputCount> 746 struct StateValuesOperator final : public Operator1<SparseInputMask> { 747 StateValuesOperator() 748 : Operator1<SparseInputMask>( // -- 749 IrOpcode::kStateValues, // opcode 750 Operator::kPure, // flags 751 "StateValues", // name 752 kInputCount, 0, 0, 1, 0, 0, // counts 753 SparseInputMask::Dense()) {} // parameter 754 }; 755 #define CACHED_STATE_VALUES(input_count) \ 756 StateValuesOperator<input_count> kStateValues##input_count##Operator; 757 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES) 758 #undef CACHED_STATE_VALUES 759 }; 760 761 762 static base::LazyInstance<CommonOperatorGlobalCache>::type kCache = 763 LAZY_INSTANCE_INITIALIZER; 764 765 766 CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone) 767 : cache_(kCache.Get()), zone_(zone) {} 768 769 770 #define CACHED(Name, properties, value_input_count, effect_input_count, \ 771 control_input_count, value_output_count, effect_output_count, \ 772 control_output_count) \ 773 const Operator* CommonOperatorBuilder::Name() { \ 774 return &cache_.k##Name##Operator; \ 775 } 776 CACHED_OP_LIST(CACHED) 777 #undef CACHED 778 779 780 const Operator* CommonOperatorBuilder::End(size_t control_input_count) { 781 switch (control_input_count) { 782 #define CACHED_END(input_count) \ 783 case input_count: \ 784 return &cache_.kEnd##input_count##Operator; 785 CACHED_END_LIST(CACHED_END) 786 #undef CACHED_END 787 default: 788 break; 789 } 790 // Uncached. 791 return new (zone()) Operator( //-- 792 IrOpcode::kEnd, Operator::kKontrol, // opcode 793 "End", // name 794 0, 0, control_input_count, 0, 0, 0); // counts 795 } 796 797 const Operator* CommonOperatorBuilder::Return(int value_input_count) { 798 switch (value_input_count) { 799 #define CACHED_RETURN(input_count) \ 800 case input_count: \ 801 return &cache_.kReturn##input_count##Operator; 802 CACHED_RETURN_LIST(CACHED_RETURN) 803 #undef CACHED_RETURN 804 default: 805 break; 806 } 807 // Uncached. 808 return new (zone()) Operator( //-- 809 IrOpcode::kReturn, Operator::kNoThrow, // opcode 810 "Return", // name 811 value_input_count + 1, 1, 1, 0, 0, 1); // counts 812 } 813 814 815 const Operator* CommonOperatorBuilder::Branch(BranchHint hint) { 816 switch (hint) { 817 case BranchHint::kNone: 818 return &cache_.kBranchNoneOperator; 819 case BranchHint::kTrue: 820 return &cache_.kBranchTrueOperator; 821 case BranchHint::kFalse: 822 return &cache_.kBranchFalseOperator; 823 } 824 UNREACHABLE(); 825 return nullptr; 826 } 827 828 const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind, 829 DeoptimizeReason reason) { 830 #define CACHED_DEOPTIMIZE(Kind, Reason) \ 831 if (kind == DeoptimizeKind::k##Kind && \ 832 reason == DeoptimizeReason::k##Reason) { \ 833 return &cache_.kDeoptimize##Kind##Reason##Operator; \ 834 } 835 CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE) 836 #undef CACHED_DEOPTIMIZE 837 // Uncached 838 DeoptimizeParameters parameter(kind, reason); 839 return new (zone()) Operator1<DeoptimizeParameters>( // -- 840 IrOpcode::kDeoptimize, // opcodes 841 Operator::kFoldable | Operator::kNoThrow, // properties 842 "Deoptimize", // name 843 1, 1, 1, 0, 0, 1, // counts 844 parameter); // parameter 845 } 846 847 const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeKind kind, 848 DeoptimizeReason reason) { 849 #define CACHED_DEOPTIMIZE_IF(Kind, Reason) \ 850 if (kind == DeoptimizeKind::k##Kind && \ 851 reason == DeoptimizeReason::k##Reason) { \ 852 return &cache_.kDeoptimizeIf##Kind##Reason##Operator; \ 853 } 854 CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF) 855 #undef CACHED_DEOPTIMIZE_IF 856 // Uncached 857 DeoptimizeParameters parameter(kind, reason); 858 return new (zone()) Operator1<DeoptimizeParameters>( // -- 859 IrOpcode::kDeoptimizeIf, // opcode 860 Operator::kFoldable | Operator::kNoThrow, // properties 861 "DeoptimizeIf", // name 862 2, 1, 1, 0, 1, 1, // counts 863 parameter); // parameter 864 } 865 866 const Operator* CommonOperatorBuilder::DeoptimizeUnless( 867 DeoptimizeKind kind, DeoptimizeReason reason) { 868 #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \ 869 if (kind == DeoptimizeKind::k##Kind && \ 870 reason == DeoptimizeReason::k##Reason) { \ 871 return &cache_.kDeoptimizeUnless##Kind##Reason##Operator; \ 872 } 873 CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS) 874 #undef CACHED_DEOPTIMIZE_UNLESS 875 // Uncached 876 DeoptimizeParameters parameter(kind, reason); 877 return new (zone()) Operator1<DeoptimizeParameters>( // -- 878 IrOpcode::kDeoptimizeUnless, // opcode 879 Operator::kFoldable | Operator::kNoThrow, // properties 880 "DeoptimizeUnless", // name 881 2, 1, 1, 0, 1, 1, // counts 882 parameter); // parameter 883 } 884 885 const Operator* CommonOperatorBuilder::TrapIf(int32_t trap_id) { 886 switch (trap_id) { 887 #define CACHED_TRAP_IF(Trap) \ 888 case Builtins::kThrowWasm##Trap: \ 889 return &cache_.kTrapIf##Trap##Operator; 890 CACHED_TRAP_IF_LIST(CACHED_TRAP_IF) 891 #undef CACHED_TRAP_IF 892 default: 893 break; 894 } 895 // Uncached 896 return new (zone()) Operator1<int>( // -- 897 IrOpcode::kTrapIf, // opcode 898 Operator::kFoldable | Operator::kNoThrow, // properties 899 "TrapIf", // name 900 1, 1, 1, 0, 0, 1, // counts 901 trap_id); // parameter 902 } 903 904 const Operator* CommonOperatorBuilder::TrapUnless(int32_t trap_id) { 905 switch (trap_id) { 906 #define CACHED_TRAP_UNLESS(Trap) \ 907 case Builtins::kThrowWasm##Trap: \ 908 return &cache_.kTrapUnless##Trap##Operator; 909 CACHED_TRAP_UNLESS_LIST(CACHED_TRAP_UNLESS) 910 #undef CACHED_TRAP_UNLESS 911 default: 912 break; 913 } 914 // Uncached 915 return new (zone()) Operator1<int>( // -- 916 IrOpcode::kTrapUnless, // opcode 917 Operator::kFoldable | Operator::kNoThrow, // properties 918 "TrapUnless", // name 919 1, 1, 1, 0, 0, 1, // counts 920 trap_id); // parameter 921 } 922 923 const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) { 924 return new (zone()) Operator( // -- 925 IrOpcode::kSwitch, Operator::kKontrol, // opcode 926 "Switch", // name 927 1, 0, 1, 0, 0, control_output_count); // counts 928 } 929 930 931 const Operator* CommonOperatorBuilder::IfValue(int32_t index) { 932 return new (zone()) Operator1<int32_t>( // -- 933 IrOpcode::kIfValue, Operator::kKontrol, // opcode 934 "IfValue", // name 935 0, 0, 1, 0, 0, 1, // counts 936 index); // parameter 937 } 938 939 940 const Operator* CommonOperatorBuilder::Start(int value_output_count) { 941 return new (zone()) Operator( // -- 942 IrOpcode::kStart, Operator::kFoldable | Operator::kNoThrow, // opcode 943 "Start", // name 944 0, 0, 0, value_output_count, 1, 1); // counts 945 } 946 947 948 const Operator* CommonOperatorBuilder::Loop(int control_input_count) { 949 switch (control_input_count) { 950 #define CACHED_LOOP(input_count) \ 951 case input_count: \ 952 return &cache_.kLoop##input_count##Operator; 953 CACHED_LOOP_LIST(CACHED_LOOP) 954 #undef CACHED_LOOP 955 default: 956 break; 957 } 958 // Uncached. 959 return new (zone()) Operator( // -- 960 IrOpcode::kLoop, Operator::kKontrol, // opcode 961 "Loop", // name 962 0, 0, control_input_count, 0, 0, 1); // counts 963 } 964 965 966 const Operator* CommonOperatorBuilder::Merge(int control_input_count) { 967 switch (control_input_count) { 968 #define CACHED_MERGE(input_count) \ 969 case input_count: \ 970 return &cache_.kMerge##input_count##Operator; 971 CACHED_MERGE_LIST(CACHED_MERGE) 972 #undef CACHED_MERGE 973 default: 974 break; 975 } 976 // Uncached. 977 return new (zone()) Operator( // -- 978 IrOpcode::kMerge, Operator::kKontrol, // opcode 979 "Merge", // name 980 0, 0, control_input_count, 0, 0, 1); // counts 981 } 982 983 984 const Operator* CommonOperatorBuilder::Parameter(int index, 985 const char* debug_name) { 986 if (!debug_name) { 987 switch (index) { 988 #define CACHED_PARAMETER(index) \ 989 case index: \ 990 return &cache_.kParameter##index##Operator; 991 CACHED_PARAMETER_LIST(CACHED_PARAMETER) 992 #undef CACHED_PARAMETER 993 default: 994 break; 995 } 996 } 997 // Uncached. 998 return new (zone()) Operator1<ParameterInfo>( // -- 999 IrOpcode::kParameter, Operator::kPure, // opcode 1000 "Parameter", // name 1001 1, 0, 0, 1, 0, 0, // counts 1002 ParameterInfo(index, debug_name)); // parameter info 1003 } 1004 1005 const Operator* CommonOperatorBuilder::OsrValue(int index) { 1006 return new (zone()) Operator1<int>( // -- 1007 IrOpcode::kOsrValue, Operator::kNoProperties, // opcode 1008 "OsrValue", // name 1009 0, 0, 1, 1, 0, 0, // counts 1010 index); // parameter 1011 } 1012 1013 const Operator* CommonOperatorBuilder::OsrGuard(OsrGuardType type) { 1014 return new (zone()) Operator1<OsrGuardType>( // -- 1015 IrOpcode::kOsrGuard, Operator::kNoThrow, // opcode 1016 "OsrGuard", // name 1017 1, 1, 1, 1, 1, 0, // counts 1018 type); // parameter 1019 } 1020 1021 const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) { 1022 return new (zone()) Operator1<int32_t>( // -- 1023 IrOpcode::kInt32Constant, Operator::kPure, // opcode 1024 "Int32Constant", // name 1025 0, 0, 0, 1, 0, 0, // counts 1026 value); // parameter 1027 } 1028 1029 1030 const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) { 1031 return new (zone()) Operator1<int64_t>( // -- 1032 IrOpcode::kInt64Constant, Operator::kPure, // opcode 1033 "Int64Constant", // name 1034 0, 0, 0, 1, 0, 0, // counts 1035 value); // parameter 1036 } 1037 1038 1039 const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) { 1040 return new (zone()) Operator1<float>( // -- 1041 IrOpcode::kFloat32Constant, Operator::kPure, // opcode 1042 "Float32Constant", // name 1043 0, 0, 0, 1, 0, 0, // counts 1044 value); // parameter 1045 } 1046 1047 1048 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) { 1049 return new (zone()) Operator1<double>( // -- 1050 IrOpcode::kFloat64Constant, Operator::kPure, // opcode 1051 "Float64Constant", // name 1052 0, 0, 0, 1, 0, 0, // counts 1053 value); // parameter 1054 } 1055 1056 1057 const Operator* CommonOperatorBuilder::ExternalConstant( 1058 const ExternalReference& value) { 1059 return new (zone()) Operator1<ExternalReference>( // -- 1060 IrOpcode::kExternalConstant, Operator::kPure, // opcode 1061 "ExternalConstant", // name 1062 0, 0, 0, 1, 0, 0, // counts 1063 value); // parameter 1064 } 1065 1066 1067 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) { 1068 return new (zone()) Operator1<double>( // -- 1069 IrOpcode::kNumberConstant, Operator::kPure, // opcode 1070 "NumberConstant", // name 1071 0, 0, 0, 1, 0, 0, // counts 1072 value); // parameter 1073 } 1074 1075 const Operator* CommonOperatorBuilder::PointerConstant(intptr_t value) { 1076 return new (zone()) Operator1<intptr_t>( // -- 1077 IrOpcode::kPointerConstant, Operator::kPure, // opcode 1078 "PointerConstant", // name 1079 0, 0, 0, 1, 0, 0, // counts 1080 value); // parameter 1081 } 1082 1083 const Operator* CommonOperatorBuilder::HeapConstant( 1084 const Handle<HeapObject>& value) { 1085 return new (zone()) Operator1<Handle<HeapObject>>( // -- 1086 IrOpcode::kHeapConstant, Operator::kPure, // opcode 1087 "HeapConstant", // name 1088 0, 0, 0, 1, 0, 0, // counts 1089 value); // parameter 1090 } 1091 1092 const Operator* CommonOperatorBuilder::RelocatableInt32Constant( 1093 int32_t value, RelocInfo::Mode rmode) { 1094 return new (zone()) Operator1<RelocatablePtrConstantInfo>( // -- 1095 IrOpcode::kRelocatableInt32Constant, Operator::kPure, // opcode 1096 "RelocatableInt32Constant", // name 1097 0, 0, 0, 1, 0, 0, // counts 1098 RelocatablePtrConstantInfo(value, rmode)); // parameter 1099 } 1100 1101 const Operator* CommonOperatorBuilder::RelocatableInt64Constant( 1102 int64_t value, RelocInfo::Mode rmode) { 1103 return new (zone()) Operator1<RelocatablePtrConstantInfo>( // -- 1104 IrOpcode::kRelocatableInt64Constant, Operator::kPure, // opcode 1105 "RelocatableInt64Constant", // name 1106 0, 0, 0, 1, 0, 0, // counts 1107 RelocatablePtrConstantInfo(value, rmode)); // parameter 1108 } 1109 1110 const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep, 1111 BranchHint hint) { 1112 return new (zone()) Operator1<SelectParameters>( // -- 1113 IrOpcode::kSelect, Operator::kPure, // opcode 1114 "Select", // name 1115 3, 0, 0, 1, 0, 0, // counts 1116 SelectParameters(rep, hint)); // parameter 1117 } 1118 1119 1120 const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep, 1121 int value_input_count) { 1122 DCHECK(value_input_count > 0); // Disallow empty phis. 1123 #define CACHED_PHI(kRep, kValueInputCount) \ 1124 if (MachineRepresentation::kRep == rep && \ 1125 kValueInputCount == value_input_count) { \ 1126 return &cache_.kPhi##kRep##kValueInputCount##Operator; \ 1127 } 1128 CACHED_PHI_LIST(CACHED_PHI) 1129 #undef CACHED_PHI 1130 // Uncached. 1131 return new (zone()) Operator1<MachineRepresentation>( // -- 1132 IrOpcode::kPhi, Operator::kPure, // opcode 1133 "Phi", // name 1134 value_input_count, 0, 1, 1, 0, 0, // counts 1135 rep); // parameter 1136 } 1137 1138 const Operator* CommonOperatorBuilder::TypeGuard(Type* type) { 1139 return new (zone()) Operator1<Type*>( // -- 1140 IrOpcode::kTypeGuard, Operator::kPure, // opcode 1141 "TypeGuard", // name 1142 1, 0, 1, 1, 0, 0, // counts 1143 type); // parameter 1144 } 1145 1146 const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) { 1147 DCHECK(effect_input_count > 0); // Disallow empty effect phis. 1148 switch (effect_input_count) { 1149 #define CACHED_EFFECT_PHI(input_count) \ 1150 case input_count: \ 1151 return &cache_.kEffectPhi##input_count##Operator; 1152 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI) 1153 #undef CACHED_EFFECT_PHI 1154 default: 1155 break; 1156 } 1157 // Uncached. 1158 return new (zone()) Operator( // -- 1159 IrOpcode::kEffectPhi, Operator::kKontrol, // opcode 1160 "EffectPhi", // name 1161 0, effect_input_count, 1, 0, 1, 0); // counts 1162 } 1163 1164 const Operator* CommonOperatorBuilder::InductionVariablePhi(int input_count) { 1165 DCHECK(input_count >= 4); // There must be always the entry, backedge, 1166 // increment and at least one bound. 1167 switch (input_count) { 1168 #define CACHED_INDUCTION_VARIABLE_PHI(input_count) \ 1169 case input_count: \ 1170 return &cache_.kInductionVariablePhi##input_count##Operator; 1171 CACHED_INDUCTION_VARIABLE_PHI_LIST(CACHED_INDUCTION_VARIABLE_PHI) 1172 #undef CACHED_INDUCTION_VARIABLE_PHI 1173 default: 1174 break; 1175 } 1176 // Uncached. 1177 return new (zone()) Operator( // -- 1178 IrOpcode::kInductionVariablePhi, Operator::kPure, // opcode 1179 "InductionVariablePhi", // name 1180 input_count, 0, 1, 1, 0, 0); // counts 1181 } 1182 1183 const Operator* CommonOperatorBuilder::BeginRegion( 1184 RegionObservability region_observability) { 1185 switch (region_observability) { 1186 case RegionObservability::kObservable: 1187 return &cache_.kBeginRegionObservableOperator; 1188 case RegionObservability::kNotObservable: 1189 return &cache_.kBeginRegionNotObservableOperator; 1190 } 1191 UNREACHABLE(); 1192 return nullptr; 1193 } 1194 1195 const Operator* CommonOperatorBuilder::StateValues(int arguments, 1196 SparseInputMask bitmask) { 1197 if (bitmask.IsDense()) { 1198 switch (arguments) { 1199 #define CACHED_STATE_VALUES(arguments) \ 1200 case arguments: \ 1201 return &cache_.kStateValues##arguments##Operator; 1202 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES) 1203 #undef CACHED_STATE_VALUES 1204 default: 1205 break; 1206 } 1207 } 1208 1209 #if DEBUG 1210 DCHECK(bitmask.IsDense() || bitmask.CountReal() == arguments); 1211 #endif 1212 1213 // Uncached. 1214 return new (zone()) Operator1<SparseInputMask>( // -- 1215 IrOpcode::kStateValues, Operator::kPure, // opcode 1216 "StateValues", // name 1217 arguments, 0, 0, 1, 0, 0, // counts 1218 bitmask); // parameter 1219 } 1220 1221 const Operator* CommonOperatorBuilder::TypedStateValues( 1222 const ZoneVector<MachineType>* types, SparseInputMask bitmask) { 1223 #if DEBUG 1224 DCHECK(bitmask.IsDense() || 1225 bitmask.CountReal() == static_cast<int>(types->size())); 1226 #endif 1227 1228 return new (zone()) Operator1<TypedStateValueInfo>( // -- 1229 IrOpcode::kTypedStateValues, Operator::kPure, // opcode 1230 "TypedStateValues", // name 1231 static_cast<int>(types->size()), 0, 0, 1, 0, 0, // counts 1232 TypedStateValueInfo(types, bitmask)); // parameters 1233 } 1234 1235 const Operator* CommonOperatorBuilder::ArgumentsObjectState() { 1236 return new (zone()) Operator( // -- 1237 IrOpcode::kArgumentsObjectState, Operator::kPure, // opcode 1238 "ArgumentsObjectState", // name 1239 0, 0, 0, 1, 0, 0); // counts 1240 } 1241 1242 const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots) { 1243 return new (zone()) Operator1<int>( // -- 1244 IrOpcode::kObjectState, Operator::kPure, // opcode 1245 "ObjectState", // name 1246 pointer_slots, 0, 0, 1, 0, 0, // counts 1247 pointer_slots); // parameter 1248 } 1249 1250 const Operator* CommonOperatorBuilder::TypedObjectState( 1251 const ZoneVector<MachineType>* types) { 1252 return new (zone()) Operator1<const ZoneVector<MachineType>*>( // -- 1253 IrOpcode::kTypedObjectState, Operator::kPure, // opcode 1254 "TypedObjectState", // name 1255 static_cast<int>(types->size()), 0, 0, 1, 0, 0, // counts 1256 types); // parameter 1257 } 1258 1259 const Operator* CommonOperatorBuilder::FrameState( 1260 BailoutId bailout_id, OutputFrameStateCombine state_combine, 1261 const FrameStateFunctionInfo* function_info) { 1262 FrameStateInfo state_info(bailout_id, state_combine, function_info); 1263 return new (zone()) Operator1<FrameStateInfo>( // -- 1264 IrOpcode::kFrameState, Operator::kPure, // opcode 1265 "FrameState", // name 1266 5, 0, 0, 1, 0, 0, // counts 1267 state_info); // parameter 1268 } 1269 1270 1271 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) { 1272 class CallOperator final : public Operator1<const CallDescriptor*> { 1273 public: 1274 explicit CallOperator(const CallDescriptor* descriptor) 1275 : Operator1<const CallDescriptor*>( 1276 IrOpcode::kCall, descriptor->properties(), "Call", 1277 descriptor->InputCount() + descriptor->FrameStateCount(), 1278 Operator::ZeroIfPure(descriptor->properties()), 1279 Operator::ZeroIfEliminatable(descriptor->properties()), 1280 descriptor->ReturnCount(), 1281 Operator::ZeroIfPure(descriptor->properties()), 1282 Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {} 1283 1284 void PrintParameter(std::ostream& os, PrintVerbosity verbose) const { 1285 os << "[" << *parameter() << "]"; 1286 } 1287 }; 1288 return new (zone()) CallOperator(descriptor); 1289 } 1290 1291 1292 const Operator* CommonOperatorBuilder::TailCall( 1293 const CallDescriptor* descriptor) { 1294 class TailCallOperator final : public Operator1<const CallDescriptor*> { 1295 public: 1296 explicit TailCallOperator(const CallDescriptor* descriptor) 1297 : Operator1<const CallDescriptor*>( 1298 IrOpcode::kTailCall, 1299 descriptor->properties() | Operator::kNoThrow, "TailCall", 1300 descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0, 1301 0, 1, descriptor) {} 1302 1303 void PrintParameter(std::ostream& os, PrintVerbosity verbose) const { 1304 os << "[" << *parameter() << "]"; 1305 } 1306 }; 1307 return new (zone()) TailCallOperator(descriptor); 1308 } 1309 1310 1311 const Operator* CommonOperatorBuilder::Projection(size_t index) { 1312 switch (index) { 1313 #define CACHED_PROJECTION(index) \ 1314 case index: \ 1315 return &cache_.kProjection##index##Operator; 1316 CACHED_PROJECTION_LIST(CACHED_PROJECTION) 1317 #undef CACHED_PROJECTION 1318 default: 1319 break; 1320 } 1321 // Uncached. 1322 return new (zone()) Operator1<size_t>( // -- 1323 IrOpcode::kProjection, // opcode 1324 Operator::kPure, // flags 1325 "Projection", // name 1326 1, 0, 1, 1, 0, 0, // counts 1327 index); // parameter 1328 } 1329 1330 1331 const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op, 1332 int size) { 1333 if (op->opcode() == IrOpcode::kPhi) { 1334 return Phi(PhiRepresentationOf(op), size); 1335 } else if (op->opcode() == IrOpcode::kEffectPhi) { 1336 return EffectPhi(size); 1337 } else if (op->opcode() == IrOpcode::kMerge) { 1338 return Merge(size); 1339 } else if (op->opcode() == IrOpcode::kLoop) { 1340 return Loop(size); 1341 } else { 1342 UNREACHABLE(); 1343 return nullptr; 1344 } 1345 } 1346 1347 const FrameStateFunctionInfo* 1348 CommonOperatorBuilder::CreateFrameStateFunctionInfo( 1349 FrameStateType type, int parameter_count, int local_count, 1350 Handle<SharedFunctionInfo> shared_info) { 1351 return new (zone()->New(sizeof(FrameStateFunctionInfo))) 1352 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info); 1353 } 1354 1355 } // namespace compiler 1356 } // namespace internal 1357 } // namespace v8 1358