moved
This commit is contained in:
21
Sapfor/_src/CFGraph/DataFlow/backward_data_flow.h
Normal file
21
Sapfor/_src/CFGraph/DataFlow/backward_data_flow.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "data_flow.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../../Utils/SgUtils.h"
|
||||
#include "../CFGraph.h"
|
||||
#include "../IR.h"
|
||||
|
||||
template <class NodeType>
|
||||
class BackwardDataFlowAnalysis : public DataFlowAnalysis<NodeType>
|
||||
{
|
||||
std::vector<SAPFOR::BasicBlock*> reorderSequence(const std::vector<SAPFOR::BasicBlock*>& blocks,
|
||||
const std::set<SAPFOR::BasicBlock*> back_edge_sources);
|
||||
public:
|
||||
void fit(const std::vector<SAPFOR::BasicBlock*>& blocks);
|
||||
};
|
||||
|
||||
#include "backward_data_flow_impl.h"
|
||||
103
Sapfor/_src/CFGraph/DataFlow/backward_data_flow_impl.h
Normal file
103
Sapfor/_src/CFGraph/DataFlow/backward_data_flow_impl.h
Normal file
@@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
#include "backward_data_flow.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
#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 <class NodeType>
|
||||
std::vector<SAPFOR::BasicBlock*>
|
||||
BackwardDataFlowAnalysis<NodeType>::reorderSequence(const std::vector<SAPFOR::BasicBlock*>& blocks,
|
||||
const std::set<SAPFOR::BasicBlock*> back_edge_sources)
|
||||
{
|
||||
std::vector<SAPFOR::BasicBlock*> 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 <class NodeType>
|
||||
void BackwardDataFlowAnalysis<NodeType>::fit(const std::vector<SAPFOR::BasicBlock*>& blocks)
|
||||
{
|
||||
std::set<std::pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>> back_edges = {};
|
||||
|
||||
bool returned = false;
|
||||
std::map<SAPFOR::BasicBlock*, std::set<SAPFOR::BasicBlock*>> back_edges_by_src;
|
||||
|
||||
auto blocks_sorted = sortCfgNodes(blocks, &back_edges);
|
||||
|
||||
std::set<SAPFOR::BasicBlock*> 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());
|
||||
|
||||
this->nodes.clear();
|
||||
std::map<SAPFOR::BasicBlock*, NodeType*> node_by_block;
|
||||
|
||||
for (auto block : blocks_sorted)
|
||||
{
|
||||
NodeType* node = this->createNode(block);
|
||||
this->nodes.push_back(node);
|
||||
node_by_block[block] = node;
|
||||
}
|
||||
|
||||
int nodes_size = this->nodes.size();
|
||||
|
||||
for (int i = 0; i < nodes_size; i++)
|
||||
{
|
||||
NodeType* node = this->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);
|
||||
}
|
||||
}
|
||||
}
|
||||
68
Sapfor/_src/CFGraph/DataFlow/data_flow.h
Normal file
68
Sapfor/_src/CFGraph/DataFlow/data_flow.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
#include<vector>
|
||||
#include<set>
|
||||
|
||||
#include "../../Utils/SgUtils.h"
|
||||
#include "../CFGraph.h"
|
||||
#include "../IR.h"
|
||||
|
||||
enum class DATA_FLOW_UPD_STATUS { NO_CHANGE = 0, PROPAGATED, GENERATED };
|
||||
|
||||
template <class DataType>
|
||||
class DataFlowAnalysisNode {
|
||||
static const int CNT_NOTINIT = 0;
|
||||
|
||||
int in_cnt = CNT_NOTINIT, out_cnt = CNT_NOTINIT;
|
||||
|
||||
std::set<int> rollback;
|
||||
|
||||
std::set<DataFlowAnalysisNode<DataType>*> prev_blocks;
|
||||
|
||||
SAPFOR::BasicBlock* bb;
|
||||
public:
|
||||
DataFlowAnalysisNode();
|
||||
|
||||
void doStep();
|
||||
|
||||
virtual DataType getIn() = 0;
|
||||
virtual DataType getOut() = 0;
|
||||
|
||||
virtual bool addIn(const DataType& data) = 0;
|
||||
virtual bool addOut(const DataType& data) = 0;
|
||||
|
||||
virtual bool updateState() { return false; }
|
||||
virtual DATA_FLOW_UPD_STATUS forwardData(const DataType& data) = 0;
|
||||
|
||||
bool newerThan(const DataFlowAnalysisNode<DataType>* block) const { return out_cnt > block->in_cnt; }
|
||||
|
||||
int getInCnt() { return in_cnt; }
|
||||
int getOutCnt() { return out_cnt; }
|
||||
|
||||
void setInCnt(int cnt) { in_cnt = cnt; }
|
||||
void setOutCnt(int cnt) { out_cnt = cnt; }
|
||||
static int getStartCounter() { return CNT_NOTINIT; }
|
||||
|
||||
std::set<int>& getRollback() { return rollback; }
|
||||
|
||||
std::set<DataFlowAnalysisNode<DataType>*>& getPrevBlocks() { return prev_blocks; }
|
||||
|
||||
SAPFOR::BasicBlock* getBlock() { return bb; }
|
||||
void setBlock(SAPFOR::BasicBlock* b) { bb = b; }
|
||||
};
|
||||
|
||||
template <class NodeType>
|
||||
class DataFlowAnalysis {
|
||||
protected:
|
||||
std::vector<NodeType*> nodes;
|
||||
|
||||
virtual NodeType* createNode(SAPFOR::BasicBlock* block) = 0;
|
||||
public:
|
||||
virtual void fit(const std::vector<SAPFOR::BasicBlock*>& blocks) = 0;
|
||||
void analyze();
|
||||
|
||||
const std::vector<NodeType*>& getNodes() { return nodes; }
|
||||
|
||||
~DataFlowAnalysis();
|
||||
};
|
||||
|
||||
#include "data_flow_impl.h"
|
||||
112
Sapfor/_src/CFGraph/DataFlow/data_flow_impl.h
Normal file
112
Sapfor/_src/CFGraph/DataFlow/data_flow_impl.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#pragma once
|
||||
#include "data_flow.h"
|
||||
|
||||
#include<vector>
|
||||
#include<set>
|
||||
|
||||
#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 <class DataType>
|
||||
const int DataFlowAnalysisNode<DataType>::CNT_NOTINIT;
|
||||
|
||||
template <class DataType>
|
||||
DataFlowAnalysisNode<DataType>::DataFlowAnalysisNode()
|
||||
{
|
||||
getRollback() = {};
|
||||
prev_blocks = {};
|
||||
}
|
||||
|
||||
template <class DataType>
|
||||
void DataFlowAnalysisNode<DataType>::doStep()
|
||||
{
|
||||
int in_max_cnt = CNT_NOTINIT, out_max_cnt = CNT_NOTINIT;
|
||||
|
||||
bool uniq_change = updateState();
|
||||
for (auto next : prev_blocks)
|
||||
{
|
||||
if (in_cnt < next->out_cnt)
|
||||
{
|
||||
if (next->out_cnt > in_max_cnt)
|
||||
in_max_cnt = next->out_cnt;
|
||||
|
||||
const auto& byOut = next->getOut();
|
||||
bool inserted = addIn( byOut);
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
auto status = forwardData(byOut);
|
||||
inserted = status != DATA_FLOW_UPD_STATUS::NO_CHANGE;
|
||||
|
||||
if (inserted && next->out_cnt > out_max_cnt)
|
||||
out_max_cnt = next->out_cnt;
|
||||
|
||||
uniq_change |= status == DATA_FLOW_UPD_STATUS::GENERATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uniq_change |= (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 (uniq_change)
|
||||
{
|
||||
out_cnt++;
|
||||
in_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
/* definitions for DataFlowAnalysis class */
|
||||
|
||||
template <class NodeType>
|
||||
void DataFlowAnalysis<NodeType>::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)
|
||||
{
|
||||
bool jump = false;
|
||||
for (const auto& jump_to : jumps)
|
||||
{
|
||||
if (curr_bb->newerThan(nodes[jump_to]))
|
||||
{
|
||||
jump = true;
|
||||
curr = jump_to;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (jump)
|
||||
continue;
|
||||
}
|
||||
|
||||
curr++;
|
||||
}
|
||||
}
|
||||
|
||||
template <class NodeType>
|
||||
DataFlowAnalysis<NodeType>::~DataFlowAnalysis()
|
||||
{
|
||||
for (NodeType* node : nodes)
|
||||
delete node;
|
||||
|
||||
nodes.clear();
|
||||
}
|
||||
Reference in New Issue
Block a user