|
|
|
|
@@ -17,7 +17,7 @@ using std::set;
|
|
|
|
|
using std::unordered_map;
|
|
|
|
|
using std::list;
|
|
|
|
|
|
|
|
|
|
using LIVE_VARIABLES::fcall;
|
|
|
|
|
using LIVE_VARIABLES::LiveDeadVarsForCall;
|
|
|
|
|
|
|
|
|
|
namespace SAPFOR
|
|
|
|
|
{
|
|
|
|
|
@@ -152,7 +152,7 @@ namespace SAPFOR
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool fcall::tryInsert(set<SAPFOR::BasicBlock*>& dest, SAPFOR::BasicBlock* b)
|
|
|
|
|
bool LiveDeadVarsForCall::tryInsert(set<SAPFOR::BasicBlock*>& dest, SAPFOR::BasicBlock* b)
|
|
|
|
|
{
|
|
|
|
|
if (b == block || dest.find(block) == dest.end())
|
|
|
|
|
{
|
|
|
|
|
@@ -163,7 +163,7 @@ bool fcall::tryInsert(set<SAPFOR::BasicBlock*>& dest, SAPFOR::BasicBlock* b)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fcall::fcall(FuncInfo* f, SAPFOR::BasicBlock* b, const vector<SAPFOR::Argument*>& p)
|
|
|
|
|
LiveDeadVarsForCall::LiveDeadVarsForCall(FuncInfo* f, SAPFOR::BasicBlock* b, const vector<SAPFOR::Argument*>& p)
|
|
|
|
|
{
|
|
|
|
|
block = b;
|
|
|
|
|
func = f;
|
|
|
|
|
@@ -176,7 +176,7 @@ fcall::fcall(FuncInfo* f, SAPFOR::BasicBlock* b, const vector<SAPFOR::Argument*>
|
|
|
|
|
params[i] = p[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fcall::make_live(SAPFOR::Argument* arg, SAPFOR::BasicBlock* b)
|
|
|
|
|
void LiveDeadVarsForCall::make_live(SAPFOR::Argument* arg, SAPFOR::BasicBlock* b)
|
|
|
|
|
{
|
|
|
|
|
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::COMMON_ || arg->getMemType() == SAPFOR::CFG_MEM_TYPE::MODULE_)
|
|
|
|
|
{
|
|
|
|
|
@@ -193,7 +193,7 @@ void fcall::make_live(SAPFOR::Argument* arg, SAPFOR::BasicBlock* b)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fcall::make_dead(SAPFOR::Argument* arg)
|
|
|
|
|
void LiveDeadVarsForCall::make_dead(SAPFOR::Argument* arg)
|
|
|
|
|
{
|
|
|
|
|
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::COMMON_ || arg->getMemType() == SAPFOR::CFG_MEM_TYPE::MODULE_)
|
|
|
|
|
{
|
|
|
|
|
@@ -210,7 +210,7 @@ void fcall::make_dead(SAPFOR::Argument* arg)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fcall::updateFromOut()
|
|
|
|
|
void LiveDeadVarsForCall::updateFromOut()
|
|
|
|
|
{
|
|
|
|
|
for (const auto& p : block->getLiveOut())
|
|
|
|
|
for (auto b : p.second)
|
|
|
|
|
@@ -221,7 +221,7 @@ static bool getLiveDead(const vector<SAPFOR::Argument*>& params, const string& f
|
|
|
|
|
set<SAPFOR::Argument*>& live, set<SAPFOR::Argument*>& dead);
|
|
|
|
|
|
|
|
|
|
static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
|
|
|
|
vector<SAPFOR::Argument*>& formal_parameters, vector<fcall>& fcalls,
|
|
|
|
|
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
|
|
|
|
const map<string, FuncInfo*>& funcByName, bool interprocedural);
|
|
|
|
|
|
|
|
|
|
class LiveVarAnalysisNode : public DataFlowAnalysisNode<map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>> {
|
|
|
|
|
@@ -260,7 +260,7 @@ public:
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
LiveVarAnalysisNode(SAPFOR::BasicBlock* block, vector<SAPFOR::Argument*>& formal_parameters,
|
|
|
|
|
vector<fcall>& fcalls, const map<string, FuncInfo*>& funcByName)
|
|
|
|
|
vector<LiveDeadVarsForCall>& fcalls, const map<string, FuncInfo*>& funcByName)
|
|
|
|
|
{
|
|
|
|
|
setBlock(block);
|
|
|
|
|
|
|
|
|
|
@@ -274,21 +274,21 @@ public:
|
|
|
|
|
class LiveVarAnalysis : public BackwardDataFlowAnalysis<map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>, LiveVarAnalysisNode> {
|
|
|
|
|
protected:
|
|
|
|
|
vector<SAPFOR::Argument*>& formal_parameters;
|
|
|
|
|
vector<fcall>& fcalls;
|
|
|
|
|
vector<LiveDeadVarsForCall>& fcalls;
|
|
|
|
|
const map<string, FuncInfo*>& funcByName;
|
|
|
|
|
|
|
|
|
|
LiveVarAnalysisNode* createNode(SAPFOR::BasicBlock* block) override {
|
|
|
|
|
return new LiveVarAnalysisNode(block, formal_parameters, fcalls, funcByName);
|
|
|
|
|
};
|
|
|
|
|
public:
|
|
|
|
|
LiveVarAnalysis(vector<SAPFOR::Argument*>& formal_parameters, vector<fcall>& fcalls,
|
|
|
|
|
LiveVarAnalysis(vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
|
|
|
|
const map<string, FuncInfo*>& funcByName) : formal_parameters(formal_parameters), fcalls(fcalls), funcByName(funcByName)
|
|
|
|
|
{ };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
|
|
|
|
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
|
|
|
|
vector<SAPFOR::Argument*>& formal_parameters, vector<fcall>& fcalls,
|
|
|
|
|
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
|
|
|
|
vector<SAPFOR::Argument*>& lastParamRef, int& last_param_ref_index, int& last_param_ref_size,
|
|
|
|
|
string& fName, const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
|
|
|
|
{
|
|
|
|
|
@@ -340,7 +340,7 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins
|
|
|
|
|
auto func_it = funcByName.find(fName);
|
|
|
|
|
if (func_it != funcByName.end())
|
|
|
|
|
{
|
|
|
|
|
fcalls.push_back(fcall(func_it->second, block, lastParamRef));
|
|
|
|
|
fcalls.push_back(LiveDeadVarsForCall(func_it->second, block, lastParamRef));
|
|
|
|
|
|
|
|
|
|
auto r_it = fcalls.rbegin();
|
|
|
|
|
auto r_end = fcalls.rend();
|
|
|
|
|
@@ -376,7 +376,7 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins
|
|
|
|
|
|
|
|
|
|
static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
|
|
|
|
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
|
|
|
|
vector<SAPFOR::Argument*>& formal_parameters, vector<fcall>& fcalls,
|
|
|
|
|
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
|
|
|
|
vector<SAPFOR::Argument*>& lastParamRef, int& last_param_ref_index, int& last_param_ref_size,
|
|
|
|
|
string& fName, const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
|
|
|
|
{
|
|
|
|
|
@@ -411,7 +411,7 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
|
|
|
|
|
|
|
|
|
|
//Build use and def sets of block. Result are stored in use and def
|
|
|
|
|
static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
|
|
|
|
vector<SAPFOR::Argument*>& formal_parameters, vector<fcall>& fcalls,
|
|
|
|
|
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
|
|
|
|
const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
|
|
|
|
{
|
|
|
|
|
vector<SAPFOR::Argument*> lastParamRef;
|
|
|
|
|
@@ -610,7 +610,7 @@ void runLiveVariableAnalysis(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>&
|
|
|
|
|
map<string, LiveVarAnalysis*> func_to_analysis_object;
|
|
|
|
|
map<string, vector<SAPFOR::Argument*>> func_to_parameters;
|
|
|
|
|
|
|
|
|
|
list<vector<fcall>> live_for_fcalls;
|
|
|
|
|
list<vector<LiveDeadVarsForCall>> live_for_fcalls;
|
|
|
|
|
|
|
|
|
|
//TODO: take into account ssc structure
|
|
|
|
|
// main stage
|
|
|
|
|
@@ -639,7 +639,7 @@ void runLiveVariableAnalysis(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>&
|
|
|
|
|
// interprocedural analysis
|
|
|
|
|
for (auto& calls_vector : live_for_fcalls)
|
|
|
|
|
{
|
|
|
|
|
map<FuncInfo*, fcall> assembled_fcalls;
|
|
|
|
|
map<FuncInfo*, LiveDeadVarsForCall> assembled_fcalls;
|
|
|
|
|
for (auto& call : calls_vector)
|
|
|
|
|
{
|
|
|
|
|
call.updateFromOut();
|
|
|
|
|
@@ -649,7 +649,7 @@ void runLiveVariableAnalysis(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>&
|
|
|
|
|
|
|
|
|
|
auto it = assembled_fcalls.find(call.func);
|
|
|
|
|
if (it == assembled_fcalls.end())
|
|
|
|
|
it = assembled_fcalls.insert({ call.func, fcall(call.func, call.block, {}) }).first;
|
|
|
|
|
it = assembled_fcalls.insert({ call.func, LiveDeadVarsForCall(call.func, call.block, {}) }).first;
|
|
|
|
|
|
|
|
|
|
for (const auto& p : call.live_after)
|
|
|
|
|
it->second.live_after[p.first].insert(p.second.begin(), p.second.end());
|
|
|
|
|
|