PPCCTRLoopsVerify.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //===-- PPCCTRLoops.cpp - Verify CTR loops -----------------===//
  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. //
  9. // This pass verifies that all bdnz/bdz instructions are dominated by a loop
  10. // mtctr before any other instructions that might clobber the ctr register.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. // CTR loops are produced by the HardwareLoops pass and this pass is simply a
  14. // verification that no invalid CTR loops are produced. As such, it isn't
  15. // something that needs to be run (or even defined) for Release builds so the
  16. // entire file is guarded by NDEBUG.
  17. #ifndef NDEBUG
  18. #include <vector>
  19. #include "MCTargetDesc/PPCMCTargetDesc.h"
  20. #include "PPC.h"
  21. #include "llvm/ADT/SmallSet.h"
  22. #include "llvm/ADT/SmallVector.h"
  23. #include "llvm/ADT/StringRef.h"
  24. #include "llvm/ADT/ilist_iterator.h"
  25. #include "llvm/CodeGen/MachineBasicBlock.h"
  26. #include "llvm/CodeGen/MachineDominators.h"
  27. #include "llvm/CodeGen/MachineFunction.h"
  28. #include "llvm/CodeGen/MachineFunctionPass.h"
  29. #include "llvm/CodeGen/MachineInstr.h"
  30. #include "llvm/CodeGen/MachineInstrBundleIterator.h"
  31. #include "llvm/CodeGen/MachineOperand.h"
  32. #include "llvm/CodeGen/Register.h"
  33. #include "llvm/InitializePasses.h"
  34. #include "llvm/Pass.h"
  35. #include "llvm/PassRegistry.h"
  36. #include "llvm/Support/CodeGen.h"
  37. #include "llvm/Support/Debug.h"
  38. #include "llvm/Support/ErrorHandling.h"
  39. #include "llvm/Support/GenericDomTreeConstruction.h"
  40. #include "llvm/Support/Printable.h"
  41. #include "llvm/Support/raw_ostream.h"
  42. using namespace llvm;
  43. #define DEBUG_TYPE "ppc-ctrloops-verify"
  44. namespace {
  45. struct PPCCTRLoopsVerify : public MachineFunctionPass {
  46. public:
  47. static char ID;
  48. PPCCTRLoopsVerify() : MachineFunctionPass(ID) {
  49. initializePPCCTRLoopsVerifyPass(*PassRegistry::getPassRegistry());
  50. }
  51. void getAnalysisUsage(AnalysisUsage &AU) const override {
  52. AU.addRequired<MachineDominatorTree>();
  53. MachineFunctionPass::getAnalysisUsage(AU);
  54. }
  55. bool runOnMachineFunction(MachineFunction &MF) override;
  56. private:
  57. MachineDominatorTree *MDT;
  58. };
  59. char PPCCTRLoopsVerify::ID = 0;
  60. } // end anonymous namespace
  61. INITIALIZE_PASS_BEGIN(PPCCTRLoopsVerify, "ppc-ctr-loops-verify",
  62. "PowerPC CTR Loops Verify", false, false)
  63. INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
  64. INITIALIZE_PASS_END(PPCCTRLoopsVerify, "ppc-ctr-loops-verify",
  65. "PowerPC CTR Loops Verify", false, false)
  66. FunctionPass *llvm::createPPCCTRLoopsVerify() {
  67. return new PPCCTRLoopsVerify();
  68. }
  69. static bool clobbersCTR(const MachineInstr &MI) {
  70. for (const MachineOperand &MO : MI.operands()) {
  71. if (MO.isReg()) {
  72. if (MO.isDef() && (MO.getReg() == PPC::CTR || MO.getReg() == PPC::CTR8))
  73. return true;
  74. } else if (MO.isRegMask()) {
  75. if (MO.clobbersPhysReg(PPC::CTR) || MO.clobbersPhysReg(PPC::CTR8))
  76. return true;
  77. }
  78. }
  79. return false;
  80. }
  81. static bool verifyCTRBranch(MachineBasicBlock *MBB,
  82. MachineBasicBlock::iterator I) {
  83. MachineBasicBlock::iterator BI = I;
  84. SmallSet<MachineBasicBlock *, 16> Visited;
  85. SmallVector<MachineBasicBlock *, 8> Preds;
  86. bool CheckPreds;
  87. if (I == MBB->begin()) {
  88. Visited.insert(MBB);
  89. goto queue_preds;
  90. } else
  91. --I;
  92. check_block:
  93. Visited.insert(MBB);
  94. if (I == MBB->end())
  95. goto queue_preds;
  96. CheckPreds = true;
  97. for (MachineBasicBlock::iterator IE = MBB->begin();; --I) {
  98. unsigned Opc = I->getOpcode();
  99. if (Opc == PPC::MTCTRloop || Opc == PPC::MTCTR8loop) {
  100. CheckPreds = false;
  101. break;
  102. }
  103. if (I != BI && clobbersCTR(*I)) {
  104. LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " (" << MBB->getFullName()
  105. << ") instruction " << *I
  106. << " clobbers CTR, invalidating "
  107. << printMBBReference(*BI->getParent()) << " ("
  108. << BI->getParent()->getFullName() << ") instruction "
  109. << *BI << "\n");
  110. return false;
  111. }
  112. if (I == IE)
  113. break;
  114. }
  115. if (!CheckPreds && Preds.empty())
  116. return true;
  117. if (CheckPreds) {
  118. queue_preds:
  119. if (MachineFunction::iterator(MBB) == MBB->getParent()->begin()) {
  120. LLVM_DEBUG(dbgs() << "Unable to find a MTCTR instruction for "
  121. << printMBBReference(*BI->getParent()) << " ("
  122. << BI->getParent()->getFullName() << ") instruction "
  123. << *BI << "\n");
  124. return false;
  125. }
  126. append_range(Preds, MBB->predecessors());
  127. }
  128. do {
  129. MBB = Preds.pop_back_val();
  130. if (!Visited.count(MBB)) {
  131. I = MBB->getLastNonDebugInstr();
  132. goto check_block;
  133. }
  134. } while (!Preds.empty());
  135. return true;
  136. }
  137. bool PPCCTRLoopsVerify::runOnMachineFunction(MachineFunction &MF) {
  138. MDT = &getAnalysis<MachineDominatorTree>();
  139. // Verify that all bdnz/bdz instructions are dominated by a loop mtctr before
  140. // any other instructions that might clobber the ctr register.
  141. for (MachineBasicBlock &MBB : MF) {
  142. if (!MDT->isReachableFromEntry(&MBB))
  143. continue;
  144. for (MachineBasicBlock::iterator MII = MBB.getFirstTerminator(),
  145. MIIE = MBB.end(); MII != MIIE; ++MII) {
  146. unsigned Opc = MII->getOpcode();
  147. if (Opc == PPC::BDNZ8 || Opc == PPC::BDNZ ||
  148. Opc == PPC::BDZ8 || Opc == PPC::BDZ)
  149. if (!verifyCTRBranch(&MBB, MII))
  150. llvm_unreachable("Invalid PPC CTR loop!");
  151. }
  152. }
  153. return false;
  154. }
  155. #endif // NDEBUG