30 #define DEBUG_TYPE "nvptx"
48 static const unsigned MaxAggrCopySize = 128;
51 return "Lower aggregate copies/intrinsics into loops";
59 Value *DstAddr,
Value *CopyLen,
bool SrcIsVolatile,
74 unsigned SrcAS = cast<PointerType>(SrcAddr->
getType())->getAddressSpace();
75 unsigned DstAS = cast<PointerType>(DstAddr->
getType())->getAddressSpace();
78 SrcAddr = Builder.CreateBitCast(SrcAddr, Builder.getInt8PtrTy(SrcAS));
79 DstAddr = Builder.CreateBitCast(DstAddr, Builder.getInt8PtrTy(DstAS));
90 LoopBuilder.
getInt8Ty(), SrcAddr, LoopIndex),
130 Value *DstAddr,
Value *CopyLen,
bool SrcIsVolatile,
143 SrcAddr, DstAddr,
"compare_src_dst");
154 CopyBackwardsBB->
setName(
"copy_backwards");
156 CopyForwardBB->
setName(
"copy_forward");
158 ExitBB->
setName(
"memmove_done");
189 PHINode *FwdCopyPhi = FwdLoopBuilder.
CreatePHI(TypeOfCopyLen, 0,
"index_ptr");
218 unsigned dstAS = cast<PointerType>(DstAddr->
getType())->getAddressSpace();
219 DstAddr = Builder.CreateBitCast(DstAddr,
239 bool NVPTXLowerAggrCopies::runOnFunction(
Function &F) {
250 if (
LoadInst *LI = dyn_cast<LoadInst>(II)) {
251 if (!LI->hasOneUse())
257 if (
StoreInst *
SI = dyn_cast<StoreInst>(LI->user_back())) {
258 if (
SI->getOperand(0) != LI)
262 }
else if (
MemIntrinsic *IntrCall = dyn_cast<MemIntrinsic>(II)) {
265 if (
ConstantInt *LenCI = dyn_cast<ConstantInt>(IntrCall->getLength())) {
266 if (LenCI->getZExtValue() >= MaxAggrCopySize) {
276 if (AggrLoads.
size() == 0 && MemCalls.
size() == 0) {
285 Value *SrcAddr = LI->getOperand(0);
290 convertMemCpyToLoop( SI,
299 LI->eraseFromParent();
304 if (
MemCpyInst *Memcpy = dyn_cast<MemCpyInst>(MemCall)) {
305 convertMemCpyToLoop( Memcpy,
306 Memcpy->getRawSource(),
307 Memcpy->getRawDest(),
309 Memcpy->isVolatile(),
310 Memcpy->isVolatile(),
313 }
else if (
MemMoveInst *Memmove = dyn_cast<MemMoveInst>(MemCall)) {
314 convertMemMoveToLoop( Memmove,
315 Memmove->getRawSource(),
316 Memmove->getRawDest(),
317 Memmove->getLength(),
318 Memmove->isVolatile(),
319 Memmove->isVolatile(),
323 }
else if (
MemSetInst *Memset = dyn_cast<MemSetInst>(MemCall)) {
324 convertMemSetToLoop( Memset,
325 Memset->getRawDest(),
331 MemCall->eraseFromParent();
344 "Lower aggregate copies, and llvm.mem* intrinsics into loops",
348 return new NVPTXLowerAggrCopies();
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore, TerminatorInst **ThenTerm, TerminatorInst **ElseTerm, MDNode *BranchWeights=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
bool isVolatile() const
Return true if this is a store to a volatile memory location.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF)
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space...
This class wraps the llvm.memset intrinsic.
An instruction for reading from memory.
This class wraps the llvm.memmove intrinsic.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
void setName(const Twine &Name)
Change the name of the value.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
void setSuccessor(unsigned idx, BasicBlock *B)
Update the specified successor to point at the provided block.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
An instruction for storing to memory.
Value * CreateInBoundsGEP(Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
LoadInst * CreateLoad(Value *Ptr, const char *Name)
Subclasses of this class are all able to terminate a basic block.
void initializeNVPTXLowerAggrCopiesPass(PassRegistry &)
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Represent the analysis usage information of a pass.
This instruction compares its operands according to the predicate given to the constructor.
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
This is the common base class for memset/memcpy/memmove.
Iterator for intrusive lists based on ilist_node.
This is the shared class of boolean and integer constants.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
This class wraps the llvm.memcpy intrinsic.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
INITIALIZE_PASS(NVPTXLowerAggrCopies,"nvptx-lower-aggr-copies","Lower aggregate copies, and llvm.mem* intrinsics into loops", false, false) FunctionPass *llvm
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
FunctionPass * createLowerAggrCopies()
static IntegerType * getInt32Ty(LLVMContext &C)
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
StringRef - Represent a constant reference to a string, i.e.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
const BasicBlock * getParent() const
LLVMContext & getContext() const
Get the global data context.