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