21#include "llvm/IR/IntrinsicsDirectX.h"
27#define DEBUG_TYPE "dxil-forward-handle-accesses"
36 Twine(
"Handle at \"") + NewII->
getName() +
"\" overwrites handle at \"" +
45 "\" is not a global resource handle"));
53 "\" is not dominated by handle creation at \"" +
60 for (
User *U :
II->users())
65 LLVM_DEBUG(
dbgs() <<
"Added " << GV->getName() <<
" to handle map\n");
80 switch (
II->getIntrinsicID()) {
81 case Intrinsic::dx_resource_handlefrombinding:
82 case Intrinsic::dx_resource_handlefromimplicitbinding:
85 case Intrinsic::lifetime_start:
86 case Intrinsic::lifetime_end:
87 if (
II->arg_size() >= 1) {
90 LifeTimeIntrinsicMap[Alloca].push_back(
II);
100 for (
LoadInst *LI : LoadsToProcess) {
101 Value *V = LI->getPointerOperand();
110 NestedLI, NestedLI->getParent(), BBI, 0,
nullptr,
nullptr);
114 if (
auto It = LifeTimeIntrinsicMap.
find(NestedAlloca);
115 It != LifeTimeIntrinsicMap.
end()) {
118 LifeTimeIntrinsicMap.
erase(It);
121 for (
auto *
User : NestedAlloca->
users()) {
126 Value *StoredVal = Store->getValueOperand();
146 BBI, 0,
nullptr,
nullptr);
155 auto It = HandleMap.
find(GV);
156 if (It == HandleMap.
end()) {
167 LLVM_DEBUG(
dbgs() <<
"Replacing uses of " << GV->getName() <<
" at "
168 << LI->getName() <<
" with " << It->second->getName()
170 LI->replaceAllUsesWith(It->second);
171 LI->eraseFromParent();
190class DXILForwardHandleAccessesLegacy :
public FunctionPass {
193 DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
197 return "DXIL Forward Handle Accesses";
200 void getAnalysisUsage(AnalysisUsage &AU)
const override {
204 DXILForwardHandleAccessesLegacy() : FunctionPass(
ID) {}
208char DXILForwardHandleAccessesLegacy::ID = 0;
212 "DXIL Forward Handle Accesses",
false,
false)
218 return new DXILForwardHandleAccessesLegacy();
static void diagnoseHandleNotFound(LoadInst *LI)
static void diagnoseUndominatedLoad(LoadInst *LI, IntrinsicInst *Handle)
static void diagnoseAmbiguousHandle(IntrinsicInst *NewII, IntrinsicInst *PrevII)
static bool forwardHandleAccesses(Function &F, DominatorTree &DT)
static void processHandle(IntrinsicInst *II, DenseMap< GlobalVariable *, IntrinsicInst * > &HandleMap)
static bool runOnFunction(Function &F, bool PostInlining)
Module.h This file contains the declarations for the Module class.
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
LLVM Basic Block Representation.
InstListType::iterator iterator
Instruction iterators...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
bool erase(const KeyT &Val)
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
FunctionPass class - This class is used to implement most global optimizations.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
Value * getPointerOperand()
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
iterator_range< user_iterator > users()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI Value * FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan=DefMaxInstsToScan, BatchAAResults *AA=nullptr, bool *IsLoadCSE=nullptr, unsigned *NumScanedInst=nullptr)
Scan backwards to see if we have the value of the given load available locally within a small number ...
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
FunctionPass * createDXILForwardHandleAccessesLegacyPass()
Pass to eliminate redundant stores and loads from handle globals.