PandA-2024.02
FSM_NI_SSA_liveness.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  */
45 #include "FSM_NI_SSA_liveness.hpp"
47 
49 #include "Parameter.hpp"
50 
52 #include "basic_block.hpp"
53 #include "function_behavior.hpp"
54 #include "op_graph.hpp"
55 
57 #include "hls.hpp"
58 #include "hls_constraints.hpp"
59 #include "hls_manager.hpp"
60 
62 #include "liveness.hpp"
63 
65 #include "memory.hpp"
66 
70 
72 #include "behavioral_helper.hpp"
73 #include "tree_helper.hpp"
74 #include "tree_manager.hpp"
75 #include "tree_node.hpp"
76 
78 #include "dbgPrintHelper.hpp"
79 
80 #include "string_manipulation.hpp" // for GET_CLASS
81 #include <boost/foreach.hpp>
82 #include <boost/range/adaptor/reversed.hpp>
83 
85  unsigned int _funId, const DesignFlowManagerConstRef _design_flow_manager)
86  : liveness_computer(_parameters, _HLSMgr, _funId, _design_flow_manager, HLSFlowStep_Type::FSM_NI_SSA_LIVENESS)
87 {
88  debug_level = parameters->get_class_debug_level(GET_CLASS(*this));
89 }
90 
92 
94 {
97 }
98 
99 static inline unsigned int get_bb_index_from_state_info(const OpGraphConstRef data, StateInfoConstRef state_info)
100 {
101  if(state_info->executing_operations.empty())
102  {
103  if(state_info->ending_operations.empty())
104  {
105  return *state_info->BB_ids.begin(); // it may happen with pipelined operations
106  }
107  else
108  {
109  return GET_BB_INDEX(data, *(state_info->ending_operations).rbegin());
110  }
111  }
112  else
113  {
114  return GET_BB_INDEX(data, *(state_info->executing_operations.rbegin()));
115  }
116 }
117 
119  const OpGraphConstRef data, vertex current_state, vertex prev_state)
120 {
121  const auto state_info = stg->CGetStateInfo(prev_state);
122  for(const auto& exec_op : state_info->executing_operations)
123  {
124  const CustomSet<unsigned int>& scalar_uses = data->CGetOpNodeInfo(exec_op)->GetVariables(
126 
127  for(const auto scalar_use : scalar_uses)
128  {
129  if(HLSMgr->is_register_compatible(scalar_use))
130  {
131  HLS->Rliv->set_live_out(current_state, scalar_use);
132  }
133  }
134  }
135 
136  for(const auto& end_op : state_info->ending_operations)
137  {
138  const CustomSet<unsigned int>& scalar_defs = data->CGetOpNodeInfo(end_op)->GetVariables(
140 
141  for(const auto scalar_def : scalar_defs)
142  {
143  if(HLSMgr->is_register_compatible(scalar_def))
144  {
145  HLS->Rliv->erase_el_live_out(current_state, scalar_def);
146  }
147  }
148  }
149 
150  if(not state_info->moved_op_use_set.empty())
151  {
152  HLS->Rliv->set_live_out(current_state, stg->CGetStateInfo(prev_state)->moved_op_use_set);
153  }
154 }
155 
157 {
158  const StateTransitionGraphConstRef astg = HLS->STG->CGetAstg();
160  const FunctionBehaviorConstRef FB = HLSMgr->CGetFunctionBehavior(funId);
163 
166  BOOST_FOREACH(vertex v, boost::vertices(*fbb))
167  {
168  bb_index_map[fbb->CGetBBNodeInfo(v)->get_bb_index()] = v;
169  }
170 
171  /*
172  * vertex of the STG analyzed in reverse order. N.B.: the reversed list is
173  * taken from the astg (Acyclic State Transition Graph), so this may affect
174  * the position of certain states in the list, depending on the presence of
175  * feedback edges
176  */
177  std::deque<vertex> reverse_order_state_list;
178  astg->ReverseTopologicalSort(reverse_order_state_list);
179  vertex exit_state = HLS->STG->get_exit_state();
180  std::deque<vertex> dummy_states;
181 
186  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "-->Computing preliminary information for liveness computation");
187  for(const auto& rosl : reverse_order_state_list)
188  {
189  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "-->Setting up state " + HLS->STG->get_state_name(rosl));
190  HLS->Rliv->add_name(rosl, HLS->STG->get_state_name(rosl));
191  HLS->Rliv->add_support_state(rosl);
192 
193  // skip exit state
194  if(rosl == exit_state)
195  {
196  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Is exit state");
197  continue;
198  }
199 
200  // compute which operation defines a variable (add_op_definition)
201  // compute in which states an operation complete the computation (add_state_for_ending_op)
202  const StateInfoConstRef state_info = astg->CGetStateInfo(rosl);
203  for(const auto& eoc : state_info->ending_operations) // these also include the moved ending operations
204  {
205  const CustomSet<unsigned int>& scalar_defs = data->CGetOpNodeInfo(eoc)->GetVariables(
207 
208  for(const auto scalar_def : scalar_defs)
209  {
210  if(HLSMgr->is_register_compatible(scalar_def))
211  {
212  HLS->Rliv->add_op_definition(scalar_def, eoc);
213  }
214  }
215 
216  HLS->Rliv->add_state_for_ending_op(eoc, rosl);
217  }
218 
219  // add dummy state
220  if(state_info->is_dummy)
221  {
222  dummy_states.push_back(rosl);
223  HLS->Rliv->add_dummy_state(rosl);
224  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Is dummy state");
225  continue;
226  }
227 
228  /*
229  * handle states that contain moved operations coming from other states
230  * (possibly coming from other BBs as well)
231  */
232  if(not state_info->moved_op_use_set.empty())
233  {
234  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "-->Contains moved operations");
235 #ifndef NDEBUG
238  {
239  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "---Used by moved operations:");
240  for(const auto& var_id : state_info->moved_op_use_set)
241  {
243  }
244  }
245 #endif
246  /*
247  * if rosl contains a moved operation, then the use set of the moved
248  * operation must be in the live in of the state
249  */
251  "Adding to the live in of state:" + HLS->STG->get_state_name(rosl));
252  HLS->Rliv->set_live_in(rosl, state_info->moved_op_use_set);
253  /*
254  * if rosl contains a moved operation, we have to add the used set to
255  * the live out of the predecessors of rosl
256  */
257  BOOST_FOREACH(EdgeDescriptor e, boost::in_edges(rosl, *stg))
258  {
259  vertex src_state = boost::source(e, *stg);
261  "Adding to the live out of predecessor state:" + HLS->STG->get_state_name(src_state));
262  HLS->Rliv->set_live_out(src_state, state_info->moved_op_use_set);
263  }
265  }
266  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Set up state " + HLS->STG->get_state_name(rosl));
267  }
268  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Computed preliminary information for liveness computation");
269 
271  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "-->Computing live_out");
272  const vertex bb_exit = fbb->CGetBBGraphInfo()->exit_vertex;
273  unsigned int prev_bb_index = fbb->CGetBBNodeInfo(bb_exit)->get_bb_index();
274  vertex prev_state = exit_state;
276  "---prev_state: " + stg->CGetStateInfo(prev_state)->name + " prev_bb_index: " + STR(prev_bb_index));
277  for(const auto& rosl : reverse_order_state_list)
278  {
280  "-->Computing live out for state " + HLS->STG->get_state_name(rosl));
281  // skip exit state
282  if(rosl == exit_state)
283  {
284  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Is exit state");
285  continue;
286  }
287 
288  StateInfoConstRef state_info = astg->CGetStateInfo(rosl);
289  // skip dummy states
290  if(state_info->is_dummy)
291  {
292  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Is dummy state");
293  continue;
294  }
295 
296  // handle duplicated states
297  if(state_info->is_duplicated)
298  {
299  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "Is duplicated state");
300  if(state_info->isOriginalState)
301  {
302  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "---Is the original copy");
303  StateInfoConstRef cloned_state_info = astg->CGetStateInfo(rosl);
304  unsigned int cloned_bb_index = *cloned_state_info->BB_ids.begin();
305  prev_state = rosl;
306  prev_bb_index = cloned_bb_index;
308  "---update prev_state: " + stg->CGetStateInfo(prev_state)->name +
309  " prev_bb_index: " + STR(prev_bb_index));
310  }
311  else
312  {
313  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "---Is the cloned copy");
314  THROW_ASSERT(state_info->clonedState != NULL_VERTEX, "");
315  StateInfoConstRef cloned_state_info = astg->CGetStateInfo(state_info->clonedState);
316  unsigned int cloned_bb_index = *cloned_state_info->BB_ids.begin();
317  bool found = false;
318  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---cloned_bb_index: " + STR(cloned_bb_index));
320  "-->Considering successors of: " + cloned_state_info->name);
321  BOOST_FOREACH(EdgeDescriptor oe, boost::out_edges(state_info->clonedState, *astg))
322  {
323  vertex target_state = boost::target(oe, *astg);
324  StateInfoConstRef target_state_info = astg->CGetStateInfo(target_state);
325  unsigned int target_bb_index = *target_state_info->BB_ids.begin();
326  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "successor: " + target_state_info->name);
327  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "target_bb_index: " + STR(target_bb_index));
328  if(cloned_bb_index == target_bb_index and target_state != rosl)
329  {
331  "---updating live out of : " + state_info->name + ", " + cloned_state_info->name);
333  "---adding live out of : " + target_state_info->name);
334  HLS->Rliv->set_live_out(rosl, HLS->Rliv->get_live_out(target_state));
335  HLS->Rliv->set_live_out(state_info->clonedState, HLS->Rliv->get_live_out(target_state));
336  update_liveout_with_prev(HLSMgr, HLS, stg, data, state_info->clonedState, target_state);
337  update_liveout_with_prev(HLSMgr, HLS, stg, data, rosl, target_state);
338  found = true;
339  }
340  }
342  "<--Considered successors of: " + cloned_state_info->name);
343 
344  if(not found)
345  {
346  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "no valid successors found");
347  for(const auto lo : fbb->CGetBBNodeInfo(bb_index_map[cloned_bb_index])->get_live_out())
348  {
349  if(HLSMgr->is_register_compatible(lo))
350  {
351 #ifndef NDEBUG
354  "---adding to live out of " + state_info->name + " var " + BH->PrintVariable(lo));
356  "---adding to live out of " + cloned_state_info->name + " var " +
357  BH->PrintVariable(lo));
358 #endif
359  HLS->Rliv->set_live_out(rosl, lo);
360  HLS->Rliv->set_live_out(state_info->clonedState, lo);
361  }
362  }
363  }
364  prev_state = rosl;
365  prev_bb_index = cloned_bb_index;
367  "---update prev_state: " + stg->CGetStateInfo(prev_state)->name +
368  " prev_bb_index: " + STR(prev_bb_index));
369  }
371  continue;
372  }
373 
374  unsigned int bb_index = get_bb_index_from_state_info(data, state_info);
375  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---bb_index: " + STR(bb_index));
376 
377  if(prev_bb_index != bb_index)
378  {
380  "---prev_bb_index " + STR(prev_bb_index) + " != bb_index " + STR(bb_index));
382  "---adding live out of BB " + STR(bb_index) + " to live out of state " + state_info->name);
383  for(const auto lo : fbb->CGetBBNodeInfo(bb_index_map[bb_index])->get_live_out())
384  {
385  if(HLSMgr->is_register_compatible(lo))
386  {
387  HLS->Rliv->set_live_out(rosl, lo);
388  }
389  }
390  }
391  else
392  {
394  "---adding live out of " + stg->CGetStateInfo(prev_state)->name + " to live out of state " +
395  state_info->name);
396  HLS->Rliv->set_live_out(rosl, HLS->Rliv->get_live_out(prev_state));
397  update_liveout_with_prev(HLSMgr, HLS, stg, data, rosl, prev_state);
398  }
399  prev_state = rosl;
400  prev_bb_index = bb_index;
402  "---update prev_state: " + stg->CGetStateInfo(prev_state)->name +
403  " prev_bb_index: " + STR(prev_bb_index));
405  "<--Computed live out for state " + HLS->STG->get_state_name(rosl));
406  }
407  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Computed live out");
408 
410  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "-->Computing live in");
411  vertex entry_state = HLS->STG->get_entry_state();
412  prev_state = entry_state;
413  CustomOrderedSet<vertex> state_to_skip;
414  for(const auto& osl : boost::adaptors::reverse(reverse_order_state_list))
415  {
416  const StateInfoConstRef state_info = astg->CGetStateInfo(osl);
417  if(state_to_skip.find(osl) != state_to_skip.end())
418  {
419  prev_state = osl;
420  prev_bb_index = *state_info->BB_ids.begin();
421  continue;
422  }
423 
424  if(state_info->is_dummy)
425  {
426  continue;
427  }
428 
429  if(state_info->is_duplicated)
430  {
431  unsigned int bb_index = *state_info->BB_ids.begin();
432  for(const auto li : fbb->CGetBBNodeInfo(bb_index_map[bb_index])->get_live_in())
433  {
434  if(HLSMgr->is_register_compatible(li))
435  {
436  HLS->Rliv->set_live_in(osl, li);
437  }
438  }
439 
440  BOOST_FOREACH(EdgeDescriptor oe, boost::out_edges(osl, *astg))
441  {
442  vertex target_state = boost::target(oe, *astg);
443  StateInfoConstRef target_state_info = astg->CGetStateInfo(target_state);
444  unsigned int target_bb_index = *target_state_info->BB_ids.begin();
445  if(bb_index == target_bb_index && !target_state_info->is_duplicated)
446  {
447  HLS->Rliv->set_live_in(target_state, HLS->Rliv->get_live_out(osl));
448  state_to_skip.insert(target_state);
449  }
450  }
451  prev_state = osl;
452  prev_bb_index = bb_index;
453  continue;
454  }
455 
456  unsigned int bb_index = get_bb_index_from_state_info(data, state_info);
457  if(prev_bb_index != bb_index)
458  {
459  for(const auto li : fbb->CGetBBNodeInfo(bb_index_map[bb_index])->get_live_in())
460  {
461  if(HLSMgr->is_register_compatible(li))
462  {
463  HLS->Rliv->set_live_in(osl, li);
464  }
465  }
466  }
467  else
468  {
469  HLS->Rliv->set_live_in(osl, HLS->Rliv->get_live_out(prev_state));
470  }
471  prev_state = osl;
472  prev_bb_index = bb_index;
473  }
474  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Computed live in");
475 
477  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "-->Adjusting liveness of dummy states");
478  for(const auto& ds : dummy_states)
479  {
480  const StateInfoConstRef state_info = astg->CGetStateInfo(ds);
481  BOOST_FOREACH(EdgeDescriptor e, boost::in_edges(ds, *astg))
482  {
483  vertex src_state = boost::source(e, *astg);
484  HLS->Rliv->set_live_out(ds, HLS->Rliv->get_live_out(src_state));
485  HLS->Rliv->set_live_in(ds, HLS->Rliv->get_live_out(src_state));
487  for(const auto& eo : state_info->executing_operations)
488  {
489  const CustomSet<unsigned int>& scalar_uses = data->CGetOpNodeInfo(eo)->GetVariables(
491  for(const auto scalar_use : scalar_uses)
492  {
493  if(HLSMgr->is_register_compatible(scalar_use))
494  {
495  HLS->Rliv->set_live_out(src_state, scalar_use);
496  HLS->Rliv->set_live_in(ds, scalar_use);
498  BOOST_FOREACH(EdgeDescriptor oe, boost::out_edges(ds, *astg))
499  {
500  vertex target_state = boost::target(oe, *astg);
501  HLS->Rliv->set_live_in(target_state, scalar_use);
502  }
503  }
504  }
505  }
506  }
507  }
508  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Adjusted liveness of dummy states");
509 
513  for(const auto& rosl : reverse_order_state_list)
514  {
515  const StateInfoConstRef state_info = astg->CGetStateInfo(rosl);
516  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "-->Analyzing state " + state_info->name);
517  for(const auto& roc : state_info->executing_operations) // these also include the moved execution operations
518  {
519  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "-->Analyzing running operation " + GET_NAME(data, roc));
520  HLS->Rliv->add_state_for_running_op(roc, rosl);
521  if((GET_TYPE(data, roc) & TYPE_NOP) != 0)
522  {
524  "<--Analyzed running operation of type NOP" + GET_NAME(data, roc));
525  continue;
526  }
527  if((GET_TYPE(data, roc) & TYPE_PHI) != 0)
528  {
529  const auto phi_node =
530  HLSMgr->get_tree_manager()->get_tree_node_const(data->CGetOpNodeInfo(roc)->GetNodeId());
531  for(const auto& def_edge : GetPointer<const gimple_phi>(phi_node)->CGetDefEdgesList())
532  {
533  unsigned int tree_var = def_edge.first->index;
534  unsigned int bb_index = def_edge.second;
535  if(state_info->is_duplicated && !state_info->all_paths)
536  {
537  if(!state_info->isOriginalState && bb_index != state_info->sourceBb)
538  {
539  continue;
540  }
541  if(state_info->isOriginalState && bb_index == state_info->sourceBb)
542  {
543  continue;
544  }
545  unsigned int written_phi = HLSMgr->get_produced_value(HLS->functionId, roc);
546  if(state_info->moved_op_def_set.find(tree_var) != state_info->moved_op_def_set.end() or
547  state_info->moved_op_use_set.find(written_phi) != state_info->moved_op_use_set.end())
548  {
549  HLS->Rliv->set_live_out(rosl, HLS->Rliv->get_live_out(stg->CGetStateInfo(rosl)->clonedState));
550 
551  if(state_info->moved_op_use_set.find(written_phi) != state_info->moved_op_use_set.end())
552  {
553  HLS->Rliv->set_live_in(rosl, tree_var);
554  BOOST_FOREACH(EdgeDescriptor ie, boost::in_edges(rosl, *stg))
555  {
556  vertex src_vrtx = boost::source(ie, *stg);
557  HLS->Rliv->set_live_out(src_vrtx, tree_var);
558  }
559  }
560  HLS->Rliv->set_live_out(rosl, written_phi);
561  BOOST_FOREACH(EdgeDescriptor e, boost::out_edges(rosl, *stg))
562  {
563  vertex tgt_vrtx = boost::target(e, *stg);
564  HLS->Rliv->set_live_in(tgt_vrtx, written_phi);
565  }
566  }
567  }
569 #if HAVE_ASSERTS
570  bool found_state = false;
571 #endif
572  BOOST_FOREACH(EdgeDescriptor ie, boost::in_edges(rosl, *stg))
573  {
574  vertex src_state = boost::source(ie, *stg);
575  const StateInfoConstRef source_state_info = stg->CGetStateInfo(src_state);
576  const CustomOrderedSet<unsigned int>& BB_ids = source_state_info->BB_ids;
577  if(BB_ids.find(bb_index) != BB_ids.end())
578  {
580  "---Adding state in " + source_state_info->name + " " +
581  FB->CGetBehavioralHelper()->PrintVariable(tree_var) + " in state " +
582  state_info->name);
583  // THROW_ASSERT((HLS->Rliv->get_live_out(src_state).find(tree_var) !=
584  // HLS->Rliv->get_live_out(src_state).end()), "unexpected live out condition");
585  THROW_ASSERT(src_state != entry_state,
586  "Source state for phi " + STR(data->CGetOpNodeInfo(roc)->GetNodeId()) + " not found");
587  HLS->Rliv->add_state_in_for_var(def_edge.first->index, roc, rosl, src_state);
588 #if HAVE_ASSERTS
589  found_state = true;
590 #endif
591  }
592  }
593  THROW_ASSERT(found_state, "Not found source for phi " + GET_NAME(data, roc) + " in state " +
594  state_info->name + " coming from BB" + STR(bb_index));
595  }
596  }
597  else
598  {
599  BOOST_FOREACH(EdgeDescriptor oe, boost::out_edges(rosl, *stg))
600  {
601  vertex tgt_state = boost::target(oe, *stg);
602  const CustomSet<unsigned int>& scalar_defs = data->CGetOpNodeInfo(roc)->GetVariables(
604  const CustomSet<unsigned int>& cited_variables = data->CGetOpNodeInfo(roc)->cited_variables;
605  const CustomSet<unsigned int> all_but_scalar_defs = cited_variables - scalar_defs;
606  for(const auto all_but_scalar_def : all_but_scalar_defs)
607  {
608  if(HLSMgr->is_register_compatible(all_but_scalar_def))
609  {
610  HLS->Rliv->add_state_in_for_var(all_but_scalar_def, roc, rosl, tgt_state);
611  }
612  else if(HLSMgr->Rmem->has_base_address(all_but_scalar_def) or
613  tree_helper::is_parameter(HLSMgr->get_tree_manager(), all_but_scalar_def))
614  {
615  HLS->Rliv->add_state_in_for_var(all_but_scalar_def, roc, rosl, tgt_state);
616  }
617  else if(tree_helper::is_ssa_name(HLSMgr->get_tree_manager(), all_but_scalar_def) and
618  tree_helper::is_virtual(HLSMgr->get_tree_manager(), all_but_scalar_def))
619  {
620  ;
621  }
622  else
623  {
624  THROW_ERROR("unexpected condition " + STR(all_but_scalar_def));
625  }
626  }
627  }
628  }
629  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Analyzed running operation " + GET_NAME(data, roc));
630  }
631  for(const auto& eoc : state_info->ending_operations) // these also include the moved ending operations
632  {
633  if((GET_TYPE(data, eoc) & TYPE_PHI) != 0)
634  {
635  if(state_info->is_duplicated && state_info->clonedState != NULL_VERTEX && !state_info->all_paths)
636  {
637  unsigned int written_phi = HLSMgr->get_produced_value(HLS->functionId, eoc);
638  bool postponed_phi = false;
639  const auto phi_node =
640  HLSMgr->get_tree_manager()->get_tree_node_const(data->CGetOpNodeInfo(eoc)->GetNodeId());
641  for(const auto& def_edge : GetPointer<const gimple_phi>(phi_node)->CGetDefEdgesList())
642  {
643  unsigned int tree_temp = def_edge.first->index;
644  unsigned int bbID = def_edge.second;
645  if(bbID != state_info->sourceBb)
646  {
647  continue;
648  }
649  else if(state_info->moved_op_def_set.find(tree_temp) != state_info->moved_op_def_set.end())
650  {
651  postponed_phi = true;
652  }
653  else if(state_info->moved_op_use_set.find(written_phi) != state_info->moved_op_use_set.end())
654  {
655  postponed_phi = true;
656  }
657  break;
658  }
659  if(not postponed_phi)
660  {
661  continue;
662  }
663  }
664  else
665  {
666  continue;
667  }
668  }
669 
670  const CustomSet<unsigned int>& scalar_defs = data->CGetOpNodeInfo(eoc)->GetVariables(
672  for(const auto scalar_def : scalar_defs)
673  {
674  if(HLSMgr->is_register_compatible(scalar_def))
675  {
676  BOOST_FOREACH(EdgeDescriptor e, boost::out_edges(rosl, *stg))
677  {
678  vertex tgt_state = boost::target(e, *stg);
679  if(HLS->Rliv->get_live_in(tgt_state).find(scalar_def) != HLS->Rliv->get_live_in(tgt_state).end())
680  {
681  HLS->Rliv->add_state_out_for_var(scalar_def, eoc, rosl, tgt_state);
682  }
683  }
684  }
685  }
686  }
687  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Analyzed state " + state_info->name);
688  }
689 
690 #ifndef NDEBUG
692  {
695  PRINT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "STG Liveness for function " + BH->get_function_name());
696  BOOST_FOREACH(vertex v, boost::vertices(*astg))
697  {
698  PRINT_DBG_STRING(DEBUG_LEVEL_PEDANTIC, debug_level, "Live In for state " + HLS->STG->get_state_name(v) + ": ");
699  for(const auto li : HLS->Rliv->get_live_in(v))
700  {
702  }
704 
706  "Live Out for state " + HLS->STG->get_state_name(v) + ": ");
707  for(const auto lo : HLS->Rliv->get_live_out(v))
708  {
710  }
712  }
713  }
714 #endif
716 }
void add_state_in_for_var(unsigned int var, vertex op, vertex state, vertex state_in)
put into relation for a given variable used in a state the state from which the variable comes ...
Definition: liveness.cpp:195
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
Class specification to contain liveness information.
#define TYPE_NOP
constant string identifying a type for a no operation.
Definition: op_graph.hpp:130
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
const HLS_managerRef HLSMgr
information about all the HLS synthesis
Definition: hls_step.hpp:205
Data structure representing the entire HLS information.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
void add_state_out_for_var(unsigned int var, vertex op, vertex state, vertex state_in)
put into relation for a given variable defined in a state the state to which the variable goes ...
Definition: liveness.cpp:230
#define GET_TYPE(data, vertex_index)
Helper macro returning the type associated with a node.
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
void add_dummy_state(vertex state)
add a state to the set of dummy vertices
Definition: liveness.hpp:386
This file contains the structures needed to manage a graph that will represent the state transition g...
void add_state_for_running_op(vertex op, vertex v)
add a running state for a given operation
Definition: liveness.hpp:319
string target
Definition: lenet_tvm.py:16
#define GET_CLASS(obj)
Macro returning the actual type of an object.
std::string get_function_name() const
Return the name of the function.
void erase_el_live_out(const vertex &v, unsigned int var)
erase a variable from the live out
Definition: liveness.cpp:137
vertex get_entry_state() const
Gets vertex that represents state that contains entry node.
const BBGraphInfoConstRef CGetBBGraphInfo() const
Returns the property associated with the graph.
const unsigned int funId
identifier of the function to be processed (0 means that it is a global step)
void add_state_for_ending_op(vertex op, vertex v)
add an ending state for a given operation
Definition: liveness.hpp:303
#define GET_NAME(data, vertex_index)
Helper macro returning the name associated with a node.
static bool is_parameter(const tree_managerConstRef &TM, const unsigned int index)
return true in case the index corresponds to a parameter in ssa form or not
#define GET_BB_INDEX(data, vertex_index)
Macro returning the index of the basic block which the node belongs to.
Definition: op_graph.hpp:435
vertex get_exit_state() const
Gets vertex that represents state that contains exit node.
void add_support_state(vertex v)
add a support state
Definition: liveness.hpp:344
#define PRINT_DBG_STRING(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed; no newline is added;...
void set_live_in(const vertex &v, unsigned int var)
Store a variable alive at the input of the given vertex.
Definition: liveness.cpp:88
static unsigned int get_bb_index_from_state_info(const OpGraphConstRef data, StateInfoConstRef state_info)
#define TYPE_PHI
constant string identifying an operation node of type PHI
Definition: op_graph.hpp:135
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
const OpNodeInfoConstRef CGetOpNodeInfo(const vertex node) const
Returns the info associated with a node.
Definition: op_graph.hpp:843
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
Definition: custom_map.hpp:148
HLSFlowStep_Type
Definition: hls_step.hpp:95
static bool is_virtual(const tree_managerConstRef &TM, const unsigned int index)
return true in case the ssa_name is virtual
Basic block control flow graph with feedback.
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
This file contains the structures needed to manage a graph that will represent the state transition g...
const CustomOrderedSet< unsigned int > & get_live_out(const vertex &v) const
Get the set of variables live at the output of a vertex.
Definition: liveness.cpp:142
const BehavioralHelperConstRef CGetBehavioralHelper() const
Returns the helper associated with the function.
Classes specification of the tree_node data structures.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
std::string PrintVariable(unsigned int var) const
Print the name of the variable associated to the index.
DesignFlowStep_Status InternalExec() override
Execute the step.
Data structure definition for HLS constraints.
const StateTransitionGraphConstRef CGetAstg() const
Returns pointer to state transition graph created.
livenessRef Rliv
data-structure containing the variable liveness
Definition: hls.hpp:127
This file collects some utility functions.
static bool is_ssa_name(const tree_managerConstRef &TM, const unsigned int index)
Return true in case index is a ssa_name.
~FSM_NI_SSA_liveness() override
Destructor.
void set_live_out(const vertex &v, const CustomOrderedSet< unsigned int > &vars)
Store the variables alive at the output of the given vertex.
Definition: liveness.cpp:126
const OpGraphConstRef CGetOpGraph(FunctionBehavior::graph_type gt) const
This method returns the operation graphs.
Class specification of the basic_block structure.
void add_name(vertex v, const std::string &name)
define the name of a state
Definition: liveness.hpp:329
hlsRef HLS
HLS data structure of the function to be analyzed.
const BBNodeInfoConstRef CGetBBNodeInfo(const vertex node) const
Return the info associated with a basic block.
Data structures used in operations graph.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
static void update_liveout_with_prev(const HLS_managerRef HLSMgr, hlsRef HLS, const StateTransitionGraphConstRef stg, const OpGraphConstRef data, vertex current_state, vertex prev_state)
const BBGraphConstRef CGetBBGraph(FunctionBehavior::bb_graph_type gt=FunctionBehavior::BB) const
This method returns the basic block graphs.
this class is used to manage the command-line or XML options.
FSM_NI_SSA_liveness(const ParameterConstRef _parameters, const HLS_managerRef HLSMgr, unsigned int funId, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
liveness analysis exploiting the SSA form of the IR
unsigned int functionId
this is the identifier of the function to be implemented
Definition: hls.hpp:87
StateTransitionGraphManagerRef STG
Store the refcounted state transition graph.
Definition: hls.hpp:124
refcount< liveness > livenessRef
Definition: liveness.hpp:405
int debug_level
The debug level.
Data structure definition for high-level synthesis flow.
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
const StateTransitionGraphConstRef CGetStg() const
Returns pointer to state transition graph created.
void add_op_definition(unsigned int var, vertex v)
add a definition vertex for a variable
Definition: liveness.hpp:233
#define NULL_VERTEX
null vertex definition
Definition: graph.hpp:1305
Datastructure to represent memory information in high-level synthesis.
Class specification of the manager of the tree structures extracted from the raw file.
A brief description of the C++ Header File.
const CustomOrderedSet< unsigned int > & get_live_in(const vertex &v) const
Get the set of variables live at the input of a vertex.
Definition: liveness.cpp:109
std::string get_state_name(vertex state) const
Get the name of a state.
boost::graph_traits< graph >::edge_descriptor EdgeDescriptor
edge definition.
Definition: graph.hpp:1316
#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:53 for PandA-2024.02 by doxygen 1.8.13