From ba963634c2c24bc92c5fdfcd44a007b024a5ee82 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Thu, 21 Nov 2024 01:27:50 +0300 Subject: [PATCH] something done --- .../ProjectParameters/projectParameters.cpp | 297 +++++++++++++++++- .../ProjectParameters/projectParameters.h | 27 +- sapfor/experts/Sapfor_2017/_src/Sapfor.cpp | 2 +- 3 files changed, 322 insertions(+), 4 deletions(-) diff --git a/sapfor/experts/Sapfor_2017/_src/ProjectParameters/projectParameters.cpp b/sapfor/experts/Sapfor_2017/_src/ProjectParameters/projectParameters.cpp index fd395dc..524f67d 100644 --- a/sapfor/experts/Sapfor_2017/_src/ProjectParameters/projectParameters.cpp +++ b/sapfor/experts/Sapfor_2017/_src/ProjectParameters/projectParameters.cpp @@ -10,24 +10,317 @@ #include #include #include +#include #include "dvm.h" #include "../Utils/errors.h" #include "../Utils/SgUtils.h" #include "../GraphCall/graph_calls.h" #include "../GraphCall/graph_calls_func.h" +#include "../CFGraph/CFGraph.h" +#include "../CFGraph/IR.h" +#include "../GraphLoop/graph_loops.h" #include "projectParameters.h" using namespace std; +set goodArgTypes = {SAPFOR::CFG_ARG_TYPE::REG, SAPFOR::CFG_ARG_TYPE::VAR}; +set funcOperatrions = {SAPFOR::CFG_OP::PARAM, SAPFOR::CFG_OP::F_CALL}; +set instructionsToLook = {SAPFOR::CFG_OP::LOAD, SAPFOR::CFG_OP::STORE, SAPFOR::CFG_OP::REC_REF_LOAD, SAPFOR::CFG_OP::REC_REF_STORE, + SAPFOR::CFG_OP::ADD, SAPFOR::CFG_OP::MULT, SAPFOR::CFG_OP::DIV, SAPFOR::CFG_OP::SUBT, SAPFOR::CFG_OP::UN_ADD, + SAPFOR::CFG_OP::UN_MINUS, SAPFOR::CFG_OP::POW, SAPFOR::CFG_OP::CONCAT, SAPFOR::CFG_OP::ASSIGN}; + +static bool isParentStmt(SgStatement* stmt, SgStatement* parent) +{ + for (; stmt; stmt = stmt->controlParent()) + if (stmt == parent) + { + return true; + } + return false; +} + +/*returns head block and loop*/ +SAPFOR::BasicBlock* GetBasicBlocksForLoop(LoopGraph* loop, vector blocks) +{ + unordered_set block_loop; + SAPFOR::BasicBlock* head_block = nullptr; + auto loop_operator = loop->loop->GetOriginal(); + for (const auto& block : blocks) + { + if (!block || (block->getInstructions().size() == 0)) + { + continue; + } + SgStatement* first = block->getInstructions().front()->getInstruction()->getOperator(); + SgStatement* last = block->getInstructions().back()->getInstruction()->getOperator(); + if (isParentStmt(first, loop_operator) && isParentStmt(last, loop_operator)) + { + if ((!head_block) && (first == loop_operator) && (last == loop_operator) && + (block->getInstructions().size() == 2) && + (block->getInstructions().back()->getInstruction()->getOperation() == SAPFOR::CFG_OP::JUMP_IF)) + { + head_block = block; + } + + } + } + return head_block; +} + +vector FindFuncInfoVec(string funcname, const map> &allFuncInfo){ + for(pair> p: allFuncInfo) { + if(p.first == funcname){ + return p.second; + } + } + vector a; + return a; +} + +vector FindBlocksVec(FuncInfo* func, const map> &fullIR){ + for(const pair>& p: fullIR) { + if(p.first == func){ + return p.second; + } + } + vector a; + return a; +} + +vector FindLoopsWithFilename(string filename, const map> loopGraph){ + for(pair> p: loopGraph) { + if(p.first == filename){ + return p.second; + } + } + vector a; + return a; +} + +// bool CheckIfInstructionIsFound(vector> found, int block_num, SAPFOR::Instruction* instr){ +// for(pair p: found){ +// if(p.first == block_num && p.second == instr){ +// return true; +// } +// } +// return +// } + map< pair, set> findParameters(const map> &defUseByFunctions, const map &commonBlocks, - const map> &allFuncInfo) + const map> &allFuncInfo, + const map> &fullIR, + const map>& loopGraph) { - map< pair, set> foundParameters; + map, set> foundParameters; + // print and look part (Yes, I am stupid) + /* + printf("\n\n\n\nPRINT EXAMPLE\n\n\n\n\n"); + cout << "DEF USE INFO" << endl; + for(pair> p: defUseByFunctions) { + cout << "function name = " << p.first << endl; + for(auto& v: p.second) { + cout << "VARIABLE = "; + v.print(); + } + } + cout << "\n\nALL FUNC INFO" << endl; + for(pair> p: allFuncInfo) { + cout << "file name = " << p.first << endl; + for(auto& v: p.second) { + cout << "func name = " << v->funcName << endl; + for(auto& v1: v->funcParams.identificators) { + cout << "identifier: " << v1 << endl; + } + } + } + cout << "\n\n FULL IR" << endl; + for(const pair>& p: fullIR) { + cout << "func name = " << p.first->funcName << endl; + for(auto v: p.second) { + cout << "block num = " << v->getNumber() << endl; + cout << "prev: {"; + for(auto pr: v->getPrev()){ + cout << pr->getNumber() << ","; + } + cout << "}\nnext: {"; + for(auto n: v->getNext()){ + cout << n->getNumber() << ","; + } + cout << "}" << endl; + for(auto inst: v->getInstructions()){ + cout << "instruction: " << inst->getInstruction()->dump() << endl; + cout << "operator: " << inst->getInstruction()->getOperator()->sunparse() << endl; + } + } + } + cout << "\n\nLoopGraph" << endl; + for(const pair>& p: loopGraph){ + cout << "file name = " << p.first << endl; + for(auto v: p.second) { + cout << v->loop->sunparse() << endl; + cout << v->countOfIters << endl; + cout << v->loopSymbol << endl; + vector fi = FindFuncInfoVec(p.first, allFuncInfo); + SAPFOR::BasicBlock* head = nullptr; + for(auto funcs: fi){ + vector blocks = FindBlocksVec(funcs, fullIR); + head = GetBasicBlocksForLoop(v, blocks); + if(head != nullptr){ + break; + } + } + if(head != nullptr){ + cout << "loop head block num = " << head->getNumber() << endl; + }else{ + cout << "no such block for loop (fail)" << endl; + } + } + } + */ + + + // Находим для каждой функции блоки, с которых начинаются циклы + map> mapFuncLoops; + for(const pair>& p: fullIR) { + vector loopsForFile = FindLoopsWithFilename(p.first->fileName, loopGraph); + SAPFOR::BasicBlock* head = nullptr; + for(auto v: loopsForFile){ + head = nullptr; + head = GetBasicBlocksForLoop(v, p.second); + if(head != nullptr){ + mapFuncLoops[p.first].push_back(head); + } + } + } + + // На всякий случай выводим их + cout << "ALL LOOPS" << endl; + for(auto m: mapFuncLoops){ + cout << "func: " << m.first->funcName << endl; + for(auto v: m.second){ + cout << "block num: " << v->getNumber() << endl; + cout << v->getInstructions().front()->getInstruction()->getOperator()->sunparse() << endl; + } + } + + map> finalInstructions; + for(const auto lookedFunc: mapFuncLoops){ + for(const auto& v: lookedFunc.second){ + // cout << "NEW LOOP SEARCH" << endl; + SAPFOR::Instruction* instr = v->getInstructions().front()->getInstruction(); + // cout << instr->getOperator()->sunparse() << endl;; + vector blocks = v->getPrev(); + vector argumentsForLook; + argumentsForLook.push_back(instr->getArg2()); + int block_ind = 0; + // for(auto pr: argumentsForLook){cout << "FIRST ARGUMENT TO FIND: " << pr->getValue() << endl;} + while(block_ind < blocks.size()){ + vector blockInstructions = blocks[block_ind]->getInstructions(); + int vec_size = blockInstructions.size(); + // cout << "NUMBER OF INSTRUCTIONS IN BLOCK " << blocks[block_ind]->getNumber() << " IS: " << vec_size << endl; + for(int i=vec_size-1; i>=0; i--){ + // cout << "ALL ARGUMENTS TO FIND: " << endl; + // for(auto pr: argumentsForLook){cout << pr->getValue() << " ";} + // cout << endl; + SAPFOR::Instruction* cur = blockInstructions[i]->getInstruction(); + // cout << "CUR INSTRUCTION: " << cur->dump() << endl; + // cout << "Instruction Operation (type): " << SAPFOR::CFG_OP_S[(int)cur->getOperation()] << endl; + if(cur->getOperation() == SAPFOR::CFG_OP::F_CALL){ + if(cur->getArg1()->getValue() == "_READ"){ + cout << "READ OPERATION FOUND" << endl; + int numParams = std::stoi(cur->getArg2()->getValue()); + bool flag = false; + for(int j=i-1; j>i-numParams-1; j--){ + auto iter = find(argumentsForLook.begin(), argumentsForLook.end(), blockInstructions[j]->getInstruction()->getArg1()); + if(iter != argumentsForLook.end()){ + argumentsForLook.erase(iter); + flag = true; + } + } + if(flag && find(finalInstructions[lookedFunc.first].begin(), finalInstructions[lookedFunc.first].end(), cur) == finalInstructions[lookedFunc.first].end()){ + finalInstructions[lookedFunc.first].push_back(cur); + } + // if(flag && CheckIfInstructionIsFound(finalInstructions[lookedFunc.first], blocks[block_ind]->getNumber(), cur)){ + // finalInstructions[lookedFunc.first].push_back({blocks[block_ind]->getNumber(), cur}); + // } + i = i-numParams; + continue; + } + auto it = find(argumentsForLook.begin(), argumentsForLook.end(), cur->getResult()); + if(cur->getResult() && it != argumentsForLook.end()){ + int numParams = std::stoi(cur->getArg2()->getValue()); + for(int j=i-1; j>i-numParams-1; j--){ + if(find(argumentsForLook.begin(), argumentsForLook.end(), blockInstructions[j]->getInstruction()->getArg1()) == argumentsForLook.end()){ + argumentsForLook.push_back(blockInstructions[j]->getInstruction()->getArg1()); + } + } + i = i-numParams; + argumentsForLook.erase(it); + continue; + } + } + // cout << "NOT F_CALL" << endl; + // cout << "CUR INSTRUCTION AGAIN: " << cur->dump() << endl; + if(instructionsToLook.find(cur->getOperation()) == instructionsToLook.end()){ + // cout << "NOT ARITH" << endl; + continue; + } + // cout << "ARITH OR ACCESS" << endl; + auto it = find(argumentsForLook.begin(), argumentsForLook.end(), cur->getResult()); + // cout << "RESULT OF INSTRUCTION:" << *it->getValue() << endl; + if(it != argumentsForLook.end()){ + if(find(argumentsForLook.begin(), argumentsForLook.end(), cur->getArg1()) == argumentsForLook.end()){ + // Проверка типа аргумента. Добавляется только если это переменная или регистр + if(goodArgTypes.find(cur->getArg1()->getType()) != goodArgTypes.end()){ + argumentsForLook.push_back(cur->getArg1()); + } + } + if(cur->getArg2() != NULL && find(argumentsForLook.begin(), argumentsForLook.end(), cur->getArg2()) == argumentsForLook.end()){ + if(goodArgTypes.find(cur->getArg2()->getType()) != goodArgTypes.end()){ + argumentsForLook.push_back(cur->getArg2()); + } + } + argumentsForLook.erase(it); + }; + } + for(auto b: blocks[block_ind]->getPrev()){ + if(find(blocks.begin(), blocks.end(), b) == blocks.end()){ + blocks.push_back(b); + } + } + block_ind++; + + // cout << "BLOCKS: "; + // for(auto bl: blocks){cout << bl->getNumber() << " ";} + // cout << endl; + // cout << "block_ind: " << block_ind << endl; + } + // cout << "END WHILE" << endl; + // В векторе argumentsForLook должны быть все аргументы инструкций, которые не получилось найти в блоках программы + // Возможно стоит еще их проверить в параметрах текущей функции, если они там есть + argumentsForLook.clear(); + blocks.clear(); + // cout << "END CLEAR" << endl; + } + } + + // Попытка напечатать полученные инструкции + cout << "\n\n\n\n\nFINAL INSTRUCTIONS" << endl; + for(auto m: finalInstructions){ + cout << "func: " << m.first->funcName << endl; + for(auto v: m.second){ + cout << "instruction num: " << v->getNumber() << endl; + cout << v->dump() << endl; + cout << v->getOperator()->sunparse() << endl; + } + } + + return foundParameters; } \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/ProjectParameters/projectParameters.h b/sapfor/experts/Sapfor_2017/_src/ProjectParameters/projectParameters.h index 5a240b0..28e06ec 100644 --- a/sapfor/experts/Sapfor_2017/_src/ProjectParameters/projectParameters.h +++ b/sapfor/experts/Sapfor_2017/_src/ProjectParameters/projectParameters.h @@ -1,3 +1,28 @@ #pragma once -std::map< std::pair, std::set> findParameters(const std::map> &defUseByFunctions, const std::map &commonBlocks, const std::map> &allFuncInfo); \ No newline at end of file +#include "../Utils/leak_detector.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dvm.h" +#include "../Utils/errors.h" +#include "../Utils/SgUtils.h" +#include "../GraphCall/graph_calls.h" +#include "../GraphCall/graph_calls_func.h" +#include "../CFGraph/CFGraph.h" +#include "../CFGraph/IR.h" + +std::map< std::pair, std::set> findParameters(const std::map> &defUseByFunctions, + const std::map &commonBlocks, + const std::map> &allFuncInfo, + const std::map> &fullIR, + const std::map>& loopGraph); \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp b/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp index 9781d75..e38979a 100644 --- a/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp @@ -1874,7 +1874,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne else if (curr_regime == RENAME_SYMBOLS) runRenameSymbols(&project, commonBlocks); else if (curr_regime == FIND_PARAMETERS) - parametersOfProject = findParameters(defUseByFunctions, commonBlocks, allFuncInfo); + parametersOfProject = findParameters(defUseByFunctions, commonBlocks, allFuncInfo, fullIR, loopGraph); else if (curr_regime == BUILD_IR) { auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));