1 //===-- examples/flang-omp-report-plugin/flang-omp-report-visitor.cpp -----===//
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
7 //===----------------------------------------------------------------------===//
9 #include "FlangOmpReportVisitor.h"
10 #include "llvm/ADT/StringExtras.h"
14 bool operator<(const ClauseInfo
&a
, const ClauseInfo
&b
) {
15 return a
.clause
< b
.clause
;
17 bool operator==(const ClauseInfo
&a
, const ClauseInfo
&b
) {
18 return a
.clause
== b
.clause
&& a
.clauseDetails
== b
.clauseDetails
;
20 bool operator!=(const ClauseInfo
&a
, const ClauseInfo
&b
) { return !(a
== b
); }
22 bool operator==(const LogRecord
&a
, const LogRecord
&b
) {
23 return a
.file
== b
.file
&& a
.line
== b
.line
&& a
.construct
== b
.construct
&&
24 a
.clauses
== b
.clauses
;
26 bool operator!=(const LogRecord
&a
, const LogRecord
&b
) { return !(a
== b
); }
28 std::string
OpenMPCounterVisitor::normalize_construct_name(std::string s
) {
29 std::transform(s
.begin(), s
.end(), s
.begin(),
30 [](unsigned char c
) { return llvm::toLower(c
); });
33 ClauseInfo
OpenMPCounterVisitor::normalize_clause_name(
34 const llvm::StringRef s
) {
35 std::size_t start
= s
.find('(');
36 std::size_t end
= s
.find(')');
37 std::string clauseName
;
38 if (start
!= llvm::StringRef::npos
&& end
!= llvm::StringRef::npos
) {
39 clauseName
= s
.substr(0, start
);
40 clauseDetails
= s
.substr(start
+ 1, end
- start
- 1);
44 std::transform(clauseName
.begin(), clauseName
.end(), clauseName
.begin(),
45 [](unsigned char c
) { return llvm::toLower(c
); });
46 std::transform(clauseDetails
.begin(), clauseDetails
.end(),
47 clauseDetails
.begin(), [](unsigned char c
) { return llvm::toLower(c
); });
48 return ClauseInfo
{clauseName
, clauseDetails
};
50 SourcePosition
OpenMPCounterVisitor::getLocation(const OmpWrapperType
&w
) {
51 if (auto *val
= std::get_if
<const OpenMPConstruct
*>(&w
)) {
52 const OpenMPConstruct
*o
{*val
};
53 return getLocation(*o
);
55 return getLocation(*std::get
<const OpenMPDeclarativeConstruct
*>(w
));
57 SourcePosition
OpenMPCounterVisitor::getLocation(
58 const OpenMPDeclarativeConstruct
&c
) {
60 [&](const auto &o
) -> SourcePosition
{
61 return parsing
->allCooked().GetSourcePositionRange(o
.source
)->first
;
65 SourcePosition
OpenMPCounterVisitor::getLocation(const OpenMPConstruct
&c
) {
67 Fortran::common::visitors
{
68 [&](const OpenMPStandaloneConstruct
&c
) -> SourcePosition
{
69 return parsing
->allCooked().GetSourcePositionRange(c
.source
)->first
;
71 // OpenMPSectionsConstruct, OpenMPLoopConstruct,
72 // OpenMPBlockConstruct, OpenMPCriticalConstruct Get the source from
73 // the directive field.
74 [&](const auto &c
) -> SourcePosition
{
75 const CharBlock
&source
{std::get
<0>(c
.t
).source
};
76 return (parsing
->allCooked().GetSourcePositionRange(source
))->first
;
78 [&](const OpenMPAtomicConstruct
&c
) -> SourcePosition
{
80 [&](const auto &o
) -> SourcePosition
{
81 const CharBlock
&source
{std::get
<Verbatim
>(o
.t
).source
};
82 return parsing
->allCooked()
83 .GetSourcePositionRange(source
)
88 [&](const OpenMPSectionConstruct
&c
) -> SourcePosition
{
89 const CharBlock
&source
{c
.source
};
90 return (parsing
->allCooked().GetSourcePositionRange(source
))->first
;
96 std::string
OpenMPCounterVisitor::getName(const OmpWrapperType
&w
) {
97 if (auto *val
= std::get_if
<const OpenMPConstruct
*>(&w
)) {
98 const OpenMPConstruct
*o
{*val
};
101 return getName(*std::get
<const OpenMPDeclarativeConstruct
*>(w
));
103 std::string
OpenMPCounterVisitor::getName(const OpenMPDeclarativeConstruct
&c
) {
105 [&](const auto &o
) -> std::string
{
106 const CharBlock
&source
{std::get
<Verbatim
>(o
.t
).source
};
107 return normalize_construct_name(source
.ToString());
111 std::string
OpenMPCounterVisitor::getName(const OpenMPConstruct
&c
) {
113 Fortran::common::visitors
{
114 [&](const OpenMPStandaloneConstruct
&c
) -> std::string
{
117 // Get source from the directive or verbatim fields
118 const CharBlock
&source
{std::get
<0>(c
.t
).source
};
119 return normalize_construct_name(source
.ToString());
123 [&](const OpenMPExecutableAllocate
&c
) -> std::string
{
124 const CharBlock
&source
{std::get
<0>(c
.t
).source
};
125 return normalize_construct_name(source
.ToString());
127 [&](const OpenMPDeclarativeAllocate
&c
) -> std::string
{
128 const CharBlock
&source
{std::get
<0>(c
.t
).source
};
129 return normalize_construct_name(source
.ToString());
131 [&](const OpenMPAllocatorsConstruct
&c
) -> std::string
{
132 const CharBlock
&source
{std::get
<0>(c
.t
).source
};
133 return normalize_construct_name(source
.ToString());
135 [&](const OpenMPAtomicConstruct
&c
) -> std::string
{
138 // Get source from the verbatim fields
139 const CharBlock
&source
{std::get
<Verbatim
>(c
.t
).source
};
141 normalize_construct_name(source
.ToString());
145 [&](const OpenMPSectionConstruct
&c
) -> std::string
{
148 // OpenMPSectionsConstruct, OpenMPLoopConstruct,
149 // OpenMPBlockConstruct, OpenMPCriticalConstruct Get the source from
150 // the directive field of the begin directive or from the verbatim
151 // field of the begin directive in Critical
152 [&](const auto &c
) -> std::string
{
153 const CharBlock
&source
{std::get
<0>(std::get
<0>(c
.t
).t
).source
};
154 return normalize_construct_name(source
.ToString());
160 bool OpenMPCounterVisitor::Pre(const OpenMPDeclarativeConstruct
&c
) {
161 OmpWrapperType
*ow
{new OmpWrapperType(&c
)};
162 ompWrapperStack
.push_back(ow
);
165 bool OpenMPCounterVisitor::Pre(const OpenMPConstruct
&c
) {
166 OmpWrapperType
*ow
{new OmpWrapperType(&c
)};
167 ompWrapperStack
.push_back(ow
);
171 void OpenMPCounterVisitor::Post(const OpenMPDeclarativeConstruct
&) {
172 PostConstructsCommon();
174 void OpenMPCounterVisitor::Post(const OpenMPConstruct
&) {
175 PostConstructsCommon();
177 void OpenMPCounterVisitor::PostConstructsCommon() {
178 OmpWrapperType
*curConstruct
= ompWrapperStack
.back();
180 clauseStrings
[curConstruct
].begin(), clauseStrings
[curConstruct
].end());
182 SourcePosition s
{getLocation(*curConstruct
)};
184 s
.path
, s
.line
, getName(*curConstruct
), clauseStrings
[curConstruct
]};
185 constructClauses
.push_back(r
);
187 auto it
= clauseStrings
.find(curConstruct
);
188 clauseStrings
.erase(it
);
189 ompWrapperStack
.pop_back();
193 void OpenMPCounterVisitor::Post(const OmpProcBindClause::Type
&c
) {
195 "type=" + std::string
{OmpProcBindClause::EnumToString(c
)} + ";";
197 void OpenMPCounterVisitor::Post(const OmpDefaultClause::Type
&c
) {
199 "type=" + std::string
{OmpDefaultClause::EnumToString(c
)} + ";";
201 void OpenMPCounterVisitor::Post(const OmpDeviceTypeClause::Type
&c
) {
203 "type=" + std::string
{OmpDeviceTypeClause::EnumToString(c
)} + ";";
205 void OpenMPCounterVisitor::Post(
206 const OmpDefaultmapClause::ImplicitBehavior
&c
) {
208 "implicit_behavior=" + std::string
{OmpDefaultmapClause::EnumToString(c
)} +
211 void OpenMPCounterVisitor::Post(
212 const OmpDefaultmapClause::VariableCategory
&c
) {
214 "variable_category=" + std::string
{OmpDefaultmapClause::EnumToString(c
)} +
217 void OpenMPCounterVisitor::Post(const OmpScheduleModifierType::ModType
&c
) {
219 "modifier=" + std::string
{OmpScheduleModifierType::EnumToString(c
)} + ";";
221 void OpenMPCounterVisitor::Post(const OmpLinearModifier::Value
&c
) {
223 "modifier=" + std::string
{OmpLinearModifier::EnumToString(c
)} + ";";
225 void OpenMPCounterVisitor::Post(const OmpTaskDependenceType::Value
&c
) {
227 "type=" + std::string
{OmpTaskDependenceType::EnumToString(c
)} + ";";
229 void OpenMPCounterVisitor::Post(const OmpMapClause::Type
&c
) {
230 clauseDetails
+= "type=" + std::string
{OmpMapClause::EnumToString(c
)} + ";";
232 void OpenMPCounterVisitor::Post(const OmpScheduleClause::ScheduleType
&c
) {
234 "type=" + std::string
{OmpScheduleClause::EnumToString(c
)} + ";";
236 void OpenMPCounterVisitor::Post(const OmpIfClause::DirectiveNameModifier
&c
) {
238 "name_modifier=" + std::string
{OmpIfClause::EnumToString(c
)} + ";";
240 void OpenMPCounterVisitor::Post(const OmpCancelType::Type
&c
) {
241 clauseDetails
+= "type=" + std::string
{OmpCancelType::EnumToString(c
)} + ";";
243 void OpenMPCounterVisitor::Post(const OmpClause
&c
) {
244 PostClauseCommon(normalize_clause_name(c
.source
.ToString()));
245 clauseDetails
.clear();
247 void OpenMPCounterVisitor::PostClauseCommon(const ClauseInfo
&ci
) {
249 !ompWrapperStack
.empty() && "Construct should be visited before clause");
250 clauseStrings
[ompWrapperStack
.back()].push_back(ci
);
252 } // namespace parser
253 } // namespace Fortran