1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef ECMASCRIPT_COMPILER_GATE_ACCESSOR_H 17#define ECMASCRIPT_COMPILER_GATE_ACCESSOR_H 18 19#include "ecmascript/compiler/circuit.h" 20#include "ecmascript/compiler/mcr_gate_meta_data.h" 21#include "ecmascript/elements.h" 22#include "ecmascript/pgo_profiler/types/pgo_profiler_type.h" 23 24namespace panda::ecmascript::kungfu { 25 26class StateDepend { 27public: 28 StateDepend() 29 : state_(Circuit::NullGate()), depend_(Circuit::NullGate()) {} 30 31 explicit StateDepend(GateRef state, GateRef depend) 32 : state_(state), depend_(depend) {} 33 34 GateRef State() const 35 { 36 return state_; 37 } 38 39 GateRef Depend() const 40 { 41 return depend_; 42 } 43 44 void SetState(GateRef state) 45 { 46 state_ = state; 47 } 48 49 void SetDepend(GateRef depend) 50 { 51 depend_ = depend; 52 } 53 54 void Reset() 55 { 56 state_ = Circuit::NullGate(); 57 depend_ = Circuit::NullGate(); 58 } 59 60private: 61 GateRef state_; 62 GateRef depend_; 63}; 64 65class Edge { 66public: 67 explicit Edge(GateRef gate, size_t index) : gate_(gate), index_(static_cast<uint32_t>(index)) {} 68 69 GateRef GetGate() const 70 { 71 return gate_; 72 } 73 74 size_t GetIndex() const 75 { 76 return static_cast<size_t>(index_); 77 } 78 79 void SetIndex(size_t index) 80 { 81 index_ = static_cast<uint32_t>(index); 82 } 83 84private: 85 GateRef gate_; 86 uint32_t index_; 87}; 88 89class GateAccessor { 90public: 91 constexpr static uint32_t INVALID_BC_INDEX = 0; 92 93 // do not create new gate or modify self during iteration 94 struct ConstUseIterator { 95 ConstUseIterator(const Circuit* circuit, const Out* out) : circuit_(circuit), out_(out) 96 { 97 } 98 99 GateRef operator*() const 100 { 101 if (out_ != nullptr) { 102 return circuit_->GetGateRef(out_->GetGateConst()); 103 } 104 return 0; 105 } 106 107 const ConstUseIterator operator++() 108 { 109 ASSERT(out_ != nullptr); 110 if (!out_->IsNextOutNull()) { 111 out_ = out_->GetNextOutConst(); 112 return *this; 113 } 114 out_ = nullptr; 115 return *this; 116 } 117 const ConstUseIterator operator++(int) 118 { 119 ConstUseIterator tmp = *this; 120 ++(*this); 121 return tmp; 122 } 123 124 size_t GetIndex() const 125 { 126 ASSERT(out_ != nullptr); 127 return out_->GetIndex(); 128 } 129 130 OpCode GetOpCode() const 131 { 132 ASSERT(out_ != nullptr); 133 return out_->GetGateConst()->GetOpCode(); 134 } 135 136 friend bool operator == (const ConstUseIterator& a, const ConstUseIterator& b) 137 { 138 return a.out_ == b.out_; 139 }; 140 friend bool operator != (const ConstUseIterator& a, const ConstUseIterator& b) 141 { 142 return a.out_ != b.out_; 143 }; 144 145 private: 146 const Circuit* circuit_; 147 const Out* out_; 148 }; 149 150 // do not create new gate or modify self during iteration 151 struct UseIterator { 152 UseIterator(Circuit* circuit, Out* out) : circuit_(circuit), out_(out) 153 { 154 } 155 156 GateRef operator*() const 157 { 158 if (out_ != nullptr) { 159 return circuit_->GetGateRef(out_->GetGate()); 160 } 161 return 0; 162 } 163 164 const UseIterator& operator++() 165 { 166 ASSERT(out_ != nullptr); 167 out_ = out_->IsNextOutNull() ? nullptr 168 : out_->GetNextOut(); 169 return *this; 170 } 171 172 UseIterator operator++(int) 173 { 174 UseIterator tmp = *this; 175 ++(*this); 176 return tmp; 177 } 178 179 size_t GetIndex() const 180 { 181 ASSERT(out_ != nullptr); 182 return out_->GetIndex(); 183 } 184 185 Edge GetEdge() 186 { 187 ASSERT(out_ != nullptr); 188 UseIterator it = *this; 189 return Edge(*it, GetIndex()); 190 } 191 192 OpCode GetOpCode() const 193 { 194 ASSERT(out_ != nullptr); 195 return out_->GetGateConst()->GetOpCode(); 196 } 197 198 friend bool operator == (const UseIterator& a, const UseIterator& b) 199 { 200 return a.out_ == b.out_; 201 }; 202 friend bool operator != (const UseIterator& a, const UseIterator& b) 203 { 204 return a.out_ != b.out_; 205 }; 206 207 private: 208 Circuit* circuit_; 209 Out* out_; 210 }; 211 212 struct ConstInsIterator { 213 ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in) 214 { 215 } 216 217 GateRef operator*() const 218 { 219 return circuit_->GetGateRef(in_->GetGateConst()); 220 } 221 222 const ConstInsIterator& operator++() 223 { 224 in_++; 225 return *this; 226 } 227 ConstInsIterator operator++(int) 228 { 229 ConstInsIterator tmp = *this; 230 ++(*this); 231 return tmp; 232 } 233 234 OpCode GetOpCode() const 235 { 236 ASSERT(in_ != nullptr); 237 return in_->GetGateConst()->GetOpCode(); 238 } 239 240 friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b) 241 { 242 return a.in_ == b.in_; 243 }; 244 friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b) 245 { 246 return a.in_ != b.in_; 247 }; 248 249 private: 250 const Circuit* circuit_; 251 const In* in_; 252 }; 253 254 struct InsIterator { 255 InsIterator(const Circuit* circuit, In* in) : circuit_(circuit), in_(in) 256 { 257 } 258 259 GateRef operator*() 260 { 261 return circuit_->GetGateRef(in_->GetGate()); 262 } 263 264 const InsIterator& operator++() 265 { 266 in_++; 267 return *this; 268 } 269 InsIterator operator++(int) 270 { 271 InsIterator tmp = *this; 272 ++(*this); 273 return tmp; 274 } 275 276 OpCode GetOpCode() const 277 { 278 ASSERT(in_ != nullptr); 279 return in_->GetGateConst()->GetOpCode(); 280 } 281 282 friend bool operator== (const InsIterator& a, const InsIterator& b) 283 { 284 return a.in_ == b.in_; 285 }; 286 friend bool operator!= (const InsIterator& a, const InsIterator& b) 287 { 288 return a.in_ != b.in_; 289 }; 290 291 private: 292 const Circuit* circuit_; 293 In* in_; 294 }; 295 296 struct ConstUseWrapper { 297 Circuit* circuit; 298 GateRef gate; 299 auto begin() 300 { 301 return GateAccessor(circuit).ConstUseBegin(gate); 302 } 303 auto end() 304 { 305 return GateAccessor(circuit).ConstUseEnd(); 306 } 307 }; 308 309 struct UseWrapper { 310 Circuit* circuit; 311 GateRef gate; 312 auto begin() 313 { 314 return GateAccessor(circuit).UseBegin(gate); 315 } 316 auto end() 317 { 318 return GateAccessor(circuit).UseEnd(); 319 } 320 }; 321 322 struct ConstInWrapper { 323 Circuit* circuit; 324 const GateRef gate; 325 auto begin() 326 { 327 return GateAccessor(circuit).ConstInBegin(gate); 328 } 329 auto end() 330 { 331 return GateAccessor(circuit).ConstInEnd(gate); 332 } 333 }; 334 335 struct InWrapper { 336 Circuit* circuit; 337 GateRef gate; 338 auto begin() 339 { 340 return GateAccessor(circuit).InBegin(gate); 341 } 342 auto end() 343 { 344 return GateAccessor(circuit).InEnd(gate); 345 } 346 }; 347 348 ConstInWrapper ConstIns(GateRef gate) const 349 { 350 return { circuit_, gate }; 351 } 352 353 InWrapper Ins(GateRef gate) const 354 { 355 return { circuit_, gate }; 356 } 357 358 ConstUseWrapper ConstUses(GateRef gate) const 359 { 360 return { circuit_, gate }; 361 } 362 363 UseWrapper Uses(GateRef gate) 364 { 365 return { circuit_, gate }; 366 } 367 368 explicit GateAccessor(Circuit *circuit) : circuit_(circuit) 369 { 370 } 371 372 Circuit *GetCircuit() const 373 { 374 return circuit_; 375 } 376 377 ~GateAccessor() = default; 378 void GetAllGates(std::vector<GateRef>& gates) const; 379 size_t GetNumIns(GateRef gate) const; 380 OpCode GetOpCode(GateRef gate) const; 381 bool IsGCRelated(GateRef gate) const; 382 uint64_t TryGetValue(GateRef gate) const; 383 ICmpCondition GetICmpCondition(GateRef gate) const; 384 FCmpCondition GetFCmpCondition(GateRef gate) const; 385 size_t GetOffset(GateRef gate) const; 386 size_t GetInitOffset(GateRef gate) const; 387 uint32_t GetTrueWeight(GateRef gate) const; 388 uint32_t GetFalseWeight(GateRef gate) const; 389 bool HasBranchWeight(GateRef gate) const; 390 MemoryAttribute GetMemoryAttribute(GateRef gate) const; 391 size_t GetIndex(GateRef gate) const; 392 size_t GetJSType(GateRef gate) const; 393 uint32_t GetArraySize(GateRef gate) const; 394 void SetArraySize(GateRef gate, uint32_t size); 395 uint32_t GetStringStatus(GateRef gate) const; 396 void SetStringStatus(GateRef gate, uint32_t type); 397 ElementsKind GetElementsKind(GateRef gate) const; 398 void SetElementsKind(GateRef gate, ElementsKind kind); 399 RegionSpaceFlag GetRegionSpaceFlag(GateRef gate) const; 400 size_t GetVirtualRegisterIndex(GateRef gate) const; 401 bool TypedOpIsTypedArray(GateRef gate, TypedOpKind kind) const; 402 TypedLoadOp GetTypedLoadOp(GateRef gate) const; 403 TypedStoreOp GetTypedStoreOp(GateRef gate) const; 404 MemoryType GetMemoryType(GateRef gate) const; 405 uint32_t GetHClassIndex(GateRef gate) const; 406 TypedBinOp GetTypedBinaryOp(GateRef gate) const; 407 TypedCallTargetCheckOp GetTypedCallTargetCheckOp(GateRef gate) const; 408 bool HasNumberType(GateRef gate) const; 409 bool HasStringType(GateRef gate) const; 410 GlobalTSTypeRef GetFuncGT(GateRef gate) const; 411 GateType GetParamGateType(GateRef gate) const; 412 ParamType GetParamType(GateRef gate) const; 413 TypedUnaryAccessor GetTypedUnAccessor(GateRef gate) const; 414 TypedBinaryAccessor GetTypedBinaryAccessor(GateRef gate) const; 415 TypedJumpAccessor GetTypedJumpAccessor(GateRef gate) const; 416 ArrayMetaDataAccessor GetArrayMetaDataAccessor(GateRef gate) const; 417 CreateArgumentsAccessor GetCreateArgumentsAccessor(GateRef gate) const; 418 ObjectTypeAccessor GetObjectTypeAccessor(GateRef gate) const; 419 BuiltinPrototypeHClassAccessor GetBuiltinHClassAccessor(GateRef gate) const; 420 TypedArrayMetaDataAccessor GetTypedArrayMetaDataAccessor(GateRef gate) const; 421 LoadElementAccessor GetLoadElementAccessor(GateRef gate) const; 422 StoreElementAccessor GetStoreElementAccessor(GateRef gate) const; 423 bool NeedPushArgv(GateRef gate) const; 424 uint64_t GetConstantValue(GateRef gate) const; 425 const ChunkVector<char>& GetConstantString(GateRef gate) const; 426 bool IsVtable(GateRef gate) const; 427 bool GetNoGCFlag(GateRef gate) const; 428 bool TypedCallIsNoGC(GateRef gate) const; 429 bool IsNoGC(GateRef gate) const; 430 uint32_t TryGetPcOffset(GateRef gate) const; 431 uint32_t TryGetBcIndex(GateRef gate) const; 432 uint32_t TryGetMethodOffset(GateRef gate) const; 433 GateRef GetFrameArgs(GateRef gate) const; 434 void UpdateMethodOffset(GateRef gate, uint32_t methodOffset); 435 PGOTypeRef TryGetPGOType(GateRef gate) const; 436 void TrySetPGOType(GateRef gate, PGOTypeRef type); 437 uint32_t TryGetArrayElementsLength(GateRef gate) const; 438 void TrySetArrayElementsLength(GateRef gate, uint32_t length); 439 RegionSpaceFlag TryGetRegionSpaceFlag(GateRef gate) const; 440 void TrySetRegionSpaceFlag(GateRef gate, RegionSpaceFlag length); 441 ElementsKind TryGetElementsKind(GateRef gate) const; 442 ElementsKind TryGetArrayElementsKind(GateRef gate) const; 443 ElementsKind TryGetArrayElementsKindAfterTransition(GateRef gate) const; 444 void TrySetElementsKind(GateRef gate, ElementsKind kind); 445 void TrySetTransitionElementsKind(GateRef gate, ElementsKind kind); 446 void TrySetOnHeapMode(GateRef gate, OnHeapMode onHeapMode) const; 447 OnHeapMode TryGetOnHeapMode(GateRef gate) const; 448 EcmaOpcode GetByteCodeOpcode(GateRef gate) const; 449 void Print(GateRef gate) const DUMP_API_ATTR; 450 std::string ToString(GateRef gate) const DUMP_API_ATTR; 451#ifndef NDEBUG 452 void PrintById(size_t id) const DUMP_API_ATTR ; 453#endif 454 void PrintWithBytecode(GateRef gate) const DUMP_API_ATTR; 455 void ShortPrint(GateRef gate) const; 456 GateId GetId(GateRef gate) const; 457 GateRef GetValueIn(GateRef gate, size_t idx = 0) const; 458 size_t GetNumValueIn(GateRef gate) const; 459 std::vector<GateRef> GetValueIns(GateRef gate) const; 460 GateRef GetIn(GateRef gate, size_t idx) const; 461 GateRef GetState(GateRef gate, size_t idx = 0) const; 462 GateRef GetDep(GateRef gate, size_t idx = 0) const; 463 size_t GetImmediateId(GateRef gate) const; 464 void SetDep(GateRef gate, GateRef depGate, size_t idx = 0); 465 UseIterator ReplaceIn(const UseIterator &useIt, GateRef replaceGate); 466 // Add for lowering 467 GateType GetGateType(GateRef gate) const; 468 bool IsConvertSupport(GateRef gate) const; 469 ValueType GetSrcType(GateRef gate) const; 470 ValueType GetDstType(GateRef gate) const; 471 void SetGateType(GateRef gate, GateType gt); 472 void DeleteIn(GateRef gate, size_t idx); 473 UseIterator DeleteGate(const UseIterator &useIt); 474 void DecreaseIn(const UseIterator &useIt); 475 void DecreaseIn(GateRef gate, size_t index); 476 void NewIn(GateRef gate, size_t idx, GateRef in); 477 size_t GetStateCount(GateRef gate) const; 478 size_t GetDependCount(GateRef gate) const; 479 size_t GetInValueCount(GateRef gate) const; 480 size_t GetInValueStarts(GateRef gate) const; 481 void UpdateAllUses(GateRef gate, GateRef replaceValueIn); 482 void ReplaceControlGate(GateRef gate, GateRef newState); 483 void ReplaceInAfterInsert(GateRef state, GateRef depend, GateRef newGate); 484 void GetFrameStateDependIn(GateRef gate, GateRef &dependIn); 485 void GetStateInAndDependIn(GateRef insertAfter, GateRef &stateIn, GateRef &dependIn); 486 void ReplaceIn(GateRef gate, size_t index, GateRef in); 487 void ReplaceStateIn(GateRef gate, GateRef in, size_t index = 0); 488 void ReplaceDependIn(GateRef gate, GateRef in, size_t index = 0); 489 void ReplaceOrNewDependIn(GateRef gate, GateRef in, size_t index = 0); 490 void ReplaceValueIn(GateRef gate, GateRef in, size_t index = 0); 491 void DeleteGate(GateRef gate); 492 MachineType GetMachineType(GateRef gate) const; 493 void SetMachineType(GateRef gate, MachineType type); 494 GateRef GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const; 495 GateRef GetInitialEnvGate(GateRef depend, GateRef jsFunc) const; 496 double GetFloat64FromConstant(GateRef gate) const; 497 int GetInt32FromConstant(GateRef gate) const; 498 bool IsInGateNull(GateRef gate, size_t idx) const; 499 bool IsSelector(GateRef g) const; 500 bool IsSimpleState(GateRef g) const; 501 bool IsValueSelector(GateRef g) const; 502 bool IsFrameValues(GateRef g) const; 503 bool IsControlCase(GateRef gate) const; 504 bool IsLoopExit(GateRef gate) const; 505 bool IsLoopExitRelated(GateRef gate) const; 506 bool IsLoopHead(GateRef gate) const; 507 bool IsLoopBack(GateRef gate) const; 508 bool IsState(GateRef gate) const; 509 bool IsConstant(GateRef gate) const; 510 bool IsDependSelector(GateRef gate) const; 511 bool IsConstantValue(GateRef gate, uint64_t value) const; 512 bool IsConstantTaggedValue(GateRef gate, uint64_t value) const; 513 bool IsConstantUndefined(GateRef gate) const; 514 bool IsUndefinedOrNullOrHole(GateRef gate) const; 515 bool IsConstantNumber(GateRef gate) const; 516 bool IsTypedOperator(GateRef gate) const; 517 bool IsNotWrite(GateRef gate) const; 518 bool IsDead(GateRef gate) const; 519 bool IsCheckWithOneIn(GateRef gate) const; 520 bool IsCheckWithTwoIns(GateRef gate) const; 521 bool IsSchedulable(GateRef gate) const; 522 bool IsVirtualState(GateRef gate) const; 523 bool IsGeneralState(GateRef gate) const; 524 MarkCode GetMark(GateRef gate) const; 525 void SetMark(GateRef gate, MarkCode mark); 526 bool IsFinished(GateRef gate) const; 527 bool IsVisited(GateRef gate) const; 528 bool IsPrevisit(GateRef gate) const; 529 bool IsNotMarked(GateRef gate) const; 530 void SetFinished(GateRef gate); 531 void SetPrevisit(GateRef gate); 532 void SetVisited(GateRef gate); 533 bool IsStateIn(const UseIterator &useIt) const; 534 bool IsDependIn(const UseIterator &useIt) const; 535 bool IsValueIn(const UseIterator &useIt) const; 536 bool IsFrameStateIn(const UseIterator &useIt) const; 537 bool IsStateIn(GateRef gate, size_t index) const; 538 bool IsDependIn(GateRef gate, size_t index) const; 539 bool IsValueIn(GateRef gate, size_t index) const; 540 void GetStateUses(GateRef gate, std::vector<GateRef> &stateUses); 541 void GetDependUses(GateRef gate, std::vector<GateRef> &dependUses); 542 void GetValueUses(GateRef gate, std::vector<GateRef> &valueUses); 543 size_t GetValueUsesCount(GateRef gate); 544 bool IsFrameStateIn(GateRef gate, size_t index) const; 545 void EliminateRedundantPhi(); 546 void ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value); 547 void ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef replacement); 548 void ReplaceGate(GateRef gate, GateRef replacement); 549 uint32_t GetFirstValue(GateRef gate) const; 550 uint32_t GetSecondValue(GateRef gate) const; 551 GateRef GetGlueFromArgList() const; 552 void GetArgsOuts(std::vector<GateRef>& outs) const; 553 void GetReturnOuts(std::vector<GateRef>& outs) const; 554 bool IsFixed(GateRef g) const; 555 bool IsProlog(GateRef g) const; 556 bool IsCFGMerge(GateRef g) const; 557 bool MetaDataEqu(GateRef g1, GateRef g2) const; 558 bool MetaDataValueEqu(GateRef g1, GateRef g2) const; 559 bool IsNop(GateRef g) const; 560 bool IsRoot(GateRef g) const; 561 bool HasOuts(GateRef gate) const; 562 void DeleteGateIfNoUse(GateRef gate); 563 GateRef GetDependSelectorFromMerge(GateRef gate); 564 bool HasIfExceptionUse(GateRef gate) const; 565 bool IsIn(GateRef g, GateRef in) const; 566 bool IsHeapObjectFromElementsKind(GateRef gate); 567 bool IsConstString(GateRef gate); 568 bool IsSingleCharGate(GateRef gate); 569 bool UseForTypeOpProfilerGate(GateRef gate) const; 570 uint32_t GetStringIdFromLdaStrGate(GateRef gate); 571 bool IsIfOrSwitchRelated(GateRef gate) const; 572 uint32_t GetConstpoolId(GateRef gate) const; 573 GateRef GetFrameValue(GateRef gate); 574 575 GateRef GetCircuitRoot() const 576 { 577 return GetRoot(OpCode::CIRCUIT_ROOT); 578 } 579 580 GateRef GetStateRoot() const 581 { 582 return GetRoot(OpCode::STATE_ENTRY); 583 } 584 585 GateRef GetDependRoot() const 586 { 587 return GetRoot(OpCode::DEPEND_ENTRY); 588 } 589 590 GateRef GetArgRoot() const 591 { 592 return GetRoot(OpCode::ARG_LIST); 593 } 594 595 GateRef GetReturnRoot() const 596 { 597 return GetRoot(OpCode::RETURN_LIST); 598 } 599 600 inline bool IsStateRoot(GateRef gate) const 601 { 602 return gate == GetStateRoot(); 603 } 604 605 size_t GetFrameDepth(GateRef gate, OpCode op); 606 GateRef GetFrameState(GateRef gate) const; 607 void ReplaceFrameStateIn(GateRef gate, GateRef in); 608 bool HasFrameState(GateRef gate) const; 609 GateRef FindNearestFrameState(GateRef gate) const; 610 GateRef FindNearestStateSplit(GateRef gate) const; 611 void SetMetaData(GateRef gate, const GateMetaData* meta); 612 613 void ReplaceHirWithIfBranch(GateRef hirGate, StateDepend success, StateDepend exception, GateRef value); 614 void ReplaceHirDirectly(GateRef hirGate, StateDepend replacement, GateRef value); 615 void ReplaceHirAndDeleteIfException(GateRef hirGate, StateDepend replacement, GateRef value); 616 617 bool IsLoopBackUse(GateRef gate, const UseIterator &useIt) const; 618 void GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const; 619 bool IsCreateArray(GateRef gate) const; 620 void SetStoreNoBarrier(GateRef gate, bool isNoBarrier); 621 bool IsNoBarrier(GateRef gate) const; 622 void GetIns(GateRef gate, std::vector<GateRef>& ins) const; 623 624 TypedBinOp GetRevCompareOpForTypedBinOp(TypedBinOp op); 625 TypedBinOp GetSwapCompareOpForTypedBinOp(TypedBinOp op); 626 627private: 628 const GateMetaData *GetMetaData(GateRef gate) const; 629 UseIterator ReplaceHirIfSuccess(const UseIterator &useIt, GateRef state); 630 UseIterator ReplaceHirIfException(const UseIterator &useIt, StateDepend replacement); 631 void ExceptionReturn(GateRef state, GateRef depend); 632 633 GateRef GetRoot(OpCode opcode) const; 634 ConstUseIterator ConstUseBegin(GateRef gate) const 635 { 636 if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) { 637 return ConstUseIterator(circuit_, nullptr); 638 } 639 auto use = circuit_->LoadGatePtrConst(gate)->GetFirstOutConst(); 640 return ConstUseIterator(circuit_, use); 641 } 642 643 ConstUseIterator ConstUseEnd() const 644 { 645 return ConstUseIterator(circuit_, nullptr); 646 } 647 648 UseIterator UseBegin(GateRef gate) const 649 { 650 if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) { 651 return UseIterator(circuit_, nullptr); 652 } 653 auto use = circuit_->LoadGatePtr(gate)->GetFirstOut(); 654 return UseIterator(circuit_, use); 655 } 656 657 UseIterator UseEnd() const 658 { 659 return UseIterator(circuit_, nullptr); 660 } 661 662 ConstInsIterator ConstInBegin(GateRef gate) const 663 { 664 return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]); 665 } 666 667 ConstInsIterator ConstInEnd(GateRef gate) const 668 { 669 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 670 return ConstInsIterator(circuit_, 671 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]); 672 } 673 674 InsIterator InBegin(GateRef gate) 675 { 676 return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[0]); 677 } 678 679 InsIterator InEnd(GateRef gate) 680 { 681 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 682 return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[endIndex]); 683 } 684 685 void GetOuts(GateRef gate, std::vector<GateRef>& outs) const; 686 687 void GetInStates(GateRef gate, std::vector<GateRef>& ins) const; 688 689 Circuit *circuit_; 690 691 friend class Circuit; 692 friend class CircuitBuilder; 693 friend class LLVMIRBuilder; 694 friend class LiteCGIRBuilder; 695 friend class Scheduler; 696 friend class LoopPeeling; 697}; 698 699class ConstGateAccessor { 700public: 701 struct ConstInsIterator { 702 ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in) 703 { 704 } 705 706 GateRef operator*() const 707 { 708 return circuit_->GetGateRef(in_->GetGateConst()); 709 } 710 711 const ConstInsIterator& operator++() 712 { 713 in_++; 714 return *this; 715 } 716 ConstInsIterator operator++(int) 717 { 718 ConstInsIterator tmp = *this; 719 ++(*this); 720 return tmp; 721 } 722 723 OpCode GetOpCode() const 724 { 725 ASSERT(in_ != nullptr); 726 return in_->GetGateConst()->GetOpCode(); 727 } 728 729 friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b) 730 { 731 return a.in_ == b.in_; 732 }; 733 friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b) 734 { 735 return a.in_ != b.in_; 736 }; 737 738 private: 739 const Circuit* circuit_; 740 const In* in_; 741 }; 742 743 struct ConstInWrapper { 744 const Circuit* circuit; 745 const GateRef gate; 746 auto begin() 747 { 748 return ConstGateAccessor(circuit).ConstInBegin(gate); 749 } 750 auto end() 751 { 752 return ConstGateAccessor(circuit).ConstInEnd(gate); 753 } 754 }; 755 756 ConstInWrapper Ins(GateRef gate) const 757 { 758 return { circuit_, gate }; 759 } 760 761 explicit ConstGateAccessor(const Circuit *circuit) : circuit_(circuit) 762 { 763 } 764 765 ~ConstGateAccessor() = default; 766 767 bool IsFixed(GateRef g) const; 768 bool IsProlog(GateRef g) const; 769 bool IsSchedulable(GateRef g) const; 770 771private: 772 ConstInsIterator ConstInBegin(GateRef gate) const 773 { 774 return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]); 775 } 776 777 ConstInsIterator ConstInEnd(GateRef gate) const 778 { 779 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 780 return ConstInsIterator(circuit_, 781 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]); 782 } 783 const GateMetaData *GetMetaData(GateRef g) const; 784 785 const Circuit *circuit_; 786 friend struct ConstInWrapper; 787}; 788} 789#endif // ECMASCRIPT_COMPILER_GATE_ACCESSOR_H 790