1 //===--------- PPCPreEmitPeephole.cpp - Late peephole optimizations -------===//
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 pre-emit peephole for catching opportunities introduced by late passes such
10 // as MachineBlockPlacement.
12 //===----------------------------------------------------------------------===//
15 #include "PPCInstrInfo.h"
16 #include "PPCSubtarget.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/Statistic.h"
19 #include "llvm/CodeGen/LivePhysRegs.h"
20 #include "llvm/CodeGen/MachineBasicBlock.h"
21 #include "llvm/CodeGen/MachineFunctionPass.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/Support/CommandLine.h"
25 #include "llvm/ADT/Statistic.h"
26 #include "llvm/Support/Debug.h"
30 #define DEBUG_TYPE "ppc-pre-emit-peephole"
32 STATISTIC(NumRRConvertedInPreEmit
,
33 "Number of r+r instructions converted to r+i in pre-emit peephole");
34 STATISTIC(NumRemovedInPreEmit
,
35 "Number of instructions deleted in pre-emit peephole");
36 STATISTIC(NumberOfSelfCopies
,
37 "Number of self copy instructions eliminated");
40 RunPreEmitPeephole("ppc-late-peephole", cl::Hidden
, cl::init(true),
41 cl::desc("Run pre-emit peephole optimizations."));
44 class PPCPreEmitPeephole
: public MachineFunctionPass
{
47 PPCPreEmitPeephole() : MachineFunctionPass(ID
) {
48 initializePPCPreEmitPeepholePass(*PassRegistry::getPassRegistry());
51 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
52 MachineFunctionPass::getAnalysisUsage(AU
);
55 MachineFunctionProperties
getRequiredProperties() const override
{
56 return MachineFunctionProperties().set(
57 MachineFunctionProperties::Property::NoVRegs
);
60 bool runOnMachineFunction(MachineFunction
&MF
) override
{
61 if (skipFunction(MF
.getFunction()) || !RunPreEmitPeephole
)
64 const PPCInstrInfo
*TII
= MF
.getSubtarget
<PPCSubtarget
>().getInstrInfo();
65 const TargetRegisterInfo
*TRI
= MF
.getSubtarget().getRegisterInfo();
66 SmallVector
<MachineInstr
*, 4> InstrsToErase
;
67 for (MachineBasicBlock
&MBB
: MF
) {
68 for (MachineInstr
&MI
: MBB
) {
69 unsigned Opc
= MI
.getOpcode();
70 // Detect self copies - these can result from running AADB.
71 if (PPCInstrInfo::isSameClassPhysRegCopy(Opc
)) {
72 const MCInstrDesc
&MCID
= TII
->get(Opc
);
73 if (MCID
.getNumOperands() == 3 &&
74 MI
.getOperand(0).getReg() == MI
.getOperand(1).getReg() &&
75 MI
.getOperand(0).getReg() == MI
.getOperand(2).getReg()) {
77 LLVM_DEBUG(dbgs() << "Deleting self-copy instruction: ");
78 LLVM_DEBUG(MI
.dump());
79 InstrsToErase
.push_back(&MI
);
82 else if (MCID
.getNumOperands() == 2 &&
83 MI
.getOperand(0).getReg() == MI
.getOperand(1).getReg()) {
85 LLVM_DEBUG(dbgs() << "Deleting self-copy instruction: ");
86 LLVM_DEBUG(MI
.dump());
87 InstrsToErase
.push_back(&MI
);
91 MachineInstr
*DefMIToErase
= nullptr;
92 if (TII
->convertToImmediateForm(MI
, &DefMIToErase
)) {
94 NumRRConvertedInPreEmit
++;
95 LLVM_DEBUG(dbgs() << "Converted instruction to imm form: ");
96 LLVM_DEBUG(MI
.dump());
98 InstrsToErase
.push_back(DefMIToErase
);
103 // Eliminate conditional branch based on a constant CR bit by
104 // CRSET or CRUNSET. We eliminate the conditional branch or
105 // convert it into an unconditional branch. Also, if the CR bit
106 // is not used by other instructions, we eliminate CRSET as well.
107 auto I
= MBB
.getFirstInstrTerminator();
108 if (I
== MBB
.instr_end())
110 MachineInstr
*Br
= &*I
;
111 if (Br
->getOpcode() != PPC::BC
&& Br
->getOpcode() != PPC::BCn
)
113 MachineInstr
*CRSetMI
= nullptr;
114 unsigned CRBit
= Br
->getOperand(0).getReg();
115 unsigned CRReg
= getCRFromCRBit(CRBit
);
116 bool SeenUse
= false;
117 MachineBasicBlock::reverse_iterator It
= Br
, Er
= MBB
.rend();
118 for (It
++; It
!= Er
; It
++) {
119 if (It
->modifiesRegister(CRBit
, TRI
)) {
120 if ((It
->getOpcode() == PPC::CRUNSET
||
121 It
->getOpcode() == PPC::CRSET
) &&
122 It
->getOperand(0).getReg() == CRBit
)
126 if (It
->readsRegister(CRBit
, TRI
))
129 if (!CRSetMI
) continue;
131 unsigned CRSetOp
= CRSetMI
->getOpcode();
132 if ((Br
->getOpcode() == PPC::BCn
&& CRSetOp
== PPC::CRSET
) ||
133 (Br
->getOpcode() == PPC::BC
&& CRSetOp
== PPC::CRUNSET
)) {
134 // Remove this branch since it cannot be taken.
135 InstrsToErase
.push_back(Br
);
136 MBB
.removeSuccessor(Br
->getOperand(1).getMBB());
139 // This conditional branch is always taken. So, remove all branches
140 // and insert an unconditional branch to the destination of this.
141 MachineBasicBlock::iterator It
= Br
, Er
= MBB
.end();
142 for (; It
!= Er
; It
++) {
143 if (It
->isDebugInstr()) continue;
144 assert(It
->isTerminator() && "Non-terminator after a terminator");
145 InstrsToErase
.push_back(&*It
);
147 if (!MBB
.isLayoutSuccessor(Br
->getOperand(1).getMBB())) {
148 ArrayRef
<MachineOperand
> NoCond
;
149 TII
->insertBranch(MBB
, Br
->getOperand(1).getMBB(), nullptr,
150 NoCond
, Br
->getDebugLoc());
152 for (auto &Succ
: MBB
.successors())
153 if (Succ
!= Br
->getOperand(1).getMBB()) {
154 MBB
.removeSuccessor(Succ
);
159 // If the CRBit is not used by another instruction, we can eliminate
160 // CRSET/CRUNSET instruction.
162 // We need to check use of the CRBit in successors.
163 for (auto &SuccMBB
: MBB
.successors())
164 if (SuccMBB
->isLiveIn(CRBit
) || SuccMBB
->isLiveIn(CRReg
)) {
169 InstrsToErase
.push_back(CRSetMI
);
172 for (MachineInstr
*MI
: InstrsToErase
) {
173 LLVM_DEBUG(dbgs() << "PPC pre-emit peephole: erasing instruction: ");
174 LLVM_DEBUG(MI
->dump());
175 MI
->eraseFromParent();
176 NumRemovedInPreEmit
++;
183 INITIALIZE_PASS(PPCPreEmitPeephole
, DEBUG_TYPE
, "PowerPC Pre-Emit Peephole",
185 char PPCPreEmitPeephole::ID
= 0;
187 FunctionPass
*llvm::createPPCPreEmitPeepholePass() {
188 return new PPCPreEmitPeephole();