LLVM  15.0.0git
PPCEarlyReturn.cpp
Go to the documentation of this file.
1 //===------------- PPCEarlyReturn.cpp - Form Early Returns ----------------===//
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 // A pass that form early (predicated) returns. If-conversion handles some of
10 // this, but this pass picks up some remaining cases.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "PPC.h"
16 #include "PPCInstrBuilder.h"
17 #include "PPCInstrInfo.h"
18 #include "PPCMachineFunctionInfo.h"
19 #include "PPCTargetMachine.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/Statistic.h"
27 #include "llvm/MC/MCAsmInfo.h"
28 #include "llvm/MC/TargetRegistry.h"
29 #include "llvm/Support/Debug.h"
32 
33 using namespace llvm;
34 
35 #define DEBUG_TYPE "ppc-early-ret"
36 STATISTIC(NumBCLR, "Number of early conditional returns");
37 STATISTIC(NumBLR, "Number of early returns");
38 
39 namespace {
40  // PPCEarlyReturn pass - For simple functions without epilogue code, move
41  // returns up, and create conditional returns, to avoid unnecessary
42  // branch-to-blr sequences.
43  struct PPCEarlyReturn : public MachineFunctionPass {
44  static char ID;
45  PPCEarlyReturn() : MachineFunctionPass(ID) {
47  }
48 
49  const TargetInstrInfo *TII;
50 
51 protected:
52  bool processBlock(MachineBasicBlock &ReturnMBB) {
53  bool Changed = false;
54 
55  MachineBasicBlock::iterator I = ReturnMBB.begin();
56  I = ReturnMBB.SkipPHIsLabelsAndDebug(I);
57 
58  // The block must be essentially empty except for the blr.
59  if (I == ReturnMBB.end() ||
60  (I->getOpcode() != PPC::BLR && I->getOpcode() != PPC::BLR8) ||
61  I != ReturnMBB.getLastNonDebugInstr())
62  return Changed;
63 
65  for (MachineBasicBlock *Pred : ReturnMBB.predecessors()) {
66  bool OtherReference = false, BlockChanged = false;
67 
68  if (Pred->empty())
69  continue;
70 
71  for (MachineBasicBlock::iterator J = Pred->getLastNonDebugInstr();;) {
72  if (J == Pred->end())
73  break;
74 
75  if (J->getOpcode() == PPC::B) {
76  if (J->getOperand(0).getMBB() == &ReturnMBB) {
77  // This is an unconditional branch to the return. Replace the
78  // branch with a blr.
79  MachineInstr *MI = ReturnMBB.getParent()->CloneMachineInstr(&*I);
80  Pred->insert(J, MI);
81 
83  K->eraseFromParent();
84  BlockChanged = true;
85  ++NumBLR;
86  continue;
87  }
88  } else if (J->getOpcode() == PPC::BCC) {
89  if (J->getOperand(2).getMBB() == &ReturnMBB) {
90  // This is a conditional branch to the return. Replace the branch
91  // with a bclr.
92  MachineInstr *MI = ReturnMBB.getParent()->CloneMachineInstr(&*I);
93  MI->setDesc(TII->get(PPC::BCCLR));
94  MachineInstrBuilder(*ReturnMBB.getParent(), MI)
95  .add(J->getOperand(0))
96  .add(J->getOperand(1));
97  Pred->insert(J, MI);
98 
100  K->eraseFromParent();
101  BlockChanged = true;
102  ++NumBCLR;
103  continue;
104  }
105  } else if (J->getOpcode() == PPC::BC || J->getOpcode() == PPC::BCn) {
106  if (J->getOperand(1).getMBB() == &ReturnMBB) {
107  // This is a conditional branch to the return. Replace the branch
108  // with a bclr.
109  MachineInstr *MI = ReturnMBB.getParent()->CloneMachineInstr(&*I);
110  MI->setDesc(
111  TII->get(J->getOpcode() == PPC::BC ? PPC::BCLR : PPC::BCLRn));
112  MachineInstrBuilder(*ReturnMBB.getParent(), MI)
113  .add(J->getOperand(0));
114  Pred->insert(J, MI);
115 
117  K->eraseFromParent();
118  BlockChanged = true;
119  ++NumBCLR;
120  continue;
121  }
122  } else if (J->isBranch()) {
123  if (J->isIndirectBranch()) {
124  if (ReturnMBB.hasAddressTaken())
125  OtherReference = true;
126  } else
127  for (unsigned i = 0; i < J->getNumOperands(); ++i)
128  if (J->getOperand(i).isMBB() &&
129  J->getOperand(i).getMBB() == &ReturnMBB)
130  OtherReference = true;
131  } else if (!J->isTerminator() && !J->isDebugInstr())
132  break;
133 
134  if (J == Pred->begin())
135  break;
136 
137  --J;
138  }
139 
140  if (Pred->canFallThrough() && Pred->isLayoutSuccessor(&ReturnMBB))
141  OtherReference = true;
142 
143  // Predecessors are stored in a vector and can't be removed here.
144  if (!OtherReference && BlockChanged) {
145  PredToRemove.push_back(Pred);
146  }
147 
148  if (BlockChanged)
149  Changed = true;
150  }
151 
152  for (unsigned i = 0, ie = PredToRemove.size(); i != ie; ++i)
153  PredToRemove[i]->removeSuccessor(&ReturnMBB, true);
154 
155  if (Changed && !ReturnMBB.hasAddressTaken()) {
156  // We now might be able to merge this blr-only block into its
157  // by-layout predecessor.
158  if (ReturnMBB.pred_size() == 1) {
159  MachineBasicBlock &PrevMBB = **ReturnMBB.pred_begin();
160  if (PrevMBB.isLayoutSuccessor(&ReturnMBB) && PrevMBB.canFallThrough()) {
161  // Move the blr into the preceding block.
162  PrevMBB.splice(PrevMBB.end(), &ReturnMBB, I);
163  PrevMBB.removeSuccessor(&ReturnMBB, true);
164  }
165  }
166 
167  if (ReturnMBB.pred_empty())
168  ReturnMBB.eraseFromParent();
169  }
170 
171  return Changed;
172  }
173 
174 public:
175  bool runOnMachineFunction(MachineFunction &MF) override {
176  if (skipFunction(MF.getFunction()))
177  return false;
178 
179  TII = MF.getSubtarget().getInstrInfo();
180 
181  bool Changed = false;
182 
183  // If the function does not have at least two blocks, then there is
184  // nothing to do.
185  if (MF.size() < 2)
186  return Changed;
187 
189  Changed |= processBlock(B);
190 
191  return Changed;
192  }
193 
194  MachineFunctionProperties getRequiredProperties() const override {
197  }
198 
199  void getAnalysisUsage(AnalysisUsage &AU) const override {
201  }
202  };
203 }
204 
205 INITIALIZE_PASS(PPCEarlyReturn, DEBUG_TYPE,
206  "PowerPC Early-Return Creation", false, false)
207 
208 char PPCEarlyReturn::ID = 0;
210 llvm::createPPCEarlyReturnPass() { return new PPCEarlyReturn(); }
i
i
Definition: README.txt:29
llvm::MachineBasicBlock::pred_begin
pred_iterator pred_begin()
Definition: MachineBasicBlock.h:326
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:93
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
PPCInstrBuilder.h
Statistic.h
ErrorHandling.h
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::MachineFunctionProperties
Properties which a MachineFunction may have at a given point in time.
Definition: MachineFunction.h:127
STLExtras.h
llvm::createPPCEarlyReturnPass
FunctionPass * createPPCEarlyReturnPass()
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:103
MachineRegisterInfo.h
llvm::MachineBasicBlock::pred_size
unsigned pred_size() const
Definition: MachineBasicBlock.h:338
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
DEBUG_TYPE
#define DEBUG_TYPE
Definition: PPCEarlyReturn.cpp:35
INITIALIZE_PASS
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:37
llvm::MachineBasicBlock::eraseFromParent
void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
Definition: MachineBasicBlock.cpp:1332
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
llvm::MachineFunction::size
unsigned size() const
Definition: MachineFunction.h:863
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::MachineFunctionProperties::set
MachineFunctionProperties & set(Property P)
Definition: MachineFunction.h:196
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
PPC.h
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::MachineFunctionProperties::Property::NoVRegs
@ NoVRegs
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:656
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:69
llvm::MachineBasicBlock::hasAddressTaken
bool hasAddressTaken() const
Test whether this block is potentially the target of an indirect branch.
Definition: MachineBasicBlock.h:220
llvm::MachineFunction::CloneMachineInstr
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
Definition: MachineFunction.cpp:383
PPCInstrInfo.h
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::make_early_inc_range
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:618
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:263
MachineFunctionPass.h
llvm::MachineBasicBlock::canFallThrough
bool canFallThrough()
Return true if the block can implicitly transfer control to the block after it by falling off the end...
Definition: MachineBasicBlock.cpp:966
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:234
llvm::MachineBasicBlock::predecessors
iterator_range< pred_iterator > predecessors()
Definition: MachineBasicBlock.h:359
llvm::MachineBasicBlock::pred_empty
bool pred_empty() const
Definition: MachineBasicBlock.h:341
llvm::MachineFunction
Definition: MachineFunction.h:257
MCAsmInfo.h
llvm::MachineBasicBlock::splice
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
Definition: MachineBasicBlock.h:982
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:622
llvm::MachineBasicBlock::removeSuccessor
void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
Definition: MachineBasicBlock.cpp:785
MachineFrameInfo.h
llvm::MachineBasicBlock::isLayoutSuccessor
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
Definition: MachineBasicBlock.cpp:913
llvm::initializePPCEarlyReturnPass
void initializePPCEarlyReturnPass(PassRegistry &)
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:278
MachineInstrBuilder.h
PPCMachineFunctionInfo.h
MachineMemOperand.h
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::MachineBasicBlock::SkipPHIsLabelsAndDebug
iterator SkipPHIsLabelsAndDebug(iterator I, bool SkipPseudoOp=true)
Return the first instruction in MBB after I that is not a PHI, label or debug.
Definition: MachineBasicBlock.cpp:221
raw_ostream.h
PPCPredicates.h
llvm::MachineInstrBundleIterator< MachineInstr >
TargetRegistry.h
Debug.h
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:280
PPCTargetMachine.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38