dead code removing: handle dead call statements

This commit is contained in:
Михаил Кочармин
2024-02-02 15:52:36 +03:00
parent 0a423234d2
commit 42fe628ce0
2 changed files with 55 additions and 26 deletions

View File

@@ -338,7 +338,7 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins
if ((instr_operation == SAPFOR::CFG_OP::F_CALL || instr_operation == SAPFOR::CFG_OP::PARAM) && last_param_ref_index < 0) { if ((instr_operation == SAPFOR::CFG_OP::F_CALL || instr_operation == SAPFOR::CFG_OP::PARAM) && last_param_ref_index < 0) {
auto func_it = funcByName.find(fName); auto func_it = funcByName.find(fName);
if (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, lastParamRef));
@@ -360,6 +360,18 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins
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())
{
int arg_num = lastParamRef.size();
for (int i = 0; i < arg_num; i++)
{
if(func_it->second->funcParams.isArgOut(i))
def.insert(lastParamRef[i]);
if (func_it->second->funcParams.isArgIn(i))
use.insert(lastParamRef[i]);
}
}
else else
use.insert(lastParamRef.begin(), lastParamRef.end()); use.insert(lastParamRef.begin(), lastParamRef.end());

View File

@@ -19,23 +19,19 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
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*>& lastParamRef, int& last_param_ref_index, int& last_param_ref_size,
string& fName, string& fName, const map<string, FuncInfo*>& funcByName,
bool& useful, bool& last_fcall_useful, bool& useful, bool& last_fcall_useful,
set<SAPFOR::Argument*>& usedByThisBlock) set<SAPFOR::Argument*>& usedByThisBlock)
{ {
set<SAPFOR::Argument*> res, args; set<SAPFOR::Argument*> res, args;
if (fName == "")
last_fcall_useful = false;
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, lastParamRef, last_param_ref_index, last_param_ref_size,
fName, {}, fName, funcByName,
false false
); );
@@ -62,17 +58,18 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
SAPFOR::CFG_OP::ENTRY, SAPFOR::CFG_OP::ENTRY,
SAPFOR::CFG_OP::EXIT, SAPFOR::CFG_OP::EXIT,
SAPFOR::CFG_OP::DVM_DIR, SAPFOR::CFG_OP::DVM_DIR,
SAPFOR::CFG_OP::SPF_DIR, SAPFOR::CFG_OP::SPF_DIR
SAPFOR::CFG_OP::JUMP,
SAPFOR::CFG_OP::JUMP_IF,
SAPFOR::CFG_OP::F_CALL //TODO: handle pure functions
}; };
if (always_useful.find(instr->getOperation()) != always_useful.end()) if (always_useful.find(instr->getOperation()) != always_useful.end())
useful = true; useful = true;
else if(instr->getOperation() == SAPFOR::CFG_OP::PARAM && last_fcall_useful) else if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
useful = true; {
auto func_it = funcByName.find(instr->getArg1()->getValue());
useful |= func_it == funcByName.end() || !(func_it->second->isPure);
}
else if (instr->getOperation() == SAPFOR::CFG_OP::PARAM)
useful |= last_fcall_useful;
} }
if (useful) if (useful)
@@ -94,13 +91,16 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
insertIfVar(args.begin(), args.end(), usedByThisBlock); insertIfVar(args.begin(), args.end(), usedByThisBlock);
} }
if ((instr->getOperation() == SAPFOR::CFG_OP::F_CALL || instr->getOperation() == SAPFOR::CFG_OP::PARAM) && fName == "")
last_fcall_useful = false;
} }
//Build use and def sets of block. Result are stored in use and def //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, static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
vector<SAPFOR::Argument*>& formal_parameters, vector<bool>& useful, vector<SAPFOR::Argument*>& formal_parameters, vector<bool>& useful,
set<SAPFOR::Argument*>& usedByThisBlock) set<SAPFOR::Argument*>& usedByThisBlock, const map<string, FuncInfo*>& funcByName)
{ {
set<SAPFOR::Argument*> use_with_regs = use, def_with_regs = def; set<SAPFOR::Argument*> use_with_regs = use, def_with_regs = def;
@@ -120,7 +120,7 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use,
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, lastParamRef, last_param_ref_index, last_param_ref_size,
fName, fName, funcByName,
u, last_fcall_useful, u, last_fcall_useful,
usedByThisBlock usedByThisBlock
); );
@@ -141,6 +141,7 @@ private:
bool useful_jump = false; bool useful_jump = false;
vector<SAPFOR::Argument*>& formal_parameters; vector<SAPFOR::Argument*>& formal_parameters;
const map<string, FuncInfo*>& funcByName;
public: public:
bool updateJumpStatus() bool updateJumpStatus()
{ {
@@ -228,7 +229,7 @@ public:
use.insert(byArg.first); use.insert(byArg.first);
set<SAPFOR::Argument*> usedByThisBlock; set<SAPFOR::Argument*> usedByThisBlock;
buildUseDef(bb, use, def, this->formal_parameters, useful, usedByThisBlock); buildUseDef(bb, use, def, this->formal_parameters, useful, usedByThisBlock, funcByName);
auto in = bb->getLiveIn(), out = bb->getLiveOut(); auto in = bb->getLiveIn(), out = bb->getLiveOut();
@@ -288,15 +289,19 @@ public:
return inserted; return inserted;
} }
DeadCodeAnalysisNode(SAPFOR::BasicBlock* block, vector<SAPFOR::Argument*>& formal_parameters) : DeadCodeAnalysisNode(SAPFOR::BasicBlock* block,
formal_parameters(formal_parameters) vector<SAPFOR::Argument*>& formal_parameters,
const map<string, FuncInfo*>& funcByName)
:
formal_parameters(formal_parameters),
funcByName(funcByName)
{ {
setBlock(block); setBlock(block);
useful.resize(block->getInstructions().size(), false); useful.resize(block->getInstructions().size(), false);
set<SAPFOR::Argument*> use, def; set<SAPFOR::Argument*> use, def;
set<SAPFOR::Argument*> usedByThisBlock; set<SAPFOR::Argument*> usedByThisBlock;
buildUseDef(getBlock(), use, def, this->formal_parameters, useful, usedByThisBlock); buildUseDef(getBlock(), use, def, this->formal_parameters, useful, usedByThisBlock, funcByName);
for (SAPFOR::Argument* arg : use) for (SAPFOR::Argument* arg : use)
getBlock()->addLiveIn({ { arg, { getBlock() } } }); getBlock()->addLiveIn({ { arg, { getBlock() } } });
@@ -308,13 +313,16 @@ public:
class DeadCodeAnalysis : public BackwardDataFlowAnalysis<DeadCodeAnalysisNode> { class DeadCodeAnalysis : public BackwardDataFlowAnalysis<DeadCodeAnalysisNode> {
protected: protected:
vector<SAPFOR::Argument*>& formal_parameters; vector<SAPFOR::Argument*>& formal_parameters;
const map<string, FuncInfo*>& funcByName;
DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override { DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override {
return new DeadCodeAnalysisNode(block, formal_parameters); 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)
formal_parameters(formal_parameters) :
formal_parameters(formal_parameters),
funcByName(funcByName)
{ } { }
}; };
@@ -378,7 +386,13 @@ void removeDeadCode(SgStatement* func,
vector<SAPFOR::Argument*> func_parameters(cfg_pair.first->funcParams.countOfPars, NULL); vector<SAPFOR::Argument*> func_parameters(cfg_pair.first->funcParams.countOfPars, NULL);
DeadCodeAnalysis analysis_object(func_parameters); map<string, FuncInfo*> funcByName;
for (auto& byFile : allFuncs)
for (auto byFunc : byFile.second)
funcByName[byFunc->funcName] = byFunc;
DeadCodeAnalysis analysis_object(func_parameters, funcByName);
analysis_object.fit(cfg_pair.second); analysis_object.fit(cfg_pair.second);
analysis_object.analyze(); analysis_object.analyze();
@@ -413,9 +427,12 @@ void removeDeadCode(SgStatement* func,
SgStatement* end = func->lastNodeOfStmt(), *st = func; SgStatement* end = func->lastNodeOfStmt(), *st = func;
set<int> removable = set<int> removable =
{ {
ASSIGN_STAT ASSIGN_STAT,
PROC_STAT,
WRITE_STAT,
READ_STAT
}; };
while (st != end) while (st != end)