15#define DEBUG_TYPE "dxil-mem-intrinsics"
24 assert(LengthCI &&
"Expected length to be a ConstantInt");
27 Builder.GetInsertBlock()->getModule()->getDataLayout();
32 assert(Alloca &&
"Expected memset on an Alloca");
34 "Expected for memset size to match DataLayout size");
38 assert(ArrTy &&
"Expected Alloca for an Array Type");
40 Type *ElemTy = ArrTy->getElementType();
43 [[maybe_unused]]
uint64_t ElemSize =
DL.getTypeStoreSize(ElemTy);
45 assert(ElemSize > 0 &&
"Size must be set");
46 assert(OrigLength == ElemSize *
Size &&
"Size in bytes must match");
48 Value *TypedVal = Val;
51 TypedVal = Builder.CreateIntCast(Val, ElemTy,
false);
54 Value *Zero = Builder.getInt32(0);
56 Value *Ptr = Builder.CreateGEP(ArrTy, Dst, {Zero,
Offset},
"gep");
57 Builder.CreateStore(TypedVal, Ptr);
68 assert(LengthCI &&
"Expected Length to be a ConstantInt");
76 const DataLayout &
DL = Builder.GetInsertBlock()->getModule()->getDataLayout();
81 "Expected Val to be an Alloca or Global Variable");
89 ArrayType *DstArrTy = GetArrTyFromVal(Dst);
90 assert(DstArrTy &&
"Expected Dst of memcpy to be a Pointer to an Array Type");
92 assert(!DstGlobalVar->isConstant() &&
93 "The Dst of memcpy must not be a constant Global Variable");
94 [[maybe_unused]]
ArrayType *SrcArrTy = GetArrTyFromVal(Src);
95 assert(SrcArrTy &&
"Expected Src of memcpy to be a Pointer to an Array Type");
97 Type *DstElemTy = DstArrTy->getElementType();
98 uint64_t DstElemByteSize =
DL.getTypeStoreSize(DstElemTy);
99 assert(DstElemByteSize > 0 &&
"Dst element type store size must be set");
100 Type *SrcElemTy = SrcArrTy->getElementType();
101 [[maybe_unused]]
uint64_t SrcElemByteSize =
DL.getTypeStoreSize(SrcElemTy);
102 assert(SrcElemByteSize > 0 &&
"Src element type store size must be set");
106 assert(DstElemTy == SrcElemTy &&
107 "The element types of Src and Dst arrays must match");
109 [[maybe_unused]]
uint64_t DstArrNumElems = DstArrTy->getArrayNumElements();
110 assert(DstElemByteSize * DstArrNumElems >= ByteLength &&
111 "Dst array size must be at least as large as the memcpy length");
112 [[maybe_unused]]
uint64_t SrcArrNumElems = SrcArrTy->getArrayNumElements();
113 assert(SrcElemByteSize * SrcArrNumElems >= ByteLength &&
114 "Src array size must be at least as large as the memcpy length");
116 uint64_t NumElemsToCopy = ByteLength / DstElemByteSize;
117 assert(ByteLength % DstElemByteSize == 0 &&
118 "memcpy length must be divisible by array element type");
121 Builder.getInt32(
I)};
122 Value *SrcPtr = Builder.CreateInBoundsGEP(SrcArrTy, Src, Indices,
"gep");
123 Value *SrcVal = Builder.CreateLoad(SrcElemTy, SrcPtr);
124 Value *DstPtr = Builder.CreateInBoundsGEP(DstArrTy, Dst, Indices,
"gep");
125 Builder.CreateStore(SrcVal, DstPtr);
136 bool HadMemIntrinsicUses =
false;
140 case Intrinsic::memcpy:
141 case Intrinsic::memcpy_inline:
142 case Intrinsic::memmove:
143 case Intrinsic::memset:
144 case Intrinsic::memset_inline:
150 HadMemIntrinsicUses =
true;
160 assert(
F.user_empty() &&
"Mem intrinsic not eliminated?");
163 return HadMemIntrinsicUses;
182 "DXIL Memory Intrinsic Elimination",
false,
false)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool eliminateMemIntrinsics(Module &M)
void expandMemSet(MemSetInst *MemSet)
void expandMemCpy(MemCpyInst *MemCpy)
void expandMemMove(MemMoveInst *MemMove)
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)
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
DXILMemIntrinsicsLegacy()
an instruction to allocate memory on the stack
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
A parsed version of the target data layout string in and methods for querying it.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This class wraps the llvm.memcpy intrinsic.
Value * getLength() const
Value * getDest() const
This is just like getRawDest, but it strips off any cast instructions (including addrspacecast) that ...
This class wraps the llvm.memmove intrinsic.
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
Value * getSource() const
This is just like getRawSource, but it strips off any cast instructions that feed it,...
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.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - 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...
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
ModulePass * createDXILMemIntrinsicsLegacyPass()
Pass to transform all llvm memory intrinsics to explicit loads and stores.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.