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