Skip to content

Commit 07d8827

Browse files
author
Sunil Kuravinakop
committed
Adding support for clauses novariants and nocontext occuring on the same
dispatch directive.
1 parent fd150c2 commit 07d8827

File tree

5 files changed

+219
-98
lines changed

5 files changed

+219
-98
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11899,9 +11899,6 @@ def err_omp_clause_requires_dispatch_construct : Error<
1189911899
"'%0' clause requires 'dispatch' context selector">;
1190011900
def err_omp_append_args_with_varargs : Error<
1190111901
"'append_args' is not allowed with varargs functions">;
11902-
def warn_omp_dispatch_clause_novariants_nocontext : Warning<
11903-
"'nocontext' clause is ignored, only 'novariants' clause is applied">,
11904-
InGroup<SourceUsesOpenMP>;
1190511902
def err_openmp_vla_in_task_untied : Error<
1190611903
"variable length arrays are not supported in OpenMP tasking regions with 'untied' clause">;
1190711904
def warn_omp_unterminated_declare_target : Warning<

clang/lib/CodeGen/CGStmtOpenMP.cpp

Lines changed: 126 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4529,59 +4529,144 @@ void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
45294529
emitMaster(*this, S);
45304530
}
45314531

4532-
static Expr *replaceWithNewTraitsOrDirectCall(Stmt *AssocExpr,
4533-
CallExpr *ReplacementFunction) {
4534-
Expr *FinalCall = ReplacementFunction;
4535-
4536-
if (BinaryOperator *BinaryCopyOpr = dyn_cast<BinaryOperator>(AssocExpr)) {
4537-
BinaryCopyOpr->setRHS(FinalCall);
4538-
return BinaryCopyOpr;
4532+
static Expr *replaceWithNewTraitsOrDirectCall(CapturedDecl *CDecl,
4533+
Expr *NewExpr) {
4534+
Expr *CurrentCallExpr = nullptr;
4535+
Stmt *CallExprStmt = CDecl->getBody();
4536+
4537+
if (BinaryOperator *BinaryCopyOpr = dyn_cast<BinaryOperator>(CallExprStmt)) {
4538+
CurrentCallExpr = BinaryCopyOpr->getRHS();
4539+
BinaryCopyOpr->setRHS(NewExpr);
4540+
} else {
4541+
CurrentCallExpr = dyn_cast<Expr>(CallExprStmt);
4542+
CDecl->setBody(NewExpr);
45394543
}
45404544

4541-
return FinalCall;
4545+
return CurrentCallExpr;
45424546
}
45434547

4544-
static void transformCallInStmt(Stmt *StmtP) {
4545-
if (auto *AssocStmt = dyn_cast<CapturedStmt>(StmtP)) {
4546-
CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
4548+
static Expr *transformCallInStmt(Stmt *StmtP, bool NoContext = false) {
4549+
Expr *CurrentExpr = nullptr;
4550+
if (auto *CptStmt = dyn_cast<CapturedStmt>(StmtP)) {
4551+
CapturedDecl *CDecl = CptStmt->getCapturedDecl();
45474552

4548-
// Access AnnotateAttr
45494553
CallExpr *NewCallExpr = nullptr;
45504554
for (const auto *attr : CDecl->attrs()) {
4551-
if (const auto *annotateAttr = llvm::dyn_cast<clang::AnnotateAttr>(attr);
4552-
annotateAttr &&
4553-
annotateAttr->getAnnotation() == "NoContextInvariant") {
4554-
NewCallExpr = llvm::dyn_cast<CallExpr>(*annotateAttr->args_begin());
4555+
if (NoContext) {
4556+
if (const auto *annotateAttr =
4557+
llvm::dyn_cast<clang::AnnotateAttr>(attr);
4558+
annotateAttr && annotateAttr->getAnnotation() == "NoContextAttr") {
4559+
NewCallExpr = llvm::dyn_cast<CallExpr>(*annotateAttr->args_begin());
4560+
}
4561+
} else {
4562+
if (const auto *annotateAttr =
4563+
llvm::dyn_cast<clang::AnnotateAttr>(attr);
4564+
annotateAttr && annotateAttr->getAnnotation() == "NoVariantsAttr") {
4565+
NewCallExpr = llvm::dyn_cast<CallExpr>(*annotateAttr->args_begin());
4566+
}
45554567
}
45564568
}
45574569

4558-
Stmt *CallExprStmt = CDecl->getBody();
4559-
Stmt *NewCallExprStmt =
4560-
replaceWithNewTraitsOrDirectCall(CallExprStmt, NewCallExpr);
4561-
CDecl->setBody(NewCallExprStmt);
4570+
CurrentExpr = replaceWithNewTraitsOrDirectCall(CDecl, NewCallExpr);
45624571
}
4572+
return CurrentExpr;
45634573
}
45644574

4565-
static void emitIfElse(CodeGenFunction *CGF, Expr *Condition,
4566-
Stmt *AssociatedStmt) {
4575+
// emitIfElse is used for the following conditions:
4576+
//
4577+
// NoVariants = 0 && NoContext = 1
4578+
// if (Condition_NoContext) {
4579+
// foo_variant2(); // Present in AnnotationAttr
4580+
// } else {
4581+
// foo_variant();
4582+
// }
4583+
//
4584+
// NoVariants = 1 && NoContext = 0
4585+
// if (Condition_NoVariants) {
4586+
// foo();
4587+
// } else {
4588+
// foo_variant();
4589+
// }
4590+
//
4591+
// NoVariants = 1 && NoContext = 1
4592+
// if (Condition_NoVariants) { // ==> label if.then.NoVariants
4593+
// foo();
4594+
// } else { // ==> label else.NoVariants
4595+
// if (Condition_NoContext) { // ==> label if.then.NoContext
4596+
// foo_variant2(); // Present in AnnotationAttr
4597+
// } else { // ==> label else
4598+
// foo_variant();
4599+
// }
4600+
// }
4601+
//
4602+
static void emitIfElse(CodeGenFunction *CGF, Stmt *AssociatedStmt,
4603+
Expr *Condition_NoVariants, Expr *Condition_NoContext) {
45674604
llvm::BasicBlock *ThenBlock = CGF->createBasicBlock("if.then");
45684605
llvm::BasicBlock *ElseBlock = CGF->createBasicBlock("if.else");
45694606
llvm::BasicBlock *MergeBlock = CGF->createBasicBlock("if.end");
4607+
llvm::BasicBlock *ThenNoVariantsBlock = nullptr;
4608+
llvm::BasicBlock *ElseNoVariantsBlock = nullptr;
4609+
llvm::BasicBlock *ThenNoContextBlock = nullptr;
4610+
Expr *ElseCall = nullptr;
45704611

4571-
CGF->EmitBranchOnBoolExpr(Condition, ThenBlock, ElseBlock, 0);
4612+
if (Condition_NoVariants && Condition_NoContext) {
4613+
ThenNoVariantsBlock = CGF->createBasicBlock("if.then.NoVariants");
4614+
ElseNoVariantsBlock = CGF->createBasicBlock("else.NoVariants");
4615+
ThenNoContextBlock = CGF->createBasicBlock("if.then.NoContext");
4616+
4617+
CGF->EmitBranchOnBoolExpr(Condition_NoVariants, ThenNoVariantsBlock,
4618+
ElseNoVariantsBlock, 0);
4619+
4620+
} else if (Condition_NoVariants)
4621+
CGF->EmitBranchOnBoolExpr(Condition_NoVariants, ThenBlock, ElseBlock, 0);
4622+
else
4623+
CGF->EmitBranchOnBoolExpr(Condition_NoContext, ThenBlock, ElseBlock, 0);
4624+
4625+
if (Condition_NoVariants && Condition_NoContext) {
4626+
// Emit the NoVariants (if then, for the NoVariants) block.
4627+
CGF->EmitBlock(ThenNoVariantsBlock);
4628+
Stmt *ThenStmt = AssociatedStmt;
4629+
ElseCall = transformCallInStmt(ThenStmt, false);
4630+
CGF->EmitStmt(ThenStmt);
4631+
CGF->Builder.CreateBr(MergeBlock);
4632+
4633+
CGF->EmitBlock(ElseNoVariantsBlock);
4634+
CGF->EmitBranchOnBoolExpr(Condition_NoVariants, ThenNoContextBlock,
4635+
ElseBlock, 0);
4636+
// Emit the NoContext (else if, for the NoContext) block.
4637+
CGF->EmitBlock(ThenNoContextBlock);
4638+
Stmt *ThenNoContextStmt = AssociatedStmt;
4639+
transformCallInStmt(ThenNoContextStmt, true);
4640+
CGF->EmitStmt(ThenNoContextStmt);
4641+
CGF->Builder.CreateBr(MergeBlock);
4642+
4643+
} else if (Condition_NoVariants) {
4644+
// Emit the NoVariants (then) block.
4645+
CGF->EmitBlock(ThenBlock);
4646+
Stmt *ThenStmt = AssociatedStmt;
4647+
ElseCall = transformCallInStmt(ThenStmt, false);
4648+
CGF->EmitStmt(ThenStmt);
4649+
CGF->Builder.CreateBr(MergeBlock);
4650+
4651+
} else if (Condition_NoContext) {
4652+
// Emit the NoContext (then) block.
4653+
CGF->EmitBlock(ThenBlock);
4654+
Stmt *ThenStmt = AssociatedStmt;
4655+
ElseCall = transformCallInStmt(ThenStmt, true);
4656+
CGF->EmitStmt(ThenStmt);
4657+
CGF->Builder.CreateBr(MergeBlock);
4658+
}
45724659

45734660
// Emit the else block.
4574-
Stmt *ElseStmt = AssociatedStmt;
45754661
CGF->EmitBlock(ElseBlock);
4662+
Stmt *ElseStmt = AssociatedStmt;
4663+
if (auto *CaptStmt = dyn_cast<CapturedStmt>(ElseStmt)) {
4664+
CapturedDecl *CDecl = CaptStmt->getCapturedDecl();
4665+
replaceWithNewTraitsOrDirectCall(CDecl, ElseCall);
4666+
}
45764667
CGF->EmitStmt(ElseStmt);
45774668
CGF->Builder.CreateBr(MergeBlock);
45784669

4579-
// Emit the then block.
4580-
Stmt *ThenStmt = AssociatedStmt;
4581-
transformCallInStmt(ThenStmt);
4582-
CGF->EmitBlock(ThenBlock);
4583-
CGF->EmitStmt(ThenStmt);
4584-
CGF->Builder.CreateBr(MergeBlock);
45854670
CGF->EmitBlock(MergeBlock);
45864671
}
45874672

@@ -4598,25 +4683,32 @@ void CodeGenFunction::EmitOMPDispatchDirective(const OMPDispatchDirective &S) {
45984683
if (!CapturedStmtInfo)
45994684
CapturedStmtInfo = &CapStmtInfo;
46004685

4686+
Expr *NoVariantsCondition = nullptr;
4687+
Expr *NoContextCondition = nullptr;
46014688
if (!Clauses.empty()) {
46024689
if (S.hasClausesOfKind<OMPDependClause>())
46034690
EmitOMPDispatchToTaskwaitDirective(S);
46044691

46054692
if (S.hasClausesOfKind<OMPNovariantsClause>() ||
46064693
S.hasClausesOfKind<OMPNocontextClause>()) {
4607-
Expr *Condition = nullptr;
46084694
if (const OMPNovariantsClause *NoVariantsC =
46094695
OMPExecutableDirective::getSingleClause<OMPNovariantsClause>(
46104696
Clauses)) {
4611-
Condition = NoVariantsC->getCondition();
4697+
NoVariantsCondition = NoVariantsC->getCondition();
4698+
if (const OMPNocontextClause *NoContextC =
4699+
OMPExecutableDirective::getSingleClause<OMPNocontextClause>(
4700+
Clauses)) {
4701+
NoContextCondition = NoContextC->getCondition();
4702+
}
46124703
} else {
46134704
const OMPNocontextClause *NoContextC =
46144705
OMPExecutableDirective::getSingleClause<OMPNocontextClause>(
46154706
Clauses);
4616-
Condition = NoContextC->getCondition();
4707+
NoContextCondition = NoContextC->getCondition();
46174708
}
4709+
46184710
OMPLexicalScope Scope(*this, S, OMPD_dispatch);
4619-
emitIfElse(this, Condition, AssociatedStmt);
4711+
emitIfElse(this, AssociatedStmt, NoVariantsCondition, NoContextCondition);
46204712
}
46214713
} else
46224714
EmitStmt(AssociatedStmt);

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6030,6 +6030,28 @@ static Expr *getNewTraitsOrDirectCall(const ASTContext &Context,
60306030
return FinalCall;
60316031
}
60326032

6033+
// Add Attribute NoContextAttr or NoVariantsAttr
6034+
// to the CapturedDecl.
6035+
static void addAttr(const ASTContext &Context, Expr *AssocExpr,
6036+
SemaOpenMP *SemaPtr, bool NoContext, CapturedDecl *CDecl) {
6037+
llvm::SmallVector<Expr *, 4> Args;
6038+
Expr *NewCallExpr = nullptr;
6039+
6040+
if (NoContext) {
6041+
NewCallExpr = getNewTraitsOrDirectCall(Context, AssocExpr, SemaPtr, true);
6042+
Args.push_back(NewCallExpr);
6043+
CDecl->addAttr(AnnotateAttr::CreateImplicit(
6044+
const_cast<ASTContext &>(Context), "NoContextAttr", Args.data(),
6045+
Args.size()));
6046+
} else {
6047+
NewCallExpr = getNewTraitsOrDirectCall(Context, AssocExpr, SemaPtr, false);
6048+
Args.push_back(NewCallExpr);
6049+
CDecl->addAttr(AnnotateAttr::CreateImplicit(
6050+
const_cast<ASTContext &>(Context), "NoVariantsAttr", Args.data(),
6051+
Args.size()));
6052+
}
6053+
}
6054+
60336055
/// annotateAStmt() function is used by ActOnOpenMPExecutableDirective()
60346056
/// for the dispatch directive (nocontext or invariant clauses).
60356057
/// An annotation "NoContextInvariant" is added to the Captured Decl
@@ -6049,24 +6071,20 @@ void SemaOpenMP::annotateAStmt(const ASTContext &Context, Stmt *StmtP,
60496071
Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
60506072
CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
60516073
auto *AssocExpr = dyn_cast<Expr>(AssocExprStmt);
6052-
bool NoContext = false;
60536074

60546075
if (OMPExecutableDirective::getSingleClause<OMPNovariantsClause>(Clauses)) {
6055-
6056-
if (OMPExecutableDirective::getSingleClause<OMPNocontextClause>(Clauses))
6057-
Diag(StartLoc, diag::warn_omp_dispatch_clause_novariants_nocontext);
6076+
addAttr(const_cast<ASTContext &>(Context), AssocExpr, SemaPtr, false,
6077+
CDecl);
6078+
if (OMPExecutableDirective::getSingleClause<OMPNocontextClause>(
6079+
Clauses)) {
6080+
addAttr(const_cast<ASTContext &>(Context), AssocExpr, SemaPtr, true,
6081+
CDecl);
6082+
}
60586083
} else if (OMPExecutableDirective::getSingleClause<OMPNocontextClause>(
6059-
Clauses))
6060-
NoContext = true;
6061-
6062-
Expr *NewCallExpr =
6063-
getNewTraitsOrDirectCall(Context, AssocExpr, SemaPtr, NoContext);
6064-
// Annotate "NoContextInvariant" to CDecl of the AssocStmt
6065-
llvm::SmallVector<Expr *, 4> Args;
6066-
Args.push_back(NewCallExpr);
6067-
CDecl->addAttr(AnnotateAttr::CreateImplicit(
6068-
const_cast<ASTContext &>(Context), "NoContextInvariant", Args.data(),
6069-
Args.size()));
6084+
Clauses)) {
6085+
addAttr(const_cast<ASTContext &>(Context), AssocExpr, SemaPtr, true,
6086+
CDecl);
6087+
}
60706088
}
60716089
}
60726090

0 commit comments

Comments
 (0)