2023-09-14 19:43:13 +03:00
|
|
|
#include <cstdio>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <set>
|
2025-04-15 12:23:32 +03:00
|
|
|
#include <string>
|
2023-09-14 19:43:13 +03:00
|
|
|
#include <vector>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <tuple>
|
|
|
|
|
|
2025-03-05 16:34:32 +03:00
|
|
|
#include "../Utils/SgUtils.h"
|
|
|
|
|
#include "../CFGraph/CFGraph.h"
|
|
|
|
|
#include "CFGraph/IR.h"
|
|
|
|
|
#include "Distribution/Array.h"
|
2023-09-14 19:43:13 +03:00
|
|
|
#include "dvm.h"
|
|
|
|
|
#include "../Utils/errors.h"
|
|
|
|
|
#include "../GraphCall/graph_calls.h"
|
|
|
|
|
#include "../GraphCall/graph_calls_func.h"
|
|
|
|
|
|
2025-03-05 16:34:32 +03:00
|
|
|
#include "libSage++.h"
|
2023-09-14 19:43:13 +03:00
|
|
|
#include "projectParameters.h"
|
2025-04-15 12:23:32 +03:00
|
|
|
#include "domTree.h"
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
2025-04-15 12:23:32 +03:00
|
|
|
tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> stmtToIR(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt)
|
|
|
|
|
{
|
|
|
|
|
SgStatement* cur = stmt;
|
2025-05-01 11:43:35 +03:00
|
|
|
cur->switchToFile();
|
2025-04-15 12:23:32 +03:00
|
|
|
while (cur->variant() != PROC_HEDR && cur->variant() != PROG_HEDR && cur->variant() != FUNC_HEDR)
|
|
|
|
|
cur = cur->controlParent();
|
|
|
|
|
|
|
|
|
|
string funcName = ((SgProcHedrStmt*)cur)->nameWithContains();
|
|
|
|
|
|
|
|
|
|
int stmtID = stmt->id();
|
|
|
|
|
for (const auto& [func, bblocks] : CFGraph)
|
|
|
|
|
{
|
|
|
|
|
if (func->funcName != funcName)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
for (auto basicBlock : bblocks)
|
|
|
|
|
for (auto ins : basicBlock->getInstructions())
|
|
|
|
|
if (stmtID == ins->getInstruction()->getOperator()->id())
|
|
|
|
|
return make_tuple(func, ins->getInstruction(), basicBlock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
return { NULL, NULL, NULL };
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> IRByNumber(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, int num)
|
|
|
|
|
{
|
|
|
|
|
if (num < 0)
|
|
|
|
|
return { NULL, NULL, NULL };
|
2025-05-01 18:52:29 +03:00
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
for (const auto& [func, bblocks] : CFGraph)
|
|
|
|
|
for (auto byBB : bblocks)
|
|
|
|
|
if (byBB->getInstructions().front()->getNumber() <= num && byBB->getInstructions().back()->getNumber() >= num)
|
|
|
|
|
return make_tuple(func, getInstructionByNumber(byBB->getInstructions(), num), byBB);
|
2025-05-01 18:52:29 +03:00
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
return { NULL, NULL, NULL};
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-05 16:34:32 +03:00
|
|
|
template<typename Iterator>
|
2025-05-01 11:43:35 +03:00
|
|
|
void processArgument(set<SAPFOR::Argument*>& worklist,
|
|
|
|
|
SAPFOR::Argument* arg,
|
|
|
|
|
Iterator instr,
|
|
|
|
|
Iterator first_instr)
|
2025-04-15 12:23:32 +03:00
|
|
|
{
|
2025-03-05 16:34:32 +03:00
|
|
|
if (arg == NULL)
|
|
|
|
|
return;
|
2025-04-15 12:23:32 +03:00
|
|
|
if (arg->getType() == SAPFOR::CFG_ARG_TYPE::REG)
|
2025-03-05 16:34:32 +03:00
|
|
|
extract_vars_from_reg(worklist, arg, instr, first_instr);
|
2025-05-01 11:43:35 +03:00
|
|
|
else if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
|
|
|
|
worklist.insert(arg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename Iterator>
|
2025-05-01 11:43:35 +03:00
|
|
|
void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist,
|
|
|
|
|
SAPFOR::Argument* reg,
|
|
|
|
|
Iterator instr,
|
|
|
|
|
Iterator first_instr)
|
2025-04-15 12:23:32 +03:00
|
|
|
{
|
|
|
|
|
for (; instr >= first_instr; instr--)
|
|
|
|
|
{
|
|
|
|
|
if ((*instr)->getInstruction()->getResult() == reg)
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
|
|
|
|
processArgument(worklist, (*instr)->getInstruction()->getArg1(), instr, first_instr);
|
|
|
|
|
processArgument(worklist, (*instr)->getInstruction()->getArg2(), instr, first_instr);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& where_to_add,
|
|
|
|
|
set<SAPFOR::Argument*>& worklist,
|
|
|
|
|
SAPFOR::Instruction* instr,
|
|
|
|
|
SAPFOR::BasicBlock* bblock,
|
|
|
|
|
FuncInfo* cur_func,
|
|
|
|
|
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
while (bblock)
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
auto first_instr = bblock->getInstructions().begin();
|
|
|
|
|
auto cur_instr = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
|
|
|
|
|
return i->getInstruction() == instr;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for (; cur_instr >= bblock->getInstructions().begin(); cur_instr--)
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
auto instr = (*cur_instr)->getInstruction();
|
|
|
|
|
auto result_arg = instr->getResult();
|
|
|
|
|
auto arg1 = instr->getArg1();
|
|
|
|
|
auto arg2 = instr->getArg2();
|
2025-03-05 16:34:32 +03:00
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
if (worklist.count(result_arg))
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
processArgument(worklist, arg1, cur_instr, first_instr);
|
|
|
|
|
processArgument(worklist, arg2, cur_instr, first_instr);
|
|
|
|
|
worklist.erase(result_arg);
|
|
|
|
|
}
|
|
|
|
|
if (instr->getOperation() == SAPFOR::CFG_OP::PARAM && worklist.count(arg1))
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
// skip to F_CALL
|
|
|
|
|
auto f_call_instr = cur_instr;
|
|
|
|
|
while ((*f_call_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL)
|
|
|
|
|
f_call_instr++;
|
|
|
|
|
|
|
|
|
|
if ((*f_call_instr)->getInstruction()->getArg1()->getValue() == "_READ")
|
|
|
|
|
{
|
|
|
|
|
auto stmt_before = (*f_call_instr)->getInstruction()->getOperator();
|
|
|
|
|
auto filename = stmt_before->fileName();
|
|
|
|
|
auto line = stmt_before->lineNumber();
|
|
|
|
|
auto var_name = arg1->getValue().substr(arg1->getValue().find('%') + 1);
|
|
|
|
|
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg1->getValue().c_str(), line, filename);
|
|
|
|
|
auto toAdd = make_tuple(stmt_before, var_name, MODE::AFTER);
|
|
|
|
|
where_to_add.insert(toAdd);
|
|
|
|
|
worklist.erase(arg1);
|
|
|
|
|
}
|
2025-03-05 16:34:32 +03:00
|
|
|
}
|
|
|
|
|
}
|
2025-05-01 11:43:35 +03:00
|
|
|
|
|
|
|
|
const auto& RD = bblock->getRD_In();
|
|
|
|
|
map<SAPFOR::BasicBlock*, SAPFOR::Instruction*> group_by_block;
|
|
|
|
|
for (auto& arg : worklist)
|
|
|
|
|
{
|
|
|
|
|
if (RD.count(arg))
|
|
|
|
|
{
|
|
|
|
|
if (RD.at(arg).size() == 1 && *RD.at(arg).begin() == SAPFOR::CFG_VAL::UNINIT)
|
2025-05-01 18:52:29 +03:00
|
|
|
__spf_print(1, "variable %s has no definition\n", arg->getValue().c_str());
|
2025-05-01 11:43:35 +03:00
|
|
|
else if (RD.at(arg).size() > 1)
|
|
|
|
|
{
|
|
|
|
|
auto stmt_after = (*first_instr)->getInstruction()->getOperator();
|
|
|
|
|
auto filename = stmt_after->fileName();
|
|
|
|
|
auto line = stmt_after->lineNumber();
|
|
|
|
|
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
|
|
|
|
|
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
|
|
|
|
|
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
|
|
|
|
|
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
|
|
|
|
|
where_to_add.insert(toAdd);
|
|
|
|
|
worklist.erase(arg);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
auto instr_num = *RD.at(arg).begin();
|
|
|
|
|
auto [func, instr, bblock] = IRByNumber(fullIR, instr_num);
|
2025-05-01 18:43:51 +03:00
|
|
|
if (cur_func == func && (group_by_block[bblock] == NULL || group_by_block[bblock]->getNumber() < instr_num))
|
2025-05-01 11:43:35 +03:00
|
|
|
group_by_block[bblock] = instr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (bblock && group_by_block.find(bblock) == group_by_block.end())
|
|
|
|
|
bblock = bblock->getIdom();
|
|
|
|
|
if (bblock)
|
|
|
|
|
instr = group_by_block[bblock];
|
2025-03-05 16:34:32 +03:00
|
|
|
}
|
|
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
// other variables are from global scope
|
|
|
|
|
const auto& RD = fullIR.at(cur_func).front()->getRD_In();
|
2025-04-15 12:23:32 +03:00
|
|
|
for (auto& arg : worklist)
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 18:52:29 +03:00
|
|
|
if (arg->isMemGlobal())
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
set<int> found_rd;
|
|
|
|
|
if (RD.count(arg))
|
|
|
|
|
found_rd = RD.at(arg);
|
|
|
|
|
if (found_rd.size() == 0)
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
auto call_instr = call_sites[cur_func].size() ? call_sites[cur_func].front() : NULL;
|
|
|
|
|
while (call_instr && found_rd.size() == 0)
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber());
|
2025-05-01 18:52:29 +03:00
|
|
|
if (call_bblock->getRD_Out().count(arg))
|
2025-05-01 11:43:35 +03:00
|
|
|
found_rd = call_bblock->getRD_Out().at(arg);
|
2025-05-01 18:52:29 +03:00
|
|
|
|
|
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
call_instr = call_sites[call_func].size() ? call_sites[call_func].front() : NULL;
|
2025-03-05 16:34:32 +03:00
|
|
|
}
|
|
|
|
|
}
|
2025-05-01 11:43:35 +03:00
|
|
|
if (found_rd.size() == 1 && *found_rd.begin() == SAPFOR::CFG_VAL::UNINIT)
|
|
|
|
|
{
|
2025-05-01 18:52:29 +03:00
|
|
|
__spf_print(1, "variable %s has no definition\n", arg->getValue().c_str());
|
2025-05-01 11:43:35 +03:00
|
|
|
} else if (found_rd.size() > 1)
|
|
|
|
|
{
|
|
|
|
|
auto first_instr = fullIR.at(cur_func).front()->getInstructions().begin();
|
|
|
|
|
auto stmt_after = (*first_instr)->getInstruction()->getOperator();
|
|
|
|
|
auto filename = stmt_after->fileName();
|
|
|
|
|
auto line = stmt_after->lineNumber();
|
|
|
|
|
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
|
|
|
|
|
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
|
|
|
|
|
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
|
|
|
|
|
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
|
|
|
|
|
where_to_add.insert(toAdd);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
auto instr_num = *found_rd.begin();
|
|
|
|
|
auto [func, instr, bblock] = IRByNumber(fullIR, instr_num);
|
|
|
|
|
set<SAPFOR::Argument*> new_worklist = {arg};
|
2025-05-01 18:52:29 +03:00
|
|
|
|
|
|
|
|
lookup_for_vars(where_to_add, new_worklist, instr, bblock, func, fullIR);
|
2025-05-01 11:43:35 +03:00
|
|
|
}
|
2025-03-05 16:34:32 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
|
|
|
|
|
for (const auto& call_instr : call_sites[cur_func])
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
set<SAPFOR::Argument*> new_worklist;
|
|
|
|
|
auto params_num = cur_func->funcParams.countOfPars;
|
|
|
|
|
|
|
|
|
|
auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber());
|
|
|
|
|
auto first_instr = call_bblock->getInstructions().begin();
|
|
|
|
|
auto cur_instr = std::find_if(first_instr, call_bblock->getInstructions().end(), [call_instr](SAPFOR::IR_Block* i) {
|
|
|
|
|
return i->getInstruction() == call_instr;
|
|
|
|
|
});
|
|
|
|
|
for (auto& arg : worklist)
|
2025-04-15 12:23:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_)
|
|
|
|
|
{
|
|
|
|
|
auto param_num= stoi(arg->getValue().substr(arg->getValue().find('%', arg->getValue().find('%') + 1) + 1));
|
|
|
|
|
auto param_instr = (cur_instr - (params_num - param_num));
|
|
|
|
|
auto param_arg = (*param_instr)->getInstruction()->getArg1();
|
|
|
|
|
processArgument(new_worklist, param_arg, param_instr, first_instr);
|
|
|
|
|
}
|
2025-04-15 12:23:32 +03:00
|
|
|
}
|
2025-05-01 11:43:35 +03:00
|
|
|
lookup_for_vars(where_to_add, new_worklist, call_instr, call_bblock, call_func, fullIR);
|
2025-03-05 16:34:32 +03:00
|
|
|
}
|
2025-05-01 11:43:35 +03:00
|
|
|
|
2025-03-05 16:34:32 +03:00
|
|
|
}
|
|
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
void handle_single_allocate(std::set<tuple<SgStatement*, std::string, MODE>>& where_to_add,
|
|
|
|
|
SgStatement* alloc_statement,
|
|
|
|
|
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
|
2025-04-15 12:23:32 +03:00
|
|
|
{
|
|
|
|
|
auto [func, instr, bblock] = stmtToIR(fullIR, alloc_statement);
|
|
|
|
|
|
2025-03-05 16:34:32 +03:00
|
|
|
auto first_instr = bblock->getInstructions().begin();
|
|
|
|
|
auto cur_instr = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
|
|
|
|
|
return i->getInstruction() == instr;
|
|
|
|
|
});
|
|
|
|
|
auto alloc_instr = cur_instr;
|
|
|
|
|
|
|
|
|
|
// skip to F_CALL _ALLOC n
|
|
|
|
|
while ((*alloc_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL ||
|
2025-04-15 12:23:32 +03:00
|
|
|
(*alloc_instr)->getInstruction()->getArg1()->getValue() != "_ALLOC")
|
2025-03-05 16:34:32 +03:00
|
|
|
alloc_instr++;
|
2025-05-01 18:52:29 +03:00
|
|
|
|
2025-03-05 16:34:32 +03:00
|
|
|
|
|
|
|
|
auto arrays_num = stoi((*alloc_instr)->getInstruction()->getArg2()->getValue());
|
|
|
|
|
|
|
|
|
|
set<SAPFOR::Argument*> worklist;
|
|
|
|
|
for (int i = 0; i < arrays_num; i++)
|
|
|
|
|
{
|
|
|
|
|
auto param_instr = --alloc_instr;
|
|
|
|
|
auto param_reg = (*param_instr)->getInstruction()->getArg1();
|
|
|
|
|
|
|
|
|
|
while ((*param_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::LOAD ||
|
|
|
|
|
(*param_instr)->getInstruction()->getResult() != param_reg)
|
|
|
|
|
param_instr--;
|
2025-05-01 18:52:29 +03:00
|
|
|
|
2025-03-05 16:34:32 +03:00
|
|
|
|
|
|
|
|
auto dimensions_num = stoi((*param_instr)->getInstruction()->getArg2()->getValue());
|
2025-04-15 12:23:32 +03:00
|
|
|
|
2025-03-05 16:34:32 +03:00
|
|
|
for (int j = 0; j < dimensions_num; j++)
|
|
|
|
|
{
|
|
|
|
|
auto ref_instr = --param_instr;
|
2025-05-01 11:43:35 +03:00
|
|
|
if ((*ref_instr)->getInstruction()->getOperation() == SAPFOR::CFG_OP::RANGE)
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
vector<SAPFOR::Argument*> range_args = {(*ref_instr)->getInstruction()->getArg1(),
|
|
|
|
|
(*ref_instr)->getInstruction()->getArg2(),
|
|
|
|
|
(*ref_instr)->getInstruction()->getResult()};
|
2025-05-01 18:52:29 +03:00
|
|
|
for (auto& arg : range_args)
|
2025-05-01 11:43:35 +03:00
|
|
|
processArgument(worklist, arg, ref_instr, first_instr);
|
2025-05-01 18:52:29 +03:00
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
} else
|
2025-03-05 16:34:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
auto arg = (*ref_instr)->getInstruction()->getArg1();
|
2025-05-01 18:52:29 +03:00
|
|
|
processArgument(worklist, arg, ref_instr, first_instr);
|
2025-03-05 16:34:32 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-01 11:43:35 +03:00
|
|
|
lookup_for_vars(where_to_add,worklist, instr, bblock, func, fullIR);
|
2025-03-05 16:34:32 +03:00
|
|
|
}
|
|
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
|
|
|
|
|
void handle_single_loop(std::set<tuple<SgStatement*, std::string, MODE>>& where_to_add,
|
|
|
|
|
SgStatement* loop_stmt,
|
|
|
|
|
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
|
2025-04-15 12:23:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
auto [func, instr, bblock] = stmtToIR(fullIR, loop_stmt);
|
2025-04-15 12:23:32 +03:00
|
|
|
|
|
|
|
|
auto cur_instr = bblock->getInstructions().end() - 1;
|
|
|
|
|
|
|
|
|
|
set<SAPFOR::Argument*> worklist;
|
|
|
|
|
extract_vars_from_reg(worklist, (*cur_instr)->getInstruction()->getResult(), cur_instr, bblock->getInstructions().begin());
|
|
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
lookup_for_vars(where_to_add, worklist, (*cur_instr)->getInstruction(), bblock, func, fullIR);
|
2025-04-15 12:23:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
findParameters(ResultSet& foundParameters,
|
|
|
|
|
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
|
2025-03-05 16:34:32 +03:00
|
|
|
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
|
2023-09-14 19:43:13 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
set<tuple<SgStatement*, string, MODE>> where_to_add;
|
2025-04-15 12:23:32 +03:00
|
|
|
|
|
|
|
|
map<string, FuncInfo*> name_to_func;
|
|
|
|
|
for (const auto& [func, _] : fullIR)
|
|
|
|
|
name_to_func[func->funcName] = func;
|
|
|
|
|
|
|
|
|
|
for (auto& [func, bblocks] : fullIR)
|
|
|
|
|
{
|
|
|
|
|
for (const auto& block : bblocks)
|
|
|
|
|
for (const auto& ir_block : block->getInstructions())
|
|
|
|
|
{
|
|
|
|
|
auto instr = ir_block->getInstruction();
|
|
|
|
|
if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
|
|
|
|
|
{
|
|
|
|
|
auto func_name = instr->getArg1()->getValue();
|
|
|
|
|
auto func_info = name_to_func.find(func_name);
|
|
|
|
|
|
|
|
|
|
if (func_info != name_to_func.end())
|
|
|
|
|
call_sites[func_info->second].push_back(instr);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-01 18:52:29 +03:00
|
|
|
|
2025-04-15 12:23:32 +03:00
|
|
|
|
|
|
|
|
SAPFOR::buildDominatorTreeLT(bblocks);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-05 16:34:32 +03:00
|
|
|
std::set<SgStatement*> alloc_statements;
|
2025-05-01 11:43:35 +03:00
|
|
|
for (const auto& [func, bblocks] : fullIR)
|
|
|
|
|
for (const auto& block : bblocks)
|
|
|
|
|
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
|
|
|
|
|
{
|
|
|
|
|
auto op = (*instr)->getInstruction()->getOperator();
|
|
|
|
|
if (op && op->variant() == ALLOCATE_STMT) {
|
|
|
|
|
alloc_statements.insert(op);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-04-15 12:23:32 +03:00
|
|
|
|
|
|
|
|
set<SgStatement*> for_statements;
|
|
|
|
|
// Find all FOR statements in the program
|
|
|
|
|
for (const auto& [func, bblocks] : fullIR)
|
|
|
|
|
for (const auto& block : bblocks)
|
|
|
|
|
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
|
|
|
|
|
{
|
|
|
|
|
auto op = (*instr)->getInstruction()->getOperator();
|
2025-05-01 18:52:29 +03:00
|
|
|
if (op && op->variant() == FOR_NODE)
|
2025-04-15 12:23:32 +03:00
|
|
|
for_statements.insert(op);
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-01 18:52:29 +03:00
|
|
|
for (const auto& alloc_statement : alloc_statements)
|
|
|
|
|
handle_single_allocate(where_to_add, alloc_statement, fullIR);
|
|
|
|
|
|
2025-04-15 12:23:32 +03:00
|
|
|
for (const auto& stmt : for_statements)
|
|
|
|
|
handle_single_loop(where_to_add, stmt, fullIR);
|
|
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
for (const auto& [stmt_before, var_name, mode] : where_to_add)
|
2025-04-15 12:23:32 +03:00
|
|
|
{
|
2025-05-01 11:43:35 +03:00
|
|
|
stmt_before->switchToFile();
|
2025-05-01 18:52:29 +03:00
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
SgVariableSymb* var_symb = new SgVariableSymb(var_name.c_str());
|
|
|
|
|
SgVarRefExp* var = new SgVarRefExp(var_symb);
|
|
|
|
|
SgValueExp* zero = new SgValueExp(1337);
|
|
|
|
|
SgExprListExp* ex = new SgExprListExp();
|
2025-05-01 18:52:29 +03:00
|
|
|
auto assgn_op = new SgExpression(ASSGN_OP, var, zero);
|
|
|
|
|
ex->setLhs(assgn_op);
|
|
|
|
|
|
2025-05-01 18:43:51 +03:00
|
|
|
SgExpression* parameter_op = new SgExpression(SPF_PARAMETER_OP, ex);
|
2025-05-01 18:52:29 +03:00
|
|
|
auto dir_list = new SgExprListExp();
|
|
|
|
|
dir_list->setLhs(parameter_op);
|
|
|
|
|
SgStatement* toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, dir_list, NULL, NULL);
|
|
|
|
|
|
2025-05-01 11:43:35 +03:00
|
|
|
toAdd->setlineNumber(stmt_before->lineNumber());
|
|
|
|
|
toAdd->setLocalLineNumber(stmt_before->lineNumber());
|
|
|
|
|
toAdd->setFileId(stmt_before->getFileId());
|
|
|
|
|
toAdd->setProject(stmt_before->getProject());
|
2025-05-01 18:52:29 +03:00
|
|
|
|
2025-05-01 18:43:51 +03:00
|
|
|
if (mode == MODE::AFTER)
|
|
|
|
|
stmt_before->insertStmtAfter(*toAdd, *stmt_before->controlParent());
|
|
|
|
|
else
|
|
|
|
|
stmt_before->insertStmtBefore(*toAdd, *stmt_before->controlParent());
|
2025-04-15 12:23:32 +03:00
|
|
|
|
|
|
|
|
foundParameters.insert(make_tuple(stmt_before->fileName(), stmt_before->lineNumber(), var_name));
|
2025-03-05 16:34:32 +03:00
|
|
|
}
|
|
|
|
|
}
|