dead code: handle STORE and LOAD instructions

This commit is contained in:
2024-04-10 22:03:27 +03:00
parent aace0bf06f
commit a827c40543
3 changed files with 101 additions and 75 deletions

View File

@@ -294,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())
{ {
@@ -341,50 +348,60 @@ 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) {
auto func_it = funcByName.find(fName); if(instr_operation == SAPFOR::CFG_OP::PARAM || instr_operation == SAPFOR::CFG_OP::F_CALL)
if (interprocedural && func_it != funcByName.end())
{ {
fcalls.push_back(LiveDeadVarsForCall(func_it->second, block, lastParamRef)); auto func_it = funcByName.find(fName);
if (interprocedural && func_it != funcByName.end())
auto r_it = fcalls.rbegin();
auto r_end = fcalls.rend();
for (auto e : def)
r_it->make_dead(e);
for (auto e : use)
r_it->make_live(e, block);
}
set<SAPFOR::Argument*> make_live, make_dead;
if (fName == "_READ")
def.insert(lastParamRef.begin(), lastParamRef.end());
else if (interprocedural && getLiveDead(lastParamRef, fName, make_live, make_dead))
{
use.insert(make_live.begin(), make_live.end());
def.insert(make_dead.begin(), make_dead.end());
}
else if (func_it != funcByName.end())
{
int arg_num = lastParamRef.size();
for (int i = 0; i < arg_num; i++)
{ {
if(func_it->second->funcParams.isArgOut(i)) fcalls.push_back(LiveDeadVarsForCall(func_it->second, block, arg_stack));
def.insert(lastParamRef[i]);
if (func_it->second->funcParams.isArgIn(i)) auto r_it = fcalls.rbegin();
use.insert(lastParamRef[i]); auto r_end = fcalls.rend();
for (auto e : def)
r_it->make_dead(e);
for (auto e : use)
r_it->make_live(e, block);
} }
set<SAPFOR::Argument*> make_live, make_dead;
if (fName == "_READ")
def.insert(arg_stack.begin(), arg_stack.end());
else if (interprocedural && getLiveDead(arg_stack, fName, make_live, make_dead))
{
use.insert(make_live.begin(), make_live.end());
def.insert(make_dead.begin(), make_dead.end());
}
else if (func_it != funcByName.end())
{
int arg_num = arg_stack.size();
for (int i = 0; i < arg_num; i++)
{
if(func_it->second->funcParams.isArgOut(i))
def.insert(arg_stack[i]);
if (func_it->second->funcParams.isArgIn(i))
use.insert(arg_stack[i]);
}
}
else
use.insert(arg_stack.begin(), arg_stack.end());
fName = "";
} }
else else
use.insert(lastParamRef.begin(), lastParamRef.end()); {
use.insert(arg_stack.begin(), arg_stack.end());
}
last_param_ref_index = 0; arg_stack_index = 0;
last_param_ref_size = 0; arg_stack_size = 0;
lastParamRef.clear(); arg_stack.clear();
fName = "";
last_stack_op = true;
} }
if (res_arg) if (res_arg)
@@ -394,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
); );
@@ -431,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();
@@ -443,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
); );

View File

@@ -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);

View File

@@ -19,23 +19,27 @@ using std::remove_if;
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)
@@ -64,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)
{ {
@@ -95,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;
} }
@@ -107,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;
@@ -122,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