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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "FlangOmpReportVisitor.h"
10#include "llvm/ADT/StringExtras.h"
11#include "llvm/Frontend/OpenMP/OMP.h"
12
13namespace Fortran {
14namespace parser {
15bool operator<(const ClauseInfo &a, const ClauseInfo &b) {
16 return a.clause < b.clause;
17}
18bool operator==(const ClauseInfo &a, const ClauseInfo &b) {
19 return a.clause == b.clause && a.clauseDetails == b.clauseDetails;
20}
21bool operator!=(const ClauseInfo &a, const ClauseInfo &b) { return !(a == b); }
22
23bool operator==(const LogRecord &a, const LogRecord &b) {
24 return a.file == b.file && a.line == b.line && a.construct == b.construct &&
25 a.clauses == b.clauses;
26}
27bool operator!=(const LogRecord &a, const LogRecord &b) { return !(a == b); }
28
29std::string OpenMPCounterVisitor::normalize_construct_name(std::string s) {
30 std::transform(first: s.begin(), last: s.end(), result: s.begin(),
31 unary_op: [](unsigned char c) { return llvm::toLower(x: c); });
32 return s;
33}
34ClauseInfo OpenMPCounterVisitor::normalize_clause_name(
35 const llvm::StringRef s) {
36 std::size_t start = s.find(C: '(');
37 std::size_t end = s.find(C: ')');
38 std::string clauseName;
39 if (start != llvm::StringRef::npos && end != llvm::StringRef::npos) {
40 clauseName = s.substr(Start: 0, N: start);
41 clauseDetails = s.substr(Start: start + 1, N: end - start - 1);
42 } else {
43 clauseName = s;
44 }
45 std::transform(first: clauseName.begin(), last: clauseName.end(), result: clauseName.begin(),
46 unary_op: [](unsigned char c) { return llvm::toLower(x: c); });
47 std::transform(first: clauseDetails.begin(), last: clauseDetails.end(),
48 result: clauseDetails.begin(), unary_op: [](unsigned char c) { return llvm::toLower(x: c); });
49 return ClauseInfo{clauseName, clauseDetails};
50}
51SourcePosition OpenMPCounterVisitor::getLocation(const OmpWrapperType &w) {
52 if (auto *val = std::get_if<const OpenMPConstruct *>(&w)) {
53 const OpenMPConstruct *o{*val};
54 return getLocation(*o);
55 }
56 return getLocation(*std::get<const OpenMPDeclarativeConstruct *>(w));
57}
58SourcePosition OpenMPCounterVisitor::getLocation(
59 const OpenMPDeclarativeConstruct &c) {
60 return std::visit(
61 [&](const auto &o) -> SourcePosition {
62 return parsing->allCooked().GetSourcePositionRange(o.source)->first;
63 },
64 c.u);
65}
66SourcePosition OpenMPCounterVisitor::getLocation(const OpenMPConstruct &c) {
67 return std::visit(
68 Fortran::common::visitors{
69 [&](const OpenMPStandaloneConstruct &c) -> SourcePosition {
70 return parsing->allCooked().GetSourcePositionRange(c.source)->first;
71 },
72 // OpenMPSectionsConstruct, OpenMPLoopConstruct,
73 // OpenMPBlockConstruct, OpenMPCriticalConstruct Get the source from
74 // the directive field.
75 [&](const auto &c) -> SourcePosition {
76 const CharBlock &source{std::get<0>(c.t).source};
77 return parsing->allCooked().GetSourcePositionRange(source)->first;
78 },
79 [&](const OpenMPAtomicConstruct &c) -> SourcePosition {
80 const CharBlock &source{c.source};
81 return parsing->allCooked().GetSourcePositionRange(source)->first;
82 },
83 [&](const OpenMPSectionConstruct &c) -> SourcePosition {
84 const CharBlock &source{c.source};
85 return parsing->allCooked().GetSourcePositionRange(source)->first;
86 },
87 [&](const OpenMPUtilityConstruct &c) -> SourcePosition {
88 const CharBlock &source{c.source};
89 return parsing->allCooked().GetSourcePositionRange(source)->first;
90 },
91 },
92 c.u);
93}
94
95std::string OpenMPCounterVisitor::getName(const OmpWrapperType &w) {
96 if (auto *val = std::get_if<const OpenMPConstruct *>(&w)) {
97 const OpenMPConstruct *o{*val};
98 return getName(*o);
99 }
100 return getName(*std::get<const OpenMPDeclarativeConstruct *>(w));
101}
102std::string OpenMPCounterVisitor::getName(const OpenMPDeclarativeConstruct &c) {
103 return std::visit( //
104 Fortran::common::visitors{
105 [&](const OpenMPUtilityConstruct &o) -> std::string {
106 const CharBlock &source{o.source};
107 return normalize_construct_name(source.ToString());
108 },
109 [&](const OmpMetadirectiveDirective &o) -> std::string {
110 const CharBlock &source{o.source};
111 return normalize_construct_name(source.ToString());
112 },
113 [&](const auto &o) -> std::string {
114 const CharBlock &source{std::get<Verbatim>(o.t).source};
115 return normalize_construct_name(source.ToString());
116 },
117 },
118 c.u);
119}
120std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
121 return std::visit(
122 Fortran::common::visitors{
123 [&](const OpenMPStandaloneConstruct &c) -> std::string {
124 return common::visit(
125 common::visitors{
126 [&](const OmpMetadirectiveDirective &d) {
127 return normalize_construct_name(d.source.ToString());
128 },
129 [&](auto &&d) {
130 const CharBlock &source{
131 std::get<OmpDirectiveName>(d.v.t).source};
132 return normalize_construct_name(source.ToString());
133 },
134 },
135 c.u);
136 },
137 [&](const OpenMPExecutableAllocate &c) -> std::string {
138 const CharBlock &source{std::get<0>(c.t).source};
139 return normalize_construct_name(source.ToString());
140 },
141 [&](const OpenMPDeclarativeAllocate &c) -> std::string {
142 const CharBlock &source{std::get<0>(c.t).source};
143 return normalize_construct_name(source.ToString());
144 },
145 [&](const OpenMPAssumeConstruct &c) -> std::string {
146 const CharBlock &source{std::get<0>(c.t).source};
147 return normalize_construct_name(source.ToString());
148 },
149 [&](const OpenMPAllocatorsConstruct &c) -> std::string {
150 const CharBlock &source{std::get<0>(c.t).source};
151 return normalize_construct_name(source.ToString());
152 },
153 [&](const OpenMPAtomicConstruct &c) -> std::string {
154 auto &dirSpec = std::get<OmpDirectiveSpecification>(c.t);
155 auto &dirName = std::get<OmpDirectiveName>(dirSpec.t);
156 return normalize_construct_name(dirName.source.ToString());
157 },
158 [&](const OpenMPUtilityConstruct &c) -> std::string {
159 const CharBlock &source{c.source};
160 return normalize_construct_name(source.ToString());
161 },
162 [&](const OpenMPSectionConstruct &c) -> std::string {
163 return "section";
164 },
165 // OpenMPSectionsConstruct, OpenMPLoopConstruct,
166 // OpenMPBlockConstruct, OpenMPCriticalConstruct Get the source from
167 // the directive field of the begin directive or from the verbatim
168 // field of the begin directive in Critical
169 [&](const auto &c) -> std::string {
170 const CharBlock &source{std::get<0>(std::get<0>(c.t).t).source};
171 return normalize_construct_name(source.ToString());
172 },
173 },
174 c.u);
175}
176
177bool OpenMPCounterVisitor::Pre(const OpenMPDeclarativeConstruct &c) {
178 OmpWrapperType *ow{new OmpWrapperType(&c)};
179 ompWrapperStack.push_back(ow);
180 return true;
181}
182bool OpenMPCounterVisitor::Pre(const OpenMPConstruct &c) {
183 OmpWrapperType *ow{new OmpWrapperType(&c)};
184 ompWrapperStack.push_back(ow);
185 return true;
186}
187
188void OpenMPCounterVisitor::Post(const OpenMPDeclarativeConstruct &) {
189 PostConstructsCommon();
190}
191void OpenMPCounterVisitor::Post(const OpenMPConstruct &) {
192 PostConstructsCommon();
193}
194void OpenMPCounterVisitor::PostConstructsCommon() {
195 OmpWrapperType *curConstruct = ompWrapperStack.back();
196 std::sort(
197 clauseStrings[curConstruct].begin(), clauseStrings[curConstruct].end());
198
199 SourcePosition s{getLocation(*curConstruct)};
200 LogRecord r{
201 s.path, s.line, getName(*curConstruct), clauseStrings[curConstruct]};
202 constructClauses.push_back(Elt: r);
203
204 auto it = clauseStrings.find(curConstruct);
205 clauseStrings.erase(it);
206 ompWrapperStack.pop_back();
207 delete curConstruct;
208}
209
210void OpenMPCounterVisitor::Post(const OmpProcBindClause::AffinityPolicy &c) {
211 clauseDetails +=
212 "type=" + std::string{OmpProcBindClause::EnumToString(c)} + ";";
213}
214void OpenMPCounterVisitor::Post(
215 const OmpDefaultClause::DataSharingAttribute &c) {
216 clauseDetails +=
217 "type=" + std::string{OmpDefaultClause::EnumToString(c)} + ";";
218}
219void OpenMPCounterVisitor::Post(
220 const OmpDeviceTypeClause::DeviceTypeDescription &c) {
221 clauseDetails +=
222 "type=" + std::string{OmpDeviceTypeClause::EnumToString(c)} + ";";
223}
224void OpenMPCounterVisitor::Post(
225 const OmpDefaultmapClause::ImplicitBehavior &c) {
226 clauseDetails +=
227 "implicit_behavior=" + std::string{OmpDefaultmapClause::EnumToString(c)} +
228 ";";
229}
230void OpenMPCounterVisitor::Post(const OmpVariableCategory::Value &c) {
231 clauseDetails +=
232 "variable_category=" + std::string{OmpVariableCategory::EnumToString(c)} +
233 ";";
234}
235void OpenMPCounterVisitor::Post(const OmpChunkModifier::Value &c) {
236 clauseDetails +=
237 "modifier=" + std::string{OmpChunkModifier::EnumToString(c)} + ";";
238}
239void OpenMPCounterVisitor::Post(const OmpLinearModifier::Value &c) {
240 clauseDetails +=
241 "modifier=" + std::string{OmpLinearModifier::EnumToString(c)} + ";";
242}
243void OpenMPCounterVisitor::Post(const OmpOrderingModifier::Value &c) {
244 clauseDetails +=
245 "modifier=" + std::string{OmpOrderingModifier::EnumToString(c)} + ";";
246}
247void OpenMPCounterVisitor::Post(const OmpTaskDependenceType::Value &c) {
248 clauseDetails +=
249 "type=" + std::string{OmpTaskDependenceType::EnumToString(c)} + ";";
250}
251void OpenMPCounterVisitor::Post(const OmpMapType::Value &c) {
252 clauseDetails += "type=" + std::string{OmpMapType::EnumToString(c)} + ";";
253}
254void OpenMPCounterVisitor::Post(const OmpScheduleClause::Kind &c) {
255 clauseDetails +=
256 "type=" + std::string{OmpScheduleClause::EnumToString(c)} + ";";
257}
258void OpenMPCounterVisitor::Post(const OmpDirectiveNameModifier &c) {
259 clauseDetails += "name_modifier=" +
260 llvm::omp::getOpenMPDirectiveName(c.v, llvm::omp::FallbackVersion).str() +
261 ";";
262}
263void OpenMPCounterVisitor::Post(const OmpClause &c) {
264 PostClauseCommon(ci: normalize_clause_name(s: c.source.ToString()));
265 clauseDetails.clear();
266}
267void OpenMPCounterVisitor::PostClauseCommon(const ClauseInfo &ci) {
268 assert(
269 !ompWrapperStack.empty() && "Construct should be visited before clause");
270 clauseStrings[ompWrapperStack.back()].push_back(ci);
271}
272} // namespace parser
273} // namespace Fortran
274

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp