Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
llvm-doe
llvm-project
Commits
56252580
Commit
56252580
authored
May 31, 2021
by
Joel E. Denny
Browse files
WIP: [Clacc][OpenACC] Prototype `acc routine seq`
parent
a59e21d4
Changes
26
Hide whitespace changes
Inline
Side-by-side
clang/README-OpenACC-status.md
View file @
56252580
...
...
@@ -240,7 +240,7 @@ Run-Time Environment Variables
*
Appearing within a
`parallel`
construct and any number of levels
of nesting within other
`loop`
directives are supported.
*
Appearing outside a
`parallel`
construct (that is, an orphaned
loop) is not yet supported.
`
loop
`
construct
) is not yet supported.
*
Use without clauses is supported.
*
Supported partitionability clauses
*
Implicit
`independent`
...
...
@@ -303,6 +303,25 @@ Run-Time Environment Variables
*
A
`reduction`
clause implies a
`copy`
clause (overriding the
implicit
`firstprivate`
clause).
`routine` Directive
-------------------
*
Lexical context
*
Appearing at file scope is supported.
*
Appearing within a function definition is not supported.
*
Supported clauses
*
`seq`
(required)
*
Associated declaration
*
A lone function definition or prototype is supported.
*
A declaration containing multiple declarators is not supported.
For example,
`void foo(), bar();`
.
*
Function definition body
*
Appearance of any OpenACC directive produces a compile-time
error diagnostic. Thus, orphaned
`loop`
constructs are not yet
supported.
*
Declaration of a static local variable produces a compile-time
error diagnostic.
Subarrays
---------
...
...
@@ -317,10 +336,11 @@ Subarrays
Device-Side Directives
----------------------
Nesting of an
`update`
,
`data`
,
`parallel`
, or
`parallel loop`
directive inside a
`parallel`
,
`loop`
, or
`parallel loop`
construct is
not yet supported. We're not aware of any OpenACC implementation that
supports this yet.
Nesting of an
`update`
,
`enter data`
,
`exit data`
,
`data`
,
`parallel`
,
or
`parallel loop`
directive inside a
`parallel`
,
`loop`
, or
`parallel
loop`
construct or inside a function attributed with a
`routine`
directive is not yet supported. We're not aware of any OpenACC
implementation that supports such cases yet.
OpenACC Runtime Library API and Preprocessor
--------------------------------------------
...
...
clang/include/clang/AST/PrettyPrinter.h
View file @
56252580
...
...
@@ -91,7 +91,7 @@ struct PrintingPolicy {
MSVCFormatting
(
false
),
ConstantsAsWritten
(
false
),
SuppressImplicitBase
(
false
),
FullyQualifiedName
(
false
),
PrintCanonicalTypes
(
false
),
PrintInjectedClassNameWithArguments
(
true
),
OpenACCPrint
(
OpenACCPrint_ACC
)
{}
OpenACCPrint
(
OpenACCPrint_ACC
)
{}
/// Adjust this printing policy for cases where it's known that we're
/// printing C++ code (for instance, if AST dumping reaches a C++-only
...
...
clang/include/clang/AST/StmtOpenACC.h
View file @
56252580
...
...
@@ -28,9 +28,18 @@ namespace clang {
// AST classes for directives.
//===----------------------------------------------------------------------===//
/// This is a basic class for representing
single
OpenACC executable
///
directive
.
/// This is a basic class for representing OpenACC executable
directives and
///
constructs
.
///
/// FIXME: The name should be changed to reflect that it's not just OpenACC
/// executable directives (like acc update). The base class ExecutableDirective
/// should become something more generic too then, but it has to also make sense
/// for OMPExecutableDirective. ActOnOpenACCExecutableDirective should be
/// renamed in Sema accordingly. Perhaps ACCExecutableDirectiveOrConstruct is
/// the right name to distinguish it from declarative directives. Perhaps the
/// base class should be ExecutableDirectiveOrConstruct. Or maybe
/// ACCDirectiveStmt and base class DirectiveStmt is a nice summary of a
/// directive that is more than declarative.
class
ACCExecutableDirective
:
public
ExecutableDirective
{
friend
class
ASTStmtReader
;
/// Kind of the directive.
...
...
clang/include/clang/Basic/Attr.td
View file @
56252580
...
...
@@ -534,6 +534,9 @@ class Attr {
// Set to true if this attribute meaningful when applied to or inherited
// in a class template definition.
bit MeaningfulToClassTemplateDefinition = 0;
// Set to true if provides a custom implementation of the printPretty
// function.
bit HasCustomPrintPretty = 0;
// Set to true if this attribute can be used with '#pragma clang attribute'.
// By default, an attribute is supported by the '#pragma clang attribute'
// only when:
...
...
@@ -3604,7 +3607,8 @@ def OMPDeclareTargetDecl : InheritableAttr {
EnumArgument<"DevType", "DevTypeTy",
[ "host", "nohost", "any" ],
[ "DT_Host", "DT_NoHost", "DT_Any" ]>,
UnsignedArgument<"Level">
UnsignedArgument<"Level">,
BoolArgument<"IsOpenACCTranslation">
];
let AdditionalMembers = [{
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const;
...
...
@@ -3614,6 +3618,7 @@ def OMPDeclareTargetDecl : InheritableAttr {
static llvm::Optional<DevTypeTy> getDeviceType(const ValueDecl *VD);
static llvm::Optional<SourceLocation> getLocation(const ValueDecl *VD);
}];
let HasCustomPrintPretty = 1;
}
def OMPAllocateDecl : InheritableAttr {
...
...
@@ -3659,6 +3664,19 @@ def OMPDeclareVariant : InheritableAttr {
}];
}
def ACCRoutineDecl : InheritableAttr {
let Spellings = [Pragma<"acc", "routine">];
let SemaHandler = 0;
let Subjects = SubjectList<[Function]>;
let Args = [
EnumArgument<"Partitioning", "PartitioningTy",
[ "seq" ],
[ "Seq" ]>
];
let Documentation = [Undocumented];
let HasCustomPrintPretty = 1;
}
def Assumption : InheritableAttr {
let Spellings = [Clang<"assume">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
...
...
clang/include/clang/Basic/DiagnosticFrontendKinds.td
View file @
56252580
...
...
@@ -319,6 +319,15 @@ def err_rewrite_acc_end_in_macro : Error<
def err_rewrite_acc_end_in_pragma_op : Error<
"cannot rewrite OpenACC directive that has no associated statement and that "
"appears within a _Pragma operator">;
def err_rewrite_acc_routine_in_pragma_op : Error<
"cannot rewrite OpenACC routine directive that appears within a _Pragma "
"operator">;
def err_rewrite_acc_routine_function_start_in_macro : Error<
"cannot rewrite OpenACC routine directive whose associated function "
"declaration starts within a macro expansion">;
def err_rewrite_acc_routine_function_end_in_macro : Error<
"cannot rewrite OpenACC routine directive whose associated function "
"declaration ends within a macro expansion">;
} // end of RewriteOpenACC category
}
clang/include/clang/Basic/DiagnosticSemaKinds.td
View file @
56252580
...
...
@@ -10842,6 +10842,22 @@ def note_acc_disable_diag : Note<
def err_acc_no_self_host_device_clause : Error<
"expected at least one 'self', 'host', or 'device' clause for '#pragma acc "
"update'">;
// TODO: Once the other clauses are supported, this should say:
// "expected at least one 'gang', 'worker', 'vector', or 'seq' clause for "
// "'#pragma acc routine'"
def err_acc_no_gang_worker_vector_seq_clause : Error<
"expected 'seq' clause for '#pragma acc routine'">;
def err_acc_expected_function_after_directive : Error<
"'#pragma acc %0' must be followed by a lone function prototype or "
"definition">;
def err_acc_routine_unexpected_directive : Error<
"'#pragma acc %0' is not permitted within function '%1' because the latter "
"is attributed with '#pragma acc routine'">;
def err_acc_routine_static_local : Error<
"static local variable '%0' is not permitted within function '%1' because "
"the latter is attributed with '#pragma acc routine'">;
def note_acc_routine : Note<
"function '%0' attributed with '#pragma acc routine' here">;
} // end of OpenACC category
let CategoryName = "Related Result Type Issue" in {
...
...
clang/include/clang/Basic/OpenACCKinds.def
View file @
56252580
...
...
@@ -112,6 +112,9 @@
#ifndef OPENACC_PARALLEL_LOOP_CLAUSE
# define OPENACC_PARALLEL_LOOP_CLAUSE(Name)
#endif
#ifndef OPENACC_ROUTINE_CLAUSE
# define OPENACC_ROUTINE_CLAUSE(Name)
#endif
#ifndef OPENACC_UPDATE_PARENT
# define OPENACC_UPDATE_PARENT(Name)
#endif
...
...
@@ -133,6 +136,9 @@
#ifndef OPENACC_PARALLEL_LOOP_PARENT
# define OPENACC_PARALLEL_LOOP_PARENT(Name)
#endif
#ifndef OPENACC_ROUTINE_PARENT
# define OPENACC_ROUTINE_PARENT(Name)
#endif
#define OPENACC_ALIASED_CLAUSE(Def, Name, Class) \
Def(Name, Class) \
...
...
@@ -173,6 +179,7 @@ OPENACC_DIRECTIVE(data)
OPENACC_DIRECTIVE(parallel)
OPENACC_DIRECTIVE(loop)
OPENACC_DIRECTIVE_EXT(parallel_loop, "parallel loop")
OPENACC_DIRECTIVE(routine)
// Specifying and iterating OpenACC clauses, data attributes (DAs), data
// mapping attributes (DMAs), data sharing attributes (DSAs), and clause
...
...
@@ -407,6 +414,9 @@ OPENACC_PARALLEL_LOOP_CLAUSE(worker)
OPENACC_PARALLEL_LOOP_CLAUSE(vector)
OPENACC_PARALLEL_LOOP_CLAUSE(collapse)
// Explicit clauses allowed for OpenACC directive 'routine'.
OPENACC_ROUTINE_CLAUSE(seq)
// Parent directives allowed for 'update'.
OPENACC_UPDATE_PARENT(unknown)
OPENACC_UPDATE_PARENT(data)
...
...
@@ -440,6 +450,9 @@ OPENACC_LOOP_PARENT(parallel_loop)
OPENACC_PARALLEL_LOOP_PARENT(unknown)
OPENACC_PARALLEL_LOOP_PARENT(data)
// Parent directives allowed for 'routine'.
OPENACC_ROUTINE_PARENT(unknown)
#undef OPENACC_DIRECTIVE
#undef OPENACC_DIRECTIVE_EXT
#undef OPENACC_DMA
...
...
@@ -473,6 +486,7 @@ OPENACC_PARALLEL_LOOP_PARENT(data)
#undef OPENACC_PARALLEL_CLAUSE
#undef OPENACC_LOOP_CLAUSE
#undef OPENACC_PARALLEL_LOOP_CLAUSE
#undef OPENACC_ROUTINE_CLAUSE
#undef OPENACC_UPDATE_PARENT
#undef OPENACC_ENTER_DATA_PARENT
#undef OPENACC_EXIT_DATA_PARENT
...
...
@@ -480,6 +494,7 @@ OPENACC_PARALLEL_LOOP_PARENT(data)
#undef OPENACC_PARALLEL_PARENT
#undef OPENACC_LOOP_PARENT
#undef OPENACC_PARALLEL_LOOP_PARENT
#undef OPENACC_ROUTINE_PARENT
#undef OPENACC_ALIASED_CLAUSE
#undef OPENACC_CLAUSE_AND_DMA
#undef OPENACC_CLAUSE_AND_DSA_MAPPABLE
...
...
clang/include/clang/Parse/Parser.h
View file @
56252580
...
...
@@ -3373,12 +3373,16 @@ public:
/// Parses declarative OpenACC directives.
DeclGroupPtrTy
ParseOpenACCDeclarativeDirective
();
/// Parses
declarative or
executable
OpenACC
directive.
/// Parses
OpenACC
executable directive
s or constructs
.
///
/// \param StmtCtx The context in which we're parsing the directive.
StmtResult
ParseOpenACCDeclarativeOrExecutableDirective
(
ParsedStmtContext
StmtCtx
);
/// Parses clause of kind \a CKind for directive of a kind \a Kind.
StmtResult
ParseOpenACCExecutableDirective
(
ParsedStmtContext
StmtCtx
);
/// Parses clauses for directive of kind \a Kind.
///
/// \param DKind Kind of current directive.
void
ParseOpenACCClauses
(
OpenACCDirectiveKind
DKind
,
SmallVectorImpl
<
ACCClause
*>
&
Clauses
);
/// Parses clause of kind \a CKind for directive of kind \a Kind.
///
/// \param DKind Kind of current directive.
/// \param CKind Kind of current clause.
...
...
clang/include/clang/Sema/Sema.h
View file @
56252580
...
...
@@ -11254,14 +11254,25 @@ private:
void DestroyOpenACCDirectiveStack();
public:
/// Called on start of new data attribute block.
void StartOpenACCDABlock(OpenACCDirectiveKind RealDKind, SourceLocation Loc);
/// Start analysis of clauses.
/// Called at start of an OpenACC directive before its clauses. Returns true
/// in the case of an error.
bool StartOpenACCDirectiveAndAssociate(OpenACCDirectiveKind RealDKind,
SourceLocation Loc);
/// Called at start of a clause.
void StartOpenACCClause(OpenACCClauseKind K);
///
End analysis
of clause
s
.
///
Called at end
of
a
clause.
void EndOpenACCClause();
/// Called on end of data attribute block.
void EndOpenACCDABlock();
/// Called at start of an OpenACC directive's associated statement. Returns
/// true in the case of an error.
bool StartOpenACCAssociatedStatement(OpenACCDirectiveKind DKind,
ArrayRef<ACCClause *> Clauses,
SourceLocation StartLoc);
/// Called at end of an OpenACC directive's associated statement and before
/// the \c ActOn function for the directive. Returns true in the case of an
/// error.
bool EndOpenACCAssociatedStatement();
/// Called after the \c ActOn function for the directive.
void EndOpenACCDirectiveAndAssociate();
/// If the current region is an OpenACC loop region, record any loop control
/// variables assigned but not declared in \p Init, the init of the attached
...
...
@@ -11271,13 +11282,10 @@ public:
/// directive.
void ActOnOpenACCLoopBreakStatement(SourceLocation BreakLoc,
Scope *CurScope);
/// Check a function definition against any OpenACC restrictions (such as any
/// OpenACC routine directive).
void ActOnFunctionDefinitionForOpenACC(FunctionDecl *FD);
/// Start of OpenACC region.
bool ActOnOpenACCRegionStart(OpenACCDirectiveKind DKind,
ArrayRef<ACCClause *> Clauses,
SourceLocation StartLoc);
/// End of OpenACC region.
bool ActOnOpenACCRegionEnd();
StmtResult ActOnOpenACCExecutableDirective(
OpenACCDirectiveKind Kind, ArrayRef<ACCClause *> Clauses, Stmt *AStmt,
SourceLocation StartLoc, SourceLocation EndLoc);
...
...
@@ -11314,6 +11322,10 @@ public:
StmtResult ActOnOpenACCParallelLoopDirective(
ArrayRef<ACCClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
/// Called on well-formed '\#pragma acc routine'.
void ActOnOpenACCRoutineDirective(ArrayRef<ACCClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc, DeclGroupRef Decl);
ACCClause *ActOnOpenACCSingleExprClause(OpenACCClauseKind Kind,
Expr *Expr,
...
...
clang/lib/AST/AttrImpl.cpp
View file @
56252580
...
...
@@ -132,6 +132,32 @@ void OMPDeclareSimdDeclAttr::printPrettyPragma(
}
}
void
OMPDeclareTargetDeclAttr
::
printPretty
(
raw_ostream
&
OS
,
const
PrintingPolicy
&
Policy
)
const
{
// TODO: If this isn't an OpenACC translation, print exactly the way upstream
// prints it to avoid merge conflicts in tests. However, we need to come to
// terms with why inherited attributes should be printed as that seems to
// indicate they weren't specified in the original source. See related todo
// in DeclPrinter::VisitDeclContext.
OpenACCPrintKind
PrintMode
=
OpenACCPrint_OMP
;
if
(
getIsOpenACCTranslation
())
PrintMode
=
isInherited
()
?
OpenACCPrint_ACC
:
Policy
.
OpenACCPrint
;
switch
(
PrintMode
)
{
case
OpenACCPrint_ACC_OMP
:
OS
<<
"// "
;
LLVM_FALLTHROUGH
;
case
OpenACCPrint_OMP
:
case
OpenACCPrint_OMP_ACC
:
case
OpenACCPrint_OMP_HEAD
:
OS
<<
"#pragma omp declare target"
;
printPrettyPragma
(
OS
,
Policy
);
OS
<<
'\n'
;
break
;
case
OpenACCPrint_ACC
:
break
;
}
}
void
OMPDeclareTargetDeclAttr
::
printPrettyPragma
(
raw_ostream
&
OS
,
const
PrintingPolicy
&
Policy
)
const
{
// Use fake syntax because it is for testing and debugging purpose only.
...
...
@@ -197,4 +223,23 @@ void OMPDeclareVariantAttr::printPrettyPragma(
OS
<<
" match("
<<
traitInfos
<<
")"
;
}
void
ACCRoutineDeclAttr
::
printPretty
(
raw_ostream
&
OS
,
const
PrintingPolicy
&
Policy
)
const
{
if
(
isInherited
()
||
isImplicit
())
return
;
switch
(
Policy
.
OpenACCPrint
)
{
case
OpenACCPrint_OMP_ACC
:
OS
<<
"// "
;
LLVM_FALLTHROUGH
;
case
OpenACCPrint_ACC
:
case
OpenACCPrint_ACC_OMP
:
OS
<<
"#pragma acc routine "
<<
ConvertPartitioningTyToStr
(
getPartitioning
())
<<
"
\n
"
;
break
;
case
OpenACCPrint_OMP
:
case
OpenACCPrint_OMP_HEAD
:
break
;
}
}
#include
"clang/AST/AttrImpl.inc"
clang/lib/AST/DeclPrinter.cpp
View file @
56252580
...
...
@@ -488,8 +488,30 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
// Declare target attribute is special one, natural spelling for the pragma
// assumes "ending" construct so print it here.
if
(
D
->
hasAttr
<
OMPDeclareTargetDeclAttr
>
())
Out
<<
"#pragma omp end declare target
\n
"
;
if
(
OMPDeclareTargetDeclAttr
*
Attr
=
D
->
getAttr
<
OMPDeclareTargetDeclAttr
>
())
{
// TODO: If this isn't an OpenACC translation, print exactly the way
// upstream prints it to avoid merge conflicts in tests. However, we need
// to come to terms with why inherited attributes should be printed as
// that seems to indicate they weren't specified in the original source.
// See related todo in OMPDeclareTargetDeclAttr::printPretty.
OpenACCPrintKind
PrintMode
=
OpenACCPrint_OMP
;
if
(
Attr
->
getIsOpenACCTranslation
())
PrintMode
=
Attr
->
isInherited
()
?
OpenACCPrint_ACC
:
Policy
.
OpenACCPrint
;
switch
(
PrintMode
)
{
case
OpenACCPrint_ACC_OMP
:
Out
<<
"// "
;
LLVM_FALLTHROUGH
;
case
OpenACCPrint_OMP
:
case
OpenACCPrint_OMP_ACC
:
case
OpenACCPrint_OMP_HEAD
:
Out
<<
"#pragma omp end declare target
\n
"
;
break
;
case
OpenACCPrint_ACC
:
break
;
}
}
}
if
(
!
Decls
.
empty
())
...
...
clang/lib/Basic/OpenACCKinds.cpp
View file @
56252580
...
...
@@ -198,6 +198,8 @@ bool clang::isAllowedDAForDirective(OpenACCDirectiveKind DKind,
break
;
}
break
;
case
ACCD_routine
:
break
;
case
ACCD_unknown
:
llvm_unreachable
(
"unexpected unknown directive"
);
}
...
...
@@ -278,6 +280,8 @@ bool clang::isAllowedDAForDirective(OpenACCDirectiveKind DKind,
break
;
}
break
;
case
ACCD_routine
:
break
;
case
ACCD_unknown
:
llvm_unreachable
(
"unexpected unknown directive"
);
}
...
...
@@ -290,8 +294,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
switch
(
DKind
)
{
case
ACCD_update
:
switch
(
CKind
)
{
#define OPENACC_UPDATE_CLAUSE(Name) \
case ACCC_##Name: \
#define OPENACC_UPDATE_CLAUSE(Name)
\
case ACCC_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -300,8 +304,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_enter_data
:
switch
(
CKind
)
{
#define OPENACC_ENTER_DATA_CLAUSE(Name) \
case ACCC_##Name: \
#define OPENACC_ENTER_DATA_CLAUSE(Name)
\
case ACCC_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -310,8 +314,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_exit_data
:
switch
(
CKind
)
{
#define OPENACC_EXIT_DATA_CLAUSE(Name) \
case ACCC_##Name: \
#define OPENACC_EXIT_DATA_CLAUSE(Name)
\
case ACCC_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -320,8 +324,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_data
:
switch
(
CKind
)
{
#define OPENACC_DATA_CLAUSE(Name) \
case ACCC_##Name: \
#define OPENACC_DATA_CLAUSE(Name)
\
case ACCC_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -330,8 +334,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_parallel
:
switch
(
CKind
)
{
#define OPENACC_PARALLEL_CLAUSE(Name) \
case ACCC_##Name: \
#define OPENACC_PARALLEL_CLAUSE(Name)
\
case ACCC_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -340,8 +344,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_loop
:
switch
(
CKind
)
{
#define OPENACC_LOOP_CLAUSE(Name) \
case ACCC_##Name: \
#define OPENACC_LOOP_CLAUSE(Name)
\
case ACCC_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -350,8 +354,18 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_parallel_loop
:
switch
(
CKind
)
{
#define OPENACC_PARALLEL_LOOP_CLAUSE(Name) \
case ACCC_##Name: \
#define OPENACC_PARALLEL_LOOP_CLAUSE(Name) \
case ACCC_##Name: \
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
break
;
}
break
;
case
ACCD_routine
:
switch
(
CKind
)
{
#define OPENACC_ROUTINE_CLAUSE(Name) \
case ACCC_##Name: \
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -369,8 +383,8 @@ bool clang::isAllowedParentForDirective(OpenACCDirectiveKind DKind,
switch
(
DKind
)
{
case
ACCD_update
:
switch
(
ParentDKind
)
{
#define OPENACC_UPDATE_PARENT(Name) \
case ACCD_##Name: \
#define OPENACC_UPDATE_PARENT(Name)
\
case ACCD_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -379,8 +393,8 @@ bool clang::isAllowedParentForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_enter_data
:
switch
(
ParentDKind
)
{
#define OPENACC_ENTER_DATA_PARENT(Name) \
case ACCD_##Name: \
#define OPENACC_ENTER_DATA_PARENT(Name)
\
case ACCD_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -389,8 +403,8 @@ bool clang::isAllowedParentForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_exit_data
:
switch
(
ParentDKind
)
{
#define OPENACC_EXIT_DATA_PARENT(Name) \
case ACCD_##Name: \
#define OPENACC_EXIT_DATA_PARENT(Name)
\
case ACCD_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -399,8 +413,8 @@ bool clang::isAllowedParentForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_data
:
switch
(
ParentDKind
)
{
#define OPENACC_DATA_PARENT(Name) \
case ACCD_##Name: \
#define OPENACC_DATA_PARENT(Name)
\
case ACCD_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -409,8 +423,8 @@ bool clang::isAllowedParentForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_parallel
:
switch
(
ParentDKind
)
{
#define OPENACC_PARALLEL_PARENT(Name) \
case ACCD_##Name: \
#define OPENACC_PARALLEL_PARENT(Name)
\
case ACCD_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -419,8 +433,8 @@ bool clang::isAllowedParentForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_loop
:
switch
(
ParentDKind
)
{
#define OPENACC_LOOP_PARENT(Name) \
case ACCD_##Name: \
#define OPENACC_LOOP_PARENT(Name)
\
case ACCD_##Name:
\
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -429,8 +443,18 @@ bool clang::isAllowedParentForDirective(OpenACCDirectiveKind DKind,
break
;
case
ACCD_parallel_loop
:
switch
(
ParentDKind
)
{
#define OPENACC_PARALLEL_LOOP_PARENT(Name) \
case ACCD_##Name: \
#define OPENACC_PARALLEL_LOOP_PARENT(Name) \
case ACCD_##Name: \
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
break
;
}
break
;
case
ACCD_routine
:
switch
(
ParentDKind
)
{
#define OPENACC_ROUTINE_PARENT(Name) \
case ACCD_##Name: \
return true;
#include
"clang/Basic/OpenACCKinds.def"
default:
...
...
@@ -451,6 +475,7 @@ int clang::getOpenACCEffectiveDirectives(OpenACCDirectiveKind DKind) {
case
ACCD_data
:
case
ACCD_parallel
:
case
ACCD_loop
:
case
ACCD_routine
:
return
1
;
case
ACCD_parallel_loop
:
return
2
;
...
...
clang/lib/Frontend/Rewrite/RewriteOpenACC.cpp
View file @
56252580
...
...
@@ -218,6 +218,7 @@ public:
std
::
string
RewriteString
;
llvm
::
raw_string_ostream
RewriteStream
(
RewriteString
);
// Generate new text.
switch
(
OpenACCPrint
)
{
case
OpenACCPrint_ACC
:
case
OpenACCPrint_OMP_HEAD
:
...
...
@@ -374,6 +375,203 @@ public:
// associated statements separately.
return
DirectiveOnly
;
}
bool
VisitDecl
(
Decl
*
D
)
{
// TODO: There's a lot of logic in here that could probably be shared with
// VisitACCExecutableDirective by encapsulating into separate functions.
SourceManager
&
SM
=
Context
->
getSourceManager
();
const
LangOptions
&
LO
=
Context
->
getLangOpts
();
// Is this a function prototype or definition?
FunctionDecl
*
FD
=
dyn_cast
<
FunctionDecl
>
(
D
);
if
(
!
FD
)
return
true
;
// Is there an OpenACC routine directive to rewrite?
ACCRoutineDeclAttr
*
ACCAttr
=
FD
->
getAttr
<
ACCRoutineDeclAttr
>
();
OMPDeclareTargetDeclAttr
*
OMPAttr
=
FD
->
getAttr
<
OMPDeclareTargetDeclAttr
>
();
if
(
!
ACCAttr
||
!
OMPAttr
||
!
OMPAttr
->
getIsOpenACCTranslation
())
return
true
;
assert
(
ACCAttr
->
isInherited
()
==
OMPAttr
->
isInherited
()
&&
"expected OpenACC attribute and its OpenMP translation to either "
"both be inherited or neither"
);
if
(
ACCAttr
->
isInherited
())