3#include <unordered_set>
12#define LOOP_INFO_PROPERTIES \
13 X(int, loopnest_index, -1) \
14 X(sdfg::ElementId, element_id, 0) \
15 X(size_t, num_loops, 0) \
16 X(size_t, num_maps, 0) \
17 X(size_t, num_fors, 0) \
18 X(size_t, num_whiles, 0) \
19 X(size_t, max_depth, 0) \
20 X(bool, is_perfectly_nested, false) \
21 X(bool, is_perfectly_parallel, false) \
22 X(bool, is_elementwise, false) \
23 X(bool, has_side_effects, false) \
24 X(uint32_t, loop_level, 0) \
25 X(uint32_t, map_stack_depth, 0)
39#define X(type, name, val) type name = val;
77 nlohmann::json j = nlohmann::json{
78 {
"loopnest_index", info.loopnest_index},
79 {
"element_id", info.element_id},
80 {
"num_loops", info.num_loops},
81 {
"num_maps", info.num_maps},
82 {
"num_fors", info.num_fors},
83 {
"num_whiles", info.num_whiles},
84 {
"max_depth", info.max_depth},
85 {
"is_perfectly_nested", info.is_perfectly_nested},
86 {
"is_perfectly_parallel", info.is_perfectly_parallel},
87 {
"is_elementwise", info.is_elementwise},
88 {
"has_side_effects", info.has_side_effects},
89 {
"loop_level", info.loop_level},
90 {
"map_stack_depth", info.map_stack_depth}
109 std::vector<structured_control_flow::ControlFlowNode*> loops_;
110 std::unordered_map<structured_control_flow::ControlFlowNode*, structured_control_flow::ControlFlowNode*> loop_tree_;
111 std::unordered_map<structured_control_flow::ControlFlowNode*, std::vector<structured_control_flow::ControlFlowNode*>>
114 std::unordered_map<structured_control_flow::ControlFlowNode*, LoopState> loop_infos_;
124 void init_new_loop_info(
136 uint32_t loop_level);
140 std::list<std::vector<sdfg::structured_control_flow::ControlFlowNode*>> loop_tree_paths(
142 const std::unordered_map<
155 void reindex_loop_nest_idx();
174 std::vector<structured_control_flow::ControlFlowNode*>::iterator start,
175 std::vector<structured_control_flow::ControlFlowNode*>::iterator end
184 void propagate_changed_nest_info(std::vector<structured_control_flow::ControlFlowNode*>::iterator top);
189 std::string
name()
const override {
190 return "LoopAnalysis";
205 const std::vector<structured_control_flow::ControlFlowNode*>
loops()
const;
217 const std::unordered_map<structured_control_flow::ControlFlowNode*, structured_control_flow::ControlFlowNode*>&
228 const std::vector<structured_control_flow::ControlFlowNode*>&
outermost_loops()
const;
232 const std::vector<structured_control_flow::ControlFlowNode*>
outermost_maps()
const;
234 const std::vector<sdfg::structured_control_flow::ControlFlowNode*>&
237 std::list<std::vector<sdfg::structured_control_flow::ControlFlowNode*>>
240 std::unordered_set<sdfg::structured_control_flow::ControlFlowNode*>
243 std::unordered_set<sdfg::structured_control_flow::ControlFlowNode*>
246 std::vector<sdfg::structured_control_flow::ControlFlowNode*>::const_iterator
252 std::vector<sdfg::structured_control_flow::ControlFlowNode*>::const_iterator
263 bool start_not_end =
false
270 bool start_not_end =
false
Definition structured_sdfg.h:30
Analysis(StructuredSDFG &sdfg)
Definition assumptions_analysis.h:15
std::vector< sdfg::structured_control_flow::ControlFlowNode * >::const_iterator get_subtree_end(structured_control_flow::ControlFlowNode *loop)
For a given loop, return the end-iterator of its subtree (the iterator after the last descendant loop...
std::unordered_set< sdfg::structured_control_flow::ControlFlowNode * > ancestors(sdfg::structured_control_flow::ControlFlowNode *loop) const
void copied_loop(structured_control_flow::ControlFlowNode *existing_loop, structured_control_flow::ControlFlowNode *new_parent_loop, structured_control_flow::ControlFlowNode *new_loop, bool start_not_end=false)
const std::vector< structured_control_flow::ControlFlowNode * > & loops_in_pre_order() const
Loops in Pre-order.
std::vector< sdfg::structured_control_flow::ControlFlowNode * >::const_iterator get_loop_iterator(structured_control_flow::ControlFlowNode *loop)
bool invalidate(structured_control_flow::ControlFlowNode &changed) override
Updates the nest of the outermost loop around changed, the only nest whose infos depend on it,...
const LocalLoopInfo & loop_info_local(structured_control_flow::ControlFlowNode *loop) const
const std::vector< structured_control_flow::ControlFlowNode * > & outermost_loops() const
void removed_loop(structured_control_flow::ControlFlowNode *existing_loop)
LoopInfo loop_info(structured_control_flow::ControlFlowNode *loop) const
void dump_to_file(std::filesystem::path file) const
std::string name() const override
Definition loop_analysis.h:189
const std::vector< structured_control_flow::ControlFlowNode * > loops() const
Currently guaranteed to be in Pre-Order.
LoopAnalysis(StructuredSDFG &sdfg)
void moved_loop(structured_control_flow::ControlFlowNode *existing_loop, structured_control_flow::StructuredLoop *new_parent, bool start_not_end=false)
void run(analysis::AnalysisManager &analysis_manager) override
const std::vector< structured_control_flow::ControlFlowNode * > outermost_maps() const
std::unordered_set< sdfg::structured_control_flow::ControlFlowNode * > descendants(sdfg::structured_control_flow::ControlFlowNode *loop) const
void added_local_contents(structured_control_flow::ControlFlowNode *loop, bool side_effects, bool non_perfectly_nested)
structured_control_flow::ControlFlowNode * parent_loop(structured_control_flow::ControlFlowNode *loop) const
const std::unordered_map< structured_control_flow::ControlFlowNode *, structured_control_flow::ControlFlowNode * > & loop_tree() const
Tree of parents of nodes.
structured_control_flow::ControlFlowNode * find_loop_by_indvar(const std::string &indvar)
std::list< std::vector< sdfg::structured_control_flow::ControlFlowNode * > > loop_tree_paths(sdfg::structured_control_flow::ControlFlowNode *loop) const
const std::vector< sdfg::structured_control_flow::ControlFlowNode * > & children(sdfg::structured_control_flow::ControlFlowNode *node) const
bool is_outermost_loop(structured_control_flow::ControlFlowNode *loop) const
Base class for all structured control flow nodes in a StructuredSDFG.
Definition control_flow_node.h:44
Represents a parallel map loop with configurable scheduling.
Definition map.h:47
A sequential container of control flow nodes.
Definition sequence.h:52
Base class for structured loop constructs.
Definition structured_loop.h:244
#define LOOP_INFO_PROPERTIES
Definition loop_analysis.h:12
nlohmann::json loop_info_to_json(LoopInfo info)
Definition loop_analysis.h:76
void loop_info_local_to_json(nlohmann::json &j, const LocalLoopInfo &info)
Meant to contain only per-loop data (does not reflect what loops nested inside do / have) This is a p...
Definition loop_analysis.h:50
bool is_elementwise
Definition loop_analysis.h:64
uint32_t last_child_id
ID of the last child.
Definition loop_analysis.h:61
LoopType
Definition loop_analysis.h:51
@ For
Definition loop_analysis.h:51
@ While
Definition loop_analysis.h:51
@ Map
Definition loop_analysis.h:51
bool contains_non_perfectly_nested
The loop contains anything other than a direct child loop.
Definition loop_analysis.h:69
uint32_t loop_id
Unique ID for each loop, not just loop nests.
Definition loop_analysis.h:56
uint32_t loop_level
Definition loop_analysis.h:62
bool contains_side_effects
The loop contains side-effects directly in its body (does not include anything that happens in child ...
Definition loop_analysis.h:73
LoopType type
Definition loop_analysis.h:63
Definition loop_analysis.h:103
uint32_t last_child_id
Definition loop_analysis.h:104
LoopInfo nest
Definition loop_analysis.h:105
Definition loop_analysis.h:99
LocalLoopInfo local
Definition loop_analysis.h:100
LoopInfo nest
Definition loop_analysis.h:101
is_perfectly_nested: is the entire loop hierarchy with loop at the top perfectly nested on every leve...
Definition loop_analysis.h:38