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/opcodes.h" 11 #include "src/compiler/operator.h" 12 #include "src/handles-inl.h" 13 #include "src/zone.h" 14 15 namespace v8 { 16 namespace internal { 17 namespace compiler { 18 19 std::ostream& operator<<(std::ostream& os, BranchHint hint) { 20 switch (hint) { 21 case BranchHint::kNone: 22 return os << "None"; 23 case BranchHint::kTrue: 24 return os << "True"; 25 case BranchHint::kFalse: 26 return os << "False"; 27 } 28 UNREACHABLE(); 29 return os; 30 } 31 32 33 BranchHint BranchHintOf(const Operator* const op) { 34 DCHECK_EQ(IrOpcode::kBranch, op->opcode()); 35 return OpParameter<BranchHint>(op); 36 } 37 38 39 size_t hash_value(DeoptimizeKind kind) { return static_cast<size_t>(kind); } 40 41 42 std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) { 43 switch (kind) { 44 case DeoptimizeKind::kEager: 45 return os << "Eager"; 46 case DeoptimizeKind::kSoft: 47 return os << "Soft"; 48 } 49 UNREACHABLE(); 50 return os; 51 } 52 53 54 DeoptimizeKind DeoptimizeKindOf(const Operator* const op) { 55 DCHECK_EQ(IrOpcode::kDeoptimize, op->opcode()); 56 return OpParameter<DeoptimizeKind>(op); 57 } 58 59 60 size_t hash_value(IfExceptionHint hint) { return static_cast<size_t>(hint); } 61 62 63 std::ostream& operator<<(std::ostream& os, IfExceptionHint hint) { 64 switch (hint) { 65 case IfExceptionHint::kLocallyCaught: 66 return os << "Caught"; 67 case IfExceptionHint::kLocallyUncaught: 68 return os << "Uncaught"; 69 } 70 UNREACHABLE(); 71 return os; 72 } 73 74 75 bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) { 76 return lhs.representation() == rhs.representation() && 77 lhs.hint() == rhs.hint(); 78 } 79 80 81 bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) { 82 return !(lhs == rhs); 83 } 84 85 86 size_t hash_value(SelectParameters const& p) { 87 return base::hash_combine(p.representation(), p.hint()); 88 } 89 90 91 std::ostream& operator<<(std::ostream& os, SelectParameters const& p) { 92 return os << p.representation() << "|" << p.hint(); 93 } 94 95 96 SelectParameters const& SelectParametersOf(const Operator* const op) { 97 DCHECK_EQ(IrOpcode::kSelect, op->opcode()); 98 return OpParameter<SelectParameters>(op); 99 } 100 101 CallDescriptor const* CallDescriptorOf(const Operator* const op) { 102 DCHECK(op->opcode() == IrOpcode::kCall || 103 op->opcode() == IrOpcode::kTailCall); 104 return OpParameter<CallDescriptor const*>(op); 105 } 106 107 size_t ProjectionIndexOf(const Operator* const op) { 108 DCHECK_EQ(IrOpcode::kProjection, op->opcode()); 109 return OpParameter<size_t>(op); 110 } 111 112 113 MachineRepresentation PhiRepresentationOf(const Operator* const op) { 114 DCHECK_EQ(IrOpcode::kPhi, op->opcode()); 115 return OpParameter<MachineRepresentation>(op); 116 } 117 118 119 int ParameterIndexOf(const Operator* const op) { 120 DCHECK_EQ(IrOpcode::kParameter, op->opcode()); 121 return OpParameter<ParameterInfo>(op).index(); 122 } 123 124 125 const ParameterInfo& ParameterInfoOf(const Operator* const op) { 126 DCHECK_EQ(IrOpcode::kParameter, op->opcode()); 127 return OpParameter<ParameterInfo>(op); 128 } 129 130 131 bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) { 132 return lhs.index() == rhs.index(); 133 } 134 135 136 bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) { 137 return !(lhs == rhs); 138 } 139 140 141 size_t hash_value(ParameterInfo const& p) { return p.index(); } 142 143 144 std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) { 145 if (i.debug_name()) os << i.debug_name() << '#'; 146 os << i.index(); 147 return os; 148 } 149 150 bool operator==(RelocatablePtrConstantInfo const& lhs, 151 RelocatablePtrConstantInfo const& rhs) { 152 return lhs.rmode() == rhs.rmode() && lhs.value() == rhs.value() && 153 lhs.type() == rhs.type(); 154 } 155 156 bool operator!=(RelocatablePtrConstantInfo const& lhs, 157 RelocatablePtrConstantInfo const& rhs) { 158 return !(lhs == rhs); 159 } 160 161 size_t hash_value(RelocatablePtrConstantInfo const& p) { 162 return base::hash_combine(p.value(), p.rmode(), p.type()); 163 } 164 165 std::ostream& operator<<(std::ostream& os, 166 RelocatablePtrConstantInfo const& p) { 167 return os << p.value() << "|" << p.rmode() << "|" << p.type(); 168 } 169 170 size_t hash_value(RegionObservability observability) { 171 return static_cast<size_t>(observability); 172 } 173 174 std::ostream& operator<<(std::ostream& os, RegionObservability observability) { 175 switch (observability) { 176 case RegionObservability::kObservable: 177 return os << "observable"; 178 case RegionObservability::kNotObservable: 179 return os << "not-observable"; 180 } 181 UNREACHABLE(); 182 return os; 183 } 184 185 RegionObservability RegionObservabilityOf(Operator const* op) { 186 DCHECK_EQ(IrOpcode::kBeginRegion, op->opcode()); 187 return OpParameter<RegionObservability>(op); 188 } 189 190 std::ostream& operator<<(std::ostream& os, 191 const ZoneVector<MachineType>* types) { 192 // Print all the MachineTypes, separated by commas. 193 bool first = true; 194 for (MachineType elem : *types) { 195 if (!first) { 196 os << ", "; 197 } 198 first = false; 199 os << elem; 200 } 201 return os; 202 } 203 204 #define CACHED_OP_LIST(V) \ 205 V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \ 206 V(DeoptimizeIf, Operator::kFoldable, 2, 1, 1, 0, 1, 1) \ 207 V(DeoptimizeUnless, Operator::kFoldable, 2, 1, 1, 0, 1, 1) \ 208 V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ 209 V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ 210 V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ 211 V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ 212 V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1) \ 213 V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \ 214 V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \ 215 V(OsrLoopEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \ 216 V(Checkpoint, Operator::kKontrol, 0, 1, 1, 0, 1, 0) \ 217 V(FinishRegion, Operator::kKontrol, 1, 1, 0, 1, 1, 0) 218 219 #define CACHED_RETURN_LIST(V) \ 220 V(1) \ 221 V(2) \ 222 V(3) 223 224 225 #define CACHED_END_LIST(V) \ 226 V(1) \ 227 V(2) \ 228 V(3) \ 229 V(4) \ 230 V(5) \ 231 V(6) \ 232 V(7) \ 233 V(8) 234 235 236 #define CACHED_EFFECT_PHI_LIST(V) \ 237 V(1) \ 238 V(2) \ 239 V(3) \ 240 V(4) \ 241 V(5) \ 242 V(6) 243 244 245 #define CACHED_LOOP_LIST(V) \ 246 V(1) \ 247 V(2) 248 249 250 #define CACHED_MERGE_LIST(V) \ 251 V(1) \ 252 V(2) \ 253 V(3) \ 254 V(4) \ 255 V(5) \ 256 V(6) \ 257 V(7) \ 258 V(8) 259 260 261 #define CACHED_PARAMETER_LIST(V) \ 262 V(0) \ 263 V(1) \ 264 V(2) \ 265 V(3) \ 266 V(4) \ 267 V(5) \ 268 V(6) 269 270 271 #define CACHED_PHI_LIST(V) \ 272 V(kTagged, 1) \ 273 V(kTagged, 2) \ 274 V(kTagged, 3) \ 275 V(kTagged, 4) \ 276 V(kTagged, 5) \ 277 V(kTagged, 6) \ 278 V(kBit, 2) \ 279 V(kFloat64, 2) \ 280 V(kWord32, 2) 281 282 283 #define CACHED_PROJECTION_LIST(V) \ 284 V(0) \ 285 V(1) 286 287 288 #define CACHED_STATE_VALUES_LIST(V) \ 289 V(0) \ 290 V(1) \ 291 V(2) \ 292 V(3) \ 293 V(4) \ 294 V(5) \ 295 V(6) \ 296 V(7) \ 297 V(8) \ 298 V(10) \ 299 V(11) \ 300 V(12) \ 301 V(13) \ 302 V(14) 303 304 305 struct CommonOperatorGlobalCache final { 306 #define CACHED(Name, properties, value_input_count, effect_input_count, \ 307 control_input_count, value_output_count, effect_output_count, \ 308 control_output_count) \ 309 struct Name##Operator final : public Operator { \ 310 Name##Operator() \ 311 : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \ 312 effect_input_count, control_input_count, \ 313 value_output_count, effect_output_count, \ 314 control_output_count) {} \ 315 }; \ 316 Name##Operator k##Name##Operator; 317 CACHED_OP_LIST(CACHED) 318 #undef CACHED 319 320 template <DeoptimizeKind kKind> 321 struct DeoptimizeOperator final : public Operator1<DeoptimizeKind> { 322 DeoptimizeOperator() 323 : Operator1<DeoptimizeKind>( // -- 324 IrOpcode::kDeoptimize, Operator::kNoThrow, // opcode 325 "Deoptimize", // name 326 1, 1, 1, 0, 0, 1, // counts 327 kKind) {} // parameter 328 }; 329 DeoptimizeOperator<DeoptimizeKind::kEager> kDeoptimizeEagerOperator; 330 DeoptimizeOperator<DeoptimizeKind::kSoft> kDeoptimizeSoftOperator; 331 332 template <IfExceptionHint kCaughtLocally> 333 struct IfExceptionOperator final : public Operator1<IfExceptionHint> { 334 IfExceptionOperator() 335 : Operator1<IfExceptionHint>( // -- 336 IrOpcode::kIfException, Operator::kKontrol, // opcode 337 "IfException", // name 338 0, 1, 1, 1, 1, 1, // counts 339 kCaughtLocally) {} // parameter 340 }; 341 IfExceptionOperator<IfExceptionHint::kLocallyCaught> kIfExceptionCOperator; 342 IfExceptionOperator<IfExceptionHint::kLocallyUncaught> kIfExceptionUOperator; 343 344 template <size_t kInputCount> 345 struct EndOperator final : public Operator { 346 EndOperator() 347 : Operator( // -- 348 IrOpcode::kEnd, Operator::kKontrol, // opcode 349 "End", // name 350 0, 0, kInputCount, 0, 0, 0) {} // counts 351 }; 352 #define CACHED_END(input_count) \ 353 EndOperator<input_count> kEnd##input_count##Operator; 354 CACHED_END_LIST(CACHED_END) 355 #undef CACHED_END 356 357 template <size_t kInputCount> 358 struct ReturnOperator final : public Operator { 359 ReturnOperator() 360 : Operator( // -- 361 IrOpcode::kReturn, Operator::kNoThrow, // opcode 362 "Return", // name 363 kInputCount, 1, 1, 0, 0, 1) {} // counts 364 }; 365 #define CACHED_RETURN(input_count) \ 366 ReturnOperator<input_count> kReturn##input_count##Operator; 367 CACHED_RETURN_LIST(CACHED_RETURN) 368 #undef CACHED_RETURN 369 370 template <BranchHint kBranchHint> 371 struct BranchOperator final : public Operator1<BranchHint> { 372 BranchOperator() 373 : Operator1<BranchHint>( // -- 374 IrOpcode::kBranch, Operator::kKontrol, // opcode 375 "Branch", // name 376 1, 0, 1, 0, 0, 2, // counts 377 kBranchHint) {} // parameter 378 }; 379 BranchOperator<BranchHint::kNone> kBranchNoneOperator; 380 BranchOperator<BranchHint::kTrue> kBranchTrueOperator; 381 BranchOperator<BranchHint::kFalse> kBranchFalseOperator; 382 383 template <int kEffectInputCount> 384 struct EffectPhiOperator final : public Operator { 385 EffectPhiOperator() 386 : Operator( // -- 387 IrOpcode::kEffectPhi, Operator::kPure, // opcode 388 "EffectPhi", // name 389 0, kEffectInputCount, 1, 0, 1, 0) {} // counts 390 }; 391 #define CACHED_EFFECT_PHI(input_count) \ 392 EffectPhiOperator<input_count> kEffectPhi##input_count##Operator; 393 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI) 394 #undef CACHED_EFFECT_PHI 395 396 template <RegionObservability kRegionObservability> 397 struct BeginRegionOperator final : public Operator1<RegionObservability> { 398 BeginRegionOperator() 399 : Operator1<RegionObservability>( // -- 400 IrOpcode::kBeginRegion, Operator::kKontrol, // opcode 401 "BeginRegion", // name 402 0, 1, 0, 0, 1, 0, // counts 403 kRegionObservability) {} // parameter 404 }; 405 BeginRegionOperator<RegionObservability::kObservable> 406 kBeginRegionObservableOperator; 407 BeginRegionOperator<RegionObservability::kNotObservable> 408 kBeginRegionNotObservableOperator; 409 410 template <size_t kInputCount> 411 struct LoopOperator final : public Operator { 412 LoopOperator() 413 : Operator( // -- 414 IrOpcode::kLoop, Operator::kKontrol, // opcode 415 "Loop", // name 416 0, 0, kInputCount, 0, 0, 1) {} // counts 417 }; 418 #define CACHED_LOOP(input_count) \ 419 LoopOperator<input_count> kLoop##input_count##Operator; 420 CACHED_LOOP_LIST(CACHED_LOOP) 421 #undef CACHED_LOOP 422 423 template <size_t kInputCount> 424 struct MergeOperator final : public Operator { 425 MergeOperator() 426 : Operator( // -- 427 IrOpcode::kMerge, Operator::kKontrol, // opcode 428 "Merge", // name 429 0, 0, kInputCount, 0, 0, 1) {} // counts 430 }; 431 #define CACHED_MERGE(input_count) \ 432 MergeOperator<input_count> kMerge##input_count##Operator; 433 CACHED_MERGE_LIST(CACHED_MERGE) 434 #undef CACHED_MERGE 435 436 template <MachineRepresentation kRep, int kInputCount> 437 struct PhiOperator final : public Operator1<MachineRepresentation> { 438 PhiOperator() 439 : Operator1<MachineRepresentation>( //-- 440 IrOpcode::kPhi, Operator::kPure, // opcode 441 "Phi", // name 442 kInputCount, 0, 1, 1, 0, 0, // counts 443 kRep) {} // parameter 444 }; 445 #define CACHED_PHI(rep, input_count) \ 446 PhiOperator<MachineRepresentation::rep, input_count> \ 447 kPhi##rep##input_count##Operator; 448 CACHED_PHI_LIST(CACHED_PHI) 449 #undef CACHED_PHI 450 451 template <int kIndex> 452 struct ParameterOperator final : public Operator1<ParameterInfo> { 453 ParameterOperator() 454 : Operator1<ParameterInfo>( // -- 455 IrOpcode::kParameter, Operator::kPure, // opcode 456 "Parameter", // name 457 1, 0, 0, 1, 0, 0, // counts, 458 ParameterInfo(kIndex, nullptr)) {} // parameter and name 459 }; 460 #define CACHED_PARAMETER(index) \ 461 ParameterOperator<index> kParameter##index##Operator; 462 CACHED_PARAMETER_LIST(CACHED_PARAMETER) 463 #undef CACHED_PARAMETER 464 465 template <size_t kIndex> 466 struct ProjectionOperator final : public Operator1<size_t> { 467 ProjectionOperator() 468 : Operator1<size_t>( // -- 469 IrOpcode::kProjection, // opcode 470 Operator::kPure, // flags 471 "Projection", // name 472 1, 0, 1, 1, 0, 0, // counts, 473 kIndex) {} // parameter 474 }; 475 #define CACHED_PROJECTION(index) \ 476 ProjectionOperator<index> kProjection##index##Operator; 477 CACHED_PROJECTION_LIST(CACHED_PROJECTION) 478 #undef CACHED_PROJECTION 479 480 template <int kInputCount> 481 struct StateValuesOperator final : public Operator { 482 StateValuesOperator() 483 : Operator( // -- 484 IrOpcode::kStateValues, // opcode 485 Operator::kPure, // flags 486 "StateValues", // name 487 kInputCount, 0, 0, 1, 0, 0) {} // counts 488 }; 489 #define CACHED_STATE_VALUES(input_count) \ 490 StateValuesOperator<input_count> kStateValues##input_count##Operator; 491 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES) 492 #undef CACHED_STATE_VALUES 493 }; 494 495 496 static base::LazyInstance<CommonOperatorGlobalCache>::type kCache = 497 LAZY_INSTANCE_INITIALIZER; 498 499 500 CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone) 501 : cache_(kCache.Get()), zone_(zone) {} 502 503 504 #define CACHED(Name, properties, value_input_count, effect_input_count, \ 505 control_input_count, value_output_count, effect_output_count, \ 506 control_output_count) \ 507 const Operator* CommonOperatorBuilder::Name() { \ 508 return &cache_.k##Name##Operator; \ 509 } 510 CACHED_OP_LIST(CACHED) 511 #undef CACHED 512 513 514 const Operator* CommonOperatorBuilder::End(size_t control_input_count) { 515 switch (control_input_count) { 516 #define CACHED_END(input_count) \ 517 case input_count: \ 518 return &cache_.kEnd##input_count##Operator; 519 CACHED_END_LIST(CACHED_END) 520 #undef CACHED_END 521 default: 522 break; 523 } 524 // Uncached. 525 return new (zone()) Operator( //-- 526 IrOpcode::kEnd, Operator::kKontrol, // opcode 527 "End", // name 528 0, 0, control_input_count, 0, 0, 0); // counts 529 } 530 531 532 const Operator* CommonOperatorBuilder::Return(int value_input_count) { 533 switch (value_input_count) { 534 #define CACHED_RETURN(input_count) \ 535 case input_count: \ 536 return &cache_.kReturn##input_count##Operator; 537 CACHED_RETURN_LIST(CACHED_RETURN) 538 #undef CACHED_RETURN 539 default: 540 break; 541 } 542 // Uncached. 543 return new (zone()) Operator( //-- 544 IrOpcode::kReturn, Operator::kNoThrow, // opcode 545 "Return", // name 546 value_input_count, 1, 1, 0, 0, 1); // counts 547 } 548 549 550 const Operator* CommonOperatorBuilder::Branch(BranchHint hint) { 551 switch (hint) { 552 case BranchHint::kNone: 553 return &cache_.kBranchNoneOperator; 554 case BranchHint::kTrue: 555 return &cache_.kBranchTrueOperator; 556 case BranchHint::kFalse: 557 return &cache_.kBranchFalseOperator; 558 } 559 UNREACHABLE(); 560 return nullptr; 561 } 562 563 564 const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind) { 565 switch (kind) { 566 case DeoptimizeKind::kEager: 567 return &cache_.kDeoptimizeEagerOperator; 568 case DeoptimizeKind::kSoft: 569 return &cache_.kDeoptimizeSoftOperator; 570 } 571 UNREACHABLE(); 572 return nullptr; 573 } 574 575 576 const Operator* CommonOperatorBuilder::IfException(IfExceptionHint hint) { 577 switch (hint) { 578 case IfExceptionHint::kLocallyCaught: 579 return &cache_.kIfExceptionCOperator; 580 case IfExceptionHint::kLocallyUncaught: 581 return &cache_.kIfExceptionUOperator; 582 } 583 UNREACHABLE(); 584 return nullptr; 585 } 586 587 588 const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) { 589 return new (zone()) Operator( // -- 590 IrOpcode::kSwitch, Operator::kKontrol, // opcode 591 "Switch", // name 592 1, 0, 1, 0, 0, control_output_count); // counts 593 } 594 595 596 const Operator* CommonOperatorBuilder::IfValue(int32_t index) { 597 return new (zone()) Operator1<int32_t>( // -- 598 IrOpcode::kIfValue, Operator::kKontrol, // opcode 599 "IfValue", // name 600 0, 0, 1, 0, 0, 1, // counts 601 index); // parameter 602 } 603 604 605 const Operator* CommonOperatorBuilder::Start(int value_output_count) { 606 return new (zone()) Operator( // -- 607 IrOpcode::kStart, Operator::kFoldable, // opcode 608 "Start", // name 609 0, 0, 0, value_output_count, 1, 1); // counts 610 } 611 612 613 const Operator* CommonOperatorBuilder::Loop(int control_input_count) { 614 switch (control_input_count) { 615 #define CACHED_LOOP(input_count) \ 616 case input_count: \ 617 return &cache_.kLoop##input_count##Operator; 618 CACHED_LOOP_LIST(CACHED_LOOP) 619 #undef CACHED_LOOP 620 default: 621 break; 622 } 623 // Uncached. 624 return new (zone()) Operator( // -- 625 IrOpcode::kLoop, Operator::kKontrol, // opcode 626 "Loop", // name 627 0, 0, control_input_count, 0, 0, 1); // counts 628 } 629 630 631 const Operator* CommonOperatorBuilder::Merge(int control_input_count) { 632 switch (control_input_count) { 633 #define CACHED_MERGE(input_count) \ 634 case input_count: \ 635 return &cache_.kMerge##input_count##Operator; 636 CACHED_MERGE_LIST(CACHED_MERGE) 637 #undef CACHED_MERGE 638 default: 639 break; 640 } 641 // Uncached. 642 return new (zone()) Operator( // -- 643 IrOpcode::kMerge, Operator::kKontrol, // opcode 644 "Merge", // name 645 0, 0, control_input_count, 0, 0, 1); // counts 646 } 647 648 649 const Operator* CommonOperatorBuilder::Parameter(int index, 650 const char* debug_name) { 651 if (!debug_name) { 652 switch (index) { 653 #define CACHED_PARAMETER(index) \ 654 case index: \ 655 return &cache_.kParameter##index##Operator; 656 CACHED_PARAMETER_LIST(CACHED_PARAMETER) 657 #undef CACHED_PARAMETER 658 default: 659 break; 660 } 661 } 662 // Uncached. 663 return new (zone()) Operator1<ParameterInfo>( // -- 664 IrOpcode::kParameter, Operator::kPure, // opcode 665 "Parameter", // name 666 1, 0, 0, 1, 0, 0, // counts 667 ParameterInfo(index, debug_name)); // parameter info 668 } 669 670 671 const Operator* CommonOperatorBuilder::OsrValue(int index) { 672 return new (zone()) Operator1<int>( // -- 673 IrOpcode::kOsrValue, Operator::kNoProperties, // opcode 674 "OsrValue", // name 675 0, 0, 1, 1, 0, 0, // counts 676 index); // parameter 677 } 678 679 680 const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) { 681 return new (zone()) Operator1<int32_t>( // -- 682 IrOpcode::kInt32Constant, Operator::kPure, // opcode 683 "Int32Constant", // name 684 0, 0, 0, 1, 0, 0, // counts 685 value); // parameter 686 } 687 688 689 const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) { 690 return new (zone()) Operator1<int64_t>( // -- 691 IrOpcode::kInt64Constant, Operator::kPure, // opcode 692 "Int64Constant", // name 693 0, 0, 0, 1, 0, 0, // counts 694 value); // parameter 695 } 696 697 698 const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) { 699 return new (zone()) Operator1<float>( // -- 700 IrOpcode::kFloat32Constant, Operator::kPure, // opcode 701 "Float32Constant", // name 702 0, 0, 0, 1, 0, 0, // counts 703 value); // parameter 704 } 705 706 707 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) { 708 return new (zone()) Operator1<double>( // -- 709 IrOpcode::kFloat64Constant, Operator::kPure, // opcode 710 "Float64Constant", // name 711 0, 0, 0, 1, 0, 0, // counts 712 value); // parameter 713 } 714 715 716 const Operator* CommonOperatorBuilder::ExternalConstant( 717 const ExternalReference& value) { 718 return new (zone()) Operator1<ExternalReference>( // -- 719 IrOpcode::kExternalConstant, Operator::kPure, // opcode 720 "ExternalConstant", // name 721 0, 0, 0, 1, 0, 0, // counts 722 value); // parameter 723 } 724 725 726 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) { 727 return new (zone()) Operator1<double>( // -- 728 IrOpcode::kNumberConstant, Operator::kPure, // opcode 729 "NumberConstant", // name 730 0, 0, 0, 1, 0, 0, // counts 731 value); // parameter 732 } 733 734 735 const Operator* CommonOperatorBuilder::HeapConstant( 736 const Handle<HeapObject>& value) { 737 return new (zone()) Operator1<Handle<HeapObject>>( // -- 738 IrOpcode::kHeapConstant, Operator::kPure, // opcode 739 "HeapConstant", // name 740 0, 0, 0, 1, 0, 0, // counts 741 value); // parameter 742 } 743 744 const Operator* CommonOperatorBuilder::RelocatableInt32Constant( 745 int32_t value, RelocInfo::Mode rmode) { 746 return new (zone()) Operator1<RelocatablePtrConstantInfo>( // -- 747 IrOpcode::kRelocatableInt32Constant, Operator::kPure, // opcode 748 "RelocatableInt32Constant", // name 749 0, 0, 0, 1, 0, 0, // counts 750 RelocatablePtrConstantInfo(value, rmode)); // parameter 751 } 752 753 const Operator* CommonOperatorBuilder::RelocatableInt64Constant( 754 int64_t value, RelocInfo::Mode rmode) { 755 return new (zone()) Operator1<RelocatablePtrConstantInfo>( // -- 756 IrOpcode::kRelocatableInt64Constant, Operator::kPure, // opcode 757 "RelocatableInt64Constant", // name 758 0, 0, 0, 1, 0, 0, // counts 759 RelocatablePtrConstantInfo(value, rmode)); // parameter 760 } 761 762 const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep, 763 BranchHint hint) { 764 return new (zone()) Operator1<SelectParameters>( // -- 765 IrOpcode::kSelect, Operator::kPure, // opcode 766 "Select", // name 767 3, 0, 0, 1, 0, 0, // counts 768 SelectParameters(rep, hint)); // parameter 769 } 770 771 772 const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep, 773 int value_input_count) { 774 DCHECK(value_input_count > 0); // Disallow empty phis. 775 #define CACHED_PHI(kRep, kValueInputCount) \ 776 if (MachineRepresentation::kRep == rep && \ 777 kValueInputCount == value_input_count) { \ 778 return &cache_.kPhi##kRep##kValueInputCount##Operator; \ 779 } 780 CACHED_PHI_LIST(CACHED_PHI) 781 #undef CACHED_PHI 782 // Uncached. 783 return new (zone()) Operator1<MachineRepresentation>( // -- 784 IrOpcode::kPhi, Operator::kPure, // opcode 785 "Phi", // name 786 value_input_count, 0, 1, 1, 0, 0, // counts 787 rep); // parameter 788 } 789 790 791 const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) { 792 DCHECK(effect_input_count > 0); // Disallow empty effect phis. 793 switch (effect_input_count) { 794 #define CACHED_EFFECT_PHI(input_count) \ 795 case input_count: \ 796 return &cache_.kEffectPhi##input_count##Operator; 797 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI) 798 #undef CACHED_EFFECT_PHI 799 default: 800 break; 801 } 802 // Uncached. 803 return new (zone()) Operator( // -- 804 IrOpcode::kEffectPhi, Operator::kPure, // opcode 805 "EffectPhi", // name 806 0, effect_input_count, 1, 0, 1, 0); // counts 807 } 808 809 const Operator* CommonOperatorBuilder::BeginRegion( 810 RegionObservability region_observability) { 811 switch (region_observability) { 812 case RegionObservability::kObservable: 813 return &cache_.kBeginRegionObservableOperator; 814 case RegionObservability::kNotObservable: 815 return &cache_.kBeginRegionNotObservableOperator; 816 } 817 UNREACHABLE(); 818 return nullptr; 819 } 820 821 const Operator* CommonOperatorBuilder::StateValues(int arguments) { 822 switch (arguments) { 823 #define CACHED_STATE_VALUES(arguments) \ 824 case arguments: \ 825 return &cache_.kStateValues##arguments##Operator; 826 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES) 827 #undef CACHED_STATE_VALUES 828 default: 829 break; 830 } 831 // Uncached. 832 return new (zone()) Operator( // -- 833 IrOpcode::kStateValues, Operator::kPure, // opcode 834 "StateValues", // name 835 arguments, 0, 0, 1, 0, 0); // counts 836 } 837 838 839 const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots, int id) { 840 return new (zone()) Operator1<int>( // -- 841 IrOpcode::kObjectState, Operator::kPure, // opcode 842 "ObjectState", // name 843 pointer_slots, 0, 0, 1, 0, 0, id); // counts 844 } 845 846 847 const Operator* CommonOperatorBuilder::TypedStateValues( 848 const ZoneVector<MachineType>* types) { 849 return new (zone()) Operator1<const ZoneVector<MachineType>*>( // -- 850 IrOpcode::kTypedStateValues, Operator::kPure, // opcode 851 "TypedStateValues", // name 852 static_cast<int>(types->size()), 0, 0, 1, 0, 0, types); // counts 853 } 854 855 856 const Operator* CommonOperatorBuilder::FrameState( 857 BailoutId bailout_id, OutputFrameStateCombine state_combine, 858 const FrameStateFunctionInfo* function_info) { 859 FrameStateInfo state_info(bailout_id, state_combine, function_info); 860 return new (zone()) Operator1<FrameStateInfo>( // -- 861 IrOpcode::kFrameState, Operator::kPure, // opcode 862 "FrameState", // name 863 5, 0, 0, 1, 0, 0, // counts 864 state_info); // parameter 865 } 866 867 868 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) { 869 class CallOperator final : public Operator1<const CallDescriptor*> { 870 public: 871 explicit CallOperator(const CallDescriptor* descriptor) 872 : Operator1<const CallDescriptor*>( 873 IrOpcode::kCall, descriptor->properties(), "Call", 874 descriptor->InputCount() + descriptor->FrameStateCount(), 875 Operator::ZeroIfPure(descriptor->properties()), 876 Operator::ZeroIfEliminatable(descriptor->properties()), 877 descriptor->ReturnCount(), 878 Operator::ZeroIfPure(descriptor->properties()), 879 Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {} 880 881 void PrintParameter(std::ostream& os) const override { 882 os << "[" << *parameter() << "]"; 883 } 884 }; 885 return new (zone()) CallOperator(descriptor); 886 } 887 888 889 const Operator* CommonOperatorBuilder::TailCall( 890 const CallDescriptor* descriptor) { 891 class TailCallOperator final : public Operator1<const CallDescriptor*> { 892 public: 893 explicit TailCallOperator(const CallDescriptor* descriptor) 894 : Operator1<const CallDescriptor*>( 895 IrOpcode::kTailCall, descriptor->properties(), "TailCall", 896 descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0, 897 0, 1, descriptor) {} 898 899 void PrintParameter(std::ostream& os) const override { 900 os << "[" << *parameter() << "]"; 901 } 902 }; 903 return new (zone()) TailCallOperator(descriptor); 904 } 905 906 907 const Operator* CommonOperatorBuilder::Projection(size_t index) { 908 switch (index) { 909 #define CACHED_PROJECTION(index) \ 910 case index: \ 911 return &cache_.kProjection##index##Operator; 912 CACHED_PROJECTION_LIST(CACHED_PROJECTION) 913 #undef CACHED_PROJECTION 914 default: 915 break; 916 } 917 // Uncached. 918 return new (zone()) Operator1<size_t>( // -- 919 IrOpcode::kProjection, // opcode 920 Operator::kPure, // flags 921 "Projection", // name 922 1, 0, 1, 1, 0, 0, // counts 923 index); // parameter 924 } 925 926 927 const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op, 928 int size) { 929 if (op->opcode() == IrOpcode::kPhi) { 930 return Phi(PhiRepresentationOf(op), size); 931 } else if (op->opcode() == IrOpcode::kEffectPhi) { 932 return EffectPhi(size); 933 } else if (op->opcode() == IrOpcode::kMerge) { 934 return Merge(size); 935 } else if (op->opcode() == IrOpcode::kLoop) { 936 return Loop(size); 937 } else { 938 UNREACHABLE(); 939 return nullptr; 940 } 941 } 942 943 944 const FrameStateFunctionInfo* 945 CommonOperatorBuilder::CreateFrameStateFunctionInfo( 946 FrameStateType type, int parameter_count, int local_count, 947 Handle<SharedFunctionInfo> shared_info) { 948 return new (zone()->New(sizeof(FrameStateFunctionInfo))) 949 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info); 950 } 951 952 } // namespace compiler 953 } // namespace internal 954 } // namespace v8 955