//=== AMDGPUPrintfRuntimeBinding.cpp - OpenCL printf implementation -------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// \file
//
// The pass bind printfs to a kernel arg pointer that will be bound to a buffer
// later by the runtime.
//
// This pass traverses the functions in the module and converts
// each call to printf to a sequence of operations that
// store the following into the printf buffer:
// - format string (passed as a module's metadata unique ID)
// - bitwise copies of printf arguments
// The backend passes will need to store metadata in the kernel
//===----------------------------------------------------------------------===//

#include "AMDGPU.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/InitializePasses.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"

using namespace llvm;

#define DEBUG_TYPE "printfToRuntime"
#define DWORD_ALIGN 4

namespace {
class AMDGPUPrintfRuntimeBinding final : public ModulePass {

public:
  static char ID;

  explicit AMDGPUPrintfRuntimeBinding();

private:
  bool runOnModule(Module &M) override;

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<TargetLibraryInfoWrapperPass>();
    AU.addRequired<DominatorTreeWrapperPass>();
  }
};

class AMDGPUPrintfRuntimeBindingImpl {
public:
  AMDGPUPrintfRuntimeBindingImpl(
      function_ref<const DominatorTree &(Function &)> GetDT,
      function_ref<const TargetLibraryInfo &(Function &)> GetTLI)
      : GetDT(GetDT), GetTLI(GetTLI) {}
  bool run(Module &M);

private:
  void getConversionSpecifiers(SmallVectorImpl<char> &OpConvSpecifiers,
                               StringRef fmt, size_t num_ops) const;

  bool shouldPrintAsStr(char Specifier, Type *OpType) const;
  bool lowerPrintfForGpu(Module &M);

  Value *simplify(Instruction *I, const TargetLibraryInfo *TLI,
                  const DominatorTree *DT) {
    return SimplifyInstruction(I, {*TD, TLI, DT});
  }

  const DataLayout *TD;
  function_ref<const DominatorTree &(Function &)> GetDT;
  function_ref<const TargetLibraryInfo &(Function &)> GetTLI;
  SmallVector<CallInst *, 32> Printfs;
};
} // namespace

char AMDGPUPrintfRuntimeBinding::ID = 0;

INITIALIZE_PASS_BEGIN(AMDGPUPrintfRuntimeBinding,
                      "amdgpu-printf-runtime-binding", "AMDGPU Printf lowering",
                      false, false)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_END(AMDGPUPrintfRuntimeBinding, "amdgpu-printf-runtime-binding",
                    "AMDGPU Printf lowering", false, false)

char &llvm::AMDGPUPrintfRuntimeBindingID = AMDGPUPrintfRuntimeBinding::ID;

namespace llvm {
ModulePass *createAMDGPUPrintfRuntimeBinding() {
  return new AMDGPUPrintfRuntimeBinding();
}
} // namespace llvm

AMDGPUPrintfRuntimeBinding::AMDGPUPrintfRuntimeBinding() : ModulePass(ID) {
  initializeAMDGPUPrintfRuntimeBindingPass(*PassRegistry::getPassRegistry());
}

void AMDGPUPrintfRuntimeBindingImpl::getConversionSpecifiers(
    SmallVectorImpl<char> &OpConvSpecifiers, StringRef Fmt,
    size_t NumOps) const {
  // not all format characters are collected.
  // At this time the format characters of interest
  // are %p and %s, which use to know if we
  // are either storing a literal string or a
  // pointer to the printf buffer.
  static const char ConvSpecifiers[] = "cdieEfgGaosuxXp";
  size_t CurFmtSpecifierIdx = 0;
  size_t PrevFmtSpecifierIdx = 0;

  while ((CurFmtSpecifierIdx = Fmt.find_first_of(
              ConvSpecifiers, CurFmtSpecifierIdx)) != StringRef::npos) {
    bool ArgDump = false;
    StringRef CurFmt = Fmt.substr(PrevFmtSpecifierIdx,
                                  CurFmtSpecifierIdx - PrevFmtSpecifierIdx);
    size_t pTag = CurFmt.find_last_of("%");
    if (pTag != StringRef::npos) {
      ArgDump = true;
      while (pTag && CurFmt[--pTag] == '%') {
        ArgDump = !ArgDump;
      }
    }

    if (ArgDump)
      OpConvSpecifiers.push_back(Fmt[CurFmtSpecifierIdx]);

    PrevFmtSpecifierIdx = ++CurFmtSpecifierIdx;
  }
}

bool AMDGPUPrintfRuntimeBindingImpl::shouldPrintAsStr(char Specifier,
                                                      Type *OpType) const {
  if (Specifier != 's')
    return false;
  const PointerType *PT = dyn_cast<PointerType>(OpType);
  if (!PT || PT->getAddressSpace() != AMDGPUAS::CONSTANT_ADDRESS)
    return false;
  Type *ElemType = PT->getContainedType(0);
  if (ElemType->getTypeID() != Type::IntegerTyID)
    return false;
  IntegerType *ElemIType = cast<IntegerType>(ElemType);
  return ElemIType->getBitWidth() == 8;
}

bool AMDGPUPrintfRuntimeBindingImpl::lowerPrintfForGpu(Module &M) {
  LLVMContext &Ctx = M.getContext();
  IRBuilder<> Builder(Ctx);
  Type *I32Ty = Type::getInt32Ty(Ctx);
  unsigned UniqID = 0;
  // NB: This is important for this string size to be divisible by 4
  const char NonLiteralStr[4] = "???";

  for (auto CI : Printfs) {
    unsigned NumOps = CI->arg_size();

    SmallString<16> OpConvSpecifiers;
    Value *Op = CI->getArgOperand(0);

    if (auto LI = dyn_cast<LoadInst>(Op)) {
      Op = LI->getPointerOperand();
      for (auto Use : Op->users()) {
        if (auto SI = dyn_cast<StoreInst>(Use)) {
          Op = SI->getValueOperand();
          break;
        }
      }
    }

    if (auto I = dyn_cast<Instruction>(Op)) {
      Value *Op_simplified =
          simplify(I, &GetTLI(*I->getFunction()), &GetDT(*I->getFunction()));
      if (Op_simplified)
        Op = Op_simplified;
    }

    ConstantExpr *ConstExpr = dyn_cast<ConstantExpr>(Op);

    if (ConstExpr) {
      GlobalVariable *GVar = dyn_cast<GlobalVariable>(ConstExpr->getOperand(0));

      StringRef Str("unknown");
      if (GVar && GVar->hasInitializer()) {
        auto *Init = GVar->getInitializer();
        if (auto *CA = dyn_cast<ConstantDataArray>(Init)) {
          if (CA->isString())
            Str = CA->getAsCString();
        } else if (isa<ConstantAggregateZero>(Init)) {
          Str = "";
        }
        //
        // we need this call to ascertain
        // that we are printing a string
        // or a pointer. It takes out the
        // specifiers and fills up the first
        // arg
        getConversionSpecifiers(OpConvSpecifiers, Str, NumOps - 1);
      }
      // Add metadata for the string
      std::string AStreamHolder;
      raw_string_ostream Sizes(AStreamHolder);
      int Sum = DWORD_ALIGN;
      Sizes << CI->arg_size() - 1;
      Sizes << ':';
      for (unsigned ArgCount = 1;
           ArgCount < CI->arg_size() && ArgCount <= OpConvSpecifiers.size();
           ArgCount++) {
        Value *Arg = CI->getArgOperand(ArgCount);
        Type *ArgType = Arg->getType();
        unsigned ArgSize = TD->getTypeAllocSizeInBits(ArgType);
        ArgSize = ArgSize / 8;
        //
        // ArgSize by design should be a multiple of DWORD_ALIGN,
        // expand the arguments that do not follow this rule.
        //
        if (ArgSize % DWORD_ALIGN != 0) {
          llvm::Type *ResType = llvm::Type::getInt32Ty(Ctx);
          auto *LLVMVecType = llvm::dyn_cast<llvm::FixedVectorType>(ArgType);
          int NumElem = LLVMVecType ? LLVMVecType->getNumElements() : 1;
          if (LLVMVecType && NumElem > 1)
            ResType = llvm::FixedVectorType::get(ResType, NumElem);
          Builder.SetInsertPoint(CI);
          Builder.SetCurrentDebugLocation(CI->getDebugLoc());
          if (OpConvSpecifiers[ArgCount - 1] == 'x' ||
              OpConvSpecifiers[ArgCount - 1] == 'X' ||
              OpConvSpecifiers[ArgCount - 1] == 'u' ||
              OpConvSpecifiers[ArgCount - 1] == 'o')
            Arg = Builder.CreateZExt(Arg, ResType);
          else
            Arg = Builder.CreateSExt(Arg, ResType);
          ArgType = Arg->getType();
          ArgSize = TD->getTypeAllocSizeInBits(ArgType);
          ArgSize = ArgSize / 8;
          CI->setOperand(ArgCount, Arg);
        }
        if (OpConvSpecifiers[ArgCount - 1] == 'f') {
          ConstantFP *FpCons = dyn_cast<ConstantFP>(Arg);
          if (FpCons)
            ArgSize = 4;
          else {
            FPExtInst *FpExt = dyn_cast<FPExtInst>(Arg);
            if (FpExt && FpExt->getType()->isDoubleTy() &&
                FpExt->getOperand(0)->getType()->isFloatTy())
              ArgSize = 4;
          }
        }
        if (shouldPrintAsStr(OpConvSpecifiers[ArgCount - 1], ArgType)) {
          if (auto *ConstExpr = dyn_cast<ConstantExpr>(Arg)) {
            auto *GV = dyn_cast<GlobalVariable>(ConstExpr->getOperand(0));
            if (GV && GV->hasInitializer()) {
              Constant *Init = GV->getInitializer();
              bool IsZeroValue = Init->isZeroValue();
              auto *CA = dyn_cast<ConstantDataArray>(Init);
              if (IsZeroValue || (CA && CA->isString())) {
                size_t SizeStr =
                    IsZeroValue ? 1 : (strlen(CA->getAsCString().data()) + 1);
                size_t Rem = SizeStr % DWORD_ALIGN;
                size_t NSizeStr = 0;
                LLVM_DEBUG(dbgs() << "Printf string original size = " << SizeStr
                                  << '\n');
                if (Rem) {
                  NSizeStr = SizeStr + (DWORD_ALIGN - Rem);
                } else {
                  NSizeStr = SizeStr;
                }
                ArgSize = NSizeStr;
              }
            } else {
              ArgSize = sizeof(NonLiteralStr);
            }
          } else {
            ArgSize = sizeof(NonLiteralStr);
          }
        }
        LLVM_DEBUG(dbgs() << "Printf ArgSize (in buffer) = " << ArgSize
                          << " for type: " << *ArgType << '\n');
        Sizes << ArgSize << ':';
        Sum += ArgSize;
      }
      LLVM_DEBUG(dbgs() << "Printf format string in source = " << Str.str()
                        << '\n');
      for (char C : Str) {
        // Rest of the C escape sequences (e.g. \') are handled correctly
        // by the MDParser
        switch (C) {
        case '\a':
          Sizes << "\\a";
          break;
        case '\b':
          Sizes << "\\b";
          break;
        case '\f':
          Sizes << "\\f";
          break;
        case '\n':
          Sizes << "\\n";
          break;
        case '\r':
          Sizes << "\\r";
          break;
        case '\v':
          Sizes << "\\v";
          break;
        case ':':
          // ':' cannot be scanned by Flex, as it is defined as a delimiter
          // Replace it with it's octal representation \72
          Sizes << "\\72";
          break;
        default:
          Sizes << C;
          break;
        }
      }

      // Insert the printf_alloc call
      Builder.SetInsertPoint(CI);
      Builder.SetCurrentDebugLocation(CI->getDebugLoc());

      AttributeList Attr = AttributeList::get(Ctx, AttributeList::FunctionIndex,
                                              Attribute::NoUnwind);

      Type *SizetTy = Type::getInt32Ty(Ctx);

      Type *Tys_alloc[1] = {SizetTy};
      Type *I8Ty = Type::getInt8Ty(Ctx);
      Type *I8Ptr = PointerType::get(I8Ty, 1);
      FunctionType *FTy_alloc = FunctionType::get(I8Ptr, Tys_alloc, false);
      FunctionCallee PrintfAllocFn =
          M.getOrInsertFunction(StringRef("__printf_alloc"), FTy_alloc, Attr);

      LLVM_DEBUG(dbgs() << "Printf metadata = " << Sizes.str() << '\n');
      std::string fmtstr = itostr(++UniqID) + ":" + Sizes.str();
      MDString *fmtStrArray = MDString::get(Ctx, fmtstr);

      // Instead of creating global variables, the
      // printf format strings are extracted
      // and passed as metadata. This avoids
      // polluting llvm's symbol tables in this module.
      // Metadata is going to be extracted
      // by the backend passes and inserted
      // into the OpenCL binary as appropriate.
      StringRef amd("llvm.printf.fmts");
      NamedMDNode *metaD = M.getOrInsertNamedMetadata(amd);
      MDNode *myMD = MDNode::get(Ctx, fmtStrArray);
      metaD->addOperand(myMD);
      Value *sumC = ConstantInt::get(SizetTy, Sum, false);
      SmallVector<Value *, 1> alloc_args;
      alloc_args.push_back(sumC);
      CallInst *pcall =
          CallInst::Create(PrintfAllocFn, alloc_args, "printf_alloc_fn", CI);

      //
      // Insert code to split basicblock with a
      // piece of hammock code.
      // basicblock splits after buffer overflow check
      //
      ConstantPointerNull *zeroIntPtr =
          ConstantPointerNull::get(PointerType::get(I8Ty, 1));
      auto *cmp = cast<ICmpInst>(Builder.CreateICmpNE(pcall, zeroIntPtr, ""));
      if (!CI->use_empty()) {
        Value *result =
            Builder.CreateSExt(Builder.CreateNot(cmp), I32Ty, "printf_res");
        CI->replaceAllUsesWith(result);
      }
      SplitBlock(CI->getParent(), cmp);
      Instruction *Brnch =
          SplitBlockAndInsertIfThen(cmp, cmp->getNextNode(), false);

      Builder.SetInsertPoint(Brnch);

      // store unique printf id in the buffer
      //
      GetElementPtrInst *BufferIdx = GetElementPtrInst::Create(
          I8Ty, pcall, ConstantInt::get(Ctx, APInt(32, 0)), "PrintBuffID",
          Brnch);

      Type *idPointer = PointerType::get(I32Ty, AMDGPUAS::GLOBAL_ADDRESS);
      Value *id_gep_cast =
          new BitCastInst(BufferIdx, idPointer, "PrintBuffIdCast", Brnch);

      new StoreInst(ConstantInt::get(I32Ty, UniqID), id_gep_cast, Brnch);

      // 1st 4 bytes hold the printf_id
      // the following GEP is the buffer pointer
      BufferIdx = GetElementPtrInst::Create(
          I8Ty, pcall, ConstantInt::get(Ctx, APInt(32, 4)), "PrintBuffGep",
          Brnch);

      Type *Int32Ty = Type::getInt32Ty(Ctx);
      Type *Int64Ty = Type::getInt64Ty(Ctx);
      for (unsigned ArgCount = 1;
           ArgCount < CI->arg_size() && ArgCount <= OpConvSpecifiers.size();
           ArgCount++) {
        Value *Arg = CI->getArgOperand(ArgCount);
        Type *ArgType = Arg->getType();
        SmallVector<Value *, 32> WhatToStore;
        if (ArgType->isFPOrFPVectorTy() && !isa<VectorType>(ArgType)) {
          Type *IType = (ArgType->isFloatTy()) ? Int32Ty : Int64Ty;
          if (OpConvSpecifiers[ArgCount - 1] == 'f') {
            if (auto *FpCons = dyn_cast<ConstantFP>(Arg)) {
              APFloat Val(FpCons->getValueAPF());
              bool Lost = false;
              Val.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven,
                          &Lost);
              Arg = ConstantFP::get(Ctx, Val);
              IType = Int32Ty;
            } else if (auto *FpExt = dyn_cast<FPExtInst>(Arg)) {
              if (FpExt->getType()->isDoubleTy() &&
                  FpExt->getOperand(0)->getType()->isFloatTy()) {
                Arg = FpExt->getOperand(0);
                IType = Int32Ty;
              }
            }
          }
          Arg = new BitCastInst(Arg, IType, "PrintArgFP", Brnch);
          WhatToStore.push_back(Arg);
        } else if (ArgType->getTypeID() == Type::PointerTyID) {
          if (shouldPrintAsStr(OpConvSpecifiers[ArgCount - 1], ArgType)) {
            const char *S = NonLiteralStr;
            if (auto *ConstExpr = dyn_cast<ConstantExpr>(Arg)) {
              auto *GV = dyn_cast<GlobalVariable>(ConstExpr->getOperand(0));
              if (GV && GV->hasInitializer()) {
                Constant *Init = GV->getInitializer();
                bool IsZeroValue = Init->isZeroValue();
                auto *CA = dyn_cast<ConstantDataArray>(Init);
                if (IsZeroValue || (CA && CA->isString())) {
                  S = IsZeroValue ? "" : CA->getAsCString().data();
                }
              }
            }
            size_t SizeStr = strlen(S) + 1;
            size_t Rem = SizeStr % DWORD_ALIGN;
            size_t NSizeStr = 0;
            if (Rem) {
              NSizeStr = SizeStr + (DWORD_ALIGN - Rem);
            } else {
              NSizeStr = SizeStr;
            }
            if (S[0]) {
              char *MyNewStr = new char[NSizeStr]();
              strcpy(MyNewStr, S);
              int NumInts = NSizeStr / 4;
              int CharC = 0;
              while (NumInts) {
                int ANum = *(int *)(MyNewStr + CharC);
                CharC += 4;
                NumInts--;
                Value *ANumV = ConstantInt::get(Int32Ty, ANum, false);
                WhatToStore.push_back(ANumV);
              }
              delete[] MyNewStr;
            } else {
              // Empty string, give a hint to RT it is no NULL
              Value *ANumV = ConstantInt::get(Int32Ty, 0xFFFFFF00, false);
              WhatToStore.push_back(ANumV);
            }
          } else {
            uint64_t Size = TD->getTypeAllocSizeInBits(ArgType);
            assert((Size == 32 || Size == 64) && "unsupported size");
            Type *DstType = (Size == 32) ? Int32Ty : Int64Ty;
            Arg = new PtrToIntInst(Arg, DstType, "PrintArgPtr", Brnch);
            WhatToStore.push_back(Arg);
          }
        } else if (isa<FixedVectorType>(ArgType)) {
          Type *IType = nullptr;
          uint32_t EleCount = cast<FixedVectorType>(ArgType)->getNumElements();
          uint32_t EleSize = ArgType->getScalarSizeInBits();
          uint32_t TotalSize = EleCount * EleSize;
          if (EleCount == 3) {
            ShuffleVectorInst *Shuffle =
                new ShuffleVectorInst(Arg, Arg, ArrayRef<int>{0, 1, 2, 2});
            Shuffle->insertBefore(Brnch);
            Arg = Shuffle;
            ArgType = Arg->getType();
            TotalSize += EleSize;
          }
          switch (EleSize) {
          default:
            EleCount = TotalSize / 64;
            IType = Type::getInt64Ty(ArgType->getContext());
            break;
          case 8:
            if (EleCount >= 8) {
              EleCount = TotalSize / 64;
              IType = Type::getInt64Ty(ArgType->getContext());
            } else if (EleCount >= 3) {
              EleCount = 1;
              IType = Type::getInt32Ty(ArgType->getContext());
            } else {
              EleCount = 1;
              IType = Type::getInt16Ty(ArgType->getContext());
            }
            break;
          case 16:
            if (EleCount >= 3) {
              EleCount = TotalSize / 64;
              IType = Type::getInt64Ty(ArgType->getContext());
            } else {
              EleCount = 1;
              IType = Type::getInt32Ty(ArgType->getContext());
            }
            break;
          }
          if (EleCount > 1) {
            IType = FixedVectorType::get(IType, EleCount);
          }
          Arg = new BitCastInst(Arg, IType, "PrintArgVect", Brnch);
          WhatToStore.push_back(Arg);
        } else {
          WhatToStore.push_back(Arg);
        }
        for (unsigned I = 0, E = WhatToStore.size(); I != E; ++I) {
          Value *TheBtCast = WhatToStore[I];
          unsigned ArgSize =
              TD->getTypeAllocSizeInBits(TheBtCast->getType()) / 8;
          SmallVector<Value *, 1> BuffOffset;
          BuffOffset.push_back(ConstantInt::get(I32Ty, ArgSize));

          Type *ArgPointer = PointerType::get(TheBtCast->getType(), 1);
          Value *CastedGEP =
              new BitCastInst(BufferIdx, ArgPointer, "PrintBuffPtrCast", Brnch);
          StoreInst *StBuff = new StoreInst(TheBtCast, CastedGEP, Brnch);
          LLVM_DEBUG(dbgs() << "inserting store to printf buffer:\n"
                            << *StBuff << '\n');
          (void)StBuff;
          if (I + 1 == E && ArgCount + 1 == CI->arg_size())
            break;
          BufferIdx = GetElementPtrInst::Create(I8Ty, BufferIdx, BuffOffset,
                                                "PrintBuffNextPtr", Brnch);
          LLVM_DEBUG(dbgs() << "inserting gep to the printf buffer:\n"
                            << *BufferIdx << '\n');
        }
      }
    }
  }

  // erase the printf calls
  for (auto CI : Printfs)
    CI->eraseFromParent();

  Printfs.clear();
  return true;
}

bool AMDGPUPrintfRuntimeBindingImpl::run(Module &M) {
  Triple TT(M.getTargetTriple());
  if (TT.getArch() == Triple::r600)
    return false;

  auto PrintfFunction = M.getFunction("printf");
  if (!PrintfFunction)
    return false;

  for (auto &U : PrintfFunction->uses()) {
    if (auto *CI = dyn_cast<CallInst>(U.getUser())) {
      if (CI->isCallee(&U))
        Printfs.push_back(CI);
    }
  }

  if (Printfs.empty())
    return false;

  if (auto HostcallFunction = M.getFunction("__ockl_hostcall_internal")) {
    for (auto &U : HostcallFunction->uses()) {
      if (auto *CI = dyn_cast<CallInst>(U.getUser())) {
        M.getContext().emitError(
            CI, "Cannot use both printf and hostcall in the same module");
      }
    }
  }

  TD = &M.getDataLayout();

  return lowerPrintfForGpu(M);
}

bool AMDGPUPrintfRuntimeBinding::runOnModule(Module &M) {
  auto GetDT = [this](Function &F) -> DominatorTree & {
    return this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
  };
  auto GetTLI = [this](Function &F) -> TargetLibraryInfo & {
    return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
  };

  return AMDGPUPrintfRuntimeBindingImpl(GetDT, GetTLI).run(M);
}

PreservedAnalyses
AMDGPUPrintfRuntimeBindingPass::run(Module &M, ModuleAnalysisManager &AM) {
  FunctionAnalysisManager &FAM =
      AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
  auto GetDT = [&FAM](Function &F) -> DominatorTree & {
    return FAM.getResult<DominatorTreeAnalysis>(F);
  };
  auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
    return FAM.getResult<TargetLibraryAnalysis>(F);
  };
  bool Changed = AMDGPUPrintfRuntimeBindingImpl(GetDT, GetTLI).run(M);
  return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
}
