16995e5daSNemanja Ivanovic //===--------- PPCPreEmitPeephole.cpp - Late peephole optimizations -------===//
26995e5daSNemanja Ivanovic //
36995e5daSNemanja Ivanovic //                     The LLVM Compiler Infrastructure
46995e5daSNemanja Ivanovic //
56995e5daSNemanja Ivanovic // This file is distributed under the University of Illinois Open Source
66995e5daSNemanja Ivanovic // License. See LICENSE.TXT for details.
76995e5daSNemanja Ivanovic //
86995e5daSNemanja Ivanovic //===----------------------------------------------------------------------===//
96995e5daSNemanja Ivanovic //
106995e5daSNemanja Ivanovic // A pre-emit peephole for catching opportunities introduced by late passes such
116995e5daSNemanja Ivanovic // as MachineBlockPlacement.
126995e5daSNemanja Ivanovic //
136995e5daSNemanja Ivanovic //===----------------------------------------------------------------------===//
146995e5daSNemanja Ivanovic 
156995e5daSNemanja Ivanovic #include "PPC.h"
166995e5daSNemanja Ivanovic #include "PPCInstrInfo.h"
176995e5daSNemanja Ivanovic #include "PPCSubtarget.h"
186995e5daSNemanja Ivanovic #include "llvm/ADT/DenseMap.h"
196995e5daSNemanja Ivanovic #include "llvm/ADT/Statistic.h"
206995e5daSNemanja Ivanovic #include "llvm/CodeGen/LivePhysRegs.h"
216995e5daSNemanja Ivanovic #include "llvm/CodeGen/MachineFunctionPass.h"
226995e5daSNemanja Ivanovic #include "llvm/CodeGen/MachineInstrBuilder.h"
236995e5daSNemanja Ivanovic #include "llvm/CodeGen/MachineRegisterInfo.h"
246995e5daSNemanja Ivanovic #include "llvm/Support/CommandLine.h"
256995e5daSNemanja Ivanovic #include "llvm/ADT/Statistic.h"
266995e5daSNemanja Ivanovic #include "llvm/Support/Debug.h"
276995e5daSNemanja Ivanovic 
286995e5daSNemanja Ivanovic using namespace llvm;
296995e5daSNemanja Ivanovic 
306995e5daSNemanja Ivanovic #define DEBUG_TYPE "ppc-pre-emit-peephole"
316995e5daSNemanja Ivanovic 
326995e5daSNemanja Ivanovic STATISTIC(NumRRConvertedInPreEmit,
336995e5daSNemanja Ivanovic           "Number of r+r instructions converted to r+i in pre-emit peephole");
346995e5daSNemanja Ivanovic STATISTIC(NumRemovedInPreEmit,
356995e5daSNemanja Ivanovic           "Number of instructions deleted in pre-emit peephole");
366995e5daSNemanja Ivanovic 
376995e5daSNemanja Ivanovic static cl::opt<bool>
384e1f5e07SNemanja Ivanovic RunPreEmitPeephole("ppc-late-peephole", cl::Hidden, cl::init(true),
396995e5daSNemanja Ivanovic                    cl::desc("Run pre-emit peephole optimizations."));
406995e5daSNemanja Ivanovic 
416995e5daSNemanja Ivanovic namespace {
426995e5daSNemanja Ivanovic   class PPCPreEmitPeephole : public MachineFunctionPass {
436995e5daSNemanja Ivanovic   public:
446995e5daSNemanja Ivanovic     static char ID;
456995e5daSNemanja Ivanovic     PPCPreEmitPeephole() : MachineFunctionPass(ID) {
466995e5daSNemanja Ivanovic       initializePPCPreEmitPeepholePass(*PassRegistry::getPassRegistry());
476995e5daSNemanja Ivanovic     }
486995e5daSNemanja Ivanovic 
496995e5daSNemanja Ivanovic     void getAnalysisUsage(AnalysisUsage &AU) const override {
506995e5daSNemanja Ivanovic       MachineFunctionPass::getAnalysisUsage(AU);
516995e5daSNemanja Ivanovic     }
526995e5daSNemanja Ivanovic 
536995e5daSNemanja Ivanovic     MachineFunctionProperties getRequiredProperties() const override {
546995e5daSNemanja Ivanovic       return MachineFunctionProperties().set(
556995e5daSNemanja Ivanovic           MachineFunctionProperties::Property::NoVRegs);
566995e5daSNemanja Ivanovic     }
576995e5daSNemanja Ivanovic 
586995e5daSNemanja Ivanovic     bool runOnMachineFunction(MachineFunction &MF) override {
59f1caa283SMatthias Braun       if (skipFunction(MF.getFunction()) || !RunPreEmitPeephole)
606995e5daSNemanja Ivanovic         return false;
616995e5daSNemanja Ivanovic       bool Changed = false;
626995e5daSNemanja Ivanovic       const PPCInstrInfo *TII = MF.getSubtarget<PPCSubtarget>().getInstrInfo();
636995e5daSNemanja Ivanovic       SmallVector<MachineInstr *, 4> InstrsToErase;
646995e5daSNemanja Ivanovic       for (MachineBasicBlock &MBB : MF) {
656995e5daSNemanja Ivanovic         for (MachineInstr &MI : MBB) {
666995e5daSNemanja Ivanovic           MachineInstr *DefMIToErase = nullptr;
676995e5daSNemanja Ivanovic           if (TII->convertToImmediateForm(MI, &DefMIToErase)) {
686995e5daSNemanja Ivanovic             Changed = true;
696995e5daSNemanja Ivanovic             NumRRConvertedInPreEmit++;
70*d34e60caSNicola Zaghen             LLVM_DEBUG(dbgs() << "Converted instruction to imm form: ");
71*d34e60caSNicola Zaghen             LLVM_DEBUG(MI.dump());
726995e5daSNemanja Ivanovic             if (DefMIToErase) {
736995e5daSNemanja Ivanovic               InstrsToErase.push_back(DefMIToErase);
746995e5daSNemanja Ivanovic             }
756995e5daSNemanja Ivanovic           }
766995e5daSNemanja Ivanovic         }
776995e5daSNemanja Ivanovic       }
786995e5daSNemanja Ivanovic       for (MachineInstr *MI : InstrsToErase) {
79*d34e60caSNicola Zaghen         LLVM_DEBUG(dbgs() << "PPC pre-emit peephole: erasing instruction: ");
80*d34e60caSNicola Zaghen         LLVM_DEBUG(MI->dump());
816995e5daSNemanja Ivanovic         MI->eraseFromParent();
826995e5daSNemanja Ivanovic         NumRemovedInPreEmit++;
836995e5daSNemanja Ivanovic       }
846995e5daSNemanja Ivanovic       return Changed;
856995e5daSNemanja Ivanovic     }
866995e5daSNemanja Ivanovic   };
876995e5daSNemanja Ivanovic }
886995e5daSNemanja Ivanovic 
896995e5daSNemanja Ivanovic INITIALIZE_PASS(PPCPreEmitPeephole, DEBUG_TYPE, "PowerPC Pre-Emit Peephole",
906995e5daSNemanja Ivanovic                 false, false)
916995e5daSNemanja Ivanovic char PPCPreEmitPeephole::ID = 0;
926995e5daSNemanja Ivanovic 
936995e5daSNemanja Ivanovic FunctionPass *llvm::createPPCPreEmitPeepholePass() {
946995e5daSNemanja Ivanovic   return new PPCPreEmitPeephole();
956995e5daSNemanja Ivanovic }
96