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

1

2

3

4

5

6

7

8

9

10

11

12

13

32

33#define DEBUG_TYPE "dxil-prepare"

34

35using namespace llvm;

37

38namespace {

39

42 Attribute::AlwaysInline,

43 Attribute::Builtin,

44 Attribute::ByVal,

45 Attribute::InAlloca,

46 Attribute::Cold,

47 Attribute::Convergent,

48 Attribute::InlineHint,

49 Attribute::InReg,

50 Attribute::JumpTable,

51 Attribute::MinSize,

52 Attribute::Naked,

53 Attribute::Nest,

54 Attribute::NoAlias,

55 Attribute::NoBuiltin,

56 Attribute::NoCapture,

57 Attribute::NoDuplicate,

58 Attribute::NoImplicitFloat,

59 Attribute::NoInline,

60 Attribute::NonLazyBind,

61 Attribute::NonNull,

62 Attribute::Dereferenceable,

63 Attribute::DereferenceableOrNull,

64 Attribute::Memory,

65 Attribute::NoRedZone,

66 Attribute::NoReturn,

67 Attribute::NoUnwind,

68 Attribute::OptimizeForSize,

69 Attribute::OptimizeNone,

70 Attribute::ReadNone,

71 Attribute::ReadOnly,

72 Attribute::Returned,

73 Attribute::ReturnsTwice,

74 Attribute::SExt,

75 Attribute::StackAlignment,

76 Attribute::StackProtect,

77 Attribute::StackProtectReq,

78 Attribute::StackProtectStrong,

79 Attribute::SafeStack,

80 Attribute::StructRet,

81 Attribute::SanitizeAddress,

82 Attribute::SanitizeThread,

83 Attribute::SanitizeMemory,

84 Attribute::UWTable,

85 Attribute::ZExt},

86 Attr);

87}

88

91 bool AllowExperimental) {

92 for (auto &Attr : AS) {

93 if (!Attr.isStringAttribute())

94 continue;

95 StringRef Key = Attr.getKindAsString();

97 continue;

98 if (AllowExperimental && Key.starts_with("exp-"))

99 continue;

101 }

102}

103

104static void removeStringFunctionAttributes(Function &F,

105 bool AllowExperimental) {

107 const StringSet<> LiveKeys = {"waveops-include-helper-lanes",

108 "fp32-denorm-mode"};

109

111 collectDeadStringAttrs(DeadAttrs, Attrs.getFnAttrs(), LiveKeys,

112 AllowExperimental);

113 collectDeadStringAttrs(DeadAttrs, Attrs.getRetAttrs(), LiveKeys,

114 AllowExperimental);

115

116 F.removeFnAttrs(DeadAttrs);

117 F.removeRetAttrs(DeadAttrs);

118}

119

120static void cleanModuleFlags(Module &M) {

121 NamedMDNode *MDFlags = M.getModuleFlagsMetadata();

122 if (!MDFlags)

123 return;

124

126 M.getModuleFlagsMetadata(FlagEntries);

127 bool Updated = false;

128 for (auto &Flag : FlagEntries) {

129

130 if (Flag.Behavior <= Module::ModFlagBehavior::AppendUnique)

131 continue;

132 Flag.Behavior = Module::ModFlagBehavior::Warning;

133 Updated = true;

134 }

135

136 if (!Updated)

137 return;

138

140

141 for (auto &Flag : FlagEntries)

142 M.addModuleFlag(Flag.Behavior, Flag.Key->getString(), Flag.Val);

143}

144

145class DXILPrepareModule : public ModulePass {

146

151

152 auto It = PointerTypes.find(Operand);

153 if (It != PointerTypes.end())

154 if (cast(It->second)->getElementType() == Ty)

155 return nullptr;

156

158

159

161 return Builder.Insert(

163 Builder.getPtrTy(PtrTy->getAddressSpace())));

164 }

165

166public:

172 if (!isValidForDXIL(I))

174 }

175

177 getAnalysis().getModuleMetadata();

179 bool SkipValidation = ValVer.getMajor() == 0 && ValVer.getMinor() == 0;

180

181 for (auto &F : M.functions()) {

182 F.removeFnAttrs(AttrMask);

183 F.removeRetAttrs(AttrMask);

184

185

186

187 removeStringFunctionAttributes(F, SkipValidation);

189 F.removeParamAttrs(Idx, AttrMask);

190

191 for (auto &BB : F) {

194 if (I.getOpcode() == Instruction::FNeg) {

196 Value *In = I.getOperand(0);

197 Value *Zero = ConstantFP::get(In->getType(), -0.0);

198 I.replaceAllUsesWith(Builder.CreateFSub(Zero, In));

199 I.eraseFromParent();

200 continue;

201 }

202

203

204

205 if (auto LI = dyn_cast(&I)) {

206 if (Value *NoOpBitcast = maybeGenerateBitcast(

207 Builder, PointerTypes, I, LI->getPointerOperand(),

208 LI->getType())) {

209 LI->replaceAllUsesWith(

210 Builder.CreateLoad(LI->getType(), NoOpBitcast));

211 LI->eraseFromParent();

212 }

213 continue;

214 }

215 if (auto SI = dyn_cast(&I)) {

216 if (Value *NoOpBitcast = maybeGenerateBitcast(

217 Builder, PointerTypes, I, SI->getPointerOperand(),

218 SI->getValueOperand()->getType())) {

219

220 SI->replaceAllUsesWith(

221 Builder.CreateStore(SI->getValueOperand(), NoOpBitcast));

222 SI->eraseFromParent();

223 }

224 continue;

225 }

226 if (auto GEP = dyn_cast(&I)) {

227 if (Value *NoOpBitcast = maybeGenerateBitcast(

228 Builder, PointerTypes, I, GEP->getPointerOperand(),

229 GEP->getSourceElementType()))

230 GEP->setOperand(0, NoOpBitcast);

231 continue;

232 }

233 if (auto *CB = dyn_cast(&I)) {

234 CB->removeFnAttrs(AttrMask);

235 CB->removeRetAttrs(AttrMask);

236 for (size_t Idx = 0, End = CB->arg_size(); Idx < End; ++Idx)

237 CB->removeParamAttrs(Idx, AttrMask);

238 continue;

239 }

240 }

241 }

242 }

243

244 cleanModuleFlags(M);

245 return true;

246 }

247

255 }

256 static char ID;

257};

258char DXILPrepareModule::ID = 0;

259

260}

261

263 false, false)

267

269 return new DXILPrepareModule();

270}

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

Module.h This file contains the declarations for the Module class.

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

This file defines the SmallVector class.

StringSet - A set-like wrapper for the StringMap.

Defines the llvm::VersionTuple class, which represents a version in the form major[....

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.

AttributeMask & addAttribute(Attribute::AttrKind Val)

Add an attribute to the mask.

AttrKind

This enumeration lists the attributes that can be associated with parameters, function results,...

@ None

No attributes have been set.

@ EndAttrKinds

Sentinel value useful for loops.

static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...

The legacy pass manager's analysis pass to compute DXIL resource information.

iterator find(const_arg_type_t< KeyT > Val)

Value * CreateFSub(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)

InstTy * Insert(InstTy *I, const Twine &Name="") const

Insert and return the specified instruction.

LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)

Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...

StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)

PointerType * getPtrTy(unsigned AddrSpace=0)

Fetch the type representing a pointer.

void SetInsertPoint(BasicBlock *TheBB)

This specifies that created instructions should be appended to the end of the specified block.

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

ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...

virtual bool runOnModule(Module &M)=0

runOnModule - Virtual method overriden by subclasses to process the module being operated on.

A Module instance is used to store all the information related to an LLVM module.

void eraseFromParent()

Drop all references and remove the node from parent module.

virtual void getAnalysisUsage(AnalysisUsage &) const

getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...

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.

StringSet - A wrapper for StringMap that provides set-like functionality.

bool contains(StringRef key) const

Check if the set contains the given key.

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

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

Represents a version number in the form major[.minor[.subminor[.build]]].

unsigned getMajor() const

Retrieve the major version number.

std::optional< unsigned > getMinor() const

Retrieve the minor version number, if provided.

Wrapper pass for the legacy pass manager.

unsigned ID

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

PointerTypeMap run(const Module &M)

Compute the PointerTypeMap for the module M.

This is an optimization pass for GlobalISel generic memory operations.

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

ModulePass * createDXILPrepareModulePass()

Pass to convert modules into DXIL-compatable modules.

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.