45 #include "config_HAVE_ASSERTS.hpp" 66 : number_of_storage_values(0), HLS_mgr(_HLS_mgr), function_id(_function_id)
82 for(boost::tie(ki, ki_end) = boost::vertices(*
data); ki != ki_end; ++ki)
86 if(not scalar_defs.empty())
88 auto it_end = scalar_defs.end();
92 for(
auto it = scalar_defs.begin(); it != it_end; ++it)
107 for(
const auto scalar_def : scalar_defs)
130 "the storage value is missing");
135 unsigned int storage_value_index2)
const 148 "variable " +
STR(
HLS_mgr->get_tree_manager()->CGetTreeNode(var2)) +
" not in the map");
156 "-->Evaluation storage values (vars): [" +
STR(
HLS_mgr->get_tree_manager()->CGetTreeNode(var1)) +
159 STR(
HLS_mgr->get_tree_manager()->CGetTreeNode(var2)) +
"]");
166 const auto it_succ_v1 = boost::adjacent_vertices(v1, *
data);
167 const auto it_succ_v2 = boost::adjacent_vertices(v2, *
data);
170 if(
HLS_mgr->get_parameter()->getOption<
bool>(OPT_shared_input_registers))
172 static const std::vector<std::string> labels = {
"mult_expr",
"widen_mult_expr",
"ternary_plus_expr",
173 "ternary_mm_expr",
"ternary_pm_expr",
"ternary_mp_expr"};
174 for(
const auto& label : labels)
182 std::for_each(it_succ_v1.first, it_succ_v1.second,
183 [
this, &op_succ_of_v1_port0, &op_succ_of_v1_port1, &op_succ_of_v1_port2, &var1,
184 &label](
const vertex succ) {
185 const std::string op_label = data->CGetOpNodeInfo(succ)->GetOperation();
186 const unsigned int succ_id = data->CGetOpNodeInfo(succ)->GetNodeId();
187 INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, 0,
188 "---[" + STR(succ_id) +
"] type: " + STR(op_label));
189 if((op_label == label))
191 std::vector<HLS_manager::io_binding_type> var_read =
192 HLS_mgr->get_required_values(function_id, succ);
193 if(std::get<0>(var_read[0]) == var1)
195 op_succ_of_v1_port0.insert(succ_id);
197 else if(std::get<0>(var_read[1]) == var1)
199 op_succ_of_v1_port1.insert(succ_id);
201 else if(var_read.size() == 3 && std::get<0>(var_read[2]) == var1)
203 op_succ_of_v1_port2.insert(succ_id);
207 THROW_ERROR(
"unexpected case:" + STR(succ_id) +
"|" + STR(std::get<0>(var_read[0])) +
208 ":" + STR(std::get<0>(var_read[1])));
219 std::for_each(it_succ_v2.first, it_succ_v2.second,
220 [
this, &op_succ_of_v2_port0, &op_succ_of_v2_port1, &op_succ_of_v2_port2, &var2,
221 &label](
const vertex succ) {
222 const std::string op_label = data->CGetOpNodeInfo(succ)->GetOperation();
223 const unsigned int succ_id = data->CGetOpNodeInfo(succ)->GetNodeId();
224 INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, 0,
225 "---[" + STR(succ_id) +
"] type: " + STR(op_label));
226 if(op_label == label)
228 std::vector<HLS_manager::io_binding_type> var_read =
229 HLS_mgr->get_required_values(function_id, succ);
230 if(std::get<0>(var_read[0]) == var2)
232 op_succ_of_v2_port0.insert(succ_id);
234 else if(std::get<0>(var_read[1]) == var2)
236 op_succ_of_v2_port1.insert(succ_id);
238 else if(var_read.size() == 3 && std::get<0>(var_read[2]) == var2)
240 op_succ_of_v2_port2.insert(succ_id);
244 THROW_ERROR(
"unexpected case");
252 auto P0cond = !op_succ_of_v1_port0.empty() && !op_succ_of_v2_port0.empty();
253 auto P1cond = (!op_succ_of_v1_port1.empty() && !op_succ_of_v2_port1.empty());
254 auto P2cond = (!op_succ_of_v1_port2.empty() && !op_succ_of_v2_port2.empty());
255 const bool both_pilot_complex_ops = P0cond || P1cond || P2cond;
258 if(both_pilot_complex_ops)
287 if(ssa_read1.find(var2) != ssa_read1.end())
296 if(ssa_read2.find(var1) != ssa_read2.end())
303 unsigned int fu_unit1 =
fu.
lock()->get_assign(v1);
304 unsigned int fu_unit2 =
fu.
lock()->get_assign(v2);
305 if(fu_unit1 == fu_unit2)
311 if(
fu.
lock()->get_index(v1) ==
fu.
lock()->get_index(v2) )
320 bool they_have_common_inputs =
false;
321 auto it1_end = ssa_read1.end();
322 for(
auto it1 = ssa_read1.begin(); it1 != it1_end; ++it1)
324 if(ssa_read2.find(*it1) != ssa_read2.end())
326 they_have_common_inputs =
true;
332 auto it2_end = ssa_read2.end();
333 for(
auto it2 = ssa_read2.begin(); it2 != it2_end; ++it2)
338 if(
fu.
lock()->get_assign(from_v1) ==
fu.
lock()->get_assign(from_v2) &&
340 fu.
lock()->get_index(from_v1) ==
fu.
lock()->get_index(from_v2))
342 they_have_common_inputs =
true;
347 if(they_have_common_inputs)
353 if(they_have_common_inputs)
357 if(ssa_read1.find(var2) != ssa_read1.end())
361 if(ssa_read2.find(var1) != ssa_read2.end())
372 unsigned int storage_value_index2)
const 376 const auto TM =
HLS_mgr->get_tree_manager();
377 const auto var1 = TM->CGetTreeReindex(var1_nid);
378 const auto var2 = TM->CGetTreeReindex(var2_nid);
385 return isInt1 == isInt2 && isReal1 == isReal2 &&
386 (((isInt1 && isInt2) || (isReal1 && isReal2)) ? size1 == size2 : ceil_pow2(size1) == ceil_pow2(size2));
#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;.
#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.
mathematical utility function not provided by standard libraries
#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
const tree_nodeConstRef CGetTreeNode(const unsigned int i) const
#define TYPE_PHI
constant string identifying an operation node of type PHI
#define STR(s)
Macro which performs a lexical_cast to a string.
static bool IsSignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of integer type.
const OpNodeInfoConstRef CGetOpNodeInfo(const vertex node) const
Returns the info associated with a node.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
fu_bindingRef Rfu
Store the refcounted functional unit binding of the operations.
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
StorageValueInformationRef storage_value_information
data-structure for storage values
static bool is_virtual(const tree_managerConstRef &TM, const unsigned int index)
return true in case the ssa_name is virtual
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
This file collects some utility functions and macros.
#define DEBUG_LEVEL_NONE
no debugging print is performed.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
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.
refcount< T > lock() const
Data structure used to store the functional-unit binding of the vertexes.
const OpGraphConstRef CGetOpGraph(FunctionBehavior::graph_type gt) const
This method returns the operation graphs.
#define INFINITE_UINT
UNSIGNED INT representing infinite.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
this class is used to manage the command-line or XML options.
#define TYPE_ENTRY
constant identifying the node type of an entry node.
unsigned counter[N_THREADS]
Data structure definition for high-level synthesis flow.
Class specification of the manager of the tree structures extracted from the raw file.
A brief description of the C++ Header File.
static bool IsRealType(const tree_nodeConstRef &type)
Return true if the treenode is of real type.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...