[OPENMP] Code cleanup for capturing of variables in OpenMP regions.

llvm-svn: 236821
This commit is contained in:
Alexey Bataev 2015-05-08 10:41:21 +00:00
parent 307b917696
commit 39f915b8f4
5 changed files with 156 additions and 126 deletions

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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.

View File

@ -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())

View File

@ -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]]