45 #include "config_HAVE_ASSERTS.hpp" 46 #include "config_HAVE_UNORDERED.hpp" 48 #include <boost/graph/adjacency_list.hpp> 49 #include <boost/graph/filtered_graph.hpp> 50 #include <boost/iterator/filter_iterator.hpp> 51 #include <boost/iterator/iterator_facade.hpp> 52 #include <boost/tuple/tuple.hpp> 74 : design_flow_graph(_design_flow_graph)
82 const bool x_composed = x_info->design_flow_step->IsComposed();
83 const bool y_composed = y_info->design_flow_step->IsComposed();
84 const bool x_unnecessary =
86 const bool y_unnecessary =
88 if(x_composed and not y_composed)
92 else if(not x_composed and y_composed)
96 else if(x_unnecessary and not y_unnecessary)
100 else if(not x_unnecessary and y_unnecessary)
109 return x_info->design_flow_step->GetName() < y_info->design_flow_step->GetName();
119 feedback_design_flow_graph(
125 output_level(_parameters->getOption<int>(OPT_output_level))
137 step_names[design_flow_graph_info->entry] =
"Entry";
149 step_names[design_flow_graph_info->exit] =
"Exit";
172 static size_t temp_counter = 0;
174 for(
const auto& design_flow_step : steps)
176 const std::string signature = design_flow_step->GetSignature();
178 "-->Adding design flow step " + design_flow_step->GetName() +
" - Signature " + signature);
213 "---This step already exist but was unnecessary. Now it becomes necessary");
218 "Switching to necessary " + design_flow_step_info->design_flow_step->GetName() +
219 " which has already skipped");
233 step_names[step_vertex] = design_flow_step->GetName();
244 for(
const auto& relationship : relationships)
246 const std::string relationship_signature = relationship->GetSignature();
255 std::list<vertex> vertices;
271 relationships.clear();
274 for(
const auto& relationship : relationships)
276 const std::string relationship_signature = relationship->GetSignature();
285 std::list<vertex> vertices;
300 bool current_ready =
true;
302 for(boost::tie(ie, ie_end) = boost::in_edges(step_vertex, *
design_flow_graph); ie != ie_end; ie++)
306 switch(pre_info->status)
319 current_ready =
false;
336 "---Adding " + design_flow_step->GetName() +
" to list of ready steps");
349 for(boost::tie(ie, ie_end) = boost::in_edges(step_vertex, *
design_flow_graph); ie != ie_end; ie++)
364 "<--Added design flow step " + design_flow_step->GetName() +
" - Signature " + signature);
378 "---Seed for design flow manager: " +
379 STR(
parameters->isOption(OPT_test_single_non_deterministic_flow) ?
380 parameters->getOption<
size_t>(OPT_test_single_non_deterministic_flow) :
382 auto generator = std::bind(std::uniform_int_distribution<size_t>(0, 10000),
383 std::mt19937(
parameters->isOption(OPT_test_single_non_deterministic_flow) ?
384 parameters->getOption<
size_t>(OPT_test_single_non_deterministic_flow) :
395 size_t executed_passes = 0;
396 size_t skipped_passes = 0;
397 size_t graph_changes = 0;
398 long design_flow_manager_time = 0;
403 long before_time = 0;
414 "---" +
design_flow_graph->CGetDesignFlowStepInfo(ready_step)->design_flow_step->GetName());
421 if(
parameters->isOption(OPT_test_single_non_deterministic_flow))
423 const size_t random = generator();
424 const size_t offset = random % possibly_ready.size();
426 "---Random is " +
STR(random) +
" - Offset is " +
STR(offset) +
" (Size is " +
427 STR(possibly_ready.size()) +
")");
428 auto begin = possibly_ready.begin();
429 std::advance(begin, offset);
434 return *(possibly_ready.begin());
437 const auto erased_elements =
439 possibly_ready.erase(next);
443 "-->Beginning iteration number " +
STR(
step_counter) +
" - Considering step " + step->GetName());
446 for(
const auto ready_step : possibly_ready)
449 "---" +
design_flow_graph->CGetDesignFlowStepInfo(ready_step)->design_flow_step->GetName());
453 THROW_ASSERT(erased_elements == 1,
"Number of erased elements is " +
STR(erased_elements));
466 bool current_ready =
true;
467 DesignFlowStepSet::const_iterator pre_dependence_step, pre_dependence_step_end = pre_dependence_steps.end();
468 for(pre_dependence_step = pre_dependence_steps.begin(); pre_dependence_step != pre_dependence_step_end;
469 ++pre_dependence_step)
471 const vertex pre_dependence_vertex =
476 switch(pre_info->status)
489 current_ready =
false;
504 for(
const auto& pre_precedence_step : pre_precedence_steps)
506 const vertex pre_precedence_vertex =
511 switch(pre_info->status)
524 current_ready =
false;
538 if(not current_ready)
550 for(boost::tie(temp_step, temp_step_end) = boost::vertices(*
design_flow_graph); temp_step != temp_step_end;
567 if(final_number_vertices > initial_number_vertices or final_number_edges > initial_number_edges)
576 design_flow_manager_time += before_time;
581 "---Skipping execution of " + step->GetName() +
" since unnecessary");
584 else if(step->HasToBeExecuted())
590 long step_execution_time = 0;
591 if(OUTPUT_LEVEL_VERY_PEDANTIC <= output_level || parameters->IsParameter(
"profile_steps"))
598 step->PrintInitialIR();
600 design_flow_step_info->status = step->Exec();
604 step->PrintFinalIR();
606 if(OUTPUT_LEVEL_VERY_PEDANTIC <= output_level || parameters->IsParameter(
"profile_steps"))
610 const std::string memory_usage =
632 "<--Ended execution of " + step->GetName() +
636 " in " +
print_cpu_time(step_execution_time) +
" seconds" + memory_usage);
658 bool invalidations =
false;
659 if(not
parameters->IsParameter(
"disable-invalidations"))
666 invalidations = not relationships.empty();
667 DesignFlowStepSet::const_iterator relationship, relationship_end = relationships.end();
668 for(relationship = relationships.begin(); relationship != relationship_end; ++relationship)
670 const std::string relationship_signature = (*relationship)->GetSignature();
672 THROW_ASSERT(relationship_vertex,
"Missing vertex " + relationship_signature);
684 design_flow_graph->CGetDesignFlowStepInfo(relationship_vertex)->design_flow_step->GetName() +
685 " which is not before the current one");
692 for(boost::tie(oe, oe_end) = boost::out_edges(next, *
design_flow_graph); oe != oe_end; oe++)
696 switch(target_info->status)
724 "-->Examining successor " +
726 bool target_ready =
true;
728 for(boost::tie(ie, ie_end) = boost::in_edges(target, *
design_flow_graph); ie != ie_end; ie++)
733 "-->Examining predecessor " + source_info->design_flow_step->GetName());
734 switch(source_info->status)
746 target_ready =
false;
751 target_ready =
false;
776 " to list of ready steps");
777 possibly_ready.insert(target);
784 for(boost::tie(ie, ie_end) =
791 to_be_removeds.insert(*ie);
794 for(
const auto& to_be_removed : to_be_removeds)
806 for(boost::tie(temp_step, temp_step_end) = boost::vertices(*
design_flow_graph); temp_step != temp_step_end;
823 design_flow_manager_time += after_time;
826 "<--Ended iteration number " +
STR(
step_counter) +
" - Step " + step->GetName());
831 if(final_number_vertices > initial_number_vertices or final_number_edges > initial_number_edges or
836 if(
parameters->GetParameter<
size_t>(
"dfm_statistics") > 1)
839 size_t executed_vertices = 0;
840 static size_t previous_executed_vertices = 0;
841 for(boost::tie(v_stat, v_stat_end) = boost::vertices(*
design_flow_graph); v_stat != v_stat_end; v_stat++)
845 switch(local_design_flow_step_info->status)
872 if(previous_executed_vertices > executed_vertices)
875 "dfm_statistics - number of invalidated vertices by " + step->GetName() +
": " +
876 STR(previous_executed_vertices - executed_vertices));
879 "dfm_statistics - number of vertices at the end of iteration " +
STR(
step_counter) +
": " +
880 STR(executed_vertices) +
" / " +
STR(final_number_vertices));
882 "dfm_statistics - number of edges at the end of iteration " +
STR(
step_counter) +
": " +
883 STR(final_number_edges));
884 previous_executed_vertices = executed_vertices;
891 for(
size_t writing_step_counter = 0; writing_step_counter <
step_counter; writing_step_counter++)
896 "-->Writing Design_Flow_History_" +
STR(writing_step_counter));
900 "<--Written Design_Flow_History_" +
STR(writing_step_counter));
917 "dfm_statistics - number of vertices in final graph: " +
920 "dfm_statistics - number of edges in final graph: " +
STR(boost::num_edges(*
design_flow_graph)));
922 "dfm_statistics - number of executed passes: " +
STR(executed_passes));
924 "dfm_statistics - number of skipped passes: " +
STR(skipped_passes));
926 "dfm_statistics - number of graph changes: " +
STR(graph_changes));
928 "dfm_statistics - design flow manager time: " +
print_cpu_time(design_flow_manager_time) +
958 "No factory to create steps with prefix " + prefix +
" found");
972 "---DeExecuting " + design_flow_step_info->design_flow_step->GetName());
973 switch(design_flow_step_info->status)
1016 bool current_ready =
true;
1018 for(boost::tie(ie, ie_end) = boost::in_edges(starting_vertex, *
design_flow_graph); ie != ie_end; ie++)
1022 switch(pre_info->status)
1035 current_ready =
false;
1056 for(boost::tie(oe, oe_end) = boost::out_edges(starting_vertex, *
design_flow_graph); oe != oe_end; oe++)
1060 switch(target_info->status)
1104 THROW_ASSERT(signature.find(
"::") != std::string::npos, signature);
1105 const auto prefix = signature.substr(0, signature.find(
"::"));
1112 std::map<size_t, UnorderedSetStdStable<vertex>> sccs;
1114 for(
const auto& id_scc : sccs)
1116 const auto& scc_id = id_scc.first;
1117 const auto& scc = id_scc.second;
1121 for(
const auto v : scc)
1129 .
WriteDot(
"DesignFlowLoop_" +
STR(scc_id) +
".dot");
void DeExecute(const vertex starting_vertex, bool force_execution)
Recursively remove executed flag starting from a vertex.
const DesignFlowStepRef CreateFlowStep(const std::string &signature) const
Create a design flow step.
The key comparison functor for design flow step; it puts necessary steps before unnecessary ones; in ...
void WriteDot(const std::string &file_name, const int detail_level=0) const
Write this graph in dot format.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
void RecursivelyAddSteps(const DesignFlowStepSet &steps, const bool unnecessary)
Recursively add steps and corresponding dependencies to the design flow.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
void AddStep(const DesignFlowStepRef step)
Add step and corresponding dependencies to the design flow.
boost::graph_traits< graph >::out_edge_iterator OutEdgeIterator
out_edge_iterator definition.
File containing functions and utilities to support the printing of debug messagges.
const DesignFlowGraphRef design_flow_graph
The graph of steps composing the design flow.
void AddSteps(const DesignFlowStepSet &steps)
Add steps and corresponding dependencies to the design flow.
Class for describing auxiliary steps in design flow.
#define OUTPUT_LEVEL_NONE
no output print is performed.
Step successfully executed.
void RegisterFactory(const DesignFlowStepFactoryConstRef factory)
Register a design flow step factory.
DesignFlowStepNecessitySorter(const DesignFlowGraphConstRef _design_flow_graph)
Constructor.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
void WriteLoopDot() const
const DesignFlowGraphConstRef design_flow_graph
The design flow graph.
CustomMap< size_t, CustomUnorderedMapStable< EdgeDescriptor, int > > edge_history
This structure stores "history of design flow graph manager - edges" First key is the iteration Secon...
virtual ~DesignFlowManager()
Destructor.
Step successfully executed but without any IR change.
std::set< vertex, DesignFlowStepNecessitySorter > possibly_ready
The set of potentially ready steps; when a step is added to set is ready to be executed, but it can become unready because of new added vertices.
Source must be executed to satisfy target.
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
static size_t step_counter
NOTE: static should be removed when all the design flow managers will be merged Counter of current it...
static const int DEPENDENCE_SELECTOR
The dependence selector.
boost::graph_traits< graph >::in_edge_iterator InEdgeIterator
in_edge_iterator definition.
exceptions managed by PandA
DesignFlowStep_Status GetStatus(const std::string &signature) const
Return the status of a design step (if it does not exist return NONEXISTENT)
Definition of hash function for EdgeDescriptor.
CustomUnorderedMap< std::string, DesignFlowStepFactoryConstRef > design_flow_step_factories
The registered factories.
vertex GetDesignFlowStep(const std::string &signature) const
Return the vertex associated with a design step if exists, NULL_VERTEX otherwise. ...
static const int DEPENDENCE_FEEDBACK_SELECTOR
The dependence feedback selector.
Include a set of utilities used to manage CPU time measures.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
DesignFlowManager(const ParameterConstRef parameters)
Constructor.
boost::graph_traits< graph >::edge_iterator EdgeIterator
edge_iterator definition.
Pure virtual base class for all the design flow step factory.
#define START_TIME(time_var)
Macro used to store the start time into time_var.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Base class for step of design flow.
const DesignFlowGraphConstRef feedback_design_flow_graph
The design flow graph with feedback edges.
CustomMap< vertex, std::string > step_names
The name of each vertex (we have to store since it is possible that it cannot be recomputed at the en...
int debug_level
The debug level.
Classes to describe design flow graph.
CustomMap< vertex, size_t > unchanged_executions
The number of times each step is executed with unchanged exit.
Target must be reexecuted.
redefinition of set to manage ordered/unordered structures
#define STOP_TIME(time_var)
Macro used to store the elapsed time into time_var.
const ParameterConstRef parameters
The set of input parameters.
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
unsigned offset[NUM_VERTICES+1]
static const int PRECEDENCE_SELECTOR
The condition selector.
CustomMap< size_t, CustomMap< vertex, DesignFlowStep_Status > > vertex_history
This structure stores "history of design flow graph manager - vertices" First key is the iteration Se...
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
DesignFlowStep_Status
The status of a step.
std::string PrintVirtualDataMemoryUsage()
virtual void Exec() final
Execute the design flow.
const DesignFlowGraphsCollectionRef design_flow_graphs_collection
The bulk graph of steps composing the design flow.
std::string print_cpu_time(long int t)
massage a long which represents a time interval in milliseconds, into a string suitable for output ...
refcount< DesignFlowStep > DesignFlowStepRef
Class describing auxiliary steps in design flow.
#define OUTPUT_LEVEL_VERY_PEDANTIC
verbose debugging print is performed.
const int output_level
The output level.
CustomMap< vertex, long > accumulated_execution_time
The accumulated times of each step.
size_t indentation
The current indentation for debug messages.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
#define DEBUG_LEVEL_PARANOIC
paranoid level debugging print is performed.
this class is used to manage the command-line or XML options.
CustomMap< vertex, size_t > skipped_executions
The number of times the execution of a step is skipped.
DesignFlowStepFactoryConstRef CGetDesignFlowStepFactory(const std::string &prefix) const
Return the factory which can create design flow step with signature beginning with prefix...
x
Return the smallest n such that 2^n >= _x.
Utility managing CPU statistics.
static const int AUX_SELECTOR
The auxiliary selector.
bool operator()(const vertex x, const vertex y) const
Compare position of two vertices.
CustomMap< vertex, size_t > success_executions
The number of times each step is executed with success.
Step is symbolic and it has already been marked.
#define NULL_VERTEX
null vertex definition
const DesignFlowGraphConstRef CGetDesignFlowGraph() const
Return the design flow graph.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...