//===-- 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/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetMachine.h"

using namespace llvm;

#define DEBUG_TYPE "hexagon-peephole"

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

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

static cl::opt<bool>
    DisableOptSZExt("disable-hexagon-optszext", cl::Hidden, 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::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 (MachineBasicBlock &MBB : MF) {
    PeepholeMap.clear();
    PeepholeDoubleRegsMap.clear();

    // Traverse the basic block.
    for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
      // 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);
        Register DstReg = Dst.getReg();
        Register SrcReg = Src.getReg();
        // Just handle virtual registers.
        if (DstReg.isVirtual() && SrcReg.isVirtual()) {
          // 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;
        Register DstReg = Dst.getReg();
        Register 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;
        Register DstReg = Dst.getReg();
        Register 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);
        Register DstReg = Dst.getReg();
        Register SrcReg = Src.getReg();
        // Just handle virtual registers.
        if (DstReg.isVirtual() && SrcReg.isVirtual()) {
          // 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;

        Register DstReg = Dst.getReg();
        Register SrcReg = Src.getReg();
        if (DstReg.isVirtual() && SrcReg.isVirtual()) {
          // 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);
          Register 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 (Reg0.isVirtual()) {
              // 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) {
            Register 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();
}
