1 //===------------- PPCEarlyReturn.cpp - Form Early Returns ----------------===//
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
7 //===----------------------------------------------------------------------===//
9 // A pass that form early (predicated) returns. If-conversion handles some of
10 // this, but this pass picks up some remaining cases.
12 //===----------------------------------------------------------------------===//
14 #include "MCTargetDesc/PPCPredicates.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"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineMemOperand.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/MC/MCAsmInfo.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include "llvm/Support/TargetRegistry.h"
31 #include "llvm/Support/raw_ostream.h"
35 #define DEBUG_TYPE "ppc-early-ret"
36 STATISTIC(NumBCLR
, "Number of early conditional returns");
37 STATISTIC(NumBLR
, "Number of early returns");
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
{
45 PPCEarlyReturn() : MachineFunctionPass(ID
) {
46 initializePPCEarlyReturnPass(*PassRegistry::getPassRegistry());
49 const TargetInstrInfo
*TII
;
52 bool processBlock(MachineBasicBlock
&ReturnMBB
) {
55 MachineBasicBlock::iterator I
= ReturnMBB
.begin();
56 I
= ReturnMBB
.SkipPHIsLabelsAndDebug(I
);
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())
64 SmallVector
<MachineBasicBlock
*, 8> PredToRemove
;
65 for (MachineBasicBlock::pred_iterator PI
= ReturnMBB
.pred_begin(),
66 PIE
= ReturnMBB
.pred_end(); PI
!= PIE
; ++PI
) {
67 bool OtherReference
= false, BlockChanged
= false;
72 for (MachineBasicBlock::iterator J
= (*PI
)->getLastNonDebugInstr();;) {
73 if (J
== (*PI
)->end())
76 if (J
->getOpcode() == PPC::B
) {
77 if (J
->getOperand(0).getMBB() == &ReturnMBB
) {
78 // This is an unconditional branch to the return. Replace the
80 MachineInstr
*MI
= ReturnMBB
.getParent()->CloneMachineInstr(&*I
);
83 MachineBasicBlock::iterator K
= J
--;
89 } else if (J
->getOpcode() == PPC::BCC
) {
90 if (J
->getOperand(2).getMBB() == &ReturnMBB
) {
91 // This is a conditional branch to the return. Replace the branch
93 MachineInstr
*MI
= ReturnMBB
.getParent()->CloneMachineInstr(&*I
);
94 MI
->setDesc(TII
->get(PPC::BCCLR
));
95 MachineInstrBuilder(*ReturnMBB
.getParent(), MI
)
96 .add(J
->getOperand(0))
97 .add(J
->getOperand(1));
100 MachineBasicBlock::iterator K
= J
--;
101 K
->eraseFromParent();
106 } else if (J
->getOpcode() == PPC::BC
|| J
->getOpcode() == PPC::BCn
) {
107 if (J
->getOperand(1).getMBB() == &ReturnMBB
) {
108 // This is a conditional branch to the return. Replace the branch
110 MachineInstr
*MI
= ReturnMBB
.getParent()->CloneMachineInstr(&*I
);
112 TII
->get(J
->getOpcode() == PPC::BC
? PPC::BCLR
: PPC::BCLRn
));
113 MachineInstrBuilder(*ReturnMBB
.getParent(), MI
)
114 .add(J
->getOperand(0));
115 (*PI
)->insert(J
, MI
);
117 MachineBasicBlock::iterator K
= J
--;
118 K
->eraseFromParent();
123 } else if (J
->isBranch()) {
124 if (J
->isIndirectBranch()) {
125 if (ReturnMBB
.hasAddressTaken())
126 OtherReference
= true;
128 for (unsigned i
= 0; i
< J
->getNumOperands(); ++i
)
129 if (J
->getOperand(i
).isMBB() &&
130 J
->getOperand(i
).getMBB() == &ReturnMBB
)
131 OtherReference
= true;
132 } else if (!J
->isTerminator() && !J
->isDebugInstr())
135 if (J
== (*PI
)->begin())
141 if ((*PI
)->canFallThrough() && (*PI
)->isLayoutSuccessor(&ReturnMBB
))
142 OtherReference
= true;
144 // Predecessors are stored in a vector and can't be removed here.
145 if (!OtherReference
&& BlockChanged
) {
146 PredToRemove
.push_back(*PI
);
153 for (unsigned i
= 0, ie
= PredToRemove
.size(); i
!= ie
; ++i
)
154 PredToRemove
[i
]->removeSuccessor(&ReturnMBB
, true);
156 if (Changed
&& !ReturnMBB
.hasAddressTaken()) {
157 // We now might be able to merge this blr-only block into its
158 // by-layout predecessor.
159 if (ReturnMBB
.pred_size() == 1) {
160 MachineBasicBlock
&PrevMBB
= **ReturnMBB
.pred_begin();
161 if (PrevMBB
.isLayoutSuccessor(&ReturnMBB
) && PrevMBB
.canFallThrough()) {
162 // Move the blr into the preceding block.
163 PrevMBB
.splice(PrevMBB
.end(), &ReturnMBB
, I
);
164 PrevMBB
.removeSuccessor(&ReturnMBB
, true);
168 if (ReturnMBB
.pred_empty())
169 ReturnMBB
.eraseFromParent();
176 bool runOnMachineFunction(MachineFunction
&MF
) override
{
177 if (skipFunction(MF
.getFunction()))
180 TII
= MF
.getSubtarget().getInstrInfo();
182 bool Changed
= false;
184 // If the function does not have at least two blocks, then there is
189 // We can't use a range-based for loop due to clobbering the iterator.
190 for (MachineFunction::iterator I
= MF
.begin(), E
= MF
.end(); I
!= E
;) {
191 MachineBasicBlock
&B
= *I
++;
192 Changed
|= processBlock(B
);
198 MachineFunctionProperties
getRequiredProperties() const override
{
199 return MachineFunctionProperties().set(
200 MachineFunctionProperties::Property::NoVRegs
);
203 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
204 MachineFunctionPass::getAnalysisUsage(AU
);
209 INITIALIZE_PASS(PPCEarlyReturn
, DEBUG_TYPE
,
210 "PowerPC Early-Return Creation", false, false)
212 char PPCEarlyReturn::ID
= 0;
214 llvm::createPPCEarlyReturnPass() { return new PPCEarlyReturn(); }