LLVM  14.0.0git
PPCCTRLoops.cpp
Go to the documentation of this file.
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 
14 // CTR loops are produced by the HardwareLoops pass and this pass is simply a
15 // verification that no invalid CTR loops are produced. As such, it isn't
16 // something that needs to be run (or even defined) for Release builds so the
17 // entire file is guarded by NDEBUG.
18 #ifndef NDEBUG
19 #include <vector>
20 
22 #include "PPC.h"
23 #include "llvm/ADT/SmallSet.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/ADT/StringRef.h"
34 #include "llvm/CodeGen/Register.h"
35 #include "llvm/InitializePasses.h"
36 #include "llvm/Pass.h"
37 #include "llvm/PassRegistry.h"
38 #include "llvm/Support/CodeGen.h"
39 #include "llvm/Support/Debug.h"
42 #include "llvm/Support/Printable.h"
44 
45 using namespace llvm;
46 
47 #define DEBUG_TYPE "ppc-ctrloops-verify"
48 
49 namespace {
50 
51  struct PPCCTRLoopsVerify : public MachineFunctionPass {
52  public:
53  static char ID;
54 
55  PPCCTRLoopsVerify() : MachineFunctionPass(ID) {
57  }
58 
59  void getAnalysisUsage(AnalysisUsage &AU) const override {
62  }
63 
64  bool runOnMachineFunction(MachineFunction &MF) override;
65 
66  private:
68  };
69 
70  char PPCCTRLoopsVerify::ID = 0;
71 } // end anonymous namespace
72 
73 INITIALIZE_PASS_BEGIN(PPCCTRLoopsVerify, "ppc-ctr-loops-verify",
74  "PowerPC CTR Loops Verify", false, false)
76 INITIALIZE_PASS_END(PPCCTRLoopsVerify, "ppc-ctr-loops-verify",
77  "PowerPC CTR Loops Verify", false, false)
78 
80  return new PPCCTRLoopsVerify();
81 }
82 
83 static bool clobbersCTR(const MachineInstr &MI) {
84  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
85  const MachineOperand &MO = MI.getOperand(i);
86  if (MO.isReg()) {
87  if (MO.isDef() && (MO.getReg() == PPC::CTR || MO.getReg() == PPC::CTR8))
88  return true;
89  } else if (MO.isRegMask()) {
90  if (MO.clobbersPhysReg(PPC::CTR) || MO.clobbersPhysReg(PPC::CTR8))
91  return true;
92  }
93  }
94 
95  return false;
96 }
97 
103  bool CheckPreds;
104 
105  if (I == MBB->begin()) {
106  Visited.insert(MBB);
107  goto queue_preds;
108  } else
109  --I;
110 
111 check_block:
112  Visited.insert(MBB);
113  if (I == MBB->end())
114  goto queue_preds;
115 
116  CheckPreds = true;
117  for (MachineBasicBlock::iterator IE = MBB->begin();; --I) {
118  unsigned Opc = I->getOpcode();
119  if (Opc == PPC::MTCTRloop || Opc == PPC::MTCTR8loop) {
120  CheckPreds = false;
121  break;
122  }
123 
124  if (I != BI && clobbersCTR(*I)) {
125  LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " (" << MBB->getFullName()
126  << ") instruction " << *I
127  << " clobbers CTR, invalidating "
128  << printMBBReference(*BI->getParent()) << " ("
129  << BI->getParent()->getFullName() << ") instruction "
130  << *BI << "\n");
131  return false;
132  }
133 
134  if (I == IE)
135  break;
136  }
137 
138  if (!CheckPreds && Preds.empty())
139  return true;
140 
141  if (CheckPreds) {
142 queue_preds:
144  LLVM_DEBUG(dbgs() << "Unable to find a MTCTR instruction for "
145  << printMBBReference(*BI->getParent()) << " ("
146  << BI->getParent()->getFullName() << ") instruction "
147  << *BI << "\n");
148  return false;
149  }
150 
151  append_range(Preds, MBB->predecessors());
152  }
153 
154  do {
155  MBB = Preds.pop_back_val();
156  if (!Visited.count(MBB)) {
158  goto check_block;
159  }
160  } while (!Preds.empty());
161 
162  return true;
163 }
164 
165 bool PPCCTRLoopsVerify::runOnMachineFunction(MachineFunction &MF) {
166  MDT = &getAnalysis<MachineDominatorTree>();
167 
168  // Verify that all bdnz/bdz instructions are dominated by a loop mtctr before
169  // any other instructions that might clobber the ctr register.
170  for (MachineFunction::iterator I = MF.begin(), IE = MF.end();
171  I != IE; ++I) {
172  MachineBasicBlock *MBB = &*I;
173  if (!MDT->isReachableFromEntry(MBB))
174  continue;
175 
177  MIIE = MBB->end(); MII != MIIE; ++MII) {
178  unsigned Opc = MII->getOpcode();
179  if (Opc == PPC::BDNZ8 || Opc == PPC::BDNZ ||
180  Opc == PPC::BDZ8 || Opc == PPC::BDZ)
181  if (!verifyCTRBranch(MBB, MII))
182  llvm_unreachable("Invalid PPC CTR loop!");
183  }
184  }
185 
186  return false;
187 }
188 #endif // NDEBUG
i
i
Definition: README.txt:29
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
MachineInstr.h
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::PPCISD::BDNZ
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
Definition: PPCISelLowering.h:288
Printable.h
StringRef.h
Pass.h
Loops
Hexagon Hardware Loops
Definition: HexagonHardwareLoops.cpp:372
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::MachineFunction::end
iterator end()
Definition: MachineFunction.h:810
verifyCTRBranch
static bool verifyCTRBranch(MachineBasicBlock *MBB, MachineBasicBlock::iterator I)
Definition: PPCCTRLoops.cpp:98
llvm::printMBBReference
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Definition: MachineBasicBlock.cpp:119
clobbersCTR
static bool clobbersCTR(const MachineInstr &MI)
Definition: PPCCTRLoops.cpp:83
ErrorHandling.h
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
MachineBasicBlock.h
llvm::SmallSet
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
PPCMCTargetDesc.h
llvm::createPPCCTRLoopsVerify
FunctionPass * createPPCCTRLoopsVerify()
Definition: PPCCTRLoops.cpp:79
PassRegistry.h
loops
loops
Definition: LoopInfo.cpp:1175
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::PPCISD::BDZ
@ BDZ
Definition: PPCISelLowering.h:289
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
false
Definition: StackSlotColoring.cpp:142
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
PPC.h
llvm::MachineFunction::begin
iterator begin()
Definition: MachineFunction.h:808
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::ARM_PROC::IE
@ IE
Definition: ARMBaseInfo.h:27
llvm::MachineOperand::clobbersPhysReg
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
Definition: MachineOperand.h:617
Verify
ppc ctr loops PowerPC CTR Loops Verify
Definition: PPCCTRLoops.cpp:77
llvm::SmallSet::count
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition: SmallSet.h:164
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:321
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::MachineBasicBlock::getLastNonDebugInstr
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
Definition: MachineBasicBlock.cpp:267
MachineFunctionPass.h
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:225
llvm::MachineOperand::isRegMask
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
Definition: MachineOperand.h:345
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::MachineBasicBlock::predecessors
iterator_range< pred_iterator > predecessors()
Definition: MachineBasicBlock.h:349
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::initializePPCCTRLoopsVerifyPass
void initializePPCCTRLoopsVerifyPass(PassRegistry &)
llvm::MachineBasicBlock::getFirstTerminator
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Definition: MachineBasicBlock.cpp:242
llvm::MachineBasicBlock::getFullName
std::string getFullName() const
Return a formatted string to identify this block and its parent function.
Definition: MachineBasicBlock.cpp:322
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
MachineInstrBundleIterator.h
llvm::append_range
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
Definition: STLExtras.h:1748
verify
ppc ctr loops verify
Definition: PPCCTRLoops.cpp:76
llvm::MachineOperand::isDef
bool isDef() const
Definition: MachineOperand.h:375
llvm::SmallSet::insert
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:180
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::ilist_iterator
Iterator for intrusive lists based on ilist_node.
Definition: ilist_iterator.h:57
ppc
Unrolling by would eliminate the &in both leading to a net reduction in code size The resultant code would then also be suitable for exit value computation We miss a bunch of rotate opportunities on various including ppc
Definition: README.txt:567
GenericDomTreeConstruction.h
CodeGen.h
SmallVector.h
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
MachineOperand.h
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
Register.h
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
raw_ostream.h
llvm::MachineDominatorTree
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Definition: MachineDominators.h:45
MachineFunction.h
llvm::MachineInstrBundleIterator< MachineInstr >
InitializePasses.h
Debug.h
ilist_iterator.h
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(PPCCTRLoopsVerify, "ppc-ctr-loops-verify", "PowerPC CTR Loops Verify", false, false) INITIALIZE_PASS_END(PPCCTRLoopsVerify
MachineDominators.h
SmallSet.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37