forked from OSchip/llvm-project
[OPENMP] Code cleanup for capturing of variables in OpenMP regions.
llvm-svn: 236821
This commit is contained in:
parent
307b917696
commit
39f915b8f4
|
@ -7462,6 +7462,10 @@ public:
|
|||
void StartOpenMPDSABlock(OpenMPDirectiveKind K,
|
||||
const DeclarationNameInfo &DirName, Scope *CurScope,
|
||||
SourceLocation Loc);
|
||||
/// \brief Start analysis of clauses.
|
||||
void StartOpenMPClauses();
|
||||
/// \brief End analysis of clauses.
|
||||
void EndOpenMPClauses();
|
||||
/// \brief Called on end of data sharing attribute block.
|
||||
void EndOpenMPDSABlock(Stmt *CurDirective);
|
||||
|
||||
|
|
|
@ -533,7 +533,16 @@ void CodeGenFunction::EmitOMPInnerLoop(
|
|||
void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
|
||||
auto IC = S.counters().begin();
|
||||
for (auto F : S.finals()) {
|
||||
if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) {
|
||||
auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
|
||||
if (LocalDeclMap.lookup(OrigVD)) {
|
||||
DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
|
||||
CapturedStmtInfo->lookup(OrigVD) != nullptr,
|
||||
(*IC)->getType(), VK_LValue, (*IC)->getExprLoc());
|
||||
auto *OrigAddr = EmitLValue(&DRE).getAddress();
|
||||
OMPPrivateScope VarScope(*this);
|
||||
VarScope.addPrivate(OrigVD,
|
||||
[OrigAddr]() -> llvm::Value *{ return OrigAddr; });
|
||||
(void)VarScope.Privatize();
|
||||
EmitIgnoredExpr(F);
|
||||
}
|
||||
++IC;
|
||||
|
@ -541,8 +550,19 @@ void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
|
|||
// Emit the final values of the linear variables.
|
||||
for (auto &&I = S.getClausesOfKind(OMPC_linear); I; ++I) {
|
||||
auto *C = cast<OMPLinearClause>(*I);
|
||||
auto IC = C->varlist_begin();
|
||||
for (auto F : C->finals()) {
|
||||
auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
|
||||
DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
|
||||
CapturedStmtInfo->lookup(OrigVD) != nullptr,
|
||||
(*IC)->getType(), VK_LValue, (*IC)->getExprLoc());
|
||||
auto *OrigAddr = EmitLValue(&DRE).getAddress();
|
||||
OMPPrivateScope VarScope(*this);
|
||||
VarScope.addPrivate(OrigVD,
|
||||
[OrigAddr]() -> llvm::Value *{ return OrigAddr; });
|
||||
(void)VarScope.Privatize();
|
||||
EmitIgnoredExpr(F);
|
||||
++IC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,6 +223,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
|
|||
ParseScope OMPDirectiveScope(this, ScopeFlags);
|
||||
Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
|
||||
|
||||
Actions.StartOpenMPClauses();
|
||||
while (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
||||
OpenMPClauseKind CKind =
|
||||
Tok.isAnnotation()
|
||||
|
@ -242,6 +243,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
|
|||
if (Tok.is(tok::comma))
|
||||
ConsumeToken();
|
||||
}
|
||||
Actions.EndOpenMPClauses();
|
||||
// End location of the directive.
|
||||
EndLoc = Tok.getLocation();
|
||||
// Consume final annot_pragma_openmp_end.
|
||||
|
|
|
@ -114,6 +114,9 @@ private:
|
|||
|
||||
/// \brief Stack of used declaration and their data-sharing attributes.
|
||||
StackTy Stack;
|
||||
/// \brief true, if check for DSA must be from parent directive, false, if
|
||||
/// from current directive.
|
||||
bool FromParent;
|
||||
Sema &SemaRef;
|
||||
|
||||
typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
|
||||
|
@ -124,7 +127,10 @@ private:
|
|||
bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
|
||||
|
||||
public:
|
||||
explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {}
|
||||
explicit DSAStackTy(Sema &S) : Stack(1), FromParent(false), SemaRef(S) {}
|
||||
|
||||
bool isFromParent() const { return FromParent; }
|
||||
void setFromParent(bool Flag) { FromParent = Flag; }
|
||||
|
||||
void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
|
||||
Scope *CurScope, SourceLocation Loc) {
|
||||
|
@ -418,6 +424,28 @@ bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// \brief Build a variable declaration for OpenMP loop iteration variable.
|
||||
static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
|
||||
StringRef Name) {
|
||||
DeclContext *DC = SemaRef.CurContext;
|
||||
IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
|
||||
TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
|
||||
VarDecl *Decl =
|
||||
VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
|
||||
Decl->setImplicit();
|
||||
return Decl;
|
||||
}
|
||||
|
||||
static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
|
||||
SourceLocation Loc,
|
||||
bool RefersToCapture = false) {
|
||||
D->setReferenced();
|
||||
D->markUsed(S.Context);
|
||||
return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
|
||||
SourceLocation(), D, RefersToCapture, Loc, Ty,
|
||||
VK_LValue);
|
||||
}
|
||||
|
||||
DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {
|
||||
D = D->getCanonicalDecl();
|
||||
DSAVarData DVar;
|
||||
|
@ -428,12 +456,8 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {
|
|||
if (D->getTLSKind() != VarDecl::TLS_None ||
|
||||
(D->getStorageClass() == SC_Register && D->hasAttr<AsmLabelAttr>() &&
|
||||
!D->isLocalVarDecl())) {
|
||||
addDSA(D,
|
||||
DeclRefExpr::Create(SemaRef.getASTContext(),
|
||||
NestedNameSpecifierLoc(), SourceLocation(), D,
|
||||
/*RefersToEnclosingVariableOrCapture=*/false,
|
||||
D->getLocation(),
|
||||
D->getType().getNonReferenceType(), VK_LValue),
|
||||
addDSA(D, buildDeclRefExpr(SemaRef, D, D->getType().getNonReferenceType(),
|
||||
D->getLocation()),
|
||||
OMPC_threadprivate);
|
||||
}
|
||||
if (Stack[0].SharingMap.count(D)) {
|
||||
|
@ -592,13 +616,15 @@ bool Sema::IsOpenMPCapturedVar(VarDecl *VD) {
|
|||
assert(LangOpts.OpenMP && "OpenMP is not allowed");
|
||||
VD = VD->getCanonicalDecl();
|
||||
if (DSAStack->getCurrentDirective() != OMPD_unknown) {
|
||||
if (DSAStack->isLoopControlVariable(VD))
|
||||
if (DSAStack->isLoopControlVariable(VD) ||
|
||||
(VD->hasLocalStorage() &&
|
||||
isParallelOrTaskRegion(DSAStack->getCurrentDirective())))
|
||||
return true;
|
||||
auto DVarPrivate = DSAStack->getTopDSA(VD, /*FromParent=*/false);
|
||||
auto DVarPrivate = DSAStack->getTopDSA(VD, DSAStack->isFromParent());
|
||||
if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
|
||||
return true;
|
||||
DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(),
|
||||
/*FromParent=*/false);
|
||||
DSAStack->isFromParent());
|
||||
return DVarPrivate.CKind != OMPC_unknown;
|
||||
}
|
||||
return false;
|
||||
|
@ -613,6 +639,14 @@ void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
|
|||
PushExpressionEvaluationContext(PotentiallyEvaluated);
|
||||
}
|
||||
|
||||
void Sema::StartOpenMPClauses() {
|
||||
DSAStack->setFromParent(/*Flag=*/true);
|
||||
}
|
||||
|
||||
void Sema::EndOpenMPClauses() {
|
||||
DSAStack->setFromParent(/*Flag=*/false);
|
||||
}
|
||||
|
||||
void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
|
||||
// OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
|
||||
// A variable of class type (or array thereof) that appears in a lastprivate
|
||||
|
@ -636,18 +670,14 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
|
|||
// by the address of the new private variable in CodeGen. This new
|
||||
// variable is not added to IdResolver, so the code in the OpenMP
|
||||
// region uses original variable for proper diagnostics.
|
||||
auto *VDPrivate = VarDecl::Create(
|
||||
Context, CurContext, DE->getLocStart(), DE->getExprLoc(),
|
||||
VD->getIdentifier(), VD->getType(), VD->getTypeSourceInfo(),
|
||||
SC_Auto);
|
||||
auto *VDPrivate =
|
||||
buildVarDecl(*this, DE->getExprLoc(),
|
||||
VD->getType().getUnqualifiedType(), VD->getName());
|
||||
ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
|
||||
if (VDPrivate->isInvalidDecl())
|
||||
continue;
|
||||
CurContext->addDecl(VDPrivate);
|
||||
PrivateCopies.push_back(DeclRefExpr::Create(
|
||||
Context, NestedNameSpecifierLoc(), SourceLocation(), VDPrivate,
|
||||
/*RefersToEnclosingVariableOrCapture=*/false, SourceLocation(),
|
||||
DE->getType(), VK_LValue));
|
||||
PrivateCopies.push_back(buildDeclRefExpr(
|
||||
*this, VDPrivate, DE->getType(), DE->getExprLoc()));
|
||||
} else {
|
||||
// The variable is also a firstprivate, so initialization sequence
|
||||
// for private copy is generated already.
|
||||
|
@ -811,7 +841,7 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
|
|||
}
|
||||
|
||||
QualType ExprType = VD->getType().getNonReferenceType();
|
||||
ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_LValue, Id.getLoc());
|
||||
ExprResult DE = buildDeclRefExpr(*this, VD, ExprType, Id.getLoc());
|
||||
return DE;
|
||||
}
|
||||
|
||||
|
@ -2440,10 +2470,7 @@ Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const {
|
|||
|
||||
/// \brief Build reference expression to the counter be used for codegen.
|
||||
Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const {
|
||||
return DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(),
|
||||
GetIncrementSrcRange().getBegin(), Var,
|
||||
/*RefersToEnclosingVariableOrCapture=*/true,
|
||||
DefaultLoc, Var->getType(), VK_LValue);
|
||||
return buildDeclRefExpr(SemaRef, Var, Var->getType(), DefaultLoc);
|
||||
}
|
||||
|
||||
/// \brief Build initization of the counter be used for codegen.
|
||||
|
@ -2624,18 +2651,6 @@ static bool CheckOpenMPIterationSpace(
|
|||
return HasErrors;
|
||||
}
|
||||
|
||||
/// \brief Build a variable declaration for OpenMP loop iteration variable.
|
||||
static VarDecl *BuildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
|
||||
StringRef Name) {
|
||||
DeclContext *DC = SemaRef.CurContext;
|
||||
IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
|
||||
TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
|
||||
VarDecl *Decl =
|
||||
VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
|
||||
Decl->setImplicit();
|
||||
return Decl;
|
||||
}
|
||||
|
||||
/// \brief Build 'VarRef = Start + Iter * Step'.
|
||||
static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S,
|
||||
SourceLocation Loc, ExprResult VarRef,
|
||||
|
@ -2823,10 +2838,10 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
|
|||
if (!IsConstant) {
|
||||
SourceLocation SaveLoc;
|
||||
VarDecl *SaveVar =
|
||||
BuildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(),
|
||||
buildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(),
|
||||
".omp.last.iteration");
|
||||
ExprResult SaveRef = SemaRef.BuildDeclRefExpr(
|
||||
SaveVar, LastIteration.get()->getType(), VK_LValue, SaveLoc);
|
||||
ExprResult SaveRef = buildDeclRefExpr(
|
||||
SemaRef, SaveVar, LastIteration.get()->getType(), SaveLoc);
|
||||
CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign,
|
||||
SaveRef.get(), LastIteration.get());
|
||||
LastIteration = SaveRef;
|
||||
|
@ -2846,15 +2861,15 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
|
|||
ExprResult LB, UB, IL, ST, EUB;
|
||||
if (isOpenMPWorksharingDirective(DKind)) {
|
||||
// Lower bound variable, initialized with zero.
|
||||
VarDecl *LBDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
|
||||
LB = SemaRef.BuildDeclRefExpr(LBDecl, VType, VK_LValue, InitLoc);
|
||||
VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
|
||||
LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
|
||||
SemaRef.AddInitializerToDecl(
|
||||
LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
|
||||
/*DirectInit*/ false, /*TypeMayContainAuto*/ false);
|
||||
|
||||
// Upper bound variable, initialized with last iteration number.
|
||||
VarDecl *UBDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
|
||||
UB = SemaRef.BuildDeclRefExpr(UBDecl, VType, VK_LValue, InitLoc);
|
||||
VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
|
||||
UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
|
||||
SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
|
||||
/*DirectInit*/ false,
|
||||
/*TypeMayContainAuto*/ false);
|
||||
|
@ -2862,15 +2877,15 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
|
|||
// A 32-bit variable-flag where runtime returns 1 for the last iteration.
|
||||
// This will be used to implement clause 'lastprivate'.
|
||||
QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
|
||||
VarDecl *ILDecl = BuildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
|
||||
IL = SemaRef.BuildDeclRefExpr(ILDecl, Int32Ty, VK_LValue, InitLoc);
|
||||
VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
|
||||
IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
|
||||
SemaRef.AddInitializerToDecl(
|
||||
ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
|
||||
/*DirectInit*/ false, /*TypeMayContainAuto*/ false);
|
||||
|
||||
// Stride variable returned by runtime (we initialize it to 1 by default).
|
||||
VarDecl *STDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.stride");
|
||||
ST = SemaRef.BuildDeclRefExpr(STDecl, VType, VK_LValue, InitLoc);
|
||||
VarDecl *STDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.stride");
|
||||
ST = buildDeclRefExpr(SemaRef, STDecl, VType, InitLoc);
|
||||
SemaRef.AddInitializerToDecl(
|
||||
STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
|
||||
/*DirectInit*/ false, /*TypeMayContainAuto*/ false);
|
||||
|
@ -2890,8 +2905,8 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
|
|||
ExprResult IV;
|
||||
ExprResult Init;
|
||||
{
|
||||
VarDecl *IVDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.iv");
|
||||
IV = SemaRef.BuildDeclRefExpr(IVDecl, VType, VK_LValue, InitLoc);
|
||||
VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv");
|
||||
IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc);
|
||||
Expr *RHS = isOpenMPWorksharingDirective(DKind)
|
||||
? LB.get()
|
||||
: SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
|
||||
|
@ -2979,9 +2994,13 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
|
|||
break;
|
||||
}
|
||||
|
||||
// Build update: IS.CounterVar = IS.Start + Iter * IS.Step
|
||||
// Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
|
||||
auto *CounterVar = buildDeclRefExpr(
|
||||
SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()),
|
||||
IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
|
||||
/*RefersToCapture=*/true);
|
||||
ExprResult Update =
|
||||
BuildCounterUpdate(SemaRef, CurScope, UpdLoc, IS.CounterVar,
|
||||
BuildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
|
||||
IS.CounterInit, Iter, IS.CounterStep, IS.Subtract);
|
||||
if (!Update.isUsable()) {
|
||||
HasErrors = true;
|
||||
|
@ -2990,7 +3009,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
|
|||
|
||||
// Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
|
||||
ExprResult Final = BuildCounterUpdate(
|
||||
SemaRef, CurScope, UpdLoc, IS.CounterVar, IS.CounterInit,
|
||||
SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
|
||||
IS.NumIterations, IS.CounterStep, IS.Subtract);
|
||||
if (!Final.isUsable()) {
|
||||
HasErrors = true;
|
||||
|
@ -4771,20 +4790,14 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
|
|||
// the new private variable in CodeGen. This new variable is not added to
|
||||
// IdResolver, so the code in the OpenMP region uses original variable for
|
||||
// proper diagnostics.
|
||||
auto VDPrivate = VarDecl::Create(Context, CurContext, DE->getLocStart(),
|
||||
DE->getExprLoc(), VD->getIdentifier(),
|
||||
VD->getType().getUnqualifiedType(),
|
||||
VD->getTypeSourceInfo(), /*S*/ SC_Auto);
|
||||
ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto*/ false);
|
||||
auto VDPrivate =
|
||||
buildVarDecl(*this, DE->getExprLoc(),
|
||||
VD->getType().getUnqualifiedType(), VD->getName());
|
||||
ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
|
||||
if (VDPrivate->isInvalidDecl())
|
||||
continue;
|
||||
CurContext->addDecl(VDPrivate);
|
||||
auto VDPrivateRefExpr =
|
||||
DeclRefExpr::Create(Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
|
||||
/*TemplateKWLoc*/ SourceLocation(), VDPrivate,
|
||||
/*RefersToEnclosingVariableOrCapture*/ false,
|
||||
/*NameLoc*/ SourceLocation(), DE->getType(),
|
||||
/*VK*/ VK_LValue);
|
||||
buildDeclRefExpr(*this, VDPrivate, DE->getType(), DE->getExprLoc());
|
||||
|
||||
DSAStack->addDSA(VD, DE, OMPC_private);
|
||||
Vars.push_back(DE);
|
||||
|
@ -4985,10 +4998,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
|
|||
}
|
||||
}
|
||||
|
||||
auto VDPrivate =
|
||||
VarDecl::Create(Context, CurContext, DE->getLocStart(), ELoc,
|
||||
VD->getIdentifier(), VD->getType().getUnqualifiedType(),
|
||||
VD->getTypeSourceInfo(), /*S*/ SC_Auto);
|
||||
auto VDPrivate = buildVarDecl(
|
||||
*this, ELoc, VD->getType().getUnqualifiedType(), VD->getName());
|
||||
// Generate helper private variable and initialize it with the value of the
|
||||
// original variable. The address of the original variable is replaced by
|
||||
// the address of the new private variable in the CodeGen. This new variable
|
||||
|
@ -4998,18 +5009,11 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
|
|||
// For arrays generate initializer for single element and replace it by the
|
||||
// original array element in CodeGen.
|
||||
if (DE->getType()->isArrayType()) {
|
||||
auto VDInit = VarDecl::Create(Context, CurContext, DE->getLocStart(),
|
||||
ELoc, VD->getIdentifier(), Type,
|
||||
VD->getTypeSourceInfo(), /*S*/ SC_Auto);
|
||||
CurContext->addHiddenDecl(VDInit);
|
||||
VDInitRefExpr = DeclRefExpr::Create(
|
||||
Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
|
||||
/*TemplateKWLoc*/ SourceLocation(), VDInit,
|
||||
/*RefersToEnclosingVariableOrCapture*/ true, ELoc, Type,
|
||||
/*VK*/ VK_LValue);
|
||||
auto VDInit = buildVarDecl(*this, DE->getExprLoc(), Type, VD->getName());
|
||||
VDInitRefExpr = buildDeclRefExpr(*this, VDInit, Type, ELoc);
|
||||
auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
|
||||
auto *VDInitTemp =
|
||||
BuildVarDecl(*this, DE->getLocStart(), Type.getUnqualifiedType(),
|
||||
buildVarDecl(*this, DE->getLocStart(), Type.getUnqualifiedType(),
|
||||
".firstprivate.temp");
|
||||
InitializedEntity Entity =
|
||||
InitializedEntity::InitializeVariable(VDInitTemp);
|
||||
|
@ -5023,9 +5027,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
|
|||
VDPrivate->setInit(Result.getAs<Expr>());
|
||||
} else {
|
||||
auto *VDInit =
|
||||
BuildVarDecl(*this, DE->getLocStart(), Type, ".firstprivate.temp");
|
||||
VDInitRefExpr =
|
||||
BuildDeclRefExpr(VDInit, Type, VK_LValue, DE->getExprLoc()).get();
|
||||
buildVarDecl(*this, DE->getLocStart(), Type, ".firstprivate.temp");
|
||||
VDInitRefExpr = buildDeclRefExpr(*this, VDInit, Type, DE->getExprLoc());
|
||||
AddInitializerToDecl(VDPrivate,
|
||||
DefaultLvalueConversion(VDInitRefExpr).get(),
|
||||
/*DirectInit=*/false, /*TypeMayContainAuto=*/false);
|
||||
|
@ -5038,11 +5041,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
|
|||
continue;
|
||||
}
|
||||
CurContext->addDecl(VDPrivate);
|
||||
auto VDPrivateRefExpr = DeclRefExpr::Create(
|
||||
Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
|
||||
/*TemplateKWLoc*/ SourceLocation(), VDPrivate,
|
||||
/*RefersToEnclosingVariableOrCapture*/ false, DE->getLocStart(),
|
||||
DE->getType().getUnqualifiedType(), /*VK*/ VK_LValue);
|
||||
auto VDPrivateRefExpr = buildDeclRefExpr(
|
||||
*this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc());
|
||||
DSAStack->addDSA(VD, DE, OMPC_firstprivate);
|
||||
Vars.push_back(DE);
|
||||
PrivateCopies.push_back(VDPrivateRefExpr);
|
||||
|
@ -5140,6 +5140,7 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
|
|||
// lastprivate clause on a worksharing construct if any of the corresponding
|
||||
// worksharing regions ever binds to any of the corresponding parallel
|
||||
// regions.
|
||||
DSAStackTy::DSAVarData TopDVar = DVar;
|
||||
if (isOpenMPWorksharingDirective(CurrDir) &&
|
||||
!isOpenMPParallelDirective(CurrDir)) {
|
||||
DVar = DSAStack->getImplicitDSA(VD, true);
|
||||
|
@ -5160,14 +5161,14 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
|
|||
// lastprivate clause requires an accessible, unambiguous copy assignment
|
||||
// operator for the class type.
|
||||
Type = Context.getBaseElementType(Type).getNonReferenceType();
|
||||
auto *SrcVD = BuildVarDecl(*this, DE->getLocStart(),
|
||||
auto *SrcVD = buildVarDecl(*this, DE->getLocStart(),
|
||||
Type.getUnqualifiedType(), ".lastprivate.src");
|
||||
auto *PseudoSrcExpr = BuildDeclRefExpr(SrcVD, Type.getUnqualifiedType(),
|
||||
VK_LValue, DE->getExprLoc()).get();
|
||||
auto *PseudoSrcExpr = buildDeclRefExpr(
|
||||
*this, SrcVD, Type.getUnqualifiedType(), DE->getExprLoc());
|
||||
auto *DstVD =
|
||||
BuildVarDecl(*this, DE->getLocStart(), Type, ".lastprivate.dst");
|
||||
buildVarDecl(*this, DE->getLocStart(), Type, ".lastprivate.dst");
|
||||
auto *PseudoDstExpr =
|
||||
BuildDeclRefExpr(DstVD, Type, VK_LValue, DE->getExprLoc()).get();
|
||||
buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc());
|
||||
// For arrays generate assignment operation for single element and replace
|
||||
// it by the original array element in CodeGen.
|
||||
auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
|
||||
|
@ -5179,7 +5180,7 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
|
|||
if (AssignmentOp.isInvalid())
|
||||
continue;
|
||||
|
||||
if (DVar.CKind != OMPC_firstprivate)
|
||||
if (TopDVar.CKind != OMPC_firstprivate)
|
||||
DSAStack->addDSA(VD, DE, OMPC_lastprivate);
|
||||
Vars.push_back(DE);
|
||||
SrcExprs.push_back(PseudoSrcExpr);
|
||||
|
@ -5547,8 +5548,8 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
|
|||
}
|
||||
}
|
||||
Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
|
||||
auto *LHSVD = BuildVarDecl(*this, ELoc, Type, ".reduction.lhs");
|
||||
auto *RHSVD = BuildVarDecl(*this, ELoc, Type, VD->getName());
|
||||
auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs");
|
||||
auto *RHSVD = buildVarDecl(*this, ELoc, Type, VD->getName());
|
||||
// Add initializer for private variable.
|
||||
Expr *Init = nullptr;
|
||||
switch (BOK) {
|
||||
|
@ -5670,8 +5671,8 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
|
|||
<< VD;
|
||||
continue;
|
||||
}
|
||||
auto *LHSDRE = BuildDeclRefExpr(LHSVD, Type, VK_LValue, ELoc).get();
|
||||
auto *RHSDRE = BuildDeclRefExpr(RHSVD, Type, VK_LValue, ELoc).get();
|
||||
auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc);
|
||||
auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc);
|
||||
ExprResult ReductionOp =
|
||||
BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BOK,
|
||||
LHSDRE, RHSDRE);
|
||||
|
@ -5812,16 +5813,11 @@ OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
|
|||
}
|
||||
|
||||
// Build var to save initial value.
|
||||
VarDecl *Init = BuildVarDecl(*this, ELoc, DE->getType(), ".linear.start");
|
||||
VarDecl *Init = buildVarDecl(*this, ELoc, DE->getType(), ".linear.start");
|
||||
AddInitializerToDecl(Init, DefaultLvalueConversion(DE).get(),
|
||||
/*DirectInit*/ false, /*TypeMayContainAuto*/ false);
|
||||
CurContext->addDecl(Init);
|
||||
Init->setIsUsed();
|
||||
auto InitRef = DeclRefExpr::Create(
|
||||
Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
|
||||
/*TemplateKWLoc*/ SourceLocation(), Init,
|
||||
/*isEnclosingLocal*/ false, DE->getLocStart(), DE->getType(),
|
||||
/*VK*/ VK_LValue);
|
||||
auto InitRef =
|
||||
buildDeclRefExpr(*this, Init, DE->getType(), DE->getExprLoc());
|
||||
DSAStack->addDSA(VD, DE, OMPC_linear);
|
||||
Vars.push_back(DE);
|
||||
Inits.push_back(InitRef);
|
||||
|
@ -5843,11 +5839,9 @@ OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
|
|||
|
||||
// Build var to save the step value.
|
||||
VarDecl *SaveVar =
|
||||
BuildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
|
||||
CurContext->addDecl(SaveVar);
|
||||
SaveVar->setIsUsed();
|
||||
buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
|
||||
ExprResult SaveRef =
|
||||
BuildDeclRefExpr(SaveVar, StepExpr->getType(), VK_LValue, StepLoc);
|
||||
buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
|
||||
ExprResult CalcStep =
|
||||
BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
|
||||
|
||||
|
@ -5890,11 +5884,9 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
|
|||
|
||||
// Build privatized reference to the current linear var.
|
||||
auto DE = cast<DeclRefExpr>(RefExpr);
|
||||
auto PrivateRef = DeclRefExpr::Create(
|
||||
SemaRef.Context, /*QualifierLoc*/ DE->getQualifierLoc(),
|
||||
/*TemplateKWLoc*/ SourceLocation(), DE->getDecl(),
|
||||
/* RefersToEnclosingVariableOrCapture */ true, DE->getLocStart(),
|
||||
DE->getType(), /*VK*/ VK_LValue);
|
||||
auto PrivateRef =
|
||||
buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), DE->getType(),
|
||||
DE->getExprLoc(), /*RefersToCapture=*/true);
|
||||
|
||||
// Build update: Var = InitExpr + IV * Step
|
||||
ExprResult Update =
|
||||
|
@ -5904,8 +5896,8 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
|
|||
|
||||
// Build final: Var = InitExpr + NumIterations * Step
|
||||
ExprResult Final =
|
||||
BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), RefExpr, InitExpr,
|
||||
NumIterations, Step, /* Subtract */ false);
|
||||
BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), PrivateRef,
|
||||
InitExpr, NumIterations, Step, /* Subtract */ false);
|
||||
Final = SemaRef.ActOnFinishFullExpr(Final.get());
|
||||
if (!Update.isUsable() || !Final.isUsable()) {
|
||||
Updates.push_back(nullptr);
|
||||
|
@ -6054,14 +6046,13 @@ OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
|
|||
// copyin clause requires an accessible, unambiguous copy assignment
|
||||
// operator for the class type.
|
||||
Type = Context.getBaseElementType(Type).getNonReferenceType();
|
||||
auto *SrcVD = BuildVarDecl(*this, DE->getLocStart(),
|
||||
auto *SrcVD = buildVarDecl(*this, DE->getLocStart(),
|
||||
Type.getUnqualifiedType(), ".copyin.src");
|
||||
auto *PseudoSrcExpr = BuildDeclRefExpr(SrcVD, Type.getUnqualifiedType(),
|
||||
VK_LValue, DE->getExprLoc())
|
||||
.get();
|
||||
auto *DstVD = BuildVarDecl(*this, DE->getLocStart(), Type, ".copyin.dst");
|
||||
auto *PseudoSrcExpr = buildDeclRefExpr(
|
||||
*this, SrcVD, Type.getUnqualifiedType(), DE->getExprLoc());
|
||||
auto *DstVD = buildVarDecl(*this, DE->getLocStart(), Type, ".copyin.dst");
|
||||
auto *PseudoDstExpr =
|
||||
BuildDeclRefExpr(DstVD, Type, VK_LValue, DE->getExprLoc()).get();
|
||||
buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc());
|
||||
// For arrays generate assignment operation for single element and replace
|
||||
// it by the original array element in CodeGen.
|
||||
auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
|
||||
|
@ -6165,13 +6156,13 @@ OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
|
|||
// operator for the class type.
|
||||
Type = Context.getBaseElementType(Type).getUnqualifiedType();
|
||||
auto *SrcVD =
|
||||
BuildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.src");
|
||||
buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.src");
|
||||
auto *PseudoSrcExpr =
|
||||
BuildDeclRefExpr(SrcVD, Type, VK_LValue, DE->getExprLoc()).get();
|
||||
buildDeclRefExpr(*this, SrcVD, Type, DE->getExprLoc());
|
||||
auto *DstVD =
|
||||
BuildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.dst");
|
||||
buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.dst");
|
||||
auto *PseudoDstExpr =
|
||||
BuildDeclRefExpr(DstVD, Type, VK_LValue, DE->getExprLoc()).get();
|
||||
buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc());
|
||||
auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
|
||||
PseudoDstExpr, PseudoSrcExpr);
|
||||
if (AssignmentOp.isInvalid())
|
||||
|
|
|
@ -18,6 +18,7 @@ struct S {
|
|||
};
|
||||
|
||||
volatile int g = 1212;
|
||||
float f;
|
||||
|
||||
// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
|
||||
// CHECK: [[CAP_MAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* }
|
||||
|
@ -25,6 +26,7 @@ volatile int g = 1212;
|
|||
// CHECK: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* }
|
||||
// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
|
||||
// CHECK-DAG: [[X:@.+]] = global double 0.0
|
||||
// CHECK-DAG: [[F:@.+]] = global float 0.0
|
||||
template <typename T>
|
||||
T tmain() {
|
||||
S<T> test;
|
||||
|
@ -167,7 +169,7 @@ int main() {
|
|||
s_arr[i] = var;
|
||||
}
|
||||
#pragma omp parallel
|
||||
#pragma omp for lastprivate(A::x, B::x)
|
||||
#pragma omp for lastprivate(A::x, B::x) firstprivate(f) lastprivate(f)
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
A::x++;
|
||||
}
|
||||
|
@ -255,11 +257,17 @@ int main() {
|
|||
|
||||
//
|
||||
// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, %{{.+}}* %{{.+}})
|
||||
// CHECK: [[F_PRIV:%.+]] = alloca float,
|
||||
// CHECK-NOT: alloca float
|
||||
// CHECK: [[X_PRIV:%.+]] = alloca double,
|
||||
// CHECK-NOT: alloca float
|
||||
// CHECK-NOT: alloca double
|
||||
|
||||
// Check for default initialization.
|
||||
// CHECK-NOT: [[X_PRIV]]
|
||||
// CHECK: [[F_VAL:%.+]] = load float, float* [[F]],
|
||||
// CHECK: store float [[F_VAL]], float* [[F_PRIV]],
|
||||
// CHECK-NOT: [[X_PRIV]]
|
||||
|
||||
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
|
||||
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
|
||||
|
@ -277,6 +285,11 @@ int main() {
|
|||
// original x=private_x;
|
||||
// CHECK: [[X_VAL:%.+]] = load double, double* [[X_PRIV]],
|
||||
// CHECK: store double [[X_VAL]], double* [[X]],
|
||||
|
||||
// original f=private_f;
|
||||
// CHECK: [[F_VAL:%.+]] = load float, float* [[F_PRIV]],
|
||||
// CHECK: store float [[F_VAL]], float* [[F]],
|
||||
|
||||
// CHECK-NEXT: br label %[[LAST_DONE]]
|
||||
// CHECK: [[LAST_DONE]]
|
||||
|
||||
|
|
Loading…
Reference in New Issue