//===- DXILResourceAccess.cpp - Resource access via load/store ------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "DXILRemoveUnusedResources.h"
#include "DirectX.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Dominators.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/LLVMContext.h"
#include "llvm/InitializePasses.h"
#include "llvm/Transforms/Utils/ValueMapper.h"

#define DEBUG_TYPE "dxil-remove-unused-resources"

// Hidden option to disable the pass to make it easier to test
// other passes related to DXIL resources using llc.
static llvm::cl::opt<bool> DisableDXILRemoveUnusedResources(
    "disable-dxil-remove-unused-resources",
    llvm::cl::desc("Disable dxil-remove-unused-resources pass"),
    llvm::cl::init(false), llvm::cl::Hidden);

using namespace llvm;

static bool isResourceHandleCreation(Intrinsic::ID ID) {
  return ID == Intrinsic::dx_resource_handlefrombinding ||
         ID == Intrinsic::dx_resource_handlefromimplicitbinding ||
         ID == Intrinsic::dx_resource_handlefromheap;
}

// Removes all calls to resource handle creation intrinsics that
// either are not used, or their only use is in a store instruction, which
// stores the initialized handle into a global variable that does not have
// external linkage and that is not used anywhere else in the module.
static bool removeUnusedResources(Function &F) {
  if (DisableDXILRemoveUnusedResources)
    return false;

  SmallVector<Instruction *> DeadInstr;
  SmallSetVector<GlobalVariable *, 4> DeadGlobals;
  for (BasicBlock &BB : make_early_inc_range(F)) {
    for (Instruction &I : BB) {
      if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
        if (!isResourceHandleCreation(II->getIntrinsicID()))
          continue;
        if (II->user_empty()) {
          // Initialized handle is not used anywhere.
          DeadInstr.push_back(II);
          continue;
        }
        if (!II->hasOneUser())
          continue;

        // Initialized handle is only used in one store instruction, the store
        // is into global variable, and that global variable is not used
        // anywhere else and does not have external linkage.
        auto *SI = dyn_cast<StoreInst>(*II->user_begin());
        if (!SI)
          continue;
        assert(SI->getValueOperand() == II &&
               "expected value operand to be the resource handle");

        GlobalVariable *GV = dyn_cast<GlobalVariable>(SI->getPointerOperand());
        if (!GV || GV->hasExternalLinkage())
          continue;

        if (GV->hasOneUser()) {
          assert(*GV->user_begin() == SI &&
                 "expected single user to be the store instruction");
          DeadInstr.push_back(SI);
          DeadInstr.push_back(II);
          DeadGlobals.insert(GV);
        }
      }
    }
  }

  if (DeadInstr.empty())
    return false;

  for (auto *Instr : DeadInstr) {
    if (auto *II = dyn_cast<IntrinsicInst>(Instr)) {
      assert(isResourceHandleCreation(II->getIntrinsicID()));
      // A heap resource does not have an associated global variable to remove.
      if (II->getIntrinsicID() == Intrinsic::dx_resource_handlefromheap)
        continue;
      const unsigned ResourceNameOpIndex = 4;
      GlobalVariable *ResourceName = dyn_cast_or_null<GlobalVariable>(
          II->getArgOperand(ResourceNameOpIndex));
      if (ResourceName)
        DeadGlobals.insert(ResourceName);
    }
    Instr->eraseFromParent();
  }

  for (auto *GV : DeadGlobals)
    if (GV->use_empty())
      GV->eraseFromParent();

  return true;
}

PreservedAnalyses DXILRemoveUnusedResources::run(Function &F,
                                                 FunctionAnalysisManager &AM) {
  removeUnusedResources(F);
  return PreservedAnalyses::all();
}

namespace {
class DXILRemoveUnusedResourcesLegacy : public FunctionPass {
public:
  bool runOnFunction(Function &F) override { return removeUnusedResources(F); }
  StringRef getPassName() const override {
    return "DXIL Remove Unused Resources";
  }
  DXILRemoveUnusedResourcesLegacy() : FunctionPass(ID) {}

  static char ID; // Pass identification.
  void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
    AU.setPreservesAll();
  }
};
char DXILRemoveUnusedResourcesLegacy::ID = 0;
} // end anonymous namespace

INITIALIZE_PASS_BEGIN(DXILRemoveUnusedResourcesLegacy, DEBUG_TYPE,
                      "DXIL Remove Unused Resources", false, false)
INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
INITIALIZE_PASS_END(DXILRemoveUnusedResourcesLegacy, DEBUG_TYPE,
                    "DXIL Remove Unused Resources", false, false)

FunctionPass *llvm::createDXILRemoveUnusedResourcesLegacyPass() {
  return new DXILRemoveUnusedResourcesLegacy();
}
