32#define DEBUG_TYPE "dxil-prepare"
41 Attribute::AlwaysInline,
46 Attribute::Convergent,
47 Attribute::InlineHint,
56 Attribute::NoDuplicate,
57 Attribute::NoImplicitFloat,
59 Attribute::NonLazyBind,
61 Attribute::Dereferenceable,
62 Attribute::DereferenceableOrNull,
67 Attribute::OptimizeForSize,
68 Attribute::OptimizeNone,
72 Attribute::ReturnsTwice,
74 Attribute::StackAlignment,
75 Attribute::StackProtect,
76 Attribute::StackProtectReq,
77 Attribute::StackProtectStrong,
80 Attribute::SanitizeAddress,
81 Attribute::SanitizeThread,
82 Attribute::SanitizeMemory,
90 bool AllowExperimental) {
91 for (
auto &Attr : AS) {
92 if (!Attr.isStringAttribute())
97 if (AllowExperimental && Key.starts_with(
"exp-"))
103static void removeStringFunctionAttributes(
Function &
F,
104 bool AllowExperimental) {
106 const StringSet<> LiveKeys = {
"waveops-include-helper-lanes",
110 collectDeadStringAttrs(DeadAttrs, Attrs.getFnAttrs(), LiveKeys,
112 collectDeadStringAttrs(DeadAttrs, Attrs.getRetAttrs(), LiveKeys,
115 F.removeFnAttrs(DeadAttrs);
116 F.removeRetAttrs(DeadAttrs);
126 auto It = PointerTypes.
find(Operand);
127 if (It != PointerTypes.
end())
128 if (cast<TypedPointerType>(It->second)->getElementType() == Ty)
137 Builder.
getPtrTy(PtrTy->getAddressSpace())));
146 if (!isValidForDXIL(
I))
154 for (
auto &
F : M.functions()) {
155 F.removeFnAttrs(AttrMask);
156 F.removeRetAttrs(AttrMask);
160 removeStringFunctionAttributes(
F, SkipValidation);
162 F.removeParamAttrs(
Idx, AttrMask);
167 if (
I.getOpcode() == Instruction::FNeg) {
169 Value *In =
I.getOperand(0);
170 Value *Zero = ConstantFP::get(In->getType(), -0.0);
171 I.replaceAllUsesWith(Builder.
CreateFSub(Zero, In));
178 if (
auto LI = dyn_cast<LoadInst>(&
I)) {
179 if (
Value *NoOpBitcast = maybeGenerateBitcast(
180 Builder, PointerTypes,
I, LI->getPointerOperand(),
182 LI->replaceAllUsesWith(
183 Builder.
CreateLoad(LI->getType(), NoOpBitcast));
184 LI->eraseFromParent();
188 if (
auto SI = dyn_cast<StoreInst>(&
I)) {
189 if (
Value *NoOpBitcast = maybeGenerateBitcast(
190 Builder, PointerTypes,
I, SI->getPointerOperand(),
191 SI->getValueOperand()->getType())) {
193 SI->replaceAllUsesWith(
194 Builder.
CreateStore(SI->getValueOperand(), NoOpBitcast));
195 SI->eraseFromParent();
199 if (
auto GEP = dyn_cast<GetElementPtrInst>(&
I)) {
200 if (
Value *NoOpBitcast = maybeGenerateBitcast(
201 Builder, PointerTypes,
I,
GEP->getPointerOperand(),
202 GEP->getSourceElementType()))
203 GEP->setOperand(0, NoOpBitcast);
206 if (
auto *CB = dyn_cast<CallBase>(&
I)) {
207 CB->removeFnAttrs(AttrMask);
208 CB->removeRetAttrs(AttrMask);
210 CB->removeParamAttrs(
Idx, AttrMask);
226char DXILPrepareModule::ID = 0;
236 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_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 & 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, BasicBlock::iterator InsertBefore)
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.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
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.
VersionTuple getAsVersionTuple()
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.