PPCCTRLoops.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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 (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
  71. const MachineOperand &MO = MI.getOperand(i);
  72. if (MO.isReg()) {
  73. if (MO.isDef() && (MO.getReg() == PPC::CTR || MO.getReg() == PPC::CTR8))
  74. return true;
  75. } else if (MO.isRegMask()) {
  76. if (MO.clobbersPhysReg(PPC::CTR) || MO.clobbersPhysReg(PPC::CTR8))
  77. return true;
  78. }
  79. }
  80. return false;
  81. }
  82. static bool verifyCTRBranch(MachineBasicBlock *MBB,
  83. MachineBasicBlock::iterator I) {
  84. MachineBasicBlock::iterator BI = I;
  85. SmallSet<MachineBasicBlock *, 16> Visited;
  86. SmallVector<MachineBasicBlock *, 8> Preds;
  87. bool CheckPreds;
  88. if (I == MBB->begin()) {
  89. Visited.insert(MBB);
  90. goto queue_preds;
  91. } else
  92. --I;
  93. check_block:
  94. Visited.insert(MBB);
  95. if (I == MBB->end())
  96. goto queue_preds;
  97. CheckPreds = true;
  98. for (MachineBasicBlock::iterator IE = MBB->begin();; --I) {
  99. unsigned Opc = I->getOpcode();
  100. if (Opc == PPC::MTCTRloop || Opc == PPC::MTCTR8loop) {
  101. CheckPreds = false;
  102. break;
  103. }
  104. if (I != BI && clobbersCTR(*I)) {
  105. LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " (" << MBB->getFullName()
  106. << ") instruction " << *I
  107. << " clobbers CTR, invalidating "
  108. << printMBBReference(*BI->getParent()) << " ("
  109. << BI->getParent()->getFullName() << ") instruction "
  110. << *BI << "\n");
  111. return false;
  112. }
  113. if (I == IE)
  114. break;
  115. }
  116. if (!CheckPreds && Preds.empty())
  117. return true;
  118. if (CheckPreds) {
  119. queue_preds:
  120. if (MachineFunction::iterator(MBB) == MBB->getParent()->begin()) {
  121. LLVM_DEBUG(dbgs() << "Unable to find a MTCTR instruction for "
  122. << printMBBReference(*BI->getParent()) << " ("
  123. << BI->getParent()->getFullName() << ") instruction "
  124. << *BI << "\n");
  125. return false;
  126. }
  127. append_range(Preds, MBB->predecessors());
  128. }
  129. do {
  130. MBB = Preds.pop_back_val();
  131. if (!Visited.count(MBB)) {
  132. I = MBB->getLastNonDebugInstr();
  133. goto check_block;
  134. }
  135. } while (!Preds.empty());
  136. return true;
  137. }
  138. bool PPCCTRLoopsVerify::runOnMachineFunction(MachineFunction &MF) {
  139. MDT = &getAnalysis<MachineDominatorTree>();
  140. // Verify that all bdnz/bdz instructions are dominated by a loop mtctr before
  141. // any other instructions that might clobber the ctr register.
  142. for (MachineFunction::iterator I = MF.begin(), IE = MF.end();
  143. I != IE; ++I) {
  144. MachineBasicBlock *MBB = &*I;
  145. if (!MDT->isReachableFromEntry(MBB))
  146. continue;
  147. for (MachineBasicBlock::iterator MII = MBB->getFirstTerminator(),
  148. MIIE = MBB->end(); MII != MIIE; ++MII) {
  149. unsigned Opc = MII->getOpcode();
  150. if (Opc == PPC::BDNZ8 || Opc == PPC::BDNZ ||
  151. Opc == PPC::BDZ8 || Opc == PPC::BDZ)
  152. if (!verifyCTRBranch(MBB, MII))
  153. llvm_unreachable("Invalid PPC CTR loop!");
  154. }
  155. }
  156. return false;
  157. }
  158. #endif // NDEBUG