[flang][openacc] OpenACC 3.0 parser

Summary:
This patch introduce the parser for OpenACC 3.0 in Flang. It uses the same TableGen mechanism
than OpenMP.

Reviewers: nvdatian, sscalpone, tskeith, klausler, ichoyjx, jdoerfert, DavidTruby

Reviewed By: klausler

Subscribers: MaskRay, SouraVX, mgorny, hiraditya, jfb, sstefan1, llvm-commits

Tags: #llvm, #flang

Differential Revision: https://reviews.llvm.org/D83649
This commit is contained in:
Valentin Clement
2020-07-14 14:28:34 -04:00
committed by clementval
parent 1254f6d531
commit 0a90ffa772
28 changed files with 1884 additions and 18 deletions

View File

@@ -1777,6 +1777,375 @@ public:
}
Walk(std::get<Name>(x.t));
}
// OpenACC Directives & Clauses
void Unparse(const AccAtomicCapture &x) {
BeginOpenACC();
Word("!$ACC CAPTURE");
Put("\n");
EndOpenACC();
Walk(std::get<AccAtomicCapture::Stmt1>(x.t));
Put("\n");
Walk(std::get<AccAtomicCapture::Stmt2>(x.t));
BeginOpenACC();
Word("!$ACC END ATOMIC\n");
EndOpenACC();
}
void Unparse(const AccAtomicRead &x) {
BeginOpenACC();
Word("!$ACC ATOMIC READ");
Put("\n");
EndOpenACC();
Walk(std::get<Statement<AssignmentStmt>>(x.t));
BeginOpenACC();
Walk(std::get<std::optional<AccEndAtomic>>(x.t), "!$ACC END ATOMIC\n");
EndOpenACC();
}
void Unparse(const AccAtomicWrite &x) {
BeginOpenACC();
Word("!$ACC ATOMIC WRITE");
Put("\n");
EndOpenACC();
Walk(std::get<Statement<AssignmentStmt>>(x.t));
BeginOpenACC();
Walk(std::get<std::optional<AccEndAtomic>>(x.t), "!$ACC END ATOMIC\n");
EndOpenACC();
}
void Unparse(const AccAtomicUpdate &x) {
BeginOpenACC();
Word("!$ACC ATOMIC UPDATE");
Put("\n");
EndOpenACC();
Walk(std::get<Statement<AssignmentStmt>>(x.t));
BeginOpenACC();
Walk(std::get<std::optional<AccEndAtomic>>(x.t), "!$ACC END ATOMIC\n");
EndOpenACC();
}
void Unparse(const llvm::acc::Directive &x) {
Word(llvm::acc::getOpenACCDirectiveName(x).str());
}
void Before(const AccClause::Auto &) { Word("AUTO"); }
void Before(const AccClause::Capture &) { Word("CAPTURE"); }
void Before(const AccClause::Finalize &) { Word("FINALIZE"); }
void Before(const AccClause::IfPresent &) { Word("IF_PRESENT"); }
void Before(const AccClause::Independent &) { Word("INDEPENDENT"); }
void Before(const AccClause::NoHost &) { Word("NOHOST"); }
void Before(const AccClause::Read &) { Word("READ"); }
void Before(const AccClause::Seq &) { Word("SEQ"); }
void Before(const AccClause::Write &) { Word("WRITE"); }
void Before(const AccClause::Unknown &) { Word("UNKNOWN"); }
void Unparse(const AccClause::Attach &x) {
Word("ATTACH");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Bind &x) {
Word("BIND");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Collapse &x) {
Word("COLLAPSE");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Copy &x) {
Word("COPY");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Copyin &x) {
Word("COPYIN");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Copyout &x) {
Word("COPYOUT");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Create &x) {
Word("CREATE");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Default &x) {
Word("DEFAULT");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Delete &x) {
Word("DELETE");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Detach &x) {
Word("DETACH");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Device &x) {
Word("DEVICE");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::DevicePtr &x) {
Word("DEVICEPTR");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::DeviceResident &x) {
Word("DEVICE_RESIDENT");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::FirstPrivate &x) {
Word("FIRSTPRIVATE");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Host &x) {
Word("HOST");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::If &x) {
Word("IF");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Link &x) {
Word("LINK");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::NumGangs &x) {
Word("NUM_GANGS");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::NumWorkers &x) {
Word("NUM_WORKERS");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Present &x) {
Word("PRESENT");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Private &x) {
Word("PRIVATE");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Reduction &x) {
Word("REDUCTION");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::VectorLength &x) {
Word("VECTOR_LENGTH");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Async &x) {
Word("ASYNC");
Walk("(", x.v, ")");
}
void Unparse(const AccClause::DefaultAsync &x) {
Word("DEFAULT_ASYNC");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::DeviceNum &x) {
Word("DEVICE_NUM");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Gang &x) {
Word("GANG");
Walk("(", x.v, ")");
}
void Unparse(const AccClause::NoCreate &x) {
Word("NO_CREATE");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::UseDevice &x) {
Word("USE_DEVICE");
Put("(");
Walk(x.v);
Put(")");
}
void Unparse(const AccClause::Self &x) {
Word("SELF");
Walk("(", x.v, ")");
}
void Unparse(const AccClause::Vector &x) {
Word("VECTOR");
Walk("(", x.v, ")");
}
void Unparse(const AccClause::Wait &x) {
Word("WAIT");
Walk("(", x.v, ")");
}
void Unparse(const AccClause::Worker &x) {
Word("WORKER");
Walk("(", x.v, ")");
}
void Unparse(const AccClause::DeviceType &x) {
Word("DEVICE_TYPE");
Put("(");
if (x.v.has_value())
Walk(x.v);
else
Put("*");
Put(")");
}
void Unparse(const AccObjectListWithModifier &x) {
Walk(std::get<std::optional<AccDataModifier>>(x.t), ":");
Walk(std::get<AccObjectList>(x.t));
}
void Unparse(const AccDataModifier::Modifier &x) {
Word(AccDataModifier::EnumToString(x));
}
void Unparse(const AccDefaultClause &x) {
switch (x.v) {
case AccDefaultClause::Arg::None:
Put("NONE");
break;
case AccDefaultClause::Arg::Present:
Put("PRESENT");
break;
}
}
void Unparse(const AccClauseList &x) { Walk(" ", x.v, " "); }
void Unparse(const AccGangArgument &x) {
Walk("NUM:", std::get<std::optional<ScalarIntExpr>>(x.t));
Walk(", STATIC:", std::get<std::optional<AccSizeExpr>>(x.t));
}
void Unparse(const OpenACCBlockConstruct &x) {
BeginOpenACC();
Word("!$ACC ");
Walk(std::get<AccBeginBlockDirective>(x.t));
Put("\n");
EndOpenACC();
Walk(std::get<Block>(x.t), "");
BeginOpenACC();
Word("!$ACC END ");
Walk(std::get<AccEndBlockDirective>(x.t));
Put("\n");
EndOpenACC();
}
void Unparse(const OpenACCLoopConstruct &x) {
BeginOpenACC();
Word("!$ACC ");
Walk(std::get<AccBeginLoopDirective>(x.t));
Put("\n");
EndOpenACC();
Walk(std::get<std::optional<DoConstruct>>(x.t));
}
void Unparse(const AccBeginLoopDirective &x) {
Walk(std::get<AccLoopDirective>(x.t));
Walk(std::get<AccClauseList>(x.t));
}
void Unparse(const OpenACCStandaloneConstruct &x) {
BeginOpenACC();
Word("!$ACC ");
Walk(std::get<AccStandaloneDirective>(x.t));
Walk(std::get<AccClauseList>(x.t));
Put("\n");
EndOpenACC();
}
void Unparse(const OpenACCStandaloneDeclarativeConstruct &x) {
BeginOpenACC();
Word("!$ACC ");
Walk(std::get<AccDeclarativeDirective>(x.t));
Walk(std::get<AccClauseList>(x.t));
Put("\n");
EndOpenACC();
}
void Unparse(const OpenACCCombinedConstruct &x) {
BeginOpenACC();
Word("!$ACC ");
Walk(std::get<AccBeginCombinedDirective>(x.t));
Put("\n");
EndOpenACC();
Walk(std::get<Block>(x.t), "");
BeginOpenACC();
Word("!$ACC END ");
Walk(std::get<std::optional<AccEndCombinedDirective>>(x.t));
Put("\n");
EndOpenACC();
}
void Unparse(const OpenACCRoutineConstruct &x) {
BeginOpenACC();
Word("!$ACC ROUTINE");
Walk("(", std::get<std::optional<Name>>(x.t), ")");
Walk(std::get<AccClauseList>(x.t));
Put("\n");
EndOpenACC();
}
void Unparse(const AccObject &x) {
std::visit(common::visitors{
[&](const Designator &y) { Walk(y); },
[&](const Name &y) { Put("/"), Walk(y), Put("/"); },
},
x.u);
}
void Unparse(const AccObjectList &x) { Walk(x.v, ","); }
void Unparse(const AccObjectListWithReduction &x) {
Walk(std::get<AccReductionOperator>(x.t));
Put(":");
Walk(std::get<AccObjectList>(x.t));
}
void Unparse(const OpenACCCacheConstruct &x) {
BeginOpenACC();
Word("!$ACC ");
Word("CACHE(");
Walk(std::get<AccObjectListWithModifier>(x.t));
Put(")");
Put("\n");
EndOpenACC();
}
void Unparse(const OpenACCWaitConstruct &x) {
BeginOpenACC();
Word("!$ACC ");
Word("WAIT(");
Walk(std::get<std::optional<AccWaitArgument>>(x.t));
Walk(std::get<AccClauseList>(x.t));
Put(")");
Put("\n");
EndOpenACC();
}
// OpenMP Clauses & Directives
void Unparse(const OmpObject &x) {
std::visit(common::visitors{
@@ -2522,6 +2891,8 @@ private:
}
void BeginOpenMP() { openmpDirective_ = true; }
void EndOpenMP() { openmpDirective_ = false; }
void BeginOpenACC() { openaccDirective_ = true; }
void EndOpenACC() { openaccDirective_ = false; }
// Call back to the traversal framework.
template <typename T> void Walk(const T &x) {
@@ -2591,6 +2962,7 @@ private:
std::set<CharBlock> structureComponents_;
Encoding encoding_{Encoding::UTF_8};
bool capitalizeKeywords_{true};
bool openaccDirective_{false};
bool openmpDirective_{false};
bool backslashEscapes_{false};
preStatementType *preStatement_{nullptr};
@@ -2599,7 +2971,7 @@ private:
void UnparseVisitor::Put(char ch) {
int sav = indent_;
if (openmpDirective_) {
if (openmpDirective_ || openaccDirective_) {
indent_ = 0;
}
if (column_ <= 1) {
@@ -2620,13 +2992,16 @@ void UnparseVisitor::Put(char ch) {
if (openmpDirective_) {
out_ << "!$OMP&";
column_ = 8;
} else if (openaccDirective_) {
out_ << "!$ACC&";
column_ = 8;
} else {
out_ << '&';
column_ = indent_ + 3;
}
}
out_ << ch;
if (openmpDirective_) {
if (openmpDirective_ || openaccDirective_) {
indent_ = sav;
}
}