LoopTraversal.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. //===- LoopTraversal.cpp - Optimal basic block traversal order --*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/CodeGen/LoopTraversal.h"
  9. #include "llvm/ADT/PostOrderIterator.h"
  10. #include "llvm/CodeGen/MachineFunction.h"
  11. using namespace llvm;
  12. bool LoopTraversal::isBlockDone(MachineBasicBlock *MBB) {
  13. unsigned MBBNumber = MBB->getNumber();
  14. assert(MBBNumber < MBBInfos.size() && "Unexpected basic block number.");
  15. return MBBInfos[MBBNumber].PrimaryCompleted &&
  16. MBBInfos[MBBNumber].IncomingCompleted ==
  17. MBBInfos[MBBNumber].PrimaryIncoming &&
  18. MBBInfos[MBBNumber].IncomingProcessed == MBB->pred_size();
  19. }
  20. LoopTraversal::TraversalOrder LoopTraversal::traverse(MachineFunction &MF) {
  21. // Initialize the MMBInfos
  22. MBBInfos.assign(MF.getNumBlockIDs(), MBBInfo());
  23. MachineBasicBlock *Entry = &*MF.begin();
  24. ReversePostOrderTraversal<MachineBasicBlock *> RPOT(Entry);
  25. SmallVector<MachineBasicBlock *, 4> Workqueue;
  26. SmallVector<TraversedMBBInfo, 4> MBBTraversalOrder;
  27. for (MachineBasicBlock *MBB : RPOT) {
  28. // N.B: IncomingProcessed and IncomingCompleted were already updated while
  29. // processing this block's predecessors.
  30. unsigned MBBNumber = MBB->getNumber();
  31. assert(MBBNumber < MBBInfos.size() && "Unexpected basic block number.");
  32. MBBInfos[MBBNumber].PrimaryCompleted = true;
  33. MBBInfos[MBBNumber].PrimaryIncoming = MBBInfos[MBBNumber].IncomingProcessed;
  34. bool Primary = true;
  35. Workqueue.push_back(MBB);
  36. while (!Workqueue.empty()) {
  37. MachineBasicBlock *ActiveMBB = Workqueue.pop_back_val();
  38. bool Done = isBlockDone(ActiveMBB);
  39. MBBTraversalOrder.push_back(TraversedMBBInfo(ActiveMBB, Primary, Done));
  40. for (MachineBasicBlock *Succ : ActiveMBB->successors()) {
  41. unsigned SuccNumber = Succ->getNumber();
  42. assert(SuccNumber < MBBInfos.size() &&
  43. "Unexpected basic block number.");
  44. if (!isBlockDone(Succ)) {
  45. if (Primary)
  46. MBBInfos[SuccNumber].IncomingProcessed++;
  47. if (Done)
  48. MBBInfos[SuccNumber].IncomingCompleted++;
  49. if (isBlockDone(Succ))
  50. Workqueue.push_back(Succ);
  51. }
  52. }
  53. Primary = false;
  54. }
  55. }
  56. // We need to go through again and finalize any blocks that are not done yet.
  57. // This is possible if blocks have dead predecessors, so we didn't visit them
  58. // above.
  59. for (MachineBasicBlock *MBB : RPOT) {
  60. if (!isBlockDone(MBB))
  61. MBBTraversalOrder.push_back(TraversedMBBInfo(MBB, false, true));
  62. // Don't update successors here. We'll get to them anyway through this
  63. // loop.
  64. }
  65. MBBInfos.clear();
  66. return MBBTraversalOrder;
  67. }