//===-- HexagonPeephole.cpp - Hexagon Peephole Optimiztions ---------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// This peephole pass optimizes in the following cases.
// 1. Optimizes redundant sign extends for the following case
//    Transform the following pattern
//    %170 = SXTW %166
//    ...
//    %176 = COPY %170:isub_lo
//
//    Into
//    %176 = COPY %166
//
//  2. Optimizes redundant negation of predicates.
//     %15 = CMPGTrr %6, %2
//     ...
//     %16 = NOT_p killed %15
//     ...
//     JMP_c killed %16, <%bb.1>, implicit dead %pc
//
//     Into
//     %15 = CMPGTrr %6, %2;
//     ...
//     JMP_cNot killed %15, <%bb.1>, implicit dead %pc;
//
// Note: The peephole pass makes the instrucstions like
// %170 = SXTW %166 or %16 = NOT_p killed %15
// redundant and relies on some form of dead removal instructions, like
// DCE or DIE to actually eliminate them.

//===----------------------------------------------------------------------===//

#include "Hexagon.h"
#include "HexagonTargetMachine.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/PassSupport.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>

using namespace llvm;

#define DEBUG_TYPE "hexagon-peephole"

static cl::opt<bool> DisableHexagonPeephole("disable-hexagon-peephole",
    cl::Hidden, cl::ZeroOrMore, cl::init(false),
    cl::desc("Disable Peephole Optimization"));

static cl::opt<bool> DisablePNotP("disable-hexagon-pnotp",
    cl::Hidden, cl::ZeroOrMore, cl::init(false),
    cl::desc("Disable Optimization of PNotP"));

static cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext",
    cl::Hidden, cl::ZeroOrMore, cl::init(true),
    cl::desc("Disable Optimization of Sign/Zero Extends"));

static cl::opt<bool> DisableOptExtTo64("disable-hexagon-opt-ext-to-64",
    cl::Hidden, cl::ZeroOrMore, cl::init(true),
    cl::desc("Disable Optimization of extensions to i64."));

namespace llvm {
  FunctionPass *createHexagonPeephole();
  void initializeHexagonPeepholePass(PassRegistry&);
}

namespace {
  struct HexagonPeephole : public MachineFunctionPass {
    const HexagonInstrInfo    *QII;
    const HexagonRegisterInfo *QRI;
    const MachineRegisterInfo *MRI;

  public:
    static char ID;
    HexagonPeephole() : MachineFunctionPass(ID) {
      initializeHexagonPeepholePass(*PassRegistry::getPassRegistry());
    }

    bool runOnMachineFunction(MachineFunction &MF) override;

    StringRef getPassName() const override {
      return "Hexagon optimize redundant zero and size extends";
    }

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      MachineFunctionPass::getAnalysisUsage(AU);
    }
  };
}

char HexagonPeephole::ID = 0;

INITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole",
                false, false)

bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
  if (skipFunction(MF.getFunction()))
    return false;

  QII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
  QRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
  MRI = &MF.getRegInfo();

  DenseMap<unsigned, unsigned> PeepholeMap;
  DenseMap<unsigned, std::pair<unsigned, unsigned> > PeepholeDoubleRegsMap;

  if (DisableHexagonPeephole) return false;

  // Loop over all of the basic blocks.
  for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
       MBBb != MBBe; ++MBBb) {
    MachineBasicBlock *MBB = &*MBBb;
    PeepholeMap.clear();
    PeepholeDoubleRegsMap.clear();

    // Traverse the basic block.
    for (auto I = MBB->begin(), E = MBB->end(), NextI = I; I != E; I = NextI) {
      NextI = std::next(I);
      MachineInstr &MI = *I;
      // Look for sign extends:
      // %170 = SXTW %166
      if (!DisableOptSZExt && MI.getOpcode() == Hexagon::A2_sxtw) {
        assert(MI.getNumOperands() == 2);
        MachineOperand &Dst = MI.getOperand(0);
        MachineOperand &Src = MI.getOperand(1);
        unsigned DstReg = Dst.getReg();
        unsigned SrcReg = Src.getReg();
        // Just handle virtual registers.
        if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
            TargetRegisterInfo::isVirtualRegister(SrcReg)) {
          // Map the following:
          // %170 = SXTW %166
          // PeepholeMap[170] = %166
          PeepholeMap[DstReg] = SrcReg;
        }
      }

      // Look for  %170 = COMBINE_ir_V4 (0, %169)
      // %170:DoublRegs, %169:IntRegs
      if (!DisableOptExtTo64 && MI.getOpcode() == Hexagon::A4_combineir) {
        assert(MI.getNumOperands() == 3);
        MachineOperand &Dst = MI.getOperand(0);
        MachineOperand &Src1 = MI.getOperand(1);
        MachineOperand &Src2 = MI.getOperand(2);
        if (Src1.getImm() != 0)
          continue;
        unsigned DstReg = Dst.getReg();
        unsigned SrcReg = Src2.getReg();
        PeepholeMap[DstReg] = SrcReg;
      }

      // Look for this sequence below
      // %DoubleReg1 = LSRd_ri %DoubleReg0, 32
      // %IntReg = COPY %DoubleReg1:isub_lo.
      // and convert into
      // %IntReg = COPY %DoubleReg0:isub_hi.
      if (MI.getOpcode() == Hexagon::S2_lsr_i_p) {
        assert(MI.getNumOperands() == 3);
        MachineOperand &Dst = MI.getOperand(0);
        MachineOperand &Src1 = MI.getOperand(1);
        MachineOperand &Src2 = MI.getOperand(2);
        if (Src2.getImm() != 32)
          continue;
        unsigned DstReg = Dst.getReg();
        unsigned SrcReg = Src1.getReg();
        PeepholeDoubleRegsMap[DstReg] =
          std::make_pair(*&SrcReg, Hexagon::isub_hi);
      }

      // Look for P=NOT(P).
      if (!DisablePNotP && MI.getOpcode() == Hexagon::C2_not) {
        assert(MI.getNumOperands() == 2);
        MachineOperand &Dst = MI.getOperand(0);
        MachineOperand &Src = MI.getOperand(1);
        unsigned DstReg = Dst.getReg();
        unsigned SrcReg = Src.getReg();
        // Just handle virtual registers.
        if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
            TargetRegisterInfo::isVirtualRegister(SrcReg)) {
          // Map the following:
          // %170 = NOT_xx %166
          // PeepholeMap[170] = %166
          PeepholeMap[DstReg] = SrcReg;
        }
      }

      // Look for copy:
      // %176 = COPY %170:isub_lo
      if (!DisableOptSZExt && MI.isCopy()) {
        assert(MI.getNumOperands() == 2);
        MachineOperand &Dst = MI.getOperand(0);
        MachineOperand &Src = MI.getOperand(1);

        // Make sure we are copying the lower 32 bits.
        if (Src.getSubReg() != Hexagon::isub_lo)
          continue;

        unsigned DstReg = Dst.getReg();
        unsigned SrcReg = Src.getReg();
        if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
            TargetRegisterInfo::isVirtualRegister(SrcReg)) {
          // Try to find in the map.
          if (unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) {
            // Change the 1st operand.
            MI.RemoveOperand(1);
            MI.addOperand(MachineOperand::CreateReg(PeepholeSrc, false));
          } else  {
            DenseMap<unsigned, std::pair<unsigned, unsigned> >::iterator DI =
              PeepholeDoubleRegsMap.find(SrcReg);
            if (DI != PeepholeDoubleRegsMap.end()) {
              std::pair<unsigned,unsigned> PeepholeSrc = DI->second;
              MI.RemoveOperand(1);
              MI.addOperand(MachineOperand::CreateReg(
                  PeepholeSrc.first, false /*isDef*/, false /*isImp*/,
                  false /*isKill*/, false /*isDead*/, false /*isUndef*/,
                  false /*isEarlyClobber*/, PeepholeSrc.second));
            }
          }
        }
      }

      // Look for Predicated instructions.
      if (!DisablePNotP) {
        bool Done = false;
        if (QII->isPredicated(MI)) {
          MachineOperand &Op0 = MI.getOperand(0);
          unsigned Reg0 = Op0.getReg();
          const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0);
          if (RC0->getID() == Hexagon::PredRegsRegClassID) {
            // Handle instructions that have a prediate register in op0
            // (most cases of predicable instructions).
            if (TargetRegisterInfo::isVirtualRegister(Reg0)) {
              // Try to find in the map.
              if (unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) {
                // Change the 1st operand and, flip the opcode.
                MI.getOperand(0).setReg(PeepholeSrc);
                MRI->clearKillFlags(PeepholeSrc);
                int NewOp = QII->getInvertedPredicatedOpcode(MI.getOpcode());
                MI.setDesc(QII->get(NewOp));
                Done = true;
              }
            }
          }
        }

        if (!Done) {
          // Handle special instructions.
          unsigned Op = MI.getOpcode();
          unsigned NewOp = 0;
          unsigned PR = 1, S1 = 2, S2 = 3;   // Operand indices.

          switch (Op) {
            case Hexagon::C2_mux:
            case Hexagon::C2_muxii:
              NewOp = Op;
              break;
            case Hexagon::C2_muxri:
              NewOp = Hexagon::C2_muxir;
              break;
            case Hexagon::C2_muxir:
              NewOp = Hexagon::C2_muxri;
              break;
          }
          if (NewOp) {
            unsigned PSrc = MI.getOperand(PR).getReg();
            if (unsigned POrig = PeepholeMap.lookup(PSrc)) {
              BuildMI(*MBB, MI.getIterator(), MI.getDebugLoc(),
                      QII->get(NewOp), MI.getOperand(0).getReg())
                .addReg(POrig)
                .add(MI.getOperand(S2))
                .add(MI.getOperand(S1));
              MRI->clearKillFlags(POrig);
              MI.eraseFromParent();
            }
          } // if (NewOp)
        } // if (!Done)

      } // if (!DisablePNotP)

    } // Instruction
  } // Basic Block
  return true;
}

FunctionPass *llvm::createHexagonPeephole() {
  return new HexagonPeephole();
}
