71 const DesignFlowManagerConstRef _design_flow_manager)
84 switch(relationship_type)
88 relationships.insert(std::make_pair(BLOCK_FIX,
SAME_FUNCTION));
97 relationships.insert(std::make_pair(SHORT_CIRCUIT_TAF,
SAME_FUNCTION));
98 relationships.insert(std::make_pair(MULTI_WAY_IF,
SAME_FUNCTION));
107 return relationships;
116 std::string raw_file_name =
117 parameters->getOption<std::string>(OPT_output_temporary_directory) +
"before_virtual_phi_nodes_split.raw";
118 std::ofstream raw_file(raw_file_name.c_str());
125 std::map<std::pair<unsigned int, unsigned int>,
unsigned int> replace;
128 auto* fd = GetPointer<function_decl>(temp);
129 auto*
sl = GetPointer<statement_list>(
GET_NODE(fd->body));
130 std::map<unsigned int, blocRef>& list_of_bloc = sl->list_of_bloc;
132 std::map<unsigned int, blocRef>::iterator iit, iit_end = list_of_bloc.end();
133 for(iit = list_of_bloc.begin(); iit != iit_end; ++iit)
135 blocRef& bb_block = iit->second;
136 for(
const auto&
phi : bb_block->CGetPhiList())
144 std::string raw_file_name =
145 parameters->getOption<std::string>(OPT_output_temporary_directory) +
"after_virtual_phi_nodes_split.raw";
146 std::ofstream raw_file(raw_file_name.c_str());
156 std::map<unsigned int, blocRef>& list_of_bloc,
const tree_managerRef TM,
157 std::map<std::pair<unsigned int, unsigned int>,
unsigned int>& replace)
160 auto*
phi = GetPointer<gimple_phi>(
GET_NODE(tree_phi));
163 if(
phi->virtual_flag)
168 for(
const auto& def_edge :
phi->CGetDefEdgesList())
173 auto* ssa_var = GetPointer<ssa_name>(
GET_NODE(
phi->res));
180 unsigned int bb_source = def_edge.second;
182 std::map<unsigned int, blocRef>::iterator it, it_end = list_of_bloc.end();
183 for(it = list_of_bloc.begin(); it != it_end; ++it)
185 source_bb = it->second;
186 if(source_bb->number != bb_source)
190 if(replace.find(std::make_pair(bb_source, bb_block->number)) != replace.end())
192 bb_source = replace[std::make_pair(bb_source, bb_block->number)];
193 source_bb = list_of_bloc.find(bb_source)->second;
202 THROW_ASSERT(source_bb->list_of_succ.size() == 1,
"ENTRY BB has more than one successor");
203 unsigned int this_bb_index = source_bb->list_of_succ.front();
205 blocRef new_bb = blocRef(
new bloc(list_of_bloc.rbegin()->first + 1));
207 new_bb->list_of_succ.push_back(this_bb_index);
212 source_bb->list_of_succ.clear();
213 source_bb->list_of_succ.push_back(new_bb->number);
218 for(index = 0; index < list_of_bloc.size(); index++)
220 if(list_of_bloc[index]->number == this_bb_index)
222 this_bb = list_of_bloc[
index];
226 THROW_ASSERT(index < list_of_bloc.size(),
"Current basic block not found");
227 for(index = 0; index < this_bb->list_of_pred.size(); index++)
232 "Adding edge from " +
STR(new_bb->number) +
" to " +
233 STR(this_bb->list_of_pred[index]));
234 this_bb->list_of_pred[
index] = new_bb->number;
239 "Entry not found in predecessors of current basic block");
241 list_of_bloc[new_bb->number] = new_bb;
250 const auto list_of_stmt = source_bb->CGetStmtList();
254 if(list_of_stmt.size() and (GetPointer<gimple_goto>(
GET_NODE(list_of_stmt.back())) ||
255 GetPointer<gimple_while>(
GET_NODE(list_of_stmt.back())) ||
256 GetPointer<gimple_for>(
GET_NODE(list_of_stmt.back())) ||
257 GetPointer<gimple_switch>(
GET_NODE(list_of_stmt.back()))))
259 source_bb->PushBack(created_stmt,
AppM);
262 else if(list_of_stmt.size() && GetPointer<gimple_cond>(
GET_NODE(list_of_stmt.back())))
265 bool true_case = source_bb->true_edge == bb_block->number;
266 blocRef new_bb = blocRef(
new bloc(list_of_bloc.rbegin()->first + 1));
271 new_bb->list_of_pred.push_back(source_bb->true_edge);
272 new_bb->list_of_succ.push_back(bb_block->number);
276 source_bb->list_of_succ.erase(
277 std::find(source_bb->list_of_succ.begin(), source_bb->list_of_succ.end(), bb_block->number));
278 source_bb->list_of_succ.push_back(new_bb->number);
279 source_bb->true_edge = new_bb->number;
282 bb_block->list_of_pred.erase(
283 std::find(bb_block->list_of_pred.begin(), bb_block->list_of_pred.end(), source_bb->number));
284 bb_block->list_of_pred.push_back(new_bb->number);
286 "Adding edge from " +
STR(source_bb->number) +
" to " +
STR(new_bb->number));
292 new_bb->list_of_pred.push_back(source_bb->false_edge);
293 new_bb->list_of_succ.push_back(bb_block->number);
297 source_bb->list_of_succ.erase(
298 std::find(source_bb->list_of_succ.begin(), source_bb->list_of_succ.end(), bb_block->number));
299 source_bb->list_of_succ.push_back(new_bb->number);
300 source_bb->false_edge = new_bb->number;
304 bb_block->list_of_pred.erase(
305 std::find(bb_block->list_of_pred.begin(), bb_block->list_of_pred.end(), source_bb->number));
306 bb_block->list_of_pred.push_back(new_bb->number);
308 "Adding edge from " +
STR(source_bb->number) +
" to " +
STR(new_bb->number));
310 list_of_bloc[new_bb->number] = new_bb;
311 replace[std::make_pair(source_bb->number, bb_block->number)] = new_bb->number;
315 new_bb->PushBack(created_stmt,
AppM);
324 source_bb->PushBack(created_stmt,
AppM);
#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.
This struct specifies the field bloc (basic block).
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.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
Definition of the class representing a generic C application.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
A simple interface to token object of the raw files.
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Data structure describing a basic block at tree level.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
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.
static bool tree_dumped
flag to check if initial tree has been dumped
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
unsigned map[NUM_VERTICES]
Target must be reexecuted.
std::pair< tree_nodeRef, unsigned int > DefEdge
The type of the def edge.
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.
This file collects some utility functions.
void virtual_split_phi(tree_nodeRef phi, blocRef &bb_block, std::map< unsigned int, blocRef > &list_of_bloc, const tree_managerRef TM, std::map< std::pair< unsigned int, unsigned int >, unsigned int > &replace)
virtually split a particular phi in two or more assignments
tree_manipulationRef tree_man
DesignFlowStep_Status InternalExec() override
Performs the virtual splitting of the phi-nodes.
const unsigned int function_id
The index of the function to be analyzed.
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.
~virtual_phi_nodes_split() override
Destructor.
const application_managerRef AppM
The application manager.
struct definition of the type node structures.
Class specification of the tree_reindex support class.
static const unsigned int ENTRY_BLOCK_ID
constant identifying the entry basic block
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.
Classes specification of the tree_node data structures not present in the gcc.
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.
virtual_phi_nodes_split(const ParameterConstRef _parameters, const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
int debug_level
The debug level.
blocRef next_entry
Basic block introduced after entry.
#define GET_INDEX_CONST_NODE(t)
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.
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.
A brief description of the C++ Header File.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...