193 lines · cpp
1//===-- examples/flang-omp-report-plugin/flang-omp-report-visitor.cpp -----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "FlangOmpReportVisitor.h"10#include "flang/Common/idioms.h"11#include "flang/Parser/openmp-utils.h"12#include "llvm/ADT/StringExtras.h"13#include "llvm/Frontend/OpenMP/OMP.h"14 15namespace Fortran {16namespace parser {17bool operator<(const ClauseInfo &a, const ClauseInfo &b) {18 return a.clause < b.clause;19}20bool operator==(const ClauseInfo &a, const ClauseInfo &b) {21 return a.clause == b.clause && a.clauseDetails == b.clauseDetails;22}23bool operator!=(const ClauseInfo &a, const ClauseInfo &b) { return !(a == b); }24 25bool operator==(const LogRecord &a, const LogRecord &b) {26 return a.file == b.file && a.line == b.line && a.construct == b.construct &&27 a.clauses == b.clauses;28}29bool operator!=(const LogRecord &a, const LogRecord &b) { return !(a == b); }30 31std::string OpenMPCounterVisitor::normalize_construct_name(std::string s) {32 std::transform(s.begin(), s.end(), s.begin(),33 [](unsigned char c) { return llvm::toLower(c); });34 return s;35}36ClauseInfo OpenMPCounterVisitor::normalize_clause_name(37 const llvm::StringRef s) {38 std::size_t start = s.find('(');39 std::size_t end = s.find(')');40 std::string clauseName;41 if (start != llvm::StringRef::npos && end != llvm::StringRef::npos) {42 clauseName = s.substr(0, start);43 clauseDetails = s.substr(start + 1, end - start - 1);44 } else {45 clauseName = s;46 }47 std::transform(clauseName.begin(), clauseName.end(), clauseName.begin(),48 [](unsigned char c) { return llvm::toLower(c); });49 std::transform(clauseDetails.begin(), clauseDetails.end(),50 clauseDetails.begin(), [](unsigned char c) { return llvm::toLower(c); });51 return ClauseInfo{clauseName, clauseDetails};52}53SourcePosition OpenMPCounterVisitor::getLocation(const OmpWrapperType &w) {54 if (auto *val = std::get_if<const OpenMPConstruct *>(&w)) {55 const OpenMPConstruct *o{*val};56 return getLocation(*o);57 }58 return getLocation(*std::get<const OpenMPDeclarativeConstruct *>(w));59}60SourcePosition OpenMPCounterVisitor::getLocation(61 const OpenMPDeclarativeConstruct &c) {62 const parser::AllCookedSources &allCooked{parsing->allCooked()};63 return std::visit(64 common::visitors{65 [&](const parser::OmpMetadirectiveDirective &o) -> SourcePosition {66 return allCooked.GetSourcePositionRange(o.v.source)->first;67 },68 [&](const auto &o) -> SourcePosition {69 return allCooked.GetSourcePositionRange(o.source)->first;70 },71 },72 c.u);73}74SourcePosition OpenMPCounterVisitor::getLocation(const OpenMPConstruct &c) {75 return parsing->allCooked()76 .GetSourcePositionRange(omp::GetOmpDirectiveName(c).source)77 ->first;78}79 80std::string OpenMPCounterVisitor::getName(const OmpWrapperType &w) {81 if (auto *val = std::get_if<const OpenMPConstruct *>(&w)) {82 const OpenMPConstruct *o{*val};83 return getName(*o);84 }85 return getName(*std::get<const OpenMPDeclarativeConstruct *>(w));86}87std::string OpenMPCounterVisitor::getName(const OpenMPDeclarativeConstruct &c) {88 return normalize_construct_name(89 omp::GetOmpDirectiveName(c).source.ToString());90}91std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {92 return normalize_construct_name(93 omp::GetOmpDirectiveName(c).source.ToString());94}95 96bool OpenMPCounterVisitor::Pre(const OpenMPDeclarativeConstruct &c) {97 OmpWrapperType *ow{new OmpWrapperType(&c)};98 ompWrapperStack.push_back(ow);99 return true;100}101bool OpenMPCounterVisitor::Pre(const OpenMPConstruct &c) {102 OmpWrapperType *ow{new OmpWrapperType(&c)};103 ompWrapperStack.push_back(ow);104 return true;105}106 107void OpenMPCounterVisitor::Post(const OpenMPDeclarativeConstruct &) {108 PostConstructsCommon();109}110void OpenMPCounterVisitor::Post(const OpenMPConstruct &) {111 PostConstructsCommon();112}113void OpenMPCounterVisitor::PostConstructsCommon() {114 OmpWrapperType *curConstruct = ompWrapperStack.back();115 std::sort(116 clauseStrings[curConstruct].begin(), clauseStrings[curConstruct].end());117 118 SourcePosition s{getLocation(*curConstruct)};119 LogRecord r{120 s.path, s.line, getName(*curConstruct), clauseStrings[curConstruct]};121 constructClauses.push_back(r);122 123 auto it = clauseStrings.find(curConstruct);124 clauseStrings.erase(it);125 ompWrapperStack.pop_back();126 delete curConstruct;127}128 129void OpenMPCounterVisitor::Post(const OmpProcBindClause::AffinityPolicy &c) {130 clauseDetails +=131 "type=" + std::string{OmpProcBindClause::EnumToString(c)} + ";";132}133void OpenMPCounterVisitor::Post(134 const OmpDefaultClause::DataSharingAttribute &c) {135 clauseDetails +=136 "type=" + std::string{OmpDefaultClause::EnumToString(c)} + ";";137}138void OpenMPCounterVisitor::Post(139 const OmpDeviceTypeClause::DeviceTypeDescription &c) {140 clauseDetails +=141 "type=" + std::string{OmpDeviceTypeClause::EnumToString(c)} + ";";142}143void OpenMPCounterVisitor::Post(144 const OmpDefaultmapClause::ImplicitBehavior &c) {145 clauseDetails +=146 "implicit_behavior=" + std::string{OmpDefaultmapClause::EnumToString(c)} +147 ";";148}149void OpenMPCounterVisitor::Post(const OmpVariableCategory::Value &c) {150 clauseDetails +=151 "variable_category=" + std::string{OmpVariableCategory::EnumToString(c)} +152 ";";153}154void OpenMPCounterVisitor::Post(const OmpChunkModifier::Value &c) {155 clauseDetails +=156 "modifier=" + std::string{OmpChunkModifier::EnumToString(c)} + ";";157}158void OpenMPCounterVisitor::Post(const OmpLinearModifier::Value &c) {159 clauseDetails +=160 "modifier=" + std::string{OmpLinearModifier::EnumToString(c)} + ";";161}162void OpenMPCounterVisitor::Post(const OmpOrderingModifier::Value &c) {163 clauseDetails +=164 "modifier=" + std::string{OmpOrderingModifier::EnumToString(c)} + ";";165}166void OpenMPCounterVisitor::Post(const OmpTaskDependenceType::Value &c) {167 clauseDetails +=168 "type=" + std::string{OmpTaskDependenceType::EnumToString(c)} + ";";169}170void OpenMPCounterVisitor::Post(const OmpMapType::Value &c) {171 clauseDetails += "type=" + std::string{OmpMapType::EnumToString(c)} + ";";172}173void OpenMPCounterVisitor::Post(const OmpScheduleClause::Kind &c) {174 clauseDetails +=175 "type=" + std::string{OmpScheduleClause::EnumToString(c)} + ";";176}177void OpenMPCounterVisitor::Post(const OmpDirectiveNameModifier &c) {178 clauseDetails += "name_modifier=" +179 llvm::omp::getOpenMPDirectiveName(c.v, llvm::omp::FallbackVersion).str() +180 ";";181}182void OpenMPCounterVisitor::Post(const OmpClause &c) {183 PostClauseCommon(normalize_clause_name(c.source.ToString()));184 clauseDetails.clear();185}186void OpenMPCounterVisitor::PostClauseCommon(const ClauseInfo &ci) {187 assert(188 !ompWrapperStack.empty() && "Construct should be visited before clause");189 clauseStrings[ompWrapperStack.back()].push_back(ci);190}191} // namespace parser192} // namespace Fortran193