Streamline the coding style in NVPTXLowerAggrCopies

Make the style consistent with LLVM style throughout and clang-format.




git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242439 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Bendersky
2015-07-16 20:42:38 +00:00
parent da787addf3
commit ccd3aa85a9

View File

@@ -7,6 +7,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// \file
// Lower aggregate copies, memset, memcpy, memmov intrinsics into loops when // Lower aggregate copies, memset, memcpy, memmov intrinsics into loops when
// the size is large or is not a compile-time constant. // the size is large or is not a compile-time constant.
// //
@@ -19,7 +20,6 @@
#include "llvm/IR/DataLayout.h" #include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h" #include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h" #include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Intrinsics.h"
@@ -57,47 +57,52 @@ struct NVPTXLowerAggrCopies : public FunctionPass {
char NVPTXLowerAggrCopies::ID = 0; char NVPTXLowerAggrCopies::ID = 0;
// Lower memcpy to loop. // Lower memcpy to loop.
void convertMemCpyToLoop(Instruction *splitAt, Value *srcAddr, Value *dstAddr, void convertMemCpyToLoop(Instruction *ConvertedInst, Value *SrcAddr,
Value *len, bool srcVolatile, bool dstVolatile, Value *DstAddr, Value *CopyLen, bool SrcIsVolatile,
LLVMContext &Context, Function &F) { bool DstIsVolatile, LLVMContext &Context,
Type *indType = len->getType(); Function &F) {
Type *TypeOfCopyLen = CopyLen->getType();
BasicBlock *origBB = splitAt->getParent(); BasicBlock *OrigBB = ConvertedInst->getParent();
BasicBlock *newBB = splitAt->getParent()->splitBasicBlock(splitAt, "split"); BasicBlock *NewBB =
BasicBlock *loopBB = BasicBlock::Create(Context, "loadstoreloop", &F, newBB); ConvertedInst->getParent()->splitBasicBlock(ConvertedInst, "split");
BasicBlock *LoopBB = BasicBlock::Create(Context, "loadstoreloop", &F, NewBB);
origBB->getTerminator()->setSuccessor(0, loopBB); OrigBB->getTerminator()->setSuccessor(0, LoopBB);
IRBuilder<> builder(origBB, origBB->getTerminator()); IRBuilder<> Builder(OrigBB, OrigBB->getTerminator());
// srcAddr and dstAddr are expected to be pointer types, // SrcAddr and DstAddr are expected to be pointer types,
// so no check is made here. // so no check is made here.
unsigned srcAS = cast<PointerType>(srcAddr->getType())->getAddressSpace(); unsigned SrcAS = cast<PointerType>(SrcAddr->getType())->getAddressSpace();
unsigned dstAS = cast<PointerType>(dstAddr->getType())->getAddressSpace(); unsigned DstAS = cast<PointerType>(DstAddr->getType())->getAddressSpace();
// Cast pointers to (char *) // Cast pointers to (char *)
srcAddr = builder.CreateBitCast(srcAddr, Type::getInt8PtrTy(Context, srcAS)); SrcAddr = Builder.CreateBitCast(SrcAddr, Builder.getInt8PtrTy(SrcAS));
dstAddr = builder.CreateBitCast(dstAddr, Type::getInt8PtrTy(Context, dstAS)); DstAddr = Builder.CreateBitCast(DstAddr, Builder.getInt8PtrTy(DstAS));
IRBuilder<> loop(loopBB); IRBuilder<> LoopBuilder(LoopBB);
// The loop index (ind) is a phi node. PHINode *LoopIndex = LoopBuilder.CreatePHI(TypeOfCopyLen, 0);
PHINode *ind = loop.CreatePHI(indType, 0); LoopIndex->addIncoming(ConstantInt::get(TypeOfCopyLen, 0), OrigBB);
// Incoming value for ind is 0
ind->addIncoming(ConstantInt::get(indType, 0), origBB);
// load from srcAddr+ind // load from SrcAddr+LoopIndex
// TODO: we can leverage the align parameter of llvm.memcpy for more efficient // TODO: we can leverage the align parameter of llvm.memcpy for more efficient
// word-sized loads and stores. // word-sized loads and stores.
Value *val = loop.CreateLoad(loop.CreateGEP(loop.getInt8Ty(), srcAddr, ind), Value *Element = LoopBuilder.CreateLoad(
srcVolatile); LoopBuilder.CreateGEP(LoopBuilder.getInt8Ty(), SrcAddr, LoopIndex),
// store at dstAddr+ind SrcIsVolatile);
loop.CreateStore(val, loop.CreateGEP(loop.getInt8Ty(), dstAddr, ind), // store at DstAddr+LoopIndex
dstVolatile); LoopBuilder.CreateStore(
Element,
LoopBuilder.CreateGEP(LoopBuilder.getInt8Ty(), DstAddr, LoopIndex),
DstIsVolatile);
// The value for ind coming from backedge is (ind + 1) // The value for LoopIndex coming from backedge is (LoopIndex + 1)
Value *newind = loop.CreateAdd(ind, ConstantInt::get(indType, 1)); Value *NewIndex =
ind->addIncoming(newind, loopBB); LoopBuilder.CreateAdd(LoopIndex, ConstantInt::get(TypeOfCopyLen, 1));
LoopIndex->addIncoming(NewIndex, LoopBB);
loop.CreateCondBr(loop.CreateICmpULT(newind, len), loopBB, newBB); LoopBuilder.CreateCondBr(LoopBuilder.CreateICmpULT(NewIndex, CopyLen), LoopBB,
NewBB);
} }
// Lower memmove to IR. memmove is required to correctly copy overlapping memory // Lower memmove to IR. memmove is required to correctly copy overlapping memory
@@ -122,11 +127,12 @@ void convertMemCpyToLoop(Instruction *splitAt, Value *srcAddr, Value *dstAddr,
// } // }
// return dst; // return dst;
// } // }
void convertMemMoveToLoop(Instruction *splitAt, Value *srcAddr, Value *dstAddr, void convertMemMoveToLoop(Instruction *ConvertedInst, Value *SrcAddr,
Value *len, bool srcVolatile, bool dstVolatile, Value *DstAddr, Value *CopyLen, bool SrcIsVolatile,
LLVMContext &Context, Function &F) { bool DstIsVolatile, LLVMContext &Context,
Type *TypeOfLen = len->getType(); Function &F) {
BasicBlock *OrigBB = splitAt->getParent(); Type *TypeOfCopyLen = CopyLen->getType();
BasicBlock *OrigBB = ConvertedInst->getParent();
// Create the a comparison of src and dst, based on which we jump to either // Create the a comparison of src and dst, based on which we jump to either
// the forward-copy part of the function (if src >= dst) or the backwards-copy // the forward-copy part of the function (if src >= dst) or the backwards-copy
@@ -134,10 +140,11 @@ void convertMemMoveToLoop(Instruction *splitAt, Value *srcAddr, Value *dstAddr,
// SplitBlockAndInsertIfThenElse conveniently creates the basic if-then-else // SplitBlockAndInsertIfThenElse conveniently creates the basic if-then-else
// structure. Its block terminators (unconditional branches) are replaced by // structure. Its block terminators (unconditional branches) are replaced by
// the appropriate conditional branches when the loop is built. // the appropriate conditional branches when the loop is built.
ICmpInst *PtrCompare = new ICmpInst(splitAt, ICmpInst::ICMP_ULT, srcAddr, ICmpInst *PtrCompare = new ICmpInst(ConvertedInst, ICmpInst::ICMP_ULT,
dstAddr, "compare_src_dst"); SrcAddr, DstAddr, "compare_src_dst");
TerminatorInst *ThenTerm, *ElseTerm; TerminatorInst *ThenTerm, *ElseTerm;
SplitBlockAndInsertIfThenElse(PtrCompare, splitAt, &ThenTerm, &ElseTerm); SplitBlockAndInsertIfThenElse(PtrCompare, ConvertedInst, &ThenTerm,
&ElseTerm);
// Each part of the function consists of two blocks: // Each part of the function consists of two blocks:
// copy_backwards: used to skip the loop when n == 0 // copy_backwards: used to skip the loop when n == 0
@@ -148,31 +155,31 @@ void convertMemMoveToLoop(Instruction *splitAt, Value *srcAddr, Value *dstAddr,
CopyBackwardsBB->setName("copy_backwards"); CopyBackwardsBB->setName("copy_backwards");
BasicBlock *CopyForwardBB = ElseTerm->getParent(); BasicBlock *CopyForwardBB = ElseTerm->getParent();
CopyForwardBB->setName("copy_forward"); CopyForwardBB->setName("copy_forward");
BasicBlock *ExitBB = splitAt->getParent(); BasicBlock *ExitBB = ConvertedInst->getParent();
ExitBB->setName("memmove_done"); ExitBB->setName("memmove_done");
// Initial comparison of n == 0 that lets us skip the loops altogether. Shared // Initial comparison of n == 0 that lets us skip the loops altogether. Shared
// between both backwards and forward copy clauses. // between both backwards and forward copy clauses.
ICmpInst *CompareN = ICmpInst *CompareN =
new ICmpInst(OrigBB->getTerminator(), ICmpInst::ICMP_EQ, len, new ICmpInst(OrigBB->getTerminator(), ICmpInst::ICMP_EQ, CopyLen,
ConstantInt::get(TypeOfLen, 0), "compare_n_to_0"); ConstantInt::get(TypeOfCopyLen, 0), "compare_n_to_0");
// Copying backwards. // Copying backwards.
BasicBlock *LoopBB = BasicBlock *LoopBB =
BasicBlock::Create(Context, "copy_backwards_loop", &F, CopyForwardBB); BasicBlock::Create(Context, "copy_backwards_loop", &F, CopyForwardBB);
IRBuilder<> LoopBuilder(LoopBB); IRBuilder<> LoopBuilder(LoopBB);
PHINode *LoopPhi = LoopBuilder.CreatePHI(TypeOfLen, 0); PHINode *LoopPhi = LoopBuilder.CreatePHI(TypeOfCopyLen, 0);
Value *IndexPtr = LoopBuilder.CreateSub( Value *IndexPtr = LoopBuilder.CreateSub(
LoopPhi, ConstantInt::get(TypeOfLen, 1), "index_ptr"); LoopPhi, ConstantInt::get(TypeOfCopyLen, 1), "index_ptr");
Value *Element = LoopBuilder.CreateLoad( Value *Element = LoopBuilder.CreateLoad(
LoopBuilder.CreateInBoundsGEP(srcAddr, IndexPtr), "element"); LoopBuilder.CreateInBoundsGEP(SrcAddr, IndexPtr), "element");
LoopBuilder.CreateStore(Element, LoopBuilder.CreateStore(Element,
LoopBuilder.CreateInBoundsGEP(dstAddr, IndexPtr)); LoopBuilder.CreateInBoundsGEP(DstAddr, IndexPtr));
LoopBuilder.CreateCondBr( LoopBuilder.CreateCondBr(
LoopBuilder.CreateICmpEQ(IndexPtr, ConstantInt::get(TypeOfLen, 0)), LoopBuilder.CreateICmpEQ(IndexPtr, ConstantInt::get(TypeOfCopyLen, 0)),
ExitBB, LoopBB); ExitBB, LoopBB);
LoopPhi->addIncoming(IndexPtr, LoopBB); LoopPhi->addIncoming(IndexPtr, LoopBB);
LoopPhi->addIncoming(len, CopyBackwardsBB); LoopPhi->addIncoming(CopyLen, CopyBackwardsBB);
BranchInst::Create(ExitBB, LoopBB, CompareN, ThenTerm); BranchInst::Create(ExitBB, LoopBB, CompareN, ThenTerm);
ThenTerm->eraseFromParent(); ThenTerm->eraseFromParent();
@@ -180,52 +187,57 @@ void convertMemMoveToLoop(Instruction *splitAt, Value *srcAddr, Value *dstAddr,
BasicBlock *FwdLoopBB = BasicBlock *FwdLoopBB =
BasicBlock::Create(Context, "copy_forward_loop", &F, ExitBB); BasicBlock::Create(Context, "copy_forward_loop", &F, ExitBB);
IRBuilder<> FwdLoopBuilder(FwdLoopBB); IRBuilder<> FwdLoopBuilder(FwdLoopBB);
PHINode *FwdCopyPhi = FwdLoopBuilder.CreatePHI(TypeOfLen, 0, "index_ptr"); PHINode *FwdCopyPhi = FwdLoopBuilder.CreatePHI(TypeOfCopyLen, 0, "index_ptr");
Value *FwdElement = FwdLoopBuilder.CreateLoad( Value *FwdElement = FwdLoopBuilder.CreateLoad(
FwdLoopBuilder.CreateInBoundsGEP(srcAddr, FwdCopyPhi), "element"); FwdLoopBuilder.CreateInBoundsGEP(SrcAddr, FwdCopyPhi), "element");
FwdLoopBuilder.CreateStore( FwdLoopBuilder.CreateStore(
FwdElement, FwdLoopBuilder.CreateInBoundsGEP(dstAddr, FwdCopyPhi)); FwdElement, FwdLoopBuilder.CreateInBoundsGEP(DstAddr, FwdCopyPhi));
Value *FwdIndexPtr = FwdLoopBuilder.CreateAdd( Value *FwdIndexPtr = FwdLoopBuilder.CreateAdd(
FwdCopyPhi, ConstantInt::get(TypeOfLen, 1), "index_increment"); FwdCopyPhi, ConstantInt::get(TypeOfCopyLen, 1), "index_increment");
FwdLoopBuilder.CreateCondBr(FwdLoopBuilder.CreateICmpEQ(FwdIndexPtr, len), FwdLoopBuilder.CreateCondBr(FwdLoopBuilder.CreateICmpEQ(FwdIndexPtr, CopyLen),
ExitBB, FwdLoopBB); ExitBB, FwdLoopBB);
FwdCopyPhi->addIncoming(FwdIndexPtr, FwdLoopBB); FwdCopyPhi->addIncoming(FwdIndexPtr, FwdLoopBB);
FwdCopyPhi->addIncoming(ConstantInt::get(TypeOfLen, 0), CopyForwardBB); FwdCopyPhi->addIncoming(ConstantInt::get(TypeOfCopyLen, 0), CopyForwardBB);
BranchInst::Create(ExitBB, FwdLoopBB, CompareN, ElseTerm); BranchInst::Create(ExitBB, FwdLoopBB, CompareN, ElseTerm);
ElseTerm->eraseFromParent(); ElseTerm->eraseFromParent();
} }
// Lower memset to loop. // Lower memset to loop.
void convertMemSetToLoop(Instruction *splitAt, Value *dstAddr, Value *len, void convertMemSetToLoop(Instruction *ConvertedInst, Value *DstAddr,
Value *val, LLVMContext &Context, Function &F) { Value *CopyLen, Value *SetValue, LLVMContext &Context,
BasicBlock *origBB = splitAt->getParent(); Function &F) {
BasicBlock *newBB = splitAt->getParent()->splitBasicBlock(splitAt, "split"); BasicBlock *OrigBB = ConvertedInst->getParent();
BasicBlock *loopBB = BasicBlock::Create(Context, "loadstoreloop", &F, newBB); BasicBlock *NewBB =
ConvertedInst->getParent()->splitBasicBlock(ConvertedInst, "split");
BasicBlock *LoopBB = BasicBlock::Create(Context, "loadstoreloop", &F, NewBB);
origBB->getTerminator()->setSuccessor(0, loopBB); OrigBB->getTerminator()->setSuccessor(0, LoopBB);
IRBuilder<> builder(origBB, origBB->getTerminator()); IRBuilder<> Builder(OrigBB, OrigBB->getTerminator());
unsigned dstAS = cast<PointerType>(dstAddr->getType())->getAddressSpace();
// Cast pointer to the type of value getting stored // Cast pointer to the type of value getting stored
dstAddr = unsigned dstAS = cast<PointerType>(DstAddr->getType())->getAddressSpace();
builder.CreateBitCast(dstAddr, PointerType::get(val->getType(), dstAS)); DstAddr = Builder.CreateBitCast(DstAddr,
PointerType::get(SetValue->getType(), dstAS));
IRBuilder<> loop(loopBB); IRBuilder<> LoopBuilder(LoopBB);
PHINode *ind = loop.CreatePHI(len->getType(), 0); PHINode *LoopIndex = LoopBuilder.CreatePHI(CopyLen->getType(), 0);
ind->addIncoming(ConstantInt::get(len->getType(), 0), origBB); LoopIndex->addIncoming(ConstantInt::get(CopyLen->getType(), 0), OrigBB);
loop.CreateStore(val, loop.CreateGEP(val->getType(), dstAddr, ind), false); LoopBuilder.CreateStore(
SetValue, LoopBuilder.CreateGEP(SetValue->getType(), DstAddr, LoopIndex),
false);
Value *newind = loop.CreateAdd(ind, ConstantInt::get(len->getType(), 1)); Value *NewIndex =
ind->addIncoming(newind, loopBB); LoopBuilder.CreateAdd(LoopIndex, ConstantInt::get(CopyLen->getType(), 1));
LoopIndex->addIncoming(NewIndex, LoopBB);
loop.CreateCondBr(loop.CreateICmpULT(newind, len), loopBB, newBB); LoopBuilder.CreateCondBr(LoopBuilder.CreateICmpULT(NewIndex, CopyLen), LoopBB,
NewBB);
} }
bool NVPTXLowerAggrCopies::runOnFunction(Function &F) { bool NVPTXLowerAggrCopies::runOnFunction(Function &F) {
SmallVector<LoadInst *, 4> aggrLoads; SmallVector<LoadInst *, 4> AggrLoads;
SmallVector<MemIntrinsic *, 4> MemCalls; SmallVector<MemIntrinsic *, 4> MemCalls;
const DataLayout &DL = F.getParent()->getDataLayout(); const DataLayout &DL = F.getParent()->getDataLayout();
@@ -235,18 +247,17 @@ bool NVPTXLowerAggrCopies::runOnFunction(Function &F) {
for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) { for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); II != IE; for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); II != IE;
++II) { ++II) {
if (LoadInst *load = dyn_cast<LoadInst>(II)) { if (LoadInst *LI = dyn_cast<LoadInst>(II)) {
if (!load->hasOneUse()) if (!LI->hasOneUse())
continue; continue;
if (DL.getTypeStoreSize(load->getType()) < MaxAggrCopySize) if (DL.getTypeStoreSize(LI->getType()) < MaxAggrCopySize)
continue; continue;
User *use = load->user_back(); if (StoreInst *SI = dyn_cast<StoreInst>(LI->user_back())) {
if (StoreInst *store = dyn_cast<StoreInst>(use)) { if (SI->getOperand(0) != LI)
if (store->getOperand(0) != load)
continue; continue;
aggrLoads.push_back(load); AggrLoads.push_back(LI);
} }
} else if (MemIntrinsic *IntrCall = dyn_cast<MemIntrinsic>(II)) { } else if (MemIntrinsic *IntrCall = dyn_cast<MemIntrinsic>(II)) {
// Convert intrinsic calls with variable size or with constant size // Convert intrinsic calls with variable size or with constant size
@@ -262,55 +273,60 @@ bool NVPTXLowerAggrCopies::runOnFunction(Function &F) {
} }
} }
if (aggrLoads.size() == 0 && MemCalls.size() == 0) { if (AggrLoads.size() == 0 && MemCalls.size() == 0) {
return false; return false;
} }
// //
// Do the transformation of an aggr load/copy/set to a loop // Do the transformation of an aggr load/copy/set to a loop
// //
for (LoadInst *load : aggrLoads) { for (LoadInst *LI : AggrLoads) {
StoreInst *store = dyn_cast<StoreInst>(*load->user_begin()); StoreInst *SI = dyn_cast<StoreInst>(*LI->user_begin());
Value *srcAddr = load->getOperand(0); Value *SrcAddr = LI->getOperand(0);
Value *dstAddr = store->getOperand(1); Value *DstAddr = SI->getOperand(1);
unsigned numLoads = DL.getTypeStoreSize(load->getType()); unsigned NumLoads = DL.getTypeStoreSize(LI->getType());
Value *len = ConstantInt::get(Type::getInt32Ty(Context), numLoads); Value *CopyLen = ConstantInt::get(Type::getInt32Ty(Context), NumLoads);
convertMemCpyToLoop(store, srcAddr, dstAddr, len, load->isVolatile(), convertMemCpyToLoop(/* ConvertedInst */ SI,
store->isVolatile(), Context, F); /* SrcAddr */ SrcAddr, /* DstAddr */ DstAddr,
/* CopyLen */ CopyLen,
/* SrcIsVolatile */ LI->isVolatile(),
/* DstIsVolatile */ SI->isVolatile(),
/* Context */ Context,
/* Function F */ F);
store->eraseFromParent(); SI->eraseFromParent();
load->eraseFromParent(); LI->eraseFromParent();
} }
// Transform mem* intrinsic calls. // Transform mem* intrinsic calls.
for (MemIntrinsic *MemCall : MemCalls) { for (MemIntrinsic *MemCall : MemCalls) {
if (MemCpyInst *Memcpy = dyn_cast<MemCpyInst>(MemCall)) { if (MemCpyInst *Memcpy = dyn_cast<MemCpyInst>(MemCall)) {
convertMemCpyToLoop(/* splitAt */ Memcpy, convertMemCpyToLoop(/* ConvertedInst */ Memcpy,
/* srcAddr */ Memcpy->getRawSource(), /* SrcAddr */ Memcpy->getRawSource(),
/* dstAddr */ Memcpy->getRawDest(), /* DstAddr */ Memcpy->getRawDest(),
/* len */ Memcpy->getLength(), /* CopyLen */ Memcpy->getLength(),
/* srcVolatile */ Memcpy->isVolatile(), /* SrcIsVolatile */ Memcpy->isVolatile(),
/* dstVolatile */ Memcpy->isVolatile(), /* DstIsVolatile */ Memcpy->isVolatile(),
/* Context */ Context, /* Context */ Context,
/* Function F */ F); /* Function F */ F);
} else if (MemMoveInst *Memmove = dyn_cast<MemMoveInst>(MemCall)) { } else if (MemMoveInst *Memmove = dyn_cast<MemMoveInst>(MemCall)) {
convertMemMoveToLoop(/* splitAt */ Memmove, convertMemMoveToLoop(/* ConvertedInst */ Memmove,
/* srcAddr */ Memmove->getRawSource(), /* SrcAddr */ Memmove->getRawSource(),
/* dstAddr */ Memmove->getRawDest(), /* DstAddr */ Memmove->getRawDest(),
/* len */ Memmove->getLength(), /* CopyLen */ Memmove->getLength(),
/* srcVolatile */ Memmove->isVolatile(), /* SrcIsVolatile */ Memmove->isVolatile(),
/* dstVolatile */ Memmove->isVolatile(), /* DstIsVolatile */ Memmove->isVolatile(),
/* Context */ Context, /* Context */ Context,
/* Function F */ F); /* Function F */ F);
} else if (MemSetInst *Memset = dyn_cast<MemSetInst>(MemCall)) { } else if (MemSetInst *Memset = dyn_cast<MemSetInst>(MemCall)) {
convertMemSetToLoop(/* splitAt */ Memset, convertMemSetToLoop(/* ConvertedInst */ Memset,
/* dstAddr */ Memset->getRawDest(), /* DstAddr */ Memset->getRawDest(),
/* len */ Memset->getLength(), /* CopyLen */ Memset->getLength(),
/* val */ Memset->getValue(), /* SetValue */ Memset->getValue(),
/* Context */ Context, /* Context */ Context,
/* F */ F); /* Function F */ F);
} }
MemCall->eraseFromParent(); MemCall->eraseFromParent();
} }