finalyze moving
This commit is contained in:
151
src/CFGraph/CFGraph.h
Normal file
151
src/CFGraph/CFGraph.h
Normal file
@@ -0,0 +1,151 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "IR.h"
|
||||
|
||||
namespace SAPFOR
|
||||
{
|
||||
enum CFG_VAL : int { KILL_ALL = -1, UNINIT = -2 };
|
||||
|
||||
class IR_Block;
|
||||
class Argument;
|
||||
class Instruction;
|
||||
|
||||
class BasicBlock
|
||||
{
|
||||
static int lastNumBlock;
|
||||
private:
|
||||
int num;
|
||||
std::vector<IR_Block*> instructions;
|
||||
|
||||
std::vector<BasicBlock*> next;
|
||||
std::vector<BasicBlock*> prev;
|
||||
|
||||
//reaching definition
|
||||
std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out;
|
||||
|
||||
//live variables [arg -> blocks with usages]
|
||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> live_in, live_out, live_inout;
|
||||
|
||||
bool addLive(const std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& to_add, bool in);
|
||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> getLive(bool in) const;
|
||||
bool removeLive(SAPFOR::Argument* to_remove, bool in);
|
||||
public:
|
||||
BasicBlock() { num = lastNumBlock++; }
|
||||
BasicBlock(IR_Block* item);
|
||||
BasicBlock(const BasicBlock& copyFrom);
|
||||
|
||||
void addInstructionBeforeInstruction(IR_Block* item, Instruction* istruction);
|
||||
void addInstructionInFront(IR_Block* item);
|
||||
void addInstruction(IR_Block* item);
|
||||
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
||||
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
||||
|
||||
int removePrev(BasicBlock* removed);
|
||||
int removeNext(BasicBlock* removed);
|
||||
|
||||
void replacePrevNext(const std::map<BasicBlock*, BasicBlock*>& oldToNew)
|
||||
{
|
||||
for (int z = 0; z < next.size(); ++z)
|
||||
{
|
||||
auto it = oldToNew.find(next[z]);
|
||||
if (it == oldToNew.end())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
next[z] = it->second;
|
||||
}
|
||||
|
||||
for (int z = 0; z < prev.size(); ++z)
|
||||
{
|
||||
auto it = oldToNew.find(prev[z]);
|
||||
if (it == oldToNew.end())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
prev[z] = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
int getNumber() const { return num; }
|
||||
const std::vector<IR_Block*>& getInstructions() const { return instructions; }
|
||||
const std::vector<BasicBlock*>& getNext() const { return next; }
|
||||
const std::vector<BasicBlock*>& getPrev() const { return prev; }
|
||||
|
||||
/*
|
||||
* FOR LIVE ANALYSIS
|
||||
*/
|
||||
bool addLiveIn(const std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& to_add) { return addLive(to_add, true); };
|
||||
bool addLiveOut(const std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& to_add) { return addLive(to_add, false); };
|
||||
|
||||
bool removeLiveIn(SAPFOR::Argument* to_remove) { return removeLive(to_remove, true); };
|
||||
bool removeLiveOut(SAPFOR::Argument* to_remove) { return removeLive(to_remove, false); };
|
||||
|
||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> getLiveIn() const { return getLive(true); };
|
||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> getLiveOut() const { return getLive(false); };
|
||||
void compressLives();
|
||||
|
||||
/*
|
||||
* FOR REACHING DEFINITIONS
|
||||
*/
|
||||
void setRD_In(const std::map<Argument*, std::set<int>>& inSet) { RD_in = inSet; }
|
||||
void setRD_Out(const std::map<Argument*, std::set<int>>& outSet) { RD_out = outSet; }
|
||||
const std::map<Argument*, std::set<int>>& getRD_In() const { return RD_in; }
|
||||
const std::map<Argument*, std::set<int>>& getRD_Out() const { return RD_out; }
|
||||
std::map<Argument*, std::set<int>>& getModRD_In() { return RD_in; }
|
||||
std::map<Argument*, std::set<int>>& getModRD_Out() { return RD_out; }
|
||||
|
||||
~BasicBlock();
|
||||
};
|
||||
|
||||
struct CFG_Settings
|
||||
{
|
||||
bool atLeastOneIterInLoop = false;
|
||||
bool withRD = true;
|
||||
bool withRegisters = false;
|
||||
bool withSPF = false;
|
||||
bool withDVM = false;
|
||||
bool withCallsInBlocks = false; // separate each F_CALL to own BasicBlock
|
||||
bool withCallFrom = true;
|
||||
|
||||
explicit CFG_Settings(int) { }
|
||||
|
||||
explicit CFG_Settings(bool atLeastOneIterInLoop = false, bool withRD = true, bool withRegisters = false,
|
||||
bool withDVM = false, bool withSPF = false, bool withCallsInBlocks = false, bool withCallFrom = true) :
|
||||
atLeastOneIterInLoop(atLeastOneIterInLoop), withRD(withRD), withRegisters(withRegisters), withDVM(withDVM), withSPF(withSPF),
|
||||
withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom)
|
||||
{ }
|
||||
};
|
||||
}
|
||||
|
||||
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>> buildCFG(const std::map<std::string, CommonBlock*>& commonBlocks, const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo, const SAPFOR::CFG_Settings settings);
|
||||
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>> buildCFGforCurrentFunc(SgStatement* stmt, SAPFOR::CFG_Settings settings, const std::map<std::string, CommonBlock*>& commonBlocks, const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
|
||||
|
||||
std::vector<std::pair<const Variable*, CommonBlock*>> getCommonsByFunction(SgFile* file, SgStatement* function, const std::map<std::string, CommonBlock*>& commonBlocks);
|
||||
std::vector<SAPFOR::IR_Block*> getAllIR(const std::vector<SAPFOR::BasicBlock*>& blocks);
|
||||
void dumpCFG(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& blocks, bool withRD);
|
||||
std::vector<std::set<FuncInfo*>> groupByCallDependencies(const std::map<FuncInfo*, std::set<FuncInfo*>>& callDeps, std::vector<std::set<FuncInfo*>>& scc);
|
||||
|
||||
template<typename T>
|
||||
bool intersectAndAdd(std::set<T>& s1, const std::set<T>& s2);
|
||||
|
||||
void buildGenKillForCFG(const std::vector<SAPFOR::BasicBlock*>& CFG,
|
||||
const std::map<std::string, FuncInfo*>& funcByName,
|
||||
const std::map<FuncInfo*, std::map<SAPFOR::Argument*, std::set<int>>>& outForFunc,
|
||||
std::map<SAPFOR::BasicBlock*, std::map<SAPFOR::Argument*, std::set<int>>>& gen,
|
||||
std::map<SAPFOR::BasicBlock*, std::map<SAPFOR::Argument*, std::set<int>>>& kill,
|
||||
std::map<SAPFOR::Instruction*, std::map<SAPFOR::Argument*, std::set<int>>>* genForIR,
|
||||
std::map<SAPFOR::Instruction*, std::map<SAPFOR::Argument*, std::set<int>>>* killForIR,
|
||||
std::map<SAPFOR::BasicBlock*, std::set<SAPFOR::Argument*>>& notInitedGlobals,
|
||||
const SAPFOR::CFG_Settings settings);
|
||||
|
||||
static inline void deleteCFG(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& cfg)
|
||||
{
|
||||
for (auto& byFunc : cfg)
|
||||
{
|
||||
for (auto& block : byFunc.second)
|
||||
delete block;
|
||||
byFunc.second.clear();
|
||||
}
|
||||
cfg.clear();
|
||||
}
|
||||
Reference in New Issue
Block a user