dead_code_removing #36
@@ -14,6 +14,40 @@ using std::set;
|
||||
using std::remove_if;
|
||||
|
||||
#define PRINT_USELESS_STATEMENTS 1
|
||||
#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,
|
||||
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
||||
@@ -91,7 +125,7 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
|
||||
def.erase(e);
|
||||
}
|
||||
|
||||
insertIfVar(args.begin(), args.end(), usedByThisBlock);
|
||||
usedByThisBlock.insert(args.begin(), args.end());
|
||||
}
|
||||
|
||||
if ((instr->getOperation() == SAPFOR::CFG_OP::F_CALL || instr->getOperation() == SAPFOR::CFG_OP::PARAM) && fName == "")
|
||||
@@ -130,8 +164,8 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use,
|
||||
useful[i] = u;
|
||||
}
|
||||
|
||||
insertIfVar(use_with_regs.begin(), use_with_regs.end(), use);
|
||||
insertIfVar(def_with_regs.begin(), def_with_regs.end(), def);
|
||||
use.insert(use_with_regs.begin(), use_with_regs.end());
|
||||
def.insert(def_with_regs.begin(), def_with_regs.end());
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +179,7 @@ private:
|
||||
|
||||
vector<SAPFOR::Argument*>& formal_parameters;
|
||||
const map<string, FuncInfo*>& funcByName;
|
||||
const set<SAPFOR::Argument*>& shared_regs;
|
||||
public:
|
||||
bool updateJumpStatus()
|
||||
{
|
||||
@@ -249,30 +284,34 @@ public:
|
||||
|
||||
for (SAPFOR::Argument* arg : use)
|
||||
{
|
||||
bool this_block = usedByThisBlock.find(arg) != usedByThisBlock.end();
|
||||
|
||||
if (!this_block)
|
||||
if(arg && (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR ||
|
||||
(arg->getType() == SAPFOR::CFG_ARG_TYPE::REG && shared_regs.find(arg) != shared_regs.end())))
|
||||
{
|
||||
auto data_it = data.find(arg);
|
||||
bool this_block = usedByThisBlock.find(arg) != usedByThisBlock.end();
|
||||
|
||||
if (data_it == data.end())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
inserted |= bb->addLiveIn({ *data_it });
|
||||
}
|
||||
else
|
||||
{
|
||||
auto in_it = in.find(arg);
|
||||
bool skip = false;
|
||||
if (in_it != in.end())
|
||||
if (!this_block)
|
||||
{
|
||||
if (in_it->second.size() == 1 && *(in_it->second.begin()) == bb)
|
||||
skip = true; // nothing to do, inserted = false
|
||||
else
|
||||
bb->removeLiveIn(arg);
|
||||
auto data_it = data.find(arg);
|
||||
|
||||
if (data_it == data.end())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
inserted |= bb->addLiveIn({ *data_it });
|
||||
}
|
||||
else
|
||||
{
|
||||
auto in_it = in.find(arg);
|
||||
bool skip = false;
|
||||
if (in_it != in.end())
|
||||
{
|
||||
if (in_it->second.size() == 1 && *(in_it->second.begin()) == bb)
|
||||
skip = true; // nothing to do, inserted = false
|
||||
else
|
||||
bb->removeLiveIn(arg);
|
||||
}
|
||||
if(!skip)
|
||||
inserted |= bb->addLiveIn({ { arg, { bb } } });
|
||||
}
|
||||
if(!skip)
|
||||
inserted |= bb->addLiveIn({ { arg, { bb } } });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,10 +344,12 @@ public:
|
||||
|
||||
DeadCodeAnalysisNode(SAPFOR::BasicBlock* block,
|
||||
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),
|
||||
funcByName(funcByName)
|
||||
funcByName(funcByName),
|
||||
shared_regs(shared_regs)
|
||||
{
|
||||
setBlock(block);
|
||||
useful.resize(block->getInstructions().size(), false);
|
||||
@@ -322,16 +363,20 @@ class DeadCodeAnalysis : public BackwardDataFlowAnalysis<DeadCodeAnalysisNode>
|
||||
protected:
|
||||
vector<SAPFOR::Argument*>& formal_parameters;
|
||||
const map<string, FuncInfo*>& funcByName;
|
||||
const set<SAPFOR::Argument*>& shared_regs;
|
||||
|
||||
DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override
|
||||
{
|
||||
return new DeadCodeAnalysisNode(block, formal_parameters, funcByName);
|
||||
return new DeadCodeAnalysisNode(block, formal_parameters, funcByName, shared_regs);
|
||||
}
|
||||
public:
|
||||
DeadCodeAnalysis(vector<SAPFOR::Argument*>& formal_parameters, const map<string, FuncInfo*>& funcByName)
|
||||
DeadCodeAnalysis(vector<SAPFOR::Argument*>& formal_parameters,
|
||||
const map<string, FuncInfo*>& funcByName,
|
||||
const set<SAPFOR::Argument*>& shared_regs)
|
||||
:
|
||||
formal_parameters(formal_parameters),
|
||||
funcByName(funcByName)
|
||||
funcByName(funcByName),
|
||||
shared_regs(shared_regs)
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -403,8 +448,10 @@ void removeDeadCode(SgStatement* func,
|
||||
|
||||
cfg_pair.second.erase(remove_unreachable_it, cfg_pair.second.end());
|
||||
|
||||
#if DEBUG_IR
|
||||
dumpCFG({ cfg_pair }, false);
|
||||
#endif
|
||||
// detect useless code
|
||||
|
||||
vector<SAPFOR::Argument*> func_parameters(cfg_pair.first->funcParams.countOfPars, NULL);
|
||||
|
||||
map<string, FuncInfo*> funcByName;
|
||||
@@ -412,8 +459,11 @@ void removeDeadCode(SgStatement* func,
|
||||
for (auto& byFile : allFuncs)
|
||||
for (auto byFunc : byFile.second)
|
||||
funcByName[byFunc->funcName] = byFunc;
|
||||
|
||||
set<SAPFOR::Argument*> shared_regs;
|
||||
fillSharedRegs({ cfg_pair }, shared_regs);
|
||||
|
||||
DeadCodeAnalysis analysis_object(func_parameters, funcByName);
|
||||
DeadCodeAnalysis analysis_object(func_parameters, funcByName, shared_regs);
|
||||
|
||||
analysis_object.fit(cfg_pair.second);
|
||||
analysis_object.analyze();
|
||||
|
||||
Reference in New Issue
Block a user