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 (const MachineOperand &MO : MI.operands()) {
85  if (MO.isReg()) {
86  if (MO.isDef() && (MO.getReg() == PPC::CTR || MO.getReg() == PPC::CTR8))
87  return true;
88  } else if (MO.isRegMask()) {
89  if (MO.clobbersPhysReg(PPC::CTR) || MO.clobbersPhysReg(PPC::CTR8))
90  return true;
91  }
92  }
93 
94  return false;
95 }
96 
102  bool CheckPreds;
103 
104  if (I == MBB->begin()) {
105  Visited.insert(MBB);
106  goto queue_preds;
107  } else
108  --I;
109 
110 check_block:
111  Visited.insert(MBB);
112  if (I == MBB->end())
113  goto queue_preds;
114 
115  CheckPreds = true;
116  for (MachineBasicBlock::iterator IE = MBB->begin();; --I) {
117  unsigned Opc = I->getOpcode();
118  if (Opc == PPC::MTCTRloop || Opc == PPC::MTCTR8loop) {
119  CheckPreds = false;
120  break;
121  }
122 
123  if (I != BI && clobbersCTR(*I)) {
124  LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " (" << MBB->getFullName()
125  << ") instruction " << *I
126  << " clobbers CTR, invalidating "
127  << printMBBReference(*BI->getParent()) << " ("
128  << BI->getParent()->getFullName() << ") instruction "
129  << *BI << "\n");
130  return false;
131  }
132 
133  if (I == IE)
134  break;
135  }
136 
137  if (!CheckPreds && Preds.empty())
138  return true;
139 
140  if (CheckPreds) {
141 queue_preds:
143  LLVM_DEBUG(dbgs() << "Unable to find a MTCTR instruction for "
144  << printMBBReference(*BI->getParent()) << " ("
145  << BI->getParent()->getFullName() << ") instruction "
146  << *BI << "\n");
147  return false;
148  }
149 
150  append_range(Preds, MBB->predecessors());
151  }
152 
153  do {
154  MBB = Preds.pop_back_val();
155  if (!Visited.count(MBB)) {
157  goto check_block;
158  }
159  } while (!Preds.empty());
160 
161  return true;
162 }
163 
164 bool PPCCTRLoopsVerify::runOnMachineFunction(MachineFunction &MF) {
165  MDT = &getAnalysis<MachineDominatorTree>();
166 
167  // Verify that all bdnz/bdz instructions are dominated by a loop mtctr before
168  // any other instructions that might clobber the ctr register.
169  for (MachineBasicBlock &MBB : MF) {
170  if (!MDT->isReachableFromEntry(&MBB))
171  continue;
172 
174  MIIE = MBB.end(); MII != MIIE; ++MII) {
175  unsigned Opc = MII->getOpcode();
176  if (Opc == PPC::BDNZ8 || Opc == PPC::BDNZ ||
177  Opc == PPC::BDZ8 || Opc == PPC::BDZ)
178  if (!verifyCTRBranch(&MBB, MII))
179  llvm_unreachable("Invalid PPC CTR loop!");
180  }
181  }
182 
183  return false;
184 }
185 #endif // NDEBUG
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
MachineInstr.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::PPCISD::BDNZ
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
Definition: PPCISelLowering.h:296
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:1177
verifyCTRBranch
static bool verifyCTRBranch(MachineBasicBlock *MBB, MachineBasicBlock::iterator I)
Definition: PPCCTRLoops.cpp:97
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:644
PPCMCTargetDesc.h
llvm::createPPCCTRLoopsVerify
FunctionPass * createPPCCTRLoopsVerify()
Definition: PPCCTRLoops.cpp:79
PassRegistry.h
loops
loops
Definition: LoopInfo.cpp:1176
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:297
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:823
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
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::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
I
#define I(x, y, z)
Definition: MD5.cpp:58
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:266
MachineFunctionPass.h
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:229
llvm::MachineBasicBlock::predecessors
iterator_range< pred_iterator > predecessors()
Definition: MachineBasicBlock.h:353
llvm::MachineFunction
Definition: MachineFunction.h:241
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:241
llvm::MachineBasicBlock::getFullName
std::string getFullName() const
Return a formatted string to identify this block and its parent function.
Definition: MachineBasicBlock.cpp:321
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
MachineInstrBundleIterator.h
llvm::append_range
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
Definition: STLExtras.h:1846
verify
ppc ctr loops verify
Definition: PPCCTRLoops.cpp:76
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:272
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:46
MachineFunction.h
llvm::MachineInstrBundleIterator< MachineInstr >
InitializePasses.h
Debug.h
ilist_iterator.h
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:274
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:38