xref: /llvm-project/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp (revision adeff9f63a24f60b0bf240bf13e40bbf7c1dd0e8)
17ccacaf4SAndrzej Warzynski //===-- examples/flang-omp-report-plugin/flang-omp-report-visitor.cpp -----===//
27ccacaf4SAndrzej Warzynski //
37ccacaf4SAndrzej Warzynski // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47ccacaf4SAndrzej Warzynski // See https://llvm.org/LICENSE.txt for license information.
57ccacaf4SAndrzej Warzynski // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67ccacaf4SAndrzej Warzynski //
77ccacaf4SAndrzej Warzynski //===----------------------------------------------------------------------===//
87ccacaf4SAndrzej Warzynski 
97ccacaf4SAndrzej Warzynski #include "FlangOmpReportVisitor.h"
107ccacaf4SAndrzej Warzynski #include "llvm/ADT/StringExtras.h"
1133faa828SKrzysztof Parzyszek #include "llvm/Frontend/OpenMP/OMP.h"
127ccacaf4SAndrzej Warzynski 
137ccacaf4SAndrzej Warzynski namespace Fortran {
147ccacaf4SAndrzej Warzynski namespace parser {
157ccacaf4SAndrzej Warzynski bool operator<(const ClauseInfo &a, const ClauseInfo &b) {
167ccacaf4SAndrzej Warzynski   return a.clause < b.clause;
177ccacaf4SAndrzej Warzynski }
187ccacaf4SAndrzej Warzynski bool operator==(const ClauseInfo &a, const ClauseInfo &b) {
197ccacaf4SAndrzej Warzynski   return a.clause == b.clause && a.clauseDetails == b.clauseDetails;
207ccacaf4SAndrzej Warzynski }
217ccacaf4SAndrzej Warzynski bool operator!=(const ClauseInfo &a, const ClauseInfo &b) { return !(a == b); }
227ccacaf4SAndrzej Warzynski 
237ccacaf4SAndrzej Warzynski bool operator==(const LogRecord &a, const LogRecord &b) {
247ccacaf4SAndrzej Warzynski   return a.file == b.file && a.line == b.line && a.construct == b.construct &&
257ccacaf4SAndrzej Warzynski       a.clauses == b.clauses;
267ccacaf4SAndrzej Warzynski }
277ccacaf4SAndrzej Warzynski bool operator!=(const LogRecord &a, const LogRecord &b) { return !(a == b); }
287ccacaf4SAndrzej Warzynski 
297ccacaf4SAndrzej Warzynski std::string OpenMPCounterVisitor::normalize_construct_name(std::string s) {
307ccacaf4SAndrzej Warzynski   std::transform(s.begin(), s.end(), s.begin(),
317ccacaf4SAndrzej Warzynski       [](unsigned char c) { return llvm::toLower(c); });
327ccacaf4SAndrzej Warzynski   return s;
337ccacaf4SAndrzej Warzynski }
347ccacaf4SAndrzej Warzynski ClauseInfo OpenMPCounterVisitor::normalize_clause_name(
357ccacaf4SAndrzej Warzynski     const llvm::StringRef s) {
367ccacaf4SAndrzej Warzynski   std::size_t start = s.find('(');
377ccacaf4SAndrzej Warzynski   std::size_t end = s.find(')');
387ccacaf4SAndrzej Warzynski   std::string clauseName;
397ccacaf4SAndrzej Warzynski   if (start != llvm::StringRef::npos && end != llvm::StringRef::npos) {
407ccacaf4SAndrzej Warzynski     clauseName = s.substr(0, start);
417ccacaf4SAndrzej Warzynski     clauseDetails = s.substr(start + 1, end - start - 1);
427ccacaf4SAndrzej Warzynski   } else {
437ccacaf4SAndrzej Warzynski     clauseName = s;
447ccacaf4SAndrzej Warzynski   }
457ccacaf4SAndrzej Warzynski   std::transform(clauseName.begin(), clauseName.end(), clauseName.begin(),
467ccacaf4SAndrzej Warzynski       [](unsigned char c) { return llvm::toLower(c); });
477ccacaf4SAndrzej Warzynski   std::transform(clauseDetails.begin(), clauseDetails.end(),
487ccacaf4SAndrzej Warzynski       clauseDetails.begin(), [](unsigned char c) { return llvm::toLower(c); });
497ccacaf4SAndrzej Warzynski   return ClauseInfo{clauseName, clauseDetails};
507ccacaf4SAndrzej Warzynski }
517ccacaf4SAndrzej Warzynski SourcePosition OpenMPCounterVisitor::getLocation(const OmpWrapperType &w) {
527ccacaf4SAndrzej Warzynski   if (auto *val = std::get_if<const OpenMPConstruct *>(&w)) {
537ccacaf4SAndrzej Warzynski     const OpenMPConstruct *o{*val};
547ccacaf4SAndrzej Warzynski     return getLocation(*o);
557ccacaf4SAndrzej Warzynski   }
567ccacaf4SAndrzej Warzynski   return getLocation(*std::get<const OpenMPDeclarativeConstruct *>(w));
577ccacaf4SAndrzej Warzynski }
587ccacaf4SAndrzej Warzynski SourcePosition OpenMPCounterVisitor::getLocation(
597ccacaf4SAndrzej Warzynski     const OpenMPDeclarativeConstruct &c) {
607ccacaf4SAndrzej Warzynski   return std::visit(
617ccacaf4SAndrzej Warzynski       [&](const auto &o) -> SourcePosition {
627ccacaf4SAndrzej Warzynski         return parsing->allCooked().GetSourcePositionRange(o.source)->first;
637ccacaf4SAndrzej Warzynski       },
647ccacaf4SAndrzej Warzynski       c.u);
657ccacaf4SAndrzej Warzynski }
667ccacaf4SAndrzej Warzynski SourcePosition OpenMPCounterVisitor::getLocation(const OpenMPConstruct &c) {
677ccacaf4SAndrzej Warzynski   return std::visit(
687ccacaf4SAndrzej Warzynski       Fortran::common::visitors{
697ccacaf4SAndrzej Warzynski           [&](const OpenMPStandaloneConstruct &c) -> SourcePosition {
707ccacaf4SAndrzej Warzynski             return parsing->allCooked().GetSourcePositionRange(c.source)->first;
717ccacaf4SAndrzej Warzynski           },
727ccacaf4SAndrzej Warzynski           // OpenMPSectionsConstruct, OpenMPLoopConstruct,
737ccacaf4SAndrzej Warzynski           // OpenMPBlockConstruct, OpenMPCriticalConstruct Get the source from
747ccacaf4SAndrzej Warzynski           // the directive field.
757ccacaf4SAndrzej Warzynski           [&](const auto &c) -> SourcePosition {
767ccacaf4SAndrzej Warzynski             const CharBlock &source{std::get<0>(c.t).source};
777ccacaf4SAndrzej Warzynski             return (parsing->allCooked().GetSourcePositionRange(source))->first;
787ccacaf4SAndrzej Warzynski           },
797ccacaf4SAndrzej Warzynski           [&](const OpenMPAtomicConstruct &c) -> SourcePosition {
807ccacaf4SAndrzej Warzynski             return std::visit(
817ccacaf4SAndrzej Warzynski                 [&](const auto &o) -> SourcePosition {
827ccacaf4SAndrzej Warzynski                   const CharBlock &source{std::get<Verbatim>(o.t).source};
837ccacaf4SAndrzej Warzynski                   return parsing->allCooked()
847ccacaf4SAndrzej Warzynski                       .GetSourcePositionRange(source)
857ccacaf4SAndrzej Warzynski                       ->first;
867ccacaf4SAndrzej Warzynski                 },
877ccacaf4SAndrzej Warzynski                 c.u);
887ccacaf4SAndrzej Warzynski           },
89ae1623b3SShraiysh Vaishay           [&](const OpenMPSectionConstruct &c) -> SourcePosition {
90ae1623b3SShraiysh Vaishay             const CharBlock &source{c.source};
91ae1623b3SShraiysh Vaishay             return (parsing->allCooked().GetSourcePositionRange(source))->first;
92ae1623b3SShraiysh Vaishay           },
93df859f90SKrzysztof Parzyszek           [&](const OpenMPUtilityConstruct &c) -> SourcePosition {
94df859f90SKrzysztof Parzyszek             const CharBlock &source{c.source};
95df859f90SKrzysztof Parzyszek             return (parsing->allCooked().GetSourcePositionRange(source))->first;
96df859f90SKrzysztof Parzyszek           },
977ccacaf4SAndrzej Warzynski       },
987ccacaf4SAndrzej Warzynski       c.u);
997ccacaf4SAndrzej Warzynski }
1007ccacaf4SAndrzej Warzynski 
1017ccacaf4SAndrzej Warzynski std::string OpenMPCounterVisitor::getName(const OmpWrapperType &w) {
1027ccacaf4SAndrzej Warzynski   if (auto *val = std::get_if<const OpenMPConstruct *>(&w)) {
1037ccacaf4SAndrzej Warzynski     const OpenMPConstruct *o{*val};
1047ccacaf4SAndrzej Warzynski     return getName(*o);
1057ccacaf4SAndrzej Warzynski   }
1067ccacaf4SAndrzej Warzynski   return getName(*std::get<const OpenMPDeclarativeConstruct *>(w));
1077ccacaf4SAndrzej Warzynski }
1087ccacaf4SAndrzej Warzynski std::string OpenMPCounterVisitor::getName(const OpenMPDeclarativeConstruct &c) {
109*adeff9f6SKrzysztof Parzyszek   return std::visit( //
110*adeff9f6SKrzysztof Parzyszek       Fortran::common::visitors{
111*adeff9f6SKrzysztof Parzyszek           [&](const OpenMPUtilityConstruct &o) -> std::string {
112*adeff9f6SKrzysztof Parzyszek             const CharBlock &source{o.source};
113*adeff9f6SKrzysztof Parzyszek             return normalize_construct_name(source.ToString());
114*adeff9f6SKrzysztof Parzyszek           },
1157ccacaf4SAndrzej Warzynski           [&](const auto &o) -> std::string {
1167ccacaf4SAndrzej Warzynski             const CharBlock &source{std::get<Verbatim>(o.t).source};
1177ccacaf4SAndrzej Warzynski             return normalize_construct_name(source.ToString());
1187ccacaf4SAndrzej Warzynski           },
119*adeff9f6SKrzysztof Parzyszek       },
1207ccacaf4SAndrzej Warzynski       c.u);
1217ccacaf4SAndrzej Warzynski }
1227ccacaf4SAndrzej Warzynski std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
1237ccacaf4SAndrzej Warzynski   return std::visit(
1247ccacaf4SAndrzej Warzynski       Fortran::common::visitors{
1257ccacaf4SAndrzej Warzynski           [&](const OpenMPStandaloneConstruct &c) -> std::string {
1267ccacaf4SAndrzej Warzynski             return std::visit(
1277ccacaf4SAndrzej Warzynski                 [&](const auto &c) {
1287ccacaf4SAndrzej Warzynski                   // Get source from the directive or verbatim fields
1297ccacaf4SAndrzej Warzynski                   const CharBlock &source{std::get<0>(c.t).source};
1307ccacaf4SAndrzej Warzynski                   return normalize_construct_name(source.ToString());
1317ccacaf4SAndrzej Warzynski                 },
1327ccacaf4SAndrzej Warzynski                 c.u);
1337ccacaf4SAndrzej Warzynski           },
1347ccacaf4SAndrzej Warzynski           [&](const OpenMPExecutableAllocate &c) -> std::string {
1357ccacaf4SAndrzej Warzynski             const CharBlock &source{std::get<0>(c.t).source};
1367ccacaf4SAndrzej Warzynski             return normalize_construct_name(source.ToString());
1377ccacaf4SAndrzej Warzynski           },
1387ccacaf4SAndrzej Warzynski           [&](const OpenMPDeclarativeAllocate &c) -> std::string {
1397ccacaf4SAndrzej Warzynski             const CharBlock &source{std::get<0>(c.t).source};
1407ccacaf4SAndrzej Warzynski             return normalize_construct_name(source.ToString());
1417ccacaf4SAndrzej Warzynski           },
1426311ab21SEthan Luis McDonough           [&](const OpenMPAllocatorsConstruct &c) -> std::string {
1436311ab21SEthan Luis McDonough             const CharBlock &source{std::get<0>(c.t).source};
1446311ab21SEthan Luis McDonough             return normalize_construct_name(source.ToString());
1456311ab21SEthan Luis McDonough           },
1467ccacaf4SAndrzej Warzynski           [&](const OpenMPAtomicConstruct &c) -> std::string {
1477ccacaf4SAndrzej Warzynski             return std::visit(
1487ccacaf4SAndrzej Warzynski                 [&](const auto &c) {
1497ccacaf4SAndrzej Warzynski                   // Get source from the verbatim fields
1507ccacaf4SAndrzej Warzynski                   const CharBlock &source{std::get<Verbatim>(c.t).source};
1517ccacaf4SAndrzej Warzynski                   return "atomic-" +
1527ccacaf4SAndrzej Warzynski                       normalize_construct_name(source.ToString());
1537ccacaf4SAndrzej Warzynski                 },
1547ccacaf4SAndrzej Warzynski                 c.u);
1557ccacaf4SAndrzej Warzynski           },
156df859f90SKrzysztof Parzyszek           [&](const OpenMPUtilityConstruct &c) -> std::string {
157df859f90SKrzysztof Parzyszek             const CharBlock &source{c.source};
15875e6d0ebSMats Petersson             return normalize_construct_name(source.ToString());
15975e6d0ebSMats Petersson           },
160ae1623b3SShraiysh Vaishay           [&](const OpenMPSectionConstruct &c) -> std::string {
161ae1623b3SShraiysh Vaishay             return "section";
162ae1623b3SShraiysh Vaishay           },
1637ccacaf4SAndrzej Warzynski           // OpenMPSectionsConstruct, OpenMPLoopConstruct,
1647ccacaf4SAndrzej Warzynski           // OpenMPBlockConstruct, OpenMPCriticalConstruct Get the source from
1657ccacaf4SAndrzej Warzynski           // the directive field of the begin directive or from the verbatim
1667ccacaf4SAndrzej Warzynski           // field of the begin directive in Critical
1677ccacaf4SAndrzej Warzynski           [&](const auto &c) -> std::string {
1687ccacaf4SAndrzej Warzynski             const CharBlock &source{std::get<0>(std::get<0>(c.t).t).source};
1697ccacaf4SAndrzej Warzynski             return normalize_construct_name(source.ToString());
1707ccacaf4SAndrzej Warzynski           },
1717ccacaf4SAndrzej Warzynski       },
1727ccacaf4SAndrzej Warzynski       c.u);
1737ccacaf4SAndrzej Warzynski }
1747ccacaf4SAndrzej Warzynski 
1757ccacaf4SAndrzej Warzynski bool OpenMPCounterVisitor::Pre(const OpenMPDeclarativeConstruct &c) {
1767ccacaf4SAndrzej Warzynski   OmpWrapperType *ow{new OmpWrapperType(&c)};
1777ccacaf4SAndrzej Warzynski   ompWrapperStack.push_back(ow);
1787ccacaf4SAndrzej Warzynski   return true;
1797ccacaf4SAndrzej Warzynski }
1807ccacaf4SAndrzej Warzynski bool OpenMPCounterVisitor::Pre(const OpenMPConstruct &c) {
1817ccacaf4SAndrzej Warzynski   OmpWrapperType *ow{new OmpWrapperType(&c)};
1827ccacaf4SAndrzej Warzynski   ompWrapperStack.push_back(ow);
1837ccacaf4SAndrzej Warzynski   return true;
1847ccacaf4SAndrzej Warzynski }
1857ccacaf4SAndrzej Warzynski 
1867ccacaf4SAndrzej Warzynski void OpenMPCounterVisitor::Post(const OpenMPDeclarativeConstruct &) {
1877ccacaf4SAndrzej Warzynski   PostConstructsCommon();
1887ccacaf4SAndrzej Warzynski }
1897ccacaf4SAndrzej Warzynski void OpenMPCounterVisitor::Post(const OpenMPConstruct &) {
1907ccacaf4SAndrzej Warzynski   PostConstructsCommon();
1917ccacaf4SAndrzej Warzynski }
1927ccacaf4SAndrzej Warzynski void OpenMPCounterVisitor::PostConstructsCommon() {
1937ccacaf4SAndrzej Warzynski   OmpWrapperType *curConstruct = ompWrapperStack.back();
1947ccacaf4SAndrzej Warzynski   std::sort(
1957ccacaf4SAndrzej Warzynski       clauseStrings[curConstruct].begin(), clauseStrings[curConstruct].end());
1967ccacaf4SAndrzej Warzynski 
1977ccacaf4SAndrzej Warzynski   SourcePosition s{getLocation(*curConstruct)};
198e12ffe6aSPeter Klausler   LogRecord r{
199e12ffe6aSPeter Klausler       s.path, s.line, getName(*curConstruct), clauseStrings[curConstruct]};
2007ccacaf4SAndrzej Warzynski   constructClauses.push_back(r);
2017ccacaf4SAndrzej Warzynski 
2027ccacaf4SAndrzej Warzynski   auto it = clauseStrings.find(curConstruct);
2037ccacaf4SAndrzej Warzynski   clauseStrings.erase(it);
2047ccacaf4SAndrzej Warzynski   ompWrapperStack.pop_back();
2057ccacaf4SAndrzej Warzynski   delete curConstruct;
2067ccacaf4SAndrzej Warzynski }
2077ccacaf4SAndrzej Warzynski 
208608f4ae1SKrzysztof Parzyszek void OpenMPCounterVisitor::Post(const OmpProcBindClause::AffinityPolicy &c) {
209629a29caSPeter Klausler   clauseDetails +=
210629a29caSPeter Klausler       "type=" + std::string{OmpProcBindClause::EnumToString(c)} + ";";
2117ccacaf4SAndrzej Warzynski }
212608f4ae1SKrzysztof Parzyszek void OpenMPCounterVisitor::Post(
213608f4ae1SKrzysztof Parzyszek     const OmpDefaultClause::DataSharingAttribute &c) {
214629a29caSPeter Klausler   clauseDetails +=
215629a29caSPeter Klausler       "type=" + std::string{OmpDefaultClause::EnumToString(c)} + ";";
2167ccacaf4SAndrzej Warzynski }
217608f4ae1SKrzysztof Parzyszek void OpenMPCounterVisitor::Post(
218608f4ae1SKrzysztof Parzyszek     const OmpDeviceTypeClause::DeviceTypeDescription &c) {
219849c4402SAkash Banerjee   clauseDetails +=
220849c4402SAkash Banerjee       "type=" + std::string{OmpDeviceTypeClause::EnumToString(c)} + ";";
221849c4402SAkash Banerjee }
2227ccacaf4SAndrzej Warzynski void OpenMPCounterVisitor::Post(
2237ccacaf4SAndrzej Warzynski     const OmpDefaultmapClause::ImplicitBehavior &c) {
2247ccacaf4SAndrzej Warzynski   clauseDetails +=
225629a29caSPeter Klausler       "implicit_behavior=" + std::string{OmpDefaultmapClause::EnumToString(c)} +
226629a29caSPeter Klausler       ";";
2277ccacaf4SAndrzej Warzynski }
2284fc1141eSKrzysztof Parzyszek void OpenMPCounterVisitor::Post(const OmpVariableCategory::Value &c) {
2297ccacaf4SAndrzej Warzynski   clauseDetails +=
2304fc1141eSKrzysztof Parzyszek       "variable_category=" + std::string{OmpVariableCategory::EnumToString(c)} +
231629a29caSPeter Klausler       ";";
2327ccacaf4SAndrzej Warzynski }
233e79cd246SKrzysztof Parzyszek void OpenMPCounterVisitor::Post(const OmpChunkModifier::Value &c) {
234745f6fcdSPeter Klausler   clauseDetails +=
235e79cd246SKrzysztof Parzyszek       "modifier=" + std::string{OmpChunkModifier::EnumToString(c)} + ";";
2367ccacaf4SAndrzej Warzynski }
237cfd67c21SKrzysztof Parzyszek void OpenMPCounterVisitor::Post(const OmpLinearModifier::Value &c) {
238629a29caSPeter Klausler   clauseDetails +=
239629a29caSPeter Klausler       "modifier=" + std::string{OmpLinearModifier::EnumToString(c)} + ";";
2407ccacaf4SAndrzej Warzynski }
241e79cd246SKrzysztof Parzyszek void OpenMPCounterVisitor::Post(const OmpOrderingModifier::Value &c) {
242e79cd246SKrzysztof Parzyszek   clauseDetails +=
243e79cd246SKrzysztof Parzyszek       "modifier=" + std::string{OmpOrderingModifier::EnumToString(c)} + ";";
244e79cd246SKrzysztof Parzyszek }
245cfd67c21SKrzysztof Parzyszek void OpenMPCounterVisitor::Post(const OmpTaskDependenceType::Value &c) {
246629a29caSPeter Klausler   clauseDetails +=
24709a4bcf1SKrzysztof Parzyszek       "type=" + std::string{OmpTaskDependenceType::EnumToString(c)} + ";";
2487ccacaf4SAndrzej Warzynski }
24952755ac2SKrzysztof Parzyszek void OpenMPCounterVisitor::Post(const OmpMapType::Value &c) {
25052755ac2SKrzysztof Parzyszek   clauseDetails += "type=" + std::string{OmpMapType::EnumToString(c)} + ";";
2517ccacaf4SAndrzej Warzynski }
252e79cd246SKrzysztof Parzyszek void OpenMPCounterVisitor::Post(const OmpScheduleClause::Kind &c) {
253629a29caSPeter Klausler   clauseDetails +=
254629a29caSPeter Klausler       "type=" + std::string{OmpScheduleClause::EnumToString(c)} + ";";
2557ccacaf4SAndrzej Warzynski }
25633faa828SKrzysztof Parzyszek void OpenMPCounterVisitor::Post(const OmpDirectiveNameModifier &c) {
257629a29caSPeter Klausler   clauseDetails +=
25833faa828SKrzysztof Parzyszek       "name_modifier=" + llvm::omp::getOpenMPDirectiveName(c.v).str() + ";";
2597ccacaf4SAndrzej Warzynski }
2607ccacaf4SAndrzej Warzynski void OpenMPCounterVisitor::Post(const OmpCancelType::Type &c) {
261629a29caSPeter Klausler   clauseDetails += "type=" + std::string{OmpCancelType::EnumToString(c)} + ";";
2627ccacaf4SAndrzej Warzynski }
2637ccacaf4SAndrzej Warzynski void OpenMPCounterVisitor::Post(const OmpClause &c) {
2647ccacaf4SAndrzej Warzynski   PostClauseCommon(normalize_clause_name(c.source.ToString()));
2657ccacaf4SAndrzej Warzynski   clauseDetails.clear();
2667ccacaf4SAndrzej Warzynski }
2677ccacaf4SAndrzej Warzynski void OpenMPCounterVisitor::PostClauseCommon(const ClauseInfo &ci) {
2687ccacaf4SAndrzej Warzynski   assert(
2697ccacaf4SAndrzej Warzynski       !ompWrapperStack.empty() && "Construct should be visited before clause");
2707ccacaf4SAndrzej Warzynski   clauseStrings[ompWrapperStack.back()].push_back(ci);
2717ccacaf4SAndrzej Warzynski }
2727ccacaf4SAndrzej Warzynski } // namespace parser
2737ccacaf4SAndrzej Warzynski } // namespace Fortran
274