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