forked from OSchip/llvm-project
[OpenMP][OMPBuilder] Adding privatization related `createXXXX` to OMPBuilder
This commit is contained in:
parent
c19e82c6b3
commit
82b8236cf2
llvm
include/llvm/Frontend/OpenMP
lib/Frontend/OpenMP
unittests/Frontend
|
@ -315,7 +315,7 @@ public:
|
|||
BodyGenCallbackTy BodyGenCB,
|
||||
FinalizeCallbackTy FiniCB);
|
||||
|
||||
/// Generator for '#omp master'
|
||||
/// Generator for '#omp critical'
|
||||
///
|
||||
/// \param Loc The insert and source location description.
|
||||
/// \param BodyGenCB Callback that will generate the region body code.
|
||||
|
@ -329,6 +329,58 @@ public:
|
|||
FinalizeCallbackTy FiniCB,
|
||||
StringRef CriticalName, Value *HintInst);
|
||||
|
||||
/// Generate conditional branch and relevant BasicBlocks through which private
|
||||
/// threads copy the 'copyin' variables from Master copy to threadprivate
|
||||
/// copies.
|
||||
///
|
||||
/// \param IP insertion block for copyin conditional
|
||||
/// \param MasterVarPtr a pointer to the master variable
|
||||
/// \param PrivateVarPtr a pointer to the threadprivate variable
|
||||
/// \param IntPtrTy Pointer size type
|
||||
/// \param BranchtoEnd Create a branch between the copyin.not.master blocks
|
||||
// and copy.in.end block
|
||||
///
|
||||
/// \returns The insertion point where copying operation to be emitted.
|
||||
InsertPointTy CreateCopyinClauseBlocks(InsertPointTy IP, Value *MasterAddr,
|
||||
Value *PrivateAddr,
|
||||
llvm::IntegerType *IntPtrTy,
|
||||
bool BranchtoEnd = true);
|
||||
|
||||
/// Create a runtime call for kmpc_Alloc
|
||||
///
|
||||
/// \param Loc The insert and source location description.
|
||||
/// \param Size Size of allocated memory space
|
||||
/// \param Allocator Allocator information instruction
|
||||
/// \param Name Name of call Instruction for OMP_alloc
|
||||
///
|
||||
/// \returns CallInst to the OMP_Alloc call
|
||||
CallInst *CreateOMPAlloc(const LocationDescription &Loc, Value *Size,
|
||||
Value *Allocator, std::string Name = "");
|
||||
|
||||
/// Create a runtime call for kmpc_free
|
||||
///
|
||||
/// \param Loc The insert and source location description.
|
||||
/// \param Addr Address of memory space to be freed
|
||||
/// \param Allocator Allocator information instruction
|
||||
/// \param Name Name of call Instruction for OMP_Free
|
||||
///
|
||||
/// \returns CallInst to the OMP_Free call
|
||||
CallInst *CreateOMPFree(const LocationDescription &Loc, Value *Addr,
|
||||
Value *Allocator, std::string Name = "");
|
||||
|
||||
/// Create a runtime call for kmpc_threadprivate_cached
|
||||
///
|
||||
/// \param Loc The insert and source location description.
|
||||
/// \param Pointer pointer to data to be cached
|
||||
/// \param Size size of data to be cached
|
||||
/// \param Name Name of call Instruction for callinst
|
||||
///
|
||||
/// \returns CallInst to the thread private cache call.
|
||||
CallInst *CreateCachedThreadPrivate(const LocationDescription &Loc,
|
||||
llvm::Value *Pointer,
|
||||
llvm::ConstantInt *Size,
|
||||
const llvm::Twine &Name = Twine(""));
|
||||
|
||||
private:
|
||||
/// Common interface for generating entry calls for OMP Directives.
|
||||
/// if the directive has a region/body, It will set the insertion
|
||||
|
@ -387,7 +439,7 @@ private:
|
|||
/// \param Parts different parts of the final name that needs separation
|
||||
/// \param FirstSeparator First separator used between the initial two
|
||||
/// parts of the name.
|
||||
/// \param Separator separator used between all of the rest consecutinve
|
||||
/// \param Separator separator used between all of the rest consecutive
|
||||
/// parts of the name
|
||||
static std::string getNameWithSeparators(ArrayRef<StringRef> Parts,
|
||||
StringRef FirstSeparator,
|
||||
|
|
|
@ -611,9 +611,6 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::CreateParallel(
|
|||
"Unexpected finalization stack state!");
|
||||
|
||||
Instruction *PRegPreFiniTI = PRegPreFiniBB->getTerminator();
|
||||
assert(PRegPreFiniTI->getNumSuccessors() == 1 &&
|
||||
PRegPreFiniTI->getSuccessor(0) == PRegExitBB &&
|
||||
"Unexpected CFG structure!");
|
||||
|
||||
InsertPointTy PreFiniIP(PRegPreFiniBB, PRegPreFiniTI->getIterator());
|
||||
FiniCB(PreFiniIP);
|
||||
|
@ -948,6 +945,105 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::emitCommonDirectiveExit(
|
|||
ExitCall->getIterator());
|
||||
}
|
||||
|
||||
OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::CreateCopyinClauseBlocks(
|
||||
InsertPointTy IP, Value *MasterAddr, Value *PrivateAddr,
|
||||
llvm::IntegerType *IntPtrTy, bool BranchtoEnd) {
|
||||
if (!IP.isSet())
|
||||
return IP;
|
||||
|
||||
IRBuilder<>::InsertPointGuard IPG(Builder);
|
||||
|
||||
// creates the following CFG structure
|
||||
// OMP_Entry : (MasterAddr != PrivateAddr)?
|
||||
// F T
|
||||
// | \
|
||||
// | copin.not.master
|
||||
// | /
|
||||
// v /
|
||||
// copyin.not.master.end
|
||||
// |
|
||||
// v
|
||||
// OMP.Entry.Next
|
||||
|
||||
BasicBlock *OMP_Entry = IP.getBlock();
|
||||
Function *CurFn = OMP_Entry->getParent();
|
||||
BasicBlock *CopyBegin =
|
||||
BasicBlock::Create(M.getContext(), "copyin.not.master", CurFn);
|
||||
BasicBlock *CopyEnd = nullptr;
|
||||
|
||||
// If entry block is terminated, split to preserve the branch to following
|
||||
// basic block (i.e. OMP.Entry.Next), otherwise, leave everything as is.
|
||||
if (isa_and_nonnull<BranchInst>(OMP_Entry->getTerminator())) {
|
||||
CopyEnd = OMP_Entry->splitBasicBlock(OMP_Entry->getTerminator(),
|
||||
"copyin.not.master.end");
|
||||
OMP_Entry->getTerminator()->eraseFromParent();
|
||||
} else {
|
||||
CopyEnd =
|
||||
BasicBlock::Create(M.getContext(), "copyin.not.master.end", CurFn);
|
||||
}
|
||||
|
||||
Builder.SetInsertPoint(OMP_Entry);
|
||||
Value *MasterPtr = Builder.CreatePtrToInt(MasterAddr, IntPtrTy);
|
||||
Value *PrivatePtr = Builder.CreatePtrToInt(PrivateAddr, IntPtrTy);
|
||||
Value *cmp = Builder.CreateICmpNE(MasterPtr, PrivatePtr);
|
||||
Builder.CreateCondBr(cmp, CopyBegin, CopyEnd);
|
||||
|
||||
Builder.SetInsertPoint(CopyBegin);
|
||||
if (BranchtoEnd)
|
||||
Builder.SetInsertPoint(Builder.CreateBr(CopyEnd));
|
||||
|
||||
return Builder.saveIP();
|
||||
}
|
||||
|
||||
CallInst *OpenMPIRBuilder::CreateOMPAlloc(const LocationDescription &Loc,
|
||||
Value *Size, Value *Allocator,
|
||||
std::string Name) {
|
||||
IRBuilder<>::InsertPointGuard IPG(Builder);
|
||||
Builder.restoreIP(Loc.IP);
|
||||
|
||||
Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
|
||||
Value *Ident = getOrCreateIdent(SrcLocStr);
|
||||
Value *ThreadId = getOrCreateThreadID(Ident);
|
||||
Value *Args[] = {ThreadId, Size, Allocator};
|
||||
|
||||
Function *Fn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_alloc);
|
||||
|
||||
return Builder.CreateCall(Fn, Args, Name);
|
||||
}
|
||||
|
||||
CallInst *OpenMPIRBuilder::CreateOMPFree(const LocationDescription &Loc,
|
||||
Value *Addr, Value *Allocator,
|
||||
std::string Name) {
|
||||
IRBuilder<>::InsertPointGuard IPG(Builder);
|
||||
Builder.restoreIP(Loc.IP);
|
||||
|
||||
Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
|
||||
Value *Ident = getOrCreateIdent(SrcLocStr);
|
||||
Value *ThreadId = getOrCreateThreadID(Ident);
|
||||
Value *Args[] = {ThreadId, Addr, Allocator};
|
||||
Function *Fn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_free);
|
||||
return Builder.CreateCall(Fn, Args, Name);
|
||||
}
|
||||
|
||||
CallInst *OpenMPIRBuilder::CreateCachedThreadPrivate(
|
||||
const LocationDescription &Loc, llvm::Value *Pointer,
|
||||
llvm::ConstantInt *Size, const llvm::Twine &Name) {
|
||||
IRBuilder<>::InsertPointGuard IPG(Builder);
|
||||
Builder.restoreIP(Loc.IP);
|
||||
|
||||
Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
|
||||
Value *Ident = getOrCreateIdent(SrcLocStr);
|
||||
Value *ThreadId = getOrCreateThreadID(Ident);
|
||||
Constant *ThreadPrivateCache =
|
||||
getOrCreateOMPInternalVariable(Int8PtrPtr, Name);
|
||||
llvm::Value *Args[] = {Ident, ThreadId, Pointer, Size, ThreadPrivateCache};
|
||||
|
||||
Function *Fn =
|
||||
getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_threadprivate_cached);
|
||||
|
||||
return Builder.CreateCall(Fn, Args);
|
||||
}
|
||||
|
||||
std::string OpenMPIRBuilder::getNameWithSeparators(ArrayRef<StringRef> Parts,
|
||||
StringRef FirstSeparator,
|
||||
StringRef Separator) {
|
||||
|
|
|
@ -779,4 +779,41 @@ TEST_F(OpenMPIRBuilderTest, CriticalDirective) {
|
|||
EXPECT_EQ(CriticalEndCI->getArgOperand(2)->getType(), CriticalNamePtrTy);
|
||||
}
|
||||
|
||||
TEST_F(OpenMPIRBuilderTest, CopyinBlocks) {
|
||||
using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
|
||||
OpenMPIRBuilder OMPBuilder(*M);
|
||||
OMPBuilder.initialize();
|
||||
F->setName("func");
|
||||
IRBuilder<> Builder(BB);
|
||||
|
||||
OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
|
||||
|
||||
AllocaInst *PrivAI = Builder.CreateAlloca(F->arg_begin()->getType());
|
||||
IntegerType* Int32 = Type::getInt32Ty(M->getContext());
|
||||
AllocaInst* MasterAddress = Builder.CreateAlloca(Int32->getPointerTo());
|
||||
AllocaInst* PrivAddress = Builder.CreateAlloca(Int32->getPointerTo());
|
||||
|
||||
BasicBlock *EntryBB = BB;
|
||||
|
||||
OMPBuilder.CreateCopyinClauseBlocks(Builder.saveIP(), MasterAddress, PrivAddress, Int32, /*BranchtoEnd*/true);
|
||||
|
||||
BranchInst* EntryBr = dyn_cast_or_null<BranchInst>(EntryBB->getTerminator());
|
||||
|
||||
EXPECT_NE(EntryBr, nullptr);
|
||||
EXPECT_TRUE(EntryBr->isConditional());
|
||||
|
||||
BasicBlock* NotMasterBB = EntryBr->getSuccessor(0);
|
||||
BasicBlock* CopyinEnd = EntryBr->getSuccessor(1);
|
||||
CmpInst* CMP = dyn_cast_or_null<CmpInst>(EntryBr->getCondition());
|
||||
|
||||
EXPECT_NE(CMP, nullptr);
|
||||
EXPECT_NE(NotMasterBB, nullptr);
|
||||
EXPECT_NE(CopyinEnd, nullptr);
|
||||
|
||||
BranchInst* NotMasterBr = dyn_cast_or_null<BranchInst>(NotMasterBB->getTerminator());
|
||||
EXPECT_NE(NotMasterBr, nullptr);
|
||||
EXPECT_FALSE(NotMasterBr->isConditional());
|
||||
EXPECT_EQ(CopyinEnd,NotMasterBr->getSuccessor(0));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in New Issue