//===-- SPIRVRegularizer.cpp - regularize IR for SPIR-V ---------*- C++ -*-===//
//
// 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 pass implements regularization of LLVM IR for SPIR-V. The prototype of
// the pass was taken from SPIRV-LLVM translator.
//
//===----------------------------------------------------------------------===//

#include "SPIRV.h"
#include "SPIRVTargetMachine.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Transforms/Utils/Cloning.h"

#include <list>

#define DEBUG_TYPE "spirv-regularizer"

using namespace llvm;

namespace llvm {
void initializeSPIRVRegularizerPass(PassRegistry &);
}

namespace {
struct SPIRVRegularizer : public FunctionPass, InstVisitor<SPIRVRegularizer> {
  DenseMap<Function *, Function *> Old2NewFuncs;

public:
  static char ID;
  SPIRVRegularizer() : FunctionPass(ID) {
    initializeSPIRVRegularizerPass(*PassRegistry::getPassRegistry());
  }
  bool runOnFunction(Function &F) override;
  StringRef getPassName() const override { return "SPIR-V Regularizer"; }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    FunctionPass::getAnalysisUsage(AU);
  }
  void visitCallInst(CallInst &CI);

private:
  void visitCallScalToVec(CallInst *CI, StringRef MangledName,
                          StringRef DemangledName);
  void runLowerConstExpr(Function &F);
};
} // namespace

char SPIRVRegularizer::ID = 0;

INITIALIZE_PASS(SPIRVRegularizer, DEBUG_TYPE, "SPIR-V Regularizer", false,
                false)

// Since SPIR-V cannot represent constant expression, constant expressions
// in LLVM IR need to be lowered to instructions. For each function,
// the constant expressions used by instructions of the function are replaced
// by instructions placed in the entry block since it dominates all other BBs.
// Each constant expression only needs to be lowered once in each function
// and all uses of it by instructions in that function are replaced by
// one instruction.
// TODO: remove redundant instructions for common subexpression.
void SPIRVRegularizer::runLowerConstExpr(Function &F) {
  LLVMContext &Ctx = F.getContext();
  std::list<Instruction *> WorkList;
  for (auto &II : instructions(F))
    WorkList.push_back(&II);

  auto FBegin = F.begin();
  while (!WorkList.empty()) {
    Instruction *II = WorkList.front();

    auto LowerOp = [&II, &FBegin, &F](Value *V) -> Value * {
      if (isa<Function>(V))
        return V;
      auto *CE = cast<ConstantExpr>(V);
      LLVM_DEBUG(dbgs() << "[lowerConstantExpressions] " << *CE);
      auto ReplInst = CE->getAsInstruction();
      auto InsPoint = II->getParent() == &*FBegin ? II : &FBegin->back();
      ReplInst->insertBefore(InsPoint);
      LLVM_DEBUG(dbgs() << " -> " << *ReplInst << '\n');
      std::vector<Instruction *> Users;
      // Do not replace use during iteration of use. Do it in another loop.
      for (auto U : CE->users()) {
        LLVM_DEBUG(dbgs() << "[lowerConstantExpressions] Use: " << *U << '\n');
        auto InstUser = dyn_cast<Instruction>(U);
        // Only replace users in scope of current function.
        if (InstUser && InstUser->getParent()->getParent() == &F)
          Users.push_back(InstUser);
      }
      for (auto &User : Users) {
        if (ReplInst->getParent() == User->getParent() &&
            User->comesBefore(ReplInst))
          ReplInst->moveBefore(User);
        User->replaceUsesOfWith(CE, ReplInst);
      }
      return ReplInst;
    };

    WorkList.pop_front();
    auto LowerConstantVec = [&II, &LowerOp, &WorkList,
                             &Ctx](ConstantVector *Vec,
                                   unsigned NumOfOp) -> Value * {
      if (std::all_of(Vec->op_begin(), Vec->op_end(), [](Value *V) {
            return isa<ConstantExpr>(V) || isa<Function>(V);
          })) {
        // Expand a vector of constexprs and construct it back with
        // series of insertelement instructions.
        std::list<Value *> OpList;
        std::transform(Vec->op_begin(), Vec->op_end(),
                       std::back_inserter(OpList),
                       [LowerOp](Value *V) { return LowerOp(V); });
        Value *Repl = nullptr;
        unsigned Idx = 0;
        auto *PhiII = dyn_cast<PHINode>(II);
        Instruction *InsPoint =
            PhiII ? &PhiII->getIncomingBlock(NumOfOp)->back() : II;
        std::list<Instruction *> ReplList;
        for (auto V : OpList) {
          if (auto *Inst = dyn_cast<Instruction>(V))
            ReplList.push_back(Inst);
          Repl = InsertElementInst::Create(
              (Repl ? Repl : PoisonValue::get(Vec->getType())), V,
              ConstantInt::get(Type::getInt32Ty(Ctx), Idx++), "", InsPoint);
        }
        WorkList.splice(WorkList.begin(), ReplList);
        return Repl;
      }
      return nullptr;
    };
    for (unsigned OI = 0, OE = II->getNumOperands(); OI != OE; ++OI) {
      auto *Op = II->getOperand(OI);
      if (auto *Vec = dyn_cast<ConstantVector>(Op)) {
        Value *ReplInst = LowerConstantVec(Vec, OI);
        if (ReplInst)
          II->replaceUsesOfWith(Op, ReplInst);
      } else if (auto CE = dyn_cast<ConstantExpr>(Op)) {
        WorkList.push_front(cast<Instruction>(LowerOp(CE)));
      } else if (auto MDAsVal = dyn_cast<MetadataAsValue>(Op)) {
        auto ConstMD = dyn_cast<ConstantAsMetadata>(MDAsVal->getMetadata());
        if (!ConstMD)
          continue;
        Constant *C = ConstMD->getValue();
        Value *ReplInst = nullptr;
        if (auto *Vec = dyn_cast<ConstantVector>(C))
          ReplInst = LowerConstantVec(Vec, OI);
        if (auto *CE = dyn_cast<ConstantExpr>(C))
          ReplInst = LowerOp(CE);
        if (!ReplInst)
          continue;
        Metadata *RepMD = ValueAsMetadata::get(ReplInst);
        Value *RepMDVal = MetadataAsValue::get(Ctx, RepMD);
        II->setOperand(OI, RepMDVal);
        WorkList.push_front(cast<Instruction>(ReplInst));
      }
    }
  }
}

// It fixes calls to OCL builtins that accept vector arguments and one of them
// is actually a scalar splat.
void SPIRVRegularizer::visitCallInst(CallInst &CI) {
  auto F = CI.getCalledFunction();
  if (!F)
    return;

  auto MangledName = F->getName();
  size_t n;
  int status;
  char *NameStr = itaniumDemangle(F->getName().data(), nullptr, &n, &status);
  StringRef DemangledName(NameStr);

  // TODO: add support for other builtins.
  if (DemangledName.startswith("fmin") || DemangledName.startswith("fmax") ||
      DemangledName.startswith("min") || DemangledName.startswith("max"))
    visitCallScalToVec(&CI, MangledName, DemangledName);
  free(NameStr);
}

void SPIRVRegularizer::visitCallScalToVec(CallInst *CI, StringRef MangledName,
                                          StringRef DemangledName) {
  // Check if all arguments have the same type - it's simple case.
  auto Uniform = true;
  Type *Arg0Ty = CI->getOperand(0)->getType();
  auto IsArg0Vector = isa<VectorType>(Arg0Ty);
  for (unsigned I = 1, E = CI->arg_size(); Uniform && (I != E); ++I)
    Uniform = isa<VectorType>(CI->getOperand(I)->getType()) == IsArg0Vector;
  if (Uniform)
    return;

  auto *OldF = CI->getCalledFunction();
  Function *NewF = nullptr;
  if (!Old2NewFuncs.count(OldF)) {
    AttributeList Attrs = CI->getCalledFunction()->getAttributes();
    SmallVector<Type *, 2> ArgTypes = {OldF->getArg(0)->getType(), Arg0Ty};
    auto *NewFTy =
        FunctionType::get(OldF->getReturnType(), ArgTypes, OldF->isVarArg());
    NewF = Function::Create(NewFTy, OldF->getLinkage(), OldF->getName(),
                            *OldF->getParent());
    ValueToValueMapTy VMap;
    auto NewFArgIt = NewF->arg_begin();
    for (auto &Arg : OldF->args()) {
      auto ArgName = Arg.getName();
      NewFArgIt->setName(ArgName);
      VMap[&Arg] = &(*NewFArgIt++);
    }
    SmallVector<ReturnInst *, 8> Returns;
    CloneFunctionInto(NewF, OldF, VMap,
                      CloneFunctionChangeType::LocalChangesOnly, Returns);
    NewF->setAttributes(Attrs);
    Old2NewFuncs[OldF] = NewF;
  } else {
    NewF = Old2NewFuncs[OldF];
  }
  assert(NewF);

  // This produces an instruction sequence that implements a splat of
  // CI->getOperand(1) to a vector Arg0Ty. However, we use InsertElementInst
  // and ShuffleVectorInst to generate the same code as the SPIR-V translator.
  // For instance (transcoding/OpMin.ll), this call
  //   call spir_func <2 x i32> @_Z3minDv2_ii(<2 x i32> <i32 1, i32 10>, i32 5)
  // is translated to
  //    %8 = OpUndef %v2uint
  //   %14 = OpConstantComposite %v2uint %uint_1 %uint_10
  //   ...
  //   %10 = OpCompositeInsert %v2uint %uint_5 %8 0
  //   %11 = OpVectorShuffle %v2uint %10 %8 0 0
  // %call = OpExtInst %v2uint %1 s_min %14 %11
  auto ConstInt = ConstantInt::get(IntegerType::get(CI->getContext(), 32), 0);
  PoisonValue *PVal = PoisonValue::get(Arg0Ty);
  Instruction *Inst =
      InsertElementInst::Create(PVal, CI->getOperand(1), ConstInt, "", CI);
  ElementCount VecElemCount = cast<VectorType>(Arg0Ty)->getElementCount();
  Constant *ConstVec = ConstantVector::getSplat(VecElemCount, ConstInt);
  Value *NewVec = new ShuffleVectorInst(Inst, PVal, ConstVec, "", CI);
  CI->setOperand(1, NewVec);
  CI->replaceUsesOfWith(OldF, NewF);
  CI->mutateFunctionType(NewF->getFunctionType());
}

bool SPIRVRegularizer::runOnFunction(Function &F) {
  runLowerConstExpr(F);
  visit(F);
  for (auto &OldNew : Old2NewFuncs) {
    Function *OldF = OldNew.first;
    Function *NewF = OldNew.second;
    NewF->takeName(OldF);
    OldF->eraseFromParent();
  }
  return true;
}

FunctionPass *llvm::createSPIRVRegularizerPass() {
  return new SPIRVRegularizer();
}
