dead_code_removing #40
@@ -33,23 +33,21 @@ void DataFlowAnalysisNode<DataType>::doStep()
|
|||||||
{
|
{
|
||||||
if (in_cnt < next->out_cnt)
|
if (in_cnt < next->out_cnt)
|
||||||
{
|
{
|
||||||
for (const auto& byOut : next->getOut())
|
const auto& byOut = next->getOut();
|
||||||
{
|
bool inserted = addIn( byOut);
|
||||||
bool inserted = addIn({ byOut });
|
|
||||||
|
|
||||||
if (inserted)
|
if (inserted)
|
||||||
{
|
{
|
||||||
if (next->out_cnt > in_max_cnt)
|
if (next->out_cnt > in_max_cnt)
|
||||||
in_max_cnt = next->out_cnt;
|
in_max_cnt = next->out_cnt;
|
||||||
|
|
||||||
inserted = forwardData({ byOut });
|
inserted = forwardData(byOut);
|
||||||
|
|
||||||
if (inserted && next->out_cnt > out_max_cnt)
|
if (inserted && next->out_cnt > out_max_cnt)
|
||||||
out_max_cnt = next->out_cnt;
|
out_max_cnt = next->out_cnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
uniq_change |= (out_cnt == CNT_NOTINIT);
|
uniq_change |= (out_cnt == CNT_NOTINIT);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::pair;
|
using std::pair;
|
||||||
@@ -138,7 +139,11 @@ namespace SAPFOR
|
|||||||
for (auto& by_pair : by_source)
|
for (auto& by_pair : by_source)
|
||||||
{
|
{
|
||||||
auto& dest = res[by_pair.first];
|
auto& dest = res[by_pair.first];
|
||||||
dest.insert(dest.end(), by_pair.second.begin(), by_pair.second.end());
|
auto dest_copy = dest;
|
||||||
|
|
||||||
|
dest.resize(dest_copy.size() + by_pair.second.size());
|
||||||
|
|
||||||
|
set_union(dest_copy.begin(), dest_copy.end(), by_pair.second.begin(), by_pair.second.end(), dest.begin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,39 +294,46 @@ public:
|
|||||||
void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
||||||
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
||||||
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
||||||
vector<SAPFOR::Argument*>& lastParamRef, int& last_param_ref_index, int& last_param_ref_size,
|
vector<SAPFOR::Argument*>& arg_stack, int& arg_stack_index, int& arg_stack_size,
|
||||||
|
bool& last_stack_op,
|
||||||
string& fName, const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
string& fName, const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
||||||
{
|
{
|
||||||
for (auto arg : { instr->getArg1(), instr->getArg2(), instr->getResult() })
|
for (auto arg : { instr->getArg1(), instr->getArg2(), instr->getResult() })
|
||||||
if (arg && arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_)
|
if (arg && arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_)
|
||||||
formal_parameters[getParamIndex(arg, formal_parameters.size())] = arg;
|
formal_parameters[getParamIndex(arg, formal_parameters.size())] = arg;
|
||||||
|
|
||||||
|
last_stack_op = false;
|
||||||
SAPFOR::Argument* res_arg = NULL;
|
SAPFOR::Argument* res_arg = NULL;
|
||||||
|
|
||||||
static const set<SAPFOR::CFG_OP> skip = { SAPFOR::CFG_OP::ENTRY };
|
static const set<SAPFOR::CFG_OP> skip = { SAPFOR::CFG_OP::ENTRY };
|
||||||
SAPFOR::CFG_OP instr_operation = instr->getOperation();
|
SAPFOR::CFG_OP instr_operation = instr->getOperation();
|
||||||
if (hasStoreStructure(instr_operation))
|
if (instr_operation == SAPFOR::CFG_OP::F_CALL ||
|
||||||
|
instr_operation == SAPFOR::CFG_OP::STORE ||
|
||||||
|
instr_operation == SAPFOR::CFG_OP::LOAD)
|
||||||
|
{
|
||||||
|
res_arg = (instr_operation == SAPFOR::CFG_OP::STORE ? instr->getArg1() : instr->getResult());
|
||||||
|
if(instr_operation != SAPFOR::CFG_OP::F_CALL)
|
||||||
|
use.insert(instr_operation != SAPFOR::CFG_OP::STORE ? instr->getArg1() : instr->getResult());
|
||||||
|
|
||||||
|
arg_stack_size = stoi(instr->getArg2()->getValue());
|
||||||
|
|
||||||
|
arg_stack.clear();
|
||||||
|
arg_stack.resize(arg_stack_size);
|
||||||
|
|
||||||
|
arg_stack_index = arg_stack_size - 1;
|
||||||
|
|
||||||
|
if(instr_operation == SAPFOR::CFG_OP::F_CALL)
|
||||||
|
fName = instr->getArg1()->getValue();
|
||||||
|
}
|
||||||
|
else if (hasStoreStructure(instr_operation))
|
||||||
{
|
{
|
||||||
res_arg = instr->getArg1();
|
res_arg = instr->getArg1();
|
||||||
set<SAPFOR::Argument*> instr_args = { instr->getResult(), instr->getArg2() };
|
set<SAPFOR::Argument*> instr_args = { instr->getResult(), instr->getArg2() };
|
||||||
use.insert(instr_args.begin(), instr_args.end());
|
use.insert(instr_args.begin(), instr_args.end());
|
||||||
}
|
}
|
||||||
else if (instr_operation == SAPFOR::CFG_OP::PARAM)
|
else if (instr_operation == SAPFOR::CFG_OP::PARAM || instr_operation == SAPFOR::CFG_OP::REF)
|
||||||
{
|
{
|
||||||
lastParamRef[last_param_ref_index--] = instr->getArg1();
|
arg_stack[arg_stack_index--] = instr->getArg1();
|
||||||
}
|
|
||||||
else if (instr_operation == SAPFOR::CFG_OP::F_CALL)
|
|
||||||
{
|
|
||||||
res_arg = instr->getResult();
|
|
||||||
|
|
||||||
last_param_ref_size = stoi(instr->getArg2()->getValue());
|
|
||||||
|
|
||||||
lastParamRef.clear();
|
|
||||||
lastParamRef.resize(last_param_ref_size);
|
|
||||||
|
|
||||||
last_param_ref_index = last_param_ref_size - 1;
|
|
||||||
|
|
||||||
fName = instr->getArg1()->getValue();
|
|
||||||
}
|
}
|
||||||
else if (skip.find(instr_operation) == skip.end())
|
else if (skip.find(instr_operation) == skip.end())
|
||||||
{
|
{
|
||||||
@@ -336,11 +348,13 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((instr_operation == SAPFOR::CFG_OP::F_CALL || instr_operation == SAPFOR::CFG_OP::PARAM) && last_param_ref_index < 0) {
|
if (arg_stack_index < 0) {
|
||||||
|
if(instr_operation == SAPFOR::CFG_OP::PARAM || instr_operation == SAPFOR::CFG_OP::F_CALL)
|
||||||
|
{
|
||||||
auto func_it = funcByName.find(fName);
|
auto func_it = funcByName.find(fName);
|
||||||
if (interprocedural && func_it != funcByName.end())
|
if (interprocedural && func_it != funcByName.end())
|
||||||
{
|
{
|
||||||
fcalls.push_back(LiveDeadVarsForCall(func_it->second, block, lastParamRef));
|
fcalls.push_back(LiveDeadVarsForCall(func_it->second, block, arg_stack));
|
||||||
|
|
||||||
auto r_it = fcalls.rbegin();
|
auto r_it = fcalls.rbegin();
|
||||||
auto r_end = fcalls.rend();
|
auto r_end = fcalls.rend();
|
||||||
@@ -354,33 +368,41 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins
|
|||||||
|
|
||||||
set<SAPFOR::Argument*> make_live, make_dead;
|
set<SAPFOR::Argument*> make_live, make_dead;
|
||||||
if (fName == "_READ")
|
if (fName == "_READ")
|
||||||
def.insert(lastParamRef.begin(), lastParamRef.end());
|
def.insert(arg_stack.begin(), arg_stack.end());
|
||||||
else if (interprocedural && getLiveDead(lastParamRef, fName, make_live, make_dead))
|
else if (interprocedural && getLiveDead(arg_stack, fName, make_live, make_dead))
|
||||||
{
|
{
|
||||||
use.insert(make_live.begin(), make_live.end());
|
use.insert(make_live.begin(), make_live.end());
|
||||||
def.insert(make_dead.begin(), make_dead.end());
|
def.insert(make_dead.begin(), make_dead.end());
|
||||||
}
|
}
|
||||||
else if (func_it != funcByName.end())
|
else if (func_it != funcByName.end())
|
||||||
{
|
{
|
||||||
int arg_num = lastParamRef.size();
|
int arg_num = arg_stack.size();
|
||||||
for (int i = 0; i < arg_num; i++)
|
for (int i = 0; i < arg_num; i++)
|
||||||
{
|
{
|
||||||
if(func_it->second->funcParams.isArgOut(i))
|
if(func_it->second->funcParams.isArgOut(i))
|
||||||
def.insert(lastParamRef[i]);
|
def.insert(arg_stack[i]);
|
||||||
|
|
||||||
if (func_it->second->funcParams.isArgIn(i))
|
if (func_it->second->funcParams.isArgIn(i))
|
||||||
use.insert(lastParamRef[i]);
|
use.insert(arg_stack[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
use.insert(lastParamRef.begin(), lastParamRef.end());
|
use.insert(arg_stack.begin(), arg_stack.end());
|
||||||
|
|
||||||
last_param_ref_index = 0;
|
|
||||||
last_param_ref_size = 0;
|
|
||||||
|
|
||||||
lastParamRef.clear();
|
|
||||||
fName = "";
|
fName = "";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
use.insert(arg_stack.begin(), arg_stack.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
arg_stack_index = 0;
|
||||||
|
arg_stack_size = 0;
|
||||||
|
|
||||||
|
arg_stack.clear();
|
||||||
|
|
||||||
|
last_stack_op = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (res_arg)
|
if (res_arg)
|
||||||
def.insert(res_arg);
|
def.insert(res_arg);
|
||||||
@@ -389,15 +411,16 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins
|
|||||||
static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
||||||
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
||||||
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
||||||
vector<SAPFOR::Argument*>& lastParamRef, int& last_param_ref_index, int& last_param_ref_size,
|
vector<SAPFOR::Argument*>& arg_stack, int& arg_stack_index, int& arg_stack_size,
|
||||||
string& fName, const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
string& fName, const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
||||||
{
|
{
|
||||||
set<SAPFOR::Argument*> res, args;
|
set<SAPFOR::Argument*> res, args;
|
||||||
|
bool last_stack_op;
|
||||||
getUseDefForInstruction(block, instr,
|
getUseDefForInstruction(block, instr,
|
||||||
args, res,
|
args, res,
|
||||||
formal_parameters, fcalls,
|
formal_parameters, fcalls,
|
||||||
lastParamRef, last_param_ref_index, last_param_ref_size,
|
arg_stack, arg_stack_index, arg_stack_size,
|
||||||
|
last_stack_op,
|
||||||
fName, funcByName,
|
fName, funcByName,
|
||||||
interprocedural
|
interprocedural
|
||||||
);
|
);
|
||||||
@@ -426,8 +449,8 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use,
|
|||||||
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
||||||
const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
||||||
{
|
{
|
||||||
vector<SAPFOR::Argument*> lastParamRef;
|
vector<SAPFOR::Argument*> arg_stack;
|
||||||
int last_param_ref_index = 0, last_param_ref_size = 0;
|
int arg_stack_index = 0, arg_stack_size = 0;
|
||||||
string fName;
|
string fName;
|
||||||
|
|
||||||
const auto& instructions = block->getInstructions();
|
const auto& instructions = block->getInstructions();
|
||||||
@@ -438,7 +461,7 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use,
|
|||||||
updateUseDefForInstruction(block, (*ir_block_it)->getInstruction(),
|
updateUseDefForInstruction(block, (*ir_block_it)->getInstruction(),
|
||||||
use, def,
|
use, def,
|
||||||
formal_parameters, fcalls,
|
formal_parameters, fcalls,
|
||||||
lastParamRef, last_param_ref_index, last_param_ref_size,
|
arg_stack, arg_stack_index, arg_stack_size,
|
||||||
fName, funcByName,
|
fName, funcByName,
|
||||||
interprocedural
|
interprocedural
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ void insertIfVar(IT begin, IT end, DEST& to) {
|
|||||||
void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
||||||
std::set<SAPFOR::Argument*>& use, std::set<SAPFOR::Argument*>& def,
|
std::set<SAPFOR::Argument*>& use, std::set<SAPFOR::Argument*>& def,
|
||||||
std::vector<SAPFOR::Argument*>& formal_parameters, std::vector<LIVE_VARIABLES::LiveDeadVarsForCall>& fcalls,
|
std::vector<SAPFOR::Argument*>& formal_parameters, std::vector<LIVE_VARIABLES::LiveDeadVarsForCall>& fcalls,
|
||||||
std::vector<SAPFOR::Argument*>& lastParamRef, int& last_param_ref_index, int& last_param_ref_size,
|
std::vector<SAPFOR::Argument*>& arg_stack, int& arg_stack_index, int& arg_stack_size,
|
||||||
|
bool& last_stack_op,
|
||||||
std::string& fName, const std::map<std::string, FuncInfo*>& funcByName, bool interprocedural);
|
std::string& fName, const std::map<std::string, FuncInfo*>& funcByName, bool interprocedural);
|
||||||
|
|
||||||
void runLiveVariableAnalysis(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& CFGraph_for_project);
|
void runLiveVariableAnalysis(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& CFGraph_for_project);
|
||||||
|
|||||||
@@ -1028,6 +1028,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
{
|
{
|
||||||
auto funcsForFile = getObjectForFileFromMap(file_name, allFuncInfo);
|
auto funcsForFile = getObjectForFileFromMap(file_name, allFuncInfo);
|
||||||
for (auto& func : funcsForFile)
|
for (auto& func : funcsForFile)
|
||||||
|
if(func->funcPointer->variant() != ENTRY_STAT)
|
||||||
removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks);
|
removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks);
|
||||||
}
|
}
|
||||||
else if (curr_regime == TEST_PASS)
|
else if (curr_regime == TEST_PASS)
|
||||||
|
|||||||
@@ -16,59 +16,30 @@ using std::remove_if;
|
|||||||
#define PRINT_USELESS_STATEMENTS 1
|
#define PRINT_USELESS_STATEMENTS 1
|
||||||
#define DEBUG_IR 0
|
#define DEBUG_IR 0
|
||||||
|
|
||||||
// detect wich registers are used at more than one block
|
|
||||||
// such registers should participate in live analysis to spread information about useful instructions
|
|
||||||
// such registers appears at loops
|
|
||||||
static void fillSharedRegs(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& cfg, set<SAPFOR::Argument*>& shared_regs)
|
|
||||||
{
|
|
||||||
map<SAPFOR::Argument*, SAPFOR::BasicBlock*> used_at;
|
|
||||||
|
|
||||||
for (const auto& byFunc : cfg)
|
|
||||||
{
|
|
||||||
for (const auto& byBlock : byFunc.second)
|
|
||||||
{
|
|
||||||
for (const auto& byIrBlock : byBlock->getInstructions())
|
|
||||||
{
|
|
||||||
auto instr = byIrBlock->getInstruction();
|
|
||||||
|
|
||||||
set<SAPFOR::Argument*> used = { instr->getResult(), instr->getArg1(), instr->getArg2() };
|
|
||||||
for (auto arg : used)
|
|
||||||
{
|
|
||||||
if(arg && arg->getType() == SAPFOR::CFG_ARG_TYPE::REG)
|
|
||||||
{
|
|
||||||
auto it = used_at.find(arg);
|
|
||||||
|
|
||||||
if (it == used_at.end())
|
|
||||||
used_at[arg] = byBlock;
|
|
||||||
else if(it->second != byBlock)
|
|
||||||
shared_regs.insert(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
||||||
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
||||||
vector<SAPFOR::Argument*>& formal_parameters,
|
vector<SAPFOR::Argument*>& formal_parameters,
|
||||||
vector<SAPFOR::Argument*>& lastParamRef, int& last_param_ref_index, int& last_param_ref_size,
|
vector<SAPFOR::Argument*>& arg_stack, int& arg_stack_index, int& arg_stack_size,
|
||||||
string& fName, const map<string, FuncInfo*>& funcByName,
|
string& fName, const map<string, FuncInfo*>& funcByName,
|
||||||
bool& useful, bool& last_fcall_useful,
|
bool& useful, bool& last_stack_op_useful,
|
||||||
set<SAPFOR::Argument*>& usedByThisBlock)
|
set<SAPFOR::Argument*>& usedByThisBlock)
|
||||||
{
|
{
|
||||||
set<SAPFOR::Argument*> res, args;
|
set<SAPFOR::Argument*> res, args;
|
||||||
|
bool last_stack_op;
|
||||||
|
|
||||||
vector<LIVE_VARIABLES::LiveDeadVarsForCall> fcalls;
|
vector<LIVE_VARIABLES::LiveDeadVarsForCall> fcalls;
|
||||||
|
|
||||||
getUseDefForInstruction(block, instr,
|
getUseDefForInstruction(block, instr,
|
||||||
args, res,
|
args, res,
|
||||||
formal_parameters, fcalls,
|
formal_parameters, fcalls,
|
||||||
lastParamRef, last_param_ref_index, last_param_ref_size,
|
arg_stack, arg_stack_index, arg_stack_size,
|
||||||
|
last_stack_op,
|
||||||
fName, funcByName,
|
fName, funcByName,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const auto instr_operation = instr->getOperation();
|
||||||
|
|
||||||
if (!useful)
|
if (!useful)
|
||||||
{
|
{
|
||||||
for (SAPFOR::Argument* r : res)
|
for (SAPFOR::Argument* r : res)
|
||||||
@@ -85,7 +56,7 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
|
|||||||
|
|
||||||
if (!useful)
|
if (!useful)
|
||||||
{
|
{
|
||||||
set<SAPFOR::CFG_OP> always_useful =
|
static const set<SAPFOR::CFG_OP> always_useful =
|
||||||
{
|
{
|
||||||
SAPFOR::CFG_OP::POINTER_ASS,
|
SAPFOR::CFG_OP::POINTER_ASS,
|
||||||
SAPFOR::CFG_OP::STORE,
|
SAPFOR::CFG_OP::STORE,
|
||||||
@@ -97,21 +68,24 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
|
|||||||
SAPFOR::CFG_OP::SPF_DIR
|
SAPFOR::CFG_OP::SPF_DIR
|
||||||
};
|
};
|
||||||
|
|
||||||
if (always_useful.find(instr->getOperation()) != always_useful.end())
|
if (always_useful.find(instr_operation) != always_useful.end())
|
||||||
useful = true;
|
useful = true;
|
||||||
else if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
|
else if (instr_operation == SAPFOR::CFG_OP::F_CALL)
|
||||||
{
|
{
|
||||||
auto func_it = funcByName.find(instr->getArg1()->getValue());
|
auto func_it = funcByName.find(instr->getArg1()->getValue());
|
||||||
useful |= func_it == funcByName.end() || !(func_it->second->isPure);
|
useful |= func_it == funcByName.end() || !(func_it->second->isPure);
|
||||||
}
|
}
|
||||||
else if (instr->getOperation() == SAPFOR::CFG_OP::PARAM)
|
else if (instr_operation == SAPFOR::CFG_OP::PARAM ||
|
||||||
useful |= last_fcall_useful;
|
instr_operation == SAPFOR::CFG_OP::REF)
|
||||||
|
useful |= last_stack_op_useful;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useful)
|
if (useful)
|
||||||
{
|
{
|
||||||
if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
|
if (instr_operation == SAPFOR::CFG_OP::F_CALL ||
|
||||||
last_fcall_useful = true;
|
instr_operation == SAPFOR::CFG_OP::LOAD ||
|
||||||
|
instr_operation == SAPFOR::CFG_OP::STORE)
|
||||||
|
last_stack_op_useful = true;
|
||||||
|
|
||||||
for (auto e : res)
|
for (auto e : res)
|
||||||
{
|
{
|
||||||
@@ -128,8 +102,8 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
|
|||||||
usedByThisBlock.insert(args.begin(), args.end());
|
usedByThisBlock.insert(args.begin(), args.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((instr->getOperation() == SAPFOR::CFG_OP::F_CALL || instr->getOperation() == SAPFOR::CFG_OP::PARAM) && fName == "")
|
if (last_stack_op)
|
||||||
last_fcall_useful = false;
|
last_stack_op_useful = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -140,8 +114,8 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use,
|
|||||||
{
|
{
|
||||||
set<SAPFOR::Argument*> use_with_regs = use, def_with_regs = def;
|
set<SAPFOR::Argument*> use_with_regs = use, def_with_regs = def;
|
||||||
|
|
||||||
vector<SAPFOR::Argument*> lastParamRef;
|
vector<SAPFOR::Argument*> arg_stack;
|
||||||
int last_param_ref_index = 0, last_param_ref_size = 0;
|
int arg_stack_index = 0, arg_stack_size = 0;
|
||||||
string fName = "";
|
string fName = "";
|
||||||
bool last_fcall_useful = false;
|
bool last_fcall_useful = false;
|
||||||
|
|
||||||
@@ -155,7 +129,7 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use,
|
|||||||
updateUseDefForInstruction(block, instructions[i]->getInstruction(),
|
updateUseDefForInstruction(block, instructions[i]->getInstruction(),
|
||||||
use_with_regs, def_with_regs,
|
use_with_regs, def_with_regs,
|
||||||
formal_parameters,
|
formal_parameters,
|
||||||
lastParamRef, last_param_ref_index, last_param_ref_size,
|
arg_stack, arg_stack_index, arg_stack_size,
|
||||||
fName, funcByName,
|
fName, funcByName,
|
||||||
u, last_fcall_useful,
|
u, last_fcall_useful,
|
||||||
usedByThisBlock
|
usedByThisBlock
|
||||||
@@ -179,7 +153,6 @@ private:
|
|||||||
|
|
||||||
vector<SAPFOR::Argument*>& formal_parameters;
|
vector<SAPFOR::Argument*>& formal_parameters;
|
||||||
const map<string, FuncInfo*>& funcByName;
|
const map<string, FuncInfo*>& funcByName;
|
||||||
const set<SAPFOR::Argument*>& shared_regs;
|
|
||||||
public:
|
public:
|
||||||
bool updateJumpStatus()
|
bool updateJumpStatus()
|
||||||
{
|
{
|
||||||
@@ -262,7 +235,9 @@ public:
|
|||||||
updated |= updateNextNotEmpty();
|
updated |= updateNextNotEmpty();
|
||||||
|
|
||||||
updated |= updateJumpStatus();
|
updated |= updateJumpStatus();
|
||||||
updated |= this->forwardData({ });
|
|
||||||
|
if(updated)
|
||||||
|
this->forwardData({ });
|
||||||
|
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
@@ -284,8 +259,7 @@ public:
|
|||||||
|
|
||||||
for (SAPFOR::Argument* arg : use)
|
for (SAPFOR::Argument* arg : use)
|
||||||
{
|
{
|
||||||
if(arg && (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR ||
|
if(arg && (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR || arg->getType() == SAPFOR::CFG_ARG_TYPE::REG))
|
||||||
(arg->getType() == SAPFOR::CFG_ARG_TYPE::REG && shared_regs.find(arg) != shared_regs.end())))
|
|
||||||
{
|
{
|
||||||
bool this_block = usedByThisBlock.find(arg) != usedByThisBlock.end();
|
bool this_block = usedByThisBlock.find(arg) != usedByThisBlock.end();
|
||||||
|
|
||||||
@@ -344,15 +318,14 @@ public:
|
|||||||
|
|
||||||
DeadCodeAnalysisNode(SAPFOR::BasicBlock* block,
|
DeadCodeAnalysisNode(SAPFOR::BasicBlock* block,
|
||||||
vector<SAPFOR::Argument*>& formal_parameters,
|
vector<SAPFOR::Argument*>& formal_parameters,
|
||||||
const map<string, FuncInfo*>& funcByName,
|
const map<string, FuncInfo*>& funcByName)
|
||||||
const set<SAPFOR::Argument*>& shared_regs)
|
|
||||||
:
|
:
|
||||||
formal_parameters(formal_parameters),
|
formal_parameters(formal_parameters),
|
||||||
funcByName(funcByName),
|
funcByName(funcByName)
|
||||||
shared_regs(shared_regs)
|
|
||||||
{
|
{
|
||||||
setBlock(block);
|
setBlock(block);
|
||||||
useful.resize(block->getInstructions().size(), false);
|
useful.resize(block->getInstructions().size(), false);
|
||||||
|
this->forwardData({ });
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<bool>& getResult() { return useful; }
|
const vector<bool>& getResult() { return useful; }
|
||||||
@@ -363,20 +336,17 @@ class DeadCodeAnalysis : public BackwardDataFlowAnalysis<DeadCodeAnalysisNode>
|
|||||||
protected:
|
protected:
|
||||||
vector<SAPFOR::Argument*>& formal_parameters;
|
vector<SAPFOR::Argument*>& formal_parameters;
|
||||||
const map<string, FuncInfo*>& funcByName;
|
const map<string, FuncInfo*>& funcByName;
|
||||||
const set<SAPFOR::Argument*>& shared_regs;
|
|
||||||
|
|
||||||
DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override
|
DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override
|
||||||
{
|
{
|
||||||
return new DeadCodeAnalysisNode(block, formal_parameters, funcByName, shared_regs);
|
return new DeadCodeAnalysisNode(block, formal_parameters, funcByName);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
DeadCodeAnalysis(vector<SAPFOR::Argument*>& formal_parameters,
|
DeadCodeAnalysis(vector<SAPFOR::Argument*>& formal_parameters,
|
||||||
const map<string, FuncInfo*>& funcByName,
|
const map<string, FuncInfo*>& funcByName)
|
||||||
const set<SAPFOR::Argument*>& shared_regs)
|
|
||||||
:
|
:
|
||||||
formal_parameters(formal_parameters),
|
formal_parameters(formal_parameters),
|
||||||
funcByName(funcByName),
|
funcByName(funcByName)
|
||||||
shared_regs(shared_regs)
|
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -411,7 +381,8 @@ void removeDeadCode(SgStatement* func,
|
|||||||
set<SAPFOR::BasicBlock*> reachable;
|
set<SAPFOR::BasicBlock*> reachable;
|
||||||
|
|
||||||
for (auto b : cfg_pair.second)
|
for (auto b : cfg_pair.second)
|
||||||
if(b->getInstructions().front()->isHeader())
|
if(b->getInstructions().front()->isHeader() ||
|
||||||
|
b->getInstructions().front()->getInstruction()->getOperation() == SAPFOR::CFG_OP::ENTRY)
|
||||||
reachable.insert(b);
|
reachable.insert(b);
|
||||||
|
|
||||||
set<SAPFOR::BasicBlock*> worklist = reachable;
|
set<SAPFOR::BasicBlock*> worklist = reachable;
|
||||||
@@ -460,10 +431,7 @@ void removeDeadCode(SgStatement* func,
|
|||||||
for (auto byFunc : byFile.second)
|
for (auto byFunc : byFile.second)
|
||||||
funcByName[byFunc->funcName] = byFunc;
|
funcByName[byFunc->funcName] = byFunc;
|
||||||
|
|
||||||
set<SAPFOR::Argument*> shared_regs;
|
DeadCodeAnalysis analysis_object(func_parameters, funcByName);
|
||||||
fillSharedRegs({ cfg_pair }, shared_regs);
|
|
||||||
|
|
||||||
DeadCodeAnalysis analysis_object(func_parameters, funcByName, shared_regs);
|
|
||||||
|
|
||||||
analysis_object.fit(cfg_pair.second);
|
analysis_object.fit(cfg_pair.second);
|
||||||
analysis_object.analyze();
|
analysis_object.analyze();
|
||||||
@@ -495,7 +463,7 @@ void removeDeadCode(SgStatement* func,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remove dead statements
|
// remove dead statements
|
||||||
set<int> removable =
|
static const set<int> removable =
|
||||||
{
|
{
|
||||||
ASSIGN_STAT,
|
ASSIGN_STAT,
|
||||||
PROC_STAT,
|
PROC_STAT,
|
||||||
@@ -503,12 +471,29 @@ void removeDeadCode(SgStatement* func,
|
|||||||
READ_STAT
|
READ_STAT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const set<int> skip =
|
||||||
|
{
|
||||||
|
PROG_HEDR,
|
||||||
|
PROC_HEDR,
|
||||||
|
FUNC_HEDR
|
||||||
|
};
|
||||||
|
|
||||||
vector<SgStatement*> remove;
|
vector<SgStatement*> remove;
|
||||||
SgStatement* start = intervalDelStart ? intervalDelStart : func;
|
SgStatement* start = intervalDelStart ? intervalDelStart : func;
|
||||||
SgStatement* end = intervalDelEnd ? intervalDelEnd : func->lastNodeOfStmt();
|
SgStatement* end = intervalDelEnd ? intervalDelEnd : func->lastNodeOfStmt();
|
||||||
|
|
||||||
for (auto st = start; st != end; st = st->lexNext())
|
auto st = start;
|
||||||
|
if (skip.find(st->variant()) != skip.end())
|
||||||
|
st = st->lexNext();
|
||||||
|
|
||||||
|
for (; st != end; st = st->lexNext())
|
||||||
{
|
{
|
||||||
|
if (skip.find(st->variant()) != skip.end())
|
||||||
|
{
|
||||||
|
st = st->lastNodeOfStmt();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (removable.find(st->variant()) != removable.end() && useful.find(st) == useful.end())
|
if (removable.find(st->variant()) != removable.end() && useful.find(st) == useful.end())
|
||||||
{
|
{
|
||||||
remove.push_back(st);
|
remove.push_back(st);
|
||||||
@@ -526,9 +511,21 @@ void removeDeadCode(SgStatement* func,
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
remove.clear();
|
remove.clear();
|
||||||
for (auto st = start; st != end; st = st->lexNext())
|
|
||||||
|
st = start;
|
||||||
|
if (skip.find(st->variant()) != skip.end())
|
||||||
|
st = st->lexNext();
|
||||||
|
|
||||||
|
for (; st != end; st = st->lexNext())
|
||||||
{
|
{
|
||||||
const int var = st->variant();
|
const int var = st->variant();
|
||||||
|
|
||||||
|
if (skip.find(var) != skip.end())
|
||||||
|
{
|
||||||
|
st = st->lastNodeOfStmt();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((var == FOR_NODE || var == WHILE_NODE || var == SWITCH_NODE) &&
|
if ((var == FOR_NODE || var == WHILE_NODE || var == SWITCH_NODE) &&
|
||||||
st->lexNext()->variant() == CONTROL_END)
|
st->lexNext()->variant() == CONTROL_END)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user