forked from OSchip/llvm-project
[OPENMP50]Add codegen for update clause in depobj directive.
Added codegen for update clause in depobj. Reads the number of the elements from the first element and updates flags for each element in the loop. ``` omp_depend_t x; kmp_depend_info *base = (kmp_depend_info *)x; intptr_t num = x[-1].base_addr; kmp_depend_info *end = x + num; kmp_depend_info *el = base; do { el.flags = new_flag; el = &el[1]; } while (el != end); ```
This commit is contained in:
parent
ea5b3ef593
commit
8d7b118875
|
@ -5360,6 +5360,67 @@ void CGOpenMPRuntime::emitDestroyClause(CodeGenFunction &CGF, LValue DepobjLVal,
|
|||
(void)CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_free), Args);
|
||||
}
|
||||
|
||||
void CGOpenMPRuntime::emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal,
|
||||
OpenMPDependClauseKind NewDepKind,
|
||||
SourceLocation Loc) {
|
||||
ASTContext &C = CGM.getContext();
|
||||
QualType FlagsTy;
|
||||
getDependTypes(C, KmpDependInfoTy, FlagsTy);
|
||||
RecordDecl *KmpDependInfoRD =
|
||||
cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
|
||||
llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy);
|
||||
LValue Base = CGF.EmitLoadOfPointerLValue(
|
||||
DepobjLVal.getAddress(CGF),
|
||||
C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
|
||||
QualType KmpDependInfoPtrTy = C.getPointerType(KmpDependInfoTy);
|
||||
Address Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
|
||||
Base.getAddress(CGF), CGF.ConvertTypeForMem(KmpDependInfoPtrTy));
|
||||
Base = CGF.MakeAddrLValue(Addr, KmpDependInfoTy, Base.getBaseInfo(),
|
||||
Base.getTBAAInfo());
|
||||
llvm::Value *DepObjAddr = CGF.Builder.CreateGEP(
|
||||
Addr.getPointer(),
|
||||
llvm::ConstantInt::get(CGF.IntPtrTy, -1, /*isSigned=*/true));
|
||||
LValue NumDepsBase = CGF.MakeAddrLValue(
|
||||
Address(DepObjAddr, Addr.getAlignment()), KmpDependInfoTy,
|
||||
Base.getBaseInfo(), Base.getTBAAInfo());
|
||||
// NumDeps = deps[i].base_addr;
|
||||
LValue BaseAddrLVal = CGF.EmitLValueForField(
|
||||
NumDepsBase, *std::next(KmpDependInfoRD->field_begin(), BaseAddr));
|
||||
llvm::Value *NumDeps = CGF.EmitLoadOfScalar(BaseAddrLVal, Loc);
|
||||
|
||||
Address Begin = Base.getAddress(CGF);
|
||||
// Cast from pointer to array type to pointer to single element.
|
||||
llvm::Value *End = CGF.Builder.CreateGEP(Begin.getPointer(), NumDeps);
|
||||
// The basic structure here is a while-do loop.
|
||||
llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.body");
|
||||
llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.done");
|
||||
llvm::BasicBlock *EntryBB = CGF.Builder.GetInsertBlock();
|
||||
CGF.EmitBlock(BodyBB);
|
||||
llvm::PHINode *ElementPHI =
|
||||
CGF.Builder.CreatePHI(Begin.getType(), 2, "omp.elementPast");
|
||||
ElementPHI->addIncoming(Begin.getPointer(), EntryBB);
|
||||
Begin = Address(ElementPHI, Begin.getAlignment());
|
||||
Base = CGF.MakeAddrLValue(Begin, KmpDependInfoTy, Base.getBaseInfo(),
|
||||
Base.getTBAAInfo());
|
||||
// deps[i].flags = NewDepKind;
|
||||
RTLDependenceKindTy DepKind = translateDependencyKind(NewDepKind);
|
||||
LValue FlagsLVal = CGF.EmitLValueForField(
|
||||
Base, *std::next(KmpDependInfoRD->field_begin(), Flags));
|
||||
CGF.EmitStoreOfScalar(llvm::ConstantInt::get(LLVMFlagsTy, DepKind),
|
||||
FlagsLVal);
|
||||
|
||||
// Shift the address forward by one element.
|
||||
Address ElementNext =
|
||||
CGF.Builder.CreateConstGEP(Begin, /*Index=*/1, "omp.elementNext");
|
||||
ElementPHI->addIncoming(ElementNext.getPointer(),
|
||||
CGF.Builder.GetInsertBlock());
|
||||
llvm::Value *IsEmpty =
|
||||
CGF.Builder.CreateICmpEQ(ElementNext.getPointer(), End, "omp.isempty");
|
||||
CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
|
||||
// Done.
|
||||
CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
|
||||
}
|
||||
|
||||
void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
|
||||
const OMPExecutableDirective &D,
|
||||
llvm::Function *TaskFunction,
|
||||
|
|
|
@ -1791,6 +1791,12 @@ public:
|
|||
/// directive.
|
||||
void emitDestroyClause(CodeGenFunction &CGF, LValue DepobjLVal,
|
||||
SourceLocation Loc);
|
||||
|
||||
/// Updates the dependency kind in the specified depobj object.
|
||||
/// \param DepobjLVal LValue for the main depobj object.
|
||||
/// \param NewDepKind New dependency kind.
|
||||
void emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal,
|
||||
OpenMPDependClauseKind NewDepKind, SourceLocation Loc);
|
||||
};
|
||||
|
||||
/// Class supports emissionof SIMD-only code.
|
||||
|
|
|
@ -3817,6 +3817,11 @@ void CodeGenFunction::EmitOMPDepobjDirective(const OMPDepobjDirective &S) {
|
|||
CGM.getOpenMPRuntime().emitDestroyClause(*this, DOLVal, DC->getBeginLoc());
|
||||
return;
|
||||
}
|
||||
if (const auto *UC = S.getSingleClause<OMPUpdateClause>()) {
|
||||
CGM.getOpenMPRuntime().emitUpdateClause(
|
||||
*this, DOLVal, UC->getDependencyKind(), UC->getBeginLoc());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
|
||||
|
|
|
@ -67,6 +67,21 @@ int main(int argc, char **argv) {
|
|||
// CHECK: [[B_REF:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[B_BASE]], i{{.+}} -1
|
||||
// CHECK: [[B:%.+]] = bitcast %struct.kmp_depend_info* [[B_REF]] to i8*
|
||||
// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[B]], i8* null)
|
||||
// CHECK: [[B:%.+]] = load i8*, i8** [[B_ADDR]],
|
||||
// CHECK: [[B_BASE:%.+]] = bitcast i8* [[B]] to %struct.kmp_depend_info*
|
||||
// CHECK: [[NUMDEPS_BASE:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[B_BASE]], i64 -1
|
||||
// CHECK: [[NUMDEPS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[NUMDEPS_BASE]], i{{.+}} 0, i{{.+}} 0
|
||||
// CHECK: [[NUMDEPS:%.+]] = load i64, i64* [[NUMDEPS_ADDR]],
|
||||
// CHECK: [[END:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[B_BASE]], i64 [[NUMDEPS]]
|
||||
// CHECK: br label %[[BODY:.+]]
|
||||
// CHECK: [[BODY]]:
|
||||
// CHECK: [[EL:%.+]] = phi %struct.kmp_depend_info* [ [[B_BASE]], %{{.+}} ], [ [[EL_NEXT:%.+]], %[[BODY]] ]
|
||||
// CHECK: [[FLAG_BASE:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[EL]], i{{.+}} 0, i{{.+}} 2
|
||||
// CHECK: store i8 4, i8* [[FLAG_BASE]],
|
||||
// CHECK: [[EL_NEXT]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[EL]], i{{.+}} 1
|
||||
// CHECK: [[IS_DONE:%.+]] = icmp eq %struct.kmp_depend_info* [[EL_NEXT]], [[END]]
|
||||
// CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[BODY]]
|
||||
// CHECK: [[DONE]]:
|
||||
|
||||
// CHECK-LABEL: tmain
|
||||
// CHECK: [[ARGC_ADDR:%.+]] = alloca i8*,
|
||||
|
@ -91,5 +106,20 @@ int main(int argc, char **argv) {
|
|||
// CHECK: [[ARGC_REF:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[ARGC_BASE]], i{{.+}} -1
|
||||
// CHECK: [[ARGC:%.+]] = bitcast %struct.kmp_depend_info* [[ARGC_REF]] to i8*
|
||||
// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[ARGC]], i8* null)
|
||||
// CHECK: [[ARGC:%.+]] = load i8*, i8** [[ARGC_ADDR]],
|
||||
// CHECK: [[ARGC_BASE:%.+]] = bitcast i8* [[ARGC]] to %struct.kmp_depend_info*
|
||||
// CHECK: [[NUMDEPS_BASE:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[ARGC_BASE]], i64 -1
|
||||
// CHECK: [[NUMDEPS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[NUMDEPS_BASE]], i{{.+}} 0, i{{.+}} 0
|
||||
// CHECK: [[NUMDEPS:%.+]] = load i64, i64* [[NUMDEPS_ADDR]],
|
||||
// CHECK: [[END:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[ARGC_BASE]], i64 [[NUMDEPS]]
|
||||
// CHECK: br label %[[BODY:.+]]
|
||||
// CHECK: [[BODY]]:
|
||||
// CHECK: [[EL:%.+]] = phi %struct.kmp_depend_info* [ [[ARGC_BASE]], %{{.+}} ], [ [[EL_NEXT:%.+]], %[[BODY]] ]
|
||||
// CHECK: [[FLAG_BASE:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[EL]], i{{.+}} 0, i{{.+}} 2
|
||||
// CHECK: store i8 3, i8* [[FLAG_BASE]],
|
||||
// CHECK: [[EL_NEXT]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[EL]], i{{.+}} 1
|
||||
// CHECK: [[IS_DONE:%.+]] = icmp eq %struct.kmp_depend_info* [[EL_NEXT]], [[END]]
|
||||
// CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[BODY]]
|
||||
// CHECK: [[DONE]]:
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue