Skip to content

Commit 17ae5d7

Browse files
committed
[OpenMP][Clang] Migrate OpenMP UserDefinedMapper from Clang to OMPIRBuilder
This patch migrates the OpenMP UserDefinedMapper codegen from Clang to the OpenMPIRBuilder. I will be adding further patches in the near future so that OpenMP dialect in MLIR can make use of these.
1 parent 056153f commit 17ae5d7

File tree

7 files changed

+459
-381
lines changed

7 files changed

+459
-381
lines changed

clang/lib/CodeGen/CGOpenMPRuntime.cpp

Lines changed: 49 additions & 241 deletions
Original file line numberDiff line numberDiff line change
@@ -9042,257 +9042,65 @@ void CGOpenMPRuntime::emitUserDefinedMapper(const OMPDeclareMapperDecl *D,
90429042
return;
90439043
ASTContext &C = CGM.getContext();
90449044
QualType Ty = D->getType();
9045-
QualType PtrTy = C.getPointerType(Ty).withRestrict();
9046-
QualType Int64Ty = C.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/true);
90479045
auto *MapperVarDecl =
90489046
cast<VarDecl>(cast<DeclRefExpr>(D->getMapperVarRef())->getDecl());
9049-
SourceLocation Loc = D->getLocation();
90509047
CharUnits ElementSize = C.getTypeSizeInChars(Ty);
90519048
llvm::Type *ElemTy = CGM.getTypes().ConvertTypeForMem(Ty);
90529049

9053-
// Prepare mapper function arguments and attributes.
9054-
ImplicitParamDecl HandleArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
9055-
C.VoidPtrTy, ImplicitParamKind::Other);
9056-
ImplicitParamDecl BaseArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
9057-
ImplicitParamKind::Other);
9058-
ImplicitParamDecl BeginArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
9059-
C.VoidPtrTy, ImplicitParamKind::Other);
9060-
ImplicitParamDecl SizeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, Int64Ty,
9061-
ImplicitParamKind::Other);
9062-
ImplicitParamDecl TypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, Int64Ty,
9063-
ImplicitParamKind::Other);
9064-
ImplicitParamDecl NameArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
9065-
ImplicitParamKind::Other);
9066-
FunctionArgList Args;
9067-
Args.push_back(&HandleArg);
9068-
Args.push_back(&BaseArg);
9069-
Args.push_back(&BeginArg);
9070-
Args.push_back(&SizeArg);
9071-
Args.push_back(&TypeArg);
9072-
Args.push_back(&NameArg);
9073-
const CGFunctionInfo &FnInfo =
9074-
CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
9075-
llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
9076-
SmallString<64> TyStr;
9077-
llvm::raw_svector_ostream Out(TyStr);
9078-
CGM.getCXXABI().getMangleContext().mangleCanonicalTypeName(Ty, Out);
9079-
std::string Name = getName({"omp_mapper", TyStr, D->getName()});
9080-
auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
9081-
Name, &CGM.getModule());
9082-
CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
9083-
Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
9084-
// Start the mapper function code generation.
90859050
CodeGenFunction MapperCGF(CGM);
9086-
MapperCGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
9087-
// Compute the starting and end addresses of array elements.
9088-
llvm::Value *Size = MapperCGF.EmitLoadOfScalar(
9089-
MapperCGF.GetAddrOfLocalVar(&SizeArg), /*Volatile=*/false,
9090-
C.getPointerType(Int64Ty), Loc);
9091-
// Prepare common arguments for array initiation and deletion.
9092-
llvm::Value *Handle = MapperCGF.EmitLoadOfScalar(
9093-
MapperCGF.GetAddrOfLocalVar(&HandleArg),
9094-
/*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
9095-
llvm::Value *BaseIn = MapperCGF.EmitLoadOfScalar(
9096-
MapperCGF.GetAddrOfLocalVar(&BaseArg),
9097-
/*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
9098-
llvm::Value *BeginIn = MapperCGF.EmitLoadOfScalar(
9099-
MapperCGF.GetAddrOfLocalVar(&BeginArg),
9100-
/*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
9101-
// Convert the size in bytes into the number of array elements.
9102-
Size = MapperCGF.Builder.CreateExactUDiv(
9103-
Size, MapperCGF.Builder.getInt64(ElementSize.getQuantity()));
9104-
llvm::Value *PtrBegin = MapperCGF.Builder.CreateBitCast(
9105-
BeginIn, CGM.getTypes().ConvertTypeForMem(PtrTy));
9106-
llvm::Value *PtrEnd = MapperCGF.Builder.CreateGEP(ElemTy, PtrBegin, Size);
9107-
llvm::Value *MapType = MapperCGF.EmitLoadOfScalar(
9108-
MapperCGF.GetAddrOfLocalVar(&TypeArg), /*Volatile=*/false,
9109-
C.getPointerType(Int64Ty), Loc);
9110-
llvm::Value *MapName = MapperCGF.EmitLoadOfScalar(
9111-
MapperCGF.GetAddrOfLocalVar(&NameArg),
9112-
/*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
9113-
9114-
// Emit array initiation if this is an array section and \p MapType indicates
9115-
// that memory allocation is required.
9116-
llvm::BasicBlock *HeadBB = MapperCGF.createBasicBlock("omp.arraymap.head");
9117-
emitUDMapperArrayInitOrDel(MapperCGF, Handle, BaseIn, BeginIn, Size, MapType,
9118-
MapName, ElementSize, HeadBB, /*IsInit=*/true);
9119-
9120-
// Emit a for loop to iterate through SizeArg of elements and map all of them.
9121-
9122-
// Emit the loop header block.
9123-
MapperCGF.EmitBlock(HeadBB);
9124-
llvm::BasicBlock *BodyBB = MapperCGF.createBasicBlock("omp.arraymap.body");
9125-
llvm::BasicBlock *DoneBB = MapperCGF.createBasicBlock("omp.done");
9126-
// Evaluate whether the initial condition is satisfied.
9127-
llvm::Value *IsEmpty =
9128-
MapperCGF.Builder.CreateICmpEQ(PtrBegin, PtrEnd, "omp.arraymap.isempty");
9129-
MapperCGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
9130-
llvm::BasicBlock *EntryBB = MapperCGF.Builder.GetInsertBlock();
9051+
MappableExprsHandler::MapCombinedInfoTy CombinedInfo;
9052+
auto PrivatizeAndGenMapInfoCB =
9053+
[&](llvm::OpenMPIRBuilder::InsertPointTy CodeGenIP, llvm::Value *PtrPHI,
9054+
llvm::Value *BeginArg) -> llvm::OpenMPIRBuilder::MapInfosTy & {
9055+
MapperCGF.Builder.restoreIP(CodeGenIP);
9056+
9057+
// Privatize the declared variable of mapper to be the current array
9058+
// element.
9059+
Address PtrCurrent(
9060+
PtrPHI, ElemTy,
9061+
Address(BeginArg, MapperCGF.VoidPtrTy, CGM.getPointerAlign())
9062+
.getAlignment()
9063+
.alignmentOfArrayElement(ElementSize));
9064+
CodeGenFunction::OMPPrivateScope Scope(MapperCGF);
9065+
Scope.addPrivate(MapperVarDecl, PtrCurrent);
9066+
(void)Scope.Privatize();
91319067

9132-
// Emit the loop body block.
9133-
MapperCGF.EmitBlock(BodyBB);
9134-
llvm::BasicBlock *LastBB = BodyBB;
9135-
llvm::PHINode *PtrPHI = MapperCGF.Builder.CreatePHI(
9136-
PtrBegin->getType(), 2, "omp.arraymap.ptrcurrent");
9137-
PtrPHI->addIncoming(PtrBegin, EntryBB);
9138-
Address PtrCurrent(PtrPHI, ElemTy,
9139-
MapperCGF.GetAddrOfLocalVar(&BeginArg)
9140-
.getAlignment()
9141-
.alignmentOfArrayElement(ElementSize));
9142-
// Privatize the declared variable of mapper to be the current array element.
9143-
CodeGenFunction::OMPPrivateScope Scope(MapperCGF);
9144-
Scope.addPrivate(MapperVarDecl, PtrCurrent);
9145-
(void)Scope.Privatize();
9068+
// Get map clause information.
9069+
MappableExprsHandler MEHandler(*D, MapperCGF);
9070+
MEHandler.generateAllInfoForMapper(CombinedInfo, OMPBuilder);
9071+
9072+
auto FillInfoMap = [&](MappableExprsHandler::MappingExprInfo &MapExpr) {
9073+
return emitMappingInformation(MapperCGF, OMPBuilder, MapExpr);
9074+
};
9075+
if (CGM.getCodeGenOpts().getDebugInfo() !=
9076+
llvm::codegenoptions::NoDebugInfo) {
9077+
CombinedInfo.Names.resize(CombinedInfo.Exprs.size());
9078+
llvm::transform(CombinedInfo.Exprs, CombinedInfo.Names.begin(),
9079+
FillInfoMap);
9080+
}
91469081

9147-
// Get map clause information. Fill up the arrays with all mapped variables.
9148-
MappableExprsHandler::MapCombinedInfoTy Info;
9149-
MappableExprsHandler MEHandler(*D, MapperCGF);
9150-
MEHandler.generateAllInfoForMapper(Info, OMPBuilder);
9082+
return CombinedInfo;
9083+
};
91519084

9152-
// Call the runtime API __tgt_mapper_num_components to get the number of
9153-
// pre-existing components.
9154-
llvm::Value *OffloadingArgs[] = {Handle};
9155-
llvm::Value *PreviousSize = MapperCGF.EmitRuntimeCall(
9156-
OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
9157-
OMPRTL___tgt_mapper_num_components),
9158-
OffloadingArgs);
9159-
llvm::Value *ShiftedPreviousSize = MapperCGF.Builder.CreateShl(
9160-
PreviousSize,
9161-
MapperCGF.Builder.getInt64(MappableExprsHandler::getFlagMemberOffset()));
9162-
9163-
// Fill up the runtime mapper handle for all components.
9164-
for (unsigned I = 0; I < Info.BasePointers.size(); ++I) {
9165-
llvm::Value *CurBaseArg = MapperCGF.Builder.CreateBitCast(
9166-
Info.BasePointers[I], CGM.getTypes().ConvertTypeForMem(C.VoidPtrTy));
9167-
llvm::Value *CurBeginArg = MapperCGF.Builder.CreateBitCast(
9168-
Info.Pointers[I], CGM.getTypes().ConvertTypeForMem(C.VoidPtrTy));
9169-
llvm::Value *CurSizeArg = Info.Sizes[I];
9170-
llvm::Value *CurNameArg =
9171-
(CGM.getCodeGenOpts().getDebugInfo() ==
9172-
llvm::codegenoptions::NoDebugInfo)
9173-
? llvm::ConstantPointerNull::get(CGM.VoidPtrTy)
9174-
: emitMappingInformation(MapperCGF, OMPBuilder, Info.Exprs[I]);
9175-
9176-
// Extract the MEMBER_OF field from the map type.
9177-
llvm::Value *OriMapType = MapperCGF.Builder.getInt64(
9178-
static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
9179-
Info.Types[I]));
9180-
llvm::Value *MemberMapType =
9181-
MapperCGF.Builder.CreateNUWAdd(OriMapType, ShiftedPreviousSize);
9182-
9183-
// Combine the map type inherited from user-defined mapper with that
9184-
// specified in the program. According to the OMP_MAP_TO and OMP_MAP_FROM
9185-
// bits of the \a MapType, which is the input argument of the mapper
9186-
// function, the following code will set the OMP_MAP_TO and OMP_MAP_FROM
9187-
// bits of MemberMapType.
9188-
// [OpenMP 5.0], 1.2.6. map-type decay.
9189-
// | alloc | to | from | tofrom | release | delete
9190-
// ----------------------------------------------------------
9191-
// alloc | alloc | alloc | alloc | alloc | release | delete
9192-
// to | alloc | to | alloc | to | release | delete
9193-
// from | alloc | alloc | from | from | release | delete
9194-
// tofrom | alloc | to | from | tofrom | release | delete
9195-
llvm::Value *LeftToFrom = MapperCGF.Builder.CreateAnd(
9196-
MapType,
9197-
MapperCGF.Builder.getInt64(
9198-
static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
9199-
OpenMPOffloadMappingFlags::OMP_MAP_TO |
9200-
OpenMPOffloadMappingFlags::OMP_MAP_FROM)));
9201-
llvm::BasicBlock *AllocBB = MapperCGF.createBasicBlock("omp.type.alloc");
9202-
llvm::BasicBlock *AllocElseBB =
9203-
MapperCGF.createBasicBlock("omp.type.alloc.else");
9204-
llvm::BasicBlock *ToBB = MapperCGF.createBasicBlock("omp.type.to");
9205-
llvm::BasicBlock *ToElseBB = MapperCGF.createBasicBlock("omp.type.to.else");
9206-
llvm::BasicBlock *FromBB = MapperCGF.createBasicBlock("omp.type.from");
9207-
llvm::BasicBlock *EndBB = MapperCGF.createBasicBlock("omp.type.end");
9208-
llvm::Value *IsAlloc = MapperCGF.Builder.CreateIsNull(LeftToFrom);
9209-
MapperCGF.Builder.CreateCondBr(IsAlloc, AllocBB, AllocElseBB);
9210-
// In case of alloc, clear OMP_MAP_TO and OMP_MAP_FROM.
9211-
MapperCGF.EmitBlock(AllocBB);
9212-
llvm::Value *AllocMapType = MapperCGF.Builder.CreateAnd(
9213-
MemberMapType,
9214-
MapperCGF.Builder.getInt64(
9215-
~static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
9216-
OpenMPOffloadMappingFlags::OMP_MAP_TO |
9217-
OpenMPOffloadMappingFlags::OMP_MAP_FROM)));
9218-
MapperCGF.Builder.CreateBr(EndBB);
9219-
MapperCGF.EmitBlock(AllocElseBB);
9220-
llvm::Value *IsTo = MapperCGF.Builder.CreateICmpEQ(
9221-
LeftToFrom,
9222-
MapperCGF.Builder.getInt64(
9223-
static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
9224-
OpenMPOffloadMappingFlags::OMP_MAP_TO)));
9225-
MapperCGF.Builder.CreateCondBr(IsTo, ToBB, ToElseBB);
9226-
// In case of to, clear OMP_MAP_FROM.
9227-
MapperCGF.EmitBlock(ToBB);
9228-
llvm::Value *ToMapType = MapperCGF.Builder.CreateAnd(
9229-
MemberMapType,
9230-
MapperCGF.Builder.getInt64(
9231-
~static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
9232-
OpenMPOffloadMappingFlags::OMP_MAP_FROM)));
9233-
MapperCGF.Builder.CreateBr(EndBB);
9234-
MapperCGF.EmitBlock(ToElseBB);
9235-
llvm::Value *IsFrom = MapperCGF.Builder.CreateICmpEQ(
9236-
LeftToFrom,
9237-
MapperCGF.Builder.getInt64(
9238-
static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
9239-
OpenMPOffloadMappingFlags::OMP_MAP_FROM)));
9240-
MapperCGF.Builder.CreateCondBr(IsFrom, FromBB, EndBB);
9241-
// In case of from, clear OMP_MAP_TO.
9242-
MapperCGF.EmitBlock(FromBB);
9243-
llvm::Value *FromMapType = MapperCGF.Builder.CreateAnd(
9244-
MemberMapType,
9245-
MapperCGF.Builder.getInt64(
9246-
~static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
9247-
OpenMPOffloadMappingFlags::OMP_MAP_TO)));
9248-
// In case of tofrom, do nothing.
9249-
MapperCGF.EmitBlock(EndBB);
9250-
LastBB = EndBB;
9251-
llvm::PHINode *CurMapType =
9252-
MapperCGF.Builder.CreatePHI(CGM.Int64Ty, 4, "omp.maptype");
9253-
CurMapType->addIncoming(AllocMapType, AllocBB);
9254-
CurMapType->addIncoming(ToMapType, ToBB);
9255-
CurMapType->addIncoming(FromMapType, FromBB);
9256-
CurMapType->addIncoming(MemberMapType, ToElseBB);
9257-
9258-
llvm::Value *OffloadingArgs[] = {Handle, CurBaseArg, CurBeginArg,
9259-
CurSizeArg, CurMapType, CurNameArg};
9260-
if (Info.Mappers[I]) {
9085+
auto CustomMapperCB = [&](unsigned I, llvm::Function **MapperFunc) {
9086+
if (CombinedInfo.Mappers[I]) {
92619087
// Call the corresponding mapper function.
9262-
llvm::Function *MapperFunc = getOrCreateUserDefinedMapperFunc(
9263-
cast<OMPDeclareMapperDecl>(Info.Mappers[I]));
9264-
assert(MapperFunc && "Expect a valid mapper function is available.");
9265-
MapperCGF.EmitNounwindRuntimeCall(MapperFunc, OffloadingArgs);
9266-
} else {
9267-
// Call the runtime API __tgt_push_mapper_component to fill up the runtime
9268-
// data structure.
9269-
MapperCGF.EmitRuntimeCall(
9270-
OMPBuilder.getOrCreateRuntimeFunction(
9271-
CGM.getModule(), OMPRTL___tgt_push_mapper_component),
9272-
OffloadingArgs);
9273-
}
9274-
}
9275-
9276-
// Update the pointer to point to the next element that needs to be mapped,
9277-
// and check whether we have mapped all elements.
9278-
llvm::Value *PtrNext = MapperCGF.Builder.CreateConstGEP1_32(
9279-
ElemTy, PtrPHI, /*Idx0=*/1, "omp.arraymap.next");
9280-
PtrPHI->addIncoming(PtrNext, LastBB);
9281-
llvm::Value *IsDone =
9282-
MapperCGF.Builder.CreateICmpEQ(PtrNext, PtrEnd, "omp.arraymap.isdone");
9283-
llvm::BasicBlock *ExitBB = MapperCGF.createBasicBlock("omp.arraymap.exit");
9284-
MapperCGF.Builder.CreateCondBr(IsDone, ExitBB, BodyBB);
9285-
9286-
MapperCGF.EmitBlock(ExitBB);
9287-
// Emit array deletion if this is an array section and \p MapType indicates
9288-
// that deletion is required.
9289-
emitUDMapperArrayInitOrDel(MapperCGF, Handle, BaseIn, BeginIn, Size, MapType,
9290-
MapName, ElementSize, DoneBB, /*IsInit=*/false);
9291-
9292-
// Emit the function exit block.
9293-
MapperCGF.EmitBlock(DoneBB, /*IsFinished=*/true);
9294-
MapperCGF.FinishFunction();
9295-
UDMMap.try_emplace(D, Fn);
9088+
*MapperFunc = getOrCreateUserDefinedMapperFunc(
9089+
cast<OMPDeclareMapperDecl>(CombinedInfo.Mappers[I]));
9090+
assert(*MapperFunc && "Expect a valid mapper function is available.");
9091+
return true;
9092+
}
9093+
return false;
9094+
};
9095+
9096+
SmallString<64> TyStr;
9097+
llvm::raw_svector_ostream Out(TyStr);
9098+
CGM.getCXXABI().getMangleContext().mangleCanonicalTypeName(Ty, Out);
9099+
std::string Name = getName({"omp_mapper", TyStr, D->getName()});
9100+
9101+
auto *newFn = OMPBuilder.emitUserDefinedMapper(PrivatizeAndGenMapInfoCB,
9102+
ElemTy, Name, CustomMapperCB);
9103+
UDMMap.try_emplace(D, newFn);
92969104
if (CGF)
92979105
FunctionUDMMap[CGF->CurFn].push_back(D);
92989106
}

0 commit comments

Comments
 (0)