112 lines
2.5 KiB
C++
112 lines
2.5 KiB
C++
#pragma once
|
|
#include "data_flow.h"
|
|
|
|
#include<vector>
|
|
#include<set>
|
|
|
|
#include "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();
|
|
} |