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 {
|
||||
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());
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue