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