docc 0.8.3 (0d44999b)
C++ API Reference
Loading...
Searching...
No Matches
pointer_analyzers.h
Go to the documentation of this file.
1#pragma once
2
3#include <concepts>
4#include <string>
5#include <unordered_map>
6
8#include "sdfg/function.h"
9
10namespace sdfg::analysis {
19template<typename P>
20concept EscapePolicy = requires(P& p, const std::string& container, const ControlFlowNode* node, const Element* user) {
21 p.on_escape(container, node, user);
22};
23
31template<typename P>
33 P& p,
34 const std::string& container,
35 const ControlFlowNode* node,
36 const data_flow::LibraryNode& lib_node,
37 const structured_control_flow::Return& return_node,
38 const data_flow::PointerAccessType& access_type
39 ) {
40 p.on_ptr_input_into_lib_node(container, node, lib_node, access_type);
41 p.on_ptr_returned(container, return_node);
42 // p.on_ptr_written_to_memory
43 // ..
44};
45
60template<EscapePolicy Policy, bool ForceDetailed = false>
62 const StructuredSDFG& sdfg_;
63 Policy& policy_;
64
65public:
66 PointerEscapeAnalyzer(const StructuredSDFG& sdfg, Policy& policy) : sdfg_(sdfg), policy_(policy) {
67 }
68
69 void use_as_return_src(const std::string& container, const Return& ret) override {
70 if (sdfg_.type(container).type_id() == types::TypeID::Pointer) {
71 if constexpr (ForceDetailed || EscapeDetailsPolicy<Policy>) {
72 policy_.on_ptr_returned(container, ret);
73 } else {
74 policy_.on_escape(container, &ret, &ret);
75 }
76 }
77 }
78
80 const std::string& container,
81 const ControlFlowNode* node,
82 const Element* user,
84 int loc_index,
86 ) override {
87 auto& type = sdfg_.type(container);
88 if (type.type_id() == types::TypeID::Pointer) {
89 policy_.on_escape(container, node, user);
90 }
91 }
92
94 const std::string& container,
95 const data_flow::AccessNode& node,
96 const data_flow::Memlet& edge,
97 const Block& block
98 ) override {
99 auto& type = sdfg_.type(container);
100 if (edge.is_src_pointed_to_address_leak(type) || edge.is_src_address_leak()) {
101 // pulls a reference to the owned memory area or can alias the entire pointer
102
103 if constexpr (ForceDetailed || EscapeDetailsPolicy<Policy>) {
104 auto& target_node = edge.dst();
105 if (auto* lib_node = dyn_cast<data_flow::LibraryNode*>(&target_node)) {
106 auto meta = lib_node->pointer_access_type(edge);
107 policy_.on_ptr_input_into_lib_node(container, &block, *lib_node, meta);
108 } else {
109 // we currently do not have the analysis to track this through tasmklets, so fall back to generic
110 // escape
111 policy_.on_escape(container, &block, &edge);
112 }
113 } else {
114 policy_.on_escape(container, &block, &edge);
115 // it may not be, but this is the safest
116 // assumption. other passes can forward the original container and fold it into accesses
117 }
118 }
119 }
120
122 const std::string& container,
123 const data_flow::AccessNode& node,
124 const data_flow::Memlet& edge,
125 const Block& block
126 ) override {
127 }
129 const symbolic::Symbol& container, const ControlFlowNode* node, const Element* user, SymbolWriteLocation loc
130 ) override {
131 }
132};
133
134template<typename P>
136 requires(P& p, const std::string& container, const ControlFlowNode* node, const Element* user) {
137 p.on_overwrite(container, node, user);
138 };
139
152template<OverwritePolicy Policy>
154 const StructuredSDFG& sdfg_;
155 Policy& policy_;
156
157public:
158 PointerOverwriteAnalyzer(const StructuredSDFG& sdfg, Policy& policy) : sdfg_(sdfg), policy_(policy) {
159 }
160
162 const std::string& container,
163 const data_flow::AccessNode& node,
164 const data_flow::Memlet& edge,
165 const Block& block
166 ) override {
167 if (edge.is_dst_write()) { // writes to the ptr
168 auto& type = sdfg_.type(container);
169 if (type.type_id() == types::TypeID::Pointer) {
170 policy_.on_overwrite(container, &block, &edge);
171 }
172 }
173 }
174
176 const symbolic::Symbol& container, const ControlFlowNode* node, const Element* user, SymbolWriteLocation loc
177 ) override {
178 auto name = container->get_name();
179 if (sdfg_.type(name).type_id() == types::TypeID::Pointer) {
180 policy_.on_overwrite(name, node, user);
181 }
182 }
183
184 void use_as_return_src(const std::string& container, const Return& ret) override {
185 }
187 const std::string& container,
188 const data_flow::AccessNode& node,
189 const data_flow::Memlet& edge,
190 const Block& block
191 ) override {
192 }
194 const std::string& container,
195 const ControlFlowNode* node,
196 const Element* user,
198 int loc_index,
200 ) override {
201 }
202};
203
204template<typename P>
206 requires(P& p, const std::string& container, const ControlFlowNode* node, const data_flow::Memlet* user) {
207 p.on_write_via(container, node, user);
208 p.on_read_via(container, node, user);
209 };
210
214template<PointerUsedPolicy Policy>
216 const StructuredSDFG& sdfg_;
217 Policy& policy_;
218
219public:
220 PointerUsedAnalyzer(const StructuredSDFG& sdfg, Policy& policy) : sdfg_(sdfg), policy_(policy) {
221 }
222
224 const std::string& container,
225 const data_flow::AccessNode& node,
226 const data_flow::Memlet& edge,
227 const Block& block
228 ) override {
229 if (edge.is_src_pointed_to_read()) {
230 policy_.on_read_via(container, &block, &edge);
231 }
232 }
233
235 const std::string& container,
236 const data_flow::AccessNode& node,
237 const data_flow::Memlet& edge,
238 const Block& block
239 ) override {
240 if (edge.is_dst_pointed_to_write()) {
241 policy_.on_write_via(container, &block, &edge);
242 }
243 }
244
246 const symbolic::Symbol& container, const ControlFlowNode* node, const Element* user, SymbolWriteLocation loc
247 ) override {
248 }
249
250 void use_as_return_src(const std::string& container, const Return& ret) override {
251 }
252
254 const std::string& container,
255 const ControlFlowNode* node,
256 const Element* user,
258 int loc_index,
260 ) override {
261 }
262};
263
264
265} // namespace sdfg::analysis
Definition element.h:159
Definition structured_sdfg.h:30
PointerEscapeAnalyzer(const StructuredSDFG &sdfg, Policy &policy)
Definition pointer_analyzers.h:66
void use_as_symbol_read(const std::string &container, const ControlFlowNode *node, const Element *user, SymbolReadLocation loc, int loc_index, symbolic::Expression expr) override
Definition pointer_analyzers.h:79
void use_as_symbol_write(const symbolic::Symbol &container, const ControlFlowNode *node, const Element *user, SymbolWriteLocation loc) override
Definition pointer_analyzers.h:128
void use_as_src_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition pointer_analyzers.h:93
void use_as_dst_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition pointer_analyzers.h:121
void use_as_return_src(const std::string &container, const Return &ret) override
Definition pointer_analyzers.h:69
void use_as_src_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition pointer_analyzers.h:186
void use_as_dst_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition pointer_analyzers.h:161
void use_as_return_src(const std::string &container, const Return &ret) override
Definition pointer_analyzers.h:184
void use_as_symbol_read(const std::string &container, const ControlFlowNode *node, const Element *user, SymbolReadLocation loc, int loc_index, symbolic::Expression expr) override
Definition pointer_analyzers.h:193
PointerOverwriteAnalyzer(const StructuredSDFG &sdfg, Policy &policy)
Definition pointer_analyzers.h:158
void use_as_symbol_write(const symbolic::Symbol &container, const ControlFlowNode *node, const Element *user, SymbolWriteLocation loc) override
Definition pointer_analyzers.h:175
void use_as_return_src(const std::string &container, const Return &ret) override
Definition pointer_analyzers.h:250
PointerUsedAnalyzer(const StructuredSDFG &sdfg, Policy &policy)
Definition pointer_analyzers.h:220
void use_as_src_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition pointer_analyzers.h:223
void use_as_symbol_write(const symbolic::Symbol &container, const ControlFlowNode *node, const Element *user, SymbolWriteLocation loc) override
Definition pointer_analyzers.h:245
void use_as_symbol_read(const std::string &container, const ControlFlowNode *node, const Element *user, SymbolReadLocation loc, int loc_index, symbolic::Expression expr) override
Definition pointer_analyzers.h:253
void use_as_dst_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition pointer_analyzers.h:234
Node representing access to a data container in the dataflow graph.
Definition access_node.h:84
Base class for all library nodes in the dataflow graph.
Definition library_node.h:106
Edge in the dataflow graph representing data movement.
Definition memlet.h:131
bool is_dst_write() const
makes a memory write to dst (itself).
bool is_src_pointed_to_address_leak(const types::IType &src_type) const
Leaks address of what src points to.
const DataFlowNode & dst() const
Get the destination node (const).
bool is_src_pointed_to_read() const
Makes a memory read with src-contents as (partial) address.
bool is_src_address_leak() const
Leaks the address of src or uses it in an address calculation that is returned.
bool is_dst_pointed_to_write() const
Contents of dst are used in the address calculation of a memory write.
A control flow node representing a basic block with dataflow computations.
Definition block.h:42
Base class for all structured control flow nodes in a StructuredSDFG.
Definition control_flow_node.h:44
Represents a return statement that exits the function with a value.
Definition return.h:32
Definition base_user_visitor.h:7
SymbolReadLocation
Definition base_user_visitor.h:13
SymbolWriteLocation
Definition base_user_visitor.h:21
A more detailed variant of EscapePolicy that aims to distinguish between different types of pointer e...
Definition pointer_analyzers.h:32
Concept for policies that handle pointer usages.
Definition pointer_analyzers.h:20
Definition pointer_analyzers.h:135
Definition pointer_analyzers.h:205
SymEngine::RCP< const SymEngine::Basic > Expression
Reference-counted pointer to a symbolic expression (SymEngine Basic).
Definition symbolic.h:83
SymEngine::RCP< const SymEngine::Symbol > Symbol
Reference-counted pointer to a SymEngine Symbol.
Definition symbolic.h:71
Definition analysis.h:8
std::unique_ptr< PointerAccessMeta, PtrAccessDeleter > PointerAccessType
Definition pointer_metadata.h:32
@ Pointer
Pointer type.
Definition type.h:611
Definition analysis.h:7
element_cast_target_t< T > * dyn_cast(Element *element)
Efficient down-cast to T, or nullptr if element is not a T.
Definition element.h:246