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 /* 17 * The file defines the data structures of Control Dependence Graph(CDG). 18 */ 19 #ifndef MAPLEBE_INCLUDE_CG_CG_CDG_H 20 #define MAPLEBE_INCLUDE_CG_CG_CDG_H 21 22 #include <string> 23 #include "cgfunc.h" 24 #include "mpl_number.h" 25 #include "deps.h" 26 #include "mempool_allocator.h" 27 28 namespace maplebe { 29 class CDGNode; 30 class CDGEdge; 31 class CDGRegion; 32 using CDGNodeId = utils::Index<CDGNode>; 33 using CDGRegionId = utils::Index<CDGRegion>; 34 35 // Encapsulation of BB 36 class CDGNode { 37 public: CDGNode(CDGNodeId nId,BB & bb,MapleAllocator & alloc)38 CDGNode(CDGNodeId nId, BB &bb, MapleAllocator &alloc) 39 : id(nId), 40 bb(&bb), 41 outEdges(alloc.Adapter()), 42 inEdges(alloc.Adapter()), 43 lastComments(alloc.Adapter()), 44 dataNodes(alloc.Adapter()), 45 cfiInsns(alloc.Adapter()) 46 { 47 } ~CDGNode()48 virtual ~CDGNode() 49 { 50 topoPredInRegion = nullptr; 51 lastFrameDef = nullptr; 52 bb = nullptr; 53 regUses = nullptr; 54 mayThrows = nullptr; 55 ehInRegs = nullptr; 56 heapDefs = nullptr; 57 ambiInsns = nullptr; 58 membarInsn = nullptr; 59 pseudoSepNodes = nullptr; 60 lastCallInsn = nullptr; 61 lastInlineAsmInsn = nullptr; 62 regDefs = nullptr; 63 stackDefs = nullptr; 64 region = nullptr; 65 heapUses = nullptr; 66 stackUses = nullptr; 67 } 68 GetBB()69 BB *GetBB() 70 { 71 return bb; 72 } 73 GetBB()74 const BB *GetBB() const 75 { 76 return bb; 77 } 78 GetNodeId()79 CDGNodeId GetNodeId() 80 { 81 return id; 82 } 83 GetNodeId()84 CDGNodeId GetNodeId() const 85 { 86 return id; 87 } 88 SetNodeId(CDGNodeId nId)89 void SetNodeId(CDGNodeId nId) 90 { 91 id = nId; 92 } 93 GetRegion()94 CDGRegion *GetRegion() 95 { 96 return region; 97 } 98 GetRegion()99 const CDGRegion *GetRegion() const 100 { 101 return region; 102 } 103 SetRegion(CDGRegion * cdgRegion)104 void SetRegion(CDGRegion *cdgRegion) 105 { 106 region = cdgRegion; 107 } 108 ClearRegion()109 void ClearRegion() 110 { 111 region = nullptr; 112 } 113 IsEntryNode()114 bool IsEntryNode() const 115 { 116 return isEntryNode; 117 } 118 SetEntryNode()119 void SetEntryNode() 120 { 121 isEntryNode = true; 122 } 123 IsExitNode()124 bool IsExitNode() const 125 { 126 return isExitNode; 127 } 128 SetExitNode()129 void SetExitNode() 130 { 131 isExitNode = true; 132 } 133 AddOutEdges(CDGEdge * edge)134 void AddOutEdges(CDGEdge *edge) 135 { 136 outEdges.emplace_back(edge); 137 } 138 GetAllOutEdges()139 MapleVector<CDGEdge *> &GetAllOutEdges() 140 { 141 return outEdges; 142 } 143 AddInEdges(CDGEdge * edge)144 void AddInEdges(CDGEdge *edge) 145 { 146 inEdges.emplace_back(edge); 147 } 148 GetAllInEdges()149 MapleVector<CDGEdge *> &GetAllInEdges() 150 { 151 return inEdges; 152 } 153 GetOutEdgesNum()154 std::size_t GetOutEdgesNum() const 155 { 156 return outEdges.size(); 157 } 158 GetInEdgesNum()159 std::size_t GetInEdgesNum() const 160 { 161 return inEdges.size(); 162 } 163 SetVisitedInTopoSort(bool isVisited)164 void SetVisitedInTopoSort(bool isVisited) 165 { 166 isVisitedInTopoSort = isVisited; 167 } 168 IsVisitedInTopoSort()169 bool IsVisitedInTopoSort() const 170 { 171 return isVisitedInTopoSort; 172 } 173 SetVisitedInExtendedFind()174 void SetVisitedInExtendedFind() 175 { 176 isVisitedInExtendedFind = true; 177 } 178 IsVisitedInExtendedFind()179 bool IsVisitedInExtendedFind() const 180 { 181 return isVisitedInExtendedFind; 182 } 183 GetInsnNum()184 uint32 GetInsnNum() const 185 { 186 return insnNum; 187 } 188 SetInsnNum(uint32 num)189 void SetInsnNum(uint32 num) 190 { 191 insnNum = num; 192 } 193 HasAmbiRegs()194 bool HasAmbiRegs() const 195 { 196 return hasAmbiRegs; 197 } 198 SetHasAmbiRegs(bool flag)199 void SetHasAmbiRegs(bool flag) 200 { 201 hasAmbiRegs = flag; 202 } 203 GetMembarInsn()204 Insn *GetMembarInsn() 205 { 206 return membarInsn; 207 } 208 SetMembarInsn(Insn * insn)209 void SetMembarInsn(Insn *insn) 210 { 211 membarInsn = insn; 212 } 213 GetLastCallInsn()214 Insn *GetLastCallInsn() 215 { 216 return lastCallInsn; 217 } 218 SetLastCallInsn(Insn * callInsn)219 void SetLastCallInsn(Insn *callInsn) 220 { 221 lastCallInsn = callInsn; 222 } 223 GetLastFrameDefInsn()224 Insn *GetLastFrameDefInsn() 225 { 226 return lastFrameDef; 227 } 228 SetLastFrameDefInsn(Insn * frameInsn)229 void SetLastFrameDefInsn(Insn *frameInsn) 230 { 231 lastFrameDef = frameInsn; 232 } 233 GetLastInlineAsmInsn()234 Insn *GetLastInlineAsmInsn() 235 { 236 return lastInlineAsmInsn; 237 } 238 SetLastInlineAsmInsn(Insn * asmInsn)239 void SetLastInlineAsmInsn(Insn *asmInsn) 240 { 241 lastInlineAsmInsn = asmInsn; 242 } 243 InitTopoInRegionInfo(MemPool & tmpMp,MapleAllocator & tmpAlloc)244 void InitTopoInRegionInfo(MemPool &tmpMp, MapleAllocator &tmpAlloc) 245 { 246 topoPredInRegion = tmpMp.New<MapleSet<CDGNodeId>>(tmpAlloc.Adapter()); 247 } 248 ClearTopoInRegionInfo()249 void ClearTopoInRegionInfo() 250 { 251 topoPredInRegion = nullptr; 252 } 253 InitDataDepInfo(MemPool & tmpMp,MapleAllocator & tmpAlloc,uint32 maxRegNum)254 void InitDataDepInfo(MemPool &tmpMp, MapleAllocator &tmpAlloc, uint32 maxRegNum) 255 { 256 regDefs = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter()); 257 regUses = tmpMp.New<MapleVector<RegList *>>(tmpAlloc.Adapter()); 258 stackUses = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter()); 259 stackDefs = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter()); 260 heapUses = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter()); 261 heapDefs = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter()); 262 mayThrows = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter()); 263 ambiInsns = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter()); 264 pseudoSepNodes = tmpMp.New<MapleVector<DepNode *>>(tmpAlloc.Adapter()); 265 ehInRegs = tmpMp.New<MapleSet<regno_t>>(tmpAlloc.Adapter()); 266 267 regDefs->resize(maxRegNum); 268 regUses->resize(maxRegNum); 269 } 270 ClearDataDepInfo()271 void ClearDataDepInfo() 272 { 273 membarInsn = nullptr; 274 lastCallInsn = nullptr; 275 lastFrameDef = nullptr; 276 lastInlineAsmInsn = nullptr; 277 lastComments.clear(); 278 279 regDefs = nullptr; 280 regUses = nullptr; 281 stackUses = nullptr; 282 stackDefs = nullptr; 283 heapUses = nullptr; 284 heapDefs = nullptr; 285 mayThrows = nullptr; 286 ambiInsns = nullptr; 287 pseudoSepNodes = nullptr; 288 ehInRegs = nullptr; 289 } 290 ClearDepDataVec()291 void ClearDepDataVec() 292 { 293 membarInsn = nullptr; 294 lastCallInsn = nullptr; 295 lastFrameDef = nullptr; 296 lastInlineAsmInsn = nullptr; 297 298 for (auto ®Def : *regDefs) { 299 regDef = nullptr; 300 } 301 for (auto ®Use : *regUses) { 302 regUse = nullptr; 303 } 304 305 stackUses->clear(); 306 stackDefs->clear(); 307 heapUses->clear(); 308 heapDefs->clear(); 309 mayThrows->clear(); 310 ambiInsns->clear(); 311 } 312 GetLatestDefInsn(regno_t regNO)313 Insn *GetLatestDefInsn(regno_t regNO) 314 { 315 return (*regDefs)[regNO]; 316 } 317 SetLatestDefInsn(regno_t regNO,Insn * defInsn)318 void SetLatestDefInsn(regno_t regNO, Insn *defInsn) 319 { 320 (*regDefs)[regNO] = defInsn; 321 } 322 GetUseInsnChain(regno_t regNO)323 RegList *GetUseInsnChain(regno_t regNO) 324 { 325 return (*regUses)[regNO]; 326 } 327 AppendUseInsnChain(regno_t regNO,Insn * useInsn,MemPool & mp)328 void AppendUseInsnChain(regno_t regNO, Insn *useInsn, MemPool &mp) 329 { 330 CHECK_FATAL(useInsn != nullptr, "invalid useInsn"); 331 auto *newUse = mp.New<RegList>(); 332 newUse->insn = useInsn; 333 newUse->next = nullptr; 334 335 RegList *headUse = (*regUses)[regNO]; 336 if (headUse == nullptr) { 337 (*regUses)[regNO] = newUse; 338 } else { 339 while (headUse->next != nullptr) { 340 headUse = headUse->next; 341 } 342 headUse->next = newUse; 343 } 344 } 345 ClearUseInsnChain(regno_t regNO)346 void ClearUseInsnChain(regno_t regNO) 347 { 348 (*regUses)[regNO] = nullptr; 349 } 350 GetStackUseInsns()351 MapleVector<Insn *> &GetStackUseInsns() 352 { 353 return *stackUses; 354 } 355 AddStackUseInsn(Insn * stackInsn)356 void AddStackUseInsn(Insn *stackInsn) 357 { 358 stackUses->emplace_back(stackInsn); 359 } 360 GetStackDefInsns()361 MapleVector<Insn *> &GetStackDefInsns() 362 { 363 return *stackDefs; 364 } 365 AddStackDefInsn(Insn * stackInsn)366 void AddStackDefInsn(Insn *stackInsn) 367 { 368 stackDefs->emplace_back(stackInsn); 369 } 370 GetHeapUseInsns()371 MapleVector<Insn *> &GetHeapUseInsns() 372 { 373 return *heapUses; 374 } 375 AddHeapUseInsn(Insn * heapInsn)376 void AddHeapUseInsn(Insn *heapInsn) const 377 { 378 heapUses->emplace_back(heapInsn); 379 } 380 GetHeapDefInsns()381 MapleVector<Insn *> &GetHeapDefInsns() 382 { 383 return *heapDefs; 384 } 385 AddHeapDefInsn(Insn * heapInsn)386 void AddHeapDefInsn(Insn *heapInsn) const 387 { 388 heapDefs->emplace_back(heapInsn); 389 } 390 GetMayThrowInsns()391 MapleVector<Insn *> &GetMayThrowInsns() 392 { 393 return *mayThrows; 394 } 395 AddMayThrowInsn(Insn * throwInsn)396 void AddMayThrowInsn(Insn *throwInsn) 397 { 398 mayThrows->emplace_back(throwInsn); 399 } 400 GetAmbiguousInsns()401 MapleVector<Insn *> &GetAmbiguousInsns() 402 { 403 return *ambiInsns; 404 } 405 AddAmbiguousInsn(Insn * ambiInsn)406 void AddAmbiguousInsn(Insn *ambiInsn) const 407 { 408 ambiInsns->emplace_back(ambiInsn); 409 } 410 GetTopoPredInRegion()411 MapleSet<CDGNodeId> &GetTopoPredInRegion() 412 { 413 return *topoPredInRegion; 414 } 415 InsertVisitedTopoPredInRegion(CDGNodeId nodeId)416 void InsertVisitedTopoPredInRegion(CDGNodeId nodeId) const 417 { 418 topoPredInRegion->insert(nodeId); 419 } 420 GetLastComments()421 MapleVector<Insn *> &GetLastComments() 422 { 423 return lastComments; 424 } 425 AddCommentInsn(Insn * commentInsn)426 void AddCommentInsn(Insn *commentInsn) 427 { 428 lastComments.emplace_back(commentInsn); 429 } 430 CopyAndClearComments(MapleVector<Insn * > & comments)431 void CopyAndClearComments(MapleVector<Insn *> &comments) 432 { 433 lastComments = comments; 434 comments.clear(); 435 } 436 ClearLastComments()437 void ClearLastComments() 438 { 439 lastComments.clear(); 440 } 441 AddPseudoSepNodes(DepNode * node)442 void AddPseudoSepNodes(DepNode *node) const 443 { 444 pseudoSepNodes->emplace_back(node); 445 } 446 GetEhInRegs()447 MapleSet<regno_t> &GetEhInRegs() 448 { 449 return *ehInRegs; 450 } 451 GetAllDataNodes()452 MapleVector<DepNode *> &GetAllDataNodes() 453 { 454 return dataNodes; 455 } 456 AddDataNode(DepNode * depNode)457 void AddDataNode(DepNode *depNode) 458 { 459 (void)dataNodes.emplace_back(depNode); 460 } 461 ClearDataNodes()462 void ClearDataNodes() 463 { 464 dataNodes.clear(); 465 } 466 GetCfiInsns()467 MapleVector<Insn *> &GetCfiInsns() 468 { 469 return cfiInsns; 470 } 471 AddCfiInsn(Insn * cfiInsn)472 void AddCfiInsn(Insn *cfiInsn) 473 { 474 (void)cfiInsns.emplace_back(cfiInsn); 475 } 476 RemoveDepNodeFromDataNodes(const DepNode & depNode)477 void RemoveDepNodeFromDataNodes(const DepNode &depNode) 478 { 479 for (auto iter = dataNodes.begin(); iter != dataNodes.end(); ++iter) { 480 if (*iter == &depNode) { 481 void(dataNodes.erase(iter)); 482 break; 483 } 484 } 485 } 486 InitPredNodeSumInRegion(int32 predSum)487 void InitPredNodeSumInRegion(int32 predSum) 488 { 489 CHECK_FATAL(predSum >= 0, "invalid predSum"); 490 predNodesInRegion = predSum; 491 } 492 DecPredNodeSumInRegion()493 void DecPredNodeSumInRegion() 494 { 495 predNodesInRegion--; 496 } 497 IsAllPredInRegionProcessed()498 bool IsAllPredInRegionProcessed() const 499 { 500 return (predNodesInRegion == 0); 501 } 502 GetNodeSum()503 uint32 &GetNodeSum() 504 { 505 return nodeSum; 506 } 507 AccNodeSum()508 void AccNodeSum() 509 { 510 nodeSum++; 511 } 512 SetNodeSum(uint32 sum)513 void SetNodeSum(uint32 sum) 514 { 515 nodeSum = sum; 516 } 517 518 bool operator!=(const CDGNode &node) 519 { 520 if (this != &node) { 521 return true; 522 } 523 if (this->id != node.GetNodeId() || this->bb != node.GetBB() || this->region != node.GetRegion()) { 524 return true; 525 } 526 if (this->GetInEdgesNum() != node.GetInEdgesNum() || this->GetOutEdgesNum() != node.GetOutEdgesNum()) { 527 return true; 528 } 529 return false; 530 } 531 532 private: 533 CDGNodeId id; // same to bbId 534 BB *bb = nullptr; 535 CDGRegion *region = nullptr; 536 bool isEntryNode = false; 537 bool isExitNode = false; 538 MapleVector<CDGEdge *> outEdges; 539 MapleVector<CDGEdge *> inEdges; 540 bool isVisitedInTopoSort = false; // for sorting nodes in region by topological order 541 bool isVisitedInExtendedFind = false; // for finding a fallthrough path as a region 542 uint32 insnNum = 0; // record insn total num of BB 543 // The following structures are used to record data flow infos in building data dependence among insns 544 bool hasAmbiRegs = false; 545 Insn *membarInsn = nullptr; 546 Insn *lastCallInsn = nullptr; 547 Insn *lastFrameDef = nullptr; 548 Insn *lastInlineAsmInsn = nullptr; 549 MapleVector<Insn *> *regDefs = nullptr; // the index is regNO, record the latest defInsn in the curBB 550 MapleVector<RegList *> *regUses = nullptr; // the index is regNO 551 MapleVector<Insn *> *stackUses = nullptr; 552 MapleVector<Insn *> *stackDefs = nullptr; 553 MapleVector<Insn *> *heapUses = nullptr; 554 MapleVector<Insn *> *heapDefs = nullptr; 555 MapleVector<Insn *> *mayThrows = nullptr; 556 MapleVector<Insn *> *ambiInsns = nullptr; 557 MapleVector<DepNode *> *pseudoSepNodes = nullptr; 558 MapleSet<regno_t> *ehInRegs = nullptr; 559 MapleSet<CDGNodeId> *topoPredInRegion = nullptr; 560 MapleVector<Insn *> lastComments; 561 MapleVector<DepNode *> dataNodes; 562 MapleVector<Insn *> cfiInsns; 563 // For computing topological order of cdgNodes in a region, 564 // which is initialized to the number of pred nodes in CFG at the beginning of processing the region, 565 // and change dynamically 566 int32 predNodesInRegion = -1; 567 // For intra-block dda: it accumulates from the first insn (nodeSum = 1) of bb 568 // For inter-block dda: it accumulates from the maximum of nodeSum in all the predecessor of cur cdgNode 569 uint32 nodeSum = 0; 570 }; 571 572 class CDGEdge { 573 public: CDGEdge(CDGNode & from,CDGNode & to,int32 cond)574 CDGEdge(CDGNode &from, CDGNode &to, int32 cond) : fromNode(from), toNode(to), condition(cond) {} 575 virtual ~CDGEdge() = default; 576 GetFromNode()577 CDGNode &GetFromNode() 578 { 579 return fromNode; 580 } 581 GetFromNode()582 CDGNode &GetFromNode() const 583 { 584 return fromNode; 585 } 586 SetFromNode(const CDGNode & from)587 void SetFromNode(const CDGNode &from) 588 { 589 fromNode = from; 590 } 591 GetToNode()592 CDGNode &GetToNode() 593 { 594 return toNode; 595 } 596 GetToNode()597 CDGNode &GetToNode() const 598 { 599 return toNode; 600 } 601 SetToNode(const CDGNode & to)602 void SetToNode(const CDGNode &to) 603 { 604 toNode = to; 605 } 606 GetCondition()607 int32 GetCondition() const 608 { 609 return condition; 610 } 611 SetCondition(int32 cond)612 void SetCondition(int32 cond) 613 { 614 condition = cond; 615 } 616 617 // for checking same control dependence 618 bool operator==(const CDGEdge &edge) 619 { 620 if (this == &edge) { 621 return true; 622 } 623 if (this->fromNode != edge.GetFromNode()) { 624 return false; 625 } 626 if (this->toNode != edge.GetToNode()) { 627 return false; 628 } 629 if (this->condition != edge.GetCondition()) { 630 return false; 631 } 632 return true; 633 } 634 635 private: 636 CDGNode &fromNode; 637 CDGNode &toNode; 638 // allocate different COND number to different succ edges of the same fromBB 639 // default value is -1 indicated no cond. 640 int32 condition; 641 }; 642 643 // A region consists of nodes with the same control dependence sets 644 class CDGRegion { 645 public: CDGRegion(CDGRegionId rId,MapleAllocator & alloc)646 CDGRegion(CDGRegionId rId, MapleAllocator &alloc) : id(rId), memberNodes(alloc.Adapter()), cdEdges(alloc.Adapter()) 647 { 648 } ~CDGRegion()649 virtual ~CDGRegion() 650 { 651 root = nullptr; 652 } 653 GetRegionId()654 CDGRegionId GetRegionId() 655 { 656 return id; 657 } 658 GetRegionNodes()659 MapleVector<CDGNode *> &GetRegionNodes() 660 { 661 return memberNodes; 662 } 663 GetRegionNodeSize()664 std::size_t GetRegionNodeSize() const 665 { 666 return memberNodes.size(); 667 } 668 669 // Ensure the node is unique AddCDGNode(CDGNode * node)670 void AddCDGNode(CDGNode *node) 671 { 672 if (std::find(memberNodes.cbegin(), memberNodes.cend(), node) == memberNodes.cend()) { 673 memberNodes.emplace_back(node); 674 } 675 } 676 RemoveCDGNode(CDGNode * node)677 void RemoveCDGNode(CDGNode *node) 678 { 679 auto it = std::find(memberNodes.begin(), memberNodes.end(), node); 680 if (it == memberNodes.end()) { 681 return; 682 } 683 (void)memberNodes.erase(it); 684 } 685 GetCDGNodeById(CDGNodeId nodeId)686 CDGNode *GetCDGNodeById(CDGNodeId nodeId) 687 { 688 for (auto cdgNode : memberNodes) { 689 if (cdgNode->GetNodeId() == nodeId) { 690 return cdgNode; 691 } 692 } 693 return nullptr; 694 } 695 GetCDEdges()696 MapleVector<CDGEdge *> &GetCDEdges() 697 { 698 return cdEdges; 699 } 700 AddCDEdge(CDGEdge * edge)701 void AddCDEdge(CDGEdge *edge) 702 { 703 cdEdges.emplace_back(edge); 704 } 705 AddCDEdgeSet(MapleVector<CDGEdge * > & cds)706 void AddCDEdgeSet(MapleVector<CDGEdge *> &cds) 707 { 708 for (auto &cd : cds) { 709 cdEdges.emplace_back(cd); 710 } 711 } 712 GetMaxBBIdInRegion()713 uint32 GetMaxBBIdInRegion() 714 { 715 uint32 maxId = 0; 716 for (auto node : memberNodes) { 717 maxId = (node->GetNodeId() > maxId ? static_cast<uint32>(node->GetNodeId()) : maxId); 718 } 719 return maxId; 720 } 721 SetRegionRoot(CDGNode & node)722 void SetRegionRoot(CDGNode &node) 723 { 724 root = &node; 725 } 726 GetRegionRoot()727 CDGNode *GetRegionRoot() 728 { 729 return root; 730 } 731 SetBackBBId(BBID bbId)732 void SetBackBBId(BBID bbId) 733 { 734 backEdgeFromBBId = bbId; 735 } 736 GetBackBBId()737 BBID GetBackBBId() const 738 { 739 return backEdgeFromBBId; 740 } 741 742 private: 743 CDGRegionId id; 744 MapleVector<CDGNode *> memberNodes; // The nodes in CDGRegion by topological order 745 // The control dependence sets of the parent node. 746 // If it is a general non-linear region, the cdEdges is empty. 747 MapleVector<CDGEdge *> cdEdges; 748 CDGNode *root = nullptr; 749 BBID backEdgeFromBBId = UINT32_MAX; // For loop region 750 }; 751 752 // Forward Control Dependence Graph 753 // which does not compute the control dependence on the back edges 754 class FCDG { 755 public: FCDG(const CGFunc & f,MapleAllocator & alloc)756 FCDG(const CGFunc &f, MapleAllocator &alloc) 757 : nodes(f.GetAllBBSize(), alloc.Adapter()), 758 fcds(alloc.Adapter()), 759 regions(f.GetAllBBSize() + 1, alloc.Adapter()) 760 { 761 } 762 virtual ~FCDG() = default; 763 GetAllFCDGNodes()764 MapleVector<CDGNode *> &GetAllFCDGNodes() 765 { 766 return nodes; 767 } 768 GetFCDGNodeSize()769 std::size_t GetFCDGNodeSize() const 770 { 771 return nodes.size(); 772 } 773 GetCDGNodeFromId(CDGNodeId id)774 CDGNode *GetCDGNodeFromId(CDGNodeId id) 775 { 776 return nodes[id]; 777 } 778 GetAllFCDGEdges()779 MapleVector<CDGEdge *> &GetAllFCDGEdges() 780 { 781 return fcds; 782 } 783 GetAllRegions()784 MapleVector<CDGRegion *> &GetAllRegions() 785 { 786 return regions; 787 } 788 GetRegionFromId(CDGRegionId id)789 CDGRegion *GetRegionFromId(CDGRegionId id) 790 { 791 return regions[id]; 792 } 793 794 // Ensure the node is unique AddFCDGNode(CDGNode & node)795 void AddFCDGNode(CDGNode &node) 796 { 797 if (nodes[node.GetNodeId()] == nullptr) { 798 nodes[node.GetNodeId()] = &node; 799 } 800 } 801 AddFCDGEdge(CDGEdge * edge)802 void AddFCDGEdge(CDGEdge *edge) 803 { 804 fcds.emplace_back(edge); 805 } 806 807 // Ensure the region is unique AddRegion(CDGRegion & region)808 void AddRegion(CDGRegion ®ion) 809 { 810 if (regions[region.GetRegionId()] == nullptr) { 811 regions[region.GetRegionId()] = ®ion; 812 } 813 } 814 RemoveRegionById(CDGRegionId id)815 void RemoveRegionById(CDGRegionId id) 816 { 817 regions[id] = nullptr; 818 } 819 820 // Provide interfaces for global scheduling 821 822 private: 823 MapleVector<CDGNode *> nodes; // all CDGNodes in FCDG that use nodeId as the index 824 MapleVector<CDGEdge *> fcds; // all forward-control-dependence in FCDG 825 MapleVector<CDGRegion *> regions; // all regions in FCDG that use CDGRegionId as the index 826 }; 827 828 struct CDGOutEdgeComparator { operatorCDGOutEdgeComparator829 bool operator()(const CDGEdge &outEdge1, const CDGEdge &outEdge2) const 830 { 831 const CDGNode &toNode1 = outEdge1.GetToNode(); 832 const CDGNode &toNode2 = outEdge2.GetToNode(); 833 return toNode1.GetNodeId() < toNode2.GetNodeId(); 834 } 835 }; 836 837 struct CDGInEdgeComparator { operatorCDGInEdgeComparator838 bool operator()(const CDGEdge &inEdge1, const CDGEdge &inEdge2) const 839 { 840 const CDGNode &fromNode1 = inEdge1.GetFromNode(); 841 const CDGNode &fromNode2 = inEdge2.GetToNode(); 842 return fromNode1.GetNodeId() < fromNode2.GetNodeId(); 843 } 844 }; 845 } // namespace maplebe 846 847 namespace std { 848 template <> 849 struct hash<maplebe::CDGNodeId> { 850 size_t operator()(const maplebe::CDGNodeId &nId) const 851 { 852 return nId; 853 } 854 }; 855 856 template <> 857 struct hash<maplebe::CDGRegionId> { 858 size_t operator()(const maplebe::CDGRegionId &rId) const 859 { 860 return rId; 861 } 862 }; 863 } // namespace std 864 #endif // MAPLEBE_INCLUDE_CG_CG_CDG_H 865