From 3b4af6672067c16425e21a49ba1660798605b3c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=9A=D0=BE=D1=87?= =?UTF-8?q?=D0=B0=D1=80=D0=BC=D0=B8=D0=BD?= Date: Tue, 30 Jan 2024 19:40:14 +0300 Subject: [PATCH] dead code removing: unreachable code --- .../Sapfor_2017/_src/CFGraph/CFGraph.cpp | 16 ++++++ .../Sapfor_2017/_src/CFGraph/CFGraph.h | 3 ++ .../_src/Transformations/dead_code.cpp | 53 ++++++++++++++++++- 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.cpp b/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.cpp index d98dc14..b00a2b1 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.cpp +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.cpp @@ -56,6 +56,22 @@ void BBlock::addInstruction(IR_Block* item) 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() { for (auto& instr : instructions) diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.h index e47447c..319b420 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.h +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.h @@ -42,6 +42,9 @@ namespace SAPFOR void addInstruction(IR_Block* item); void addPrev(BasicBlock* prev_) { prev.push_back(prev_); } void addNext(BasicBlock* next_) { next.push_back(next_); } + + int removePrev(BasicBlock* removed); + int removeNext(BasicBlock* removed); void replacePrevNext(const std::map& oldToNew) { diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp index 0590d4e..4df0ca5 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp @@ -4,12 +4,15 @@ #include #include #include +#include using std::map; using std::string; using std::vector; using std::set; +using std::remove_if; + #define PRINT_USELESS_STATEMENTS 0 static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr, @@ -325,7 +328,51 @@ void removeDeadCode(SgStatement* func, if(cfg.size() != 1) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - const auto& cfg_pair = *(cfg.begin()); + auto& cfg_pair = *(cfg.begin()); + + // delete unreachable blocks + + set reachable; + + for (auto b : cfg_pair.second) + if(b->getInstructions().front()->isHeader()) + reachable.insert(b); + + set worklist = reachable; + while (worklist.size() != 0) + { + set 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 func_parameters(cfg_pair.first->funcParams.countOfPars, NULL); @@ -334,6 +381,8 @@ void removeDeadCode(SgStatement* func, analysis_object.fit(cfg_pair.second); analysis_object.analyze(); + // detect dead statements + set useful; for (DeadCodeAnalysisNode* byNode : analysis_object.getNodes()) @@ -358,6 +407,8 @@ void removeDeadCode(SgStatement* func, } } + // remove dead statements + SgStatement* end = func->lastNodeOfStmt(), *st = func; set removable =