dead_code_removing improvements #23
@@ -95,7 +95,7 @@ namespace SAPFOR
|
|||||||
}
|
}
|
||||||
|
|
||||||
return inserted;
|
return inserted;
|
||||||
};
|
}
|
||||||
|
|
||||||
bool BasicBlock::removeLive(SAPFOR::Argument* to_remove, bool in)
|
bool BasicBlock::removeLive(SAPFOR::Argument* to_remove, bool in)
|
||||||
{
|
{
|
||||||
@@ -126,7 +126,7 @@ namespace SAPFOR
|
|||||||
}
|
}
|
||||||
|
|
||||||
return removed;
|
return removed;
|
||||||
};
|
}
|
||||||
|
|
||||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> BasicBlock::getLive(bool in) const {
|
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> BasicBlock::getLive(bool in) const {
|
||||||
auto& current_set = in ? live_in : live_out;
|
auto& current_set = in ? live_in : live_out;
|
||||||
@@ -231,22 +231,22 @@ public:
|
|||||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getIn()
|
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getIn()
|
||||||
{
|
{
|
||||||
return getBlock()->getLiveOut();
|
return getBlock()->getLiveOut();
|
||||||
};
|
}
|
||||||
|
|
||||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getOut()
|
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getOut()
|
||||||
{
|
{
|
||||||
return getBlock()->getLiveIn();
|
return getBlock()->getLiveIn();
|
||||||
};
|
}
|
||||||
|
|
||||||
bool addIn(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data)
|
bool addIn(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data)
|
||||||
{
|
{
|
||||||
return getBlock()->addLiveOut(data);
|
return getBlock()->addLiveOut(data);
|
||||||
};
|
}
|
||||||
|
|
||||||
bool addOut(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data)
|
bool addOut(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data)
|
||||||
{
|
{
|
||||||
return getBlock()->addLiveIn(data);
|
return getBlock()->addLiveIn(data);
|
||||||
};
|
}
|
||||||
|
|
||||||
bool forwardData(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data)
|
bool forwardData(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data)
|
||||||
{
|
{
|
||||||
@@ -257,7 +257,7 @@ public:
|
|||||||
inserted |= getBlock()->addLiveIn({ byArg });
|
inserted |= getBlock()->addLiveIn({ byArg });
|
||||||
|
|
||||||
return inserted;
|
return inserted;
|
||||||
};
|
}
|
||||||
|
|
||||||
LiveVarAnalysisNode(SAPFOR::BasicBlock* block, vector<SAPFOR::Argument*>& formal_parameters,
|
LiveVarAnalysisNode(SAPFOR::BasicBlock* block, vector<SAPFOR::Argument*>& formal_parameters,
|
||||||
vector<LiveDeadVarsForCall>& fcalls, const map<string, FuncInfo*>& funcByName)
|
vector<LiveDeadVarsForCall>& fcalls, const map<string, FuncInfo*>& funcByName)
|
||||||
@@ -279,11 +279,11 @@ protected:
|
|||||||
|
|
||||||
LiveVarAnalysisNode* createNode(SAPFOR::BasicBlock* block) override {
|
LiveVarAnalysisNode* createNode(SAPFOR::BasicBlock* block) override {
|
||||||
return new LiveVarAnalysisNode(block, formal_parameters, fcalls, funcByName);
|
return new LiveVarAnalysisNode(block, formal_parameters, fcalls, funcByName);
|
||||||
};
|
}
|
||||||
public:
|
public:
|
||||||
LiveVarAnalysis(vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
LiveVarAnalysis(vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
||||||
const map<string, FuncInfo*>& funcByName) : formal_parameters(formal_parameters), fcalls(fcalls), funcByName(funcByName)
|
const map<string, FuncInfo*>& funcByName) : formal_parameters(formal_parameters), fcalls(fcalls), funcByName(funcByName)
|
||||||
{ };
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ void insertIfVar(IT begin, IT end, DEST& to) {
|
|||||||
for (auto it = begin; it != end; it++)
|
for (auto it = begin; it != end; it++)
|
||||||
if (*it && (*it)->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
if (*it && (*it)->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||||||
to.insert(*it);
|
to.insert(*it);
|
||||||
};
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ using std::string;
|
|||||||
using std::vector;
|
using std::vector;
|
||||||
using std::set;
|
using std::set;
|
||||||
|
|
||||||
|
#define PRINT_USELESS_STATEMENTS 1
|
||||||
|
|
||||||
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,
|
||||||
@@ -190,11 +192,11 @@ public:
|
|||||||
|
|
||||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getIn() {
|
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getIn() {
|
||||||
return getBlock()->getLiveOut();
|
return getBlock()->getLiveOut();
|
||||||
};
|
}
|
||||||
|
|
||||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getOut() {
|
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getOut() {
|
||||||
return getBlock()->getLiveIn();
|
return getBlock()->getLiveIn();
|
||||||
};
|
}
|
||||||
|
|
||||||
bool addIn(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data) {
|
bool addIn(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data) {
|
||||||
bool inserted = getBlock()->addLiveOut(data);
|
bool inserted = getBlock()->addLiveOut(data);
|
||||||
@@ -205,11 +207,11 @@ public:
|
|||||||
inserted |= updateJumpStatus();
|
inserted |= updateJumpStatus();
|
||||||
|
|
||||||
return inserted;
|
return inserted;
|
||||||
};
|
}
|
||||||
|
|
||||||
bool addOut(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data) {
|
bool addOut(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data) {
|
||||||
return getBlock()->addLiveIn(data);
|
return getBlock()->addLiveIn(data);
|
||||||
};
|
}
|
||||||
|
|
||||||
bool forwardData(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data) {
|
bool forwardData(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data) {
|
||||||
bool inserted = false;
|
bool inserted = false;
|
||||||
@@ -279,7 +281,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
return inserted;
|
return inserted;
|
||||||
};
|
}
|
||||||
|
|
||||||
DeadCodeAnalysisNode(SAPFOR::BasicBlock* block, vector<SAPFOR::Argument*>& formal_parameters) :
|
DeadCodeAnalysisNode(SAPFOR::BasicBlock* block, vector<SAPFOR::Argument*>& formal_parameters) :
|
||||||
formal_parameters(formal_parameters)
|
formal_parameters(formal_parameters)
|
||||||
@@ -295,7 +297,7 @@ public:
|
|||||||
getBlock()->addLiveIn({ { arg, { getBlock() } } });
|
getBlock()->addLiveIn({ { arg, { getBlock() } } });
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<bool>& getResult() { return useful; };
|
const vector<bool>& getResult() { return useful; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeadCodeAnalysis : public BackwardDataFlowAnalysis<DeadCodeAnalysisNode> {
|
class DeadCodeAnalysis : public BackwardDataFlowAnalysis<DeadCodeAnalysisNode> {
|
||||||
@@ -304,11 +306,11 @@ protected:
|
|||||||
|
|
||||||
DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override {
|
DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override {
|
||||||
return new DeadCodeAnalysisNode(block, formal_parameters);
|
return new DeadCodeAnalysisNode(block, formal_parameters);
|
||||||
};
|
}
|
||||||
public:
|
public:
|
||||||
DeadCodeAnalysis(vector<SAPFOR::Argument*>& formal_parameters) :
|
DeadCodeAnalysis(vector<SAPFOR::Argument*>& formal_parameters) :
|
||||||
formal_parameters(formal_parameters)
|
formal_parameters(formal_parameters)
|
||||||
{ };
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -318,12 +320,6 @@ void removeDeadCode(SgStatement* func,
|
|||||||
{
|
{
|
||||||
SgProgHedrStmt* prog = isSgProgHedrStmt(func);
|
SgProgHedrStmt* prog = isSgProgHedrStmt(func);
|
||||||
|
|
||||||
if (prog)
|
|
||||||
__spf_print(1, "[analyze %s]\n", prog->name().identifier());
|
|
||||||
else
|
|
||||||
__spf_print(1, "[cannot resolve name of function]\n");
|
|
||||||
|
|
||||||
|
|
||||||
auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, false, false, false, false), commonBlocks, allFuncs);
|
auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, false, false, false, false), commonBlocks, allFuncs);
|
||||||
|
|
||||||
if(cfg.size() != 1)
|
if(cfg.size() != 1)
|
||||||
@@ -333,14 +329,14 @@ 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 = new DeadCodeAnalysis(func_parameters);
|
DeadCodeAnalysis analysis_object(func_parameters);
|
||||||
|
|
||||||
analysis_object->fit(cfg_pair.second);
|
analysis_object.fit(cfg_pair.second);
|
||||||
analysis_object->analyze();
|
analysis_object.analyze();
|
||||||
|
|
||||||
set<SgStatement*> useful;
|
set<SgStatement*> useful;
|
||||||
|
|
||||||
for (DeadCodeAnalysisNode* byNode : analysis_object->getNodes())
|
for (DeadCodeAnalysisNode* byNode : analysis_object.getNodes())
|
||||||
{
|
{
|
||||||
const auto& instructions = byNode->getBlock()->getInstructions();
|
const auto& instructions = byNode->getBlock()->getInstructions();
|
||||||
const auto& statuses = byNode->getResult();
|
const auto& statuses = byNode->getResult();
|
||||||
@@ -357,13 +353,10 @@ void removeDeadCode(SgStatement* func,
|
|||||||
SgStatement* stmt = instructions[i]->getInstruction()->getOperator();
|
SgStatement* stmt = instructions[i]->getInstruction()->getOperator();
|
||||||
|
|
||||||
while(stmt && useful.insert(stmt).second)
|
while(stmt && useful.insert(stmt).second)
|
||||||
{
|
|
||||||
__spf_print(1, "[Useful statement '%s' on line %d]\n", stmt->unparse(), stmt->lineNumber());
|
|
||||||
stmt = stmt->controlParent();
|
stmt = stmt->controlParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
SgStatement* end = func->lastNodeOfStmt(), *st = func;
|
SgStatement* end = func->lastNodeOfStmt(), *st = func;
|
||||||
|
|
||||||
@@ -372,65 +365,50 @@ void removeDeadCode(SgStatement* func,
|
|||||||
ASSIGN_STAT
|
ASSIGN_STAT
|
||||||
};
|
};
|
||||||
|
|
||||||
SgStatement* enclosing = st->controlParent();
|
|
||||||
SgStatement* encl_end = enclosing ? enclosing->lastNodeOfStmt() : NULL;
|
|
||||||
|
|
||||||
while (st != end)
|
while (st != end)
|
||||||
{
|
{
|
||||||
SgStatement* next = st->lexNext();
|
SgStatement* next = st->lexNext();
|
||||||
SgStatement* parent = NULL;
|
|
||||||
|
|
||||||
if (removable.find(st->variant()) != removable.end() && useful.find(st) == useful.end())
|
if (removable.find(st->variant()) != removable.end() && useful.find(st) == useful.end())
|
||||||
{
|
{
|
||||||
__spf_print(1, "[Useless statement '%s' on line %d]\n", st->unparse(), st->lineNumber());
|
__spf_print(PRINT_USELESS_STATEMENTS, "[Useless statement '%s' on line %d]\n", st->unparse(), st->lineNumber());
|
||||||
|
|
||||||
parent = st->controlParent();
|
st->deleteStmt();
|
||||||
|
|
||||||
st->extractStmt()->deleteStmt();
|
|
||||||
st = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (st == encl_end)
|
if (isSgControlEndStmt(st))
|
||||||
{
|
{
|
||||||
if (enclosing)
|
SgStatement* parent = st->controlParent();
|
||||||
|
SgStatement* parent_end;
|
||||||
|
|
||||||
|
if (parent && (parent_end = parent->lastNodeOfStmt()) && parent_end == st)
|
||||||
{
|
{
|
||||||
bool empty_parent = false;
|
bool empty_parent = false;
|
||||||
|
|
||||||
switch (enclosing->variant())
|
switch (parent->variant())
|
||||||
{
|
{
|
||||||
case IF_NODE:
|
case IF_NODE:
|
||||||
empty_parent =
|
empty_parent =
|
||||||
enclosing->lexNext() == encl_end || // IF THEN ENDIF
|
parent->lexNext() == parent_end || // IF THEN ENDIF
|
||||||
enclosing->lexNext()->variant() == CONTROL_END &&
|
isSgControlEndStmt(parent->lexNext()) &&
|
||||||
enclosing->lexNext()->lexNext() == encl_end; // IF THEN ELSE ENDIF
|
parent->lexNext()->lexNext() == parent_end; // IF THEN ELSE ENDIF
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
empty_parent = enclosing->lexNext() == encl_end;
|
empty_parent = parent->lexNext() == parent_end; // DO, WHILE
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(empty_parent)
|
if (empty_parent)
|
||||||
{
|
parent->deleteStmt();
|
||||||
parent = enclosing->controlParent();
|
else if(isSgIfStmt(parent) && isSgControlEndStmt(parent_end->lexPrev())) // IF with empty ELSE branch
|
||||||
enclosing->extractStmt()->deleteStmt();
|
parent_end->deleteStmt();
|
||||||
st->extractStmt()->deleteStmt();
|
|
||||||
st = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!parent)
|
|
||||||
parent = st->controlParent();
|
|
||||||
|
|
||||||
if (parent != enclosing)
|
|
||||||
{
|
|
||||||
enclosing = parent;
|
|
||||||
encl_end = enclosing ? enclosing->lastNodeOfStmt() : NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
st = next;
|
st = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteCFG(cfg);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user