Merge pull request 'dead_code_removing' (#25) from dead_code_removing into master
This commit was merged in pull request #25.
This commit is contained in:
@@ -56,6 +56,22 @@ void BBlock::addInstruction(IR_Block* item)
|
|||||||
item->setBasicBlock(this);
|
item->setBasicBlock(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int BBlock::removePrev(BBlock* removed)
|
||||||
|
{
|
||||||
|
auto it = std::remove(prev.begin(), prev.end(), removed);
|
||||||
|
auto r = prev.end() - it;
|
||||||
|
prev.erase(it, prev.end());
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BBlock::removeNext(BBlock* removed)
|
||||||
|
{
|
||||||
|
auto it = std::remove(next.begin(), next.end(), removed);
|
||||||
|
auto r = next.end() - it;
|
||||||
|
next.erase(it, next.end());
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
BBlock::~BasicBlock()
|
BBlock::~BasicBlock()
|
||||||
{
|
{
|
||||||
for (auto& instr : instructions)
|
for (auto& instr : instructions)
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ namespace SAPFOR
|
|||||||
void addInstruction(IR_Block* item);
|
void addInstruction(IR_Block* item);
|
||||||
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
||||||
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
||||||
|
|
||||||
|
int removePrev(BasicBlock* removed);
|
||||||
|
int removeNext(BasicBlock* removed);
|
||||||
|
|
||||||
void replacePrevNext(const std::map<BasicBlock*, BasicBlock*>& oldToNew)
|
void replacePrevNext(const std::map<BasicBlock*, BasicBlock*>& oldToNew)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -321,38 +321,6 @@ static bool getDependencies(SAPFOR::Argument* var, SAPFOR::Instruction* instr, c
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ifVariableValid(SAPFOR::Argument* var, const set<pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*>>& defs,
|
|
||||||
SAPFOR::Argument* processed_var, const pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*>& def_of_processed_var)
|
|
||||||
{
|
|
||||||
const auto& BB_of_def_of_processed_var = def_of_processed_var.second;
|
|
||||||
|
|
||||||
if (defs.size() == 1)
|
|
||||||
{
|
|
||||||
const auto& def = *defs.begin();
|
|
||||||
if (def.second == BB_of_def_of_processed_var && def.first->getNumber() < def_of_processed_var.first->getNumber())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& RD_In_BB_of_def_of_processed_var = BB_of_def_of_processed_var->getRD_In();
|
|
||||||
auto RD_of_var_from_BB_with_processed_var = RD_In_BB_of_def_of_processed_var.find(var);
|
|
||||||
|
|
||||||
if (RD_of_var_from_BB_with_processed_var != RD_In_BB_of_def_of_processed_var.end()
|
|
||||||
&& RD_of_var_from_BB_with_processed_var->second.size() == defs.size())
|
|
||||||
{
|
|
||||||
for (const auto& def : defs)
|
|
||||||
{
|
|
||||||
int number_of_istruction_with_decl = def.first ? def.first->getNumber() : CFG_VAL::UNINIT;
|
|
||||||
|
|
||||||
if (RD_of_var_from_BB_with_processed_var->second.count(number_of_istruction_with_decl) == 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const set<SAPFOR::Argument*>& func_affects(const FuncInfo* func, const vector<SAPFOR::BasicBlock*>& blocks)
|
static const set<SAPFOR::Argument*>& func_affects(const FuncInfo* func, const vector<SAPFOR::BasicBlock*>& blocks)
|
||||||
{
|
{
|
||||||
static map<const FuncInfo*, set<SAPFOR::Argument*>> affects;
|
static map<const FuncInfo*, set<SAPFOR::Argument*>> affects;
|
||||||
@@ -1150,7 +1118,7 @@ vector<SAPFOR::BasicBlock*> sortCfgNodes(const vector<SAPFOR::BasicBlock*>& bloc
|
|||||||
if (!nodes_added && processing_stack.size() != 0) {
|
if (!nodes_added && processing_stack.size() != 0) {
|
||||||
//there is some blocks in the stack but no one can be processed
|
//there is some blocks in the stack but no one can be processed
|
||||||
//this code should be unreachable
|
//this code should be unreachable
|
||||||
#ifdef DEBUG_CHECKS
|
#if DEBUG_CHECKS
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
#endif // DEBUG_CHECKS
|
#endif // DEBUG_CHECKS
|
||||||
auto block = processing_stack.back();
|
auto block = processing_stack.back();
|
||||||
@@ -1167,7 +1135,7 @@ vector<SAPFOR::BasicBlock*> sortCfgNodes(const vector<SAPFOR::BasicBlock*>& bloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CHECKS
|
#if DEBUG_CHECKS
|
||||||
set<SAPFOR::BasicBlock*> verify_unique;
|
set<SAPFOR::BasicBlock*> verify_unique;
|
||||||
verify_unique.insert(result.begin(), result.end());
|
verify_unique.insert(result.begin(), result.end());
|
||||||
|
|
||||||
@@ -1176,7 +1144,7 @@ vector<SAPFOR::BasicBlock*> sortCfgNodes(const vector<SAPFOR::BasicBlock*>& bloc
|
|||||||
verify_unique.clear();
|
verify_unique.clear();
|
||||||
#endif // DEBUG_CHECKS
|
#endif // DEBUG_CHECKS
|
||||||
|
|
||||||
#ifdef DEBUG_CHECKS
|
#if DEBUG_CHECKS
|
||||||
set<SAPFOR::BasicBlock*> all_blocks, res_blocks;
|
set<SAPFOR::BasicBlock*> all_blocks, res_blocks;
|
||||||
|
|
||||||
all_blocks.insert(blocks.begin(), blocks.end());
|
all_blocks.insert(blocks.begin(), blocks.end());
|
||||||
@@ -1267,7 +1235,7 @@ bool isArgReaches(int decl_instr, SAPFOR::BasicBlock* decl_bb,
|
|||||||
if (RDs_for_arg.size() == 1)
|
if (RDs_for_arg.size() == 1)
|
||||||
{
|
{
|
||||||
const int rd = *RDs_for_arg.begin();
|
const int rd = *RDs_for_arg.begin();
|
||||||
if (rd >= decl_bb->getInstructions().front()->getNumber() && rd <= decl_instr)
|
if (rd >= decl_bb->getInstructions().front()->getNumber() && rd < decl_instr)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1275,7 +1243,67 @@ bool isArgReaches(int decl_instr, SAPFOR::BasicBlock* decl_bb,
|
|||||||
if (arg_in_from_decl_it == decl_bb->getRD_In().end())
|
if (arg_in_from_decl_it == decl_bb->getRD_In().end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return arg_in_from_decl_it->second == RDs_for_arg;
|
if(arg_in_from_decl_it->second != RDs_for_arg)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
set<SAPFOR::BasicBlock*> reachable = { decl_bb };
|
||||||
|
set<int> banned_instructions;
|
||||||
|
for (int instr_def : arg_in_from_decl_it->second)
|
||||||
|
if (instr_def >= decl_instr || instr_def < decl_bb->getInstructions().front()->getNumber())
|
||||||
|
//try to find way [decl_bb] -> [dest_bb] with redefining of var (that means that var value from decl_bb could be overwrited)
|
||||||
|
banned_instructions.insert(instr_def);
|
||||||
|
|
||||||
|
set<SAPFOR::BasicBlock*> worklist = reachable, banned_blocks;
|
||||||
|
bool way_found = false;
|
||||||
|
while (worklist.size() != 0 && banned_instructions.size() != 0)
|
||||||
|
{
|
||||||
|
for (SAPFOR::BasicBlock* wl : worklist)
|
||||||
|
{
|
||||||
|
int start = wl->getInstructions().front()->getNumber(), end = wl->getInstructions().back()->getNumber();
|
||||||
|
|
||||||
|
for (auto banned_it = banned_instructions.begin(); banned_it != banned_instructions.end();)
|
||||||
|
{
|
||||||
|
if(start <= *banned_it && *banned_it <= end)
|
||||||
|
{
|
||||||
|
banned_it = banned_instructions.erase(banned_it);
|
||||||
|
banned_blocks.insert(wl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
banned_it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set<SAPFOR::BasicBlock*> to_insert;
|
||||||
|
|
||||||
|
for (auto b : worklist)
|
||||||
|
for (auto next : b->getNext())
|
||||||
|
if (reachable.insert(next).second)
|
||||||
|
to_insert.insert(next);
|
||||||
|
|
||||||
|
worklist = to_insert;
|
||||||
|
}
|
||||||
|
|
||||||
|
reachable = banned_blocks;
|
||||||
|
worklist = reachable;
|
||||||
|
while (worklist.size() != 0 || banned_instructions.size() == 0)
|
||||||
|
{
|
||||||
|
if(worklist.find(dest_bb) != worklist.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
set<SAPFOR::BasicBlock*> to_insert;
|
||||||
|
|
||||||
|
for (auto b : worklist)
|
||||||
|
for (auto next : b->getNext())
|
||||||
|
if(next != decl_bb)
|
||||||
|
if (reachable.insert(next).second)
|
||||||
|
to_insert.insert(next);
|
||||||
|
|
||||||
|
worklist = to_insert;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return arg's definition if it really reaches dest_bb
|
// return arg's definition if it really reaches dest_bb
|
||||||
@@ -1597,28 +1625,7 @@ void buildSubstitutions(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGra
|
|||||||
|
|
||||||
for (SAPFOR::Argument* dep : dependencies_of_var->second)
|
for (SAPFOR::Argument* dep : dependencies_of_var->second)
|
||||||
{
|
{
|
||||||
if (dep->getType() != CFG_ARG_TYPE::VAR)
|
if (!isArgReaches(instr_num, instr_and_bb.second, dep, cur_BB))
|
||||||
{
|
|
||||||
can_use = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& RD_In_of_curr_BB = cur_BB->getRD_In();
|
|
||||||
auto dep_from_curr_RD_In = RD_In_of_curr_BB.find(dep);
|
|
||||||
|
|
||||||
if (dep_from_curr_RD_In == RD_In_of_curr_BB.end())
|
|
||||||
{
|
|
||||||
can_use = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& RDs_for_dep = dep_from_curr_RD_In->second;
|
|
||||||
|
|
||||||
set<pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*>> defs_of_dep;
|
|
||||||
for (int def_instruction_num : RDs_for_dep)
|
|
||||||
defs_of_dep.insert(getInstructionAndBlockByNumber(CFGraph_for_project, def_instruction_num));
|
|
||||||
|
|
||||||
if (!ifVariableValid(dep, defs_of_dep, in_val.first, instr_and_bb))
|
|
||||||
{
|
{
|
||||||
can_use = false;
|
can_use = false;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
|
|||||||
@@ -4,35 +4,34 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using std::map;
|
using std::map;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::set;
|
using std::set;
|
||||||
|
|
||||||
|
using std::remove_if;
|
||||||
|
|
||||||
#define PRINT_USELESS_STATEMENTS 0
|
#define PRINT_USELESS_STATEMENTS 0
|
||||||
|
|
||||||
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*>& 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
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -59,15 +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::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)
|
||||||
@@ -89,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;
|
||||||
|
|
||||||
@@ -115,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
|
||||||
);
|
);
|
||||||
@@ -136,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()
|
||||||
{
|
{
|
||||||
@@ -223,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();
|
||||||
|
|
||||||
@@ -283,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() } } });
|
||||||
@@ -303,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)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -325,15 +338,67 @@ void removeDeadCode(SgStatement* func,
|
|||||||
if(cfg.size() != 1)
|
if(cfg.size() != 1)
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
const auto& cfg_pair = *(cfg.begin());
|
auto& cfg_pair = *(cfg.begin());
|
||||||
|
|
||||||
|
// delete unreachable blocks
|
||||||
|
|
||||||
|
set<SAPFOR::BasicBlock*> reachable;
|
||||||
|
|
||||||
|
for (auto b : cfg_pair.second)
|
||||||
|
if(b->getInstructions().front()->isHeader())
|
||||||
|
reachable.insert(b);
|
||||||
|
|
||||||
|
set<SAPFOR::BasicBlock*> worklist = reachable;
|
||||||
|
while (worklist.size() != 0)
|
||||||
|
{
|
||||||
|
set<SAPFOR::BasicBlock*> to_insert;
|
||||||
|
|
||||||
|
for(auto b : worklist)
|
||||||
|
for(auto next: b->getNext())
|
||||||
|
if(reachable.insert(next).second)
|
||||||
|
to_insert.insert(next);
|
||||||
|
|
||||||
|
worklist = to_insert;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto remove_unreachable_it = remove_if(cfg_pair.second.begin(), cfg_pair.second.end(),
|
||||||
|
[&reachable](SAPFOR::BasicBlock* b)
|
||||||
|
{
|
||||||
|
if (reachable.find(b) == reachable.end())
|
||||||
|
{
|
||||||
|
for(auto next: b->getNext())
|
||||||
|
if(reachable.find(next) != reachable.end())
|
||||||
|
next->removePrev(b);
|
||||||
|
|
||||||
|
delete b;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
reachable.clear();
|
||||||
|
|
||||||
|
cfg_pair.second.erase(remove_unreachable_it, cfg_pair.second.end());
|
||||||
|
|
||||||
|
// detect useless code
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
|
// detect dead statements
|
||||||
|
|
||||||
set<SgStatement*> useful;
|
set<SgStatement*> useful;
|
||||||
|
|
||||||
for (DeadCodeAnalysisNode* byNode : analysis_object.getNodes())
|
for (DeadCodeAnalysisNode* byNode : analysis_object.getNodes())
|
||||||
@@ -358,11 +423,16 @@ void removeDeadCode(SgStatement* func,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove dead statements
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user