something done
This commit is contained in:
@@ -10,24 +10,317 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "dvm.h"
|
#include "dvm.h"
|
||||||
#include "../Utils/errors.h"
|
#include "../Utils/errors.h"
|
||||||
#include "../Utils/SgUtils.h"
|
#include "../Utils/SgUtils.h"
|
||||||
#include "../GraphCall/graph_calls.h"
|
#include "../GraphCall/graph_calls.h"
|
||||||
#include "../GraphCall/graph_calls_func.h"
|
#include "../GraphCall/graph_calls_func.h"
|
||||||
|
#include "../CFGraph/CFGraph.h"
|
||||||
|
#include "../CFGraph/IR.h"
|
||||||
|
#include "../GraphLoop/graph_loops.h"
|
||||||
|
|
||||||
#include "projectParameters.h"
|
#include "projectParameters.h"
|
||||||
|
|
||||||
using namespace std;
|
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<SAPFOR::BasicBlock*> blocks)
|
||||||
|
{
|
||||||
|
unordered_set<SAPFOR::BasicBlock*> 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<FuncInfo*> FindFuncInfoVec(string funcname, const map<string, vector<FuncInfo*>> &allFuncInfo){
|
||||||
|
for(pair<string, vector<FuncInfo*>> p: allFuncInfo) {
|
||||||
|
if(p.first == funcname){
|
||||||
|
return p.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector<FuncInfo*> a;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<SAPFOR::BasicBlock*> FindBlocksVec(FuncInfo* func, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>> &fullIR){
|
||||||
|
for(const pair<FuncInfo*, vector<SAPFOR::BasicBlock*>>& p: fullIR) {
|
||||||
|
if(p.first == func){
|
||||||
|
return p.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector<SAPFOR::BasicBlock*> a;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<LoopGraph*> FindLoopsWithFilename(string filename, const map<string, vector<LoopGraph*>> loopGraph){
|
||||||
|
for(pair<string, vector<LoopGraph*>> p: loopGraph) {
|
||||||
|
if(p.first == filename){
|
||||||
|
return p.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector<LoopGraph*> a;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bool CheckIfInstructionIsFound(vector<pair<int, SAPFOR::Instruction*>> found, int block_num, SAPFOR::Instruction* instr){
|
||||||
|
// for(pair<int, SAPFOR::Instruction*> p: found){
|
||||||
|
// if(p.first == block_num && p.second == instr){
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
map< pair<string, int>, set<string>>
|
map< pair<string, int>, set<string>>
|
||||||
findParameters(const map<string, vector<DefUseList>> &defUseByFunctions,
|
findParameters(const map<string, vector<DefUseList>> &defUseByFunctions,
|
||||||
const map<string, CommonBlock*> &commonBlocks,
|
const map<string, CommonBlock*> &commonBlocks,
|
||||||
const map<string, vector<FuncInfo*>> &allFuncInfo)
|
const map<string, vector<FuncInfo*>> &allFuncInfo,
|
||||||
|
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>> &fullIR,
|
||||||
|
const map<string, vector<LoopGraph*>>& loopGraph)
|
||||||
{
|
{
|
||||||
map< pair<string, int>, set<string>> foundParameters;
|
map<pair<string, int>, set<string>> 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<string, vector<DefUseList>> 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<string, vector<FuncInfo*>> 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<FuncInfo*, vector<SAPFOR::BasicBlock*>>& 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<string, vector<LoopGraph*>>& 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<FuncInfo*> fi = FindFuncInfoVec(p.first, allFuncInfo);
|
||||||
|
SAPFOR::BasicBlock* head = nullptr;
|
||||||
|
for(auto funcs: fi){
|
||||||
|
vector<SAPFOR::BasicBlock*> 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<FuncInfo*, vector<SAPFOR::BasicBlock*>> mapFuncLoops;
|
||||||
|
for(const pair<FuncInfo*, vector<SAPFOR::BasicBlock*>>& p: fullIR) {
|
||||||
|
vector<LoopGraph*> 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<FuncInfo*, vector<SAPFOR::Instruction*>> 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<SAPFOR::BasicBlock*> blocks = v->getPrev();
|
||||||
|
vector<SAPFOR::Argument*> 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<SAPFOR::IR_Block*> 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;
|
return foundParameters;
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
std::map< std::pair<std::string, int>, std::set<std::string>> findParameters(const std::map<std::string, std::vector<DefUseList>> &defUseByFunctions, const std::map<std::string, CommonBlock*> &commonBlocks, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo);
|
#include "../Utils/leak_detector.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
#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::string, int>, std::set<std::string>> findParameters(const std::map<std::string, std::vector<DefUseList>> &defUseByFunctions,
|
||||||
|
const std::map<std::string, CommonBlock*> &commonBlocks,
|
||||||
|
const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo,
|
||||||
|
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>> &fullIR,
|
||||||
|
const std::map<std::string, std::vector<LoopGraph*>>& loopGraph);
|
||||||
@@ -1874,7 +1874,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
else if (curr_regime == RENAME_SYMBOLS)
|
else if (curr_regime == RENAME_SYMBOLS)
|
||||||
runRenameSymbols(&project, commonBlocks);
|
runRenameSymbols(&project, commonBlocks);
|
||||||
else if (curr_regime == FIND_PARAMETERS)
|
else if (curr_regime == FIND_PARAMETERS)
|
||||||
parametersOfProject = findParameters(defUseByFunctions, commonBlocks, allFuncInfo);
|
parametersOfProject = findParameters(defUseByFunctions, commonBlocks, allFuncInfo, fullIR, loopGraph);
|
||||||
else if (curr_regime == BUILD_IR)
|
else if (curr_regime == BUILD_IR)
|
||||||
{
|
{
|
||||||
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));
|
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));
|
||||||
|
|||||||
Reference in New Issue
Block a user