75 const DesignFlowManagerConstRef _design_flow_manager,
78 TM(_AppM->get_tree_manager())
88 switch(relationship_type)
103 const auto step_signature =
108 const auto design_flow_step = design_flow_graph->CGetDesignFlowStepInfo(frontend_step)->design_flow_step;
109 relationship.insert(design_flow_step);
123 switch(relationship_type)
127 relationships.insert(std::make_pair(BB_FEEDBACK_EDGES_IDENTIFICATION,
SAME_FUNCTION));
128 relationships.insert(std::make_pair(BB_REACHABILITY_COMPUTATION,
SAME_FUNCTION));
129 relationships.insert(std::make_pair(DOM_POST_DOM_COMPUTATION,
SAME_FUNCTION));
130 relationships.insert(std::make_pair(USE_COUNTING,
SAME_FUNCTION));
135 relationships.insert(std::make_pair(BASIC_BLOCKS_CFG_COMPUTATION,
SAME_FUNCTION));
136 #if HAVE_FROM_PRAGMA_BUILT 137 relationships.insert(std::make_pair(EXTRACT_OMP_ATOMIC,
SAME_FUNCTION));
139 relationships.insert(std::make_pair(VECTORIZE,
SAME_FUNCTION));
151 return relationships;
159 const auto bb_index_map = basic_block_graph->CGetBBGraphInfo()->bb_index_map;
172 for(boost::tie(basic_block, basic_block_end) = boost::vertices(*basic_block_graph); basic_block != basic_block_end;
176 "-->Analyzing BB" +
STR(basic_block_graph->CGetBBNodeInfo(*basic_block)->block->number));
177 const auto block_info = basic_block_graph->CGetBBNodeInfo(*basic_block)->block;
178 for(
const auto& stmt : block_info->CGetStmtList())
181 const auto gn = GetPointerS<gimple_node>(
GET_NODE(stmt));
184 THROW_ASSERT(virtual_ssa_definitions.count(gn->vdef) == 0,
185 gn->vdef->ToString() +
" is defined also in " +
STR(virtual_ssa_definitions.at(gn->vdef)));
186 virtual_ssa_definitions[gn->vdef] = stmt;
188 const auto& cur_bb = bb_index_map.at(gn->bb_index);
189 const auto vo_it = gn->vdef ? gn->vovers.find(gn->vdef) : gn->vovers.end();
190 if(vo_it != gn->vovers.end() && !
function_behavior->CheckBBReachability(cur_bb, cur_bb))
192 gn->vovers.erase(vo_it);
193 GetPointerS<ssa_name>(
GET_NODE(gn->vdef))->RemoveUse(stmt);
195 for(
const auto& vover : gn->vovers)
197 vovers[vover].insert(stmt);
200 auto vu_it = gn->vuses.begin();
201 while(vu_it != gn->vuses.end())
203 const auto sn = GetPointerS<ssa_name>(
GET_NODE(*vu_it));
204 const auto def_stmt = sn->CGetDefStmt();
205 const auto use_bb_index = GetPointerS<const gimple_node>(
GET_NODE(def_stmt))->bb_index;
206 const auto& use_bb = bb_index_map.at(use_bb_index);
207 if(use_bb_index == gn->bb_index)
217 "---Removing " +
STR(*vu_it) +
" from vuses of unreachable stmt: " +
STR(sn));
218 vu_it = gn->vuses.erase(vu_it);
228 "<--Analyzed BB" +
STR(basic_block_graph->CGetBBNodeInfo(*basic_block)->block->number));
234 for(
const auto& virtual_ssa_definition : virtual_ssa_definitions)
237 "-->Considering ssa " + virtual_ssa_definition.first->ToString());
238 const auto sn = GetPointerS<ssa_name>(
GET_NODE(virtual_ssa_definition.first));
240 "---Defined in " + virtual_ssa_definition.second->ToString());
241 const auto definition = GetPointerS<const gimple_node>(
GET_CONST_NODE(virtual_ssa_definition.second));
243 const auto definition_bb_index = definition->bb_index;
244 const auto& definition_bb = bb_index_map.at(definition_bb_index);
248 auto loop_id = basic_block_graph->CGetBBNodeInfo(definition_bb)->loop_id;
251 auto depth = loops->CGetLoop(loop_id)->depth;
262 for(
const auto& use_stmt : sn->CGetUseStmts())
265 const auto use_bb_index = GetPointerS<const gimple_node>(
GET_NODE(use_stmt.first))->bb_index;
266 const auto& use_bb = bb_index_map.at(use_bb_index);
268 const auto gn = GetPointerS<const gimple_node>(
GET_NODE(use_stmt.first));
271 bool skip = [&]() ->
bool {
272 if(definition_bb_index == use_bb_index)
276 if(vovers.find(virtual_ssa_definition.first) != vovers.end())
278 for(
const auto& vover_stmt : vovers.find(virtual_ssa_definition.first)->second)
280 const auto vover_bb_index = GetPointerS<const gimple_node>(
GET_NODE(vover_stmt))->bb_index;
281 const auto vover_bb = bb_index_map.at(vover_bb_index);
282 if(
function_behavior->CheckBBReachability(use_bb, vover_bb) || use_bb == vover_bb)
288 for(
const auto& other_use_stmt : sn->CGetUseStmts())
290 const auto other_use_bb_index = GetPointerS<const gimple_node>(
GET_NODE(other_use_stmt.first))->bb_index;
291 const auto other_use_bb = bb_index_map.at(other_use_bb_index);
292 if(other_use_stmt.first->index != use_stmt.first->index &&
294 other_use_stmt.first->index != virtual_ssa_definition.second->index)
297 "---Considered other use: " +
STR(other_use_stmt.first->index) +
" " +
298 STR(other_use_stmt.first));
299 const auto other_gn = GetPointerS<const gimple_node>(
GET_NODE(other_use_stmt.first));
300 if(other_gn->vdef && gn->vuses.find(other_gn->vdef) != gn->vuses.end())
312 transitive_uses.insert(use_stmt);
315 use_stmts.insert(use_stmt.first);
316 use_bbs.insert(use_bb);
318 auto use_loop_id = basic_block_graph->CGetBBNodeInfo(use_bb)->loop_id;
319 auto use_depth = loops->CGetLoop(use_loop_id)->depth;
322 if(use_loop_id == loop_id)
329 "---Current loop is " +
STR(loop_id) +
" (depth is " +
STR(depth) +
") - Use loop is " +
330 STR(use_loop_id) +
" (depth " +
STR(use_depth) +
")");
332 while(use_depth > depth)
334 use_loop_id = loops->CGetLoop(use_loop_id)->Parent()->GetId();
335 use_depth = loops->CGetLoop(use_loop_id)->depth;
338 while(use_depth < depth)
340 loop_id = loops->CGetLoop(loop_id)->Parent()->GetId();
341 depth = loops->CGetLoop(loop_id)->depth;
343 while(use_loop_id != loop_id)
345 use_loop_id = loops->CGetLoop(use_loop_id)->Parent()->GetId();
346 loop_id = loops->CGetLoop(loop_id)->Parent()->GetId();
347 depth = loops->CGetLoop(loop_id)->depth;
351 for(
const auto& transitive_use : transitive_uses)
354 "---Removing " +
STR(virtual_ssa_definition.first) +
" from vuses of " +
355 STR(transitive_use.first));
356 const auto gn = GetPointerS<gimple_node>(
GET_NODE(transitive_use.first));
357 gn->vuses.erase(virtual_ssa_definition.first);
358 sn->RemoveUse(transitive_use.first);
372 auto current_loop = loops->CGetLoop(basic_block_graph->CGetBBNodeInfo(definition_bb)->loop_id);
373 while(current_loop->GetId() != loop_id)
375 for(
const auto& cur_pair : current_loop->get_sp_back_edges())
377 phi_headers.insert(cur_pair.second);
380 "---Phi has to be added in header of loop " +
STR(current_loop->GetId()));
381 current_loop = current_loop->Parent();
383 for(
const auto& cur_pair : current_loop->get_sp_back_edges())
385 phi_headers.insert(cur_pair.second);
388 "---Phi has to be added in header of loop " +
STR(current_loop->GetId()));
391 std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> nop_IR_schema;
392 const auto nop_id =
TM->new_tree_node_id();
395 TM->create_tree_node(nop_id, gimple_nop_K, nop_IR_schema);
397 const auto volatile_sn = tree_man->create_ssa_name(sn->var,
tree_helper::CGetType(virtual_ssa_definition.first),
398 nullptr,
nullptr,
true,
true);
399 GetPointerS<ssa_name>(
GET_NODE(volatile_sn))->SetDefStmt(
TM->GetTreeReindex(nop_id));
404 loops->CGetLoop(loop_id)->get_recursively_bb(loop_basic_blocks);
408 std::set<vertex, bb_vertex_order_by_map> to_be_processed(comp_i);
413 reaching_defs[virtual_ssa_definition.first][basic_block_graph->CGetBBGraphInfo()->entry_vertex] = volatile_sn;
415 for(boost::tie(oe, oe_end) =
416 boost::out_edges(basic_block_graph->CGetBBGraphInfo()->entry_vertex, *basic_block_graph);
420 if(basic_block_graph->CGetBBGraphInfo()->exit_vertex !=
target)
422 to_be_processed.insert(
target);
428 for(
const auto current : loop_basic_blocks)
430 bool reachable =
false;
431 for(
const auto use_bb : use_bbs)
436 "---BB" +
STR(basic_block_graph->CGetBBNodeInfo(use_bb)->block->number) +
437 " can be reached from BB" +
438 STR(basic_block_graph->CGetBBNodeInfo(current)->block->number));
442 else if(current == use_bb)
450 to_be_removed.insert(current);
453 for(
const auto removable : to_be_removed)
456 "---Removing BB" +
STR(basic_block_graph->CGetBBNodeInfo(removable)->block->number));
457 loop_basic_blocks.erase(removable);
463 loops->CGetLoop(loop_id)->get_recursively_bb(loop_bbs);
464 for(
const auto& loop_bb : loop_bbs)
467 for(boost::tie(ei, ei_end) = boost::in_edges(loop_bb, *basic_block_graph); ei != ei_end; ei++)
469 const auto source = boost::source(*ei, *basic_block_graph);
470 if(loop_bbs.find(source) == loop_bbs.end())
472 reaching_defs[virtual_ssa_definition.first][source] = volatile_sn;
476 for(
const auto& feedback_edge : loops->CGetLoop(loop_id)->get_sp_back_edges())
478 to_be_processed.insert(feedback_edge.second);
482 while(to_be_processed.size())
484 const auto current = *(to_be_processed.begin());
485 to_be_processed.erase(current);
487 "-->Checking BB" +
STR(basic_block_graph->CGetBBNodeInfo(current)->block->number));
490 if(boost::in_degree(current, *basic_block_graph) == 1)
493 boost::tie(ie, ie_end) = boost::in_edges(current, *basic_block_graph);
494 const auto source = boost::source(*ie, *basic_block_graph);
495 THROW_ASSERT(reaching_defs.at(virtual_ssa_definition.first).count(source),
"unexpected condition");
496 reaching_defs[virtual_ssa_definition.first][current] =
497 reaching_defs.at(virtual_ssa_definition.first).at(source);
503 bool build_phi =
false;
505 for(boost::tie(ie, ie_end) = boost::in_edges(current, *basic_block_graph); ie != ie_end; ie++)
507 const auto source = boost::source(*ie, *basic_block_graph);
510 if(phi_headers.find(current) != phi_headers.end())
519 const auto current_loop_id = basic_block_graph->CGetBBNodeInfo(current)->loop_id;
520 if(!loops->CGetLoop(current_loop_id)->IsReducible())
531 THROW_ASSERT(reaching_defs.find(virtual_ssa_definition.first) != reaching_defs.end() &&
532 reaching_defs.find(virtual_ssa_definition.first)->second.count(source),
533 "Definition coming from BB" +
534 STR(basic_block_graph->CGetBBNodeInfo(source)->block->number));
535 local_reaching_defs.insert(reaching_defs.at(virtual_ssa_definition.first).at(source));
538 if(local_reaching_defs.size() > 1)
547 std::vector<gimple_phi::DefEdge> def_edges;
548 for(boost::tie(ie, ie_end) = boost::in_edges(current, *basic_block_graph); ie != ie_end; ie++)
550 if((basic_block_graph->GetSelector(*ie) &
CFG_SELECTOR) != 0)
552 const auto source = boost::source(*ie, *basic_block_graph);
553 const auto& vssa = reaching_defs.at(virtual_ssa_definition.first).at(source);
559 const auto phi_stmt = tree_man->create_phi_node(phi_res, def_edges,
function_id,
true);
564 GetPointerS<gimple_phi>(
GET_NODE(phi_stmt))->SetSSAUsesComputed();
565 basic_block_graph->GetBBNodeInfo(current)->block->AddPhi(phi_stmt);
566 reaching_defs[virtual_ssa_definition.first][current] = phi_res;
567 added_phis[virtual_ssa_definition.first][current] = phi_stmt;
574 reaching_defs[virtual_ssa_definition.first][current] = *(local_reaching_defs.begin());
579 if(definition_bb == current || use_bbs.count(current))
581 bool before_definition =
582 definition_bb == current ||
function_behavior->CheckBBReachability(current, definition_bb);
583 for(
const auto& stmt : basic_block_graph->CGetBBNodeInfo(current)->block->CGetStmtList())
585 const auto& reaching_def = reaching_defs.at(virtual_ssa_definition.first).at(current);
586 if(use_stmts.count(stmt) && stmt->index != virtual_ssa_definition.second->index)
588 if(before_definition)
591 "---Adding for anti dependence " +
STR(reaching_def) +
" in " +
STR(stmt));
595 if(GetPointerS<gimple_node>(
GET_NODE(stmt))->AddVuse(reaching_def))
597 GetPointerS<ssa_name>(
GET_NODE(reaching_def))->AddUseStmt(stmt);
603 "---Replacing " +
STR(virtual_ssa_definition.first) +
" with " +
STR(reaching_def) +
608 TM->ReplaceTreeNode(stmt, virtual_ssa_definition.first, reaching_def);
611 if(stmt->index == virtual_ssa_definition.second->index)
613 before_definition =
false;
614 const auto gn = GetPointerS<gimple_node>(
GET_NODE(stmt));
615 if(gn->vovers.erase(virtual_ssa_definition.first))
617 const auto old_vssa = GetPointerS<ssa_name>(
GET_NODE(virtual_ssa_definition.first));
618 old_vssa->RemoveUse(stmt);
620 if(gn->AddVover(reaching_def))
622 const auto reaching_vssa = GetPointerS<ssa_name>(
GET_NODE(reaching_def));
623 reaching_vssa->AddUseStmt(stmt);
625 reaching_defs[virtual_ssa_definition.first][current] = virtual_ssa_definition.first;
630 "---Reaching definition at the exit is " +
631 STR(reaching_defs.at(virtual_ssa_definition.first).at(current)));
635 for(boost::tie(oe, oe_end) = boost::out_edges(current, *basic_block_graph); oe != oe_end; oe++)
638 if(loop_basic_blocks.count(
target))
641 "---Considering BB" +
STR(basic_block_graph->CGetBBNodeInfo(
target)->block->number));
644 if(phi_headers.count(
target))
646 THROW_ASSERT(added_phis.find(virtual_ssa_definition.first) != added_phis.end() &&
647 added_phis.find(virtual_ssa_definition.first)->second.count(
target),
648 "Phi for " +
STR(virtual_ssa_definition.first) +
" was not created in BB" +
649 STR(basic_block_graph->CGetBBNodeInfo(
target)->block->number));
650 GetPointerS<gimple_phi>(
GET_NODE(added_phis.at(virtual_ssa_definition.first).at(
target)))
653 basic_block_graph->CGetBBNodeInfo(current)->block->number));
655 "---Updated phi " +
STR(added_phis.at(virtual_ssa_definition.first).at(
target)));
657 else if(!loops->CGetLoop(basic_block_graph->CGetBBNodeInfo(
target)->loop_id)->IsReducible())
659 THROW_ASSERT(added_phis.find(virtual_ssa_definition.first) != added_phis.end() &&
660 added_phis.find(virtual_ssa_definition.first)->second.count(
target),
661 "Phi for " +
STR(virtual_ssa_definition.first) +
" was not created in BB" +
662 STR(basic_block_graph->CGetBBNodeInfo(
target)->block->number));
663 GetPointerS<gimple_phi>(
GET_NODE(added_phis.at(virtual_ssa_definition.first).at(
target)))
666 basic_block_graph->CGetBBNodeInfo(current)->block->number));
668 "---Updated phi " +
STR(added_phis.at(virtual_ssa_definition.first).at(
target)));
674 for(boost::tie(ie, ie_end) = boost::in_edges(
target, *basic_block_graph); ie != ie_end; ie++)
678 const auto source = boost::source(*ie, *basic_block_graph);
679 THROW_ASSERT(reaching_defs.find(virtual_ssa_definition.first) != reaching_defs.end() &&
680 reaching_defs.find(virtual_ssa_definition.first)->second.count(source),
681 "Definition coming from BB" +
682 STR(basic_block_graph->CGetBBNodeInfo(source)->block->number));
683 local_reaching_defs.insert(reaching_defs.at(virtual_ssa_definition.first).at(source));
686 if(local_reaching_defs.size() > 1)
688 THROW_ASSERT(added_phis.find(virtual_ssa_definition.first) != added_phis.end() &&
689 added_phis.find(virtual_ssa_definition.first)->second.count(
target),
690 "Phi for " +
STR(virtual_ssa_definition.first) +
" was not created in BB" +
691 STR(basic_block_graph->CGetBBNodeInfo(
target)->block->number));
692 GetPointerS<gimple_phi>(
GET_NODE(added_phis.at(virtual_ssa_definition.first).at(
target)))
695 basic_block_graph->CGetBBNodeInfo(current)->block->number));
697 "---Updated phi " +
STR(added_phis.at(virtual_ssa_definition.first).at(
target)));
703 to_be_processed.insert(
target);
709 "<--Checked BB" +
STR(basic_block_graph->CGetBBNodeInfo(current)->block->number));
715 if(
parameters->getOption<
bool>(OPT_print_dot))
720 std::set<tree_nodeRef> removedPhis;
724 for(
const auto& ssa_bbv : added_phis)
726 for(
const auto& bbv_phi : ssa_bbv.second)
728 if(removedPhis.find(bbv_phi.second) == removedPhis.end())
730 const auto& bb = basic_block_graph->GetBBNodeInfo(bbv_phi.first)->block;
731 const auto phi_stmt = GetPointerS<gimple_phi>(
GET_NODE(bbv_phi.second));
732 const auto vssa = GetPointerS<ssa_name>(
GET_NODE(phi_stmt->res));
733 if(vssa->CGetNumberUses() == 0 ||
734 (vssa->CGetNumberUses() == 1 &&
735 GET_INDEX_NODE(vssa->CGetUseStmts().begin()->first) == phi_stmt->index))
738 "---Removing just created dead phi from BB" +
STR(bb->number) +
" - (" +
739 GetPointerS<ssa_name>(
GET_NODE(ssa_bbv.first))->ToString() +
") " +
740 phi_stmt->ToString());
741 bb->RemovePhi(bbv_phi.second);
743 removedPhis.insert(bbv_phi.second);
756 for(boost::tie(basic_block, basic_block_end) = boost::vertices(*basic_block_graph);
757 basic_block != basic_block_end; basic_block++)
759 const auto&
block = basic_block_graph->CGetBBNodeInfo(*basic_block)->
block;
760 for(
const auto&
phi :
block->CGetPhiList())
765 THROW_ASSERT(gp->CGetDefEdgesList().size() == boost::in_degree(*basic_block, *basic_block_graph),
767 " has wrong number of inputs: " +
STR(gp->CGetDefEdgesList().size()) +
" vs " +
768 STR(boost::in_degree(*basic_block, *basic_block_graph)));
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
BuildVirtualPhi(const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager, const ParameterConstRef parameters)
Constructor.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
boost::graph_traits< graph >::out_edge_iterator OutEdgeIterator
out_edge_iterator definition.
File containing functions and utilities to support the printing of debug messagges.
std::string ToString() const
Print this node as string in gimple format.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
Definition of the class representing a generic C application.
refcount< tree_manipulation > tree_manipulationRef
~BuildVirtualPhi() override
Destructor.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
boost::graph_traits< graph >::in_edge_iterator InEdgeIterator
in_edge_iterator definition.
A simple interface to token object of the raw files.
Analysis step building phi of vops.
#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 TOK(token)
Macro used to convert a token symbol into a treeVocabularyTokenTypes.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
#define FB_CFG_SELECTOR
Feedback control flow edge selector.
void ComputeRelationships(DesignFlowStepSet &relationship, const DesignFlowStep::RelationshipType relationship_type) override
Compute the relationships of a step with other steps.
std::string GetSignature() const override
Return the signature of this step.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
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.
Basic block control flow graph with feedback.
Target must be reexecuted.
std::pair< tree_nodeRef, unsigned int > DefEdge
The type of the def edge.
const Wrefcount< const DesignFlowManager > design_flow_manager
The design flow manager.
#define GET_CONST_NODE(t)
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
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.
The key comparison function for vertices set based on levels.
This struct specifies the block node.
This file collects some utility functions.
void ComputeRelationships(DesignFlowStepSet &relationship, const DesignFlowStep::RelationshipType relationship_type) override
Compute the relationships of a step with other steps.
Data structures used to represent an edge in operation and basic block graphs.
refcount< T > lock() const
const unsigned int function_id
The index of the function to be analyzed.
const tree_managerRef TM
The tree manager.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
DesignFlowStep_Status InternalExec() override
Performs the loops analysis.
Class specification of the basic_block structure.
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.
interface of loops finding algorithm
this class is used to manage the command-line or XML options.
int debug_level
The debug level.
block(unsigned int i)
constructor
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.
#define CFG_SELECTOR
Control flow graph edge selector.
#define NULL_VERTEX
null vertex definition
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 map with key tree_nodeRef.
A brief description of the C++ Header 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 ...