Files
SAPFOR/src/CFGraph/DataFlow/data_flow_impl.h
2025-06-04 13:08:38 +03:00

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();
}