33#define DEBUG_TYPE "dxil-prepare"
42 Attribute::AlwaysInline,
47 Attribute::Convergent,
48 Attribute::InlineHint,
57 Attribute::NoDuplicate,
58 Attribute::NoImplicitFloat,
60 Attribute::NonLazyBind,
62 Attribute::Dereferenceable,
63 Attribute::DereferenceableOrNull,
68 Attribute::OptimizeForSize,
69 Attribute::OptimizeNone,
73 Attribute::ReturnsTwice,
75 Attribute::StackAlignment,
76 Attribute::StackProtect,
77 Attribute::StackProtectReq,
78 Attribute::StackProtectStrong,
81 Attribute::SanitizeAddress,
82 Attribute::SanitizeThread,
83 Attribute::SanitizeMemory,
91 bool AllowExperimental) {
92 for (
auto &Attr : AS) {
93 if (!Attr.isStringAttribute())
98 if (AllowExperimental && Key.starts_with(
"exp-"))
104static void removeStringFunctionAttributes(
Function &
F,
105 bool AllowExperimental) {
107 const StringSet<> LiveKeys = {
"waveops-include-helper-lanes",
111 collectDeadStringAttrs(DeadAttrs, Attrs.getFnAttrs(), LiveKeys,
113 collectDeadStringAttrs(DeadAttrs, Attrs.getRetAttrs(), LiveKeys,
116 F.removeFnAttrs(DeadAttrs);
117 F.removeRetAttrs(DeadAttrs);
120static void cleanModuleFlags(
Module &M) {
126 M.getModuleFlagsMetadata(FlagEntries);
127 bool Updated =
false;
128 for (
auto &Flag : FlagEntries) {
130 if (Flag.Behavior <= Module::ModFlagBehavior::AppendUnique)
132 Flag.Behavior = Module::ModFlagBehavior::Warning;
141 for (
auto &Flag : FlagEntries)
142 M.addModuleFlag(Flag.Behavior, Flag.Key->getString(), Flag.Val);
152 auto It = PointerTypes.
find(Operand);
153 if (It != PointerTypes.
end())
154 if (cast<TypedPointerType>(It->second)->getElementType() == Ty)
163 Builder.
getPtrTy(PtrTy->getAddressSpace())));
172 if (!isValidForDXIL(
I))
177 getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
181 for (
auto &
F : M.functions()) {
182 F.removeFnAttrs(AttrMask);
183 F.removeRetAttrs(AttrMask);
187 removeStringFunctionAttributes(
F, SkipValidation);
189 F.removeParamAttrs(
Idx, AttrMask);
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));
205 if (
auto LI = dyn_cast<LoadInst>(&
I)) {
206 if (
Value *NoOpBitcast = maybeGenerateBitcast(
207 Builder, PointerTypes,
I, LI->getPointerOperand(),
209 LI->replaceAllUsesWith(
210 Builder.
CreateLoad(LI->getType(), NoOpBitcast));
211 LI->eraseFromParent();
215 if (
auto SI = dyn_cast<StoreInst>(&
I)) {
216 if (
Value *NoOpBitcast = maybeGenerateBitcast(
217 Builder, PointerTypes,
I, SI->getPointerOperand(),
218 SI->getValueOperand()->getType())) {
220 SI->replaceAllUsesWith(
221 Builder.
CreateStore(SI->getValueOperand(), NoOpBitcast));
222 SI->eraseFromParent();
226 if (
auto GEP = dyn_cast<GetElementPtrInst>(&
I)) {
227 if (
Value *NoOpBitcast = maybeGenerateBitcast(
228 Builder, PointerTypes,
I,
GEP->getPointerOperand(),
229 GEP->getSourceElementType()))
230 GEP->setOperand(0, NoOpBitcast);
233 if (
auto *CB = dyn_cast<CallBase>(&
I)) {
234 CB->removeFnAttrs(AttrMask);
235 CB->removeRetAttrs(AttrMask);
237 CB->removeParamAttrs(
Idx, AttrMask);
258char DXILPrepareModule::ID = 0;
269 return new DXILPrepareModule();
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.