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 24 namespace panda::ecmascript::kungfu { 25 26 class StateDepend { 27 public: StateDepend()28 StateDepend() 29 : state_(Circuit::NullGate()), depend_(Circuit::NullGate()) {} 30 StateDepend(GateRef state,GateRef depend)31 explicit StateDepend(GateRef state, GateRef depend) 32 : state_(state), depend_(depend) {} 33 State()34 GateRef State() const 35 { 36 return state_; 37 } 38 Depend()39 GateRef Depend() const 40 { 41 return depend_; 42 } 43 SetState(GateRef state)44 void SetState(GateRef state) 45 { 46 state_ = state; 47 } 48 SetDepend(GateRef depend)49 void SetDepend(GateRef depend) 50 { 51 depend_ = depend; 52 } 53 Reset()54 void Reset() 55 { 56 state_ = Circuit::NullGate(); 57 depend_ = Circuit::NullGate(); 58 } 59 60 private: 61 GateRef state_; 62 GateRef depend_; 63 }; 64 65 class Edge { 66 public: Edge(GateRef gate,size_t index)67 explicit Edge(GateRef gate, size_t index) : gate_(gate), index_(static_cast<uint32_t>(index)) {} 68 GetGate()69 GateRef GetGate() const 70 { 71 return gate_; 72 } 73 GetIndex()74 size_t GetIndex() const 75 { 76 return static_cast<size_t>(index_); 77 } 78 SetIndex(size_t index)79 void SetIndex(size_t index) 80 { 81 index_ = static_cast<uint32_t>(index); 82 } 83 84 private: 85 GateRef gate_; 86 uint32_t index_; 87 }; 88 89 class GateAccessor { 90 public: 91 constexpr static uint32_t INVALID_BC_INDEX = 0; 92 93 // do not create new gate or modify self during iteration 94 struct ConstUseIterator { ConstUseIteratorConstUseIterator95 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 GetIndexConstUseIterator124 size_t GetIndex() const 125 { 126 ASSERT(out_ != nullptr); 127 return out_->GetIndex(); 128 } 129 GetOpCodeConstUseIterator130 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 { UseIteratorUseIterator152 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 GetIndexUseIterator179 size_t GetIndex() const 180 { 181 ASSERT(out_ != nullptr); 182 return out_->GetIndex(); 183 } 184 GetEdgeUseIterator185 Edge GetEdge() 186 { 187 ASSERT(out_ != nullptr); 188 UseIterator it = *this; 189 return Edge(*it, GetIndex()); 190 } 191 GetOpCodeUseIterator192 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 { ConstInsIteratorConstInsIterator213 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 GetOpCodeConstInsIterator234 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 { InsIteratorInsIterator255 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 GetOpCodeInsIterator276 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; beginConstUseWrapper299 auto begin() 300 { 301 return GateAccessor(circuit).ConstUseBegin(gate); 302 } endConstUseWrapper303 auto end() 304 { 305 return GateAccessor(circuit).ConstUseEnd(); 306 } 307 }; 308 309 struct UseWrapper { 310 Circuit* circuit; 311 GateRef gate; beginUseWrapper312 auto begin() 313 { 314 return GateAccessor(circuit).UseBegin(gate); 315 } endUseWrapper316 auto end() 317 { 318 return GateAccessor(circuit).UseEnd(); 319 } 320 }; 321 322 struct ConstInWrapper { 323 Circuit* circuit; 324 const GateRef gate; beginConstInWrapper325 auto begin() 326 { 327 return GateAccessor(circuit).ConstInBegin(gate); 328 } endConstInWrapper329 auto end() 330 { 331 return GateAccessor(circuit).ConstInEnd(gate); 332 } 333 }; 334 335 struct InWrapper { 336 Circuit* circuit; 337 GateRef gate; beginInWrapper338 auto begin() 339 { 340 return GateAccessor(circuit).InBegin(gate); 341 } endInWrapper342 auto end() 343 { 344 return GateAccessor(circuit).InEnd(gate); 345 } 346 }; 347 ConstIns(GateRef gate)348 ConstInWrapper ConstIns(GateRef gate) const 349 { 350 return { circuit_, gate }; 351 } 352 Ins(GateRef gate)353 InWrapper Ins(GateRef gate) const 354 { 355 return { circuit_, gate }; 356 } 357 ConstUses(GateRef gate)358 ConstUseWrapper ConstUses(GateRef gate) const 359 { 360 return { circuit_, gate }; 361 } 362 Uses(GateRef gate)363 UseWrapper Uses(GateRef gate) 364 { 365 return { circuit_, gate }; 366 } 367 GateAccessor(Circuit * circuit)368 explicit GateAccessor(Circuit *circuit) : circuit_(circuit) 369 { 370 } 371 GetCircuit()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 uint32_t GetTrueWeight(GateRef gate) const; 387 uint32_t GetFalseWeight(GateRef gate) const; 388 bool HasBranchWeight(GateRef gate) const; 389 MemoryOrder GetMemoryOrder(GateRef gate) const; 390 size_t GetIndex(GateRef gate) const; 391 size_t GetJSType(GateRef gate) const; 392 uint32_t GetArraySize(GateRef gate) const; 393 void SetArraySize(GateRef gate, uint32_t size); 394 uint32_t GetStringStatus(GateRef gate) const; 395 void SetStringStatus(GateRef gate, uint32_t type); 396 size_t GetVirtualRegisterIndex(GateRef gate) const; 397 bool TypedOpIsTypedArray(GateRef gate, TypedOpKind kind) const; 398 GateType GetReceiverType(GateRef gate) const; 399 GateType GetHolderType(GateRef gate) const; 400 GateType GetNewHolderType(GateRef gate) const; 401 TypedLoadOp GetTypedLoadOp(GateRef gate) const; 402 TypedStoreOp GetTypedStoreOp(GateRef gate) const; 403 MemoryType GetMemoryType(GateRef gate) const; 404 uint32_t GetHClassIndex(GateRef gate) const; 405 TypedBinOp GetTypedBinaryOp(GateRef gate) const; 406 TypedCallTargetCheckOp GetTypedCallTargetCheckOp(GateRef gate) const; 407 PGOTypeRef GetTypedBinaryType(GateRef gate) const; 408 bool HasPrimitiveNumberType(GateRef gate) const; 409 bool HasNumberType(GateRef gate) const; 410 bool HasStringType(GateRef gate) const; 411 GlobalTSTypeRef GetFuncGT(GateRef gate) const; 412 GateType GetParamGateType(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 ObjectTypeAccessor GetObjectTypeAccessor(GateRef gate) const; 418 BuiltinPrototypeHClassAccessor GetBuiltinHClassAccessor(GateRef gate) const; 419 TypedArrayMetaDateAccessor GetTypedArrayMetaDateAccessor(GateRef gate) const; 420 LoadElementAccessor GetLoadElementAccessor(GateRef gate) const; 421 StoreElementAccessor GetStoreElementAccessor(GateRef gate) const; 422 uint64_t GetConstantValue(GateRef gate) const; 423 const ChunkVector<char>& GetConstantString(GateRef gate) const; 424 bool IsVtable(GateRef gate) const; 425 bool GetNoGCFlag(GateRef gate) const; 426 bool TypedCallIsNoGC(GateRef gate) const; 427 bool IsNoGC(GateRef gate) const; 428 uint32_t TryGetPcOffset(GateRef gate) const; 429 uint32_t TryGetBcIndex(GateRef gate) const; 430 uint32_t TryGetMethodOffset(GateRef gate) const; 431 GateRef GetFrameArgs(GateRef gate) const; 432 void UpdateMethodOffset(GateRef gate, uint32_t methodOffset); 433 PGOTypeRef TryGetPGOType(GateRef gate) const; 434 void TrySetPGOType(GateRef gate, PGOTypeRef type); 435 uint32_t TryGetArrayElementsLength(GateRef gate) const; 436 void TrySetArrayElementsLength(GateRef gate, uint32_t length); 437 ElementsKind TryGetElementsKind(GateRef gate) const; 438 ElementsKind TryGetArrayElementsKind(GateRef gate) const; 439 void TrySetElementsKind(GateRef gate, ElementsKind kind); 440 void TrySetOnHeapMode(GateRef gate, OnHeapMode onHeapMode) const; 441 OnHeapMode TryGetOnHeapMode(GateRef gate) const; 442 EcmaOpcode GetByteCodeOpcode(GateRef gate) const; 443 void Print(GateRef gate) const DUMP_API_ATTR; 444 #ifndef NDEBUG 445 void PrintById(size_t id) const DUMP_API_ATTR ; 446 #endif 447 void PrintWithBytecode(GateRef gate) const DUMP_API_ATTR; 448 void ShortPrint(GateRef gate) const; 449 GateId GetId(GateRef gate) const; 450 GateRef GetValueIn(GateRef gate, size_t idx = 0) const; 451 size_t GetNumValueIn(GateRef gate) const; 452 GateRef GetIn(GateRef gate, size_t idx) const; 453 GateRef GetState(GateRef gate, size_t idx = 0) const; 454 GateRef GetDep(GateRef gate, size_t idx = 0) const; 455 size_t GetImmediateId(GateRef gate) const; 456 void SetDep(GateRef gate, GateRef depGate, size_t idx = 0); 457 UseIterator ReplaceIn(const UseIterator &useIt, GateRef replaceGate); 458 // Add for lowering 459 GateType GetGateType(GateRef gate) const; 460 bool IsConvertSupport(GateRef gate) const; 461 ValueType GetSrcType(GateRef gate) const; 462 ValueType GetDstType(GateRef gate) const; 463 void SetGateType(GateRef gate, GateType gt); 464 void DeleteIn(GateRef gate, size_t idx); 465 UseIterator DeleteGate(const UseIterator &useIt); 466 void DecreaseIn(const UseIterator &useIt); 467 void DecreaseIn(GateRef gate, size_t index); 468 void NewIn(GateRef gate, size_t idx, GateRef in); 469 size_t GetStateCount(GateRef gate) const; 470 size_t GetDependCount(GateRef gate) const; 471 size_t GetInValueCount(GateRef gate) const; 472 size_t GetInValueStarts(GateRef gate) const; 473 void UpdateAllUses(GateRef gate, GateRef replaceValueIn); 474 void ReplaceInAfterInsert(GateRef state, GateRef depend, GateRef newGate); 475 void GetFrameStateDependIn(GateRef gate, GateRef &dependIn); 476 void GetStateInAndDependIn(GateRef insertAfter, GateRef &stateIn, GateRef &dependIn); 477 void ReplaceIn(GateRef gate, size_t index, GateRef in); 478 void ReplaceStateIn(GateRef gate, GateRef in, size_t index = 0); 479 void ReplaceDependIn(GateRef gate, GateRef in, size_t index = 0); 480 void ReplaceOrNewDependIn(GateRef gate, GateRef in, size_t index = 0); 481 void ReplaceValueIn(GateRef gate, GateRef in, size_t index = 0); 482 void DeleteGate(GateRef gate); 483 MachineType GetMachineType(GateRef gate) const; 484 void SetMachineType(GateRef gate, MachineType type); 485 GateRef GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const; 486 GateRef GetInitialEnvGate(GateRef jsFunc) const; 487 double GetFloat64FromConstant(GateRef gate) const; 488 int GetInt32FromConstant(GateRef gate) const; 489 bool IsInGateNull(GateRef gate, size_t idx) const; 490 bool IsSelector(GateRef g) const; 491 bool IsSimpleState(GateRef g) const; 492 bool IsValueSelector(GateRef g) const; 493 bool IsFrameValues(GateRef g) const; 494 bool IsControlCase(GateRef gate) const; 495 bool IsLoopExit(GateRef gate) const; 496 bool IsLoopExitRelated(GateRef gate) const; 497 bool IsLoopHead(GateRef gate) const; 498 bool IsLoopBack(GateRef gate) const; 499 bool IsState(GateRef gate) const; 500 bool IsConstant(GateRef gate) const; 501 bool IsDependSelector(GateRef gate) const; 502 bool IsConstantValue(GateRef gate, uint64_t value) const; 503 bool IsConstantUndefined(GateRef gate) const; 504 bool IsUndefinedOrNull(GateRef gate) const; 505 bool IsConstantNumber(GateRef gate) const; 506 bool IsTypedOperator(GateRef gate) const; 507 bool IsNotWrite(GateRef gate) const; 508 bool IsDead(GateRef gate) const; 509 bool IsCheckWithOneIn(GateRef gate) const; 510 bool IsCheckWithTwoIns(GateRef gate) const; 511 bool IsSchedulable(GateRef gate) const; 512 bool IsVirtualState(GateRef gate) const; 513 bool IsGeneralState(GateRef gate) const; 514 MarkCode GetMark(GateRef gate) const; 515 void SetMark(GateRef gate, MarkCode mark); 516 bool IsFinished(GateRef gate) const; 517 bool IsVisited(GateRef gate) const; 518 bool IsPrevisit(GateRef gate) const; 519 bool IsNotMarked(GateRef gate) const; 520 void SetFinished(GateRef gate); 521 void SetPrevisit(GateRef gate); 522 void SetVisited(GateRef gate); 523 bool IsStateIn(const UseIterator &useIt) const; 524 bool IsDependIn(const UseIterator &useIt) const; 525 bool IsValueIn(const UseIterator &useIt) const; 526 bool IsFrameStateIn(const UseIterator &useIt) const; 527 bool IsStateIn(GateRef gate, size_t index) const; 528 bool IsDependIn(GateRef gate, size_t index) const; 529 bool IsValueIn(GateRef gate, size_t index) const; 530 void GetStateUses(GateRef gate, std::vector<GateRef> &stateUses); 531 void GetDependUses(GateRef gate, std::vector<GateRef> &dependUses); 532 void GetValueUses(GateRef gate, std::vector<GateRef> &valueUses); 533 bool IsFrameStateIn(GateRef gate, size_t index) const; 534 void EliminateRedundantPhi(); 535 void ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value); 536 void ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef replacement); 537 void ReplaceGate(GateRef gate, GateRef replacement); 538 GateType GetLeftType(GateRef gate) const; 539 GateType GetRightType(GateRef gate) const; 540 uint32_t GetFirstValue(GateRef gate) const; 541 uint32_t GetSecondValue(GateRef gate) const; 542 GateRef GetGlueFromArgList() const; 543 void GetArgsOuts(std::vector<GateRef>& outs) const; 544 void GetReturnOuts(std::vector<GateRef>& outs) const; 545 bool IsFixed(GateRef g) const; 546 bool IsProlog(GateRef g) const; 547 bool IsCFGMerge(GateRef g) const; 548 bool MetaDataEqu(GateRef g1, GateRef g2) const; 549 bool MetaDataValueEqu(GateRef g1, GateRef g2) const; 550 bool IsNop(GateRef g) const; 551 bool IsRoot(GateRef g) const; 552 bool HasOuts(GateRef gate) const; 553 void DeleteGateIfNoUse(GateRef gate); 554 GateRef GetDependSelectorFromMerge(GateRef gate); 555 bool HasIfExceptionUse(GateRef gate) const; 556 bool IsIn(GateRef g, GateRef in) const; 557 bool IsHeapObjectFromElementsKind(GateRef gate); 558 bool IsConstString(GateRef gate); 559 bool IsSingleCharGate(GateRef gate); 560 uint32_t GetStringIdFromLdaStrGate(GateRef gate); 561 bool IsIfOrSwitchRelated(GateRef gate) const; 562 GetCircuitRoot()563 GateRef GetCircuitRoot() const 564 { 565 return GetRoot(OpCode::CIRCUIT_ROOT); 566 } 567 GetStateRoot()568 GateRef GetStateRoot() const 569 { 570 return GetRoot(OpCode::STATE_ENTRY); 571 } 572 GetDependRoot()573 GateRef GetDependRoot() const 574 { 575 return GetRoot(OpCode::DEPEND_ENTRY); 576 } 577 GetArgRoot()578 GateRef GetArgRoot() const 579 { 580 return GetRoot(OpCode::ARG_LIST); 581 } 582 GetReturnRoot()583 GateRef GetReturnRoot() const 584 { 585 return GetRoot(OpCode::RETURN_LIST); 586 } 587 IsStateRoot(GateRef gate)588 inline bool IsStateRoot(GateRef gate) const 589 { 590 return gate == GetStateRoot(); 591 } 592 593 size_t GetFrameDepth(GateRef gate, OpCode op); 594 GateRef GetFrameState(GateRef gate) const; 595 void ReplaceFrameStateIn(GateRef gate, GateRef in); 596 bool HasFrameState(GateRef gate) const; 597 GateRef FindNearestFrameState(GateRef gate) const; 598 GateRef FindNearestStateSplit(GateRef gate) const; 599 void SetMetaData(GateRef gate, const GateMetaData* meta); 600 601 void ReplaceHirWithIfBranch(GateRef hirGate, StateDepend success, StateDepend exception, GateRef value); 602 void ReplaceHirDirectly(GateRef hirGate, StateDepend replacement, GateRef value); 603 void ReplaceHirAndDeleteIfException(GateRef hirGate, StateDepend replacement, GateRef value); 604 605 bool IsLoopBackUse(GateRef gate, const UseIterator &useIt) const; 606 void GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const; 607 bool IsCreateArray(GateRef gate) const; 608 void SetStoreNoBarrier(GateRef gate, bool isNoBarrier); 609 bool IsNoBarrier(GateRef gate) const; 610 611 private: 612 const GateMetaData *GetMetaData(GateRef gate) const; 613 UseIterator ReplaceHirIfSuccess(const UseIterator &useIt, GateRef state); 614 UseIterator ReplaceHirIfException(const UseIterator &useIt, StateDepend replacement); 615 void ExceptionReturn(GateRef state, GateRef depend); 616 617 GateRef GetRoot(OpCode opcode) const; ConstUseBegin(GateRef gate)618 ConstUseIterator ConstUseBegin(GateRef gate) const 619 { 620 if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) { 621 return ConstUseIterator(circuit_, nullptr); 622 } 623 auto use = circuit_->LoadGatePtrConst(gate)->GetFirstOutConst(); 624 return ConstUseIterator(circuit_, use); 625 } 626 ConstUseEnd()627 ConstUseIterator ConstUseEnd() const 628 { 629 return ConstUseIterator(circuit_, nullptr); 630 } 631 UseBegin(GateRef gate)632 UseIterator UseBegin(GateRef gate) const 633 { 634 if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) { 635 return UseIterator(circuit_, nullptr); 636 } 637 auto use = circuit_->LoadGatePtr(gate)->GetFirstOut(); 638 return UseIterator(circuit_, use); 639 } 640 UseEnd()641 UseIterator UseEnd() const 642 { 643 return UseIterator(circuit_, nullptr); 644 } 645 ConstInBegin(GateRef gate)646 ConstInsIterator ConstInBegin(GateRef gate) const 647 { 648 return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]); 649 } 650 ConstInEnd(GateRef gate)651 ConstInsIterator ConstInEnd(GateRef gate) const 652 { 653 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 654 return ConstInsIterator(circuit_, 655 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]); 656 } 657 InBegin(GateRef gate)658 InsIterator InBegin(GateRef gate) 659 { 660 return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[0]); 661 } 662 InEnd(GateRef gate)663 InsIterator InEnd(GateRef gate) 664 { 665 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 666 return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[endIndex]); 667 } 668 669 void GetIns(GateRef gate, std::vector<GateRef>& ins) const; 670 671 void GetOuts(GateRef gate, std::vector<GateRef>& outs) const; 672 673 void GetInStates(GateRef gate, std::vector<GateRef>& ins) const; 674 675 Circuit *circuit_; 676 677 friend class Circuit; 678 friend class LLVMIRBuilder; 679 friend class LiteCGIRBuilder; 680 friend class Scheduler; 681 friend class LoopPeeling; 682 }; 683 684 class ConstGateAccessor { 685 public: 686 struct ConstInsIterator { ConstInsIteratorConstInsIterator687 ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in) 688 { 689 } 690 691 GateRef operator*() const 692 { 693 return circuit_->GetGateRef(in_->GetGateConst()); 694 } 695 696 const ConstInsIterator& operator++() 697 { 698 in_++; 699 return *this; 700 } 701 ConstInsIterator operator++(int) 702 { 703 ConstInsIterator tmp = *this; 704 ++(*this); 705 return tmp; 706 } 707 GetOpCodeConstInsIterator708 OpCode GetOpCode() const 709 { 710 ASSERT(in_ != nullptr); 711 return in_->GetGateConst()->GetOpCode(); 712 } 713 714 friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b) 715 { 716 return a.in_ == b.in_; 717 }; 718 friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b) 719 { 720 return a.in_ != b.in_; 721 }; 722 723 private: 724 const Circuit* circuit_; 725 const In* in_; 726 }; 727 728 struct ConstInWrapper { 729 const Circuit* circuit; 730 const GateRef gate; beginConstInWrapper731 auto begin() 732 { 733 return ConstGateAccessor(circuit).ConstInBegin(gate); 734 } endConstInWrapper735 auto end() 736 { 737 return ConstGateAccessor(circuit).ConstInEnd(gate); 738 } 739 }; 740 Ins(GateRef gate)741 ConstInWrapper Ins(GateRef gate) const 742 { 743 return { circuit_, gate }; 744 } 745 ConstGateAccessor(const Circuit * circuit)746 explicit ConstGateAccessor(const Circuit *circuit) : circuit_(circuit) 747 { 748 } 749 750 ~ConstGateAccessor() = default; 751 752 bool IsFixed(GateRef g) const; 753 bool IsProlog(GateRef g) const; 754 bool IsSchedulable(GateRef g) const; 755 756 private: ConstInBegin(GateRef gate)757 ConstInsIterator ConstInBegin(GateRef gate) const 758 { 759 return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]); 760 } 761 ConstInEnd(GateRef gate)762 ConstInsIterator ConstInEnd(GateRef gate) const 763 { 764 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 765 return ConstInsIterator(circuit_, 766 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]); 767 } 768 const GateMetaData *GetMetaData(GateRef g) const; 769 770 const Circuit *circuit_; 771 friend struct ConstInWrapper; 772 }; 773 } 774 #endif // ECMASCRIPT_COMPILER_GATE_ACCESSOR_H 775