LLVM: lib/Target/DirectX/DXILResourceAccess.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

17#include "llvm/IR/IntrinsicsDirectX.h"

19

20#define DEBUG_TYPE "dxil-resource-access"

21

22using namespace llvm;

23

27

28 auto *HandleType = cast(II->getOperand(0)->getType());

29 assert(HandleType->getName() == "dx.TypedBuffer" &&

30 "Unexpected typed buffer type");

31 Type *ContainedType = HandleType->getTypeParameter(0);

32

33 Type *LoadType =

35

36

37

39 uint64_t ScalarSize = DL.getTypeSizeInBits(ScalarType) / 8;

40

41

42 struct AccessAndIndex {

45 };

47 for (User *U : II->users())

49

51 while (!Worklist.empty()) {

52 AccessAndIndex Current = Worklist.back();

54

55 if (auto *GEP = dyn_cast(Current.Access)) {

57

59 APInt ConstantOffset(DL.getIndexTypeSizeInBits(GEP->getType()), 0);

60 if (GEP->accumulateConstantOffset(DL, ConstantOffset)) {

63 } else {

64 auto IndexIt = GEP->idx_begin();

65 assert(cast(IndexIt)->getZExtValue() == 0 &&

66 "GEP is not indexing through pointer");

67 ++IndexIt;

68 Index = *IndexIt;

69 assert(++IndexIt == GEP->idx_end() && "Too many indices in GEP");

70 }

71

72 for (User *U : GEP->users())

75

76 } else if (auto *SI = dyn_cast(Current.Access)) {

77 assert(SI->getValueOperand() != II && "Pointer escaped!");

79

80 Value *V = SI->getValueOperand();

81 if (V->getType() == ContainedType) {

82

83 } else if (V->getType() == ScalarType) {

84

85

87 LoadType, Intrinsic::dx_resource_load_typedbuffer,

88 {II->getOperand(0), II->getOperand(1)});

90

91

92 Value *IndexOp = Current.Index

93 ? Current.Index

94 : ConstantInt::get(Builder.getInt32Ty(), 0);

96 } else {

98 }

99

101 Builder.getVoidTy(), Intrinsic::dx_resource_store_typedbuffer,

102 {II->getOperand(0), II->getOperand(1), V});

103 SI->replaceAllUsesWith(Inst);

105

106 } else if (auto *LI = dyn_cast(Current.Access)) {

109 LoadType, Intrinsic::dx_resource_load_typedbuffer,

110 {II->getOperand(0), II->getOperand(1)});

112

113 if (Current.Index)

115

118

119 } else

120 llvm_unreachable("Unhandled instruction - pointer escaped?");

121 }

122

123

125 Dead->eraseFromParent();

126 II->eraseFromParent();

127}

128

130 bool Changed = false;

134 if (auto *II = dyn_cast(&I))

135 if (II->getIntrinsicID() == Intrinsic::dx_resource_getpointer) {

136 auto *HandleTy = cast(II->getArgOperand(0)->getType());

138 }

139

140 for (auto &[II, RI] : Resources) {

141 if (RI.isTyped()) {

142 Changed = true;

144 }

145

146

147

148 }

149

150 return Changed;

151}

152

158 assert(DRTM && "DXILResourceTypeAnalysis must be available");

159

161 if (!MadeChanges)

163

167 return PA;

168}

169

170namespace {

171class DXILResourceAccessLegacy : public FunctionPass {

172public:

175 getAnalysis().getResourceTypeMap();

176

178 }

179 StringRef getPassName() const override { return "DXIL Resource Access"; }

181

182 static char ID;

186 }

187};

188char DXILResourceAccessLegacy::ID = 0;

189}

190

192 "DXIL Resource Access", false, false)

196

198 return new DXILResourceAccessLegacy();

199}

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static void replaceTypedBufferAccess(IntrinsicInst *II, dxil::ResourceTypeInfo &RTI)

static bool transformResourcePointers(Function &F, DXILResourceTypeMap &DRTM)

static bool runOnFunction(Function &F, bool PostInlining)

uint64_t IntrinsicInst * II

FunctionAnalysisManager FAM

#define INITIALIZE_PASS_DEPENDENCY(depName)

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

Class for arbitrary precision integers.

APInt udiv(const APInt &RHS) const

Unsigned division operation.

A container for analyses that lazily runs them and caches their results.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

LLVM Basic Block Representation.

PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)

A parsed version of the target data layout string in and methods for querying it.

Analysis pass which computes a DominatorTree.

Legacy analysis pass which computes a DominatorTree.

FunctionPass class - This class is used to implement most global optimizations.

Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")

Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")

Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")

IntegerType * getInt32Ty()

Fetch the type representing a 32-bit integer.

CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")

Create a call to intrinsic ID with Args, mangled using Types.

Type * getVoidTy()

Fetch the type representing void.

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

A wrapper class for inspecting calls to intrinsic functions.

An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...

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 preserve()

Mark an analysis as preserved.

reference emplace_back(ArgTypes &&... Args)

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.

static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)

This static method is the primary way to create a literal StructType.

The instances of the Type class are immutable: once they are created, they are never changed.

static IntegerType * getInt1Ty(LLVMContext &C)

Type * getScalarType() const

If this is a vector type, return the element type, otherwise return 'this'.

LLVM Value Representation.

void replaceAllUsesWith(Value *V)

Change all uses of this to point to a new Value.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

This is an optimization pass for GlobalISel generic memory operations.

auto reverse(ContainerTy &&C)

FunctionPass * createDXILResourceAccessLegacyPass()

Pass to update resource accesses to use load/store directly.