From 42fe628ce08f7f8f6901b340c6e247bf3fd52072 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: Fri, 2 Feb 2024 15:52:36 +0300 Subject: [PATCH] dead code removing: handle dead call statements --- .../_src/CFGraph/live_variable_analysis.cpp | 14 +++- .../_src/Transformations/dead_code.cpp | 67 ++++++++++++------- 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp b/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp index 5f79f52..ad41626 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp @@ -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) { 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)); @@ -360,6 +360,18 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins use.insert(make_live.begin(), make_live.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 use.insert(lastParamRef.begin(), lastParamRef.end()); diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp index 98beffd..e09ce14 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp @@ -19,23 +19,19 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru set& use, set& def, vector& formal_parameters, vector& lastParamRef, int& last_param_ref_index, int& last_param_ref_size, - string& fName, + string& fName, const map& funcByName, bool& useful, bool& last_fcall_useful, set& usedByThisBlock) { set res, args; - if (fName == "") - last_fcall_useful = false; - vector fcalls; - getUseDefForInstruction(block, instr, args, res, formal_parameters, fcalls, lastParamRef, last_param_ref_index, last_param_ref_size, - fName, {}, + fName, funcByName, false ); @@ -62,17 +58,18 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru SAPFOR::CFG_OP::ENTRY, SAPFOR::CFG_OP::EXIT, SAPFOR::CFG_OP::DVM_DIR, - SAPFOR::CFG_OP::SPF_DIR, - SAPFOR::CFG_OP::JUMP, - SAPFOR::CFG_OP::JUMP_IF, - - SAPFOR::CFG_OP::F_CALL //TODO: handle pure functions + SAPFOR::CFG_OP::SPF_DIR }; if (always_useful.find(instr->getOperation()) != always_useful.end()) useful = true; - else if(instr->getOperation() == SAPFOR::CFG_OP::PARAM && last_fcall_useful) - useful = true; + else if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL) + { + 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) @@ -94,13 +91,16 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru 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 static void buildUseDef(SAPFOR::BasicBlock* block, set& use, set& def, vector& formal_parameters, vector& useful, - set& usedByThisBlock) + set& usedByThisBlock, const map& funcByName) { set use_with_regs = use, def_with_regs = def; @@ -120,7 +120,7 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set& use, use_with_regs, def_with_regs, formal_parameters, lastParamRef, last_param_ref_index, last_param_ref_size, - fName, + fName, funcByName, u, last_fcall_useful, usedByThisBlock ); @@ -141,6 +141,7 @@ private: bool useful_jump = false; vector& formal_parameters; + const map& funcByName; public: bool updateJumpStatus() { @@ -228,7 +229,7 @@ public: use.insert(byArg.first); set 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(); @@ -288,15 +289,19 @@ public: return inserted; } - DeadCodeAnalysisNode(SAPFOR::BasicBlock* block, vector& formal_parameters) : - formal_parameters(formal_parameters) + DeadCodeAnalysisNode(SAPFOR::BasicBlock* block, + vector& formal_parameters, + const map& funcByName) + : + formal_parameters(formal_parameters), + funcByName(funcByName) { setBlock(block); useful.resize(block->getInstructions().size(), false); set use, def; set 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) getBlock()->addLiveIn({ { arg, { getBlock() } } }); @@ -308,13 +313,16 @@ public: class DeadCodeAnalysis : public BackwardDataFlowAnalysis { protected: vector& formal_parameters; + const map& funcByName; DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override { - return new DeadCodeAnalysisNode(block, formal_parameters); + return new DeadCodeAnalysisNode(block, formal_parameters, funcByName); } public: - DeadCodeAnalysis(vector& formal_parameters) : - formal_parameters(formal_parameters) + DeadCodeAnalysis(vector& formal_parameters, const map& funcByName) + : + formal_parameters(formal_parameters), + funcByName(funcByName) { } }; @@ -378,7 +386,13 @@ void removeDeadCode(SgStatement* func, vector func_parameters(cfg_pair.first->funcParams.countOfPars, NULL); - DeadCodeAnalysis analysis_object(func_parameters); + map 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.analyze(); @@ -413,9 +427,12 @@ void removeDeadCode(SgStatement* func, SgStatement* end = func->lastNodeOfStmt(), *st = func; - set removable = + set removable = { - ASSIGN_STAT + ASSIGN_STAT, + PROC_STAT, + WRITE_STAT, + READ_STAT }; while (st != end)