1 //===------------- PPCEarlyReturn.cpp - Form Early Returns ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // A pass that form early (predicated) returns. If-conversion handles some of
11 // this, but this pass picks up some remaining cases.
13 //===----------------------------------------------------------------------===//
15 #include "PPCInstrInfo.h"
16 #include "MCTargetDesc/PPCPredicates.h"
18 #include "PPCInstrBuilder.h"
19 #include "PPCMachineFunctionInfo.h"
20 #include "PPCTargetMachine.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/Statistic.h"
23 #include "llvm/CodeGen/MachineFrameInfo.h"
24 #include "llvm/CodeGen/MachineFunctionPass.h"
25 #include "llvm/CodeGen/MachineInstrBuilder.h"
26 #include "llvm/CodeGen/MachineMemOperand.h"
27 #include "llvm/CodeGen/MachineRegisterInfo.h"
28 #include "llvm/MC/MCAsmInfo.h"
29 #include "llvm/Support/CommandLine.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "ppc-early-ret"
38 STATISTIC(NumBCLR, "Number of early conditional returns");
39 STATISTIC(NumBLR, "Number of early returns");
42 void initializePPCEarlyReturnPass(PassRegistry&);
46 // PPCEarlyReturn pass - For simple functions without epilogue code, move
47 // returns up, and create conditional returns, to avoid unnecessary
48 // branch-to-blr sequences.
49 struct PPCEarlyReturn : public MachineFunctionPass {
51 PPCEarlyReturn() : MachineFunctionPass(ID) {
52 initializePPCEarlyReturnPass(*PassRegistry::getPassRegistry());
55 const TargetInstrInfo *TII;
58 bool processBlock(MachineBasicBlock &ReturnMBB) {
61 MachineBasicBlock::iterator I = ReturnMBB.begin();
62 I = ReturnMBB.SkipPHIsAndLabels(I);
64 // The block must be essentially empty except for the blr.
65 if (I == ReturnMBB.end() ||
66 (I->getOpcode() != PPC::BLR && I->getOpcode() != PPC::BLR8) ||
67 I != ReturnMBB.getLastNonDebugInstr())
70 SmallVector<MachineBasicBlock*, 8> PredToRemove;
71 for (MachineBasicBlock::pred_iterator PI = ReturnMBB.pred_begin(),
72 PIE = ReturnMBB.pred_end(); PI != PIE; ++PI) {
73 bool OtherReference = false, BlockChanged = false;
78 for (MachineBasicBlock::iterator J = (*PI)->getLastNonDebugInstr();;) {
79 if (J == (*PI)->end())
82 MachineInstrBuilder MIB;
83 if (J->getOpcode() == PPC::B) {
84 if (J->getOperand(0).getMBB() == &ReturnMBB) {
85 // This is an unconditional branch to the return. Replace the
88 BuildMI(**PI, J, J->getDebugLoc(), TII->get(I->getOpcode()));
89 MIB.copyImplicitOps(I);
90 MachineBasicBlock::iterator K = J--;
96 } else if (J->getOpcode() == PPC::BCC) {
97 if (J->getOperand(2).getMBB() == &ReturnMBB) {
98 // This is a conditional branch to the return. Replace the branch
100 MIB = BuildMI(**PI, J, J->getDebugLoc(), TII->get(PPC::BCCLR))
101 .addImm(J->getOperand(0).getImm())
102 .addReg(J->getOperand(1).getReg());
103 MIB.copyImplicitOps(I);
104 MachineBasicBlock::iterator K = J--;
105 K->eraseFromParent();
110 } else if (J->getOpcode() == PPC::BC || J->getOpcode() == PPC::BCn) {
111 if (J->getOperand(1).getMBB() == &ReturnMBB) {
112 // This is a conditional branch to the return. Replace the branch
114 MIB = BuildMI(**PI, J, J->getDebugLoc(),
115 TII->get(J->getOpcode() == PPC::BC ?
116 PPC::BCLR : PPC::BCLRn))
117 .addReg(J->getOperand(0).getReg());
118 MIB.copyImplicitOps(I);
119 MachineBasicBlock::iterator K = J--;
120 K->eraseFromParent();
125 } else if (J->isBranch()) {
126 if (J->isIndirectBranch()) {
127 if (ReturnMBB.hasAddressTaken())
128 OtherReference = true;
130 for (unsigned i = 0; i < J->getNumOperands(); ++i)
131 if (J->getOperand(i).isMBB() &&
132 J->getOperand(i).getMBB() == &ReturnMBB)
133 OtherReference = true;
134 } else if (!J->isTerminator() && !J->isDebugValue())
137 if (J == (*PI)->begin())
143 if ((*PI)->canFallThrough() && (*PI)->isLayoutSuccessor(&ReturnMBB))
144 OtherReference = true;
146 // Predecessors are stored in a vector and can't be removed here.
147 if (!OtherReference && BlockChanged) {
148 PredToRemove.push_back(*PI);
155 for (unsigned i = 0, ie = PredToRemove.size(); i != ie; ++i)
156 PredToRemove[i]->removeSuccessor(&ReturnMBB);
158 if (Changed && !ReturnMBB.hasAddressTaken()) {
159 // We now might be able to merge this blr-only block into its
160 // by-layout predecessor.
161 if (ReturnMBB.pred_size() == 1) {
162 MachineBasicBlock &PrevMBB = **ReturnMBB.pred_begin();
163 if (PrevMBB.isLayoutSuccessor(&ReturnMBB) && PrevMBB.canFallThrough()) {
164 // Move the blr into the preceding block.
165 PrevMBB.splice(PrevMBB.end(), &ReturnMBB, I);
166 PrevMBB.removeSuccessor(&ReturnMBB);
170 if (ReturnMBB.pred_empty())
171 ReturnMBB.eraseFromParent();
178 bool runOnMachineFunction(MachineFunction &MF) override {
179 TII = MF.getSubtarget().getInstrInfo();
181 bool Changed = false;
183 // If the function does not have at least two blocks, then there is
188 for (MachineFunction::iterator I = MF.begin(); I != MF.end();) {
189 MachineBasicBlock &B = *I++;
197 void getAnalysisUsage(AnalysisUsage &AU) const override {
198 MachineFunctionPass::getAnalysisUsage(AU);
203 INITIALIZE_PASS(PPCEarlyReturn, DEBUG_TYPE,
204 "PowerPC Early-Return Creation", false, false)
206 char PPCEarlyReturn::ID = 0;
208 llvm::createPPCEarlyReturnPass() { return new PPCEarlyReturn(); }