1 //===--------- PPCPreEmitPeephole.cpp - Late peephole optimizations -------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // A pre-emit peephole for catching opportunities introduced by late passes such
11 // as MachineBlockPlacement.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "PPC.h"
16 #include "PPCInstrInfo.h"
17 #include "PPCSubtarget.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/Statistic.h"
20 #include "llvm/CodeGen/LivePhysRegs.h"
21 #include "llvm/CodeGen/MachineBasicBlock.h"
22 #include "llvm/CodeGen/MachineFunctionPass.h"
23 #include "llvm/CodeGen/MachineInstrBuilder.h"
24 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/ADT/Statistic.h"
27 #include "llvm/Support/Debug.h"
28
29 using namespace llvm;
30
31 #define DEBUG_TYPE "ppc-pre-emit-peephole"
32
33 STATISTIC(NumRRConvertedInPreEmit,
34 "Number of r+r instructions converted to r+i in pre-emit peephole");
35 STATISTIC(NumRemovedInPreEmit,
36 "Number of instructions deleted in pre-emit peephole");
37 STATISTIC(NumberOfSelfCopies,
38 "Number of self copy instructions eliminated");
39
40 static cl::opt<bool>
41 RunPreEmitPeephole("ppc-late-peephole", cl::Hidden, cl::init(true),
42 cl::desc("Run pre-emit peephole optimizations."));
43
44 namespace {
45 class PPCPreEmitPeephole : public MachineFunctionPass {
46 public:
47 static char ID;
PPCPreEmitPeephole()48 PPCPreEmitPeephole() : MachineFunctionPass(ID) {
49 initializePPCPreEmitPeepholePass(*PassRegistry::getPassRegistry());
50 }
51
getAnalysisUsage(AnalysisUsage & AU) const52 void getAnalysisUsage(AnalysisUsage &AU) const override {
53 MachineFunctionPass::getAnalysisUsage(AU);
54 }
55
getRequiredProperties() const56 MachineFunctionProperties getRequiredProperties() const override {
57 return MachineFunctionProperties().set(
58 MachineFunctionProperties::Property::NoVRegs);
59 }
60
runOnMachineFunction(MachineFunction & MF)61 bool runOnMachineFunction(MachineFunction &MF) override {
62 if (skipFunction(MF.getFunction()) || !RunPreEmitPeephole)
63 return false;
64 bool Changed = false;
65 const PPCInstrInfo *TII = MF.getSubtarget<PPCSubtarget>().getInstrInfo();
66 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
67 SmallVector<MachineInstr *, 4> InstrsToErase;
68 for (MachineBasicBlock &MBB : MF) {
69 for (MachineInstr &MI : MBB) {
70 unsigned Opc = MI.getOpcode();
71 // Detect self copies - these can result from running AADB.
72 if (PPCInstrInfo::isSameClassPhysRegCopy(Opc)) {
73 const MCInstrDesc &MCID = TII->get(Opc);
74 if (MCID.getNumOperands() == 3 &&
75 MI.getOperand(0).getReg() == MI.getOperand(1).getReg() &&
76 MI.getOperand(0).getReg() == MI.getOperand(2).getReg()) {
77 NumberOfSelfCopies++;
78 LLVM_DEBUG(dbgs() << "Deleting self-copy instruction: ");
79 LLVM_DEBUG(MI.dump());
80 InstrsToErase.push_back(&MI);
81 continue;
82 }
83 else if (MCID.getNumOperands() == 2 &&
84 MI.getOperand(0).getReg() == MI.getOperand(1).getReg()) {
85 NumberOfSelfCopies++;
86 LLVM_DEBUG(dbgs() << "Deleting self-copy instruction: ");
87 LLVM_DEBUG(MI.dump());
88 InstrsToErase.push_back(&MI);
89 continue;
90 }
91 }
92 MachineInstr *DefMIToErase = nullptr;
93 if (TII->convertToImmediateForm(MI, &DefMIToErase)) {
94 Changed = true;
95 NumRRConvertedInPreEmit++;
96 LLVM_DEBUG(dbgs() << "Converted instruction to imm form: ");
97 LLVM_DEBUG(MI.dump());
98 if (DefMIToErase) {
99 InstrsToErase.push_back(DefMIToErase);
100 }
101 }
102 }
103
104 // Eliminate conditional branch based on a constant CR bit by
105 // CRSET or CRUNSET. We eliminate the conditional branch or
106 // convert it into an unconditional branch. Also, if the CR bit
107 // is not used by other instructions, we eliminate CRSET as well.
108 auto I = MBB.getFirstInstrTerminator();
109 if (I == MBB.instr_end())
110 continue;
111 MachineInstr *Br = &*I;
112 if (Br->getOpcode() != PPC::BC && Br->getOpcode() != PPC::BCn)
113 continue;
114 MachineInstr *CRSetMI = nullptr;
115 unsigned CRBit = Br->getOperand(0).getReg();
116 unsigned CRReg = getCRFromCRBit(CRBit);
117 bool SeenUse = false;
118 MachineBasicBlock::reverse_iterator It = Br, Er = MBB.rend();
119 for (It++; It != Er; It++) {
120 if (It->modifiesRegister(CRBit, TRI)) {
121 if ((It->getOpcode() == PPC::CRUNSET ||
122 It->getOpcode() == PPC::CRSET) &&
123 It->getOperand(0).getReg() == CRBit)
124 CRSetMI = &*It;
125 break;
126 }
127 if (It->readsRegister(CRBit, TRI))
128 SeenUse = true;
129 }
130 if (!CRSetMI) continue;
131
132 unsigned CRSetOp = CRSetMI->getOpcode();
133 if ((Br->getOpcode() == PPC::BCn && CRSetOp == PPC::CRSET) ||
134 (Br->getOpcode() == PPC::BC && CRSetOp == PPC::CRUNSET)) {
135 // Remove this branch since it cannot be taken.
136 InstrsToErase.push_back(Br);
137 MBB.removeSuccessor(Br->getOperand(1).getMBB());
138 }
139 else {
140 // This conditional branch is always taken. So, remove all branches
141 // and insert an unconditional branch to the destination of this.
142 MachineBasicBlock::iterator It = Br, Er = MBB.end();
143 for (; It != Er; It++) {
144 if (It->isDebugInstr()) continue;
145 assert(It->isTerminator() && "Non-terminator after a terminator");
146 InstrsToErase.push_back(&*It);
147 }
148 if (!MBB.isLayoutSuccessor(Br->getOperand(1).getMBB())) {
149 ArrayRef<MachineOperand> NoCond;
150 TII->insertBranch(MBB, Br->getOperand(1).getMBB(), nullptr,
151 NoCond, Br->getDebugLoc());
152 }
153 for (auto &Succ : MBB.successors())
154 if (Succ != Br->getOperand(1).getMBB()) {
155 MBB.removeSuccessor(Succ);
156 break;
157 }
158 }
159
160 // If the CRBit is not used by another instruction, we can eliminate
161 // CRSET/CRUNSET instruction.
162 if (!SeenUse) {
163 // We need to check use of the CRBit in successors.
164 for (auto &SuccMBB : MBB.successors())
165 if (SuccMBB->isLiveIn(CRBit) || SuccMBB->isLiveIn(CRReg)) {
166 SeenUse = true;
167 break;
168 }
169 if (!SeenUse)
170 InstrsToErase.push_back(CRSetMI);
171 }
172 }
173 for (MachineInstr *MI : InstrsToErase) {
174 LLVM_DEBUG(dbgs() << "PPC pre-emit peephole: erasing instruction: ");
175 LLVM_DEBUG(MI->dump());
176 MI->eraseFromParent();
177 NumRemovedInPreEmit++;
178 }
179 return Changed;
180 }
181 };
182 }
183
184 INITIALIZE_PASS(PPCPreEmitPeephole, DEBUG_TYPE, "PowerPC Pre-Emit Peephole",
185 false, false)
186 char PPCPreEmitPeephole::ID = 0;
187
createPPCPreEmitPeepholePass()188 FunctionPass *llvm::createPPCPreEmitPeepholePass() {
189 return new PPCPreEmitPeephole();
190 }
191