//===- DXILShaderFlags.cpp - DXIL Shader Flags helper objects -------------===//
//
// 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 This file contains helper objects and APIs for working with DXIL
///       Shader Flags.
///
//===----------------------------------------------------------------------===//

#include "DXILShaderFlags.h"
#include "DirectX.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/DXILResource.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsDirectX.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace llvm::dxil;

static bool hasUAVsAtEveryStage(const DXILResourceMap &DRM,
                                const ModuleMetadataInfo &MMDI) {
  // Heap resources do not count towards hasUAVsAtEveryStage.
  bool HasUAVWithBinding = any_of(
      DRM.uavs(), [](const ResourceInfo &RI) { return RI.hasBinding(); });
  if (!HasUAVWithBinding)
    return false;

  switch (MMDI.ShaderProfile) {
  default:
    return false;
  case Triple::EnvironmentType::Compute:
  case Triple::EnvironmentType::Pixel:
    return false;
  case Triple::EnvironmentType::Vertex:
  case Triple::EnvironmentType::Geometry:
  case Triple::EnvironmentType::Hull:
  case Triple::EnvironmentType::Domain:
    return true;
  case Triple::EnvironmentType::Library:
  case Triple::EnvironmentType::RayGeneration:
  case Triple::EnvironmentType::Intersection:
  case Triple::EnvironmentType::AnyHit:
  case Triple::EnvironmentType::ClosestHit:
  case Triple::EnvironmentType::Miss:
  case Triple::EnvironmentType::Callable:
  case Triple::EnvironmentType::Mesh:
  case Triple::EnvironmentType::Amplification:
    return MMDI.ValidatorVersion < VersionTuple(1, 8);
  }
}

static bool checkWaveOps(Intrinsic::ID IID) {
  // Currently unsupported intrinsics
  // case Intrinsic::dx_wave_readfirst:
  // case Intrinsic::dx_wave_reduce.and:
  // case Intrinsic::dx_wave_reduce.or:
  // case Intrinsic::dx_wave_reduce.xor:
  // case Intrinsic::dx_wave_prefixop:
  // case Intrinsic::dx_quad.readat:
  // case Intrinsic::dx_quad.readacrossy:
  // case Intrinsic::dx_quad.readacrossdiagonal:
  // case Intrinsic::dx_wave_prefixballot:
  // case Intrinsic::dx_wave_match:
  // case Intrinsic::dx_wavemulti.*:
  // case Intrinsic::dx_wavemulti.ballot:
  // case Intrinsic::dx_quad.vote:
  switch (IID) {
  default:
    return false;
  case Intrinsic::dx_wave_is_first_lane:
  case Intrinsic::dx_wave_getlaneindex:
  case Intrinsic::dx_wave_get_lane_count:
  case Intrinsic::dx_wave_any:
  case Intrinsic::dx_wave_all_equal:
  case Intrinsic::dx_wave_all:
  case Intrinsic::dx_wave_readlane:
  case Intrinsic::dx_wave_active_countbits:
  case Intrinsic::dx_wave_ballot:
  case Intrinsic::dx_wave_prefix_bit_count:
  // Wave Active Op Variants
  case Intrinsic::dx_wave_reduce_or:
  case Intrinsic::dx_wave_reduce_xor:
  case Intrinsic::dx_wave_reduce_and:
  case Intrinsic::dx_wave_reduce_sum:
  case Intrinsic::dx_wave_reduce_usum:
  case Intrinsic::dx_wave_product:
  case Intrinsic::dx_wave_uproduct:
  case Intrinsic::dx_wave_reduce_max:
  case Intrinsic::dx_wave_reduce_umax:
  case Intrinsic::dx_wave_reduce_min:
  case Intrinsic::dx_wave_reduce_umin:
    // Wave Prefix Op Variants
  case Intrinsic::dx_wave_prefix_sum:
  case Intrinsic::dx_wave_prefix_usum:
  case Intrinsic::dx_wave_prefix_product:
  case Intrinsic::dx_wave_prefix_uproduct:
    // Quad Op Variants
  case Intrinsic::dx_quad_read_across_x:
  case Intrinsic::dx_quad_read_across_y:
  case Intrinsic::dx_quad_read_across_diagonal:
    return true;
  }
}

static bool checkDoubleExtensionOps(Intrinsic::ID IID) {
  switch (IID) {
  default:
    return false;
  case Intrinsic::fma:
    return true;
  }
}

/// Texture load and sample operations accept "programmable offsets", i.e.
/// offsets that are not compile-time constants. Such offsets require the
/// AdvancedTextureOps shader feature flag. Returns true if \p II is one of
/// those operations and its offsets operand is not a constant.
static bool checkAdvancedTextureOps(const IntrinsicInst &II) {
  // TODO: (#116137) Several other DXIL ops also require this feature flag, but
  // none of them can be generated yet:
  //  - SampleCmp, SampleCmpBias, SampleCmpGrad and SampleCmpLevelZero set the
  //    flag for non-constant offsets, exactly like the ops handled below.
  //  - SampleCmpLevel, TextureGatherRaw and TextureStoreSample set the flag
  //    unconditionally, and have no intrinsics yet.

  // The offsets operand index differs between the intrinsics.
  unsigned OffsetsIdx;
  switch (II.getIntrinsicID()) {
  default:
    return false;
  case Intrinsic::dx_resource_load_level:
  case Intrinsic::dx_resource_sample:
  case Intrinsic::dx_resource_sample_clamp:
    OffsetsIdx = 3;
    break;
  case Intrinsic::dx_resource_samplebias:
  case Intrinsic::dx_resource_samplebias_clamp:
  case Intrinsic::dx_resource_samplelevel:
    OffsetsIdx = 4;
    break;
  case Intrinsic::dx_resource_samplegrad:
  case Intrinsic::dx_resource_samplegrad_clamp:
    OffsetsIdx = 5;
    break;
  }
  return !isa<Constant>(II.getArgOperand(OffsetsIdx));
}

static bool isOptimizationDisabled(const Module &M) {
  const StringRef Key = "dx.disable_optimizations";
  if (auto *Flag = mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(Key)))
    return Flag->getValue().getBoolValue();
  return false;
}

// Checks to see if the status bit from a load with status
// instruction is ever extracted. If it is, the module needs
// to have the TiledResources shader flag set.
bool checkIfStatusIsExtracted(const IntrinsicInst &II) {
  [[maybe_unused]] Intrinsic::ID IID = II.getIntrinsicID();
  assert(IID == Intrinsic::dx_resource_load_typedbuffer ||
         IID == Intrinsic::dx_resource_load_rawbuffer &&
             "unexpected intrinsic ID");
  for (const User *U : II.users()) {
    if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(U)) {
      // Resource load operations return a {result, status} pair.
      // Check if we extract the status
      if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 1)
        return true;
    }
  }

  return false;
}

/// Update the shader flags mask based on the given instruction.
/// \param CSF Shader flags mask to update.
/// \param I Instruction to check.
void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
                                            const Instruction &I,
                                            DXILResourceTypeMap &DRTM,
                                            const ModuleMetadataInfo &MMDI) {
  if (!CSF.Doubles)
    CSF.Doubles = I.getType()->getScalarType()->isDoubleTy();

  if (!CSF.Doubles) {
    for (const Value *Op : I.operands()) {
      if (Op->getType()->getScalarType()->isDoubleTy()) {
        CSF.Doubles = true;
        break;
      }
    }
  }

  if (CSF.Doubles) {
    switch (I.getOpcode()) {
    case Instruction::FDiv:
    case Instruction::UIToFP:
    case Instruction::SIToFP:
    case Instruction::FPToUI:
    case Instruction::FPToSI:
      CSF.DX11_1_DoubleExtensions = true;
      break;
    }
  }

  if (!CSF.LowPrecisionPresent)
    CSF.LowPrecisionPresent = I.getType()->getScalarType()->isIntegerTy(16) ||
                              I.getType()->getScalarType()->isHalfTy();

  if (!CSF.LowPrecisionPresent) {
    for (const Value *Op : I.operands()) {
      if (Op->getType()->getScalarType()->isIntegerTy(16) ||
          Op->getType()->getScalarType()->isHalfTy()) {
        CSF.LowPrecisionPresent = true;
        break;
      }
    }
  }

  if (CSF.LowPrecisionPresent) {
    if (CSF.NativeLowPrecisionMode)
      CSF.NativeLowPrecision = true;
    else
      CSF.MinimumPrecision = true;
  }

  if (!CSF.Int64Ops)
    CSF.Int64Ops = I.getType()->getScalarType()->isIntegerTy(64);

  if (!CSF.Int64Ops && !isa<LifetimeIntrinsic>(&I)) {
    for (const Value *Op : I.operands()) {
      if (Op->getType()->getScalarType()->isIntegerTy(64)) {
        CSF.Int64Ops = true;
        break;
      }
    }
  }

  if (const auto *II = dyn_cast<IntrinsicInst>(&I)) {
    CSF.AdvancedTextureOps |= checkAdvancedTextureOps(*II);

    switch (II->getIntrinsicID()) {
    default:
      break;
    case Intrinsic::dx_resource_handlefrombinding: {
      dxil::ResourceTypeInfo &RTI = DRTM[cast<TargetExtType>(II->getType())];

      // Set ResMayNotAlias if DXIL validator version >= 1.8 and the function
      // uses UAVs
      if (!CSF.ResMayNotAlias && CanSetResMayNotAlias &&
          MMDI.ValidatorVersion >= VersionTuple(1, 8) && RTI.isUAV())
        CSF.ResMayNotAlias = true;

      switch (RTI.getResourceKind()) {
      case dxil::ResourceKind::StructuredBuffer:
      case dxil::ResourceKind::RawBuffer:
        CSF.EnableRawAndStructuredBuffers = true;
        break;
      default:
        break;
      }
      break;
    }
    case Intrinsic::dx_resource_handlefromheap: {
      dxil::ResourceTypeInfo &RTI = DRTM[cast<TargetExtType>(II->getType())];
      bool IsSamplerHeap = RTI.isSampler();
      CSF.SamplerDescriptorHeapIndexing |= IsSamplerHeap;
      CSF.ResourceDescriptorHeapIndexing |= !IsSamplerHeap;

      if (!CSF.ResMayNotAlias && CanSetResMayNotAlias && RTI.isUAV() &&
          MMDI.ValidatorVersion >= VersionTuple(1, 8)) {
        CSF.ResMayNotAlias = true;
      }
      break;
    }
    case Intrinsic::dx_resource_load_typedbuffer: {
      dxil::ResourceTypeInfo &RTI =
          DRTM[cast<TargetExtType>(II->getArgOperand(0)->getType())];
      if (RTI.isTyped() && RTI.isUAV())
        CSF.TypedUAVLoadAdditionalFormats |= RTI.getTyped().ElementCount > 1;
      if (!CSF.TiledResources && checkIfStatusIsExtracted(*II))
        CSF.TiledResources = true;
      break;
    }
    case Intrinsic::dx_resource_load_rawbuffer: {
      if (!CSF.TiledResources && checkIfStatusIsExtracted(*II))
        CSF.TiledResources = true;
      break;
    }
    case Intrinsic::dx_resource_atomic_binop: {
      if (II->getType()->isIntegerTy(64)) {
        dxil::ResourceTypeInfo &RTI =
            DRTM[cast<TargetExtType>(II->getArgOperand(0)->getType())];
        if (RTI.isTyped())
          CSF.AtomicInt64OnTypedResource = true;
        // TODO(https://github.com/llvm/llvm-project/issues/116152): Set
        // AtomicInt64OnHeapResource when heap-resource intrinsics are added.
      }
      break;
    }
    }
  }
  // 64-bit atomics on groupshared memory (address space 3).
  if (const auto *ARMW = dyn_cast<AtomicRMWInst>(&I)) {
    if (ARMW->getValOperand()->getType()->isIntegerTy(64) &&
        ARMW->getPointerAddressSpace() == 3)
      CSF.AtomicInt64OnGroupShared = true;
  } else if (const auto *AXCG = dyn_cast<AtomicCmpXchgInst>(&I)) {
    if (AXCG->getNewValOperand()->getType()->isIntegerTy(64) &&
        AXCG->getPointerAddressSpace() == 3)
      CSF.AtomicInt64OnGroupShared = true;
  }
  // Handle call instructions
  if (auto *CI = dyn_cast<CallInst>(&I)) {
    const Function *CF = CI->getCalledFunction();
    // Merge-in shader flags mask of the called function in the current module
    if (FunctionFlags.contains(CF))
      CSF.merge(FunctionFlags[CF]);

    CSF.DX11_1_DoubleExtensions |=
        checkDoubleExtensionOps(CI->getIntrinsicID());
    CSF.WaveOps |= checkWaveOps(CI->getIntrinsicID());
  }
}

/// Set shader flags that apply to all functions within the module
ComputedShaderFlags
ModuleShaderFlags::gatherGlobalModuleFlags(const Module &M,
                                           const DXILResourceMap &DRM,
                                           const ModuleMetadataInfo &MMDI) {

  ComputedShaderFlags CSF;

  CSF.DisableOptimizations = isOptimizationDisabled(M);

  CSF.UAVsAtEveryStage = hasUAVsAtEveryStage(DRM, MMDI);

  // Set the Max64UAVs flag if the number of UAVs is > 8
  uint32_t NumUAVs = 0;
  for (auto &UAV : DRM.uavs()) {
    // Heap resources do not count towards Max64UAVs flag.
    if (!UAV.hasBinding())
      continue;
    if (MMDI.ValidatorVersion < VersionTuple(1, 6)) {
      NumUAVs++;
    } else { // MMDI.ValidatorVersion >= VersionTuple(1, 6)
      uint32_t Size = UAV.getSize();
      uint32_t NewNum = NumUAVs + (Size == 0 ? ~0U : Size);
      if (NewNum < NumUAVs)
        NewNum = ~0U;
      NumUAVs = NewNum;
    }
  }
  if (NumUAVs > 8)
    CSF.Max64UAVs = true;

  // Set the module flag that enables native low-precision execution mode.
  // NativeLowPrecisionMode can only be set when the command line option
  // -enable-16bit-types is provided. This is indicated by the dx.nativelowprec
  // module flag being set
  // This flag is needed even if the module does not use 16-bit types because a
  // corresponding debug module may include 16-bit types, and tools that use the
  // debug module may expect it to have the same flags as the original
  if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>(
          M.getModuleFlag("dx.nativelowprec")))
    if (MMDI.ShaderModelVersion >= VersionTuple(6, 2))
      CSF.NativeLowPrecisionMode = NativeLowPrec->getValue().getBoolValue();

  // Set ResMayNotAlias to true if DXIL validator version < 1.8 and there
  // are UAVs present globally.
  if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8))
    CSF.ResMayNotAlias = !DRM.uavs().empty();

  // The command line option -all-resources-bound will set the
  // dx.allresourcesbound module flag to 1
  if (auto *AllResourcesBound = mdconst::extract_or_null<ConstantInt>(
          M.getModuleFlag("dx.allresourcesbound")))
    if (AllResourcesBound->getValue().getBoolValue())
      CSF.AllResourcesBound = true;

  return CSF;
}

/// Construct ModuleShaderFlags for module Module M
void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
                                   const DXILResourceMap &DRM,
                                   const ModuleMetadataInfo &MMDI) {

  CanSetResMayNotAlias = MMDI.DXILVersion >= VersionTuple(1, 7);
  // The command line option -res-may-alias will set the dx.resmayalias module
  // flag to 1, thereby disabling the ability to set the ResMayNotAlias flag
  if (auto *ResMayAlias = mdconst::extract_or_null<ConstantInt>(
          M.getModuleFlag("dx.resmayalias")))
    if (ResMayAlias->getValue().getBoolValue())
      CanSetResMayNotAlias = false;

  ComputedShaderFlags GlobalSFMask = gatherGlobalModuleFlags(M, DRM, MMDI);

  CallGraph CG(M);

  // Compute Shader Flags Mask for all functions using post-order visit of SCC
  // of the call graph.
  for (scc_iterator<CallGraph *> SCCI = scc_begin(&CG); !SCCI.isAtEnd();
       ++SCCI) {
    const std::vector<CallGraphNode *> &CurSCC = *SCCI;

    // Union of shader masks of all functions in CurSCC
    ComputedShaderFlags SCCSF;
    // List of functions in CurSCC that are neither external nor declarations
    // and hence whose flags are collected
    SmallVector<Function *> CurSCCFuncs;
    for (CallGraphNode *CGN : CurSCC) {
      Function *F = CGN->getFunction();
      if (!F)
        continue;

      if (F->isDeclaration()) {
        assert(!F->getName().starts_with("dx.op.") &&
               "DXIL Shader Flag analysis should not be run post-lowering.");
        continue;
      }

      ComputedShaderFlags CSF = GlobalSFMask;
      for (const auto &BB : *F)
        for (const auto &I : BB)
          updateFunctionFlags(CSF, I, DRTM, MMDI);
      // Update combined shader flags mask for all functions in this SCC
      SCCSF.merge(CSF);

      CurSCCFuncs.push_back(F);
    }

    // Update combined shader flags mask for all functions of the module
    CombinedSFMask.merge(SCCSF);

    // Shader flags mask of each of the functions in an SCC of the call graph is
    // the union of all functions in the SCC. Update shader flags masks of
    // functions in CurSCC accordingly. This is trivially true if SCC contains
    // one function.
    for (Function *F : CurSCCFuncs)
      // Merge SCCSF with that of F
      FunctionFlags[F].merge(SCCSF);
  }
}

void ComputedShaderFlags::print(raw_ostream &OS) const {
  uint64_t FlagVal = (uint64_t) * this;
  OS << formatv("; Shader Flags Value: {0:x8}\n;\n", FlagVal);
  if (FlagVal == 0)
    return;
  OS << "; Note: shader requires additional functionality:\n";
#define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleNum, FlagName, Str)          \
  if (FlagName)                                                                \
    (OS << ";").indent(7) << Str << "\n";
#include "llvm/BinaryFormat/DXContainerConstants.def"
  OS << "; Note: extra DXIL module flags:\n";
#define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str)                         \
  if (FlagName)                                                                \
    (OS << ";").indent(7) << Str << "\n";
#include "llvm/BinaryFormat/DXContainerConstants.def"
  OS << ";\n";
}

/// Return the shader flags mask of the specified function Func.
const ComputedShaderFlags &
ModuleShaderFlags::getFunctionFlags(const Function *Func) const {
  auto Iter = FunctionFlags.find(Func);
  assert((Iter != FunctionFlags.end() && Iter->first == Func) &&
         "Get Shader Flags : No Shader Flags Mask exists for function");
  return Iter->second;
}

//===----------------------------------------------------------------------===//
// ShaderFlagsAnalysis and ShaderFlagsAnalysisPrinterPass

// Provide an explicit template instantiation for the static ID.
AnalysisKey ShaderFlagsAnalysis::Key;

ModuleShaderFlags ShaderFlagsAnalysis::run(Module &M,
                                           ModuleAnalysisManager &AM) {
  DXILResourceTypeMap &DRTM = AM.getResult<DXILResourceTypeAnalysis>(M);
  DXILResourceMap &DRM = AM.getResult<DXILResourceAnalysis>(M);
  const ModuleMetadataInfo MMDI = AM.getResult<DXILMetadataAnalysis>(M);

  ModuleShaderFlags MSFI;
  MSFI.initialize(M, DRTM, DRM, MMDI);

  return MSFI;
}

PreservedAnalyses ShaderFlagsAnalysisPrinter::run(Module &M,
                                                  ModuleAnalysisManager &AM) {
  const ModuleShaderFlags &FlagsInfo = AM.getResult<ShaderFlagsAnalysis>(M);
  // Print description of combined shader flags for all module functions
  OS << "; Combined Shader Flags for Module\n";
  FlagsInfo.getCombinedFlags().print(OS);
  // Print shader flags mask for each of the module functions
  OS << "; Shader Flags for Module Functions\n";
  for (const auto &F : M.getFunctionList()) {
    if (F.isDeclaration())
      continue;
    const ComputedShaderFlags &SFMask = FlagsInfo.getFunctionFlags(&F);
    OS << formatv("; Function {0} : {1:x8}\n;\n", F.getName(),
                  (uint64_t)(SFMask));
  }

  return PreservedAnalyses::all();
}

//===----------------------------------------------------------------------===//
// ShaderFlagsAnalysis and ShaderFlagsAnalysisPrinterPass

bool ShaderFlagsAnalysisWrapper::runOnModule(Module &M) {
  DXILResourceTypeMap &DRTM =
      getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
  DXILResourceMap &DRM =
      getAnalysis<DXILResourceWrapperPass>().getResourceMap();
  const ModuleMetadataInfo MMDI =
      getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();

  MSFI.initialize(M, DRTM, DRM, MMDI);
  return false;
}

void ShaderFlagsAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequiredTransitive<DXILResourceTypeWrapperPass>();
  AU.addRequiredTransitive<DXILResourceWrapperPass>();
  AU.addRequired<DXILMetadataAnalysisWrapperPass>();
}

char ShaderFlagsAnalysisWrapper::ID = 0;

INITIALIZE_PASS_BEGIN(ShaderFlagsAnalysisWrapper, "dx-shader-flag-analysis",
                      "DXIL Shader Flag Analysis", true, true)
INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
INITIALIZE_PASS_END(ShaderFlagsAnalysisWrapper, "dx-shader-flag-analysis",
                    "DXIL Shader Flag Analysis", true, true)
