diff --git a/sapfor/experts/Sapfor_2017/CMakeLists.txt b/sapfor/experts/Sapfor_2017/CMakeLists.txt index 94433f2..be43305 100644 --- a/sapfor/experts/Sapfor_2017/CMakeLists.txt +++ b/sapfor/experts/Sapfor_2017/CMakeLists.txt @@ -223,7 +223,9 @@ set(CFG _src/CFGraph/IR.cpp set(DATA_FLOW _src/CFGraph/DataFlow/data_flow.h + _src/CFGraph/DataFlow/data_flow_impl.h _src/CFGraph/DataFlow/backward_data_flow.h + _src/CFGraph/DataFlow/backward_data_flow_impl.h ) set(CREATE_INTER_T _src/CreateInterTree/CreateInterTree.cpp diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/backward_data_flow.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/backward_data_flow.h index dd0b3c3..58009c9 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/backward_data_flow.h +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/backward_data_flow.h @@ -8,7 +8,6 @@ #include "../../Utils/SgUtils.h" #include "../CFGraph.h" #include "../IR.h" -#include "../RD_subst.h" template class BackwardDataFlowAnalysis : public DataFlowAnalysis { @@ -18,91 +17,4 @@ public: void fit(const std::vector& blocks); }; -// minimizes the number of blocks beween the ends of back edges -template -std::vector BackwardDataFlowAnalysis::reorderSequence(const std::vector& blocks, - const std::set back_edge_sources) -{ - std::vector res = { }; - - auto blocks_end = blocks.rend(); - for (auto it = blocks.rbegin(); it < blocks_end; it++) - { - SAPFOR::BasicBlock* curr = *it; - auto res_end = res.end(); - auto inserter = res.begin(); - if (back_edge_sources.count(curr) == 0) - { - auto curr_next_begin = curr->getNext().begin(); - auto curr_next_end = curr->getNext().end(); - while (inserter < res_end && std::find(curr_next_begin, curr_next_end, *inserter) == curr_next_end) - inserter++; - } - - res.insert(inserter, curr); - } - - return res; -} - -template -void BackwardDataFlowAnalysis::fit(const std::vector& blocks) -{ - std::set> back_edges = {}; - - bool returned = false; - std::map> back_edges_by_src; - - auto blocks_sorted = sortCfgNodes(blocks, &back_edges); - - std::set back_edge_sources; - - for (auto& edge : back_edges) - { - back_edges_by_src[edge.first].insert(edge.second); - back_edge_sources.insert(edge.first); - } - - back_edges.clear(); - - blocks_sorted = reorderSequence(blocks_sorted, back_edge_sources); - back_edge_sources.clear(); - - std::reverse(blocks_sorted.begin(), blocks_sorted.end()); - - nodes.clear(); - std::map node_by_block; - - for (auto block : blocks_sorted) - { - NodeType* node = createNode(block); - nodes.push_back(node); - node_by_block[block] = node; - } - - int nodes_size = nodes.size(); - - for (int i = 0; i < nodes_size; i++) - { - NodeType* node = nodes[i]; - - auto back_edges_by_src_it = back_edges_by_src.find(node->getBlock()); - if (back_edges_by_src_it != back_edges_by_src.end()) - { - // This node is a source for back edge - for (auto dest : back_edges_by_src_it->second) - { - auto node_by_block_it = node_by_block.find(dest); - if (node_by_block_it != node_by_block.end()) - node_by_block_it->second->getRollback().insert(i); - } - } - - for (auto next : node->getBlock()->getNext()) - { - auto node_by_block_it = node_by_block.find(next); - if (node_by_block_it != node_by_block.end()) - node->getPrevBlocks().insert(node_by_block_it->second); - } - } -} \ No newline at end of file +#include "backward_data_flow_impl.h" \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/backward_data_flow_impl.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/backward_data_flow_impl.h new file mode 100644 index 0000000..d1d4486 --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/backward_data_flow_impl.h @@ -0,0 +1,103 @@ +#pragma once +#include "backward_data_flow.h" + +#include +#include +#include + +#include "../../Utils/SgUtils.h" +#include "../CFGraph.h" +#include "../IR.h" +#include "../RD_subst.h" + +/* Note: this file should be included in backward_data_flow.h to provide template definitions */ + +// minimizes the number of blocks beween the ends of back edges +template +std::vector +BackwardDataFlowAnalysis::reorderSequence(const std::vector& blocks, + const std::set back_edge_sources) +{ + std::vector res = { }; + + auto blocks_end = blocks.rend(); + for (auto it = blocks.rbegin(); it < blocks_end; it++) + { + SAPFOR::BasicBlock* curr = *it; + auto res_end = res.end(); + auto inserter = res.begin(); + if (back_edge_sources.count(curr) == 0) + { + auto curr_next_begin = curr->getNext().begin(); + auto curr_next_end = curr->getNext().end(); + while (inserter < res_end && std::find(curr_next_begin, curr_next_end, *inserter) == curr_next_end) + inserter++; + } + + res.insert(inserter, curr); + } + + return res; +} + +template +void BackwardDataFlowAnalysis::fit(const std::vector& blocks) +{ + std::set> back_edges = {}; + + bool returned = false; + std::map> back_edges_by_src; + + auto blocks_sorted = sortCfgNodes(blocks, &back_edges); + + std::set back_edge_sources; + + for (auto& edge : back_edges) + { + back_edges_by_src[edge.first].insert(edge.second); + back_edge_sources.insert(edge.first); + } + + back_edges.clear(); + + blocks_sorted = reorderSequence(blocks_sorted, back_edge_sources); + back_edge_sources.clear(); + + std::reverse(blocks_sorted.begin(), blocks_sorted.end()); + + nodes.clear(); + std::map node_by_block; + + for (auto block : blocks_sorted) + { + NodeType* node = createNode(block); + nodes.push_back(node); + node_by_block[block] = node; + } + + int nodes_size = nodes.size(); + + for (int i = 0; i < nodes_size; i++) + { + NodeType* node = nodes[i]; + + auto back_edges_by_src_it = back_edges_by_src.find(node->getBlock()); + if (back_edges_by_src_it != back_edges_by_src.end()) + { + // This node is a source for back edge + for (auto dest : back_edges_by_src_it->second) + { + auto node_by_block_it = node_by_block.find(dest); + if (node_by_block_it != node_by_block.end()) + node_by_block_it->second->getRollback().insert(i); + } + } + + for (auto next : node->getBlock()->getNext()) + { + auto node_by_block_it = node_by_block.find(next); + if (node_by_block_it != node_by_block.end()) + node->getPrevBlocks().insert(node_by_block_it->second); + } + } +} \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow.h index d4ac744..11493a0 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow.h +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow.h @@ -6,13 +6,10 @@ #include "../CFGraph.h" #include "../IR.h" -enum -{ - CNT_NOTINIT = 0 -}; - template class DataFlowAnalysisNode { + static const int CNT_NOTINIT = 0; + int in_cnt = CNT_NOTINIT, out_cnt = CNT_NOTINIT; std::set rollback; @@ -41,6 +38,7 @@ public: void setInCnt(int cnt) { in_cnt = cnt; } void setOutCnt(int cnt) { out_cnt = cnt; } + static int getStartCounter() { return CNT_NOTINIT; } std::set& getRollback() { return rollback; } std::set& getIgnoreRollback() { return ignore_rollback; } @@ -66,96 +64,4 @@ public: ~DataFlowAnalysis(); }; -template -DataFlowAnalysisNode::DataFlowAnalysisNode() { - getRollback() = {}; - getIgnoreRollback() = {}; - prev_blocks = {}; -} - -template -void DataFlowAnalysisNode::doStep() -{ - int in_max_cnt = CNT_NOTINIT, out_max_cnt = CNT_NOTINIT; - for (auto next : prev_blocks) - { - if (in_cnt < next->out_cnt) - { - for (const auto& byOut : next->getOut()) - { - bool inserted = addIn({ byOut }); - - if (inserted) - { - if (next->out_cnt > in_max_cnt) - in_max_cnt = next->out_cnt; - - inserted = forwardData({ byOut }); - - if (inserted && next->out_cnt > out_max_cnt) - out_max_cnt = next->out_cnt; - } - } - } - } - - bool was_notinit = (out_cnt == CNT_NOTINIT); - - if (out_max_cnt != CNT_NOTINIT) - out_cnt = out_max_cnt; - - if (in_max_cnt != CNT_NOTINIT) - in_cnt = in_max_cnt; - - // TODO: fix counter overflow - if (was_notinit) - { - out_cnt++; - in_cnt++; - } -} - -template -void DataFlowAnalysis::analyze() { - auto curr = 0; - auto stop = nodes.size(); - - while (curr != stop) - { - auto curr_bb = nodes[curr]; - curr_bb->doStep(); - - const auto& jumps = curr_bb->getRollback(); - if (jumps.size() != 0) - { - auto& ignored_jumps = curr_bb->getIgnoreRollback(); - - bool jump = false; - for (const auto& jump_to : jumps) - { - if (ignored_jumps.insert(jump_to).second && curr_bb->newerThan(nodes[jump_to])) - { - jump = true; - curr = jump_to; - break; - } - } - - if (!jump) - curr_bb->getIgnoreRollback().clear(); - else - continue; - } - - curr++; - } -} - -template -DataFlowAnalysis::~DataFlowAnalysis() -{ - for (DataFlowAnalysisNode* node : nodes) - delete node; - - nodes.clear(); -} \ No newline at end of file +#include "data_flow_impl.h" \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow_impl.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow_impl.h new file mode 100644 index 0000000..da5a5fb --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow_impl.h @@ -0,0 +1,113 @@ +#pragma once +#include "data_flow.h" + +#include +#include + +#include "../../Utils/SgUtils.h" +#include "../CFGraph.h" +#include "../IR.h" + +/* Note: this file should be included in data_flow.h to provide template definitions */ + +/* definitions for DataFlowAnalysisNode class */ + +template +const int DataFlowAnalysisNode::CNT_NOTINIT; + +template +DataFlowAnalysisNode::DataFlowAnalysisNode() +{ + getRollback() = {}; + getIgnoreRollback() = {}; + prev_blocks = {}; +} + +template +void DataFlowAnalysisNode::doStep() +{ + int in_max_cnt = CNT_NOTINIT, out_max_cnt = CNT_NOTINIT; + for (auto next : prev_blocks) + { + if (in_cnt < next->out_cnt) + { + for (const auto& byOut : next->getOut()) + { + bool inserted = addIn({ byOut }); + + if (inserted) + { + if (next->out_cnt > in_max_cnt) + in_max_cnt = next->out_cnt; + + inserted = forwardData({ byOut }); + + if (inserted && next->out_cnt > out_max_cnt) + out_max_cnt = next->out_cnt; + } + } + } + } + + bool was_notinit = (out_cnt == CNT_NOTINIT); + + if (out_max_cnt != CNT_NOTINIT) + out_cnt = out_max_cnt; + + if (in_max_cnt != CNT_NOTINIT) + in_cnt = in_max_cnt; + + // TODO: fix counter overflow + if (was_notinit) + { + out_cnt++; + in_cnt++; + } +} + +/* definitions for DataFlowAnalysis class */ + +template +void DataFlowAnalysis::analyze() { + auto curr = 0; + auto stop = nodes.size(); + + while (curr != stop) + { + auto curr_bb = nodes[curr]; + curr_bb->doStep(); + + const auto& jumps = curr_bb->getRollback(); + if (jumps.size() != 0) + { + auto& ignored_jumps = curr_bb->getIgnoreRollback(); + + bool jump = false; + for (const auto& jump_to : jumps) + { + if (ignored_jumps.insert(jump_to).second && curr_bb->newerThan(nodes[jump_to])) + { + jump = true; + curr = jump_to; + break; + } + } + + if (!jump) + curr_bb->getIgnoreRollback().clear(); + else + continue; + } + + curr++; + } +} + +template +DataFlowAnalysis::~DataFlowAnalysis() +{ + for (DataFlowAnalysisNode* node : nodes) + delete node; + + nodes.clear(); +} \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp b/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp index 0836b52..0919566 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp @@ -684,7 +684,7 @@ void runLiveVariableAnalysis(const map>& } set exits; - int max_cnt = CNT_NOTINIT; + int max_cnt = LiveVarAnalysisNode::getStartCounter(); for (auto block : func_it->second->getNodes()) { if (block->getBlock()->getNext().size() == 0)