trivial case for local variables only
This commit is contained in:
@@ -1,8 +1,6 @@
|
|||||||
#include "../Utils/leak_detector.h"
|
#include <cassert>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstring>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@@ -11,23 +9,202 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
#include "../Utils/SgUtils.h"
|
||||||
|
#include "../CFGraph/CFGraph.h"
|
||||||
|
#include "CFGraph/IR.h"
|
||||||
|
#include "Distribution/Array.h"
|
||||||
#include "dvm.h"
|
#include "dvm.h"
|
||||||
#include "../Utils/errors.h"
|
#include "../Utils/errors.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 "libSage++.h"
|
||||||
#include "projectParameters.h"
|
#include "projectParameters.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
map< pair<string, int>, set<string>>
|
template<typename Iterator>
|
||||||
findParameters(const map<string, vector<DefUseList>> &defUseByFunctions,
|
static void processArgument(set<SAPFOR::Argument*>& worklist, SAPFOR::Argument* arg, Iterator instr, Iterator first_instr) {
|
||||||
const map<string, CommonBlock*> &commonBlocks,
|
if (arg == NULL)
|
||||||
const map<string, vector<FuncInfo*>> &allFuncInfo)
|
return;
|
||||||
|
if (arg->getType() == SAPFOR::CFG_ARG_TYPE::REG)
|
||||||
|
extract_vars_from_reg(worklist, arg, instr, first_instr);
|
||||||
|
else if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR && arg->getMemType() == SAPFOR::CFG_MEM_TYPE::LOCAL_)
|
||||||
|
{
|
||||||
|
std::cout << "worklist add: " << arg->getValue() << std::endl; //DEBUG PRINT
|
||||||
|
worklist.insert(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist, SAPFOR::Argument* reg, Iterator instr, Iterator first_instr) {
|
||||||
|
for (; instr >= first_instr; instr--) {
|
||||||
|
if ((*instr)->getInstruction()->getResult() == reg)
|
||||||
|
{
|
||||||
|
processArgument(worklist, (*instr)->getInstruction()->getArg1(), instr, first_instr);
|
||||||
|
processArgument(worklist, (*instr)->getInstruction()->getArg2(), instr, first_instr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lookup_for_vars(ResultSet& result_set,
|
||||||
|
set<SAPFOR::Argument*>& worklist,
|
||||||
|
SAPFOR::Instruction* instr,
|
||||||
|
SAPFOR::BasicBlock* bblock,
|
||||||
|
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
|
||||||
{
|
{
|
||||||
map< pair<string, int>, set<string>> foundParameters;
|
std::cout << "Lookup in bblock no." << bblock->getNumber() << std::endl; //DEBUG PRINT
|
||||||
|
|
||||||
|
auto first_instr = bblock->getInstructions().begin();
|
||||||
return foundParameters;
|
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--)
|
||||||
|
{
|
||||||
|
auto instr = (*cur_instr)->getInstruction();
|
||||||
|
auto result_arg = instr->getResult();
|
||||||
|
auto arg1 = instr->getArg1();
|
||||||
|
auto arg2 = instr->getArg2();
|
||||||
|
|
||||||
|
if (worklist.count(result_arg))
|
||||||
|
{
|
||||||
|
processArgument(worklist, arg1, cur_instr, first_instr);
|
||||||
|
processArgument(worklist, arg2, cur_instr, first_instr);
|
||||||
|
std::cout << "worklist erase: " << result_arg->getValue() << std::endl; //DEBUG PRINT
|
||||||
|
worklist.erase(result_arg);
|
||||||
|
}
|
||||||
|
if (instr->getOperation() == SAPFOR::CFG_OP::PARAM && worklist.count(arg1))
|
||||||
|
{
|
||||||
|
// 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 filename = (*f_call_instr)->getInstruction()->getOperator()->fileName();
|
||||||
|
auto line = (*f_call_instr)->getInstruction()->getOperator()->lineNumber();
|
||||||
|
__spf_print(1,"Please specify value of variable %s on line %d of file %s", arg1->getValue().c_str(), line, filename);
|
||||||
|
result_set.insert(make_tuple(filename, line, arg1->getValue()));
|
||||||
|
|
||||||
|
std::cout << "worklist erase: " << arg1->getValue() << std::endl; //DEBUG PRINT
|
||||||
|
worklist.erase(arg1);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
//check if variable is modified in called function
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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() == 0)
|
||||||
|
__spf_print(1, "variable %s has no definition", arg->getValue().c_str());
|
||||||
|
else if (RD.at(arg).size() > 1)
|
||||||
|
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible", arg->getValue().c_str());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const auto& instr_num : RD.at(arg))
|
||||||
|
{
|
||||||
|
auto [instr, bblock] = getInstructionAndBlockByNumber(fullIR, instr_num);
|
||||||
|
if (group_by_block[bblock] == NULL || group_by_block[bblock]->getNumber() < instr_num)
|
||||||
|
group_by_block[bblock] = instr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& [bblock, instr] : group_by_block)
|
||||||
|
{
|
||||||
|
lookup_for_vars(result_set, worklist, instr, bblock, fullIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_single_allocate(ResultSet& result_set,
|
||||||
|
SAPFOR::Instruction* instr,
|
||||||
|
SAPFOR::BasicBlock* bblock,
|
||||||
|
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
|
||||||
|
{
|
||||||
|
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 ||
|
||||||
|
(*alloc_instr)->getInstruction()->getArg1()->getValue() != "_ALLOC")
|
||||||
|
{
|
||||||
|
alloc_instr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto arrays_num = stoi((*alloc_instr)->getInstruction()->getArg2()->getValue());
|
||||||
|
std::cout << "arrays_num: " << arrays_num << std::endl; //DEBUG PRINT
|
||||||
|
|
||||||
|
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--;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dimensions_num = stoi((*param_instr)->getInstruction()->getArg2()->getValue());
|
||||||
|
|
||||||
|
for (int j = 0; j < dimensions_num; j++)
|
||||||
|
{
|
||||||
|
auto ref_instr = --param_instr;
|
||||||
|
|
||||||
|
auto arg = (*ref_instr)->getInstruction()->getArg1();
|
||||||
|
if (arg->getType() == SAPFOR::CFG_ARG_TYPE::REG)
|
||||||
|
{
|
||||||
|
extract_vars_from_reg(worklist, arg, ref_instr, first_instr);
|
||||||
|
}
|
||||||
|
else if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR && arg->getMemType() == SAPFOR::CFG_MEM_TYPE::LOCAL_)
|
||||||
|
{
|
||||||
|
std::cout << "worklist add: " << arg->getValue() << std::endl; //DEBUG PRINT
|
||||||
|
worklist.insert(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lookup_for_vars(result_set,worklist, instr, bblock, fullIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultSet
|
||||||
|
findParameters(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
|
||||||
|
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
|
||||||
|
{
|
||||||
|
ResultSet foundParameters;
|
||||||
|
std::set<SgStatement*> alloc_statements;
|
||||||
|
for (const auto& elem : declaredArrays)
|
||||||
|
{
|
||||||
|
const auto& array = elem.second.first;
|
||||||
|
assert(array->GetLocation().first == Distribution::arrayLocation::l_LOCAL); // v0.1
|
||||||
|
|
||||||
|
SgSymbol* arraySymb = array->GetDeclSymbol()->GetOriginal();
|
||||||
|
SgStatement* decl = declaratedInStmt(arraySymb);
|
||||||
|
for (auto &stmt : getAttributes<SgStatement*, SgStatement*>(decl, set<int>{ ALLOCATE_STMT }))
|
||||||
|
{
|
||||||
|
alloc_statements.insert(stmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& alloc_statement : alloc_statements)
|
||||||
|
{
|
||||||
|
auto [instr, bblock] = getInstructionAndBlockByStatement(fullIR, alloc_statement);
|
||||||
|
ResultSet result_set;
|
||||||
|
handle_single_allocate(result_set, instr, bblock, fullIR);
|
||||||
|
}
|
||||||
|
return foundParameters;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,24 @@
|
|||||||
#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 <map>
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
using ResultSet = std::set<std::tuple<std::string, int, std::string>>;
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
void extract_vars_from_reg(std::set<SAPFOR::Argument*>& worklist, SAPFOR::Argument* reg, Iterator instr, Iterator first_instr);
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
static void processArgument(std::set<SAPFOR::Argument*>& worklist, SAPFOR::Argument* arg, Iterator instr, Iterator first_instr);
|
||||||
|
|
||||||
|
static void lookup_for_vars(ResultSet& result_set,
|
||||||
|
std::set<SAPFOR::Argument*>& worklist,
|
||||||
|
SAPFOR::Instruction* instr,
|
||||||
|
SAPFOR::BasicBlock* bblock,
|
||||||
|
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR);
|
||||||
|
|
||||||
|
ResultSet
|
||||||
|
findParameters(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
|
||||||
|
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);
|
||||||
|
|||||||
@@ -1881,7 +1881,11 @@ 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);
|
{
|
||||||
|
performRDSubst(fullIR, commonBlocks, &project);
|
||||||
|
parametersOfProject = findParameters(fullIR, declaredArrays);
|
||||||
|
performRDSubst(fullIR, commonBlocks, &project);
|
||||||
|
}
|
||||||
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));
|
||||||
@@ -2361,6 +2365,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
|
|||||||
case FIX_COMMON_BLOCKS:
|
case FIX_COMMON_BLOCKS:
|
||||||
case TEST_PASS:
|
case TEST_PASS:
|
||||||
case SET_IMPLICIT_NONE:
|
case SET_IMPLICIT_NONE:
|
||||||
|
case FIND_PARAMETERS:
|
||||||
runAnalysis(*project, curr_regime, false);
|
runAnalysis(*project, curr_regime, false);
|
||||||
case SUBST_EXPR_RD_AND_UNPARSE:
|
case SUBST_EXPR_RD_AND_UNPARSE:
|
||||||
case SUBST_EXPR_AND_UNPARSE:
|
case SUBST_EXPR_AND_UNPARSE:
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ std::map<int, UserFiles> filesInfo; // information about open,close,write and re
|
|||||||
//
|
//
|
||||||
|
|
||||||
//for FIND_PARAMETERS
|
//for FIND_PARAMETERS
|
||||||
std::map< std::pair<std::string, int>, std::set<std::string>> parametersOfProject; // [file, line] -> set[vars]
|
std::set<std::tuple<std::string, int, std::string>> parametersOfProject; // [file, line, varname]
|
||||||
//
|
//
|
||||||
|
|
||||||
//for GET_MIN_MAX_BLOCK_DIST
|
//for GET_MIN_MAX_BLOCK_DIST
|
||||||
|
|||||||
52
tests/sapfor/parameter/dynamic_array_maximum.f90
Normal file
52
tests/sapfor/parameter/dynamic_array_maximum.f90
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
program dynamic_array_maximum_3d
|
||||||
|
implicit none
|
||||||
|
integer :: n1, n2, n3, n4 , k, i, j, l, a
|
||||||
|
integer :: sum3
|
||||||
|
real :: max_element
|
||||||
|
real, allocatable :: array(:,:,:), array2(:,:,:), array3(:,:,:)
|
||||||
|
|
||||||
|
write(*, *) "Enter 3 integers"
|
||||||
|
read(*, *) n, m, k
|
||||||
|
m = 100
|
||||||
|
|
||||||
|
if (1 .eq. 1) then
|
||||||
|
a = 3
|
||||||
|
else if (2 .eq. 1) then
|
||||||
|
a = 4
|
||||||
|
endif
|
||||||
|
|
||||||
|
m = m + 1
|
||||||
|
k = m * 1000 + n * 10
|
||||||
|
|
||||||
|
allocate(array(n, m + n, k + m + n), &
|
||||||
|
&array2(k, m + n, k), &
|
||||||
|
&array3(k, m, k + n))
|
||||||
|
|
||||||
|
call random_seed()
|
||||||
|
do i = 1, n1
|
||||||
|
do j = 1, m * n1
|
||||||
|
do l = 1, k * m * n1
|
||||||
|
call random_number(array(i,j,l))
|
||||||
|
array(i,j,l) = int(array(i,j,l) * 100)
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
|
||||||
|
max_element = array(1,1,1)
|
||||||
|
do i = 1, n1
|
||||||
|
do j = 1, m
|
||||||
|
do l = 1, k
|
||||||
|
max_element = MAX(array(i,j,l), max_element)
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
deallocate(array, array2, array3)
|
||||||
|
write(*, *) max_element
|
||||||
|
end program dynamic_array_maximum_3d
|
||||||
|
|
||||||
|
! function sum3(x, y, z)
|
||||||
|
! implicit none
|
||||||
|
! integer :: x, y, z
|
||||||
|
! integer :: sum3
|
||||||
|
! sum3 = x + y + z
|
||||||
|
! end function sum3
|
||||||
Reference in New Issue
Block a user