//===-- SPIRVPostLegalizer.cpp - ammend info after legalization -*- C++ -*-===//
//
// which may appear after the legalizer pass
//
// 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
//
//===----------------------------------------------------------------------===//
//
// The pass partially apply pre-legalization logic to new instructions inserted
// as a result of legalization:
// - assigns SPIR-V types to registers for new instructions.
//
//===----------------------------------------------------------------------===//

#include "SPIRV.h"
#include "SPIRVSubtarget.h"
#include "SPIRVUtils.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/CodeGen/MachinePostDominators.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/IntrinsicsSPIRV.h"
#include "llvm/Target/TargetIntrinsicInfo.h"
#include <stack>

#define DEBUG_TYPE "spirv-postlegalizer"

using namespace llvm;

namespace {
class SPIRVPostLegalizer : public MachineFunctionPass {
public:
  static char ID;
  SPIRVPostLegalizer() : MachineFunctionPass(ID) {
    initializeSPIRVPostLegalizerPass(*PassRegistry::getPassRegistry());
  }
  bool runOnMachineFunction(MachineFunction &MF) override;
};
} // namespace

// Defined in SPIRVLegalizerInfo.cpp.
extern bool isTypeFoldingSupported(unsigned Opcode);

namespace llvm {
//  Defined in SPIRVPreLegalizer.cpp.
extern Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
                                  SPIRVGlobalRegistry *GR,
                                  MachineIRBuilder &MIB,
                                  MachineRegisterInfo &MRI);
extern void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
                         MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR);
} // namespace llvm

static bool mayBeInserted(unsigned Opcode) {
  switch (Opcode) {
  case TargetOpcode::G_SMAX:
  case TargetOpcode::G_UMAX:
  case TargetOpcode::G_SMIN:
  case TargetOpcode::G_UMIN:
  case TargetOpcode::G_FMINNUM:
  case TargetOpcode::G_FMINIMUM:
  case TargetOpcode::G_FMAXNUM:
  case TargetOpcode::G_FMAXIMUM:
    return true;
  default:
    return isTypeFoldingSupported(Opcode);
  }
}

static void processNewInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
                             MachineIRBuilder MIB) {
  MachineRegisterInfo &MRI = MF.getRegInfo();

  for (MachineBasicBlock &MBB : MF) {
    for (MachineInstr &I : MBB) {
      const unsigned Opcode = I.getOpcode();
      if (Opcode == TargetOpcode::G_UNMERGE_VALUES) {
        unsigned ArgI = I.getNumOperands() - 1;
        Register SrcReg = I.getOperand(ArgI).isReg()
                              ? I.getOperand(ArgI).getReg()
                              : Register(0);
        SPIRVType *DefType =
            SrcReg.isValid() ? GR->getSPIRVTypeForVReg(SrcReg) : nullptr;
        if (!DefType || DefType->getOpcode() != SPIRV::OpTypeVector)
          report_fatal_error(
              "cannot select G_UNMERGE_VALUES with a non-vector argument");
        SPIRVType *ScalarType =
            GR->getSPIRVTypeForVReg(DefType->getOperand(1).getReg());
        for (unsigned i = 0; i < I.getNumDefs(); ++i) {
          Register ResVReg = I.getOperand(i).getReg();
          SPIRVType *ResType = GR->getSPIRVTypeForVReg(ResVReg);
          if (!ResType) {
            // There was no "assign type" actions, let's fix this now
            ResType = ScalarType;
            setRegClassType(ResVReg, ResType, GR, &MRI, *GR->CurMF, true);
          }
        }
      } else if (mayBeInserted(Opcode) && I.getNumDefs() == 1 &&
                 I.getNumOperands() > 1 && I.getOperand(1).isReg()) {
        // Legalizer may have added a new instructions and introduced new
        // registers, we must decorate them as if they were introduced in a
        // non-automatic way
        Register ResVReg = I.getOperand(0).getReg();
        // Check if the register defined by the instruction is newly generated
        // or already processed
        if (MRI.getRegClassOrNull(ResVReg))
          continue;
        assert(GR->getSPIRVTypeForVReg(ResVReg) == nullptr);
        // Check if we have type defined for operands of the new instruction
        SPIRVType *ResVType = GR->getSPIRVTypeForVReg(I.getOperand(1).getReg());
        if (!ResVType)
          continue;
        // Set type & class
        setRegClassType(ResVReg, ResVType, GR, &MRI, *GR->CurMF, true);
        // If this is a simple operation that is to be reduced by TableGen
        // definition we must apply some of pre-legalizer rules here
        if (isTypeFoldingSupported(Opcode)) {
          insertAssignInstr(ResVReg, nullptr, ResVType, GR, MIB, MRI);
          processInstr(I, MIB, MRI, GR);
        }
      }
    }
  }
}

// Do a preorder traversal of the CFG starting from the BB |Start|.
// point. Calls |op| on each basic block encountered during the traversal.
void visit(MachineFunction &MF, MachineBasicBlock &Start,
           std::function<void(MachineBasicBlock *)> op) {
  std::stack<MachineBasicBlock *> ToVisit;
  SmallPtrSet<MachineBasicBlock *, 8> Seen;

  ToVisit.push(&Start);
  Seen.insert(ToVisit.top());
  while (ToVisit.size() != 0) {
    MachineBasicBlock *MBB = ToVisit.top();
    ToVisit.pop();

    op(MBB);

    for (auto Succ : MBB->successors()) {
      if (Seen.contains(Succ))
        continue;
      ToVisit.push(Succ);
      Seen.insert(Succ);
    }
  }
}

// Do a preorder traversal of the CFG starting from the given function's entry
// point. Calls |op| on each basic block encountered during the traversal.
void visit(MachineFunction &MF, std::function<void(MachineBasicBlock *)> op) {
  visit(MF, *MF.begin(), op);
}

bool SPIRVPostLegalizer::runOnMachineFunction(MachineFunction &MF) {
  // Initialize the type registry.
  const SPIRVSubtarget &ST = MF.getSubtarget<SPIRVSubtarget>();
  SPIRVGlobalRegistry *GR = ST.getSPIRVGlobalRegistry();
  GR->setCurrentFunc(MF);
  MachineIRBuilder MIB(MF);

  processNewInstrs(MF, GR, MIB);

  return true;
}

INITIALIZE_PASS(SPIRVPostLegalizer, DEBUG_TYPE, "SPIRV post legalizer", false,
                false)

char SPIRVPostLegalizer::ID = 0;

FunctionPass *llvm::createSPIRVPostLegalizerPass() {
  return new SPIRVPostLegalizer();
}
