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) {
88 Value *Ptr =
II->getArgOperand(0);
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()) {
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.
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.
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.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
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.