]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/PowerPC/PPCPreEmitPeephole.cpp
Fix a memory leak in if_delgroups() introduced in r334118.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / PowerPC / PPCPreEmitPeephole.cpp
1 //===--------- PPCPreEmitPeephole.cpp - Late peephole optimizations -------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // A pre-emit peephole for catching opportunities introduced by late passes such
10 // as MachineBlockPlacement.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "PPC.h"
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"
27
28 using namespace llvm;
29
30 #define DEBUG_TYPE "ppc-pre-emit-peephole"
31
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");
38
39 static cl::opt<bool>
40 RunPreEmitPeephole("ppc-late-peephole", cl::Hidden, cl::init(true),
41                    cl::desc("Run pre-emit peephole optimizations."));
42
43 namespace {
44   class PPCPreEmitPeephole : public MachineFunctionPass {
45   public:
46     static char ID;
47     PPCPreEmitPeephole() : MachineFunctionPass(ID) {
48       initializePPCPreEmitPeepholePass(*PassRegistry::getPassRegistry());
49     }
50
51     void getAnalysisUsage(AnalysisUsage &AU) const override {
52       MachineFunctionPass::getAnalysisUsage(AU);
53     }
54
55     MachineFunctionProperties getRequiredProperties() const override {
56       return MachineFunctionProperties().set(
57           MachineFunctionProperties::Property::NoVRegs);
58     }
59
60     bool runOnMachineFunction(MachineFunction &MF) override {
61       if (skipFunction(MF.getFunction()) || !RunPreEmitPeephole)
62         return false;
63       bool Changed = false;
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()) {
76               NumberOfSelfCopies++;
77               LLVM_DEBUG(dbgs() << "Deleting self-copy instruction: ");
78               LLVM_DEBUG(MI.dump());
79               InstrsToErase.push_back(&MI);
80               continue;
81             }
82             else if (MCID.getNumOperands() == 2 &&
83                      MI.getOperand(0).getReg() == MI.getOperand(1).getReg()) {
84               NumberOfSelfCopies++;
85               LLVM_DEBUG(dbgs() << "Deleting self-copy instruction: ");
86               LLVM_DEBUG(MI.dump());
87               InstrsToErase.push_back(&MI);
88               continue;
89             }
90           }
91           MachineInstr *DefMIToErase = nullptr;
92           if (TII->convertToImmediateForm(MI, &DefMIToErase)) {
93             Changed = true;
94             NumRRConvertedInPreEmit++;
95             LLVM_DEBUG(dbgs() << "Converted instruction to imm form: ");
96             LLVM_DEBUG(MI.dump());
97             if (DefMIToErase) {
98               InstrsToErase.push_back(DefMIToErase);
99             }
100           }
101         }
102
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())
109           continue;
110         MachineInstr *Br = &*I;
111         if (Br->getOpcode() != PPC::BC && Br->getOpcode() != PPC::BCn)
112           continue;
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)
123               CRSetMI = &*It;
124             break;
125           }
126           if (It->readsRegister(CRBit, TRI))
127             SeenUse = true;
128         }
129         if (!CRSetMI) continue;
130
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());
137         }
138         else {
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);
146           }
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());
151           }
152           for (auto &Succ : MBB.successors())
153             if (Succ != Br->getOperand(1).getMBB()) {
154               MBB.removeSuccessor(Succ);
155               break;
156             }
157         }
158
159         // If the CRBit is not used by another instruction, we can eliminate
160         // CRSET/CRUNSET instruction.
161         if (!SeenUse) {
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)) {
165               SeenUse = true;
166               break;
167             }
168           if (!SeenUse)
169             InstrsToErase.push_back(CRSetMI);
170         }
171       }
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++;
177       }
178       return Changed;
179     }
180   };
181 }
182
183 INITIALIZE_PASS(PPCPreEmitPeephole, DEBUG_TYPE, "PowerPC Pre-Emit Peephole",
184                 false, false)
185 char PPCPreEmitPeephole::ID = 0;
186
187 FunctionPass *llvm::createPPCPreEmitPeepholePass() {
188   return new PPCPreEmitPeephole();
189 }