forked from OSchip/llvm-project
[OPENMP] Fix processing of declare target construct.
The attribute marked as inheritable since OpenMP 5.0 supports it + additional fixes to support new functionality. llvm-svn: 339704
This commit is contained in:
parent
60a1e4dddc
commit
97b722121e
|
@ -2956,9 +2956,10 @@ def OMPDeclareSimdDecl : Attr {
|
|||
}];
|
||||
}
|
||||
|
||||
def OMPDeclareTargetDecl : Attr {
|
||||
def OMPDeclareTargetDecl : InheritableAttr {
|
||||
let Spellings = [Pragma<"omp", "declare target">];
|
||||
let SemaHandler = 0;
|
||||
let Subjects = SubjectList<[Function, SharedVar]>;
|
||||
let Documentation = [OMPDeclareTargetDocs];
|
||||
let Args = [
|
||||
EnumArgument<"MapType", "MapTypeTy",
|
||||
|
@ -2971,6 +2972,15 @@ def OMPDeclareTargetDecl : Attr {
|
|||
if (getMapType() != MT_To)
|
||||
OS << ' ' << ConvertMapTypeTyToStr(getMapType());
|
||||
}
|
||||
static llvm::Optional<MapTypeTy>
|
||||
isDeclareTargetDeclaration(const ValueDecl *VD) {
|
||||
if (!VD->hasAttrs())
|
||||
return llvm::None;
|
||||
if (const auto *Attr = VD->getAttr<OMPDeclareTargetDeclAttr>())
|
||||
return Attr->getMapType();
|
||||
|
||||
return llvm::None;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
@ -9806,13 +9806,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
|
|||
return true;
|
||||
|
||||
// If the decl is marked as `declare target`, it should be emitted.
|
||||
for (const auto *Decl : D->redecls()) {
|
||||
if (!Decl->hasAttrs())
|
||||
continue;
|
||||
if (const auto *Attr = Decl->getAttr<OMPDeclareTargetDeclAttr>())
|
||||
if (Attr->getMapType() != OMPDeclareTargetDeclAttr::MT_Link)
|
||||
return true;
|
||||
}
|
||||
if (const llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
|
||||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
|
||||
return *Res != OMPDeclareTargetDeclAttr::MT_Link;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1091,6 +1091,10 @@ void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
|||
printTemplateParameters(FD->getTemplateParameterList(I));
|
||||
}
|
||||
VisitRedeclarableTemplateDecl(D);
|
||||
// Declare target attribute is special one, natural spelling for the pragma
|
||||
// assumes "ending" construct so print it here.
|
||||
if (D->getTemplatedDecl()->hasAttr<OMPDeclareTargetDeclAttr>())
|
||||
Out << "#pragma omp end declare target\n";
|
||||
|
||||
// Never print "instantiations" for deduction guides (they don't really
|
||||
// have them).
|
||||
|
|
|
@ -897,25 +897,6 @@ static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
|
|||
CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
|
||||
}
|
||||
|
||||
static llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy>
|
||||
isDeclareTargetDeclaration(const ValueDecl *VD) {
|
||||
for (const Decl *D : VD->redecls()) {
|
||||
if (!D->hasAttrs())
|
||||
continue;
|
||||
if (const auto *Attr = D->getAttr<OMPDeclareTargetDeclAttr>())
|
||||
return Attr->getMapType();
|
||||
}
|
||||
if (const auto *V = dyn_cast<VarDecl>(VD)) {
|
||||
if (const VarDecl *TD = V->getTemplateInstantiationPattern())
|
||||
return isDeclareTargetDeclaration(TD);
|
||||
} else if (const auto *FD = dyn_cast<FunctionDecl>(VD)) {
|
||||
if (const auto *TD = FD->getTemplateInstantiationPattern())
|
||||
return isDeclareTargetDeclaration(TD);
|
||||
}
|
||||
|
||||
return llvm::None;
|
||||
}
|
||||
|
||||
LValue ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, const Expr *E) {
|
||||
return CGF.EmitOMPSharedLValue(E);
|
||||
}
|
||||
|
@ -2417,7 +2398,7 @@ Address CGOpenMPRuntime::getAddrOfDeclareTargetLink(const VarDecl *VD) {
|
|||
if (CGM.getLangOpts().OpenMPSimd)
|
||||
return Address::invalid();
|
||||
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
|
||||
isDeclareTargetDeclaration(VD);
|
||||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
|
||||
if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
|
||||
SmallString<64> PtrName;
|
||||
{
|
||||
|
@ -2639,7 +2620,7 @@ bool CGOpenMPRuntime::emitDeclareTargetVarDefinition(const VarDecl *VD,
|
|||
llvm::GlobalVariable *Addr,
|
||||
bool PerformInit) {
|
||||
Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
|
||||
isDeclareTargetDeclaration(VD);
|
||||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
|
||||
if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link)
|
||||
return false;
|
||||
VD = VD->getDefinition(CGM.getContext());
|
||||
|
@ -6957,7 +6938,7 @@ private:
|
|||
if (const auto *VD =
|
||||
dyn_cast_or_null<VarDecl>(I->getAssociatedDeclaration())) {
|
||||
if (llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
|
||||
isDeclareTargetDeclaration(VD))
|
||||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
|
||||
if (*Res == OMPDeclareTargetDeclAttr::MT_Link) {
|
||||
IsLink = true;
|
||||
BP = CGF.CGM.getOpenMPRuntime().getAddrOfDeclareTargetLink(VD);
|
||||
|
@ -7448,7 +7429,7 @@ public:
|
|||
if (!VD)
|
||||
continue;
|
||||
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
|
||||
isDeclareTargetDeclaration(VD);
|
||||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
|
||||
if (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)
|
||||
continue;
|
||||
StructRangeInfoTy PartialStruct;
|
||||
|
@ -8078,7 +8059,7 @@ bool CGOpenMPRuntime::emitTargetFunctions(GlobalDecl GD) {
|
|||
scanForTargetRegionsFunctions(FD->getBody(), CGM.getMangledName(GD));
|
||||
|
||||
// Do not to emit function if it is not marked as declare target.
|
||||
return !isDeclareTargetDeclaration(FD) &&
|
||||
return !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD) &&
|
||||
AlreadyEmittedTargetFunctions.count(FD->getCanonicalDecl()) == 0;
|
||||
}
|
||||
|
||||
|
@ -8105,7 +8086,8 @@ bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
|
|||
|
||||
// Do not to emit variable if it is not marked as declare target.
|
||||
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
|
||||
isDeclareTargetDeclaration(cast<VarDecl>(GD.getDecl()));
|
||||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
|
||||
cast<VarDecl>(GD.getDecl()));
|
||||
if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link) {
|
||||
if (CGM.getContext().DeclMustBeEmitted(GD.getDecl()))
|
||||
DeferredGlobalVariables.insert(cast<VarDecl>(GD.getDecl()));
|
||||
|
@ -8117,7 +8099,7 @@ bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
|
|||
void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD,
|
||||
llvm::Constant *Addr) {
|
||||
if (llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
|
||||
isDeclareTargetDeclaration(VD)) {
|
||||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
|
||||
OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags;
|
||||
StringRef VarName;
|
||||
CharUnits VarSize;
|
||||
|
@ -8171,7 +8153,7 @@ bool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) {
|
|||
void CGOpenMPRuntime::emitDeferredTargetDecls() const {
|
||||
for (const VarDecl *VD : DeferredGlobalVariables) {
|
||||
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
|
||||
isDeclareTargetDeclaration(VD);
|
||||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
|
||||
if (Res) {
|
||||
assert(*Res != OMPDeclareTargetDeclAttr::MT_Link &&
|
||||
"Implicit declare target variables must be only to().");
|
||||
|
@ -8202,7 +8184,7 @@ bool CGOpenMPRuntime::markAsGlobalTarget(GlobalDecl GD) {
|
|||
const FunctionDecl *FD = D->getCanonicalDecl();
|
||||
// Do not to emit function if it is marked as declare target as it was already
|
||||
// emitted.
|
||||
if (isDeclareTargetDeclaration(D)) {
|
||||
if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(D)) {
|
||||
if (D->hasBody() && AlreadyEmittedTargetFunctions.count(FD) == 0) {
|
||||
if (auto *F = dyn_cast_or_null<llvm::Function>(
|
||||
CGM.GetGlobalValue(CGM.getMangledName(GD))))
|
||||
|
|
|
@ -191,20 +191,10 @@ class CheckVarsEscapingDeclContext final
|
|||
bool AllEscaped = false;
|
||||
bool IsForCombinedParallelRegion = false;
|
||||
|
||||
static llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy>
|
||||
isDeclareTargetDeclaration(const ValueDecl *VD) {
|
||||
for (const Decl *D : VD->redecls()) {
|
||||
if (!D->hasAttrs())
|
||||
continue;
|
||||
if (const auto *Attr = D->getAttr<OMPDeclareTargetDeclAttr>())
|
||||
return Attr->getMapType();
|
||||
}
|
||||
return llvm::None;
|
||||
}
|
||||
|
||||
void markAsEscaped(const ValueDecl *VD) {
|
||||
// Do not globalize declare target variables.
|
||||
if (!isa<VarDecl>(VD) || isDeclareTargetDeclaration(VD))
|
||||
if (!isa<VarDecl>(VD) ||
|
||||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
|
||||
return;
|
||||
VD = cast<ValueDecl>(VD->getCanonicalDecl());
|
||||
// Variables captured by value must be globalized.
|
||||
|
|
|
@ -1258,17 +1258,6 @@ void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
|
|||
DSAStack->popFunction(OldFSI);
|
||||
}
|
||||
|
||||
static llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy>
|
||||
isDeclareTargetDeclaration(const ValueDecl *VD) {
|
||||
for (const Decl *D : VD->redecls()) {
|
||||
if (!D->hasAttrs())
|
||||
continue;
|
||||
if (const auto *Attr = D->getAttr<OMPDeclareTargetDeclAttr>())
|
||||
return Attr->getMapType();
|
||||
}
|
||||
return llvm::None;
|
||||
}
|
||||
|
||||
bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const {
|
||||
assert(LangOpts.OpenMP && "OpenMP is not allowed");
|
||||
|
||||
|
@ -1449,14 +1438,14 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) {
|
|||
(getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
|
||||
// Try to mark variable as declare target if it is used in capturing
|
||||
// regions.
|
||||
if (!isDeclareTargetDeclaration(VD))
|
||||
if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
|
||||
checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
|
||||
return nullptr;
|
||||
} else if (isInOpenMPTargetExecutionDirective()) {
|
||||
// If the declaration is enclosed in a 'declare target' directive,
|
||||
// then it should not be captured.
|
||||
//
|
||||
if (isDeclareTargetDeclaration(VD))
|
||||
if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
|
||||
return nullptr;
|
||||
return VD;
|
||||
}
|
||||
|
@ -1996,7 +1985,7 @@ public:
|
|||
|
||||
// Skip internally declared static variables.
|
||||
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
|
||||
isDeclareTargetDeclaration(VD);
|
||||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
|
||||
if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) &&
|
||||
(!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
|
||||
return;
|
||||
|
@ -13152,6 +13141,8 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
|
||||
D = FTD->getTemplatedDecl();
|
||||
if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
if (FD->hasAttr<OMPDeclareTargetDeclAttr>() &&
|
||||
(FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
|
||||
|
@ -13162,16 +13153,6 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) {
|
||||
if (FTD->hasAttr<OMPDeclareTargetDeclAttr>() &&
|
||||
(FTD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
|
||||
OMPDeclareTargetDeclAttr::MT_Link)) {
|
||||
assert(IdLoc.isValid() && "Source location is expected");
|
||||
Diag(IdLoc, diag::err_omp_function_in_link_clause);
|
||||
Diag(FTD->getLocation(), diag::note_defined_here) << FTD;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!E) {
|
||||
// Checking declaration inside declare target region.
|
||||
if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&
|
||||
|
|
|
@ -169,11 +169,35 @@ struct SSSTt {
|
|||
// CHECK: #pragma omp end declare target
|
||||
// CHECK: int b;
|
||||
|
||||
#pragma omp declare target
|
||||
template <typename T>
|
||||
T baz() { return T(); }
|
||||
#pragma omp end declare target
|
||||
|
||||
template <>
|
||||
int baz() { return 1; }
|
||||
|
||||
// CHECK: #pragma omp declare target
|
||||
// CHECK: template <typename T> T baz() {
|
||||
// CHECK: return T();
|
||||
// CHECK: }
|
||||
// CHECK: #pragma omp end declare target
|
||||
// CHECK: #pragma omp declare target
|
||||
// CHECK: template<> float baz<float>() {
|
||||
// CHECK: return float();
|
||||
// CHECK: }
|
||||
// CHECK: template<> int baz<int>() {
|
||||
// CHECK: return 1;
|
||||
// CHECK: }
|
||||
// CHECK: #pragma omp end declare target
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
foo();
|
||||
foo_c();
|
||||
foo_cpp();
|
||||
test1();
|
||||
baz<float>();
|
||||
baz<int>();
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue