From 1ac7fcca2affd230d1c4ca9d7d1d91b39edbd8be Mon Sep 17 00:00:00 2001 From: Mikhail Kocharmin Date: Wed, 3 Apr 2024 21:13:56 +0300 Subject: [PATCH 1/4] fixes for dead code removing pass --- .../_src/CFGraph/DataFlow/data_flow.h | 1 + .../_src/CFGraph/DataFlow/data_flow_impl.h | 6 ++-- .../_src/Transformations/dead_code.cpp | 33 +++++++++++-------- .../Sapfor_2017/_src/Utils/PassManager.h | 4 +-- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow.h index 8067bd7..561d1b3 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow.h +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow.h @@ -29,6 +29,7 @@ public: virtual bool addIn(const DataType& data) = 0; virtual bool addOut(const DataType& data) = 0; + virtual bool updateState() { return false; } virtual bool forwardData(const DataType& data) = 0; bool newerThan(const DataFlowAnalysisNode* block) const { return out_cnt > block->in_cnt; } diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow_impl.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow_impl.h index 5e74e29..f45b2d7 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow_impl.h +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow_impl.h @@ -27,6 +27,8 @@ template void DataFlowAnalysisNode::doStep() { int in_max_cnt = CNT_NOTINIT, out_max_cnt = CNT_NOTINIT; + + bool uniq_change = updateState(); for (auto next : prev_blocks) { if (in_cnt < next->out_cnt) @@ -49,7 +51,7 @@ void DataFlowAnalysisNode::doStep() } } - bool was_notinit = (out_cnt == CNT_NOTINIT); + uniq_change |= (out_cnt == CNT_NOTINIT); if (out_max_cnt != CNT_NOTINIT) out_cnt = out_max_cnt; @@ -58,7 +60,7 @@ void DataFlowAnalysisNode::doStep() in_cnt = in_max_cnt; // TODO: fix counter overflow - if (was_notinit) + if (uniq_change) { out_cnt++; in_cnt++; diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp index f7493d2..089ca88 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp @@ -39,7 +39,9 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru { for (SAPFOR::Argument* r : res) { - if (use.find(r) != use.end() || r->getMemType() != SAPFOR::CFG_MEM_TYPE::LOCAL_) + if (use.find(r) != use.end() || + r->getMemType() != SAPFOR::CFG_MEM_TYPE::LOCAL_ || + r->getType() != SAPFOR::CFG_ARG_TYPE::VAR) { useful = true; break; @@ -88,7 +90,7 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru use.insert(e); def.erase(e); } - + insertIfVar(args.begin(), args.end(), usedByThisBlock); } @@ -207,11 +209,6 @@ public: bool addIn(const map>& data) { bool inserted = getBlock()->addLiveOut(data); - if (!useful_block) - inserted |= updateNextNotEmpty(); - - inserted |= updateJumpStatus(); - return inserted; } @@ -219,6 +216,21 @@ public: return getBlock()->addLiveIn(data); } + bool updateState() { + if(getBlock()->getInstructions()[0]->getInstruction()->getOperator()->lineNumber() == 58) + int b = 51; + + bool updated = false; + + if (!useful_block) + updated |= updateNextNotEmpty(); + + updated |= updateJumpStatus(); + updated |= this->forwardData({ }); + + return updated; + } + bool forwardData(const map>& data) { bool inserted = false; SAPFOR::BasicBlock* bb= getBlock(); @@ -298,13 +310,6 @@ public: { setBlock(block); useful.resize(block->getInstructions().size(), false); - set use, def; - set usedByThisBlock; - - buildUseDef(getBlock(), use, def, this->formal_parameters, useful, usedByThisBlock, funcByName); - - for (SAPFOR::Argument* arg : use) - getBlock()->addLiveIn({ { arg, { getBlock() } } }); } const vector& getResult() { return useful; } diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/PassManager.h b/sapfor/experts/Sapfor_2017/_src/Utils/PassManager.h index 0e07092..0f2e0fe 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/PassManager.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/PassManager.h @@ -307,8 +307,8 @@ void InitPassesDependencies(map> &passDepsIn, set Pass(REMOVE_OMP_DIRS) <= Pass(REMOVE_OMP_DIRS_TRANSFORM); - Pass(CALL_GRAPH2) <= Pass(REMOVE_DEAD_CODE); - list({ REMOVE_DEAD_CODE, REVERT_SUBST_EXPR_RD, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE); + list({ CALL_GRAPH2, REVERT_SUBST_EXPR_RD }) <= Pass(REMOVE_DEAD_CODE); + list({ REMOVE_DEAD_CODE, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE); passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS, EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW, From e2ac45f48db8a6b8c3a9b26c96151dcc545b9e60 Mon Sep 17 00:00:00 2001 From: Mikhail Kocharmin Date: Thu, 4 Apr 2024 20:15:56 +0300 Subject: [PATCH 2/4] codestyle issues --- .../CFGraph/DataFlow/backward_data_flow.h | 3 +- .../_src/CFGraph/DataFlow/data_flow_impl.h | 3 +- .../_src/Transformations/dead_code.cpp | 34 +++++++++++-------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/backward_data_flow.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/backward_data_flow.h index 7f81751..556af90 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/backward_data_flow.h +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/backward_data_flow.h @@ -10,7 +10,8 @@ #include "../IR.h" template -class BackwardDataFlowAnalysis : public DataFlowAnalysis { +class BackwardDataFlowAnalysis : public DataFlowAnalysis +{ std::vector reorderSequence(const std::vector& blocks, const std::set back_edge_sources); public: diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow_impl.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow_impl.h index f45b2d7..db33e73 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow_impl.h +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow_impl.h @@ -70,7 +70,8 @@ void DataFlowAnalysisNode::doStep() /* definitions for DataFlowAnalysis class */ template -void DataFlowAnalysis::analyze() { +void DataFlowAnalysis::analyze() +{ auto curr = 0; auto stop = nodes.size(); diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp index 089ca88..6f724b5 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp @@ -135,7 +135,8 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set& use, } -class DeadCodeAnalysisNode : public DataFlowAnalysisNode>> { +class DeadCodeAnalysisNode : public DataFlowAnalysisNode>> +{ private: vector useful; bool useful_block = false; @@ -198,28 +199,28 @@ public: return updated; } - map> getIn() { + map> getIn() + { return getBlock()->getLiveOut(); } - map> getOut() { + map> getOut() + { return getBlock()->getLiveIn(); } - bool addIn(const map>& data) { - bool inserted = getBlock()->addLiveOut(data); - - return inserted; + bool addIn(const map>& data) + { + return getBlock()->addLiveOut(data); } - bool addOut(const map>& data) { + bool addOut(const map>& data) + { return getBlock()->addLiveIn(data); } - bool updateState() { - if(getBlock()->getInstructions()[0]->getInstruction()->getOperator()->lineNumber() == 58) - int b = 51; - + bool updateState() + { bool updated = false; if (!useful_block) @@ -231,7 +232,8 @@ public: return updated; } - bool forwardData(const map>& data) { + bool forwardData(const map>& data) + { bool inserted = false; SAPFOR::BasicBlock* bb= getBlock(); @@ -315,12 +317,14 @@ public: const vector& getResult() { return useful; } }; -class DeadCodeAnalysis : public BackwardDataFlowAnalysis { +class DeadCodeAnalysis : public BackwardDataFlowAnalysis +{ protected: vector& formal_parameters; const map& funcByName; - DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override { + DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override + { return new DeadCodeAnalysisNode(block, formal_parameters, funcByName); } public: From af194134ba729a98e55122168fb88b7ca1261571 Mon Sep 17 00:00:00 2001 From: Mikhail Kocharmin Date: Thu, 4 Apr 2024 20:37:34 +0300 Subject: [PATCH 3/4] dead_code: fix for recent changes --- sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp index 6f724b5..3535963 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp @@ -41,7 +41,7 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru { if (use.find(r) != use.end() || r->getMemType() != SAPFOR::CFG_MEM_TYPE::LOCAL_ || - r->getType() != SAPFOR::CFG_ARG_TYPE::VAR) + !(r->getType() == SAPFOR::CFG_ARG_TYPE::VAR || r->getType() == SAPFOR::CFG_ARG_TYPE::REG)) { useful = true; break; From 5f4bb71dcfb60c032784a15751ee124cf9f9e488 Mon Sep 17 00:00:00 2001 From: Mikhail Kocharmin Date: Fri, 5 Apr 2024 16:03:18 +0300 Subject: [PATCH 4/4] dead code: fix for variables from loop headers --- .../_src/Transformations/dead_code.cpp | 110 +++++++++++++----- 1 file changed, 80 insertions(+), 30 deletions(-) diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp index 3535963..52f0458 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp @@ -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>& cfg, set& shared_regs) +{ + map used_at; + + for (const auto& byFunc : cfg) + { + for (const auto& byBlock : byFunc.second) + { + for (const auto& byIrBlock : byBlock->getInstructions()) + { + auto instr = byIrBlock->getInstruction(); + + set 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& use, set& 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& 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& formal_parameters; const map& funcByName; + const set& 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& formal_parameters, - const map& funcByName) + const map& funcByName, + const set& 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 protected: vector& formal_parameters; const map& funcByName; + const set& 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& formal_parameters, const map& funcByName) + DeadCodeAnalysis(vector& formal_parameters, + const map& funcByName, + const set& 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 func_parameters(cfg_pair.first->funcParams.countOfPars, NULL); map funcByName; @@ -412,8 +459,11 @@ void removeDeadCode(SgStatement* func, for (auto& byFile : allFuncs) for (auto byFunc : byFile.second) funcByName[byFunc->funcName] = byFunc; + + set 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();