LLVM: lib/Target/DirectX/DXILPrepare.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
30
31#define DEBUG_TYPE "dxil-prepare"
32
33using namespace llvm;
35
36namespace {
37
40 Attribute::AlwaysInline,
41 Attribute::Builtin,
42 Attribute::ByVal,
43 Attribute::InAlloca,
44 Attribute::Cold,
45 Attribute::Convergent,
46 Attribute::InlineHint,
47 Attribute::InReg,
48 Attribute::JumpTable,
49 Attribute::MinSize,
50 Attribute::Naked,
51 Attribute::Nest,
52 Attribute::NoAlias,
53 Attribute::NoBuiltin,
54 Attribute::NoDuplicate,
55 Attribute::NoImplicitFloat,
56 Attribute::NoInline,
57 Attribute::NonLazyBind,
58 Attribute::NonNull,
59 Attribute::Dereferenceable,
60 Attribute::DereferenceableOrNull,
61 Attribute::Memory,
62 Attribute::NoRedZone,
63 Attribute::NoReturn,
64 Attribute::NoUnwind,
65 Attribute::OptimizeForSize,
66 Attribute::OptimizeNone,
67 Attribute::ReadNone,
68 Attribute::ReadOnly,
69 Attribute::Returned,
70 Attribute::ReturnsTwice,
71 Attribute::SExt,
72 Attribute::StackAlignment,
73 Attribute::StackProtect,
74 Attribute::StackProtectReq,
75 Attribute::StackProtectStrong,
76 Attribute::SafeStack,
77 Attribute::StructRet,
78 Attribute::SanitizeAddress,
79 Attribute::SanitizeThread,
80 Attribute::SanitizeMemory,
81 Attribute::UWTable,
82 Attribute::ZExt},
83 Attr);
84}
85
88 bool AllowExperimental) {
89 for (auto &Attr : AS) {
90 if (!Attr.isStringAttribute())
91 continue;
94 continue;
95 if (AllowExperimental && Key.starts_with("exp-"))
96 continue;
98 }
99}
100
101static void removeStringFunctionAttributes(Function &F,
102 bool AllowExperimental) {
103 AttributeList Attrs = F.getAttributes();
104 const StringSet<> LiveKeys = {"waveops-include-helper-lanes",
105 "fp32-denorm-mode"};
106
108 collectDeadStringAttrs(DeadAttrs, Attrs.getFnAttrs(), LiveKeys,
109 AllowExperimental);
110 collectDeadStringAttrs(DeadAttrs, Attrs.getRetAttrs(), LiveKeys,
111 AllowExperimental);
112
113 F.removeFnAttrs(DeadAttrs);
114 F.removeRetAttrs(DeadAttrs);
115}
116
117class DXILPrepareModule : public ModulePass {
118
123
124 auto It = PointerTypes.find(Operand);
125 if (It != PointerTypes.end()) {
127 if (OpTy == Ty)
128 return nullptr;
129 }
130
132
134 ValTy = GlobalVar->getValueType();
135
137 ValTy = AI->getAllocatedType();
138
140 Type *ElTy = ArrTy->getElementType();
141 if (ElTy == Ty)
142 return nullptr;
143 }
144
145
146
148 while (GEPInstr->getOpcode() == Instruction::GetElementPtr) {
149 Value *OpArg = GEPInstr->getOperand(0);
151 GEPInstr = NewGEPInstr;
152 continue;
153 }
154
156 ValTy = GlobalVar->getValueType();
158 ValTy = AI->getAllocatedType();
160 Type *ElTy = ArrTy->getElementType();
161 if (ElTy == Ty)
162 return nullptr;
163 }
164 break;
165 }
166 }
167
168
169 Builder.SetInsertPoint(&Inst);
170
171
173 return Builder.Insert(
175 Builder.getPtrTy(PtrTy->getAddressSpace())));
176 }
177
178public:
179 bool runOnModule(Module &M) override {
184 if (!isValidForDXIL(I))
186 }
187
189 getAnalysis().getModuleMetadata();
190 VersionTuple ValVer = MetadataInfo.ValidatorVersion;
191 bool AllowExperimental = ValVer.getMajor() == 0 && ValVer.getMinor() == 0;
192
193 for (auto &F : M.functions()) {
194 F.removeFnAttrs(AttrMask);
195 F.removeRetAttrs(AttrMask);
196
197
198
199 removeStringFunctionAttributes(F, AllowExperimental);
200 for (size_t Idx = 0, End = F.arg_size(); Idx < End; ++Idx)
201 F.removeParamAttrs(Idx, AttrMask);
202
203 for (auto &BB : F) {
206
208 CB->removeFnAttrs(AttrMask);
209 CB->removeRetAttrs(AttrMask);
210 for (size_t Idx = 0, End = CB->arg_size(); Idx < End; ++Idx)
211 CB->removeParamAttrs(Idx, AttrMask);
212 continue;
213 }
214
215
216
218 if (Value *NoOpBitcast = maybeGenerateBitcast(
219 Builder, PointerTypes, I, LI->getPointerOperand(),
220 LI->getType())) {
221 LI->replaceAllUsesWith(
222 Builder.CreateLoad(LI->getType(), NoOpBitcast));
223 LI->eraseFromParent();
224 }
225 continue;
226 }
228 if (Value *NoOpBitcast = maybeGenerateBitcast(
229 Builder, PointerTypes, I, SI->getPointerOperand(),
230 SI->getValueOperand()->getType())) {
231
232 SI->replaceAllUsesWith(
233 Builder.CreateStore(SI->getValueOperand(), NoOpBitcast));
234 SI->eraseFromParent();
235 }
236 continue;
237 }
239 if (Value *NoOpBitcast = maybeGenerateBitcast(
240 Builder, PointerTypes, I, GEP->getPointerOperand(),
241 GEP->getSourceElementType()))
242 GEP->setOperand(0, NoOpBitcast);
243 continue;
244 }
245 }
246 }
247 }
248
249 return true;
250 }
251
253 void getAnalysisUsage(AnalysisUsage &AU) const override {
255
260 }
261 static char ID;
262};
263char DXILPrepareModule::ID = 0;
264
265}
266
268 false, false)
272
274 return new DXILPrepareModule();
275}
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)
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.
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
This class holds the attributes for a particular argument, parameter, function, or return value.
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 LLVM_ABI 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 ...
A constant value that is initialized with an expression using other constant values.
iterator find(const_arg_type_t< KeyT > Val)
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...
A Module instance is used to store all the information related to an LLVM module.
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.
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.
DenseMap< const Value *, Type * > PointerTypeMap
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
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.
Definition DXILPrepare.cpp:273
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.