[OPENMP]Fix PR44133: Emit definitions of used constructors/functions.

Need to fully rebuild the initializer/combiner when instatiating the
declare reduction constrcut to properly emit used functions.
This commit is contained in:
Alexey Bataev 2019-12-02 13:04:30 -05:00
parent 9ec6d71211
commit 478541a6da
2 changed files with 47 additions and 80 deletions

View File

@ -3070,20 +3070,11 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
} else {
SubstReductionType = D->getType();
}
Expr *Combiner = D->getCombiner();
Expr *Init = D->getInitializer();
const bool CombinerRequiresInstantiation =
Combiner &&
(Combiner->isValueDependent() || Combiner->isInstantiationDependent() ||
Combiner->isTypeDependent() ||
Combiner->containsUnexpandedParameterPack());
const bool InitRequiresInstantiation =
Init &&
(Init->isValueDependent() || Init->isInstantiationDependent() ||
Init->isTypeDependent() || Init->containsUnexpandedParameterPack());
if (SubstReductionType.isNull())
return nullptr;
bool IsCorrect = !SubstReductionType.isNull();
Expr *Combiner = D->getCombiner();
Expr *Init = D->getInitializer();
bool IsCorrect = true;
// Create instantiated copy.
std::pair<QualType, SourceLocation> ReductionTypes[] = {
std::make_pair(SubstReductionType, D->getLocation())};
@ -3098,79 +3089,53 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
PrevDeclInScope);
auto *NewDRD = cast<OMPDeclareReductionDecl>(DRD.get().getSingleDecl());
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDRD);
if (!RequiresInstantiation && !CombinerRequiresInstantiation &&
!InitRequiresInstantiation) {
if (Combiner) {
NewDRD->setCombinerData(D->getCombinerIn(), D->getCombinerOut());
NewDRD->setCombiner(Combiner);
if (Init) {
NewDRD->setInitializerData(D->getInitOrig(), D->getInitPriv());
NewDRD->setInitializer(Init, D->getInitializerKind());
}
}
(void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd(
/*S=*/nullptr, DRD, IsCorrect && !D->isInvalidDecl());
return NewDRD;
}
Expr *SubstCombiner = nullptr;
Expr *SubstInitializer = nullptr;
// Combiners instantiation sequence.
if (Combiner) {
if (!CombinerRequiresInstantiation) {
NewDRD->setCombinerData(D->getCombinerIn(), D->getCombinerOut());
NewDRD->setCombiner(Combiner);
} else {
SemaRef.ActOnOpenMPDeclareReductionCombinerStart(
/*S=*/nullptr, NewDRD);
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
cast<DeclRefExpr>(D->getCombinerIn())->getDecl(),
cast<DeclRefExpr>(NewDRD->getCombinerIn())->getDecl());
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
cast<DeclRefExpr>(D->getCombinerOut())->getDecl(),
cast<DeclRefExpr>(NewDRD->getCombinerOut())->getDecl());
auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),
ThisContext);
SubstCombiner = SemaRef.SubstExpr(Combiner, TemplateArgs).get();
SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner);
}
SemaRef.ActOnOpenMPDeclareReductionCombinerStart(
/*S=*/nullptr, NewDRD);
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
cast<DeclRefExpr>(D->getCombinerIn())->getDecl(),
cast<DeclRefExpr>(NewDRD->getCombinerIn())->getDecl());
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
cast<DeclRefExpr>(D->getCombinerOut())->getDecl(),
cast<DeclRefExpr>(NewDRD->getCombinerOut())->getDecl());
auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),
ThisContext);
SubstCombiner = SemaRef.SubstExpr(Combiner, TemplateArgs).get();
SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner);
}
// Initializers instantiation sequence.
if (Init) {
if (!InitRequiresInstantiation) {
NewDRD->setInitializerData(D->getInitOrig(), D->getInitPriv());
NewDRD->setInitializer(Init, D->getInitializerKind());
VarDecl *OmpPrivParm = SemaRef.ActOnOpenMPDeclareReductionInitializerStart(
/*S=*/nullptr, NewDRD);
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
cast<DeclRefExpr>(D->getInitOrig())->getDecl(),
cast<DeclRefExpr>(NewDRD->getInitOrig())->getDecl());
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
cast<DeclRefExpr>(D->getInitPriv())->getDecl(),
cast<DeclRefExpr>(NewDRD->getInitPriv())->getDecl());
if (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit) {
SubstInitializer = SemaRef.SubstExpr(Init, TemplateArgs).get();
} else {
VarDecl *OmpPrivParm =
SemaRef.ActOnOpenMPDeclareReductionInitializerStart(
/*S=*/nullptr, NewDRD);
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
cast<DeclRefExpr>(D->getInitOrig())->getDecl(),
cast<DeclRefExpr>(NewDRD->getInitOrig())->getDecl());
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
cast<DeclRefExpr>(D->getInitPriv())->getDecl(),
cast<DeclRefExpr>(NewDRD->getInitPriv())->getDecl());
if (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit) {
SubstInitializer = SemaRef.SubstExpr(Init, TemplateArgs).get();
} else {
auto *OldPrivParm =
cast<VarDecl>(cast<DeclRefExpr>(D->getInitPriv())->getDecl());
IsCorrect = IsCorrect && OldPrivParm->hasInit();
if (IsCorrect)
SemaRef.InstantiateVariableInitializer(OmpPrivParm, OldPrivParm,
TemplateArgs);
}
SemaRef.ActOnOpenMPDeclareReductionInitializerEnd(
NewDRD, SubstInitializer, OmpPrivParm);
auto *OldPrivParm =
cast<VarDecl>(cast<DeclRefExpr>(D->getInitPriv())->getDecl());
IsCorrect = IsCorrect && OldPrivParm->hasInit();
if (IsCorrect)
SemaRef.InstantiateVariableInitializer(OmpPrivParm, OldPrivParm,
TemplateArgs);
}
SemaRef.ActOnOpenMPDeclareReductionInitializerEnd(NewDRD, SubstInitializer,
OmpPrivParm);
}
IsCorrect = IsCorrect && (!CombinerRequiresInstantiation || SubstCombiner) &&
(!InitRequiresInstantiation ||
(!Init ||
(D->getInitializerKind() == OMPDeclareReductionDecl::CallInit &&
SubstInitializer) ||
(D->getInitializerKind() != OMPDeclareReductionDecl::CallInit &&
!SubstInitializer)));
IsCorrect = IsCorrect && SubstCombiner &&
(!Init ||
(D->getInitializerKind() == OMPDeclareReductionDecl::CallInit &&
SubstInitializer) ||
(D->getInitializerKind() != OMPDeclareReductionDecl::CallInit &&
!SubstInitializer));
(void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd(
/*S=*/nullptr, DRD, IsCorrect && !D->isInvalidDecl());

View File

@ -85,9 +85,8 @@ SSS<int> d;
// CHECK-NEXT: ret void
// CHECK-NEXT: }
// CHECK: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]*
// CHECK-LOAD: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]*
void init(SSS<int> &lhs, SSS<int> &rhs) {}
template <typename T>
void init(T &lhs, T &rhs) {}
#pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig))
// CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
@ -95,7 +94,7 @@ void init(SSS<int> &lhs, SSS<int> &rhs) {}
// CHECK-NEXT: ret void
// CHECK-NEXT: }
// CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
// CHECK: call {{.*}}void [[INIT]](
// CHECK: call {{.*}}void @_Z4initI3SSSIiEEvRT_S3_(
// CHECK-NEXT: ret void
// CHECK-NEXT: }
@ -104,10 +103,13 @@ void init(SSS<int> &lhs, SSS<int> &rhs) {}
// CHECK-LOAD-NEXT: ret void
// CHECK-LOAD-NEXT: }
// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
// CHECK-LOAD: call {{.*}}void [[INIT]](
// CHECK-LOAD: call {{.*}}void @_Z4initI3SSSIiEEvRT_S3_(
// CHECK-LOAD-NEXT: ret void
// CHECK-LOAD-NEXT: }
// CHECK: define {{.*}}void @_Z4initI3SSSIiEEvRT_S3_(%struct.SSS* {{.+}}, %struct.SSS* {{.+}})
// CHECK-LOAD: define {{.*}}void @_Z4initI3SSSIiEEvRT_S3_(%struct.SSS* {{.+}}, %struct.SSS* {{.+}})
template <typename T>
T foo(T a) {
#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = 15 * omp_orig)