1 /* 2 * Copyright (c) 2023 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 MAPLEBE_INCLUDE_CG_DEPS_H 17 #define MAPLEBE_INCLUDE_CG_DEPS_H 18 19 #include "mad.h" 20 #include "pressure.h" 21 #include <array> 22 namespace maplebe { 23 #define PRINT_STR_VAL(STR, VAL) LogInfo::MapleLogger() << std::left << std::setw(12) << STR << VAL << " | "; 24 #define PRINT_VAL(VAL) LogInfo::MapleLogger() << std::left << std::setw(12) << VAL << " | "; 25 26 enum DepType : uint8 { 27 kDependenceTypeTrue, 28 kDependenceTypeOutput, 29 kDependenceTypeAnti, 30 kDependenceTypeControl, 31 kDependenceTypeMembar, 32 kDependenceTypeThrow, 33 kDependenceTypeSeparator, 34 kDependenceTypeNone 35 }; 36 37 inline const std::array<std::string, kDependenceTypeNone + 1> kDepTypeName = { 38 "true-dep", "output-dep", "anti-dep", "control-dep", "membar-dep", "throw-dep", "separator-dep", "none-dep", 39 }; 40 41 enum NodeType : uint8 { kNodeTypeNormal, kNodeTypeSeparator, kNodeTypeEmpty }; 42 43 enum ScheduleState : uint8 { 44 kNormal, 45 kReady, 46 kScheduled, 47 }; 48 49 class DepNode; 50 51 class DepLink { 52 public: DepLink(DepNode & fromNode,DepNode & toNode,DepType typ)53 DepLink(DepNode &fromNode, DepNode &toNode, DepType typ) : from(fromNode), to(toNode), depType(typ), latency(0) {} 54 virtual ~DepLink() = default; 55 GetFrom()56 DepNode &GetFrom() const 57 { 58 return from; 59 } GetTo()60 DepNode &GetTo() const 61 { 62 return to; 63 } SetDepType(DepType dType)64 void SetDepType(DepType dType) 65 { 66 depType = dType; 67 } GetDepType()68 DepType GetDepType() const 69 { 70 return depType; 71 } SetLatency(uint32 lat)72 void SetLatency(uint32 lat) 73 { 74 latency = lat; 75 } GetLatency()76 uint32 GetLatency() const 77 { 78 return latency; 79 } 80 81 private: 82 DepNode &from; 83 DepNode &to; 84 DepType depType; 85 uint32 latency; 86 }; 87 88 class DepNode { 89 public: 90 bool CanBeScheduled() const; 91 void OccupyUnits(); 92 uint32 GetUnitKind() const; 93 DepNode(Insn & insn,MapleAllocator & alloc)94 DepNode(Insn &insn, MapleAllocator &alloc) 95 : insn(&insn), 96 units(nullptr), 97 reservation(nullptr), 98 unitNum(0), 99 eStart(0), 100 lStart(0), 101 visit(0), 102 type(kNodeTypeNormal), 103 state(kNormal), 104 index(0), 105 simulateCycle(0), 106 schedCycle(0), 107 bruteForceSchedCycle(0), 108 validPredsSize(0), 109 validSuccsSize(0), 110 preds(alloc.Adapter()), 111 succs(alloc.Adapter()), 112 comments(alloc.Adapter()), 113 cfiInsns(alloc.Adapter()), 114 clinitInsns(alloc.Adapter()), 115 locInsn(nullptr), 116 useRegnos(alloc.Adapter()), 117 defRegnos(alloc.Adapter()), 118 regPressure(nullptr) 119 { 120 } 121 DepNode(Insn & insn,MapleAllocator & alloc,Unit * const * unit,uint32 num,Reservation & rev)122 DepNode(Insn &insn, MapleAllocator &alloc, Unit *const *unit, uint32 num, Reservation &rev) 123 : insn(&insn), 124 units(unit), 125 reservation(&rev), 126 unitNum(num), 127 eStart(0), 128 lStart(0), 129 visit(0), 130 type(kNodeTypeNormal), 131 state(kNormal), 132 index(0), 133 simulateCycle(0), 134 schedCycle(0), 135 bruteForceSchedCycle(0), 136 validPredsSize(0), 137 validSuccsSize(0), 138 preds(alloc.Adapter()), 139 succs(alloc.Adapter()), 140 comments(alloc.Adapter()), 141 cfiInsns(alloc.Adapter()), 142 clinitInsns(alloc.Adapter()), 143 locInsn(nullptr), 144 useRegnos(alloc.Adapter()), 145 defRegnos(alloc.Adapter()), 146 regPressure(nullptr) 147 { 148 } 149 150 virtual ~DepNode() = default; 151 GetInsn()152 Insn *GetInsn() const 153 { 154 return insn; 155 } SetInsn(Insn & rvInsn)156 void SetInsn(Insn &rvInsn) 157 { 158 insn = &rvInsn; 159 } SetUnits(Unit * const * unit)160 void SetUnits(Unit *const *unit) 161 { 162 units = unit; 163 } GetUnitByIndex(uint32 idx)164 const Unit *GetUnitByIndex(uint32 idx) const 165 { 166 DEBUG_ASSERT(index < unitNum, "out of units"); 167 return units[idx]; 168 } GetReservation()169 Reservation *GetReservation() const 170 { 171 return reservation; 172 } SetReservation(Reservation & rev)173 void SetReservation(Reservation &rev) 174 { 175 reservation = &rev; 176 } GetUnitNum()177 uint32 GetUnitNum() const 178 { 179 return unitNum; 180 } SetUnitNum(uint32 num)181 void SetUnitNum(uint32 num) 182 { 183 unitNum = num; 184 } GetEStart()185 uint32 GetEStart() const 186 { 187 return eStart; 188 } SetEStart(uint32 start)189 void SetEStart(uint32 start) 190 { 191 eStart = start; 192 } GetLStart()193 uint32 GetLStart() const 194 { 195 return lStart; 196 } SetLStart(uint32 start)197 void SetLStart(uint32 start) 198 { 199 lStart = start; 200 } GetVisit()201 uint32 GetVisit() const 202 { 203 return visit; 204 } SetVisit(uint32 visitVal)205 void SetVisit(uint32 visitVal) 206 { 207 visit = visitVal; 208 } IncreaseVisit()209 void IncreaseVisit() 210 { 211 ++visit; 212 } GetType()213 NodeType GetType() const 214 { 215 return type; 216 } SetType(NodeType nodeType)217 void SetType(NodeType nodeType) 218 { 219 type = nodeType; 220 } GetState()221 ScheduleState GetState() const 222 { 223 return state; 224 } SetState(ScheduleState scheduleState)225 void SetState(ScheduleState scheduleState) 226 { 227 state = scheduleState; 228 } GetIndex()229 uint32 GetIndex() const 230 { 231 return index; 232 } SetIndex(uint32 idx)233 void SetIndex(uint32 idx) 234 { 235 index = idx; 236 } SetSchedCycle(uint32 cycle)237 void SetSchedCycle(uint32 cycle) 238 { 239 schedCycle = cycle; 240 } GetSchedCycle()241 uint32 GetSchedCycle() const 242 { 243 return schedCycle; 244 } SetSimulateCycle(uint32 cycle)245 void SetSimulateCycle(uint32 cycle) 246 { 247 simulateCycle = cycle; 248 } GetSimulateCycle()249 uint32 GetSimulateCycle() const 250 { 251 return simulateCycle; 252 } SetBruteForceSchedCycle(uint32 cycle)253 void SetBruteForceSchedCycle(uint32 cycle) 254 { 255 bruteForceSchedCycle = cycle; 256 } GetBruteForceSchedCycle()257 uint32 GetBruteForceSchedCycle() const 258 { 259 return bruteForceSchedCycle; 260 } SetValidPredsSize(uint32 validSize)261 void SetValidPredsSize(uint32 validSize) 262 { 263 validPredsSize = validSize; 264 } GetValidPredsSize()265 uint32 GetValidPredsSize() const 266 { 267 return validPredsSize; 268 } DescreaseValidPredsSize()269 void DescreaseValidPredsSize() 270 { 271 --validPredsSize; 272 } IncreaseValidPredsSize()273 void IncreaseValidPredsSize() 274 { 275 ++validPredsSize; 276 } GetValidSuccsSize()277 uint32 GetValidSuccsSize() const 278 { 279 return validSuccsSize; 280 } SetValidSuccsSize(uint32 size)281 void SetValidSuccsSize(uint32 size) 282 { 283 validSuccsSize = size; 284 } GetPreds()285 const MapleVector<DepLink *> &GetPreds() const 286 { 287 return preds; 288 } ReservePreds(size_t size)289 void ReservePreds(size_t size) 290 { 291 preds.reserve(size); 292 } AddPred(DepLink & depLink)293 void AddPred(DepLink &depLink) 294 { 295 preds.emplace_back(&depLink); 296 } RemovePred()297 void RemovePred() 298 { 299 preds.pop_back(); 300 } GetSuccs()301 const MapleVector<DepLink *> &GetSuccs() const 302 { 303 return succs; 304 } ReserveSuccs(size_t size)305 void ReserveSuccs(size_t size) 306 { 307 succs.reserve(size); 308 } AddSucc(DepLink & depLink)309 void AddSucc(DepLink &depLink) 310 { 311 succs.emplace_back(&depLink); 312 } RemoveSucc()313 void RemoveSucc() 314 { 315 succs.pop_back(); 316 } GetComments()317 const MapleVector<Insn *> &GetComments() const 318 { 319 return comments; 320 } SetComments(MapleVector<Insn * > com)321 void SetComments(MapleVector<Insn *> com) 322 { 323 comments = com; 324 } AddComments(Insn & insn)325 void AddComments(Insn &insn) 326 { 327 comments.emplace_back(&insn); 328 } ClearComments()329 void ClearComments() 330 { 331 comments.clear(); 332 } GetCfiInsns()333 const MapleVector<Insn *> &GetCfiInsns() const 334 { 335 return cfiInsns; 336 } SetCfiInsns(MapleVector<Insn * > insns)337 void SetCfiInsns(MapleVector<Insn *> insns) 338 { 339 cfiInsns = insns; 340 } AddCfiInsn(Insn & insn)341 void AddCfiInsn(Insn &insn) 342 { 343 cfiInsns.emplace_back(&insn); 344 } ClearCfiInsns()345 void ClearCfiInsns() 346 { 347 cfiInsns.clear(); 348 } GetClinitInsns()349 const MapleVector<Insn *> &GetClinitInsns() const 350 { 351 return clinitInsns; 352 } SetClinitInsns(MapleVector<Insn * > insns)353 void SetClinitInsns(MapleVector<Insn *> insns) 354 { 355 clinitInsns = insns; 356 } AddClinitInsn(Insn & insn)357 void AddClinitInsn(Insn &insn) 358 { 359 clinitInsns.emplace_back(&insn); 360 } GetRegPressure()361 const RegPressure *GetRegPressure() const 362 { 363 return regPressure; 364 } SetRegPressure(RegPressure & pressure)365 void SetRegPressure(RegPressure &pressure) 366 { 367 regPressure = &pressure; 368 } DumpRegPressure()369 void DumpRegPressure() const 370 { 371 if (regPressure) { 372 regPressure->DumpRegPressure(); 373 } 374 } InitPressure()375 void InitPressure() const 376 { 377 regPressure->InitPressure(); 378 } GetPressure()379 const MapleVector<int32> &GetPressure() const 380 { 381 return regPressure->GetPressure(); 382 } 383 IncPressureByIndex(int32 idx)384 void IncPressureByIndex(int32 idx) const 385 { 386 regPressure->IncPressureByIndex(static_cast<uint32>(idx)); 387 } DecPressureByIndex(int32 idx)388 void DecPressureByIndex(int32 idx) const 389 { 390 regPressure->DecPressureByIndex(static_cast<uint32>(idx)); 391 } 392 GetDeadDefNum()393 const MapleVector<int32> &GetDeadDefNum() const 394 { 395 return regPressure->GetDeadDefNum(); 396 } IncDeadDefByIndex(int32 idx)397 void IncDeadDefByIndex(int32 idx) const 398 { 399 regPressure->IncDeadDefByIndex(static_cast<uint32>(idx)); 400 } 401 SetRegUses(RegList & regList)402 void SetRegUses(RegList ®List) const 403 { 404 regPressure->SetRegUses(®List); 405 } SetRegDefs(size_t idx,RegList * regList)406 void SetRegDefs(size_t idx, RegList *regList) const 407 { 408 regPressure->SetRegDefs(idx, regList); 409 } 410 GetIncPressure()411 int32 GetIncPressure() const 412 { 413 return regPressure->GetIncPressure(); 414 } SetIncPressure(bool value)415 void SetIncPressure(bool value) const 416 { 417 regPressure->SetIncPressure(value); 418 } GetMaxDepth()419 int32 GetMaxDepth() const 420 { 421 return regPressure->GetMaxDepth(); 422 } SetMaxDepth(int32 value)423 void SetMaxDepth(int32 value) const 424 { 425 regPressure->SetMaxDepth(value); 426 } GetNear()427 int32 GetNear() const 428 { 429 return regPressure->GetNear(); 430 } SetNear(int32 value)431 void SetNear(int32 value) const 432 { 433 regPressure->SetNear(value); 434 } GetPriority()435 int32 GetPriority() const 436 { 437 return regPressure->GetPriority(); 438 } SetPriority(int32 value)439 void SetPriority(int32 value) const 440 { 441 regPressure->SetPriority(value); 442 } GetRegUses(size_t idx)443 RegList *GetRegUses(size_t idx) const 444 { 445 return regPressure->GetRegUses(idx); 446 } InitRegUsesSize(size_t size)447 void InitRegUsesSize(size_t size) const 448 { 449 regPressure->InitRegUsesSize(size); 450 } GetRegDefs(size_t idx)451 RegList *GetRegDefs(size_t idx) const 452 { 453 return regPressure->GetRegDefs(idx); 454 } InitRegDefsSize(size_t size)455 void InitRegDefsSize(size_t size) const 456 { 457 regPressure->InitRegDefsSize(size); 458 } 459 SetNumCall(int32 value)460 void SetNumCall(int32 value) const 461 { 462 regPressure->SetNumCall(value); 463 } 464 GetNumCall()465 int32 GetNumCall() const 466 { 467 return regPressure->GetNumCall(); 468 } 469 SetHasNativeCallRegister(bool value)470 void SetHasNativeCallRegister(bool value) const 471 { 472 regPressure->SetHasNativeCallRegister(value); 473 } 474 GetHasNativeCallRegister()475 bool GetHasNativeCallRegister() const 476 { 477 return regPressure->GetHasNativeCallRegister(); 478 } 479 GetLocInsn()480 const Insn *GetLocInsn() const 481 { 482 return locInsn; 483 } SetLocInsn(const Insn & insn)484 void SetLocInsn(const Insn &insn) 485 { 486 locInsn = &insn; 487 } 488 489 /* printf dep-node's information of scheduling */ DumpSchedInfo()490 void DumpSchedInfo() const 491 { 492 PRINT_STR_VAL("estart: ", eStart); 493 PRINT_STR_VAL("lstart: ", lStart); 494 PRINT_STR_VAL("visit: ", visit); 495 PRINT_STR_VAL("state: ", state); 496 PRINT_STR_VAL("index: ", index); 497 PRINT_STR_VAL("validPredsSize: ", validPredsSize); 498 PRINT_STR_VAL("validSuccsSize: ", validSuccsSize); 499 LogInfo::MapleLogger() << '\n'; 500 501 constexpr int32 width = 12; 502 LogInfo::MapleLogger() << std::left << std::setw(width) << "usereg: "; 503 for (const auto &useReg : useRegnos) { 504 LogInfo::MapleLogger() << "R" << useReg << " "; 505 } 506 LogInfo::MapleLogger() << "\n"; 507 LogInfo::MapleLogger() << std::left << std::setw(width) << "defreg: "; 508 for (const auto &defReg : defRegnos) { 509 LogInfo::MapleLogger() << "R" << defReg << " "; 510 } 511 LogInfo::MapleLogger() << "\n"; 512 } 513 SetHasPreg(bool value)514 void SetHasPreg(bool value) const 515 { 516 regPressure->SetHasPreg(value); 517 } 518 GetHasPreg()519 bool GetHasPreg() const 520 { 521 return regPressure->GetHasPreg(); 522 } 523 AddUseReg(regno_t reg)524 void AddUseReg(regno_t reg) 525 { 526 useRegnos.emplace_back(reg); 527 } 528 GetUseRegnos()529 const MapleVector<regno_t> &GetUseRegnos() const 530 { 531 return useRegnos; 532 } 533 AddDefReg(regno_t reg)534 void AddDefReg(regno_t reg) 535 { 536 defRegnos.emplace_back(reg); 537 } 538 GetDefRegnos()539 const MapleVector<regno_t> &GetDefRegnos() const 540 { 541 return defRegnos; 542 } 543 544 private: 545 Insn *insn; 546 Unit *const *units; 547 Reservation *reservation; 548 uint32 unitNum; 549 uint32 eStart; 550 uint32 lStart; 551 uint32 visit; 552 NodeType type; 553 ScheduleState state; 554 uint32 index; 555 uint32 simulateCycle; 556 uint32 schedCycle; 557 uint32 bruteForceSchedCycle; 558 559 /* For scheduling, denotes unscheduled preds/succs number. */ 560 uint32 validPredsSize; 561 uint32 validSuccsSize; 562 563 /* Dependence links. */ 564 MapleVector<DepLink *> preds; 565 MapleVector<DepLink *> succs; 566 567 /* Non-machine instructions prior to insn, such as comments. */ 568 MapleVector<Insn *> comments; 569 570 /* Non-machine instructions which follows insn, such as cfi instructions. */ 571 MapleVector<Insn *> cfiInsns; 572 573 /* Special instructions which follows insn, such as clinit instructions. */ 574 MapleVector<Insn *> clinitInsns; 575 576 /* loc insn which indicate insn location in source file */ 577 const Insn *locInsn; 578 579 MapleVector<regno_t> useRegnos; 580 MapleVector<regno_t> defRegnos; 581 582 /* For register pressure analysis */ 583 RegPressure *regPressure; 584 }; 585 } /* namespace maplebe */ 586 587 #endif /* MAPLEBE_INCLUDE_CG_DEPS_H */ 588