81 #define EPSILON 0.0001 88 switch(relationship_type)
100 GetPointer<const HLS_manager>(
AppM) && GetPointer<const HLS_manager>(
AppM)->get_HLS(
function_id) and
110 design_flow_graph->CGetDesignFlowStepInfo(update_schedule)->design_flow_step;
111 if(GetPointer<const FunctionFrontendFlowStep>(design_flow_step)->
CGetBBVersion() !=
114 relationships.insert(std::make_pair(UPDATE_SCHEDULE,
SAME_FUNCTION));
124 relationships.insert(std::make_pair(COMPLETE_BB_GRAPH,
SAME_FUNCTION));
125 relationships.insert(std::make_pair(FUNCTION_CALL_OPT,
SAME_FUNCTION));
126 relationships.insert(std::make_pair(MULTI_WAY_IF,
SAME_FUNCTION));
127 relationships.insert(std::make_pair(SHORT_CIRCUIT_TAF,
SAME_FUNCTION));
135 return relationships;
139 unsigned int _function_id,
140 const DesignFlowManagerConstRef _design_flow_manager,
151 const auto ga = GetPointer<const gimple_assign>(
GET_CONST_NODE(tn));
156 auto opKind =
GET_NODE(ga->op1)->get_kind();
162 return opKind == mult_expr_K || opKind == widen_mult_expr_K || opKind == widen_sum_expr_K ||
163 opKind == bit_ior_expr_K || opKind == bit_xor_expr_K || opKind == bit_and_expr_K || opKind == eq_expr_K ||
164 opKind == ne_expr_K || opKind == plus_expr_K;
168 bool is_third_node)
const 170 const auto ga = GetPointer<const gimple_assign>(
GET_CONST_NODE(tn));
171 const auto be = GetPointer<const binary_expr>(
GET_NODE(ga->op1));
174 const auto sn = GetPointer<const ssa_name>(operand);
183 if(!is_third_node && sn->CGetNumberUses() > 1)
187 const auto def = GetPointer<const gimple_assign>(
GET_NODE(sn->CGetDefStmt()));
192 if(def->bb_index != ga->bb_index)
203 return sn->CGetDefStmt();
213 bool modified =
false;
218 auto*
sl = GetPointer<statement_list>(
GET_NODE(fd->body));
219 for(
const auto&
block : sl->list_of_bloc)
222 const auto& list_of_stmt =
block.second->CGetStmtList();
223 for(
auto stmt = list_of_stmt.begin(); stmt != list_of_stmt.end(); stmt++)
225 if(!
AppM->ApplyNewTransformation())
230 std::list<tree_nodeRef> new_tree_nodes;
233 auto next_stmt_ptr = std::next(stmt);
243 bool first_operand_of_first =
true;
244 bool first_operand_of_second =
true;
249 first_operand_of_first =
false;
254 "---Chained with a second commutative expression: " +
STR(second_stmt));
259 first_operand_of_second =
false;
267 const auto first_ga = GetPointer<const gimple_assign>(
GET_NODE(*stmt));
268 auto comm_expr_kind =
GET_NODE(first_ga->op1)->get_kind();
269 auto comm_expr_kind_text =
GET_NODE(first_ga->op1)->get_kind_text();
270 const auto first_be = GetPointer<const binary_expr>(
GET_NODE(first_ga->op1));
272 const auto second_ga = GetPointer<const gimple_assign>(
GET_NODE(second_stmt));
274 const auto second_be = GetPointer<const binary_expr>(
GET_NODE(second_ga->op1));
276 const auto third_ga = GetPointer<const gimple_assign>(
GET_NODE(third_stmt));
278 const auto third_be = GetPointer<const binary_expr>(
GET_NODE(third_ga->op1));
284 double operand_ready_time = 0.0;
286 const auto other_operand_of_first = first_operand_of_first ? first_be->op1 : first_be->op0;
287 const auto other_operand_of_second = first_operand_of_second ? second_be->op1 : second_be->op0;
289 operands.insert(std::make_pair(other_operand_of_first, *stmt));
290 operands.insert(std::make_pair(other_operand_of_second, second_stmt));
291 operands.insert(std::make_pair(third_be->op0, third_stmt));
292 operands.insert(std::make_pair(third_be->op1, third_stmt));
293 for(
const auto& operand : operands)
296 "---Analyzing when " +
STR(operand.first) +
" used in " +
STR(operand.second) +
" is ready");
297 const auto sn = GetPointer<const ssa_name>(
GET_NODE(operand.first));
300 const auto def_operand = GetPointer<const gimple_node>(
GET_NODE(sn->CGetDefStmt()));
301 if(def_operand->bb_index ==
block.first)
303 const auto def_stmt = sn->CGetDefStmt();
309 "---Connection time is " +
STR(connection_time));
310 const auto current_operand_ready_time = ending_time + connection_time;
311 operand_ready_time =
std::max(operand_ready_time, current_operand_ready_time);
313 "---New ready time is " +
STR(operand_ready_time));
320 "---Delay of first operation is " +
STR(comm_expr_time1));
321 const auto comm_expr_time2 =
324 "---Delay of second operation is " +
STR(comm_expr_time2));
325 const auto comm_expr_time3 =
328 "---Delay of third operation is " +
STR(comm_expr_time3));
329 const auto new_ending_time = operand_ready_time +
std::max(comm_expr_time1, comm_expr_time3) +
334 "---Operand ready time " +
STR(operand_ready_time) +
" - New ending time " +
335 STR(new_ending_time) +
" - Old ending time " +
STR(old_time));
336 if(new_ending_time +
EPSILON >= old_time)
349 auto first_value = first_operand_of_second ? second_be->op1 : second_be->op0;
350 auto second_value = first_operand_of_first ? first_be->op1 : first_be->op0;
351 if(!first_operand_of_first)
353 std::swap(first_value, second_value);
355 const auto comm_expr_node =
360 if(
GET_NODE(first_value)->get_kind() == ssa_name_K &&
GET_NODE(second_value)->get_kind() == ssa_name_K)
362 const auto sn1 = GetPointer<const ssa_name>(
GET_NODE(first_value));
363 const auto sn2 = GetPointer<const ssa_name>(
GET_NODE(second_value));
364 if(sn1->var && sn2->var && sn1->var->index == sn2->var->index)
369 const auto first_ga_op0 = GetPointer<ssa_name>(
GET_NODE(first_ga->op0));
371 GetPointer<ssa_name>(
GET_CONST_NODE(ssa_node))->bit_values = first_ga_op0->bit_values;
374 const auto gimple_assign_node =
379 block.second->PushBefore(gimple_assign_node, *stmt,
AppM);
380 new_tree_nodes.push_back(gimple_assign_node);
383 const auto root_comm_expr =
388 const auto root_gimple_node =
392 block.second->Replace(*stmt, root_gimple_node,
true,
AppM);
393 new_tree_nodes.push_back(root_gimple_node);
394 AppM->RegisterTransformation(
GetName(), root_gimple_node);
400 block.second->RemoveStmt(second_stmt,
AppM);
402 for(
const auto& temp_stmt : list_of_stmt)
408 (!
parameters->IsParameter(
"print-dot-FF") ||
parameters->GetParameter<
unsigned int>(
"print-dot-FF")))
412 "---Written BB_Inside_" +
GetName() +
"_" +
STR(counter) +
".dot");
416 if(new_time +
EPSILON > old_time)
420 for(
const auto& to_be_removed : new_tree_nodes)
422 block.second->RemoveStmt(to_be_removed,
AppM);
426 next_stmt ?
block.second->PushBefore(second_stmt, next_stmt,
AppM) :
427 block.second->PushBack(second_stmt,
AppM);
428 next_stmt ?
block.second->PushBefore(first_stmt, next_stmt,
AppM) :
429 block.second->PushBack(first_stmt,
AppM);
432 for(
const auto& temp_stmt : list_of_stmt)
438 stmt = std::prev(next_stmt_ptr);
442 "-->Commutative expression restructuring applied on three " + comm_expr_kind_text +
448 stmt = list_of_stmt.begin();
463 TM =
AppM->get_tree_manager();
479 GetPointer<const HLS_manager>(
AppM) && GetPointer<const HLS_manager>(
AppM)->get_HLS(
function_id) and
489 design_flow_graph->CGetDesignFlowStepInfo(update_schedule)->design_flow_step;
490 if(GetPointer<const FunctionFrontendFlowStep>(design_flow_step)->
CGetBBVersion() !=
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
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;.
virtual void Initialize()
Initialize the step (i.e., like a constructor, but executed just before exec.
File containing functions and utilities to support the printing of debug messagges.
bool IsCommExprGimple(const tree_nodeConstRef tn) const
Return true if tree node is a gimple_assign with a mult_expr/plus_expr in the right part...
Step successfully executed.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
Definition of the class representing a generic C application.
const int output_level
The output level.
std::string GetName() const override
Return the name of this design step.
RelationshipType
The relationship type.
DesignFlowStep_Status InternalExec() override
Performs the loops analysis.
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
Source must be executed to satisfy target.
AbsControlStep get_cstep(const vertex &op) const
Returns the clock cycle where the given operation has been scheduled.
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
AbsControlStep get_cstep_end(const vertex &op) const
Return the last clock cycle in which the operation execute.
tree_nodeRef create_binary_operation(const tree_nodeConstRef &type, const tree_nodeRef &op0, const tree_nodeRef &op1, const std::string &srcp, enum kind operation_kind) const
Function used to create a binary expression.
A simple interface to token object of the raw files.
Data structure describing a basic block at tree level.
ScheduleRef schedule
The schedule.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
#define EPSILON
Header include.
std::string ToString(ActorGraphBackend_Type actor_graph_backend_type)
Header include.
const tree_nodeRef get_tree_node_const(unsigned int i) const
Return the reference to the i-th tree_node Constant version of get_tree_node.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
tree_managerRef TM
The tree manager.
void UpdateTime(const unsigned int operation_index, bool update_cs=true)
Compute the starting and the ending time of a statement.
Data structure used to store the schedule of the operations.
~commutative_expr_restructuring() override
Destructor.
void WriteBBGraphDot(const std::string &filename) const
Write the current version of statement list in dot format.
const unsigned int index
Represent the index read from the raw file and the index-1 of the vector of tree_node associated to t...
Classes to describe design flow graph.
Target must be reexecuted.
const Wrefcount< const DesignFlowManager > design_flow_manager
The design flow manager.
unsigned int CGetBBVersion() const
#define GET_CONST_NODE(t)
DesignFlowStep_Status GetStatus() const
Return the status of this design step.
Classes specification of the tree_node data structures.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
#define DEBUG_LEVEL_NONE
no debugging print is performed.
static const unsigned int UNKNOWN
The value used to identified unknown functional unit.
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
This struct specifies the block node.
This file collects some utility functions.
tree_nodeRef IsCommExprChain(const tree_nodeConstRef tn, const bool first, bool is_third_node) const
Given a gimple_assign with a commutative operation it checks:
double GetStartingTime(const unsigned int operation) const
Return the starting time of the operation.
refcount< T > lock() const
const unsigned int function_id
The index of the function to be analyzed.
const application_managerRef AppM
The application manager.
struct definition of the type node structures.
Class specification of the tree_reindex support class.
Data structure used to store the functional-unit binding of the vertexes.
AllocationInformationRef allocation_information
The allocation information.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
commutative_expr_restructuring(const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager, const ParameterConstRef parameters)
Constructor.
refcount< const tree_manipulation > tree_manipulationConstRef
this class is used to manage the command-line or XML options.
tree_nodeRef create_ssa_name(const tree_nodeConstRef &var, const tree_nodeConstRef &type, const tree_nodeConstRef &min, const tree_nodeConstRef &max, bool volatile_flag=false, bool virtual_flag=false) const
MISCELLANEOUS_OBJ_TREE_NODES.
Analysis step restructing tree of commutative expressions to reduce the critical path delay...
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
unsigned counter[N_THREADS]
int debug_level
The debug level.
double GetEndingTime(const unsigned int operation) const
Return the starting time of the operation.
#define OUTPUT_LEVEL_VERBOSE
verbose debugging print is performed.
#define GET_INDEX_CONST_NODE(t)
static bool is_constant(const tree_managerConstRef &TM, const unsigned int index)
Return if a tree node is a constant object.
Data structure definition for high-level synthesis flow.
tree_nodeRef create_gimple_modify_stmt(const tree_nodeRef &op0, const tree_nodeRef &op1, unsigned int function_decl_nid, const std::string &srcp) const
GIMPLE_ASSIGN.
const CustomUnorderedSet< std::pair< FrontendFlowStepType, FunctionRelationship > > ComputeFrontendRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Return the set of analyses in relationship with this design step.
This class creates a layer to add nodes and to manipulate the tree_nodes manager. ...
Class specification of the manager of the tree structures extracted from the raw file.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
static const std::string ComputeSignature(const FrontendFlowStepType frontend_flow_step_type, const unsigned int function_id)
Compute the signature of a function frontend flow step.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...