forked from OSchip/llvm-project
[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:
parent
9ec6d71211
commit
478541a6da
|
@ -3070,20 +3070,11 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
|
||||||
} else {
|
} else {
|
||||||
SubstReductionType = D->getType();
|
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())
|
if (SubstReductionType.isNull())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
bool IsCorrect = !SubstReductionType.isNull();
|
Expr *Combiner = D->getCombiner();
|
||||||
|
Expr *Init = D->getInitializer();
|
||||||
|
bool IsCorrect = true;
|
||||||
// Create instantiated copy.
|
// Create instantiated copy.
|
||||||
std::pair<QualType, SourceLocation> ReductionTypes[] = {
|
std::pair<QualType, SourceLocation> ReductionTypes[] = {
|
||||||
std::make_pair(SubstReductionType, D->getLocation())};
|
std::make_pair(SubstReductionType, D->getLocation())};
|
||||||
|
@ -3098,79 +3089,53 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
|
||||||
PrevDeclInScope);
|
PrevDeclInScope);
|
||||||
auto *NewDRD = cast<OMPDeclareReductionDecl>(DRD.get().getSingleDecl());
|
auto *NewDRD = cast<OMPDeclareReductionDecl>(DRD.get().getSingleDecl());
|
||||||
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDRD);
|
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 *SubstCombiner = nullptr;
|
||||||
Expr *SubstInitializer = nullptr;
|
Expr *SubstInitializer = nullptr;
|
||||||
// Combiners instantiation sequence.
|
// Combiners instantiation sequence.
|
||||||
if (Combiner) {
|
if (Combiner) {
|
||||||
if (!CombinerRequiresInstantiation) {
|
SemaRef.ActOnOpenMPDeclareReductionCombinerStart(
|
||||||
NewDRD->setCombinerData(D->getCombinerIn(), D->getCombinerOut());
|
/*S=*/nullptr, NewDRD);
|
||||||
NewDRD->setCombiner(Combiner);
|
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
|
||||||
} else {
|
cast<DeclRefExpr>(D->getCombinerIn())->getDecl(),
|
||||||
SemaRef.ActOnOpenMPDeclareReductionCombinerStart(
|
cast<DeclRefExpr>(NewDRD->getCombinerIn())->getDecl());
|
||||||
/*S=*/nullptr, NewDRD);
|
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
|
||||||
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
|
cast<DeclRefExpr>(D->getCombinerOut())->getDecl(),
|
||||||
cast<DeclRefExpr>(D->getCombinerIn())->getDecl(),
|
cast<DeclRefExpr>(NewDRD->getCombinerOut())->getDecl());
|
||||||
cast<DeclRefExpr>(NewDRD->getCombinerIn())->getDecl());
|
auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
|
||||||
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
|
Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),
|
||||||
cast<DeclRefExpr>(D->getCombinerOut())->getDecl(),
|
ThisContext);
|
||||||
cast<DeclRefExpr>(NewDRD->getCombinerOut())->getDecl());
|
SubstCombiner = SemaRef.SubstExpr(Combiner, TemplateArgs).get();
|
||||||
auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
|
SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner);
|
||||||
Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),
|
|
||||||
ThisContext);
|
|
||||||
SubstCombiner = SemaRef.SubstExpr(Combiner, TemplateArgs).get();
|
|
||||||
SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Initializers instantiation sequence.
|
// Initializers instantiation sequence.
|
||||||
if (Init) {
|
if (Init) {
|
||||||
if (!InitRequiresInstantiation) {
|
VarDecl *OmpPrivParm = SemaRef.ActOnOpenMPDeclareReductionInitializerStart(
|
||||||
NewDRD->setInitializerData(D->getInitOrig(), D->getInitPriv());
|
/*S=*/nullptr, NewDRD);
|
||||||
NewDRD->setInitializer(Init, D->getInitializerKind());
|
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 {
|
} else {
|
||||||
VarDecl *OmpPrivParm =
|
auto *OldPrivParm =
|
||||||
SemaRef.ActOnOpenMPDeclareReductionInitializerStart(
|
cast<VarDecl>(cast<DeclRefExpr>(D->getInitPriv())->getDecl());
|
||||||
/*S=*/nullptr, NewDRD);
|
IsCorrect = IsCorrect && OldPrivParm->hasInit();
|
||||||
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
|
if (IsCorrect)
|
||||||
cast<DeclRefExpr>(D->getInitOrig())->getDecl(),
|
SemaRef.InstantiateVariableInitializer(OmpPrivParm, OldPrivParm,
|
||||||
cast<DeclRefExpr>(NewDRD->getInitOrig())->getDecl());
|
TemplateArgs);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
SemaRef.ActOnOpenMPDeclareReductionInitializerEnd(NewDRD, SubstInitializer,
|
||||||
|
OmpPrivParm);
|
||||||
}
|
}
|
||||||
IsCorrect = IsCorrect && (!CombinerRequiresInstantiation || SubstCombiner) &&
|
IsCorrect = IsCorrect && SubstCombiner &&
|
||||||
(!InitRequiresInstantiation ||
|
(!Init ||
|
||||||
(!Init ||
|
(D->getInitializerKind() == OMPDeclareReductionDecl::CallInit &&
|
||||||
(D->getInitializerKind() == OMPDeclareReductionDecl::CallInit &&
|
SubstInitializer) ||
|
||||||
SubstInitializer) ||
|
(D->getInitializerKind() != OMPDeclareReductionDecl::CallInit &&
|
||||||
(D->getInitializerKind() != OMPDeclareReductionDecl::CallInit &&
|
!SubstInitializer));
|
||||||
!SubstInitializer)));
|
|
||||||
|
|
||||||
(void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd(
|
(void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd(
|
||||||
/*S=*/nullptr, DRD, IsCorrect && !D->isInvalidDecl());
|
/*S=*/nullptr, DRD, IsCorrect && !D->isInvalidDecl());
|
||||||
|
|
|
@ -85,9 +85,8 @@ SSS<int> d;
|
||||||
// CHECK-NEXT: ret void
|
// CHECK-NEXT: ret void
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
|
||||||
// CHECK: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]*
|
template <typename T>
|
||||||
// CHECK-LOAD: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]*
|
void init(T &lhs, T &rhs) {}
|
||||||
void init(SSS<int> &lhs, SSS<int> &rhs) {}
|
|
||||||
|
|
||||||
#pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig))
|
#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)
|
// 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: ret void
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
// CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
|
// 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: ret void
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
|
||||||
|
@ -104,10 +103,13 @@ void init(SSS<int> &lhs, SSS<int> &rhs) {}
|
||||||
// CHECK-LOAD-NEXT: ret void
|
// CHECK-LOAD-NEXT: ret void
|
||||||
// CHECK-LOAD-NEXT: }
|
// CHECK-LOAD-NEXT: }
|
||||||
// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
|
// 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: ret void
|
||||||
// CHECK-LOAD-NEXT: }
|
// 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>
|
template <typename T>
|
||||||
T foo(T a) {
|
T foo(T a) {
|
||||||
#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = 15 * omp_orig)
|
#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = 15 * omp_orig)
|
||||||
|
|
Loading…
Reference in New Issue