#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() = {}; prev_blocks = {}; } template void DataFlowAnalysisNode::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 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) { 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 DataFlowAnalysis::~DataFlowAnalysis() { for (NodeType* node : nodes) delete node; nodes.clear(); }