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 4b40ff9..3ba060b 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/live_variable_analysis.cpp @@ -172,13 +172,17 @@ public: void make_dead(SAPFOR::Argument* arg) { if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::COMMON_ || arg->getMemType() == SAPFOR::CFG_MEM_TYPE::MODULE_) - commons_dead_after.insert(arg); + { + if (commons_live_after.find(arg) == commons_live_after.end()) + commons_dead_after.insert(arg); + } auto it = find(params.begin(), params.end(), arg); if (it != params.end()) { int idx = it - params.begin(); - dead_after.insert(idx); + if (live_after.find(idx) == live_after.end()) + dead_after.insert(idx); } } @@ -197,6 +201,10 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set& use, vector& formal_parameters, vector& fcalls, const map& funcByName); +static void buildUseDef2(SAPFOR::BasicBlock* block, set& use, set& def, + vector& formal_parameters, vector& fcalls, + const map& funcByName); + enum { CNT_NOTINIT = 0 @@ -218,7 +226,101 @@ struct BasicBlockNode bb = block; out_cnt = in_cnt = CNT_NOTINIT; - buildUseDef(bb, live, dead, formal_parameters, fcalls, funcByName); + set live1, dead1; + vector formal_parameters1 = formal_parameters; + vector fcalls1; + + buildUseDef(bb, live1, dead1, formal_parameters1, fcalls1, funcByName); + + + set live2, dead2; + vector formal_parameters2 = formal_parameters; + vector fcalls2; + + buildUseDef2(bb, live2, dead2, formal_parameters2, fcalls2, funcByName); + + bool err = false; + + for (auto& l1 : live1) { + if (live2.find(l1) == live2.end()) { + __spf_print(1, "bb %d use %s >> 1\n", bb->getNumber(), l1->getValue().c_str()); + err = true; + } + } + + for (auto& l2 : live2) { + if (live1.find(l2) == live1.end()) { + __spf_print(1, "bb %d use %s >> 2\n", bb->getNumber(), l2->getValue().c_str()); + err = true; + } + } + + err |= live1.size() != live2.size(); + + for (auto& l1 : dead1) { + if (dead2.find(l1) == dead2.end()) { + __spf_print(1, "bb %d dead %s >> 1\n", bb->getNumber(), l1->getValue().c_str()); + err = true; + } + } + + for (auto& l2 : dead2) { + if (dead1.find(l2) == dead1.end()) { + __spf_print(1, "bb %d dead %s >> 2\n", bb->getNumber(), l2->getValue().c_str()); + err = true; + } + } + + err |= dead1.size() != dead2.size(); + + if (fcalls1.size() != fcalls2.size()) { + __spf_print(1, "bb %d different fcall sizes: 1: %d, w: %d\n", bb->getNumber(), fcalls1.size(), fcalls2.size()); + + err = true; + } + else { + for (int i = 0; i < fcalls1.size(); i++) { + auto& c1 = fcalls1[i]; + auto& c2 = fcalls2[fcalls1.size() - i - 1]; + + if (c1.func->funcName != c2.func->funcName) { + __spf_print(1, "different fnames %s, %s\n", c1.func->funcName.c_str(), c2.func->funcName.c_str()); + err = true; + } + + if (c1.live_after != c2.live_after) { + __spf_print(1, "different live_after\n"); + err = true; + } + + if (c1.dead_after != c2.dead_after) { + __spf_print(1, "different dead_after\n"); + err = true; + } + + if (c1.commons_dead_after != c2.commons_dead_after) { + __spf_print(1, "different commons_dead_after\n"); + err = true; + } + + if (c1.commons_live_after != c2.commons_live_after) { + __spf_print(1, "different commons_live_after\n"); + err = true; + } + } + } + + if(err) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + live = live1; + dead = dead1; + formal_parameters = formal_parameters1; + + for (auto& fc : fcalls1) + fcalls.push_back(fc); + + for (SAPFOR::Argument* arg : live) bb->addLiveIn({ { arg, { bb } } }); @@ -278,6 +380,130 @@ struct BasicBlockNode bool newerThan(const BasicBlockNode* block) const { return in_cnt > block->out_cnt; } }; +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, + string& fName, + const map& funcByName) +{ + 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; + + set res = {}, args = {}; + SAPFOR::Argument* res_arg = NULL; + + static const set skip = { SAPFOR::CFG_OP::ENTRY }; + SAPFOR::CFG_OP instr_operation = instr->getOperation(); + if (hasStoreStructure(instr_operation)) + { + res_arg = instr->getArg1(); + set instr_args = { instr->getResult(), instr->getArg2() }; + insertIfVar(instr_args.begin(), instr_args.end(), args); + } + else if (instr_operation == SAPFOR::CFG_OP::PARAM) + { + 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(); + } + else if (skip.find(instr_operation) == skip.end()) + { + //default + res_arg = instr->getResult(); + std::set intr_args = { instr->getArg1(), instr->getArg2() }; + insertIfVar(intr_args.begin(), intr_args.end(), args); + } + else + { + //skip + 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 (func_it != funcByName.end()) + { + fcalls.push_back(fcall(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") + res.insert(lastParamRef.begin(), lastParamRef.end()); + else if (getLiveDead(lastParamRef, fName, make_live, make_dead)) + { + insertIfVar(make_live.begin(), make_live.end(), args); + insertIfVar(make_dead.begin(), make_dead.end(), res); + } + else + insertIfVar(lastParamRef.begin(), lastParamRef.end(), args); + + last_param_ref_index = 0; + last_param_ref_size = 0; + + lastParamRef.clear(); + } + + if (res_arg && res_arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR) + res.insert(res_arg); + + for (auto e : res) + { + def.insert(e); + use.erase(e); + } + + for (auto e : args) { + use.insert(e); + def.erase(e); + } +} + +//Build use and def sets of block. Result are stored in use and def +static void buildUseDef2(SAPFOR::BasicBlock* block, set& use, set& def, + vector& formal_parameters, vector& fcalls, + const map& funcByName) +{ + vector lastParamRef; + int last_param_ref_index = 0, last_param_ref_size = 0; + string fName; + + const auto& instructions = block->getInstructions(); + auto ir_block_it = instructions.rbegin(), ir_block_end = instructions.rend(); + + for (; ir_block_it != ir_block_end; ir_block_it++) + { + updateUseDefForInstruction(block, (*ir_block_it)->getInstruction(), + use, def, + formal_parameters, fcalls, + lastParamRef, last_param_ref_index, last_param_ref_size, + fName, funcByName + ); + } +} + //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& fcalls,