From a827c405438b13dafcd79da24465f299df39e108 Mon Sep 17 00:00:00 2001 From: Mikhail Kocharmin Date: Wed, 10 Apr 2024 22:03:27 +0300 Subject: [PATCH] dead code: handle STORE and LOAD instructions --- .../_src/CFGraph/live_variable_analysis.cpp | 138 ++++++++++-------- .../_src/CFGraph/live_variable_analysis.h | 3 +- .../_src/Transformations/dead_code.cpp | 35 +++-- 3 files changed, 101 insertions(+), 75 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 05f6bfb..841882e 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp @@ -294,39 +294,46 @@ public: void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr, set& use, set& def, vector& formal_parameters, vector& fcalls, - vector& lastParamRef, int& last_param_ref_index, int& last_param_ref_size, + vector& arg_stack, int& arg_stack_index, int& arg_stack_size, + bool& last_stack_op, string& fName, const map& funcByName, bool interprocedural) { for (auto arg : { instr->getArg1(), instr->getArg2(), instr->getResult() }) if (arg && arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_) formal_parameters[getParamIndex(arg, formal_parameters.size())] = arg; + last_stack_op = false; SAPFOR::Argument* res_arg = NULL; static const set skip = { SAPFOR::CFG_OP::ENTRY }; SAPFOR::CFG_OP instr_operation = instr->getOperation(); - if (hasStoreStructure(instr_operation)) + if (instr_operation == SAPFOR::CFG_OP::F_CALL || + instr_operation == SAPFOR::CFG_OP::STORE || + instr_operation == SAPFOR::CFG_OP::LOAD) + { + res_arg = (instr_operation == SAPFOR::CFG_OP::STORE ? instr->getArg1() : instr->getResult()); + if(instr_operation != SAPFOR::CFG_OP::F_CALL) + use.insert(instr_operation != SAPFOR::CFG_OP::STORE ? instr->getArg1() : instr->getResult()); + + arg_stack_size = stoi(instr->getArg2()->getValue()); + + arg_stack.clear(); + arg_stack.resize(arg_stack_size); + + arg_stack_index = arg_stack_size - 1; + + if(instr_operation == SAPFOR::CFG_OP::F_CALL) + fName = instr->getArg1()->getValue(); + } + else if (hasStoreStructure(instr_operation)) { res_arg = instr->getArg1(); set instr_args = { instr->getResult(), instr->getArg2() }; use.insert(instr_args.begin(), instr_args.end()); } - else if (instr_operation == SAPFOR::CFG_OP::PARAM) + else if (instr_operation == SAPFOR::CFG_OP::PARAM || instr_operation == SAPFOR::CFG_OP::REF) { - lastParamRef[last_param_ref_index--] = instr->getArg1(); - } - else if (instr_operation == SAPFOR::CFG_OP::F_CALL) - { - res_arg = instr->getResult(); - - last_param_ref_size = stoi(instr->getArg2()->getValue()); - - lastParamRef.clear(); - lastParamRef.resize(last_param_ref_size); - - last_param_ref_index = last_param_ref_size - 1; - - fName = instr->getArg1()->getValue(); + arg_stack[arg_stack_index--] = instr->getArg1(); } else if (skip.find(instr_operation) == skip.end()) { @@ -341,50 +348,60 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins return; } - 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 (interprocedural && func_it != funcByName.end()) + if (arg_stack_index < 0) { + if(instr_operation == SAPFOR::CFG_OP::PARAM || instr_operation == SAPFOR::CFG_OP::F_CALL) { - fcalls.push_back(LiveDeadVarsForCall(func_it->second, block, lastParamRef)); - - auto r_it = fcalls.rbegin(); - auto r_end = fcalls.rend(); - - for (auto e : def) - r_it->make_dead(e); - - for (auto e : use) - r_it->make_live(e, block); - } - - set make_live, make_dead; - if (fName == "_READ") - def.insert(lastParamRef.begin(), lastParamRef.end()); - else if (interprocedural && getLiveDead(lastParamRef, fName, make_live, make_dead)) - { - 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++) + auto func_it = funcByName.find(fName); + if (interprocedural && func_it != funcByName.end()) { - if(func_it->second->funcParams.isArgOut(i)) - def.insert(lastParamRef[i]); + fcalls.push_back(LiveDeadVarsForCall(func_it->second, block, arg_stack)); - if (func_it->second->funcParams.isArgIn(i)) - use.insert(lastParamRef[i]); + auto r_it = fcalls.rbegin(); + auto r_end = fcalls.rend(); + + for (auto e : def) + r_it->make_dead(e); + + for (auto e : use) + r_it->make_live(e, block); } + + set make_live, make_dead; + if (fName == "_READ") + def.insert(arg_stack.begin(), arg_stack.end()); + else if (interprocedural && getLiveDead(arg_stack, fName, make_live, make_dead)) + { + 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 = arg_stack.size(); + for (int i = 0; i < arg_num; i++) + { + if(func_it->second->funcParams.isArgOut(i)) + def.insert(arg_stack[i]); + + if (func_it->second->funcParams.isArgIn(i)) + use.insert(arg_stack[i]); + } + } + else + use.insert(arg_stack.begin(), arg_stack.end()); + + fName = ""; + } + else + { + use.insert(arg_stack.begin(), arg_stack.end()); } - else - use.insert(lastParamRef.begin(), lastParamRef.end()); - last_param_ref_index = 0; - last_param_ref_size = 0; + arg_stack_index = 0; + arg_stack_size = 0; - lastParamRef.clear(); - fName = ""; + arg_stack.clear(); + + last_stack_op = true; } if (res_arg) @@ -394,15 +411,16 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr, set& use, set& def, vector& formal_parameters, vector& fcalls, - vector& lastParamRef, int& last_param_ref_index, int& last_param_ref_size, + vector& arg_stack, int& arg_stack_index, int& arg_stack_size, string& fName, const map& funcByName, bool interprocedural) { set res, args; - + bool last_stack_op; getUseDefForInstruction(block, instr, args, res, formal_parameters, fcalls, - lastParamRef, last_param_ref_index, last_param_ref_size, + arg_stack, arg_stack_index, arg_stack_size, + last_stack_op, fName, funcByName, interprocedural ); @@ -431,8 +449,8 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set& use, vector& formal_parameters, vector& fcalls, const map& funcByName, bool interprocedural) { - vector lastParamRef; - int last_param_ref_index = 0, last_param_ref_size = 0; + vector arg_stack; + int arg_stack_index = 0, arg_stack_size = 0; string fName; const auto& instructions = block->getInstructions(); @@ -443,7 +461,7 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set& use, updateUseDefForInstruction(block, (*ir_block_it)->getInstruction(), use, def, formal_parameters, fcalls, - lastParamRef, last_param_ref_index, last_param_ref_size, + arg_stack, arg_stack_index, arg_stack_size, fName, funcByName, interprocedural ); diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.h index 7e6cd73..9b92523 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.h +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.h @@ -42,7 +42,8 @@ void insertIfVar(IT begin, IT end, DEST& to) { void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr, std::set& use, std::set& def, std::vector& formal_parameters, std::vector& fcalls, - std::vector& lastParamRef, int& last_param_ref_index, int& last_param_ref_size, + std::vector& arg_stack, int& arg_stack_index, int& arg_stack_size, + bool& last_stack_op, std::string& fName, const std::map& funcByName, bool interprocedural); void runLiveVariableAnalysis(const std::map>& CFGraph_for_project); diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp index b9f58c7..fb4cfba 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp @@ -19,23 +19,27 @@ using std::remove_if; static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr, set& use, set& def, vector& formal_parameters, - vector& lastParamRef, int& last_param_ref_index, int& last_param_ref_size, + vector& arg_stack, int& arg_stack_index, int& arg_stack_size, string& fName, const map& funcByName, - bool& useful, bool& last_fcall_useful, + bool& useful, bool& last_stack_op_useful, set& usedByThisBlock) { set res, args; + bool last_stack_op; vector fcalls; getUseDefForInstruction(block, instr, args, res, formal_parameters, fcalls, - lastParamRef, last_param_ref_index, last_param_ref_size, + arg_stack, arg_stack_index, arg_stack_size, + last_stack_op, fName, funcByName, false ); + const auto instr_operation = instr->getOperation(); + if (!useful) { for (SAPFOR::Argument* r : res) @@ -64,21 +68,24 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru SAPFOR::CFG_OP::SPF_DIR }; - if (always_useful.find(instr->getOperation()) != always_useful.end()) + if (always_useful.find(instr_operation) != always_useful.end()) useful = true; - else if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL) + else if (instr_operation == 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; + else if (instr_operation == SAPFOR::CFG_OP::PARAM || + instr_operation == SAPFOR::CFG_OP::REF) + useful |= last_stack_op_useful; } if (useful) { - if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL) - last_fcall_useful = true; + if (instr_operation == SAPFOR::CFG_OP::F_CALL || + instr_operation == SAPFOR::CFG_OP::LOAD || + instr_operation == SAPFOR::CFG_OP::STORE) + last_stack_op_useful = true; for (auto e : res) { @@ -95,8 +102,8 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru usedByThisBlock.insert(args.begin(), args.end()); } - if ((instr->getOperation() == SAPFOR::CFG_OP::F_CALL || instr->getOperation() == SAPFOR::CFG_OP::PARAM) && fName == "") - last_fcall_useful = false; + if (last_stack_op) + last_stack_op_useful = false; } @@ -107,8 +114,8 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set& use, { set use_with_regs = use, def_with_regs = def; - vector lastParamRef; - int last_param_ref_index = 0, last_param_ref_size = 0; + vector arg_stack; + int arg_stack_index = 0, arg_stack_size = 0; string fName = ""; bool last_fcall_useful = false; @@ -122,7 +129,7 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set& use, updateUseDefForInstruction(block, instructions[i]->getInstruction(), use_with_regs, def_with_regs, formal_parameters, - lastParamRef, last_param_ref_index, last_param_ref_size, + arg_stack, arg_stack_index, arg_stack_size, fName, funcByName, u, last_fcall_useful, usedByThisBlock