26#define DEBUG_TYPE "ppc-early-ret"
27STATISTIC(NumBCLR,
"Number of early conditional returns");
38 const TargetInstrInfo *TII;
41 bool processBlock(MachineBasicBlock &ReturnMBB) {
48 if (
I == ReturnMBB.
end() ||
49 (
I->getOpcode() != PPC::BLR &&
I->getOpcode() != PPC::BLR8) ||
53 SmallVector<MachineBasicBlock*, 8> PredToRemove;
54 for (MachineBasicBlock *Pred : ReturnMBB.
predecessors()) {
55 bool OtherReference =
false, BlockChanged =
false;
64 if (J->getOpcode() == PPC::B) {
65 if (J->getOperand(0).getMBB() == &ReturnMBB) {
68 MachineInstr *
MI = ReturnMBB.
getParent()->CloneMachineInstr(&*
I);
77 }
else if (J->getOpcode() == PPC::BCC) {
78 if (J->getOperand(2).getMBB() == &ReturnMBB) {
81 MachineInstr *
MI = ReturnMBB.
getParent()->CloneMachineInstr(&*
I);
82 MI->setDesc(TII->get(PPC::BCCLR));
84 .add(J->getOperand(0))
85 .add(J->getOperand(1));
94 }
else if (J->getOpcode() == PPC::BC || J->getOpcode() == PPC::BCn) {
95 if (J->getOperand(1).getMBB() == &ReturnMBB) {
98 MachineInstr *
MI = ReturnMBB.
getParent()->CloneMachineInstr(&*
I);
100 TII->get(J->getOpcode() == PPC::BC ? PPC::BCLR : PPC::BCLRn));
102 .add(J->getOperand(0));
106 K->eraseFromParent();
111 }
else if (J->isBranch()) {
112 if (J->isIndirectBranch()) {
114 OtherReference =
true;
116 for (
unsigned i = 0; i < J->getNumOperands(); ++i)
117 if (J->getOperand(i).isMBB() &&
118 J->getOperand(i).getMBB() == &ReturnMBB)
119 OtherReference =
true;
120 }
else if (!J->isTerminator() && !J->isDebugInstr())
123 if (J == Pred->begin())
129 if (Pred->canFallThrough() && Pred->isLayoutSuccessor(&ReturnMBB))
130 OtherReference =
true;
133 if (!OtherReference && BlockChanged) {
141 for (MachineBasicBlock *
MBB : PredToRemove)
148 MachineBasicBlock &PrevMBB = **ReturnMBB.
pred_begin();
164 bool runOnMachineFunction(MachineFunction &MF)
override {
183 MachineFunctionProperties getRequiredProperties()
const override {
184 return MachineFunctionProperties().setNoVRegs();
187 void getAnalysisUsage(AnalysisUsage &AU)
const override {
194 "PowerPC Early-Return Creation",
false,
false)
196char PPCEarlyReturn::
ID = 0;
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
FunctionPass class - This class is used to implement most global optimizations.
unsigned pred_size() const
LLVM_ABI iterator SkipPHIsLabelsAndDebug(iterator I, Register Reg=Register(), bool SkipPseudoOp=true)
Return the first instruction in MBB after I that is not a PHI, label or debug.
LLVM_ABI bool canFallThrough()
Return true if the block can implicitly transfer control to the block after it by falling off the end...
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
pred_iterator pred_begin()
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< pred_iterator > predecessors()
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 '...
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
void insert(iterator MBBI, MachineBasicBlock *MBB)
void push_back(const T &Elt)
virtual const TargetInstrInfo * getInstrInfo() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
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...
FunctionPass * createPPCEarlyReturnPass()