|
|
|
@@ -10,24 +10,241 @@
|
|
|
|
#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;
|
|
|
|
|
|
|
|
|
|
|
|
map< pair<string, int>, set<string>>
|
|
|
|
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, const SgStatement* parent)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (; stmt; stmt = stmt->controlParent())
|
|
|
|
|
|
|
|
if (stmt == parent)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*returns head block and loop*/
|
|
|
|
|
|
|
|
SAPFOR::BasicBlock* GetBasicBlocksForLoop(const LoopGraph* loop, const 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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*returns FuncInfo vetcor by filename*/
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*returns BasicBlock vector for function by FuncInfo*/
|
|
|
|
|
|
|
|
vector<SAPFOR::BasicBlock*> FindBlocksVec(const 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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*returns LoopGraph vector by filename*/
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*checks if instruction is found for result*/
|
|
|
|
|
|
|
|
bool CheckIfInstructionIsFound(const vector<pair<int, SAPFOR::Instruction*>> found, int block_num, const SAPFOR::Instruction* instr){
|
|
|
|
|
|
|
|
for(pair<int, SAPFOR::Instruction*> p: found){
|
|
|
|
|
|
|
|
if(p.first == block_num && p.second == instr){
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*main pass function*/
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
|
/*find blocks with loops start for each function*/
|
|
|
|
|
|
|
|
map<FuncInfo*, vector<SAPFOR::BasicBlock*>> mapFuncLoops;
|
|
|
|
return foundParameters;
|
|
|
|
for(const pair<FuncInfo*, vector<SAPFOR::BasicBlock*>>& partIR: fullIR) {
|
|
|
|
|
|
|
|
vector<LoopGraph*> loopsForFile = FindLoopsWithFilename(partIR.first->fileName, loopGraph);
|
|
|
|
|
|
|
|
SAPFOR::BasicBlock* head = nullptr;
|
|
|
|
|
|
|
|
for(auto vec: loopsForFile){
|
|
|
|
|
|
|
|
head = nullptr;
|
|
|
|
|
|
|
|
head = GetBasicBlocksForLoop(vec, partIR.second);
|
|
|
|
|
|
|
|
if(head != nullptr){
|
|
|
|
|
|
|
|
mapFuncLoops[partIR.first].push_back(head);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*find instructions with read operaton which affects on number iterations for loops*/
|
|
|
|
|
|
|
|
map<pair<string, int>, set<string>> finalInstructions;
|
|
|
|
|
|
|
|
/*for each function*/
|
|
|
|
|
|
|
|
for(const auto lookedFunc: mapFuncLoops){
|
|
|
|
|
|
|
|
/*for each loop in function*/
|
|
|
|
|
|
|
|
for(const auto& vectElem: lookedFunc.second){
|
|
|
|
|
|
|
|
SAPFOR::Instruction* instr = vectElem->getInstructions().front()->getInstruction();
|
|
|
|
|
|
|
|
vector<SAPFOR::BasicBlock*> blocks = vectElem->getPrev();
|
|
|
|
|
|
|
|
vector<SAPFOR::Argument*> argumentsForLook;
|
|
|
|
|
|
|
|
argumentsForLook.push_back(instr->getArg2());
|
|
|
|
|
|
|
|
int blockInd = 0;
|
|
|
|
|
|
|
|
/*run through blocks from first found to first in program taking previous blocks on each step*/
|
|
|
|
|
|
|
|
while(blockInd < blocks.size()){
|
|
|
|
|
|
|
|
if(argumentsForLook.empty()){
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
vector<SAPFOR::IR_Block*> blockInstructions = blocks[blockInd]->getInstructions();
|
|
|
|
|
|
|
|
int numberOfInstructions = blockInstructions.size();
|
|
|
|
|
|
|
|
/*run through all instructions of block from bottom to up*/
|
|
|
|
|
|
|
|
for(int i=numberOfInstructions-1; i>=0; i--){
|
|
|
|
|
|
|
|
SAPFOR::Instruction* cur = blockInstructions[i]->getInstruction();
|
|
|
|
|
|
|
|
/*if instuction type is CALL*/
|
|
|
|
|
|
|
|
if(cur->getOperation() == SAPFOR::CFG_OP::F_CALL){
|
|
|
|
|
|
|
|
/*if it is CALL of READ function*/
|
|
|
|
|
|
|
|
if(cur->getArg1()->getValue() == "_READ"){
|
|
|
|
|
|
|
|
int numParams = std::stoi(cur->getArg2()->getValue());
|
|
|
|
|
|
|
|
bool flag = false;
|
|
|
|
|
|
|
|
/*drop all found arguments from argumentsForLook and add them to answer*/
|
|
|
|
|
|
|
|
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()){
|
|
|
|
|
|
|
|
int delimeterPosition = (*iter)->getValue().find("%");
|
|
|
|
|
|
|
|
finalInstructions[{blockInstructions[j]->getInstruction()->getOperator()->fileName(),
|
|
|
|
|
|
|
|
blockInstructions[j]->getInstruction()->getLine()}].insert((*iter)->getValue().substr(delimeterPosition+1));
|
|
|
|
|
|
|
|
argumentsForLook.erase(iter);
|
|
|
|
|
|
|
|
flag = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
i = i-numParams;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*if it is CALL of another function than find it's arguments and result to change argumentsForLook vector if needed*/
|
|
|
|
|
|
|
|
auto it = find(argumentsForLook.begin(), argumentsForLook.end(), cur->getResult());
|
|
|
|
|
|
|
|
if(cur->getResult() && it != argumentsForLook.end()){
|
|
|
|
|
|
|
|
int dist = distance(argumentsForLook.begin(), it);
|
|
|
|
|
|
|
|
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(argumentsForLook.begin()+dist);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*check only some operation types because other types are useless for this task*/
|
|
|
|
|
|
|
|
if(instructionsToLook.find(cur->getOperation()) == instructionsToLook.end()){
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*check if result of operation in argumentsForLook*/
|
|
|
|
|
|
|
|
auto it = find(argumentsForLook.begin(), argumentsForLook.end(), cur->getResult());
|
|
|
|
|
|
|
|
if(*it != NULL && it != argumentsForLook.end()){
|
|
|
|
|
|
|
|
int dist = distance(argumentsForLook.begin(), it);
|
|
|
|
|
|
|
|
/*add arguments of operation to argumentsForLook vector if they are not there*/
|
|
|
|
|
|
|
|
if(cur->getArg1() != NULL && find(argumentsForLook.begin(), argumentsForLook.end(), cur->getArg1()) == argumentsForLook.end()){
|
|
|
|
|
|
|
|
/*add argument only if it's type is register or variable because constants are not needed here*/
|
|
|
|
|
|
|
|
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()){
|
|
|
|
|
|
|
|
/*add argument only if it's type is register or variable because constants are not needed here*/
|
|
|
|
|
|
|
|
if(goodArgTypes.find(cur->getArg2()->getType()) != goodArgTypes.end()){
|
|
|
|
|
|
|
|
argumentsForLook.push_back(cur->getArg2());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*drop found result of operation from argumentsForLook vector*/
|
|
|
|
|
|
|
|
argumentsForLook.erase(argumentsForLook.begin()+dist);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*add prev blocks to run through*/
|
|
|
|
|
|
|
|
for(auto b: blocks[blockInd]->getPrev()){
|
|
|
|
|
|
|
|
if(find(blocks.begin(), blocks.end(), b) == blocks.end()){
|
|
|
|
|
|
|
|
blocks.push_back(b);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
blockInd++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*next step is next function that means next structures are not needed -> clear them*/
|
|
|
|
|
|
|
|
argumentsForLook.clear();
|
|
|
|
|
|
|
|
blocks.clear();
|
|
|
|
|
|
|
|
/*In the argumentsForLook vector may be arguments of instructions that could not be found in the blocks of current program or function.
|
|
|
|
|
|
|
|
Perhaps I need to look for them in the arguments of the current function, they should be there.
|
|
|
|
|
|
|
|
That means that I will need more complex processing of function calls*/
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*here should be part of founding istructions for allocates!!*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*print found instructions for each function or program*/
|
|
|
|
|
|
|
|
cout << "\n\nFINAL INSTRUCTIONS" << endl;
|
|
|
|
|
|
|
|
for(auto m: finalInstructions){
|
|
|
|
|
|
|
|
cout << "file: " << m.first.first << endl;
|
|
|
|
|
|
|
|
cout << "line: " << m.first.second << endl;
|
|
|
|
|
|
|
|
for(auto v: m.second){
|
|
|
|
|
|
|
|
cout << "\tvar: " << v << endl;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cout << "\n";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return finalInstructions;
|
|
|
|
}
|
|
|
|
}
|