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 21 namespace panda::ecmascript::kungfu { 22 class GateAccessor { 23 public: 24 // do not create new gate or modify self during iteration 25 struct ConstUseIterator { ConstUseIteratorConstUseIterator26 explicit ConstUseIterator(const Circuit* circuit, const Out* out) : circuit_(circuit), out_(out) 27 { 28 } 29 30 GateRef operator*() const 31 { 32 if (out_ != nullptr) { 33 return circuit_->GetGateRef(out_->GetGateConst()); 34 } 35 return 0; 36 } 37 38 const ConstUseIterator operator++() 39 { 40 ASSERT(out_ != nullptr); 41 if (!out_->IsNextOutNull()) { 42 out_ = out_->GetNextOutConst(); 43 return *this; 44 } 45 out_ = nullptr; 46 return *this; 47 } 48 const ConstUseIterator operator++(int) 49 { 50 ConstUseIterator tmp = *this; 51 ++(*this); 52 return tmp; 53 } 54 GetIndexConstUseIterator55 size_t GetIndex() const 56 { 57 ASSERT(out_ != nullptr); 58 return out_->GetIndex(); 59 } 60 GetOpCodeConstUseIterator61 OpCode GetOpCode() const 62 { 63 ASSERT(out_ != nullptr); 64 return out_->GetGateConst()->GetOpCode(); 65 } 66 67 friend bool operator== (const ConstUseIterator& a, const ConstUseIterator& b) 68 { 69 return a.out_ == b.out_; 70 }; 71 friend bool operator!= (const ConstUseIterator& a, const ConstUseIterator& b) 72 { 73 return a.out_ != b.out_; 74 }; 75 76 private: 77 const Circuit* circuit_; 78 const Out* out_; 79 }; 80 81 // do not create new gate or modify self during iteration 82 struct UseIterator { UseIteratorUseIterator83 explicit UseIterator(Circuit* circuit, Out* out) : circuit_(circuit), out_(out) 84 { 85 } 86 87 GateRef operator*() const 88 { 89 if (out_ != nullptr) { 90 return circuit_->GetGateRef(out_->GetGate()); 91 } 92 return 0; 93 } 94 95 const UseIterator& operator++() 96 { 97 ASSERT(out_ != nullptr); 98 out_ = out_->IsNextOutNull() ? nullptr 99 : out_->GetNextOut(); 100 return *this; 101 } 102 103 UseIterator operator++(int) 104 { 105 UseIterator tmp = *this; 106 ++(*this); 107 return tmp; 108 } 109 GetIndexUseIterator110 size_t GetIndex() const 111 { 112 ASSERT(out_ != nullptr); 113 return out_->GetIndex(); 114 } 115 GetOpCodeUseIterator116 OpCode GetOpCode() const 117 { 118 ASSERT(out_ != nullptr); 119 return out_->GetGateConst()->GetOpCode(); 120 } 121 122 friend bool operator== (const UseIterator& a, const UseIterator& b) 123 { 124 return a.out_ == b.out_; 125 }; 126 friend bool operator!= (const UseIterator& a, const UseIterator& b) 127 { 128 return a.out_ != b.out_; 129 }; 130 131 private: 132 Circuit* circuit_; 133 Out* out_; 134 }; 135 136 struct ConstInsIterator { ConstInsIteratorConstInsIterator137 explicit ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in) 138 { 139 } 140 141 GateRef operator*() const 142 { 143 return circuit_->GetGateRef(in_->GetGateConst()); 144 } 145 146 const ConstInsIterator& operator++() 147 { 148 in_++; 149 return *this; 150 } 151 ConstInsIterator operator++(int) 152 { 153 ConstInsIterator tmp = *this; 154 ++(*this); 155 return tmp; 156 } 157 GetOpCodeConstInsIterator158 OpCode GetOpCode() const 159 { 160 ASSERT(in_ != nullptr); 161 return in_->GetGateConst()->GetOpCode(); 162 } 163 164 friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b) 165 { 166 return a.in_ == b.in_; 167 }; 168 friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b) 169 { 170 return a.in_ != b.in_; 171 }; 172 173 private: 174 const Circuit* circuit_; 175 const In* in_; 176 }; 177 178 struct InsIterator { InsIteratorInsIterator179 explicit InsIterator(const Circuit* circuit, In* in) : circuit_(circuit), in_(in) 180 { 181 } 182 183 GateRef operator*() 184 { 185 return circuit_->GetGateRef(in_->GetGate()); 186 } 187 188 const InsIterator& operator++() 189 { 190 in_++; 191 return *this; 192 } 193 InsIterator operator++(int) 194 { 195 InsIterator tmp = *this; 196 ++(*this); 197 return tmp; 198 } 199 GetOpCodeInsIterator200 OpCode GetOpCode() const 201 { 202 ASSERT(in_ != nullptr); 203 return in_->GetGateConst()->GetOpCode(); 204 } 205 206 friend bool operator== (const InsIterator& a, const InsIterator& b) 207 { 208 return a.in_ == b.in_; 209 }; 210 friend bool operator!= (const InsIterator& a, const InsIterator& b) 211 { 212 return a.in_ != b.in_; 213 }; 214 215 private: 216 const Circuit* circuit_; 217 In* in_; 218 }; 219 220 struct ConstUseWrapper { 221 Circuit* circuit; 222 GateRef gate; beginConstUseWrapper223 auto begin() 224 { 225 return GateAccessor(circuit).ConstUseBegin(gate); 226 } endConstUseWrapper227 auto end() 228 { 229 return GateAccessor(circuit).ConstUseEnd(); 230 } 231 }; 232 233 struct UseWrapper { 234 Circuit* circuit; 235 GateRef gate; beginUseWrapper236 auto begin() 237 { 238 return GateAccessor(circuit).UseBegin(gate); 239 } endUseWrapper240 auto end() 241 { 242 return GateAccessor(circuit).UseEnd(); 243 } 244 }; 245 246 struct ConstInWrapper { 247 Circuit* circuit; 248 const GateRef gate; beginConstInWrapper249 auto begin() 250 { 251 return GateAccessor(circuit).ConstInBegin(gate); 252 } endConstInWrapper253 auto end() 254 { 255 return GateAccessor(circuit).ConstInEnd(gate); 256 } 257 }; 258 259 struct InWrapper { 260 Circuit* circuit; 261 GateRef gate; beginInWrapper262 auto begin() 263 { 264 return GateAccessor(circuit).InBegin(gate); 265 } endInWrapper266 auto end() 267 { 268 return GateAccessor(circuit).InEnd(gate); 269 } 270 }; 271 ConstIns(GateRef gate)272 ConstInWrapper ConstIns(GateRef gate) const 273 { 274 return { circuit_, gate }; 275 } 276 Ins(GateRef gate)277 InWrapper Ins(GateRef gate) const 278 { 279 return { circuit_, gate }; 280 } 281 ConstUses(GateRef gate)282 ConstUseWrapper ConstUses(GateRef gate) const 283 { 284 return { circuit_, gate }; 285 } 286 Uses(GateRef gate)287 UseWrapper Uses(GateRef gate) 288 { 289 return { circuit_, gate }; 290 } 291 GateAccessor(Circuit * circuit)292 explicit GateAccessor(Circuit *circuit) : circuit_(circuit) 293 { 294 } 295 GetCircuit()296 Circuit *GetCircuit() const 297 { 298 return circuit_; 299 } 300 301 ~GateAccessor() = default; 302 void GetAllGates(std::vector<GateRef>& gates) const; 303 size_t GetNumIns(GateRef gate) const; 304 OpCode GetOpCode(GateRef gate) const; 305 bool IsGCRelated(GateRef gate) const; 306 uint64_t TryGetValue(GateRef gate) const; 307 ICmpCondition GetICmpCondition(GateRef gate) const; 308 FCmpCondition GetFCmpCondition(GateRef gate) const; 309 ConstDataId GetConstDataId(GateRef gate) const; 310 size_t GetVirtualRegisterIndex(GateRef gate) const; 311 TypedLoadOp GetTypedLoadOp(GateRef gate) const; 312 TypedStoreOp GetTypedStoreOp(GateRef gate) const; 313 TypedBinOp GetTypedBinaryOp(GateRef gate) const; 314 GateType GetParamGateType(GateRef gate) const; 315 TypedUnaryAccessor GetTypedUnOp(GateRef gate) const; 316 uint64_t GetConstantValue(GateRef gate) const; 317 uint32_t GetBytecodeIndex(GateRef gate) const; 318 EcmaOpcode GetByteCodeOpcode(GateRef gate) const; 319 void Print(GateRef gate) const; 320 void ShortPrint(GateRef gate) const; 321 GateId GetId(GateRef gate) const; 322 GateRef GetValueIn(GateRef gate, size_t idx = 0) const; 323 size_t GetNumValueIn(GateRef gate) const; 324 GateRef GetIn(GateRef gate, size_t idx) const; 325 GateRef GetState(GateRef gate, size_t idx = 0) const; 326 GateRef GetDep(GateRef gate, size_t idx = 0) const; 327 size_t GetImmediateId(GateRef gate) const; 328 void SetDep(GateRef gate, GateRef depGate, size_t idx = 0); 329 UseIterator ReplaceIn(const UseIterator &useIt, GateRef replaceGate); 330 // Add for lowering 331 GateType GetGateType(GateRef gate) const; 332 void SetGateType(GateRef gate, GateType gt); 333 UseIterator DeleteExceptionDep(const UseIterator &useIt); 334 void DeleteIn(GateRef gate, size_t idx); 335 UseIterator DeleteGate(const UseIterator &useIt); 336 void DecreaseIn(const UseIterator &useIt); 337 void DecreaseIn(GateRef gate, size_t index); 338 void NewIn(GateRef gate, size_t idx, GateRef in); 339 size_t GetStateCount(GateRef gate) const; 340 size_t GetDependCount(GateRef gate) const; 341 size_t GetInValueCount(GateRef gate) const; 342 size_t GetInValueStarts(GateRef gate) const; 343 void UpdateAllUses(GateRef gate, GateRef replaceValueIn); 344 void ReplaceIn(GateRef gate, size_t index, GateRef in); 345 void ReplaceStateIn(GateRef gate, GateRef in, size_t index = 0); 346 void ReplaceDependIn(GateRef gate, GateRef in, size_t index = 0); 347 void ReplaceValueIn(GateRef gate, GateRef in, size_t index = 0); 348 void DeleteGate(GateRef gate); 349 MachineType GetMachineType(GateRef gate) const; 350 void SetMachineType(GateRef gate, MachineType type); 351 GateRef GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const; 352 bool IsInGateNull(GateRef gate, size_t idx) const; 353 bool IsSelector(GateRef g) const; 354 bool IsControlCase(GateRef gate) const; 355 bool IsLoopHead(GateRef gate) const; 356 bool IsLoopBack(GateRef gate) const; 357 bool IsState(GateRef gate) const; 358 bool IsConstant(GateRef gate) const; 359 bool IsDependSelector(GateRef gate) const; 360 bool IsConstantValue(GateRef gate, uint64_t value) const; 361 bool IsTypedOperator(GateRef gate) const; 362 bool IsNotWrite(GateRef gate) const; 363 bool IsDead(GateRef gate) const; 364 bool IsCheckWithOneIn(GateRef gate) const; 365 bool IsCheckWithTwoIns(GateRef gate) const; 366 bool IsSchedulable(GateRef gate) const; 367 MarkCode GetMark(GateRef gate) const; 368 void SetMark(GateRef gate, MarkCode mark); 369 bool IsFinished(GateRef gate) const; 370 bool IsVisited(GateRef gate) const; 371 bool IsNotMarked(GateRef gate) const; 372 void SetFinished(GateRef gate); 373 void SetVisited(GateRef gate); 374 bool IsStateIn(const UseIterator &useIt) const; 375 bool IsDependIn(const UseIterator &useIt) const; 376 bool IsValueIn(const UseIterator &useIt) const; 377 bool IsFrameStateIn(const UseIterator &useIt) const; 378 bool IsExceptionState(const UseIterator &useIt) const; 379 bool IsDependIn(GateRef gate, size_t index) const; 380 bool IsValueIn(GateRef gate, size_t index) const; 381 void GetStateUses(GateRef gate, std::vector<GateRef>& stateUses); 382 void GetDependUses(GateRef gate, std::vector<GateRef>& dependUses); 383 bool IsFrameStateIn(GateRef gate, size_t index) const; 384 void DeleteStateSplitAndFrameState(GateRef gate); 385 void ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value); 386 GateType GetLeftType(GateRef gate) const; 387 GateType GetRightType(GateRef gate) const; 388 GateRef GetGlueFromArgList() const; 389 void GetArgsOuts(std::vector<GateRef>& outs) const; 390 void GetReturnOuts(std::vector<GateRef>& outs) const; 391 GetStateRoot()392 GateRef GetStateRoot() const 393 { 394 return GetRoot(OpCode::STATE_ENTRY); 395 } 396 GetDependRoot()397 GateRef GetDependRoot() const 398 { 399 return GetRoot(OpCode::DEPEND_ENTRY); 400 } 401 GetArgRoot()402 GateRef GetArgRoot() const 403 { 404 return GetRoot(OpCode::ARG_LIST); 405 } 406 GetReturnRoot()407 GateRef GetReturnRoot() const 408 { 409 return GetRoot(OpCode::RETURN_LIST); 410 } 411 412 GateRef GetFrameState(GateRef gate) const; 413 void ReplaceFrameStateIn(GateRef gate, GateRef in); 414 bool HasFrameState(GateRef gate) const; 415 const GateMetaData *GetMetaData(GateRef gate) const; 416 void SetMetaData(GateRef gate, const GateMetaData* meta); 417 418 private: 419 GateRef GetRoot(OpCode opcode) const; ConstUseBegin(GateRef gate)420 ConstUseIterator ConstUseBegin(GateRef gate) const 421 { 422 if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) { 423 return ConstUseIterator(circuit_, nullptr); 424 } 425 auto use = circuit_->LoadGatePtrConst(gate)->GetFirstOutConst(); 426 return ConstUseIterator(circuit_, use); 427 } 428 ConstUseEnd()429 ConstUseIterator ConstUseEnd() const 430 { 431 return ConstUseIterator(circuit_, nullptr); 432 } 433 UseBegin(GateRef gate)434 UseIterator UseBegin(GateRef gate) const 435 { 436 if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) { 437 return UseIterator(circuit_, nullptr); 438 } 439 auto use = circuit_->LoadGatePtr(gate)->GetFirstOut(); 440 return UseIterator(circuit_, use); 441 } 442 UseEnd()443 UseIterator UseEnd() const 444 { 445 return UseIterator(circuit_, nullptr); 446 } 447 ConstInBegin(GateRef gate)448 ConstInsIterator ConstInBegin(GateRef gate) const 449 { 450 return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]); 451 } 452 ConstInEnd(GateRef gate)453 ConstInsIterator ConstInEnd(GateRef gate) const 454 { 455 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 456 return ConstInsIterator(circuit_, 457 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]); 458 } 459 InBegin(GateRef gate)460 InsIterator InBegin(GateRef gate) 461 { 462 return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[0]); 463 } 464 InEnd(GateRef gate)465 InsIterator InEnd(GateRef gate) 466 { 467 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 468 return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[endIndex]); 469 } 470 471 void GetIns(GateRef gate, std::vector<GateRef>& ins) const; 472 473 void GetOuts(GateRef gate, std::vector<GateRef>& outs) const; 474 475 void GetInStates(GateRef gate, std::vector<GateRef>& ins) const; 476 477 void GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const; 478 479 Circuit *circuit_; 480 481 friend class Circuit; 482 friend class LLVMIRBuilder; 483 friend class Scheduler; 484 friend class EarlyElimination; 485 friend class ArgumentAccessor; 486 friend class BytecodeCircuitBuilder; 487 }; 488 489 class ConstGateAccessor { 490 public: 491 struct ConstInsIterator { ConstInsIteratorConstInsIterator492 explicit ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in) 493 { 494 } 495 496 GateRef operator*() const 497 { 498 return circuit_->GetGateRef(in_->GetGateConst()); 499 } 500 501 const ConstInsIterator& operator++() 502 { 503 in_++; 504 return *this; 505 } 506 ConstInsIterator operator++(int) 507 { 508 ConstInsIterator tmp = *this; 509 ++(*this); 510 return tmp; 511 } 512 GetOpCodeConstInsIterator513 OpCode GetOpCode() const 514 { 515 ASSERT(in_ != nullptr); 516 return in_->GetGateConst()->GetOpCode(); 517 } 518 519 friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b) 520 { 521 return a.in_ == b.in_; 522 }; 523 friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b) 524 { 525 return a.in_ != b.in_; 526 }; 527 528 private: 529 const Circuit* circuit_; 530 const In* in_; 531 }; 532 533 struct ConstInWrapper { 534 const Circuit* circuit; 535 const GateRef gate; beginConstInWrapper536 auto begin() 537 { 538 return ConstGateAccessor(circuit).ConstInBegin(gate); 539 } endConstInWrapper540 auto end() 541 { 542 return ConstGateAccessor(circuit).ConstInEnd(gate); 543 } 544 }; 545 Ins(GateRef gate)546 ConstInWrapper Ins(GateRef gate) const 547 { 548 return { circuit_, gate }; 549 } 550 ConstGateAccessor(const Circuit * circuit)551 explicit ConstGateAccessor(const Circuit *circuit) : circuit_(circuit) 552 { 553 } 554 555 ~ConstGateAccessor() = default; 556 557 private: ConstInBegin(GateRef gate)558 ConstInsIterator ConstInBegin(GateRef gate) const 559 { 560 return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]); 561 } 562 ConstInEnd(GateRef gate)563 ConstInsIterator ConstInEnd(GateRef gate) const 564 { 565 auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns(); 566 return ConstInsIterator(circuit_, 567 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]); 568 } 569 570 const Circuit *circuit_; 571 friend struct ConstInWrapper; 572 }; 573 } 574 #endif // ECMASCRIPT_COMPILER_GATE_ACCESSOR_H 575