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