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.