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 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 size_t GetVirtualRegisterIndex(GateRef gate) const; 400 bool TypedOpIsTypedArray(GateRef gate, TypedOpKind kind) 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 bool HasNumberType(GateRef gate) const; 408 bool HasStringType(GateRef gate) const; 409 GlobalTSTypeRef GetFuncGT(GateRef gate) const; 410 GateType GetParamGateType(GateRef gate) const; 411 ParamType GetParamType(GateRef gate) const; 412 TypedUnaryAccessor GetTypedUnAccessor(GateRef gate) const; 413 TypedBinaryAccessor GetTypedBinaryAccessor(GateRef gate) const; 414 TypedJumpAccessor GetTypedJumpAccessor(GateRef gate) const; 415 ArrayMetaDataAccessor GetArrayMetaDataAccessor(GateRef gate) const; 416 CreateArgumentsAccessor GetCreateArgumentsAccessor(GateRef gate) const; 417 ObjectTypeAccessor GetObjectTypeAccessor(GateRef gate) const; 418 BuiltinPrototypeHClassAccessor GetBuiltinHClassAccessor(GateRef gate) const; 419 TypedArrayMetaDataAccessor GetTypedArrayMetaDataAccessor(GateRef gate) const; 420 LoadElementAccessor GetLoadElementAccessor(GateRef gate) const; 421 StoreElementAccessor GetStoreElementAccessor(GateRef gate) const; 422 bool NeedPushArgv(GateRef gate) const; 423 uint64_t GetConstantValue(GateRef gate) const; 424 const ChunkVector<char>& GetConstantString(GateRef gate) const; 425 bool IsVtable(GateRef gate) const; 426 bool GetNoGCFlag(GateRef gate) const; 427 bool TypedCallIsNoGC(GateRef gate) const; 428 bool IsNoGC(GateRef gate) const; 429 uint32_t TryGetPcOffset(GateRef gate) const; 430 uint32_t TryGetBcIndex(GateRef gate) const; 431 uint32_t TryGetMethodOffset(GateRef gate) const; 432 GateRef GetFrameArgs(GateRef gate) const; 433 void UpdateMethodOffset(GateRef gate, uint32_t methodOffset); 434 PGOTypeRef TryGetPGOType(GateRef gate) const; 435 void TrySetPGOType(GateRef gate, PGOTypeRef type); 436 uint32_t TryGetArrayElementsLength(GateRef gate) const; 437 void TrySetArrayElementsLength(GateRef gate, uint32_t length); 438 ElementsKind TryGetElementsKind(GateRef gate) const; 439 ElementsKind TryGetArrayElementsKind(GateRef gate) const; 440 ElementsKind TryGetArrayElementsKindAfterTransition(GateRef gate) const; 441 void TrySetElementsKind(GateRef gate, ElementsKind kind); 442 void TrySetTransitionElementsKind(GateRef gate, ElementsKind kind); 443 void TrySetOnHeapMode(GateRef gate, OnHeapMode onHeapMode) const; 444 OnHeapMode TryGetOnHeapMode(GateRef gate) const; 445 EcmaOpcode GetByteCodeOpcode(GateRef gate) const; 446 void Print(GateRef gate) const DUMP_API_ATTR; 447 std::string ToString(GateRef gate) const DUMP_API_ATTR; 448 #ifndef NDEBUG 449 void PrintById(size_t id) const DUMP_API_ATTR ; 450 #endif 451 void PrintWithBytecode(GateRef gate) const DUMP_API_ATTR; 452 void ShortPrint(GateRef gate) const; 453 GateId GetId(GateRef gate) const; 454 GateRef GetValueIn(GateRef gate, size_t idx = 0) const; 455 size_t GetNumValueIn(GateRef gate) const; 456 std::vector<GateRef> GetValueIns(GateRef gate) const; 457 GateRef GetIn(GateRef gate, size_t idx) const; 458 GateRef GetState(GateRef gate, size_t idx = 0) const; 459 GateRef GetDep(GateRef gate, size_t idx = 0) const; 460 size_t GetImmediateId(GateRef gate) const; 461 void SetDep(GateRef gate, GateRef depGate, size_t idx = 0); 462 UseIterator ReplaceIn(const UseIterator &useIt, GateRef replaceGate); 463 // Add for lowering 464 GateType GetGateType(GateRef gate) const; 465 bool IsConvertSupport(GateRef gate) const; 466 ValueType GetSrcType(GateRef gate) const; 467 ValueType GetDstType(GateRef gate) const; 468 void SetGateType(GateRef gate, GateType gt); 469 void DeleteIn(GateRef gate, size_t idx); 470 UseIterator DeleteGate(const UseIterator &useIt); 471 void DecreaseIn(const UseIterator &useIt); 472 void DecreaseIn(GateRef gate, size_t index); 473 void NewIn(GateRef gate, size_t idx, GateRef in); 474 size_t GetStateCount(GateRef gate) const; 475 size_t GetDependCount(GateRef gate) const; 476 size_t GetInValueCount(GateRef gate) const; 477 size_t GetInValueStarts(GateRef gate) const; 478 void UpdateAllUses(GateRef gate, GateRef replaceValueIn); 479 void ReplaceControlGate(GateRef gate, GateRef newState); 480 void ReplaceInAfterInsert(GateRef state, GateRef depend, GateRef newGate); 481 void GetFrameStateDependIn(GateRef gate, GateRef &dependIn); 482 void GetStateInAndDependIn(GateRef insertAfter, GateRef &stateIn, GateRef &dependIn); 483 void ReplaceIn(GateRef gate, size_t index, GateRef in); 484 void ReplaceStateIn(GateRef gate, GateRef in, size_t index = 0); 485 void ReplaceDependIn(GateRef gate, GateRef in, size_t index = 0); 486 void ReplaceOrNewDependIn(GateRef gate, GateRef in, size_t index = 0); 487 void ReplaceValueIn(GateRef gate, GateRef in, size_t index = 0); 488 void DeleteGate(GateRef gate); 489 MachineType GetMachineType(GateRef gate) const; 490 void SetMachineType(GateRef gate, MachineType type); 491 GateRef GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const; 492 GateRef GetInitialEnvGate(GateRef depend, GateRef jsFunc) const; 493 double GetFloat64FromConstant(GateRef gate) const; 494 int GetInt32FromConstant(GateRef gate) const; 495 bool IsInGateNull(GateRef gate, size_t idx) const; 496 bool IsSelector(GateRef g) const; 497 bool IsSimpleState(GateRef g) const; 498 bool IsValueSelector(GateRef g) const; 499 bool IsFrameValues(GateRef g) const; 500 bool IsControlCase(GateRef gate) const; 501 bool IsLoopExit(GateRef gate) const; 502 bool IsLoopExitRelated(GateRef gate) const; 503 bool IsLoopHead(GateRef gate) const; 504 bool IsLoopBack(GateRef gate) const; 505 bool IsState(GateRef gate) const; 506 bool IsConstant(GateRef gate) const; 507 bool IsDependSelector(GateRef gate) const; 508 bool IsConstantValue(GateRef gate, uint64_t value) const; 509 bool IsConstantTaggedValue(GateRef gate, uint64_t value) const; 510 bool IsConstantUndefined(GateRef gate) const; 511 bool IsUndefinedOrNullOrHole(GateRef gate) const; 512 bool IsConstantNumber(GateRef gate) const; 513 bool IsTypedOperator(GateRef gate) const; 514 bool IsNotWrite(GateRef gate) const; 515 bool IsDead(GateRef gate) const; 516 bool IsCheckWithOneIn(GateRef gate) const; 517 bool IsCheckWithTwoIns(GateRef gate) const; 518 bool IsSchedulable(GateRef gate) const; 519 bool IsVirtualState(GateRef gate) const; 520 bool IsGeneralState(GateRef gate) const; 521 MarkCode GetMark(GateRef gate) const; 522 void SetMark(GateRef gate, MarkCode mark); 523 bool IsFinished(GateRef gate) const; 524 bool IsVisited(GateRef gate) const; 525 bool IsPrevisit(GateRef gate) const; 526 bool IsNotMarked(GateRef gate) const; 527 void SetFinished(GateRef gate); 528 void SetPrevisit(GateRef gate); 529 void SetVisited(GateRef gate); 530 bool IsStateIn(const UseIterator &useIt) const; 531 bool IsDependIn(const UseIterator &useIt) const; 532 bool IsValueIn(const UseIterator &useIt) const; 533 bool IsFrameStateIn(const UseIterator &useIt) const; 534 bool IsStateIn(GateRef gate, size_t index) const; 535 bool IsDependIn(GateRef gate, size_t index) const; 536 bool IsValueIn(GateRef gate, size_t index) const; 537 void GetStateUses(GateRef gate, std::vector<GateRef> &stateUses); 538 void GetDependUses(GateRef gate, std::vector<GateRef> &dependUses); 539 void GetValueUses(GateRef gate, std::vector<GateRef> &valueUses); 540 size_t GetValueUsesCount(GateRef gate); 541 bool IsFrameStateIn(GateRef gate, size_t index) const; 542 void EliminateRedundantPhi(); 543 void ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value); 544 void ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef replacement); 545 void ReplaceGate(GateRef gate, GateRef replacement); 546 uint32_t GetFirstValue(GateRef gate) const; 547 uint32_t GetSecondValue(GateRef gate) const; 548 GateRef GetGlueFromArgList() const; 549 void GetArgsOuts(std::vector<GateRef>& outs) const; 550 void GetReturnOuts(std::vector<GateRef>& outs) const; 551 bool IsFixed(GateRef g) const; 552 bool IsProlog(GateRef g) const; 553 bool IsCFGMerge(GateRef g) const; 554 bool MetaDataEqu(GateRef g1, GateRef g2) const; 555 bool MetaDataValueEqu(GateRef g1, GateRef g2) const; 556 bool IsNop(GateRef g) const; 557 bool IsRoot(GateRef g) const; 558 bool HasOuts(GateRef gate) const; 559 void DeleteGateIfNoUse(GateRef gate); 560 GateRef GetDependSelectorFromMerge(GateRef gate); 561 bool HasIfExceptionUse(GateRef gate) const; 562 bool IsIn(GateRef g, GateRef in) const; 563 bool IsHeapObjectFromElementsKind(GateRef gate); 564 bool IsConstString(GateRef gate); 565 bool IsSingleCharGate(GateRef gate); 566 bool UseForTypeOpProfilerGate(GateRef gate) const; 567 uint32_t GetStringIdFromLdaStrGate(GateRef gate); 568 bool IsIfOrSwitchRelated(GateRef gate) const; 569 uint32_t GetConstpoolId(GateRef gate) const; 570 GateRef GetFrameValue(GateRef gate); 571 GetCircuitRoot()572 GateRef GetCircuitRoot() const 573 { 574 return GetRoot(OpCode::CIRCUIT_ROOT); 575 } 576 GetStateRoot()577 GateRef GetStateRoot() const 578 { 579 return GetRoot(OpCode::STATE_ENTRY); 580 } 581 GetDependRoot()582 GateRef GetDependRoot() const 583 { 584 return GetRoot(OpCode::DEPEND_ENTRY); 585 } 586 GetArgRoot()587 GateRef GetArgRoot() const 588 { 589 return GetRoot(OpCode::ARG_LIST); 590 } 591 GetReturnRoot()592 GateRef GetReturnRoot() const 593 { 594 return GetRoot(OpCode::RETURN_LIST); 595 } 596 IsStateRoot(GateRef gate)597 inline bool IsStateRoot(GateRef gate) const 598 { 599 return gate == GetStateRoot(); 600 } 601 602 size_t GetFrameDepth(GateRef gate, OpCode op); 603 GateRef GetFrameState(GateRef gate) const; 604 void ReplaceFrameStateIn(GateRef gate, GateRef in); 605 bool HasFrameState(GateRef gate) const; 606 GateRef FindNearestFrameState(GateRef gate) const; 607 GateRef FindNearestStateSplit(GateRef gate) const; 608 void SetMetaData(GateRef gate, const GateMetaData* meta); 609 610 void ReplaceHirWithIfBranch(GateRef hirGate, StateDepend success, StateDepend exception, GateRef value); 611 void ReplaceHirDirectly(GateRef hirGate, StateDepend replacement, GateRef value); 612 void ReplaceHirAndDeleteIfException(GateRef hirGate, StateDepend replacement, GateRef value); 613 614 bool IsLoopBackUse(GateRef gate, const UseIterator &useIt) const; 615 void GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const; 616 bool IsCreateArray(GateRef gate) const; 617 void SetStoreNoBarrier(GateRef gate, bool isNoBarrier); 618 bool IsNoBarrier(GateRef gate) const; 619 void GetIns(GateRef gate, std::vector<GateRef>& ins) const; 620 621 TypedBinOp GetRevCompareOpForTypedBinOp(TypedBinOp op); 622 TypedBinOp GetSwapCompareOpForTypedBinOp(TypedBinOp op); 623 624 private: 625 const GateMetaData *GetMetaData(GateRef gate) const; 626 UseIterator ReplaceHirIfSuccess(const UseIterator &useIt, GateRef state); 627 UseIterator ReplaceHirIfException(const UseIterator &useIt, StateDepend replacement); 628 void ExceptionReturn(GateRef state, GateRef depend); 629 630 GateRef GetRoot(OpCode opcode) const; ConstUseBegin(GateRef gate)631 ConstUseIterator ConstUseBegin(GateRef gate) const 632 { 633 if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) { 634 return ConstUseIterator(circuit_, nullptr); 635 } 636 auto use = circuit_->LoadGatePtrConst(gate)->GetFirstOutConst(); 637 return ConstUseIterator(circuit_, use); 638 } 639 ConstUseEnd()640 ConstUseIterator ConstUseEnd() const 641 { 642 return ConstUseIterator(circuit_, nullptr); 643 } 644 UseBegin(GateRef gate)645 UseIterator UseBegin(GateRef gate) const 646 { 647 if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) { 648 return UseIterator(circuit_, nullptr); 649 } 650 auto use = circuit_->LoadGatePtr(gate)->GetFirstOut(); 651 return UseIterator(circuit_, use); 652 } 653 UseEnd()654 UseIterator UseEnd() const 655 { 656 return UseIterator(circuit_, nullptr); 657 } 658 ConstInBegin(GateRef gate)659 ConstInsIterator ConstInBegin(GateRef gate) const 660 { 661 return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]); 662 } 663 ConstInEnd(GateRef gate)664 ConstInsIterator ConstInEnd(GateRef gate) const 665 { 666 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 667 return ConstInsIterator(circuit_, 668 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]); 669 } 670 InBegin(GateRef gate)671 InsIterator InBegin(GateRef gate) 672 { 673 return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[0]); 674 } 675 InEnd(GateRef gate)676 InsIterator InEnd(GateRef gate) 677 { 678 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 679 return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[endIndex]); 680 } 681 682 void GetOuts(GateRef gate, std::vector<GateRef>& outs) const; 683 684 void GetInStates(GateRef gate, std::vector<GateRef>& ins) const; 685 686 Circuit *circuit_; 687 688 friend class Circuit; 689 friend class CircuitBuilder; 690 friend class LLVMIRBuilder; 691 friend class LiteCGIRBuilder; 692 friend class Scheduler; 693 friend class LoopPeeling; 694 }; 695 696 class ConstGateAccessor { 697 public: 698 struct ConstInsIterator { ConstInsIteratorConstInsIterator699 ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in) 700 { 701 } 702 703 GateRef operator*() const 704 { 705 return circuit_->GetGateRef(in_->GetGateConst()); 706 } 707 708 const ConstInsIterator& operator++() 709 { 710 in_++; 711 return *this; 712 } 713 ConstInsIterator operator++(int) 714 { 715 ConstInsIterator tmp = *this; 716 ++(*this); 717 return tmp; 718 } 719 GetOpCodeConstInsIterator720 OpCode GetOpCode() const 721 { 722 ASSERT(in_ != nullptr); 723 return in_->GetGateConst()->GetOpCode(); 724 } 725 726 friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b) 727 { 728 return a.in_ == b.in_; 729 }; 730 friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b) 731 { 732 return a.in_ != b.in_; 733 }; 734 735 private: 736 const Circuit* circuit_; 737 const In* in_; 738 }; 739 740 struct ConstInWrapper { 741 const Circuit* circuit; 742 const GateRef gate; beginConstInWrapper743 auto begin() 744 { 745 return ConstGateAccessor(circuit).ConstInBegin(gate); 746 } endConstInWrapper747 auto end() 748 { 749 return ConstGateAccessor(circuit).ConstInEnd(gate); 750 } 751 }; 752 Ins(GateRef gate)753 ConstInWrapper Ins(GateRef gate) const 754 { 755 return { circuit_, gate }; 756 } 757 ConstGateAccessor(const Circuit * circuit)758 explicit ConstGateAccessor(const Circuit *circuit) : circuit_(circuit) 759 { 760 } 761 762 ~ConstGateAccessor() = default; 763 764 bool IsFixed(GateRef g) const; 765 bool IsProlog(GateRef g) const; 766 bool IsSchedulable(GateRef g) const; 767 768 private: ConstInBegin(GateRef gate)769 ConstInsIterator ConstInBegin(GateRef gate) const 770 { 771 return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]); 772 } 773 ConstInEnd(GateRef gate)774 ConstInsIterator ConstInEnd(GateRef gate) const 775 { 776 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 777 return ConstInsIterator(circuit_, 778 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]); 779 } 780 const GateMetaData *GetMetaData(GateRef g) const; 781 782 const Circuit *circuit_; 783 friend struct ConstInWrapper; 784 }; 785 } 786 #endif // ECMASCRIPT_COMPILER_GATE_ACCESSOR_H 787