PandA-2024.02
loop.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
44 #include "loop.hpp"
46 
47 #include "basic_block.hpp"
48 #include "exceptions.hpp"
49 #include "function_behavior.hpp" // for BBGraphRef
50 #include "op_graph.hpp"
51 #include "tree_basic_block.hpp"
52 #include <boost/graph/adjacency_list.hpp>
53 #include <boost/graph/filtered_graph.hpp>
54 #include <boost/tuple/tuple.hpp> // for tie
55 #include <iosfwd>
56 #include <limits>
57 
58 #pragma GCC diagnostic push
59 #pragma GCC diagnostic error "-Weffc++"
60 
62 
64  : g(_g),
65  is_innermost_loop(false),
66  parent_loop(),
67  children(),
68  blocks(),
69  exits(),
70  landing_pads(),
71  primary_landing_pad_block(NULL_VERTEX),
72  header_block(NULL_VERTEX),
73  alternative_entries(),
74  loop_id(curr_unused_irreducible_id--),
75  exit_landing_association(),
76  sp_back_edges(),
77  depth(0),
78  loop_type(UNKNOWN_LOOP),
79  footprint_size(0),
80  instruction_size(0),
81  body_start(NULL_VERTEX),
82  main_iv(0),
83  init(tree_nodeRef()),
84  init_gimple_id(0),
85  inc_id(0),
86  increment(0),
87  increment_tn(),
88  lower_bound(0),
89  upper_bound(0),
90  upper_bound_tn(),
91  close_interval(false)
92 {
93 }
94 
95 Loop::Loop(const BBGraphRef _bb_graph, vertex _header_block)
96  : g(_bb_graph),
98  parent_loop(),
99  children(),
100  blocks(),
101  exits(),
102  landing_pads(),
104  header_block(_header_block),
106  loop_id(0),
108  sp_back_edges(),
109  depth(0),
111  footprint_size(0),
112  instruction_size(0),
114  main_iv(0),
115  init(tree_nodeRef()),
116  init_gimple_id(0),
117  inc_id(0),
118  increment(0),
119  increment_tn(),
120  lower_bound(0),
121  upper_bound(0),
122  upper_bound_tn(),
124 {
125  const BBNodeInfoConstRef bb_node_info = g->CGetBBNodeInfo(_header_block);
126  loop_id = bb_node_info->block->number;
127  add_block(_header_block);
128  alternative_entries.insert(_header_block);
129 }
130 
131 unsigned int Loop::GetId() const
132 {
133  return loop_id;
134 }
135 
137 {
138  return header_block;
139 }
140 
141 bool Loop::is_innermost() const
142 {
143  return (children.size() == 0);
144 }
145 
146 bool Loop::IsReducible() const
147 {
148  return header_block != NULL_VERTEX;
149 }
150 
151 size_t Loop::num_blocks() const
152 {
153  return blocks.size();
154 }
155 
157 {
158  return blocks;
159 }
160 
161 size_t Loop::num_exits() const
162 {
163  return exits.size();
164 }
165 
166 std::list<vertex>::const_iterator Loop::exit_block_iter_begin() const
167 {
168  return exits.begin();
169 }
170 
171 std::list<vertex>::const_iterator Loop::exit_block_iter_end() const
172 {
173  return exits.end();
174 }
175 
177 {
178  return landing_pads.size();
179 }
180 
182 {
183  return landing_pads;
184 }
185 
187 {
189  vertex candidate = NULL_VERTEX;
190  bool first = true;
191  for(lp_iter = landing_pads.begin(); lp_iter != lp_end; ++lp_iter)
192  {
193  vertex lp = *lp_iter;
194 
195  if(candidate == NULL_VERTEX)
196  {
197  candidate = lp;
198  continue;
199  }
200 
201  graph::out_edge_iterator e_out_iter, e_out_iter_end;
202  vertex test_candidate = NULL_VERTEX;
203  for(boost::tie(e_out_iter, e_out_iter_end) = boost::out_edges(lp, *g); e_out_iter != e_out_iter_end; ++e_out_iter)
204  {
205  if(test_candidate == NULL_VERTEX)
206  {
207  test_candidate = boost::target(*e_out_iter, *g);
208  }
209  else
210  {
211  test_candidate = NULL_VERTEX;
212  }
213  }
214  if(test_candidate != candidate)
215  {
216  if(first)
217  {
218  // If candidate has a single successor which is test_candidate, then test_candidate is our
219  // new candidate
220  graph::out_edge_iterator e_iter, e_iter_end;
221  first = false;
222  for(boost::tie(e_iter, e_iter_end) = boost::out_edges(candidate, *g); e_iter != e_iter_end; ++e_iter)
223  {
224  if(boost::target(*e_out_iter, *g) != test_candidate)
225  {
226  return NULL_VERTEX;
227  }
228  }
229  }
230  else
231  {
232  return NULL_VERTEX;
233  }
234  }
235  }
236  return candidate;
237 }
238 
239 const LoopRef Loop::Parent() const
240 {
241  return parent_loop;
242 }
243 
245 {
246  parent_loop = LoopRef(_parent.get(), null_deleter());
247 }
248 
250 {
251  exits.clear();
252  landing_pads.clear();
253 
254  CustomUnorderedSet<vertex> belonging;
255  get_recursively_bb(belonging);
256 
257  CustomUnorderedSet<vertex>::iterator source, source_end;
258  source_end = belonging.end();
259  for(source = belonging.begin(); source != source_end; ++source)
260  {
261  vertex block = *source;
262  graph::out_edge_iterator e_out_iter, e_out_iter_end;
263  for(boost::tie(e_out_iter, e_out_iter_end) = boost::out_edges(block, *g); e_out_iter != e_out_iter_end;
264  ++e_out_iter)
265  {
266  vertex target = boost::target(*e_out_iter, *g);
267  // If target does not belong to this loop, then this is an exit block
268  if(belonging.find(target) == belonging.end())
269  {
270  // This is an exit block.
271  exits.push_back(block);
272  // Update the landing pad info
273  landing_pads.insert(target);
274 
275  // setting the map exit_landing_association
276  exit_landing_association[block].insert(target);
277  }
278  }
279  }
280 }
281 
283 {
284  blocks.insert(block);
285 }
286 
288 {
289  children.insert(child);
290 }
291 
293 {
294  ret.insert(blocks.begin(), blocks.end());
296  for(child = children.begin(); child != child_end; ++child)
297  {
298  (*child)->get_recursively_bb(ret);
299  }
300 }
301 
303 {
304  THROW_ASSERT(boost::num_vertices(*op_graph), "Operation graph not yet built");
305  OpVertexSet ret(op_graph);
306  CustomUnorderedSet<vertex> bb_vertices;
307  get_recursively_bb(bb_vertices);
308  CustomUnorderedSet<vertex>::const_iterator it, it_end = bb_vertices.end();
309  for(it = bb_vertices.begin(); it != it_end; ++it)
310  {
311  const BBNodeInfoConstRef bb_node_info = g->CGetBBNodeInfo(*it);
312  ret.insert(bb_node_info->statements_list.begin(), bb_node_info->statements_list.end());
313  }
314  return ret;
315 }
316 
317 const std::map<vertex, CustomUnorderedSet<vertex>>& Loop::get_exit_landing_association() const
318 {
320 }
321 
323 {
324  return children;
325 }
326 #pragma GCC diagnostic pop
Loop(const BBGraphRef g)
Constructor for empty loop (used for irreducible)
Definition: loop.cpp:63
std::list< vertex > exits
exit blocks for this loop
Definition: loop.hpp:178
void SetParent(LoopRef parent)
Sets parent for this loop.
Definition: loop.cpp:244
vertex body_start
body start basic block (at the moment defined only for SIMPLE_LOOP & WHILE_LOOP)
Definition: loop.hpp:218
bool close_interval
flag for induction variable close interval defined when loop_type is COUNTABLE_LOOP ...
Definition: loop.hpp:252
long long instruction_size
loop instruction footprint
Definition: loop.hpp:215
bool is_innermost_loop
tells if there aren&#39;t loop nested in this
Definition: loop.hpp:166
std::map< vertex, CustomUnorderedSet< vertex > > exit_landing_association
Map storing the association between an exit basic block and the corresponding landing pads...
Definition: loop.hpp:196
void AddChild(LoopRef child)
Adds a child loop.
Definition: loop.cpp:287
long long footprint_size
loop memory footprint
Definition: loop.hpp:212
refcount< Loop > parent_loop
Parent loop.
Definition: loop.hpp:169
tree_nodeRef upper_bound_tn
Final value of induction variable.
Definition: loop.hpp:248
const LoopRef Parent() const
returns the parent loop
Definition: loop.cpp:239
string target
Definition: lenet_tvm.py:16
vertex primary_landing_pad() const
Definition: loop.cpp:186
integer_cst_t lower_bound
Initial value of induction variable defined when loop_type is COUNTABLE_LOOP.
Definition: loop.hpp:241
int loop_type
loop type
Definition: loop.hpp:209
exceptions managed by PandA
void add_block(vertex block)
adds a block to this loop
Definition: loop.cpp:282
const BBGraphRef g
The basic block control flow graph.
Definition: loop.hpp:163
const CustomUnorderedSet< vertex > & get_blocks() const
returns the blocks
Definition: loop.cpp:156
size_t num_exits() const
Definition: loop.cpp:161
CustomOrderedSet< LoopConstRef > children
Child loops.
Definition: loop.hpp:172
std::list< vertex >::const_iterator exit_block_iter_end() const
Definition: loop.cpp:171
Data structure describing a basic block at tree level.
CustomOrderedSet< vertex > alternative_entries
in case the loop is irreducible the loop has multiple entries while for reducible loops the entry is ...
Definition: loop.hpp:190
std::list< vertex >::const_iterator exit_block_iter_begin() const
Definition: loop.cpp:166
A set of operation vertices.
Definition: op_graph.hpp:654
#define UNKNOWN_LOOP
unknown loop
Definition: loop.hpp:123
const CustomUnorderedSet< vertex > GetLandingPadBlocks() const
Return the landing pads of the loops.
Definition: loop.cpp:181
#define max
Definition: backprop.h:17
tree_nodeRef init
value of the initialization of the induction variable
Definition: loop.hpp:224
size_t num_blocks() const
returns the number of basic blocks belonging to this loop
Definition: loop.cpp:151
CustomUnorderedSet< vertex > blocks
Blocks which belong to this loop.
Definition: loop.hpp:175
OpVertexSet GetRecursivelyOps(const OpGraphConstRef op_graph) const
Returns the operation which belongs to this loop or to a nested loop.
Definition: loop.cpp:302
unsigned int inc_id
The node id containing the increment statement.
Definition: loop.hpp:231
unsigned int loop_id
the id of the loop
Definition: loop.hpp:193
const std::map< vertex, CustomUnorderedSet< vertex > > & get_exit_landing_association() const
Returns the map exit_landing_association.
Definition: loop.cpp:317
integer_cst_t upper_bound
Final value of induction variable defined when loop_type is COUNTABLE_LOOP.
Definition: loop.hpp:245
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
CustomUnorderedSet< vertex > landing_pads
landing_pads for this loop
Definition: loop.hpp:181
tree_nodeRef increment_tn
Increment of induction variable.
Definition: loop.hpp:237
This struct specifies the block node.
Definition: tree_node.hpp:1820
unsigned int init_gimple_id
The index of the gimple tree node containing the initialization of the induction variable; right oper...
Definition: loop.hpp:228
null deleter
Definition: refcount.hpp:51
void init(int bucket[BUCKETSIZE])
Definition: sort.c:42
unsigned int GetId() const
returns the loop id
Definition: loop.cpp:131
void ComputeLandingPadExits()
compute landing pad exits
Definition: loop.cpp:249
size_t num_landing_pads() const
Definition: loop.cpp:176
bool is_innermost() const
tells if the loop is innermost
Definition: loop.cpp:141
vertex GetHeader() const
returns loop header
Definition: loop.cpp:136
CustomOrderedSet< std::pair< vertex, vertex > > sp_back_edges
set of vertex pairs describing a spanning tree back edge for the loop
Definition: loop.hpp:202
Class specification of the basic_block structure.
interface of a loop
const BBNodeInfoConstRef CGetBBNodeInfo(const vertex node) const
Return the info associated with a basic block.
Data structures used in operations graph.
T * get() const
Definition: refcount.hpp:169
refcount< Loop > LoopRef
refcount definition of the class
Definition: loop.hpp:406
void get_recursively_bb(CustomUnorderedSet< vertex > &ret) const
Returns the basic blocks which belong to this loop and to loop nested in this loop.
Definition: loop.cpp:292
static unsigned int curr_unused_irreducible_id
used to label irreducible loops
Definition: loop.hpp:199
list children
Definition: test_panda.py:872
integer_cst_t increment
Increment of induction variable.
Definition: loop.hpp:234
bool IsReducible() const
tells if the loop is reducible
Definition: loop.cpp:146
vertex primary_landing_pad_block
???
Definition: loop.hpp:184
const CustomOrderedSet< LoopConstRef > & GetChildren() const
Returns the children of this loop in the loop forest.
Definition: loop.cpp:322
unsigned int depth
Nesting depth of this loop.
Definition: loop.hpp:206
#define NULL_VERTEX
null vertex definition
Definition: graph.hpp:1305
unsigned int main_iv
the main induction variable of countable loop;
Definition: loop.hpp:221
A brief description of the C++ Header File.
vertex header_block
the header of the loop
Definition: loop.hpp:187
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

Generated on Mon Feb 12 2024 13:02:50 for PandA-2024.02 by doxygen 1.8.13