#pragma once #include #include #include "SgUtils.h" #include "../CFGraph.h" #include "../IR.h" enum class DATA_FLOW_UPD_STATUS { NO_CHANGE = 0, PROPAGATED, GENERATED }; template class DataFlowAnalysisNode { static const int CNT_NOTINIT = 0; int in_cnt = CNT_NOTINIT, out_cnt = CNT_NOTINIT; std::set rollback; std::set*> 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* 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& getRollback() { return rollback; } std::set*>& getPrevBlocks() { return prev_blocks; } SAPFOR::BasicBlock* getBlock() { return bb; } void setBlock(SAPFOR::BasicBlock* b) { bb = b; } }; template class DataFlowAnalysis { protected: std::vector nodes; virtual NodeType* createNode(SAPFOR::BasicBlock* block) = 0; public: virtual void fit(const std::vector& blocks) = 0; void analyze(); const std::vector& getNodes() { return nodes; } ~DataFlowAnalysis(); }; #include "data_flow_impl.h"