88 const auto* ssaOperand = GetPointer<const ssa_name>(
GET_CONST_NODE(operand));
90 THROW_ASSERT(ssaOperand,
"Old variable should be an ssa_name");
93 if(
auto* gp = GetPointer<gimple_phi>(
GET_NODE(user_stmt)))
95 const auto& deList = gp->CGetDefEdgesList();
96 std::vector<gimple_phi::DefEdge> validDE;
97 for(
const auto& de : deList)
101 validDE.push_back(de);
104 THROW_ASSERT(static_cast<bool>(validDE.size()),
"Required variable to be replaced not found");
105 if(validDE.size() > 1)
107 const auto newSSADefBBI =
108 GetPointer<const gimple_node>(
112 for(
const auto& de : validDE)
114 if(de.second == newSSADefBBI)
116 gp->ReplaceDefEdge(TM, de, {new_ssa, newSSADefBBI});
117 bool emptyUses = ssaOperand->CGetUseStmts().empty();
127 TM->ReplaceTreeNode(user_stmt, operand, new_ssa);
131 bool emptyUses = ssaOperand->CGetUseStmts().empty();
167 return PB->
Type == gimple_cond_K || PB->
Type == gimple_multi_way_if_K;
173 THROW_ASSERT(PType == gimple_cond_K || PType == gimple_multi_way_if_K,
174 "Only branch or multi-way if types allowd");
183 "Only branches and switches should have PHIOnly defs that require branch blocks.");
198 std::vector<ValueInfo>& ValueInfos)
200 auto OIN = ValueInfoNums.find(Operand);
201 THROW_ASSERT(OIN != ValueInfoNums.end(),
"Operand was not really in the Value Info Numbers");
202 auto OINI = OIN->second;
203 THROW_ASSERT(OINI < ValueInfos.size(),
"Value Info Number greater than size of Value Info Table");
204 return ValueInfos.at(OINI);
208 std::vector<ValueInfo>& ValueInfos)
210 auto OIN = ValueInfoNums.find(Operand);
211 if(OIN == ValueInfoNums.end())
214 ValueInfos.resize(ValueInfos.size() + 1);
216 auto InsertResult = ValueInfoNums.insert({
Operand, ValueInfos.size() - 1});
217 THROW_ASSERT(InsertResult.second,
"Value info number already existed?");
218 return ValueInfos.at(InsertResult.first->second);
220 return ValueInfos.at(OIN->second);
226 OpsToRename.insert(Op);
228 OperandInfo.
Infos.push_back(PB);
233 auto c_type = condition->
get_kind();
234 return c_type == eq_expr_K || c_type == ne_expr_K || c_type == ltgt_expr_K || c_type == gt_expr_K ||
235 c_type == lt_expr_K || c_type == ge_expr_K || c_type == le_expr_K;
241 if(
const auto* nop = GetPointer<const nop_expr>(Op))
245 else if(
const auto* ce = GetPointer<const convert_expr>(op))
249 else if(
const auto* ssa = GetPointer<const ssa_name>(Op))
251 const auto DefStmt = ssa->CGetDefStmt();
252 if(
const auto* ga = GetPointer<const gimple_assign>(
GET_CONST_NODE(DefStmt)))
256 else if(
const auto* gp = GetPointer<const gimple_phi>(
GET_CONST_NODE(DefStmt)))
258 const auto& defEdges = gp->CGetDefEdgesList();
259 THROW_ASSERT(not defEdges.empty(),
"Branch variable definition from nowhere");
260 return defEdges.size() > 1 ? nullptr :
branchOpRecurse(defEdges.front().first, DefStmt);
262 else if(GetPointer<const gimple_nop>(
GET_CONST_NODE(DefStmt)) !=
nullptr)
270 else if(GetPointer<const cst_node>(Op))
278 std::vector<ValueInfo>& ValueInfos,
CustomSet<std::pair<unsigned int, unsigned int>>& EdgeUsesOnly,
279 const std::map<unsigned int, blocRef>& BBs,
286 const auto* BI = GetPointer<const gimple_cond>(
GET_CONST_NODE(bi));
287 THROW_ASSERT(BI,
"Branch instruction should be gimple_cond");
288 THROW_ASSERT(BBs.count(BI->bb_index),
"Branch BB should be a valid BB");
289 const auto BranchBB = BBs.at(BI->bb_index);
290 THROW_ASSERT(BBs.count(BranchBB->true_edge),
"True BB should be a valid BB (BB" +
STR(BranchBB->true_edge) +
291 " from BB" +
STR(BranchBB->number) +
")");
292 THROW_ASSERT(BBs.count(BranchBB->false_edge),
"False BB should be a valid BB (BB" +
STR(BranchBB->true_edge) +
293 " from BB" +
STR(BranchBB->number) +
")");
294 const auto TrueBB = BBs.at(BranchBB->true_edge);
295 const auto FalseBB = BBs.at(BranchBB->false_edge);
296 const std::vector<blocRef> SuccsToProcess = {TrueBB, FalseBB};
298 if(GetPointer<const cst_node>(
GET_CONST_NODE(BI->op0)) !=
nullptr)
304 "Non SSA variable found in branch (" +
GET_CONST_NODE(BI->op0)->ToString() +
")");
305 const auto cond_ssa = BI->op0;
307 if(cond_stmt ==
nullptr)
310 "---Could not retrieve condition from branch variable, skipping... (" +
317 "---Constant condition from branch variable, skipping... (" +
321 const auto* CondStmt = GetPointer<const gimple_assign>(
GET_CONST_NODE(cond_stmt));
322 THROW_ASSERT(CondStmt,
"Condition variable should be defined by gimple_assign (" +
327 "Branch condition is " + CondOp->get_kind_text() +
" " + CondOp->ToString());
330 if(TrueBB->number == FalseBB->number)
337 for(
const auto& Succ : SuccsToProcess)
339 if(Succ->number == BranchBB->number)
347 addInfoFor(OperandRef(
new Operand(Op, cond_stmt)), PB, OpsToRename, ValueInfoNums, ValueInfos);
348 if(Succ->list_of_pred.size() > 1)
350 EdgeUsesOnly.insert({BranchBB->number, Succ->number});
356 if(
const auto* bin = GetPointer<const binary_expr>(CondOp))
364 InsertHelper(cond_ssa);
366 if(!GetPointer<const cst_node>(lhs) && GetPointer<const ssa_name>(lhs)->CGetUseStmts().size() > 1)
368 InsertHelper(bin->op0);
371 if(!GetPointer<const cst_node>(rhs) && GetPointer<const ssa_name>(rhs)->CGetUseStmts().size() > 1)
373 InsertHelper(bin->op1);
377 else if(bin->get_kind() == bit_and_expr_K || bin->get_kind() == bit_ior_expr_K)
379 InsertHelper(cond_ssa);
385 "Unhandled condition type, skipping... (" + CondOp->get_kind_text() +
" " + CondOp->ToString() +
394 std::vector<ValueInfo>& ValueInfos,
395 CustomSet<std::pair<unsigned int, unsigned int>>& EdgeUsesOnly,
396 const std::map<unsigned int, blocRef>& BBs,
403 const auto* MWII = GetPointer<const gimple_multi_way_if>(
GET_CONST_NODE(mwii));
404 THROW_ASSERT(MWII,
"Multi way if instruction should be gimple_multi_way_if");
405 const auto BranchBBI = MWII->bb_index;
406 const auto BranchBB = BBs.at(BranchBBI);
408 THROW_ASSERT(static_cast<bool>(BBs.count(TargetBBI)),
"Target BB should be in BB list");
409 const auto& TargetBB = BBs.at(TargetBBI);
413 auto* PS =
new PredicateWithEdge(gimple_multi_way_if_K, ssa_var, BranchBBI, TargetBBI);
414 addInfoFor(OperandRef(
new Operand(ssa_var, use_stmt)), PS, OpsToRename, ValueInfoNums, ValueInfos);
415 if(TargetBB->list_of_pred.size() > 1)
417 EdgeUsesOnly.insert(std::make_pair(BranchBBI, TargetBBI));
421 for(
const auto& var_pair : MWII->list_of_cond)
423 const auto case_var = var_pair.first;
424 const auto BBI = var_pair.second;
425 if(case_var ==
nullptr)
433 "Branch loopback detected: variable renaming not safe, skipping...");
436 if(GetPointer<const cst_node>(
GET_CONST_NODE(case_var)) !=
nullptr)
442 const auto* case_ssa = GetPointer<const ssa_name>(
GET_CONST_NODE(case_var));
445 const auto case_stmt = case_ssa->CGetDefStmt();
449 "Branch variable already defined inside a phi node, skipping...");
452 const auto* Case_stmt = GetPointer<const gimple_assign>(
GET_CONST_NODE(case_stmt));
453 THROW_ASSERT(Case_stmt,
"Case statement should be a gimple_assign (" +
457 "Condition: " +
GET_CONST_NODE(Case_stmt->op1)->get_kind_text() +
" " +
459 if(
const auto* case_cmp = GetPointer<const binary_expr>(
GET_CONST_NODE(Case_stmt->op1)))
467 InsertHelper(case_var, case_stmt, BBI);
469 if(!GetPointer<const cst_node>(lhs) && GetPointer<const ssa_name>(lhs)->CGetUseStmts().size() > 1)
471 InsertHelper(case_cmp->op0, case_stmt, BBI);
474 if(!GetPointer<const cst_node>(rhs) && GetPointer<const ssa_name>(rhs)->CGetUseStmts().size() > 1)
476 InsertHelper(case_cmp->op1, case_stmt, BBI);
480 else if(case_cmp->get_kind() == bit_and_expr_K || case_cmp->get_kind() == bit_ior_expr_K)
482 InsertHelper(case_var, case_stmt, BBI);
505 return std::make_pair(PEdge->From, PEdge->To);
510 unsigned int DFSIn = 0;
511 unsigned int DFSOut = 0;
529 unsigned int DFSIn = 0;
530 unsigned int DFSOut = 0;
534 OperandRef
U =
nullptr;
537 bool EdgeOnly =
false;
542 " Def: " + (Def ? Def->
ToString() :
"null") +
" Use: " + (U ? U->getUser()->ToString() :
"null") +
543 " EdgeOnly: " + (EdgeOnly ?
"true" :
"false");
562 const auto* PHI = GetPointer<const gimple_phi>(
GET_CONST_NODE(VD.
U->getUser()));
563 auto phiDefEdge = std::find_if(
564 PHI->CGetDefEdgesList().begin(), PHI->CGetDefEdgesList().end(), [&](
const gimple_phi::DefEdge& de) {
567 THROW_ASSERT(phiDefEdge != PHI->CGetDefEdgesList().end(),
"Unable to find variable in phi definitions");
568 return std::make_pair(phiDefEdge->second, PHI->bb_index);
577 const auto ABlockEdge = getBlockEdge_local(A);
578 const auto BBlockEdge = getBlockEdge_local(B);
580 return std::tie(ABlockEdge, A.
Def, A.
U) < std::tie(BBlockEdge, B.
Def, B.
U);
608 auto ADef = getMiddleDef(A);
609 auto BDef = getMiddleDef(B);
610 auto AInst = getDefOrUser(ADef, A.
U);
611 auto BInst = getDefOrUser(BDef, B.
U);
634 return comparePHIRelated(A, B);
642 return localComesBefore(A, B);
658 if(Stack.back().EdgeOnly)
664 const auto* PHI = GetPointer<const gimple_phi>(
GET_CONST_NODE(VDUse.
U->getUser()));
670 auto EdgePredIt = std::find_if(
671 PHI->CGetDefEdgesList().begin(), PHI->CGetDefEdgesList().end(), [&](
const gimple_phi::DefEdge& de) {
680 if(PHI->bb_index == bbedge.second && EdgePredIt->second == bbedge.first)
684 return OI.
dominates(bbedge.second, EdgePredIt->second);
687 return (VDUse.
DFSIn >= Stack.back().DFSIn && VDUse.
DFSOut <= Stack.back().DFSOut);
710 const auto defBBI = GetPointer<const gimple_node>(
GET_CONST_NODE(op->CGetDefStmt()))->bb_index;
712 for(
auto& Usize : op->CGetUseStmts())
715 const auto* gp = GetPointer<const gimple_phi>(
GET_CONST_NODE(Usize.first));
718 if(gp->CGetDefEdgesList().size() == 1)
725 const auto&
U = Usize.first;
727 THROW_ASSERT(I,
"Use statement should be a gimple_node");
728 if(I->bb_index == defBBI)
735 const auto dfs_gen = [&](
unsigned int IBlock) {
745 const auto& BBmap = DT->CGetBBGraphInfo()->bb_index_map;
746 auto DomNode_vertex = BBmap.find(IBlock);
747 THROW_ASSERT(DomNode_vertex != BBmap.end(),
"BB" +
STR(IBlock) +
" not found in DT");
752 "---BB" +
STR(IBlock) +
" is unreachable from DT root");
755 const auto& DomNode_DFSInfo = DFSInfos.at(IBlock);
756 VD.
DFSIn = DomNode_DFSInfo.DFSIn;
757 VD.
DFSOut = DomNode_DFSInfo.DFSOut;
759 DFSOrderedSet.push_back(VD);
768 for(
const auto& def_edge : gp->CGetDefEdgesList())
775 dfs_gen(def_edge.second);
782 dfs_gen(I->bb_index);
793 CustomMap<std::pair<unsigned int, unsigned int>, blocRef>& interBranchBBs,
802 auto RevIter = RenameStack.rbegin();
803 for(; RevIter != RenameStack.rend(); ++RevIter)
811 auto Start = RevIter - RenameStack.rbegin();
812 auto& BBmap = DT->GetBBGraphInfo()->bb_index_map;
817 for(
auto RenameIter = RenameStack.end() - Start; RenameIter != RenameStack.end(); ++RenameIter)
821 if(RenameIter != RenameStack.begin())
823 THROW_ASSERT((RenameIter - 1)->Def,
"A valid definition shold be on the stack at this point");
824 const auto* gp = GetPointer<const gimple_phi>(
GET_CONST_NODE((RenameIter - 1)->Def));
825 THROW_ASSERT(gp,
"Previous definition on stack should be a gimple_phi (" +
831 const auto* ValInfo = Result.
PInfo;
840 THROW_ASSERT(BBmap.contains(pwe->To),
"Basic block should be in dominator tree");
841 const auto& ToBB_vertex = BBmap.at(pwe->To);
842 const auto& ToBB = DT->CGetBBNodeInfo(ToBB_vertex)->block;
846 std::vector<std::pair<tree_nodeRef, unsigned int>> list_of_def_edge = {{Op, pwe->From}};
847 if(ToBB->list_of_pred.size() > 1)
851 auto from_number = std::make_pair(pwe->From, ToBB->number);
852 auto interBBIt = interBranchBBs.find(from_number);
853 if(interBBIt != interBranchBBs.end())
855 interBB = interBBIt->second;
859 THROW_ASSERT(static_cast<bool>(BBmap.count(pwe->From)),
"");
860 const auto& FromBB = DT->CGetBBNodeInfo(BBmap.at(pwe->From))->
block;
863 const auto interBBI = (sl->
list_of_bloc.rbegin())->first + 1;
865 interBB->loop_id = FromBB->loop_id;
866 interBB->SetSSAUsesComputed();
867 interBB->schedule = FromBB->schedule;
870 FromBB->list_of_succ.erase(
871 std::remove(FromBB->list_of_succ.begin(), FromBB->list_of_succ.end(), ToBB->number),
872 FromBB->list_of_succ.end());
873 ToBB->list_of_pred.erase(
874 std::remove(ToBB->list_of_pred.begin(), ToBB->list_of_pred.end(), FromBB->number),
875 ToBB->list_of_pred.end());
876 FromBB->list_of_succ.push_back(interBBI);
877 interBB->list_of_pred.push_back(FromBB->number);
878 interBB->list_of_succ.push_back(ToBB->number);
879 ToBB->list_of_pred.push_back(interBBI);
882 interBranchBBs.insert({{FromBB->number, ToBB->number}, interBB});
885 BBmap.insert({interBBI, BBmap.at(FromBB->number)});
886 DFSInfos.insert({interBBI, DFSInfos.at(FromBB->number)});
889 if(FromBB->false_edge == ToBB->number)
891 FromBB->false_edge = interBBI;
893 if(FromBB->true_edge == ToBB->number)
895 FromBB->true_edge = interBBI;
899 if(
auto* mwi = GetPointer<gimple_multi_way_if>(
GET_NODE(FromBB->CGetStmtList().back())))
901 for(
auto& cond : mwi->list_of_cond)
903 if(cond.second == ToBB->number)
905 cond.second = interBBI;
911 for(
const auto&
phi : ToBB->CGetPhiList())
915 std::find_if(gp->CGetDefEdgesList().begin(), gp->CGetDefEdgesList().end(),
917 if(defFrom != gp->CGetDefEdgesList().end())
919 gp->ReplaceDefEdge(TM, *defFrom, {defFrom->first, interBBI});
925 pic = tree_man->
create_phi_node(new_ssa_var, list_of_def_edge, function_id);
926 const auto gp = GetPointer<gimple_phi>(
GET_NODE(pic));
927 gp->SetSSAUsesComputed();
928 gp->artificial =
true;
929 interBB->AddPhi(pic);
931 "---Insertion moved to intermediate BB" +
STR(interBB->number));
936 pic = tree_man->
create_phi_node(new_ssa_var, list_of_def_edge, function_id);
937 const auto gp = GetPointer<gimple_phi>(
GET_NODE(pic));
938 gp->SetSSAUsesComputed();
939 gp->artificial =
true;
945 auto* newSSA = GetPointer<ssa_name>(
GET_NODE(new_ssa_var));
946 newSSA->bit_values = op->bit_values;
947 newSSA->range = RangeRef(op->range ? op->range->clone() :
nullptr);
948 newSSA->min = op->min;
949 newSSA->max = op->max;
950 newSSA->var = op->var;
952 PredicateMap.insert({pic, ValInfo});
962 return RenameStack.back().Def;
986 const auto TM = AppM->get_tree_manager();
989 bool modified =
false;
995 std::vector<OperandRef> OpsToRename(OpSet.begin(), OpSet.end());
997 auto Comparator = [&](
const OperandRef
A,
const OperandRef
B) {
1000 std::sort(OpsToRename.begin(), OpsToRename.end(), Comparator);
1003 for(
auto& Op : OpsToRename)
1005 std::vector<ValueDFS> OrderedUses;
1008 "Analysing " + Op->getOperand()->ToString() +
" with " +
STR(
ValueInfo.
Infos.size()) +
1009 " possible copies");
1023 if(EdgeUsesOnly.count(BlockEdge))
1029 const auto& DomNode = BlockEdge.first;
1032 THROW_ASSERT(DFSInfos.contains(DomNode),
"Invalid DT node");
1033 const auto& DomNode_DFSInfo = DFSInfos.at(DomNode);
1034 VD.
DFSIn = DomNode_DFSInfo.DFSIn;
1035 VD.
DFSOut = DomNode_DFSInfo.DFSOut;
1036 VD.
PInfo = PossibleCopy;
1038 OrderedUses.push_back(VD);
1047 const auto& DomNode = BlockEdge.second;
1050 THROW_ASSERT(DFSInfos.contains(DomNode),
"Invalid DT node");
1051 const auto& DomNode_DFSInfo = DFSInfos.at(DomNode);
1052 VD.
DFSIn = DomNode_DFSInfo.DFSIn;
1053 VD.
DFSOut = DomNode_DFSInfo.DFSOut;
1054 VD.
PInfo = PossibleCopy;
1055 OrderedUses.push_back(VD);
1067 std::stable_sort(OrderedUses.begin(), OrderedUses.end(), Compare);
1068 std::vector<ValueDFS> RenameStack;
1071 for(
auto& VD : OrderedUses)
1078 bool PossibleCopy = VD.PInfo !=
nullptr;
1080 if(RenameStack.empty())
1087 "RenameStack top DFS numbers are (" +
STR(RenameStack.back().DFSIn) +
"," +
1088 STR(RenameStack.back().DFSOut) +
")");
1092 "Current DFS numbers are (" +
STR(VD.DFSIn) +
"," +
STR(VD.DFSOut) +
")");
1093 bool ShouldPush = (VD.Def || PossibleCopy);
1095 if(OutOfScope || ShouldPush)
1101 RenameStack.push_back(VD);
1106 if(RenameStack.empty())
1113 if(VD.Def || PossibleCopy)
1119 ValueDFS& Result = RenameStack.back();
1120 THROW_ASSERT(VD.U,
"A use sohuld be in scope for current renaming operation");
1122 if(
const auto* gp = GetPointer<const gimple_phi>(
GET_CONST_NODE(VD.U->getUser())))
1125 "Sigma operation should not be renamed (BB" +
STR(gp->bb_index) +
" " + gp->ToString() +
")");
1134 if(not AppM->ApplyNewTransformation())
1140 Result.
Def =
materializeStack(RenameStack, function_id, sl, Op->getOperand(), PredicateMap, DT, TM,
1141 tree_man, interBranchBBs, DFSInfos
1157 const auto defVertex = DT->CGetBBGraphInfo()->bb_index_map.at(GetPointer<const gimple_node>(
GET_CONST_NODE(Result.
Def))->bb_index);
1158 const auto defBB = DT->CGetBBNodeInfo(defVertex)->block;
1159 const auto defBB_succ = defBB->list_of_succ;
1160 if(std::find(defBB_succ.begin(), defBB_succ.end(), defBB->number) == defBB_succ.end())
1162 THROW_UNREACHABLE(
"PredicateInfo def should have dominated this use at least in the CFG");
1167 if(not AppM->ApplyNewTransformation())
1173 AppM->RegisterTransformation(GetName(), VD.U->getUser());
1174 VD.U->set(phi->res, TM);
1184 const DesignFlowManagerConstRef dfm)
1196 switch(relationship_type)
1200 relationships.insert(std::make_pair(BLOCK_FIX,
SAME_FUNCTION));
1201 relationships.insert(std::make_pair(EXTRACT_GIMPLE_COND_OP,
SAME_FUNCTION));
1202 relationships.insert(std::make_pair(IR_LOWERING,
SAME_FUNCTION));
1203 relationships.insert(std::make_pair(USE_COUNTING,
SAME_FUNCTION));
1208 relationships.insert(std::make_pair(DETERMINE_MEMORY_ACCESSES,
SAME_FUNCTION));
1209 relationships.insert(std::make_pair(UN_COMPARISON_LOWERING,
SAME_FUNCTION));
1219 return relationships;
1228 auto TM =
AppM->get_tree_manager();
1229 const auto* fd = GetPointer<const function_decl>(TM->get_tree_node_const(
function_id));
1230 auto*
sl = GetPointer<statement_list>(
GET_NODE(fd->body));
1241 for(
const auto&
block : sl->list_of_bloc)
1243 inverse_vertex_map.try_emplace(
block.first,
1248 for(
const auto& curr_bb_pair : sl->list_of_bloc)
1250 unsigned int curr_bb = curr_bb_pair.first;
1251 for(
const auto& lop : sl->list_of_bloc.at(curr_bb)->list_of_pred)
1253 THROW_ASSERT(static_cast<bool>(inverse_vertex_map.count(lop)),
1254 "BB" +
STR(lop) +
" (successor of BB" +
STR(curr_bb) +
") does not exist");
1255 GCC_bb_graphs_collection->AddEdge(inverse_vertex_map.at(lop), inverse_vertex_map.at(curr_bb),
CFG_SELECTOR);
1258 for(
const auto& los : sl->list_of_bloc.at(curr_bb)->list_of_succ)
1262 GCC_bb_graphs_collection->AddEdge(inverse_vertex_map.at(curr_bb), inverse_vertex_map.at(los),
CFG_SELECTOR);
1266 if(sl->list_of_bloc.at(curr_bb)->list_of_succ.empty())
1268 GCC_bb_graphs_collection->AddEdge(inverse_vertex_map.at(curr_bb), inverse_vertex_map.at(
bloc::EXIT_BLOCK_ID),
1282 for(
const auto& it : bb_dominators.get_dominator_map())
1286 GCC_bb_graphs_collection->AddEdge(it.second, it.first,
D_SELECTOR);
1291 "Dominator tree computation completed (" +
STR(
DT->
num_bblocks()) +
" BB generated)");
1296 std::vector<ValueInfo> ValueInfos;
1297 ValueInfos.resize(1);
1308 const auto BBvisit = [&](blocRef BB) {
1309 const auto& stmt_list = BB->CGetStmtList();
1312 if(stmt_list.empty())
1318 const auto terminator = stmt_list.back();
1320 "Block terminates with " +
GET_NODE(terminator)->get_kind_text());
1326 else if(
GET_CONST_NODE(terminator)->get_kind() == gimple_multi_way_if_K)
1328 processMultiWayIf(terminator, OpsToRename, ValueInfoNums, ValueInfos, EdgeUsesOnly, sl->list_of_bloc,
1337 std::stack<std::pair<vertex, boost::iterator_range<BBGraph::adjacency_iterator>>> workStack;
1339 workStack.push({entryVertex, boost::make_iterator_range(boost::adjacent_vertices(entryVertex, *
DT))});
1341 unsigned int DFSNum = 0;
1343 DFSInfos[BBentry->number].DFSIn = DFSNum++;
1349 while(!workStack.empty())
1352 auto ChildRange = workStack.top().second;
1356 if(ChildRange.empty())
1358 DFSInfos[BB->number].DFSOut = DFSNum++;
1365 workStack.top().second.pop_front();
1368 {ChildRange.front(), boost::make_iterator_range(boost::adjacent_vertices(ChildRange.front(), *
DT))});
1369 DFSInfos[Child->number].DFSIn = DFSNum++;
1379 if(static_cast<size_t>(DFSInfos.size()) < (
DT->
num_bblocks() + 2))
1385 "Analysis detected " +
STR(OpsToRename.size()) +
" operations to rename");
1386 if(OpsToRename.empty())
1393 const auto modified =
renameUses(OpsToRename, ValueInfoNums, ValueInfos, DFSInfos, EdgeUsesOnly, sl);
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
bool dominates(const unsigned int BBIA, const unsigned int BBIB) const
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
This struct specifies the field bloc (basic block).
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
bool localComesBefore(const ValueDFS &A, const ValueDFS &B) const
DesignFlowStep_Status InternalExec() override
compute the e-SSA form
std::string ToString() const
Print this node as string in gimple format.
Step successfully executed.
const std::pair< unsigned int, unsigned int > getBlockEdge(const PredicateBase *PB)
std::vector< ValueDFS > ValueDFSStack
Definition of the node_info object for the basic_block graph.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
tree_nodeRef branchOpRecurse(tree_nodeRef op, tree_nodeRef stmt=nullptr)
BBGraphInfoRef GetBBGraphInfo()
Returns the property associated with the graph.
bool comparePHIRelated(const ValueDFS &A, const ValueDFS &B) const
This struct specifies the statement_list node.
Definition of the class representing a generic C application.
refcount< tree_manipulation > tree_manipulationRef
void addInfoFor(OperandRef Op, PredicateBase *PB, CustomSet< OperandRef > &OpsToRename, eSSA::ValueInfoLookup &ValueInfoNums, std::vector< ValueInfo > &ValueInfos)
RelationshipType
The relationship type.
Source must be executed to satisfy target.
PredicateWithEdge(kind PType, tree_nodeConstRef Op, unsigned int _From, unsigned int _To)
const std::pair< unsigned int, unsigned int > getBlockEdge_local(const ValueDFS &VD) const
CustomOrderedMap< T, U > CustomMap
bool stackIsInScope(const ValueDFSStack &Stack, const ValueDFS &VDUse, const OrderedInstructions &OI)
#define D_SELECTOR
Selectors used only in basic block graphs; numbers continue from cdfg_edge_info.hpp.
A simple interface to token object of the raw files.
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
std::map< unsigned int, blocRef > list_of_bloc
list_of_bloc field is the list of basic block. If this field is null then the list_of_stmt field is n...
static const unsigned int EXIT_BLOCK_ID
constant identifying the exit basic block
Data structure describing a basic block at tree level.
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
eSSA(const ParameterConstRef Param, const application_managerRef AM, unsigned int f_id, const DesignFlowManagerConstRef dfm)
Constructor.
std::string ToString(ActorGraphBackend_Type actor_graph_backend_type)
Header include.
void processMultiWayIf(tree_nodeConstRef mwii, CustomSet< OperandRef > &OpsToRename, eSSA::ValueInfoLookup &ValueInfoNums, std::vector< ValueInfo > &ValueInfos, CustomSet< std::pair< unsigned int, unsigned int >> &EdgeUsesOnly, const std::map< unsigned int, blocRef > &BBs, int debug_level)
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
void popStackUntilDFSScope(ValueDFSStack &Stack, const ValueDFS &VD, const OrderedInstructions &OI)
Class used to describe a particular graph with basic blocks as nodes.
~eSSA() override
Destructor.
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
ValueInfo & getOrCreateValueInfo(tree_nodeConstRef Operand, eSSA::ValueInfoLookup &ValueInfoNums, std::vector< ValueInfo > &ValueInfos)
tree_nodeRef getMiddleDef(const ValueDFS &VD) const
Information associated with the whole basic-block graph.
Target must be reexecuted.
std::pair< tree_nodeRef, unsigned int > DefEdge
The type of the def edge.
#define GET_CONST_NODE(t)
tree_nodeRef getDefOrUser(const tree_nodeRef Def, const OperandRef U) const
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
const tree_nodeRef user_stmt
void calculate_dominance_info(enum dominance::cdi_direction dir)
The main entry point into this module.
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 struct specifies the block node.
This file collects some utility functions.
bool renameUses(CustomSet< OperandRef > &OpSet, ValueInfoLookup &ValueInfoNums, std::vector< ValueInfo > &ValueInfos, CustomMap< unsigned int, DFSInfo > &DFSInfos, CustomSet< std::pair< unsigned int, unsigned int >> &EdgeUsesOnly, statement_list *sl)
void processBranch(tree_nodeConstRef bi, CustomSet< OperandRef > &OpsToRename, eSSA::ValueInfoLookup &ValueInfoNums, std::vector< ValueInfo > &ValueInfos, CustomSet< std::pair< unsigned int, unsigned int >> &EdgeUsesOnly, const std::map< unsigned int, blocRef > &BBs, int debug_level)
ValueDFS_Compare(OrderedInstructions &_OI)
const unsigned int function_id
The index of the function to be analyzed.
static bool classof(const PredicateBase *PB)
std::vector< PredicateBase * > Infos
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
static const unsigned int ENTRY_BLOCK_ID
constant identifying the entry basic block
PredicateBase(kind PT, tree_nodeConstRef Op)
const tree_nodeRef getOperand() const
const BBNodeInfoConstRef CGetBBNodeInfo(const vertex node) const
Return the info associated with a basic block.
Operand(const tree_nodeRef _operand, tree_nodeRef stmt)
void convertUsesToDFSOrdered(tree_nodeRef Op, std::vector< ValueDFS > &DFSOrderedSet, BBGraphRef DT, const CustomMap< unsigned int, DFSInfo > &DFSInfos, int debug_level)
const ValueInfo & getValueInfo(tree_nodeConstRef Operand, eSSA::ValueInfoLookup &ValueInfoNums, std::vector< ValueInfo > &ValueInfos)
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 materializeStack(ValueDFSStack &RenameStack, unsigned int function_id, statement_list *sl, tree_nodeRef OrigOp, CustomMap< tree_nodeConstRef, const PredicateBase *> &PredicateMap, const BBGraphRef DT, tree_managerRef TM, tree_manipulationRef tree_man, CustomMap< std::pair< unsigned int, unsigned int >, blocRef > &interBranchBBs, CustomMap< unsigned int, DFSInfo > &DFSInfos, int debug_level)
bool isCompare(const struct binary_expr *condition)
bool valueComesBefore(OrderedInstructions &OI, tree_nodeConstRef A, tree_nodeConstRef B)
const tree_nodeRef getUser() const
size_t num_bblocks() const
Returns the number of basic blocks contained into the graph.
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.
int debug_level
The debug level.
tree_nodeConstRef OriginalOp
tree_nodeRef create_phi_node(tree_nodeRef &ssa_res, const std::vector< std::pair< tree_nodeRef, unsigned int >> &list_of_def_edge, unsigned int function_decl_nid, bool virtual_flag=false) const
GIMPLE_PHI.
#define GET_INDEX_CONST_NODE(t)
struct definition of the binary node structures.
#define CFG_SELECTOR
Control flow graph edge selector.
CustomMap< tree_nodeConstRef, unsigned int > ValueInfoLookup
refcount< BBGraphInfo > BBGraphInfoRef
refcount definition of the class
This class contains the base representation for a generic frontend flow step which works on the whole...
unsigned int getBranchBlock(const PredicateBase *PB)
std::vector< PredicateBase * > UninsertedInfos
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.
bool operator()(const ValueDFS &A, const ValueDFS &B) const
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
This structure defines graphs where nodes are basic_blocks.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...