WIP: add dominators logic

This commit is contained in:
2024-11-14 15:28:51 +03:00
66 changed files with 1453 additions and 2747 deletions

View File

@@ -240,8 +240,6 @@ set(DIRA _src/DirectiveProcessing/directive_analyzer.cpp
_src/DirectiveProcessing/directive_creator.cpp
_src/DirectiveProcessing/directive_creator_base.cpp
_src/DirectiveProcessing/directive_creator.h
_src/DirectiveProcessing/directive_creator_base_nodist.cpp
_src/DirectiveProcessing/directive_creator_nodist.h
_src/DirectiveProcessing/directive_parser.cpp
_src/DirectiveProcessing/directive_parser.h
_src/DirectiveProcessing/directive_omp_parser.cpp
@@ -266,11 +264,8 @@ set(DISTR _src/Distribution/Array.cpp
_src/Distribution/Distribution.h
_src/Distribution/DvmhDirective.cpp
_src/Distribution/DvmhDirective.h
_src/Distribution/DvmhDirective_nodist.cpp
_src/Distribution/DvmhDirective_internal.h
_src/Distribution/DvmhDirective_func.h
_src/Distribution/DvmhDirectiveBase.cpp
_src/Distribution/DvmhDirectiveBase_nodist.cpp
_src/Distribution/DvmhDirectiveBase.h
_src/Distribution/GraphCSR.cpp
_src/Distribution/GraphCSR.h)
@@ -304,9 +299,7 @@ set(EXPR_TRANSFORM _src/ExpressionTransform/control_flow_graph_part.cpp
set(GR_CALL _src/GraphCall/graph_calls.cpp
_src/GraphCall/graph_calls.h
_src/GraphCall/graph_calls_base.cpp
_src/GraphCall/graph_calls_func.h
_src/GraphCall/select_array_conf.cpp
_src/GraphCall/select_array_conf.h)
_src/GraphCall/graph_calls_func.h)
set(GR_LOOP _src/GraphLoop/graph_loops_base.cpp
_src/GraphLoop/graph_loops.cpp
@@ -319,9 +312,6 @@ set(INLINER _src/Inliner/inliner.cpp
set(LOOP_ANALYZER _src/LoopAnalyzer/allocations_prepoc.cpp
_src/LoopAnalyzer/dep_analyzer.cpp
_src/LoopAnalyzer/loop_analyzer.cpp
_src/LoopAnalyzer/loop_analyzer_nodist.cpp
_src/LoopAnalyzer/loop_analyzer_nodist.h
_src/LoopAnalyzer/loop_analyzer_internal.h
_src/LoopAnalyzer/loop_analyzer.h)
set(RENAME_SYMBOLS _src/RenameSymbols/rename_symbols.cpp

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
jac.f.dep

View File

@@ -0,0 +1,32 @@
program do_while_loop
implicit none
integer :: i, j, n
n = 5
i = 1
print *, 'DO WHILE loop:'
do while (i <= n)
print *, 'i = ', i
i = i + 1
end do
print *, 'Nested DO loop:'
do i = 1, n
do j = 1, n
print *, 'i = ', i, ', j = ', j
end do
end do
print *, 'Implicit loop with GOTO:'
i = 1
25 if (i > n) goto 32
print *, 'i = ', i
i = i + 1
goto 25
32 continue
end program do_while_loop

Binary file not shown.

View File

@@ -395,7 +395,7 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector<IR_Block*>&
if (ex)
{
const int var = ex->variant();
if ((var == VAR_REF || var == CONST_REF || var == LABEL_REF) && !ex->lhs() && !ex->rhs()) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ((var == VAR_REF || var == CONST_REF || var == LABEL_REF) && !ex->lhs() && !ex->rhs()) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
if (var == CONST_REF)
{
@@ -1572,7 +1572,7 @@ vector<IR_Block*> buildIR(SgStatement* function, const FuncInfo* func, const vec
else
findReturn(0, blocks.size(), blocks, blocks.back()->getNumber());
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> GOTO <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> GOTO <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (int z = 0; z < blocks.size(); ++z)
{
auto op = blocks[z]->getInstruction()->getOperation();
@@ -1592,7 +1592,7 @@ vector<IR_Block*> buildIR(SgStatement* function, const FuncInfo* func, const vec
blocks[z]->setJump(it->second);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
arg->setValue(to_string(it->second->getNumber()));
arg->setType(CFG_ARG_TYPE::INSTR);
}

View File

@@ -0,0 +1,258 @@
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <set>
#include "../Utils/SgUtils.h"
#include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
#include "../ExpressionTransform/expr_transform.h"
#include "dvm.h"
#include "IR.h"
#include "CFGraph.h"
using namespace std;
using namespace SAPFOR;
typedef SAPFOR::BasicBlock BBlock;
static void printBlock(BBlock* block) {
std::cout << "block - " << block->getNumber() << endl;
cout << "next -";
for (auto i : block->getNext())
{
cout << " " << i->getNumber();
}
/*cout << endl << "prev -";
for (auto i : block->getPrev())
{
cout << " " << i->getNumber();
}
cout << endl;
for (auto i : block->getInstructions())
{
cout << i->getNumber() << " " << i->getInstruction()->dump() << endl;
}*/
cout << endl;
}
template <typename T>
static bool compareVectors(const std::vector<T>* vec1, const std::vector<T>* vec2) {
if (vec1 == vec2) {
return true;
}
if (!vec1 || !vec2) {
return false;
}
std::vector<T> sortedVec1 = *vec1;
std::vector<T> sortedVec2 = *vec2;
std::sort(sortedVec1.begin(), sortedVec1.end());
std::sort(sortedVec2.begin(), sortedVec2.end());
return sortedVec1 == sortedVec2;
}
template <typename T>
static std::vector<T>* getCommonElements(const std::vector<std::vector<T>>* vectors) {
if (!vectors || vectors->empty()) {
return new std::vector<T>(); // Return an empty vector if input is null or empty
}
// Start with the first vector
std::vector<T>* commonElements = new std::vector<T>((*vectors)[0]);
for (size_t i = 1; i < vectors->size(); ++i) {
std::vector<T> tempCommon;
// Sort the current vector and common result for intersection
std::vector<T> sortedVec = (*vectors)[i];
std::sort(commonElements->begin(), commonElements->end());
std::sort(sortedVec.begin(), sortedVec.end());
// Find the intersection
std::set_intersection(
commonElements->begin(), commonElements->end(),
sortedVec.begin(), sortedVec.end(),
std::back_inserter(tempCommon)
);
// Update common result
*commonElements = tempCommon;
// If no common elements left, break early
if (commonElements->empty()) {
break;
}
}
return commonElements;
}
static map<BBlock*, vector<BBlock*>> findDominators(vector<BBlock*> blocks) {
map<BBlock*, vector<BBlock*>> result;
bool changed = true;
while (changed) {
changed = false;
for (auto currentBlock : blocks) {
auto pred = currentBlock->getPrev();
auto prevDominators = new vector<vector<BBlock*>>();
for (auto predBlock : pred)
prevDominators->push_back(result.find(predBlock) != result.end() ? result[predBlock] : blocks);
auto currentBlockResult = getCommonElements(prevDominators);
currentBlockResult->push_back(currentBlock);
if (result.find(currentBlock) == result.end() || !compareVectors(currentBlockResult, &result[currentBlock])) {
result[currentBlock] = *currentBlockResult;
changed = true;
}
}
}
return result;
}
static void RenumberBlocks(BBlock* current, int* n, map<int, int>* res, set<BBlock*>* visited) {
if (visited->find(current) != visited->end()) {
return;
}
visited->insert(current);
std::vector<BBlock*> nextBlocks = current->getNext();
std::sort(nextBlocks.begin(), nextBlocks.end(), [](BBlock* a, BBlock* b) {
return a->getInstructions()[0]->getInstruction()->getOperator()->lineNumber() > b->getInstructions()[0]->getInstruction()->getOperator()->lineNumber();
});
for (auto i : nextBlocks) {
RenumberBlocks(i, n, res, visited);
}
(*res)[current->getNumber()] = *n;
*n -= 1;
}
static map<BBlock*, vector<BBlock*>> findDominatorBorders(vector<BBlock*>& blocks, map<BBlock*, BBlock*>& iDominators) {
map<BBlock*, vector<BBlock*>> result;
for (auto block : blocks) {
result[block] = *(new vector<BBlock*>());
}
for (auto block : blocks) {
if (block->getPrev().size() > 1) {
for (auto prev : block->getPrev()) {
auto tmpBlock = prev;
while (tmpBlock != iDominators[block]) {
if (tmpBlock->getNumber() == 8 && block->getNumber() == 8) {
cout << "okjdwebnfklwedhfgklhwdgklvhvbklwdfhgvlhbwsdfgvlikbdflwkgb" << endl << prev->getNumber() << endl;
}
result[tmpBlock].push_back(block);
tmpBlock = iDominators[tmpBlock];
}
}
}
}
return result;
}
map<FuncInfo*, vector<BBlock*>> buildIRSSAForm(map<FuncInfo*, vector<BBlock*>> fullIR) {
map<FuncInfo*, vector<BBlock*>> result;
for (auto item : fullIR) {
auto funcinfo = item.first;
auto funcIR = item.second;
auto funcResult = new vector<BBlock*>();
for (auto i : funcIR) {
printBlock(i);
}
auto dominators = findDominators(funcIR);
cout << endl << endl << endl << "DOMINATORS" << endl << endl << endl;
for (auto i : dominators) {
cout << "block - " << i.first->getNumber() << endl;
for (auto j : i.second) {
cout << "dominators - " << j->getNumber() << endl;
}
cout << endl;
}
map<int, int> numbers;
int n = funcIR.size() - 1;
RenumberBlocks(funcIR[0], &n, &numbers, new set<BBlock*>);
for (auto i : numbers) {
cout << i.first << " " << i.second << endl;
}
map<BBlock*, BBlock*> iDominators;
for (const auto& domPair : dominators) {
BBlock* block = domPair.first;
const std::vector<BBlock*>& domBlocks = domPair.second;
std::vector<int> domNumbers;
for (BBlock* domBlock : domBlocks) {
int number = numbers[domBlock->getNumber()];
domNumbers.push_back(number);
}
std::sort(domNumbers.begin(), domNumbers.end());
if (domNumbers.size() < 2) {
continue;
}
int secondLargestNumber = *(std::prev(domNumbers.end(), 2));
for (BBlock* domBlock : domBlocks) {
if (numbers[domBlock->getNumber()] == secondLargestNumber) {
iDominators[block] = domBlock;
break;
}
}
}
for (auto i : iDominators) {
cout << "block - " << i.first->getNumber() << endl;
cout << "Idominators - " << i.second->getNumber() << endl;
cout << endl;
}
auto dominatorBorders = findDominatorBorders(funcIR, iDominators);
for (auto i : dominatorBorders) {
cout << "block - " << i.first->getNumber() << endl;
for (auto j : i.second) {
cout << "border - " << j->getNumber() << endl;
}
cout << endl;
}
result[funcinfo] = *funcResult;
}
return result;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "CFGraph.h"
#include "IR.h"
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>> buildIRSSAForm(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>> fullIR);

View File

@@ -45,7 +45,7 @@ using std::get;
using std::string;
using std::wstring;
extern int mpiProgram;
extern int sharedMemoryParallelization;
static vector<pair<string, vector<Expression*>>>
groupRealignsDirs(const vector<pair<string, vector<Expression*>>>& toRealign)
@@ -453,7 +453,7 @@ void createParallelDirs(File *file,
auto& tmp = dataDirectives.distrRules;
vector<pair<DIST::Array*, const DistrVariant*>> currentVar;
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
{
for (int z1 = 0; z1 < currentVariant.size(); ++z1)
currentVar.push_back(make_pair(tmp[z1].first, &tmp[z1].second[currentVariant[z1]]));

View File

@@ -91,26 +91,17 @@ static LoopGraph* createDirectiveForLoop(LoopGraph *currentLoop, MapToArray &mai
}
currentLoop->directive = directive;
for (auto& read : currentLoop->readOpsArray)
if(!sharedMemoryParallelization)
{
const string shortName = read->GetName();
const string orignName = read->GetShortName();
pair<string, string> key = make_pair(orignName, shortName);
bool found = false;
for (int i = 0; i < directive->shadowRenew.size(); ++i)
for (auto& read : currentLoop->readOpsArray)
{
if (directive->shadowRenew[i].first == key)
const string shortName = read->GetName();
const string orignName = read->GetShortName();
pair<string, string> key = make_pair(orignName, shortName);
bool found = false;
for (int i = 0; i < directive->shadowRenew.size(); ++i)
{
found = true;
break;
}
}
if (found == false)
{
for (int i = 0; i < directive->across.size(); ++i)
{
if (directive->across[i].first == key)
if (directive->shadowRenew[i].first == key)
{
found = true;
break;
@@ -119,11 +110,23 @@ static LoopGraph* createDirectiveForLoop(LoopGraph *currentLoop, MapToArray &mai
if (found == false)
{
directive->shadowRenew.push_back(make_pair(key, vector<pair<int, int>>()));
for (int i = 0; i < directive->across.size(); ++i)
{
if (directive->across[i].first == key)
{
found = true;
break;
}
}
const DIST::Array *arrayRef = read;
for (int i = 0; i < arrayRef->GetDimSize(); ++i)
directive->shadowRenew.back().second.push_back(make_pair(0, 0));
if (found == false)
{
directive->shadowRenew.push_back(make_pair(key, vector<pair<int, int>>()));
const DIST::Array *arrayRef = read;
for (int i = 0; i < arrayRef->GetDimSize(); ++i)
directive->shadowRenew.back().second.push_back(make_pair(0, 0));
}
}
}
}
@@ -387,6 +390,9 @@ bool checkForConflict(const map<DIST::Array*, ArrayInfo*> &currAccesses,
for (auto &itArray : currAccesses)
{
if(!itArray.first)
continue; // skip fictitious array access in free loop
const ArrayInfo &currInfo = *(itArray.second);
const string &arrayName = itArray.first->GetShortName();
@@ -525,7 +531,7 @@ void createParallelDirectives(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*
const int itersCount = currLoop->calculatedCountOfIters;
uint64_t regId = currReg->GetId();
if (mpiProgram)
if (sharedMemoryParallelization)
regId = (uint64_t)currLoop;
const DIST::Arrays<int> &allArrays = currReg->GetAllArrays();
@@ -553,150 +559,155 @@ void createParallelDirectives(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*
mainArray.hasWrite = true;
mainArray.mainAccess;
set<string> uniqNamesWithAcross;
fillArraysWithAcrossStatus(currLoop, uniqNamesWithAcross);
if (arrayWriteAcc.size() == 1)
if(!sharedMemoryParallelization)
{
mainArray.arrayRef = arrayWriteAcc.begin()->first;
mainArray.dimentionPos = arrayWriteAcc.begin()->second.first;
mainArray.mainAccess = arrayWriteAcc.begin()->second.second;
set<string> uniqNamesWithAcross;
fillArraysWithAcrossStatus(currLoop, uniqNamesWithAcross);
if (uniqNamesWithAcross.size())
mainArray.underAcross = true;
}
else if (arrayWriteAcc.size() > 1)
{
if (uniqNamesWithAcross.size())
mainArray.underAcross = true;
int posDim = -1;
int minDim = 999999;
int k = 0;
vector<pair<string, pair<int, pair<int, int>>>> accesses;
map<int, set<tuple<string, int, int>>> sameDims;
for (auto i = arrayWriteAcc.begin(); i != arrayWriteAcc.end(); ++i, ++k)
if (arrayWriteAcc.size() == 1)
{
const auto array = i->first;
const string &uniqName = array->GetName();
mainArray.arrayRef = arrayWriteAcc.begin()->first;
mainArray.dimentionPos = arrayWriteAcc.begin()->second.first;
mainArray.mainAccess = arrayWriteAcc.begin()->second.second;
//ACROSS arrays have priority state for all nested loops!
if (uniqNamesWithAcross.size() > 0)
if (uniqNamesWithAcross.find(uniqName) == uniqNamesWithAcross.end())
continue;
if (uniqNamesWithAcross.size())
mainArray.underAcross = true;
}
else if (arrayWriteAcc.size() > 1)
{
if (uniqNamesWithAcross.size())
mainArray.underAcross = true;
const int currDim = array->GetDimSize();
auto& sizes = array->GetSizes();
const int currSize = sizes[i->second.first].second - sizes[i->second.first].first + 1;
sameDims[currDim].insert(make_tuple(uniqName, k, currSize));
int posDim = -1;
int minDim = 999999;
int k = 0;
if (currDim < minDim)
vector<pair<string, pair<int, pair<int, int>>>> accesses;
map<int, set<tuple<string, int, int>>> sameDims;
for (auto i = arrayWriteAcc.begin(); i != arrayWriteAcc.end(); ++i, ++k)
{
if (itersCount == 0 || (itersCount != 0) && currSize >= itersCount)
const auto array = i->first;
const string &uniqName = array->GetName();
//ACROSS arrays have priority state for all nested loops!
if (uniqNamesWithAcross.size() > 0)
if (uniqNamesWithAcross.find(uniqName) == uniqNamesWithAcross.end())
continue;
const int currDim = array->GetDimSize();
auto& sizes = array->GetSizes();
const int currSize = sizes[i->second.first].second - sizes[i->second.first].first + 1;
sameDims[currDim].insert(make_tuple(uniqName, k, currSize));
if (currDim < minDim)
{
minDim = currDim;
posDim = k;
}
}
__spf_print(PRINT_DIR_RESULT, " found writes for array %s -> [%d %d]\n", array->GetShortName().c_str(), i->second.second.first, i->second.second.second);
accesses.push_back(make_pair(array->GetName(), i->second));
}
if (posDim != -1)
{
auto itDim = sameDims.find(minDim);
if (itDim == sameDims.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
int maxArraySize = -1;
for (auto& elem : itDim->second)
{
if (get<2>(elem) > maxArraySize)
{
maxArraySize = get<2>(elem);
posDim = get<1>(elem);
}
}
}
else
{
mainArray.hasWrite = false;
__spf_print(PRINT_DIR_RESULT, " no appropriate regular writes on loop\n");
}
vector<set<DIST::Array*>> realArrayRefs(accesses.size());
for (int i = 0; i < (int)accesses.size(); ++i)
{
DIST::Array *array = allArrays.GetArrayByName(accesses[i].first);
getRealArrayRefs(array, array, realArrayRefs[i], arrayLinksByFuncCalls);
}
//check the same distribution
bool statusOk = true;
for (int i = 0; i < (int)accesses.size(); ++i)
{
for (int k = i + 1; k < (int)accesses.size(); ++k)
{
DIST::Array *array1 = allArrays.GetArrayByName(accesses[i].first);
DIST::Array *array2 = allArrays.GetArrayByName(accesses[k].first);
const set<DIST::Array*> &realArrayRefs1 = realArrayRefs[i];
const set<DIST::Array*> &realArrayRefs2 = realArrayRefs[k];
for (auto &refs1 : realArrayRefs1)
{
for (auto &refs2 : realArrayRefs2)
if (itersCount == 0 || (itersCount != 0) && currSize >= itersCount)
{
auto links = findLinksBetweenArrays(refs1, refs2, regId);
minDim = currDim;
posDim = k;
}
}
__spf_print(PRINT_DIR_RESULT, " found writes for array %s -> [%d %d]\n", array->GetShortName().c_str(), i->second.second.first, i->second.second.second);
accesses.push_back(make_pair(array->GetName(), i->second));
}
const int dimFrom = accesses[i].second.first;
const int dimTo = accesses[k].second.first;
if (posDim != -1)
{
auto itDim = sameDims.find(minDim);
if (itDim == sameDims.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (dimTo != links[dimFrom])
int maxArraySize = -1;
for (auto& elem : itDim->second)
{
if (get<2>(elem) > maxArraySize)
{
maxArraySize = get<2>(elem);
posDim = get<1>(elem);
}
}
}
else
{
mainArray.hasWrite = false;
__spf_print(PRINT_DIR_RESULT, " no appropriate regular writes on loop\n");
}
vector<set<DIST::Array*>> realArrayRefs(accesses.size());
for (int i = 0; i < (int)accesses.size(); ++i)
{
DIST::Array *array = allArrays.GetArrayByName(accesses[i].first);
getRealArrayRefs(array, array, realArrayRefs[i], arrayLinksByFuncCalls);
}
//check the same distribution
bool statusOk = true;
for (int i = 0; i < (int)accesses.size(); ++i)
{
for (int k = i + 1; k < (int)accesses.size(); ++k)
{
DIST::Array *array1 = allArrays.GetArrayByName(accesses[i].first);
DIST::Array *array2 = allArrays.GetArrayByName(accesses[k].first);
const set<DIST::Array*> &realArrayRefs1 = realArrayRefs[i];
const set<DIST::Array*> &realArrayRefs2 = realArrayRefs[k];
for (auto &refs1 : realArrayRefs1)
{
for (auto &refs2 : realArrayRefs2)
{
__spf_print(1, "arrays '%s' and '%s' have different align dimensions for loop on line %d\n --> %d vs %d(%d) \n",
array1->GetShortName().c_str(), array2->GetShortName().c_str(),
currLoop->lineNum, dimTo, links[dimFrom], dimFrom);
statusOk = false;
}
else
{
const auto accessFrom = accesses[i].second.second;
const auto accessTo = accesses[k].second.second;
auto links = findLinksBetweenArrays(refs1, refs2, regId);
auto templRule1 = refs1->GetAlignRulesWithTemplate(regId);
auto templRule2 = refs2->GetAlignRulesWithTemplate(regId);
const int dimFrom = accesses[i].second.first;
const int dimTo = accesses[k].second.first;
if (DIST::Fx(accessFrom, templRule1[dimFrom]) != DIST::Fx(accessTo, templRule2[dimTo]))
if (dimTo != links[dimFrom])
{
string format = "arrays '%s' and '%s' have different align rules -- \n -->";
format += "F1 = [%d.%d], x1 = [%d.%d], F2 = [%d.%d], x2 = [%d.%d] \n -->";
format += "F1(x1) = [%d.%d] != F2(x2) = [%d.%d]\n";
__spf_print(1, format.c_str(),
__spf_print(1, "arrays '%s' and '%s' have different align dimensions for loop on line %d\n --> %d vs %d(%d) \n",
array1->GetShortName().c_str(), array2->GetShortName().c_str(),
templRule1[dimFrom].first, templRule1[dimFrom].second, accessFrom.first, accessFrom.second,
templRule2[dimTo].first, templRule2[dimTo].second, accessTo.first, accessTo.second,
DIST::Fx(accessFrom, templRule1[dimFrom]).first, DIST::Fx(accessFrom, templRule1[dimFrom]).second,
DIST::Fx(accessTo, templRule2[dimTo]).first, DIST::Fx(accessTo, templRule2[dimTo]).second);
currLoop->lineNum, dimTo, links[dimFrom], dimFrom);
statusOk = false;
}
}
else
{
const auto accessFrom = accesses[i].second.second;
const auto accessTo = accesses[k].second.second;
auto templRule1 = refs1->GetAlignRulesWithTemplate(regId);
auto templRule2 = refs2->GetAlignRulesWithTemplate(regId);
if (DIST::Fx(accessFrom, templRule1[dimFrom]) != DIST::Fx(accessTo, templRule2[dimTo]))
{
string format = "arrays '%s' and '%s' have different align rules -- \n -->";
format += "F1 = [%d.%d], x1 = [%d.%d], F2 = [%d.%d], x2 = [%d.%d] \n -->";
format += "F1(x1) = [%d.%d] != F2(x2) = [%d.%d]\n";
__spf_print(1, format.c_str(),
array1->GetShortName().c_str(), array2->GetShortName().c_str(),
templRule1[dimFrom].first, templRule1[dimFrom].second, accessFrom.first, accessFrom.second,
templRule2[dimTo].first, templRule2[dimTo].second, accessTo.first, accessTo.second,
DIST::Fx(accessFrom, templRule1[dimFrom]).first, DIST::Fx(accessFrom, templRule1[dimFrom]).second,
DIST::Fx(accessTo, templRule2[dimTo]).first, DIST::Fx(accessTo, templRule2[dimTo]).second);
statusOk = false;
}
}
if (!statusOk)
{
wstring bufE, bufR;
__spf_printToLongBuf(bufE, L"arrays '%s' and '%s' have different align rules in this loop according to their write accesses",
to_wstring(array1->GetShortName()).c_str(), to_wstring(array2->GetShortName()).c_str());
__spf_printToLongBuf(bufR, R132, to_wstring(array1->GetShortName()).c_str(), to_wstring(array2->GetShortName()).c_str());
messages.push_back(Messages(WARR, currLoop->lineNum, bufR, bufE, 3011));
currLoop->hasDifferentAlignRules = true;
break;
}
}
if (!statusOk)
{
wstring bufE, bufR;
__spf_printToLongBuf(bufE, L"arrays '%s' and '%s' have different align rules in this loop according to their write accesses",
to_wstring(array1->GetShortName()).c_str(), to_wstring(array2->GetShortName()).c_str());
__spf_printToLongBuf(bufR, R132, to_wstring(array1->GetShortName()).c_str(), to_wstring(array2->GetShortName()).c_str());
messages.push_back(Messages(WARR, currLoop->lineNum, bufR, bufE, 3011));
currLoop->hasDifferentAlignRules = true;
break;
}
}
if (!statusOk)
break;
@@ -704,43 +715,43 @@ void createParallelDirectives(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*
if (!statusOk)
break;
}
if (!statusOk)
break;
}
if (statusOk)
{
k = 0;
for (auto array = arrayWriteAcc.begin(); array != arrayWriteAcc.end(); array++, ++k)
if (statusOk)
{
if (k == posDim)
k = 0;
for (auto array = arrayWriteAcc.begin(); array != arrayWriteAcc.end(); array++, ++k)
{
mainArray.arrayRef = array->first;
mainArray.dimentionPos = array->second.first;
mainArray.mainAccess = array->second.second;
break;
if (k == posDim)
{
mainArray.arrayRef = array->first;
mainArray.dimentionPos = array->second.first;
mainArray.mainAccess = array->second.second;
break;
}
}
}
else
{
__spf_print(PRINT_DIR_RESULT, " has conflict writes\n");
hasConflict = true;
}
}
else
{
__spf_print(PRINT_DIR_RESULT, " has conflict writes\n");
hasConflict = true;
mainArray.hasWrite = false;
__spf_print(PRINT_DIR_RESULT, " no regular writes on loop\n");
}
}
else
{
mainArray.hasWrite = false;
__spf_print(PRINT_DIR_RESULT, " no regular writes on loop\n");
// fill mainArray if no regular writes found
// now OmegaTest is used for searching dependencies
if (!mainArray.hasWrite)
findMainArrayFromRead(currAccesses, mainArray, itersCount, arrayLinksByFuncCalls);
}
// fill mainArray if no regular writes found
// now OmegaTest is used for searching dependencies
if (!mainArray.hasWrite)
findMainArrayFromRead(currAccesses, mainArray, itersCount, arrayLinksByFuncCalls);
bool dimPosFound = sharedMemoryParallelization ||
(mainArray.arrayRef != NULL && mainArray.dimentionPos != -1);
if (!hasConflict &&
mainArray.arrayRef != NULL && mainArray.dimentionPos != -1 &&
if (dimPosFound &&
!currLoop->hasLimitsToParallel() &&
(currLoop->lineNum > 0 || (currLoop->lineNum < 0 && currLoop->altLineNum > 0)))
{
@@ -749,7 +760,7 @@ void createParallelDirectives(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*
const int dimPos = mainArray.dimentionPos;
//change array to template if ACROSS was not found or not loop_array
if (mainArray.underAcross == false && !(mpiProgram == 1 && mainArray.arrayRef->IsLoopArray()))
if (!sharedMemoryParallelization && mainArray.underAcross == false && !mainArray.arrayRef->IsLoopArray())
{
set<DIST::Array*> realArrayRef;
getRealArrayRefs(mainArray.arrayRef, mainArray.arrayRef, realArrayRef, arrayLinksByFuncCalls);
@@ -788,25 +799,30 @@ void createParallelDirectives(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*
parDir = loop->directive;
if (parDir != NULL)
{
parDir->arrayRef2 = mainArrayOfLoop;
if (mainArray.underAcross == false)
if(!sharedMemoryParallelization)
{
for (int i = 0; i < mainArrayOfLoop->GetDimSize(); ++i)
{
if (i == dimPos)
parDir->on2.push_back(make_pair(currLoop->loopSymbol, mainAccess));
else
parDir->on2.push_back(make_pair("*", make_pair(0, 0)));
}
parDir->arrayRef2 = mainArrayOfLoop;
for (int z = 0; z < parDir->on2.size(); ++z)
if (parDir->on2[z].first != "*" && parDir->on2[z].second == make_pair(0, 0))
parDir->on2[z].second = mainAccess;
if (mainArray.underAcross == false)
{
for (int i = 0; i < mainArrayOfLoop->GetDimSize(); ++i)
{
if (i == dimPos)
parDir->on2.push_back(make_pair(currLoop->loopSymbol, mainAccess));
else
parDir->on2.push_back(make_pair("*", make_pair(0, 0)));
}
for (int z = 0; z < parDir->on2.size(); ++z)
if (parDir->on2[z].first != "*" && parDir->on2[z].second == make_pair(0, 0))
parDir->on2[z].second = mainAccess;
}
else
parDir->on2 = parDir->on;
addShadowFromAnalysis(parDir, currAccesses);
}
else
parDir->on2 = parDir->on;
addShadowFromAnalysis(parDir, currAccesses);
loop->directiveForLoop = new ParallelDirective(*loop->directive);
}
__spf_print(PRINT_DIR_RESULT, " directive created\n");
@@ -1762,7 +1778,7 @@ static bool addRedistributionDirs(File* file, const vector<pair<DIST::Array*, co
}
needToSkip = false;
if (mpiProgram)
if (sharedMemoryParallelization)
return false;
// Realign with global template clones
@@ -1830,10 +1846,10 @@ void selectParallelDirectiveForVariant(File* file, ParallelRegion* currParReg,
const bool isMyRegion = loop->region == currParReg;
const bool noUserDir = loop->userDvmDirective == NULL;
DIST::Array* sameAlignTemplate = NULL;
const bool sameAligns = loop->isArrayTemplatesTheSame(sameAlignTemplate, regionId, arrayLinksByFuncCalls);
const bool sameAligns = sharedMemoryParallelization ? true : loop->isArrayTemplatesTheSame(sameAlignTemplate, regionId, arrayLinksByFuncCalls);
bool freeLoopDistr = true;
if (hasDirective && loop->directive->arrayRef2->IsLoopArray())
if (!sharedMemoryParallelization && hasDirective && loop->directive->arrayRef2->IsLoopArray())
{
bool ok = false;
for (auto& elem : distribution)
@@ -1866,33 +1882,38 @@ void selectParallelDirectiveForVariant(File* file, ParallelRegion* currParReg,
//try to unite loops
if (createNestedLoops(loop, depInfoForLoopGraph, mapFuncInfo, messages))
parDirective = loop->recalculateParallelDirective();
bool topCheck = isOnlyTopPerfect(loop, distribution);
bool needToContinue = false;
if (topCheck)
if(!sharedMemoryParallelization)
{
//<Array, linksWithTempl> -> dims not mached
map<DIST::Array*, vector<bool>> dimsNotMatch;
if (!checkCorrectness(*parDirective, distribution, reducedG, allArrays, arrayLinksByFuncCalls, loop->getAllArraysInLoop(), messages, loop->lineNum, dimsNotMatch, regionId))
{
if (!tryToResolveUnmatchedDims(dimsNotMatch, loop, regionId, parDirective, reducedG, allArrays, arrayLinksByFuncCalls, distribution, mapFuncInfo))
needToContinue = addRedistributionDirs(file, distribution, toInsert, loop, mapLoopsInFile, parDirective, regionId, messages, arrayLinksByFuncCalls, sameAlignTemplate);
}
}
else
needToContinue = addRedistributionDirs(file, distribution, toInsert, loop, mapLoopsInFile, parDirective, regionId, messages, arrayLinksByFuncCalls, sameAlignTemplate);
bool topCheck = isOnlyTopPerfect(loop, distribution);
if (needToContinue)
continue;
bool needToContinue = false;
if (topCheck)
{
//<Array, linksWithTempl> -> dims not mached
map<DIST::Array*, vector<bool>> dimsNotMatch;
if (!checkCorrectness(*parDirective, distribution, reducedG, allArrays, arrayLinksByFuncCalls, loop->getAllArraysInLoop(), messages, loop->lineNum, dimsNotMatch, regionId))
{
if (!tryToResolveUnmatchedDims(dimsNotMatch, loop, regionId, parDirective, reducedG, allArrays, arrayLinksByFuncCalls, distribution, mapFuncInfo))
needToContinue = addRedistributionDirs(file, distribution, toInsert, loop, mapLoopsInFile, parDirective, regionId, messages, arrayLinksByFuncCalls, sameAlignTemplate);
}
}
else
needToContinue = addRedistributionDirs(file, distribution, toInsert, loop, mapLoopsInFile, parDirective, regionId, messages, arrayLinksByFuncCalls, sameAlignTemplate);
if (needToContinue)
continue;
}
vector<pair<DIST::Array*, const DistrVariant*>> newRules;
constructRules(newRules, distribution, loop);
if(!sharedMemoryParallelization)
constructRules(newRules, distribution, loop);
Directive* dirImpl = parDirective->genDirective(file, newRules, loop, reducedG, allArrays, regionId, arrayLinksByFuncCalls);
#if __SPF
//move label before loop
if (loop->hasRedistribute())
if (!sharedMemoryParallelization && loop->hasRedistribute())
{
auto prev = loop->loop->lexPrev();
if (!prev)

View File

@@ -1,166 +0,0 @@
#include "../Utils/leak_detector.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <vector>
#include <map>
#include <set>
#include "../ParallelizationRegions/ParRegions.h"
#include "../Distribution/Arrays.h"
#include "../Transformations/loop_transform.h"
#include "../Utils/errors.h"
#include "directive_parser.h"
#include "directive_creator.h"
#include "directive_creator_nodist.h"
#define PRINT_PROF_INFO 1
#define PRINT_DIR_RESULT 0
using std::vector;
using std::pair;
using std::tuple;
using std::map;
using std::set;
using std::make_pair;
using std::make_tuple;
using std::get;
using std::string;
using std::wstring;
void createParallelDirectivesNoDist(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*>> &loopInfos,
const vector<ParallelRegion*>& regions,
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls,
vector<Messages> &messages)
{
for (auto &loopInfo : loopInfos)
{
LoopGraph* currLoop = loopInfo.first;
ParallelRegion *currReg = getRegionByLine(regions, currLoop->fileName.c_str(), currLoop->lineNum);
if (currReg == NULL || currLoop->userDvmDirective != NULL)
{
__spf_print(PRINT_PROF_INFO, "Skip loop on file %s and line %d\n", currLoop->fileName.c_str(), currLoop->lineNum);
continue;
}
const int itersCount = currLoop->calculatedCountOfIters;
uint64_t regId = (uint64_t)currLoop;
const DIST::Arrays<int> &allArrays = currReg->GetAllArrays();
vector<pair<pair<string, string>, vector<pair<int, int>>>> acrossInfo;
fillAcrossInfoFromDirectives(currLoop, acrossInfo);
bool hasConflict = false;
// uniqKey -> pair<position of access, pair<acces>> ///write acceses ///
map<DIST::Array*, pair<int, pair<int, int>>, DIST::ArrayComparator> arrayWriteAcc;
set<DIST::Array*> acrossOutArrays;
__spf_print(PRINT_DIR_RESULT, " Loop on line %d:\n", currLoop->lineNum);
const map<DIST::Array*, ArrayInfo*> &currAccesses = loopInfo.second;
// find conflict and fill arrayWriteAcc
hasConflict = checkForConflict(currAccesses, currLoop, arrayWriteAcc, acrossInfo, acrossOutArrays);
if (hasConflict)
__spf_print(PRINT_DIR_RESULT, " has conflict\n");
else
{
if (!currLoop->hasLimitsToParallel() &&
(currLoop->lineNum > 0 || (currLoop->lineNum < 0 && currLoop->altLineNum > 0)))
{
ParallelDirective* parDir = new ParallelDirective();
#if __SPF
parDir->langType = LANG_F;
#else
parDir->langType = LANG_C;
#endif
parDir->line = currLoop->lineNum;
parDir->col = 0;
parDir->file = currLoop->fileName;
fillInfoFromDirectives(currLoop, parDir);
parDir->parallel.push_back(currLoop->loopSymbol);
currLoop->directive = parDir;
currLoop->acrossOutAttribute.insert(acrossOutArrays.begin(), acrossOutArrays.end());
addShadowFromAnalysis(parDir, currAccesses);
currLoop->directiveForLoop = new ParallelDirective(*currLoop->directive);
__spf_print(PRINT_DIR_RESULT, " directive created\n");
}
}
}
}
void selectParallelDirectiveForVariantNoDist(File* file, ParallelRegion* currParReg,
DIST::Arrays<int>& allArrays,
const vector<LoopGraph*>& loopGraph,
const map<int, LoopGraph*>& mapLoopsInFile,
const map<string, FuncInfo*>& mapFuncInfo,
vector<Directive*>& toInsert,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const map<LoopGraph*, void*>& depInfoForLoopGraph,
vector<Messages>& messages)
{
for (int i = 0; i < loopGraph.size(); ++i)
{
LoopGraph* loop = loopGraph[i];
const bool hasDirective = loop->directive;
const bool noLimits = loop->hasLimitsToParallel() == false;
const bool isMyRegion = loop->region == currParReg;
const bool noUserDir = loop->userDvmDirective == NULL;
if (hasDirective && noLimits && isMyRegion && noUserDir)
{
if (loop->perfectLoop >= 1)
{
ParallelDirective* parDirective = loop->directive;
parDirective->cloneOfTemplate = "";
//try to unite loops
if (createNestedLoops(loop, depInfoForLoopGraph, mapFuncInfo, messages))
parDirective = loop->recalculateParallelDirective();
// rewrite bool topCheck = isOnlyTopPerfect(loop, distribution);
Directive* dirImpl = parDirective->genDirectiveNoDist(file, loop, allArrays, arrayLinksByFuncCalls);
#if __SPF
//move label before loop
if(loop->lineNum > 0)
moveLabelBefore(loop->loop);
// check correctness
if (loop->lineNum < 0)
{
if (loop->altLineNum == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* local = NULL;
local = SgStatement::getStatementByFileAndLine(loop->loop->fileName(), loop->lineNum);
if (local == NULL)
local = SgStatement::getStatementByFileAndLine(loop->loop->fileName(), loop->altLineNum);
checkNull(local, convertFileName(__FILE__).c_str(), __LINE__);
}
#endif
toInsert.push_back(dirImpl);
}
}
else //TODO: add checker for indexing in this loop
{
if (loopGraph[i]->children.size() != 0)
selectParallelDirectiveForVariantNoDist(file, currParReg, allArrays, loopGraph[i]->children, mapLoopsInFile, mapFuncInfo,
toInsert, arrayLinksByFuncCalls,depInfoForLoopGraph, messages);
}
}
}
#undef PRINT_PROF_INFO
#undef PRINT_DIR_RESULT

View File

@@ -1,26 +0,0 @@
#pragma once
#include <vector>
#include <map>
#include <set>
#include <string>
#include "../Distribution/Distribution.h"
#include "../Utils/errors.h"
#include "../GraphLoop/graph_loops.h"
#include "../Utils/types.h"
void createParallelDirectivesNoDist(const std::map<LoopGraph*, std::map<DIST::Array*, ArrayInfo*>>& loopInfos,
const std::vector<ParallelRegion*>& regions,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
std::vector<Messages>& messages);
void selectParallelDirectiveForVariantNoDist(File* file, ParallelRegion* currParReg,
DIST::Arrays<int>& allArrays,
const std::vector<LoopGraph*>& loopGraph,
const std::map<int, LoopGraph*>& mapLoopsInFile,
const std::map<std::string, FuncInfo*>& mapFuncInfo,
std::vector<Directive*>& toInsert,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
const std::map<LoopGraph*, void*>& depInfoForLoopGraph,
std::vector<Messages>& messages);

View File

@@ -432,7 +432,11 @@ static vector<OmpDir> findAllGlobalParallelRegions(SgStatement* stFunc)
&& dir.keys.find("end") == end)
{
if (sections.size() && sections.back().end == NULL) // has open parallel region
{
__spf_print(1, "wrong omp directives placed on line %d\n", st->lineNumber());
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
sections.push_back(dir);
sections.back().start = st;
}
@@ -440,6 +444,11 @@ static vector<OmpDir> findAllGlobalParallelRegions(SgStatement* stFunc)
&& dir.keys.find("do") == end
&& dir.keys.find("end") != end)
{
if (!sections.size())
{
__spf_print(1, "wrong omp directives placed on line %d\n", st->lineNumber());
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
sections.back().end = st;
}
}
@@ -514,7 +523,10 @@ void parseOmpDirectives(SgFile* file, vector<Messages>& currMessages)
{
SgForStmt* currSt = (SgForStmt*)st;
if (currSt->isEnddoLoop() == 0)
{
__spf_print(1, "wrong omp directives placed\n");
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
else
parseOmpInStatement(st, getGlobalPrivate(st, globalParallelRegions), true);
}

View File

@@ -39,7 +39,7 @@ using std::make_tuple;
static const string dvmhModuleName = "dvmh_template_mod";
extern int mpiProgram;
extern int sharedMemoryParallelization;
//the size of vector indiceates type of DVM_DIR
SgStatement* createStatFromExprs(const vector<Expression*> &exprs)
@@ -2384,7 +2384,7 @@ void insertParallelDirs(SgFile *file, bool extract,
const char* file_name = file->filename();
insertDirectiveToFile(file, file_name, createdDirectives, extract, messages);
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
{
map<string, FuncInfo*> mapFuncInfo;
createMapOfFunc(callGraph, mapFuncInfo);
@@ -2420,7 +2420,7 @@ void insertParallelDirs(SgFile *file, bool extract,
for (auto& array : declaredArrays)
array.second.first->ClearShadowSpecs();
}
else if (mpiProgram == 0)
else if (sharedMemoryParallelization == 0)
{
set<uint64_t> regNum;
for (int z = 0; z < parallelRegions.size(); ++z)

View File

@@ -22,7 +22,7 @@ struct FuncInfo;
#define TO_STR std::to_string
#if __SPF
extern int mpiProgram;
extern int sharedMemoryParallelization;
#endif
namespace Distribution
@@ -117,7 +117,7 @@ namespace Distribution
if (it == templateInfo.end())
{
#if __SPF
if (withCheck && mpiProgram != 0)
if (withCheck && sharedMemoryParallelization != 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
#endif
currLink = new TemplateLink(dimSize);

View File

@@ -530,7 +530,7 @@ int createAlignDirs(DIST::GraphCSR<int, double, attrType> &reducedG, const DIST:
{
DIST::Array* array = arrayPair.second;
if (mpiProgram != 0)
if (sharedMemoryParallelization != 0)
if (onlyThese.find(array) == onlyThese.end())
continue;
@@ -604,7 +604,7 @@ int createAlignDirs(DIST::GraphCSR<int, double, attrType> &reducedG, const DIST:
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
if (isAllRulesEqualWithoutArray(rules) || mpiProgram != 0)
if (isAllRulesEqualWithoutArray(rules) || sharedMemoryParallelization != 0)
{
bool hasError = createNewAlignRule(array, allArrays, rules[0], dataDirectives, SPF_messages, canNotAlign == NULL);
if (hasError)

View File

@@ -9,7 +9,6 @@
#include "../Utils/types.h"
#include "DvmhDirective.h"
#include "DvmhDirective_internal.h"
#include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "../Sapfor.h"
@@ -75,7 +74,7 @@ static bool findArrayRefAndCheck(SgExpression *ex, const DIST::Array* currArray,
return res;
}
bool needCorner(const DIST::Array* currArray, const vector<map<pair<int, int>, int>> &shiftsByAccess, Statement *loop)
static bool needCorner(const DIST::Array* currArray, const vector<map<pair<int, int>, int>> &shiftsByAccess, Statement *loop)
{
bool need = false;
@@ -93,7 +92,6 @@ bool needCorner(const DIST::Array* currArray, const vector<map<pair<int, int>, i
return need;
}
vector<SgExpression*> genSubscripts(const vector<pair<int, int>> &shadowRenew, const vector<pair<int, int>> &shadowRenewShifts)
{
vector<SgExpression*> subs;
@@ -174,7 +172,7 @@ static SgExpression* genSgExpr(SgFile *file, const string &letter, const pair<in
return retVal;
}
std::multimap<string, Symbol*> setToMapWithSortByStr(const set<Symbol*> &setIn)
static std::multimap<string, Symbol*> setToMapWithSortByStr(const set<Symbol*> &setIn)
{
std::multimap<string, Symbol*> retMap;
for (auto& elem : setIn)
@@ -207,7 +205,7 @@ static set<string> fillUsedSymbols(SgStatement *loop)
return usedS;
}
SgStatement* getRealStat(const char *file, const int line, const int altLine)
static SgStatement* getRealStat(const char *file, const int line, const int altLine)
{
SgStatement* local = SgStatement::getStatementByFileAndLine(file, line);
if (local == NULL)
@@ -216,7 +214,7 @@ SgStatement* getRealStat(const char *file, const int line, const int altLine)
return local;
}
string correctSymbolModuleName(const string& origFull)
static string correctSymbolModuleName(const string& origFull)
{
auto it = origFull.find("::");
if (it == string::npos)
@@ -225,7 +223,7 @@ string correctSymbolModuleName(const string& origFull)
return origFull.substr(it + 2);
}
SgStatement* getModuleScope(const string& origFull, vector<SgStatement*>& moduleList, SgStatement *local)
static SgStatement* getModuleScope(const string& origFull, vector<SgStatement*>& moduleList, SgStatement *local)
{
auto it = origFull.find("::");
if (it == string::npos)
@@ -245,11 +243,14 @@ static vector<SgExpression*>
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const map<string, set<SgSymbol*>>& byUseInFunc,
File* file, const pair<int, int>& lineRange,
const set<DIST::Array*>& onlyFor)
const set<DIST::Array*>& onlyFor,
const set<string>& privates)
{
vector<SgExpression*> tieList;
vector<pair<DIST::Array*, DIST::Array*>> realRefsUsed;
for (auto& elem : currLoop->usedArrays)
const auto& usedArrays = sharedMemoryParallelization ? currLoop->usedArraysAll : currLoop->usedArrays;
for (auto& elem : usedArrays)
{
if (onlyFor.size())
if (onlyFor.find(elem) == onlyFor.end())
@@ -269,6 +270,9 @@ static vector<SgExpression*>
for (auto& pairs : realRefsUsed)
{
if (privates.find(pairs.second->GetShortName()) != privates.end())
continue;
auto type = pairs.second->GetDeclSymbol(currLoop->fileName, lineRange, getAllFilesInProject())->GetOriginal()->type();
SgSymbol* arrayS = getFromModule(byUseInFunc, findSymbolOrCreate(file, pairs.second->GetShortName(), type));
SgArrayRefExp* array = new SgArrayRefExp(*arrayS);
@@ -281,75 +285,102 @@ static vector<SgExpression*>
for (int z = 0; z < loops.size(); ++z)
{
currLoop = loops[z];
const uint64_t regId = mpiProgram ? (uint64_t)currLoop : currLoop->region->GetId();
auto dirForLoop = currLoop->directiveForLoop;
auto tmplP = pairs.first->GetTemplateArray(regId, mpiProgram != 0);
auto links = pairs.first->GetLinksWithTemplate(regId);
// no mapping for this loop, skip this
if (tmplP == dirForLoop->arrayRef)
if(!sharedMemoryParallelization)
{
for (int z = 0; z < links.size(); ++z)
const uint64_t regId = sharedMemoryParallelization ? (uint64_t)currLoop : currLoop->region->GetId();
auto dirForLoop = currLoop->directiveForLoop;
auto tmplP = pairs.first->GetTemplateArray(regId, sharedMemoryParallelization != 0);
auto links = pairs.first->GetLinksWithTemplate(regId);
// no mapping for this loop, skip this
if (tmplP == dirForLoop->arrayRef)
{
int dim = links[z];
if (dim >= 0)
for (int z = 0; z < links.size(); ++z)
{
if (dirForLoop->on[dim].first != "*")
int dim = links[z];
if (dim >= 0)
{
needToAdd = true;
subs[z] = new SgVarRefExp(findSymbolOrCreate(file, dirForLoop->on[dim].first));
break;
if (dirForLoop->on[dim].first != "*")
{
needToAdd = true;
subs[z] = new SgVarRefExp(findSymbolOrCreate(file, dirForLoop->on[dim].first));
break;
}
}
}
}
}
else if (pairs.second == dirForLoop->arrayRef)
{
for (int z = 0; z < dirForLoop->on.size(); ++z)
{
if (dirForLoop->on[z].first != "*")
{
needToAdd = true;
subs[z] = new SgVarRefExp(findSymbolOrCreate(file, dirForLoop->on[z].first));
break;
}
}
}
else if (!dirForLoop->arrayRef->IsTemplate())
{
set<DIST::Array*> realRefsLocal;
getRealArrayRefs(dirForLoop->arrayRef, dirForLoop->arrayRef, realRefsLocal, arrayLinksByFuncCalls);
if (realRefsLocal.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto tmplP = (*realRefsLocal.begin())->GetTemplateArray(regId, mpiProgram != 0);
auto links = (*realRefsLocal.begin())->GetLinksWithTemplate(regId);
auto tmplP_et = pairs.first->GetTemplateArray(regId, mpiProgram != 0);
auto links_et = pairs.first->GetLinksWithTemplate(regId);
if (tmplP == tmplP_et)
else if (pairs.second == dirForLoop->arrayRef)
{
for (int z = 0; z < dirForLoop->on.size(); ++z)
{
if (dirForLoop->on[z].first != "*")
{
const int idx = links[z];
for (int p = 0; p < links_et.size(); ++p)
{
if (idx >= 0 && links_et[p] == idx)
{
subs[p] = new SgVarRefExp(findSymbolOrCreate(file, dirForLoop->on[z].first));
needToAdd = true;
break;
}
}
{
needToAdd = true;
subs[z] = new SgVarRefExp(findSymbolOrCreate(file, dirForLoop->on[z].first));
break;
}
}
}
else if (!dirForLoop->arrayRef->IsTemplate())
{
set<DIST::Array*> realRefsLocal;
getRealArrayRefs(dirForLoop->arrayRef, dirForLoop->arrayRef, realRefsLocal, arrayLinksByFuncCalls);
if (realRefsLocal.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto tmplP = (*realRefsLocal.begin())->GetTemplateArray(regId, sharedMemoryParallelization != 0);
auto links = (*realRefsLocal.begin())->GetLinksWithTemplate(regId);
auto tmplP_et = pairs.first->GetTemplateArray(regId, sharedMemoryParallelization != 0);
auto links_et = pairs.first->GetLinksWithTemplate(regId);
if (tmplP == tmplP_et)
{
for (int z = 0; z < dirForLoop->on.size(); ++z)
{
if (dirForLoop->on[z].first != "*")
{
const int idx = links[z];
for (int p = 0; p < links_et.size(); ++p)
{
if (idx >= 0 && links_et[p] == idx)
{
subs[p] = new SgVarRefExp(findSymbolOrCreate(file, dirForLoop->on[z].first));
needToAdd = true;
break;
}
}
break;
}
}
}
}
}
else
{
for (const auto& source : { currLoop->readOpsForLoop, currLoop->writeOpsForLoop }) {
auto array_it = source.find(pairs.second);
if (array_it != source.end()) {
bool dim_found = false;
for (int i = 0; i < array_it->second.size(); i++) {
if (array_it->second[i].coefficients.size() != 0)
{
needToAdd = true;
dim_found = true;
subs[i] = new SgVarRefExp(findSymbolOrCreate(file, currLoop->loopSymbol));
break;
}
}
if (dim_found)
break;
}
}
}
}
@@ -365,7 +396,7 @@ static vector<SgExpression*>
}
//TODO: need to improve
set<SgSymbol*> fillPrivateOnlyFromSpfParameter(SgStatement* loop, const int altLine)
static set<SgSymbol*> fillPrivateOnlyFromSpfParameter(SgStatement* loop, const int altLine)
{
set<SgSymbol*> used;
set<SgSymbol*> usedInSpfPar;
@@ -385,7 +416,7 @@ set<SgSymbol*> fillPrivateOnlyFromSpfParameter(SgStatement* loop, const int altL
return usedInSpfPar;
}
set<SgSymbol*> changeLoopOrder(const vector<string>& parallel, const vector<string>& newParallel, vector<LoopGraph*>& loops)
static set<SgSymbol*> changeLoopOrder(const vector<string>& parallel, const vector<string>& newParallel, vector<LoopGraph*>& loops)
{
set<SgSymbol*> additionalPrivates;
if (parallel == newParallel)
@@ -452,7 +483,7 @@ set<SgSymbol*> changeLoopOrder(const vector<string>& parallel, const vector<stri
return additionalPrivates;
}
vector<int> sortShadow(const vector<pair<pair<string, string>, vector<pair<int, int>>>>& toSort)
static vector<int> sortShadow(const vector<pair<pair<string, string>, vector<pair<int, int>>>>& toSort)
{
map<string, int> order;
for (int z = 0; z < toSort.size(); ++z)
@@ -477,7 +508,7 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
{
const set<DIST::Array*>& acrossOutAttribute = currLoop->acrossOutAttribute;
const map<DIST::Array*, pair<vector<ArrayOp>, vector<bool>>>& readOps = currLoop->readOps;
map< DIST::Array*, vector<ArrayOp>>& remoteReads = currLoop->remoteRegularReads;
map<DIST::Array*, vector<ArrayOp>>& remoteReads = currLoop->remoteRegularReads;
Statement* loop = currLoop->loop;
string directive = "";
@@ -501,6 +532,10 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
LoopGraph* pLoop = currLoop;
const set<string> allFiles = getAllFilesInProject();
map<string, DIST::Array*> arrayByName;
for (DIST::Array* arr : currLoop->getAllArraysInLoop())
arrayByName[arr->GetName()] = arr;
for (int z = 0; z < nested; ++z)
{
loopSymbs.push_back(loopG->symbol());
@@ -552,21 +587,25 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
p->setRhs(NULL);
}
DIST::Array* mapTo = arrayRef2->IsLoopArray() ? arrayRef : arrayRef2;
auto onTo = arrayRef2->IsLoopArray() ? on : on2;
DIST::Array* mapTo;
dirStatement[2] = new Expression(expr);
if (mpiProgram)
if (sharedMemoryParallelization)
{
directive += ")";
}
else
{
mapTo = arrayRef2->IsLoopArray() ? arrayRef : arrayRef2;
directive += ") ON " + mapTo->GetShortName() + "(";
}
SgArrayRefExp* arrayExpr = NULL;
string arrayExprS = "";
if (!mpiProgram)
if (!sharedMemoryParallelization)
{
auto onTo = arrayRef2->IsLoopArray() ? on : on2;
SgSymbol* symbForPar = NULL;
if (arrayRef->IsTemplate())
{
@@ -652,52 +691,49 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
p->setLhs(makeExprList(list));
}
if (mpiProgram || across.size() != 0)
if (sharedMemoryParallelization || (across.size() != 0 && !arrayRef2->IsLoopArray()))
{
if (!arrayRef2->IsLoopArray())
vector<LoopGraph*> loopsTie;
for (int i = 0; i < (int)parallel.size(); ++i)
if (parallel[i] != "*")
loopsTie.push_back(loops[i]);
set<DIST::Array*> onlyFor;
if (sharedMemoryParallelization == 0 && across.size())
{
vector<LoopGraph*> loopsTie;
for (int i = 0; i < (int)parallel.size(); ++i)
if (parallel[i] != "*")
loopsTie.push_back(loops[i]);
set<DIST::Array*> onlyFor;
if (mpiProgram == 0 && across.size())
for (int k = 0; k < (int)across.size(); ++k)
{
for (int k = 0; k < (int)across.size(); ++k)
{
DIST::Array* currArray = allArrays.GetArrayByName(across[k].first.second);
if (currArray != mapTo)
onlyFor.insert(currArray);
}
DIST::Array* currArray = allArrays.GetArrayByName(across[k].first.second);
if (currArray != mapTo)
onlyFor.insert(currArray);
}
vector<SgExpression*> tieList;
if (mpiProgram)
tieList = compliteTieList(currLoop, loopsTie, arrayLinksByFuncCalls, byUseInFunc, file, lineRange, onlyFor);
else if (onlyFor.size()) // not MPI regime
tieList = compliteTieList(currLoop, loopsTie, arrayLinksByFuncCalls, byUseInFunc, file, lineRange, onlyFor);
}
vector<SgExpression*> tieList;
if (sharedMemoryParallelization)
tieList = compliteTieList(currLoop, loopsTie, arrayLinksByFuncCalls, byUseInFunc, file, lineRange, onlyFor, uniqNamesOfPrivates);
else if (onlyFor.size()) // not MPI regime
tieList = compliteTieList(currLoop, loopsTie, arrayLinksByFuncCalls, byUseInFunc, file, lineRange, onlyFor, uniqNamesOfPrivates);
if (tieList.size())
if (tieList.size())
{
if (dirStatement[1] != NULL)
{
if (dirStatement[1] != NULL)
{
expr = createAndSetNext(RIGHT, EXPR_LIST, expr);
p = expr;
}
p = createAndSetNext(LEFT, ACC_TIE_OP, p);
p->setLhs(makeExprList(tieList));
directive += ", TIE(";
int k = 0;
for (auto& tieL : tieList)
{
if (k != 0)
directive += ",";
directive += tieL->unparse();
++k;
}
directive += ")";
expr = createAndSetNext(RIGHT, EXPR_LIST, expr);
p = expr;
}
p = createAndSetNext(LEFT, ACC_TIE_OP, p);
p->setLhs(makeExprList(tieList));
directive += ", TIE(";
int k = 0;
for (auto& tieL : tieList)
{
if (k != 0)
directive += ",";
directive += tieL->unparse();
++k;
}
directive += ")";
}
}
@@ -729,13 +765,26 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
{
const int i1 = ordered[k];
vector<map<pair<int, int>, int>> shiftsByAccess;
DIST::Array* currArray = NULL;
DIST::Array* currArray = allArrays.GetArrayByName(across[i1].first.second);
if (currArray == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (!sharedMemoryParallelization)
{
currArray = allArrays.GetArrayByName(across[i1].first.second);
if (currArray == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
else
{
auto currArray_it = arrayByName.find(across[i1].first.second);
if (currArray_it == arrayByName.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
currArray = currArray_it->second;
}
bool isOut = acrossOutAttribute.find(currArray) != acrossOutAttribute.end();
string bounds = genBounds(across[i1], acrossShifts[i1], reducedG, allArrays, remoteReads, readOps, true, regionId, distribution, arraysInAcross, shiftsByAccess, arrayLinksByFuncCalls);
string bounds = genBounds(across[i1], acrossShifts[i1], reducedG, allArrays, currArray, remoteReads, readOps, true, regionId, distribution, arraysInAcross, shiftsByAccess, arrayLinksByFuncCalls);
if (bounds != "")
{
if (inserted != 0)
@@ -807,7 +856,7 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
}
}
if (shadowRenew.size() != 0 && mpiProgram == 0)
if (shadowRenew.size() != 0 && sharedMemoryParallelization == 0)
{
if (shadowRenewShifts.size() == 0)
{
@@ -824,7 +873,8 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
{
const int i1 = ordered[k];
vector<map<pair<int, int>, int>> shiftsByAccess;
const string bounds = genBounds(shadowRenew[i1], shadowRenewShifts[i1], reducedG, allArrays, remoteReads, readOps, false, regionId, distribution, arraysInAcross, shiftsByAccess, arrayLinksByFuncCalls);
DIST::Array* shadowArray = allArrays.GetArrayByName(shadowRenew[i1].first.second);
const string bounds = genBounds(shadowRenew[i1], shadowRenewShifts[i1], reducedG, allArrays, shadowArray, remoteReads, readOps, false, regionId, distribution, arraysInAcross, shiftsByAccess, arrayLinksByFuncCalls);
if (bounds != "")
{
DIST::Array* currArray = allArrays.GetArrayByName(shadowRenew[i1].first.second);
@@ -976,7 +1026,7 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
dirStatement[1] = new Expression(expr);
}
if (remoteAccess.size() != 0 && mpiProgram == 0)
if (remoteAccess.size() != 0 && sharedMemoryParallelization == 0)
{
if (dirStatement[1] != NULL)
{

View File

@@ -11,7 +11,7 @@
#include "../Utils/types.h"
#include "../Utils/utils.h"
extern int mpiProgram;
extern int sharedMemoryParallelization;
struct LoopGraph;
@@ -143,10 +143,6 @@ public:
const uint64_t regionId,
const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls);
Directive*
genDirectiveNoDist(File* file, LoopGraph* currLoop, DIST::Arrays<int>& allArrays,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
friend ParallelDirective* operator+(const ParallelDirective &first, const ParallelDirective &second);
~ParallelDirective()
@@ -166,7 +162,7 @@ private:
std::string genBounds(std::pair<std::pair<std::string, std::string>, std::vector<std::pair<int, int>>> &shadowOp,
std::vector<std::pair<int, int>> &shadowOpShift,
DIST::GraphCSR<int, double, attrType> &reducedG,
DIST::Arrays<int> &allArrays,
DIST::Arrays<int> &allArrays, DIST::Array* shadowArray,
std::map<DIST::Array*, std::vector<ArrayOp>>& remoteRegularReads,
const std::map<DIST::Array*, std::pair<std::vector<ArrayOp>, std::vector<bool>>> &readOps,
const bool isAcross, const uint64_t regionId,

View File

@@ -111,7 +111,7 @@ ParallelDirective* operator+(const ParallelDirective &left, const ParallelDirect
checkNull(second, convertFileName(__FILE__).c_str(), __LINE__);
bool condition = first->arrayRef == second->arrayRef;
if (mpiProgram)
if (sharedMemoryParallelization)
condition = !hasConflictUniteOnRules(first->on, second->on) && !hasConflictUniteOnRules(first->on2, second->on2);
if (condition)
@@ -268,20 +268,23 @@ static inline string calculateShifts(DIST::GraphCSR<int, double, attrType> &redu
const uint64_t regionId,
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls)
{
vector<tuple<DIST::Array*, int, pair<int, int>>> ruleForOn =
getAlignRuleWithTemplate(arrayRef, arrayLinksByFuncCalls, reducedG, allArrays, regionId);
vector<tuple<DIST::Array*, int, pair<int, int>>> ruleForOn, ruleForShadow;
vector<tuple<DIST::Array*, int, pair<int, int>>> ruleForShadow =
getAlignRuleWithTemplate(calcForArray, arrayLinksByFuncCalls, reducedG, allArrays, regionId);
if (!sharedMemoryParallelization)
{
ruleForOn = getAlignRuleWithTemplate(arrayRef, arrayLinksByFuncCalls, reducedG, allArrays, regionId);
ruleForShadow = getAlignRuleWithTemplate(calcForArray, arrayLinksByFuncCalls, reducedG, allArrays, regionId);
}
string out = "";
// check for distributed and not mapped dims -> zero them out ('coeffs.second')
set<DIST::Array*> refs;
getRealArrayRefs(calcForArray, calcForArray, refs, arrayLinksByFuncCalls);
if (mpiProgram == 0)
{//TODO: need to correct errors
/*for (auto& array : refs)
//TODO: need to correct errors
/*if (!sharedMemoryParallelization)
{
for (auto& array : refs)
{
DIST::Array* tmpl = array->GetTemplateArray(regionId);
checkNull(tmpl, convertFileName(__FILE__).c_str(), __LINE__);
@@ -322,17 +325,20 @@ static inline string calculateShifts(DIST::GraphCSR<int, double, attrType> &redu
if (!found)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
} */
}
}
}*/
const pair<vector<ArrayOp>, vector<bool>> *currReadOp = NULL;
auto readIt = readOps.find(calcForArray);
if (readIt != readOps.end())
currReadOp = &(readIt->second);
findAndReplaceDimentions(ruleForOn, allArrays);
findAndReplaceDimentions(ruleForShadow, allArrays);
if(!sharedMemoryParallelization)
{
findAndReplaceDimentions(ruleForOn, allArrays);
findAndReplaceDimentions(ruleForShadow, allArrays);
}
const int len = (int)coeffs.second.size();
vector<pair<int, int>> shift(len);
@@ -352,7 +358,20 @@ static inline string calculateShifts(DIST::GraphCSR<int, double, attrType> &redu
// no unrecognized read operations
if (currReadOp->second[k] == false)
{
if (get<0>(ruleForShadow[k]) != NULL)
if (sharedMemoryParallelization)
{
for (auto& coefs : currReadOp->first[k].coefficients)
{
auto currAccess = coefs.first;
const int currShift = coefs.first.second;
auto itFound = shiftsByAccess[k].find(currAccess);
if (itFound == shiftsByAccess[k].end())
itFound = shiftsByAccess[k].insert(itFound, make_pair(currAccess, currShift));
}
}
else if (get<0>(ruleForShadow[k]) != NULL)
{
const pair<int, int> currRuleShadow = get<2>(ruleForShadow[k]);
@@ -451,22 +470,25 @@ static inline string calculateShifts(DIST::GraphCSR<int, double, attrType> &redu
}
}
if (coeffs.second[k].first + shift[k].first < 0)
shift[k].first = -coeffs.second[k].first;
if (coeffs.second[k].second + shift[k].second < 0)
shift[k].second = -coeffs.second[k].second;
if (isAcross)
if(!sharedMemoryParallelization)
{
if (coeffs.second[k] == make_pair(0, 0))
shift[k] = make_pair(0, 0);
}
else if (isNonDistributedDim(ruleForOn, ruleForShadow, k, distribution, parallelOnRule))
{
shift[k].first = -coeffs.second[k].first;
shift[k].second = -coeffs.second[k].second;
shiftsByAccess[k].clear();
if (coeffs.second[k].first + shift[k].first < 0)
shift[k].first = -coeffs.second[k].first;
if (coeffs.second[k].second + shift[k].second < 0)
shift[k].second = -coeffs.second[k].second;
if (isAcross)
{
if (coeffs.second[k] == make_pair(0, 0))
shift[k] = make_pair(0, 0);
}
else if (isNonDistributedDim(ruleForOn, ruleForShadow, k, distribution, parallelOnRule))
{
shift[k].first = -coeffs.second[k].first;
shift[k].second = -coeffs.second[k].second;
shiftsByAccess[k].clear();
}
}
sprintf(buf, "%d:%d", coeffs.second[k].first + shift[k].first, coeffs.second[k].second + shift[k].second);
@@ -486,7 +508,7 @@ static inline string calculateShifts(DIST::GraphCSR<int, double, attrType> &redu
string ParallelDirective::genBounds(pair<pair<string, string>, vector<pair<int, int>>> &shadowOp,
vector<pair<int, int>> &shadowOpShift,
DIST::GraphCSR<int, double, attrType> &reducedG,
DIST::Arrays<int> &allArrays,
DIST::Arrays<int> &allArrays, DIST::Array* shadowArray,
map<DIST::Array*, vector<ArrayOp>>& remoteRegularReads,
const map<DIST::Array*, pair<vector<ArrayOp>, vector<bool>>> &readOps,
const bool isAcross,
@@ -496,38 +518,40 @@ string ParallelDirective::genBounds(pair<pair<string, string>, vector<pair<int,
vector<map<pair<int, int>, int>> &shiftsByAccess,
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls) const
{
DIST::Array *shadowArray = allArrays.GetArrayByName(shadowOp.first.second);
checkNull(shadowArray, convertFileName(__FILE__).c_str(), __LINE__);
checkNull(shadowArray, convertFileName(__FILE__).c_str(), __LINE__);
auto on_ext = on;
//replace to template align ::on
if (arrayRef->IsTemplate() == false && mpiProgram == 0)
if(!sharedMemoryParallelization)
{
vector<tuple<DIST::Array*, int, pair<int, int>>> ruleForRef =
getAlignRuleWithTemplate(arrayRef, arrayLinksByFuncCalls, reducedG, allArrays, regionId);
findAndReplaceDimentions(ruleForRef, allArrays);
on_ext.clear();
for (int i = 0; i < ruleForRef.size(); ++i)
//replace to template align ::on
if (arrayRef->IsTemplate() == false)
{
if (get<0>(ruleForRef[i]))
vector<tuple<DIST::Array*, int, pair<int, int>>> ruleForRef =
getAlignRuleWithTemplate(arrayRef, arrayLinksByFuncCalls, reducedG, allArrays, regionId);
findAndReplaceDimentions(ruleForRef, allArrays);
on_ext.clear();
for (int i = 0; i < ruleForRef.size(); ++i)
{
on_ext.resize(get<0>(ruleForRef[i])->GetDimSize());
break;
if (get<0>(ruleForRef[i]))
{
on_ext.resize(get<0>(ruleForRef[i])->GetDimSize());
break;
}
}
if (on_ext.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
std::fill(on_ext.begin(), on_ext.end(), make_pair("*", make_pair(0, 0)));
for (int i = 0; i < ruleForRef.size(); ++i)
if (get<0>(ruleForRef[i]))
on_ext[get<1>(ruleForRef[i])] = on[i];
}
if (on_ext.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
std::fill(on_ext.begin(), on_ext.end(), make_pair("*", make_pair(0, 0)));
for (int i = 0; i < ruleForRef.size(); ++i)
if (get<0>(ruleForRef[i]))
on_ext[get<1>(ruleForRef[i])] = on[i];
}
//replace single dim to key word 'SINGLE'
for (int i = 0; i < on_ext.size(); ++i)
//replace single dim to key word 'SINGLE'
for (int i = 0; i < on_ext.size(); ++i)
{
if (on_ext[i].first != "*")
{
@@ -535,8 +559,9 @@ string ParallelDirective::genBounds(pair<pair<string, string>, vector<pair<int,
on_ext[i].first = "SINGLE";
}
}
}
string ret = "";
string ret = "";
if (isAcross)
{
arraysInAcross.insert(shadowArray);

View File

@@ -1,96 +0,0 @@
#include "../Utils/leak_detector.h"
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <string>
#include <algorithm>
#include "DvmhDirective.h"
#include "../Distribution/Array.h"
#include "../Distribution/Arrays.h"
#include "../Distribution/GraphCSR.h"
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "../GraphCall/graph_calls_func.h"
using std::vector;
using std::string;
using std::pair;
using std::set;
using std::map;
static inline string calculateShiftsNoDist(
DIST::Array* arrayRef, DIST::Array* calcForArray,
pair<pair<string, string>, vector<pair<int, int>>>& coeffs,
vector<pair<int, int>>& shifts,
vector<map<pair<int, int>, int>>& shiftsByAccess,
const map<DIST::Array*, pair<vector<ArrayOp>, vector<bool>>>& readOps,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
string out = "";
// check for distributed and not mapped dims -> zero them out ('coeffs.second')
set<DIST::Array*> refs;
getRealArrayRefs(calcForArray, calcForArray, refs, arrayLinksByFuncCalls);
const pair<vector<ArrayOp>, vector<bool>>* currReadOp = NULL;
auto readIt = readOps.find(calcForArray);
if (readIt != readOps.end())
currReadOp = &(readIt->second);
const int len = (int)coeffs.second.size();
bool allZero = true;
for (int k = 0; k < len; ++k)
{
shiftsByAccess.push_back(map<pair<int, int>, int>());
if (k != 0)
out += ",";
char buf[256];
// calculate correct shifts from readOp info
if (currReadOp)
{
// no unrecognized read operations
if (currReadOp->second[k] == false)
{
for (auto& coefs : currReadOp->first[k].coefficients)
{
auto currAccess = coefs.first;
const int currShift = coefs.first.second;
auto itFound = shiftsByAccess[k].find(currAccess);
if (itFound == shiftsByAccess[k].end())
itFound = shiftsByAccess[k].insert(itFound, make_pair(currAccess, currShift));
}
}
}
sprintf(buf, "%d:%d", coeffs.second[k].first, coeffs.second[k].second);
shifts[k] = {0, 0};
if (coeffs.second[k].first != 0 || coeffs.second[k].second != 0)
allZero = false;
out += buf;
}
if (allZero)
return "";
else
return out;
}
string ParallelDirective::genBoundsNoDist(pair<pair<string, string>, vector<pair<int, int>>>& shadowOp,
vector<pair<int, int>>& shadowOpShift,
DIST::Array* currArray,
const map<DIST::Array*, pair<vector<ArrayOp>, vector<bool>>>& readOps,
set<DIST::Array*>& arraysInAcross,
vector<map<pair<int, int>, int>>& shiftsByAccess,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls) const
{
arraysInAcross.insert(currArray);
return calculateShiftsNoDist(arrayRef, currArray, shadowOp, shadowOpShift, shiftsByAccess, readOps, arrayLinksByFuncCalls);
}

View File

@@ -1,17 +0,0 @@
#pragma once
#include <string>
#include <vector>
#include <set>
#include <map>
std::vector<int> sortShadow(const std::vector<std::pair<std::pair<std::string, std::string>, std::vector<std::pair<int, int>>>>& toSort);
std::set<SgSymbol*> changeLoopOrder(const std::vector<std::string>& parallel, const std::vector<std::string>& newParallel, std::vector<LoopGraph*>& loops);
std::set<SgSymbol*> fillPrivateOnlyFromSpfParameter(SgStatement* loop, const int altLine);
SgStatement* getModuleScope(const std::string& origFull, std::vector<SgStatement*>& moduleList, SgStatement* local);
std::string correctSymbolModuleName(const std::string& origFull);
SgStatement* getRealStat(const char* file, const int line, const int altLine);
std::multimap<std::string, Symbol*> setToMapWithSortByStr(const std::set<Symbol*>& setIn);
bool needCorner(const DIST::Array* currArray, const std::vector<std::map<std::pair<int, int>, int>>& shiftsByAccess, Statement* loop);

View File

@@ -1,477 +0,0 @@
#include "../Utils/leak_detector.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <vector>
#include <string>
#include <algorithm>
#include "../Utils/types.h"
#include "DvmhDirective.h"
#include "DvmhDirective_func.h"
#include "DvmhDirective_internal.h"
#include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "../Sapfor.h"
#include "../GraphCall/graph_calls_func.h"
#include "dvm.h"
using std::vector;
using std::tuple;
using std::get;
using std::string;
using std::pair;
using std::set;
using std::map;
using std::make_pair;
static vector<SgExpression*>
compliteTieListNoDist(const LoopGraph* currLoop,
const set<string>& privates,
const vector<LoopGraph*>& loops,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const map<string, set<SgSymbol*>>& byUseInFunc,
File* file, const pair<int, int>& lineRange)
{
vector<SgExpression*> tieList;
if (currLoop->usedArraysAll.size() == 0)
return tieList;
SgVarRefExp* zeroS = new SgVarRefExp(findSymbolOrCreate(file, "*"));
for (auto& elem : currLoop->usedArraysAll)
{
if (privates.find(elem->GetShortName()) != privates.end())
continue;
auto type = elem->GetDeclSymbol(currLoop->fileName, lineRange, getAllFilesInProject())->GetOriginal()->type();
SgSymbol* arrayS = getFromModule(byUseInFunc, findSymbolOrCreate(file, elem->GetShortName(), type));
SgArrayRefExp* array = new SgArrayRefExp(*arrayS);
bool needToAdd = false;
vector<SgExpression*> subs;
for (int k = 0; k < elem->GetDimSize(); ++k)
subs.push_back(&zeroS->copy());
for (int z = 0; z < loops.size(); ++z)
{
currLoop = loops[z];
for (const auto& source : { currLoop->readOpsForLoop, currLoop->writeOpsForLoop }) {
auto array_it = source.find(elem);
if (array_it != source.end()) {
bool dim_found = false;
for (int i = 0; i < array_it->second.size(); i++) {
if (array_it->second[i].coefficients.size() != 0)
{
needToAdd = true;
dim_found = true;
subs[i] = new SgVarRefExp(findSymbolOrCreate(file, currLoop->loopSymbol));
break;
}
}
if (dim_found)
break;
}
}
}
if (needToAdd)
{
for (int k = 0; k < subs.size(); ++k)
array->addSubscript(*subs[k]);
tieList.push_back(array);
}
}
return tieList;
}
Directive*
ParallelDirective::genDirectiveNoDist(File* file, LoopGraph* currLoop, DIST::Arrays<int>& allArrays,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
const set<DIST::Array*>& acrossOutAttribute = currLoop->acrossOutAttribute;
const map<DIST::Array*, pair<vector<ArrayOp>, vector<bool>>>& readOps = currLoop->readOps;
map< DIST::Array*, vector<ArrayOp>>& remoteReads = currLoop->remoteRegularReads;
Statement* loop = currLoop->loop;
string directive = "";
vector<Expression*> dirStatement = { NULL, NULL, NULL };
SgForStmt* loopG = (SgForStmt*)loop->GetOriginal();
vector<SgStatement*> moduleList;
findModulesInFile(file, moduleList);
SgStatement* realStat = getRealStat(file->filename(), currLoop->lineNum, currLoop->altLineNum);
SgStatement* parentFunc = getFuncStat(realStat);
const map<string, set<SgSymbol*>> byUseInFunc = moduleRefsByUseInFunction(realStat);
const int nested = countPerfectLoopNest(loopG);
const pair<int, int> lineRange = make_pair(parentFunc->lineNumber(), parentFunc->lastNodeOfStmt()->lineNumber());
const string& filename = currLoop->fileName;
vector<SgSymbol*> loopSymbs;
vector<LoopGraph*> loops;
LoopGraph* pLoop = currLoop;
const set<string> allFiles = getAllFilesInProject();
map<string, DIST::Array*> arrayByName;
for (DIST::Array* arr : currLoop->getAllArraysInLoop())
arrayByName[arr->GetName()] = arr;
for (int z = 0; z < nested; ++z)
{
loopSymbs.push_back(loopG->symbol());
auto next = loopG->lexNext();
auto attrSpfPar = getAttributes<SgStatement*, SgStatement*>(next, set<int>{ SPF_PARAMETER_OP });
while (attrSpfPar.size() != 0 && next)
{
next = next->lexNext();
attrSpfPar = getAttributes<SgStatement*, SgStatement*>(next, set<int>{ SPF_PARAMETER_OP });
}
if (next->variant() != FOR_NODE && z + 1 < nested)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
loopG = (SgForStmt*)next;
loops.push_back(pLoop);
if (pLoop->children.size())
pLoop = pLoop->children[0];
}
SgExpression* expr = new SgExpression(EXPR_LIST);
SgExpression* p = expr;
directive += "!DVM$ PARALLEL(";
//filter parallel
vector<string> filteredParalel;
for (int i = 0; i < (int)parallel.size(); ++i)
if (parallel[i] != "*")
filteredParalel.push_back(parallel[i]);
set<SgSymbol*> privatesAfterSwap = changeLoopOrder(parallel, filteredParalel, loops);
for (int i = 0; i < (int)filteredParalel.size(); ++i)
{
if (filteredParalel[i] == "*")
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (i == 0)
directive += filteredParalel[i];
else
directive += "," + filteredParalel[i];
SgVarRefExp* tmp = NULL;
tmp = new SgVarRefExp(findSymbolOrCreate(file, filteredParalel[i]));
p->setLhs(tmp);
if (i != (int)filteredParalel.size() - 1)
p = createAndSetNext(RIGHT, EXPR_LIST, p);
else
p->setRhs(NULL);
}
dirStatement[2] = new Expression(expr);
directive += ")";
SgArrayRefExp* arrayExpr = NULL;
string arrayExprS = "";
expr = new SgExpression(EXPR_LIST);
p = expr;
dirStatement[1] = NULL;
set<string> uniqNamesOfPrivates;
for (auto& elem : privates)
uniqNamesOfPrivates.insert(elem->identifier());
auto unitedPrivates = privates;
for (auto& elem : privatesAfterSwap)
{
if (uniqNamesOfPrivates.find(elem->identifier()) == uniqNamesOfPrivates.end())
{
unitedPrivates.insert(new Symbol(elem));
uniqNamesOfPrivates.insert(elem->identifier());
}
}
if (unitedPrivates.size() != 0)
{
p = createAndSetNext(LEFT, ACC_PRIVATE_OP, p);
directive += ", PRIVATE(";
int k = 0;
vector<SgExpression*> list;
auto spfParVars = fillPrivateOnlyFromSpfParameter(loop, currLoop->lineNum < 0 ? currLoop->altLineNum : 0);
for (auto& privVar : setToMapWithSortByStr(unitedPrivates))
{
bool isSfpPriv = false;
for (auto& elem : spfParVars)
if (OriginalSymbol(elem)->identifier() == string(OriginalSymbol(privVar.second)->identifier()))
isSfpPriv = true;
if (isSfpPriv)
continue;
directive += (k != 0) ? "," + privVar.first : privVar.first;
list.push_back(new SgVarRefExp(getFromModule(byUseInFunc, privVar.second)));
++k;
}
directive += ")";
dirStatement[1] = new Expression(expr);
p->setLhs(makeExprList(list));
}
vector<LoopGraph*> loopsTie;
for (int i = 0; i < (int)parallel.size(); ++i)
if (parallel[i] != "*")
loopsTie.push_back(loops[i]);
vector<SgExpression*> tieList;
tieList = compliteTieListNoDist(currLoop, uniqNamesOfPrivates, loopsTie, arrayLinksByFuncCalls, byUseInFunc, file, lineRange);
if (tieList.size())
{
if (dirStatement[1] != NULL)
{
expr = createAndSetNext(RIGHT, EXPR_LIST, expr);
p = expr;
}
p = createAndSetNext(LEFT, ACC_TIE_OP, p);
p->setLhs(makeExprList(tieList));
directive += ", TIE(";
int k = 0;
for (auto& tieL : tieList)
{
if (k != 0)
directive += ",";
directive += tieL->unparse();
++k;
}
directive += ")";
}
set<DIST::Array*> arraysInAcross;
if (across.size() != 0)
{
if (acrossShifts.size() == 0)
{
acrossShifts.resize(across.size());
for (int i = 0; i < across.size(); ++i)
acrossShifts[i].resize(across[i].second.size());
}
//TODO: add "OUT" key for string representation
string acrossAdd = ", ACROSS(";
int inserted = 0;
SgExpression* acr_out = new SgExpression(EXPR_LIST);
SgExpression* p_out = acr_out;
SgExpression* acr_in = new SgExpression(EXPR_LIST);
SgExpression* p_in = acr_in;
SgExpression* acr_op = NULL;
int inCount = 0;
int outCount = 0;
vector<int> ordered = sortShadow(across);
for (int k = 0; k < (int)across.size(); ++k)
{
const int i1 = ordered[k];
vector<map<pair<int, int>, int>> shiftsByAccess;
auto currArray_it = arrayByName.find(across[i1].first.second);
if (currArray_it == arrayByName.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
DIST::Array* currArray = currArray_it->second;
bool isOut = acrossOutAttribute.find(currArray) != acrossOutAttribute.end();
string bounds = genBoundsNoDist(across[i1], acrossShifts[i1], currArray, readOps, arraysInAcross, shiftsByAccess, arrayLinksByFuncCalls);
if (bounds != "")
{
if (inserted != 0)
{
acrossAdd += ",";
if (isOut)
{
if (outCount > 0)
p_out = createAndSetNext(RIGHT, EXPR_LIST, p_out);
outCount++;
p = p_out;
}
else
{
if (inCount > 0)
p_in = createAndSetNext(RIGHT, EXPR_LIST, p_in);
inCount++;
p = p_in;
}
}
else if (inserted == 0)
{
if (dirStatement[1] != NULL)
expr = createAndSetNext(RIGHT, EXPR_LIST, expr);
acr_op = createAndSetNext(LEFT, ACROSS_OP, expr);
if (isOut)
{
outCount++;
p = p_out;
}
else
{
inCount++;
p = p_in;
}
}
acrossAdd += across[i1].first.first + "(" + bounds + ")";
SgArrayRefExp* newArrayRef = new SgArrayRefExp(*getFromModule(byUseInFunc, currArray->GetDeclSymbol(filename, lineRange, allFiles)->GetOriginal()));
newArrayRef->addAttribute(ARRAY_REF, currArray, sizeof(DIST::Array));
for (auto& elem : genSubscripts(across[i1].second, acrossShifts[i1]))
newArrayRef->addSubscript(*elem);
p->setLhs(newArrayRef);
inserted++;
}
}
acrossAdd += ")";
if (inserted > 0)
{
directive += acrossAdd;
if (dirStatement[1] == NULL)
dirStatement[1] = new Expression(expr);
if (acrossOutAttribute.size() > 0)
{
SgExpression* tmp = new SgExpression(DDOT, new SgKeywordValExp("OUT"), acr_out, NULL);
acr_op->setLhs(*tmp);
if (inCount != 0)
acr_op->setRhs(acr_in);
}
else
acr_op->setLhs(acr_in);
}
}
if (reduction.size() != 0)
{
if (dirStatement[1] != NULL)
{
expr = createAndSetNext(RIGHT, EXPR_LIST, expr);
p = expr;
}
p = createAndSetNext(LEFT, REDUCTION_OP, p);
p = createAndSetNext(LEFT, EXPR_LIST, p);
directive += ", REDUCTION(";
int k = 0;
for (auto it = reduction.begin(); it != reduction.end(); ++it)
{
const string& nameGroup = it->first;
for (auto& list : it->second)
{
if (k != 0)
{
directive += ",";
p = createAndSetNext(RIGHT, EXPR_LIST, p);
}
SgSymbol* base = findSymbolOrCreate(file, correctSymbolModuleName(list), NULL, getModuleScope(list, moduleList, parentFunc));
SgSymbol* redS = getFromModule(byUseInFunc, base, list.find("::") != string::npos);
directive += nameGroup + "(" + redS->identifier() + ")";
SgVarRefExp* tmp2 = new SgVarRefExp(redS);
SgFunctionCallExp* tmp1 = new SgFunctionCallExp(*findSymbolOrCreate(file, nameGroup), *tmp2);
p->setLhs(tmp1);
++k;
}
}
if (reductionLoc.size() != 0)
directive += ", ";
else
{
directive += ")";
if (dirStatement[1] == NULL)
dirStatement[1] = new Expression(expr);
}
}
if (reductionLoc.size() != 0)
{
if (dirStatement[1] != NULL && reduction.size() == 0)
{
expr = createAndSetNext(RIGHT, EXPR_LIST, expr);
p = expr;
}
if (reduction.size() == 0)
{
p = createAndSetNext(LEFT, REDUCTION_OP, p);
p = createAndSetNext(LEFT, EXPR_LIST, p);
directive += ", REDUCTION(";
}
else
p = createAndSetNext(RIGHT, EXPR_LIST, p);
int k = 0;
for (auto it = reductionLoc.begin(); it != reductionLoc.end(); ++it)
{
const string& nameGroup = it->first;
for (auto& list : it->second)
{
if (k != 0)
{
directive += ",";
p = createAndSetNext(RIGHT, EXPR_LIST, p);
}
SgSymbol* base1 = findSymbolOrCreate(file, correctSymbolModuleName(get<0>(list)), NULL, getModuleScope(get<0>(list), moduleList, parentFunc));
SgSymbol* base2 = findSymbolOrCreate(file, correctSymbolModuleName(get<1>(list)), NULL, getModuleScope(get<1>(list), moduleList, parentFunc));
SgSymbol* redS1 = getFromModule(byUseInFunc, base1, get<0>(list).find("::") != string::npos);
SgSymbol* redS2 = getFromModule(byUseInFunc, base2, get<1>(list).find("::") != string::npos);
directive += nameGroup + "(" + redS1->identifier() + ", " + redS2->identifier() + ", " + std::to_string(get<2>(list)) + ")";
SgFunctionCallExp* tmp1 = new SgFunctionCallExp(*findSymbolOrCreate(file, nameGroup));
tmp1->addArg(*new SgVarRefExp(redS1));
tmp1->addArg(*new SgVarRefExp(redS2));
tmp1->addArg(*new SgValueExp(get<2>(list)));
p->setLhs(tmp1);
++k;
}
}
directive += ")";
if (dirStatement[1] == NULL)
dirStatement[1] = new Expression(expr);
}
directive += "\n";
auto dir = new CreatedDirective(directive, dirStatement);
dir->line = currLoop->lineNum;
return dir;
}

View File

@@ -1166,7 +1166,7 @@ void DvmhRegionInserter::removePrivatesFromParallelLoops()
if (lexPrev->variant() == DVM_PARALLEL_ON_DIR)
{
if (mpiProgram == 1)
if (sharedMemoryParallelization == 1)
lexPrev->deleteStmt();
else
{
@@ -1309,7 +1309,7 @@ void insertDvmhRegions(SgProject& project, int files, const vector<ParallelRegio
const map<DIST::Array*, set<DIST::Array*>> arrayLinksByFuncCalls)
{
vector<DvmhRegionInserter*> inserters;
const bool regionCondition = ((parallelRegions.size() == 0 && parallelRegions[0]->GetName() == "DEFAULT") || mpiProgram == 1);
const bool regionCondition = ((parallelRegions.size() == 0 && parallelRegions[0]->GetName() == "DEFAULT") || sharedMemoryParallelization == 1);
set<DIST::Array*> usedArraysInRegions;
set<DIST::Array*> usedWriteArraysInRegions;
@@ -1328,7 +1328,7 @@ void insertDvmhRegions(SgProject& project, int files, const vector<ParallelRegio
for (auto& loop : loopsForFile)
loop->analyzeParallelDirs();
DvmhRegionInserter* regionInserter = new DvmhRegionInserter(file, loopsForFile, rw_analyzer, arrayLinksByFuncCalls, mapOfFuncs, funcsForFile, mpiProgram == 1);
DvmhRegionInserter* regionInserter = new DvmhRegionInserter(file, loopsForFile, rw_analyzer, arrayLinksByFuncCalls, mapOfFuncs, funcsForFile, sharedMemoryParallelization == 1);
inserters.push_back(regionInserter);
//collect info about <parallel> functions

View File

@@ -45,4 +45,4 @@ int Perform::getPercent() { return percent; }
void Perform::setNumber(int a) { number = a; }
void Perform::setPercent(int a) { percent = a; }
void Perform::gcov_print() { __spf_print(1, "%d - %d\n", number, percent); }
ostream &operator<<(ostream &out, const Perform &a) { out << "number= " << a.number << "\npercent= " << a.percent << endl; return out; }
ostream &operator<<(ostream &out, const Perform &a) { out << "number= " << a.number << ": percent= " << a.percent << endl; return out; }

View File

@@ -849,12 +849,12 @@ void excludeArraysFromDistribution(const map<DIST::Array*, set<DIST::Array*>>& a
vector<ParallelRegion*> parallelRegions,
map<string, vector<Messages>>& SPF_messages,
map<tuple<int, string, string>, DIST::Array*>& createdArrays,
int mpiProgram)
int sharedMemoryParallelization)
{
checkArraysMapping(loopGraph, SPF_messages, arrayLinksByFuncCalls);
propagateArrayFlags(arrayLinksByFuncCalls, declaredArrays, SPF_messages);
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
{
for (int z = 0; z < parallelRegions.size(); ++z)
filterArrayInCSRGraph(loopGraph, allFuncInfo, parallelRegions[z], arrayLinksByFuncCalls, SPF_messages);

View File

@@ -34,7 +34,7 @@ void createMapOfFunc(const std::vector<FuncInfo*> &allFuncInfo, std::map<std::pa
FuncInfo* getFuncInfo(const std::map<std::string, FuncInfo*> &funcMap, const std::string &funcName);
void updateFuncInfo(const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo);
void excludeArraysFromDistribution(const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays, std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::vector<ParallelRegion*> parallelRegions, std::map<std::string, std::vector<Messages>>& SPF_messages, std::map<std::tuple<int, std::string, std::string>, DIST::Array*>& createdArrays, int mpiProgram = 0);
void excludeArraysFromDistribution(const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays, std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::vector<ParallelRegion*> parallelRegions, std::map<std::string, std::vector<Messages>>& SPF_messages, std::map<std::tuple<int, std::string, std::string>, DIST::Array*>& createdArrays, int sharedMemoryParallelization = 0);
#if __SPF
void functionAnalyzer(SgFile *file, std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, const std::vector<LoopGraph*> &loops, std::vector<Messages> &messagesForFile, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR);

View File

@@ -1,303 +0,0 @@
#include "select_array_conf.h"
#include "../Utils/utils.h"
using std::map;
using std::string;
using std::vector;
using std::set;
using std::pair;
using std::wstring;
using std::inserter;
using std::copy;
using std::to_string;
bool IsSetsIntersect(const set<DIST::Array*>& lhs, const set<DIST::Array*>& rhs)
{
if (lhs.empty() || rhs.empty())
return false;
if (lhs.size() * 100 < rhs.size())
{
for (const auto& x : lhs)
if (rhs.find(x) != rhs.end())
return true;
return false;
}
if (rhs.size() * 100 < lhs.size())
{
for (const auto& x : rhs)
if (lhs.find(x) != lhs.end())
return true;
return false;
}
auto l_it = lhs.begin(), l_end = lhs.end();
auto r_it = rhs.begin(), r_end = rhs.end();
while (l_it != l_end && r_it != r_end)
{
if (*l_it < *r_it)
{
l_it = lhs.lower_bound(*r_it);
continue;
}
if (*r_it < *l_it)
{
r_it = rhs.lower_bound(*l_it);
continue;
}
return true;
}
return false;
}
static void findUsedArraysInParallelLoops(LoopGraph* loop, set<DIST::Array*>& res)
{
if(loop->directive)
copy(loop->usedArraysAll.begin(), loop->usedArraysAll.end(), inserter(res, res.end()));
else
for(LoopGraph* child : loop->children)
findUsedArraysInParallelLoops(child, res);
}
static void preventLoopsFromParallelizations(LoopGraph* loop, const set<DIST::Array*>& prevent,
vector<Messages>& messagesForFile)
{
if (loop->directive)
{
if (IsSetsIntersect(prevent, loop->usedArraysAll))
{
// prevent this loop
delete loop->directive;
loop->directive = NULL;
vector<DIST::Array*> conflict_arrays; // = prevent \intersection loop->usedArraysAll
set_intersection(prevent.begin(), prevent.end(),
loop->usedArraysAll.begin(), loop->usedArraysAll.end(),
back_inserter(conflict_arrays));
for(auto& conflict_array : conflict_arrays)
{
// constructing string with array and it's sizes
string array_bounds;
const auto& array_sizes = conflict_array->GetSizes();
for(int i = 0; i < array_sizes.size(); i++)
{
if(i != 0)
array_bounds += ",";
array_bounds += "*";
}
string array_ref = conflict_array->GetShortName() + "(" + array_bounds + ")";
// add conflict message
std::wstring bufE, bufR;
__spf_printToLongBuf(bufE, L"Array reference '%s' has a different size from the original array", to_wstring(array_ref).c_str());
__spf_printToLongBuf(bufR, R202, to_wstring(array_ref).c_str());
messagesForFile.push_back(Messages(WARR, loop->lineNum, bufR, bufE, 3023));
loop->hasAccessToSubArray = true;
}
if(!conflict_arrays.empty())
messagesForFile.push_back(Messages(NOTE, loop->lineNum, R204, L"Array's memory intersections prevents this loop from parallelization", 3024));
}
}
for (LoopGraph* child : loop->children)
preventLoopsFromParallelizations(child, prevent, messagesForFile);
}
struct DimConf
{
vector<pair<int, int>> dims;
DimConf(DIST::Array* a) : dims(a->GetSizes()) { }
friend bool operator<(const DimConf& l, const DimConf& r) { return l.dims < r.dims; }
};
static map<DimConf, map<FuncInfo*, set<DIST::Array*>>>::const_iterator
pickBest(const map<DimConf, map<FuncInfo*, set<DIST::Array*>>>& arrs)
{
const int undefined = -1;
int max_elems = undefined;
auto best_it = arrs.begin();
for (auto it = arrs.begin(); it != arrs.end(); it++)
{
int elems = 1;
for (const auto& p : it->first.dims)
{
if(p.first >= 0 && p.second >= p.first)
{
elems *= p.second - p.first;
}
else
{
elems = undefined;
break;
}
}
if (elems > max_elems)
{
max_elems = elems;
best_it = it;
}
}
return best_it;
}
void SelectArrayConfForParallelization(SgProject* proj, map<string, vector<FuncInfo*>>& funcByFile,
const map<string, vector<LoopGraph*>>& loopGraph,
map<string, vector<Messages>>& allMessages,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
map<string, FuncInfo*> funcByName;
for (const auto& byFile : funcByFile)
for(const auto& byFunc : byFile.second)
funcByName[byFunc->funcName] = byFunc;
// array(real ref) dims func array in func
map<DIST::Array*, map<DimConf, map<FuncInfo*, set<DIST::Array*>>>> usedArrays;
for (const auto& byFile : loopGraph)
{
SgFile::switchToFile(byFile.first);
auto& loops = byFile.second;
auto file_funcs_it = funcByFile.find(byFile.first);
if(file_funcs_it == funcByFile.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); // no such file in funcByFile
map<FuncInfo*, set<DIST::Array*>> usedInLoops;
for (const auto& loop : loops)
{
SgStatement* search_func = loop->loop->GetOriginal();
while (search_func && (!isSgProgHedrStmt(search_func)))
search_func = search_func->controlParent();
if (!search_func)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //loop statement outside any function statement
bool loop_analyzed = false;
for (const auto& byFunc : file_funcs_it->second)
{
if (byFunc->funcPointer->GetOriginal() == search_func)
{
if(!loop->usedArraysAll.empty())
findUsedArraysInParallelLoops(loop, usedInLoops[byFunc]);
loop_analyzed = true;
break;
}
}
if (!loop_analyzed)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //no func found for loop
}
for (const auto& byFunc : usedInLoops)
{
for (DIST::Array* arr : byFunc.second)
{
set<DIST::Array*> realRefs;
getRealArrayRefs(arr, arr, realRefs, arrayLinksByFuncCalls);
bool fullUnknownSizes = true;
for (auto& dim : arr->GetSizes())
{
if (dim.first == dim.second && dim.first != -1)
fullUnknownSizes = false;
}
if (fullUnknownSizes && realRefs.find(arr) != realRefs.end())
continue;
for(DIST::Array* ref : realRefs)
usedArrays[ref][DimConf(arr)][byFunc.first].insert(arr);
}
}
}
map<FuncInfo*, set<DIST::Array*>> preventFromParallelization;
for (const auto& byRealRef : usedArrays)
{
DIST::Array* realRef = byRealRef.first;
auto& refferedDims = byRealRef.second;
// prevent from parallelization all configurations except best one
auto best_conf_it = pickBest(refferedDims);
for (auto by_worse_dim_conf_it = refferedDims.begin(); by_worse_dim_conf_it != refferedDims.end(); by_worse_dim_conf_it++)
{
if(by_worse_dim_conf_it != best_conf_it)
{
for (const auto& byFunc : by_worse_dim_conf_it->second)
{
FuncInfo* f = byFunc.first;
auto& to_prevent = byFunc.second;
auto& destSet = preventFromParallelization[f];
copy(to_prevent.begin(), to_prevent.end(), inserter(destSet, destSet.end()));
}
}
}
}
for (const auto& byFile : loopGraph)
{
vector<Messages>& fileM = getObjectForFileFromMap(byFile.first.c_str(), allMessages);
SgFile::switchToFile(byFile.first);
auto& loops = byFile.second;
auto file_funcs_it = funcByFile.find(byFile.first);
if (file_funcs_it == funcByFile.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); // no such file in funcByFile
map<FuncInfo*, set<DIST::Array*>> usedInLoops;
for (const auto& loop : loops)
{
SgStatement* search_func = loop->loop->GetOriginal();
while (search_func && (!isSgProgHedrStmt(search_func)))
search_func = search_func->controlParent();
if (!search_func)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //loop statement outside any function statement
bool loop_analyzed = false;
for (const auto& byFunc : file_funcs_it->second)
{
if (byFunc->funcPointer->GetOriginal() == search_func)
{
auto prevent_it = preventFromParallelization.find(byFunc);
if (prevent_it != preventFromParallelization.end())
preventLoopsFromParallelizations(loop, prevent_it->second, fileM);
loop_analyzed = true;
break;
}
}
if (!loop_analyzed)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //no func found for loop
}
}
}

View File

@@ -1,16 +0,0 @@
#pragma once
#include<map>
#include<string>
#include<vector>
#include<set>
#include "../Distribution/Distribution.h"
#include "../GraphLoop/graph_loops.h"
#include "../ParallelizationRegions/ParRegions.h"
void SelectArrayConfForParallelization(SgProject* proj, std::map<std::string, std::vector<FuncInfo*>>& funcByFile,
const std::map<std::string, std::vector<LoopGraph*>>& loopGraph,
std::map<std::string, std::vector<Messages>>& allMessages,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);

View File

@@ -318,7 +318,7 @@ bool checkRegionEntries(SgStatement *begin,
return noError;
}
bool hasThisIds(SgStatement *start, set<int> &lines, const set<int> &IDs, const std::set<SgStatement*>* activeOps)
bool hasThisIds(SgStatement *start, set<int> &lines, const set<int> &IDs, const set<SgStatement*>* activeOps)
{
bool has = false;
SgStatement *end = start->lastNodeOfStmt();
@@ -333,7 +333,8 @@ bool hasThisIds(SgStatement *start, set<int> &lines, const set<int> &IDs, const
if (var == ENTRY_STAT)
continue;
if (activeOps && activeOps->size() && activeOps->find(curr) == activeOps->end())
if (activeOps && activeOps->size() && activeOps->find(curr) == activeOps->end() &&
isSgExecutableStatement(curr))
{
curr = curr->lastNodeOfStmt();
continue;
@@ -423,7 +424,7 @@ static bool hasNonRect(SgForStmt *st, const vector<LoopGraph*> &parentLoops, vec
SgExpression* end = st->end();
SgExpression* step = st->step();
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
{
set<DIST::Array*> usedArrays;
@@ -609,7 +610,7 @@ static bool hasSubstringRef(SgStatement* loop)
return false;
}
void loopGraphAnalyzer(SgFile *file, vector<LoopGraph*> &loopGraph, const vector<SpfInterval*> &intervalTree, vector<Messages> &messages, int mpiProgram)
void loopGraphAnalyzer(SgFile *file, vector<LoopGraph*> &loopGraph, const vector<SpfInterval*> &intervalTree, vector<Messages> &messages, int sharedMemoryParallelization)
{
map<int, SpfInterval*> mapIntervals;
createMapOfinterval(mapIntervals, intervalTree);
@@ -911,14 +912,8 @@ extern int PASSES_DONE[EMPTY_PASS];
static void printToBuffer(const LoopGraph *currLoop, const int childSize, char buf[512])
{
int loopState = 0; // 0 - unknown, 1 - good, 2 - bad
if (PASSES_DONE[CREATE_TEMPLATE_LINKS])
{
if (currLoop->hasLimitsToParallel())
loopState = 2;
else
loopState = 1;
}
else if (PASSES_DONE[SELECT_ARRAY_DIM_CONF])
if (PASSES_DONE[CREATE_TEMPLATE_LINKS] ||
PASSES_DONE[LOOP_ANALYZER_NODIST])
{
if (currLoop->hasLimitsToParallel())
loopState = 2;

View File

@@ -327,7 +327,7 @@ public:
bool isArrayTemplatesTheSame(DIST::Array*& sameTemplate, const uint64_t regId, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls)
{
if (mpiProgram != 0)
if (sharedMemoryParallelization != 0)
return true;
std::set<DIST::Array*> usedForRegAccess;

View File

@@ -567,12 +567,12 @@ void addToDistributionGraph(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>
getRealArrayRefs(access.first, access.first, realArrayRefs[access.first], arrayLinksByFuncCalls);
bool has_Wr_edges = false, has_Ww_edges = false, has_Rr_edges = false;
has_Wr_edges = processLinks(currAccessesV, allArrays, realArrayRefs, mpiProgram == 0 ? G :loopGraph, WW_link);
has_Ww_edges |= processLinks(currAccessesV, allArrays, realArrayRefs, mpiProgram == 0 ? G : loopGraph, WR_link);
has_Wr_edges = processLinks(currAccessesV, allArrays, realArrayRefs, sharedMemoryParallelization == 0 ? G :loopGraph, WW_link);
has_Ww_edges |= processLinks(currAccessesV, allArrays, realArrayRefs, sharedMemoryParallelization == 0 ? G : loopGraph, WR_link);
if (!has_Wr_edges && !has_Ww_edges)
has_Rr_edges = processLinks(currAccessesV, allArrays, realArrayRefs, mpiProgram == 0 ? G : loopGraph, RR_link);
has_Rr_edges = processLinks(currAccessesV, allArrays, realArrayRefs, sharedMemoryParallelization == 0 ? G : loopGraph, RR_link);
if (mpiProgram)
if (sharedMemoryParallelization)
{
if (!has_Wr_edges && !has_Ww_edges && !has_Rr_edges)
for (auto& elem : realArrayRefs)

View File

@@ -7,7 +7,7 @@
struct SpfInterval;
void loopGraphAnalyzer(SgFile *file, std::vector<LoopGraph*> &loopGraph, const std::vector<SpfInterval*> &statisticTimes, std::vector<Messages> &messages, int mpiProgram);
void loopGraphAnalyzer(SgFile *file, std::vector<LoopGraph*> &loopGraph, const std::vector<SpfInterval*> &statisticTimes, std::vector<Messages> &messages, int sharedMemoryParallelization);
void findAllRefsToLables(SgStatement *st, std::map<int, std::vector<int>> &labelsRef, bool includeWrite = true);
std::map<LoopGraph*, ParallelDirective*> findAllDirectives(SgFile *file, const std::vector<LoopGraph*> &loops, const uint64_t regId);
std::vector<std::tuple<DIST::Array*, std::vector<long>, std::pair<std::string, int>>> findAllSingleRemotes(SgFile *file, const uint64_t regId, std::vector<ParallelRegion*> &regions);

View File

@@ -1019,6 +1019,10 @@ static void insert(SgStatement* callSt, SgStatement* tempHedr, SgStatement* begi
st->setlineNumber(getNextNegativeLineNumber());
}
next = prev->lexNext();
next->setlineNumber(callSt->lineNumber());
next->setFileName(callSt->fileName());
last->extractStmt();
if (callSt->variant() == PROC_STAT)
@@ -2287,6 +2291,7 @@ static void createDeclarations(const map<SgStatement*, set<SgSymbol*>>& newSymbs
for (auto& elem : sortConstRefs(constRefs))
param->addConstant(elem);
param->setlineNumber(place->lineNumber());
place->insertStmtBefore(*param, *scope);
}
@@ -2356,8 +2361,13 @@ static void createDeclarations(const map<SgStatement*, set<SgSymbol*>>& newSymbs
}
if (newCommons.size())
{
for (auto& elem : newCommons)
{
elem->setlineNumber(place->lineNumber());
place->insertStmtBefore(*elem, *scope);
}
}
//insert SAVE
if (saveRefs.size())
@@ -2367,6 +2377,8 @@ static void createDeclarations(const map<SgStatement*, set<SgSymbol*>>& newSymbs
for (auto& s : saveRefs)
refs.push_back(new SgVarRefExp(s.second));
save->setExpression(0, makeExprList(refs));
save->setlineNumber(place->lineNumber());
place->insertStmtBefore(*save, *scope);
}
@@ -2389,18 +2401,21 @@ static void createDeclarations(const map<SgStatement*, set<SgSymbol*>>& newSymbs
strcpy(value->thellnd->entry.string_val, dataS.c_str());
decl->setExpression(0, value);
decl->setlineNumber(place->lineNumber());
place->insertStmtBefore(*decl, *scope);
}
//insert ALLOCATABLE
if (allocatable.size())
{
SgStatement* save = new SgStatement(ALLOCATABLE_STMT);
SgStatement* alloc_stat = new SgStatement(ALLOCATABLE_STMT);
vector<SgExpression*> refs;
for (auto& s : allocatable)
refs.push_back(new SgVarRefExp(s));
save->setExpression(0, makeExprList(refs));
place->insertStmtBefore(*save, *scope);
alloc_stat->setExpression(0, makeExprList(refs));
alloc_stat->setlineNumber(place->lineNumber());
place->insertStmtBefore(*alloc_stat, *scope);
}
}
}

View File

@@ -14,10 +14,57 @@
#include <utility>
#include <assert.h>
#include "loop_analyzer_internal.h"
#include "loop_analyzer.h"
#include <tuple>
#include <stack>
#include "../Utils/leak_detector.h"
#if _WIN32 && NDEBUG && __BOOST
#include <boost/thread.hpp>
#endif
extern int passDone;
#include "../Distribution/Distribution.h"
#include "../Distribution/GraphCSR.h"
#include "../Distribution/Arrays.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "../Utils/errors.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../DirectiveProcessing/directive_creator.h"
#include "../Utils/SgUtils.h"
#include "../Utils/AstWrapper.h"
#include "../GraphCall/graph_calls_func.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../ParallelizationRegions/ParRegions_func.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "../ExpressionTransform/expr_transform.h"
#include "../SageAnalysisTool/depInterfaceExt.h"
#include "../VisualizerCalls/get_information.h"
#include "../VisualizerCalls/SendMessage.h"
#include "../Transformations/enddo_loop_converter.h"
#include "../DirectiveProcessing/remote_access.h"
#include "../DirectiveProcessing/directive_omp_parser.h"
#define PRINT_ARRAY_ARCS 0
#define PRINT_LOOP_STRUCT 0
#define PRINT_PROF_INFO 0
#define DEB 0
extern REGIME currRegime;
extern std::vector<Messages>* currMessages;
extern int sharedMemoryParallelization;
extern int ignoreIO;
extern int parallizeFreeLoops;
using std::vector;
using std::pair;
using std::tuple;
@@ -126,7 +173,9 @@ static void addInfoToMap(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, S
__spf_print(DEB, "RemoteAccess[%d]: true for dim %d and array %s, loop line %d\n", __LINE__, dimNum, symb->identifier(), position->lineNumber());
}
void addInfoToVectors(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, SgForStmt *position, SgSymbol *symb,
enum { READ_OP, WRITE_OP, UNREC_OP };
static void addInfoToVectors(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, SgForStmt *position, SgSymbol *symb,
const int dimNum, const pair<int, int> newCoef, int type, const int maxDimSize, const double currentW)
{
auto itLoop = loopInfo.find(position);
@@ -159,10 +208,10 @@ void addInfoToVectors(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, SgFo
}
vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, SgExpression *subscr,
SgArrayRefExp *arrayRefIn, const int side, const int dimNum,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo,
const int currLine, const int numOfSubscriptions, const double currentW)
static vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, SgExpression *subscr,
SgArrayRefExp *arrayRefIn, const int side, const int dimNum,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo,
const int currLine, const int numOfSubscriptions, const double currentW)
{
SgExpression *origSubscr = subscr;
ArrayRefExp *arrayRef = new ArrayRefExp(arrayRefIn);
@@ -204,7 +253,7 @@ vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, S
if (countOfSymbols > 1)
{
__spf_print(PRINT_ARRAY_ARCS, " <%d|%d> ", 0, 0);
if (currRegime == DATA_DISTR)
if (currRegime == DATA_DISTR || currRegime == SHARED_MEMORY_PAR)
{
const pair<bool, string> &arrayRefString = constructArrayRefForPrint(arrayRef, dimNum, origSubscr);
__spf_print(1, "WARN: array ref '%s' at line %d has more than one loop's variables\n", arrayRefString.second.c_str(), currLine);
@@ -238,7 +287,7 @@ vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, S
for (int i = 0; i < (int)parentLoops.size(); ++i)
addInfoToMap(loopInfo, parentLoops[i], currOrigArrayS, arrayRef, dimNum, REMOTE_TRUE, currLine, numOfSubscriptions);
}
else if (currRegime == DATA_DISTR)
else if (currRegime == DATA_DISTR || currRegime == SHARED_MEMORY_PAR)
{
const pair<bool, string> &arrayRefString = constructArrayRefForPrint(arrayRef, dimNum, origSubscr);
@@ -294,7 +343,7 @@ vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, S
if (side == RIGHT)
addInfoToMap(loopInfo, parentLoops[position], currOrigArrayS, arrayRef, dimNum, REMOTE_TRUE, currLine, numOfSubscriptions);
}
else if (currRegime == DATA_DISTR)
else if (currRegime == DATA_DISTR || currRegime == SHARED_MEMORY_PAR)
{
const pair<bool, string> &arrayRefString = constructArrayRefForPrint(arrayRef, dimNum, origSubscr);
__spf_print(1, "WARN: can not calculate index expression for array ref '%s' at line %d\n", arrayRefString.second.c_str(), currLine);
@@ -335,7 +384,7 @@ vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, S
addInfoToMap(loopInfo, parentLoops[position], currOrigArrayS, arrayRef, dimNum, REMOTE_FALSE, currLine, numOfSubscriptions);
}
if (coefs.first < 0 && mpiProgram == 0)
if (coefs.first < 0 && sharedMemoryParallelization == 0)
{
if (currRegime == DATA_DISTR)
{
@@ -387,7 +436,8 @@ vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, S
return allPositions;
}
static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops, SgExpression *currExp, const int side,
static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops, vector<set<string>>& privatesVarsForLoop,
SgExpression *currExp, const int side,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, const int currLine,
map<int, LoopGraph*> &sortedLoopGraph, const ParallelRegion *reg, const double currentW,
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls)
@@ -440,13 +490,15 @@ static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops
vector<int> canNotMapToLoop;
for (int i = 0; i < wasFoundForLoop.size(); ++i)
{
if (wasFoundForLoop[i] != 1)
if (wasFoundForLoop[i] != 1 &&
// always true for distributed data case
privatesVarsForLoop[i].find(string(arrayRef->symbol()->identifier())) == privatesVarsForLoop[i].end())
{
auto itLoop = sortedLoopGraph.find(parentLoops[i]->lineNumber());
if (itLoop == sortedLoopGraph.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
ifUnknownArrayAssignFound = true;
if (side == LEFT && (currRegime == DATA_DISTR || currRegime == COMP_DISTR))
if (side == LEFT && (currRegime == DATA_DISTR || currRegime == COMP_DISTR || currRegime == SHARED_MEMORY_PAR))
itLoop->second->hasUnknownArrayAssigns = true;
itLoop->second->hasUnknownDistributedMap = true;
@@ -456,7 +508,7 @@ static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops
if (side == LEFT)
{
if (ifUnknownArrayAssignFound && (currRegime == DATA_DISTR))
if (ifUnknownArrayAssignFound && (currRegime == DATA_DISTR || currRegime == SHARED_MEMORY_PAR))
{
const string arrayRefS = arrayRef->unparse();
for (auto &line : canNotMapToLoop)
@@ -517,7 +569,8 @@ static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops
}
static void mapArrayRef(SgStatement* currentSt, SgExpression* currExp,
const vector<SgForStmt*>& parentLoops, const int side, const int lineNum,
const vector<SgForStmt*>& parentLoops, vector<set<string>>& privatesVarsForLoop,
const int side, const int lineNum,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo,
map<int, LoopGraph*> &sortedLoopGraph, map<string, pair<SgSymbol*, SgStatement*>>& notMappedDistributedArrays,
set<string>& mappedDistrbutedArrays,
@@ -533,7 +586,7 @@ static void mapArrayRef(SgStatement* currentSt, SgExpression* currExp,
__spf_print(PRINT_ARRAY_ARCS, "%s to array <%s> on line %d: ", printSide, OriginalSymbol(currExp->symbol())->identifier(), lineNum);
bool wasMapped = false;
vector<int> matched = matchArrayToLoopSymbols(parentLoops, currExp, side, loopInfo, lineNum, sortedLoopGraph, reg, currentW, arrayLinksByFuncCalls);
vector<int> matched = matchArrayToLoopSymbols(parentLoops, privatesVarsForLoop, currExp, side, loopInfo, lineNum, sortedLoopGraph, reg, currentW, arrayLinksByFuncCalls);
for (int z = 0; z < matched.size(); ++z)
wasMapped |= (matched[z] != 0);
@@ -570,7 +623,8 @@ static void findArrayRef(const vector<SgForStmt*> &parentLoops, SgExpression *cu
if (isArrayRef(currExp))
{
//... and current array is not in private list
if (privatesVars.find(string(OriginalSymbol(currExp->symbol())->identifier())) == privatesVars.end())
if (sharedMemoryParallelization ||
privatesVars.find(string(OriginalSymbol(currExp->symbol())->identifier())) == privatesVars.end())
{
if (wasDistributedArrayRef)
{
@@ -582,147 +636,104 @@ static void findArrayRef(const vector<SgForStmt*> &parentLoops, SgExpression *cu
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (itLoop->second->perfectLoop != depth)
break;
itLoop->second->hasIndirectAccess = true;
if (mpiProgram && side == RIGHT)
itLoop->second->hasIndirectAccess = false;
if (!(sharedMemoryParallelization && side == RIGHT))
itLoop->second->hasIndirectAccess = true;
}
mapArrayRef(currentSt, currExp, parentLoops, side, lineNum, loopInfo, sortedLoopGraph,
mapArrayRef(currentSt, currExp, parentLoops, privatesVarsForLoop, side, lineNum, loopInfo, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, reg, currentW, arrayLinksByFuncCalls);
}
else
{
wasDistributedArrayRef = true;
mapArrayRef(currentSt, currExp, parentLoops, side, lineNum, loopInfo, sortedLoopGraph,
mapArrayRef(currentSt, currExp, parentLoops, privatesVarsForLoop, side, lineNum, loopInfo, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, reg, currentW, arrayLinksByFuncCalls);
}
}
else
else if (currRegime == DATA_DISTR && side == LEFT)
{
if (currRegime == DATA_DISTR && side == LEFT)
auto symb = OriginalSymbol(currExp->symbol());
SgStatement *decl = declaratedInStmt(symb);
auto uniqKey = getUniqName(commonBlocks, decl, symb);
auto itFound = declaredArrays.find(uniqKey);
if (itFound == declaredArrays.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
//TODO: array access to non distributed arrays, add CONSISTENT
if (itFound->second.first->GetDistributeFlagVal() != DIST::DISTR)
{
auto symb = OriginalSymbol(currExp->symbol());
SgStatement *decl = declaratedInStmt(symb);
auto uniqKey = getUniqName(commonBlocks, decl, symb);
set<string> loopsPrivates;
set<Symbol*> loopsPrivatesS;
set<string> loopsRedUnited;
map<string, set<Symbol*>> loopsReductions;
map<string, set<tuple<Symbol*, Symbol*, int>>> loopsReductionsLoc;
auto itFound = declaredArrays.find(uniqKey);
if (itFound == declaredArrays.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
//TODO: array access to non distributed arrays, add CONSISTENT
if (itFound->second.first->GetDistributeFlagVal() != DIST::DISTR)
for (int z = 0; z < parentLoops.size(); ++z)
{
set<string> loopsPrivates;
set<Symbol*> loopsPrivatesS;
set<string> loopsRedUnited;
map<string, set<Symbol*>> loopsReductions;
map<string, set<tuple<Symbol*, Symbol*, int>>> loopsReductionsLoc;
for (int z = 0; z < parentLoops.size(); ++z)
auto& loop = parentLoops[z];
for (auto &data : getAttributes<SgStatement*, SgStatement*>(loop, set<int>{ SPF_ANALYSIS_DIR }))
{
auto& loop = parentLoops[z];
for (auto &data : getAttributes<SgStatement*, SgStatement*>(loop, set<int>{ SPF_ANALYSIS_DIR }))
{
fillPrivatesFromComment(new Statement(data), loopsPrivatesS);
for (auto& elem : loopsPrivatesS)
loopsPrivates.insert(elem->GetOriginal()->identifier());
fillReductionsFromComment(new Statement(data), loopsReductions);
fillReductionsFromComment(new Statement(data), loopsReductionsLoc);
}
fillPrivatesFromComment(new Statement(data), loopsPrivatesS);
for (auto& elem : loopsPrivatesS)
loopsPrivates.insert(elem->GetOriginal()->identifier());
fillReductionsFromComment(new Statement(data), loopsReductions);
fillReductionsFromComment(new Statement(data), loopsReductionsLoc);
}
}
for (auto &elem : loopsReductions)
for (auto &elem : loopsReductions)
{
for (auto &setElem : elem.second)
{
for (auto &setElem : elem.second)
{
loopsPrivates.insert(setElem->GetOriginal()->identifier());
loopsRedUnited.insert(setElem->GetOriginal()->identifier());
}
loopsPrivates.insert(setElem->GetOriginal()->identifier());
loopsRedUnited.insert(setElem->GetOriginal()->identifier());
}
}
for (auto &elem : loopsReductionsLoc)
for (auto &elem : loopsReductionsLoc)
{
for (auto &setElem : elem.second)
{
for (auto &setElem : elem.second)
{
loopsPrivates.insert(get<0>(setElem)->GetOriginal()->identifier());
loopsPrivates.insert(get<1>(setElem)->GetOriginal()->identifier());
loopsRedUnited.insert(get<0>(setElem)->GetOriginal()->identifier());
loopsRedUnited.insert(get<1>(setElem)->GetOriginal()->identifier());
}
loopsPrivates.insert(get<0>(setElem)->GetOriginal()->identifier());
loopsPrivates.insert(get<1>(setElem)->GetOriginal()->identifier());
loopsRedUnited.insert(get<0>(setElem)->GetOriginal()->identifier());
loopsRedUnited.insert(get<1>(setElem)->GetOriginal()->identifier());
}
}
const string key = string(OriginalSymbol(currExp->symbol())->identifier());
if (loopsPrivates.find(key) == loopsPrivates.end())
const string key = string(OriginalSymbol(currExp->symbol())->identifier());
if (loopsPrivates.find(key) == loopsPrivates.end())
{
for (auto& loop : parentLoops)
{
if (mpiProgram == 0)
{
for (auto& loop : parentLoops)
{
__spf_print(1, "WARN: write to non distributed array '%s' in loop on line %d\n", symb->identifier(), loop->lineNumber());
__spf_print(1, "WARN: write to non distributed array '%s' in loop on line %d\n", symb->identifier(), loop->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"write to non distributed array '%s' in this loop", to_wstring(symb->identifier()).c_str());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"write to non distributed array '%s' in this loop", to_wstring(symb->identifier()).c_str());
__spf_printToLongBuf(messageR, R61, to_wstring(symb->identifier()).c_str());
__spf_printToLongBuf(messageR, R61, to_wstring(symb->identifier()).c_str());
if (loop->lineNumber() > 0)
currMessages->push_back(Messages(WARR, loop->lineNumber(), messageR, messageE, 1026));
sortedLoopGraph[loop->lineNumber()]->hasWritesToNonDistribute = true;
}
}
if (loop->lineNumber() > 0)
currMessages->push_back(Messages(WARR, loop->lineNumber(), messageR, messageE, 1026));
sortedLoopGraph[loop->lineNumber()]->hasWritesToNonDistribute = true;
}
//TODO: this case looks strange
/*else if (loopsRedUnited.find(key) == loopsRedUnited.end())
}
if (loopsPrivates.find(key) != loopsPrivates.end() || loopsRedUnited.find(key) != loopsRedUnited.end())
{
auto currOrigArrayS = OriginalSymbol(currExp->symbol());
if (currOrigArrayS->type()->variant() == T_ARRAY)
{
auto saveReg = currRegime;
currRegime = ARRAY_ACC_CORNER;
bool wasMapped = false;
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> tmpLoopInfo = loopInfo;
vector<int> matched = matchArrayToLoopSymbols(parentLoops, currExp, side, tmpLoopInfo, currLine, sortedLoopGraph, reg, currentW, arrayLinksByFuncCalls);
for (int z = 0; z < matched.size(); ++z)
wasMapped |= (matched[z] != 0);
currRegime = saveReg;
if (wasMapped)
DIST::Array* currArray = getArrayFromDeclarated(declaratedInStmt(currOrigArrayS), currOrigArrayS->identifier());
checkNull(currArray, convertFileName(__FILE__).c_str(), __LINE__);
{
if (mpiProgram == 0)
{
int z = 0;
for (auto& loop : parentLoops)
{
if (tmpLoopInfo.find(loop) != tmpLoopInfo.end() && matched[z])
{
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"write to non distributed array '%s' in this loop", to_wstring(symb->identifier()).c_str());
set<DIST::Array*> realArrayRefs;
getRealArrayRefs(currArray, currArray, realArrayRefs, arrayLinksByFuncCalls);
__spf_printToLongBuf(messageR, R60, to_wstring(symb->identifier()).c_str());
if (loop->lineNumber() > 0)
currMessages->push_back(Messages(WARR, loop->lineNumber(), messageR, messageE, 1026));
sortedLoopGraph[loop->lineNumber()]->hasWritesToNonDistribute = true;
}
++z;
}
}
}
} */
if (loopsPrivates.find(key) != loopsPrivates.end() || loopsRedUnited.find(key) != loopsRedUnited.end())
{
auto currOrigArrayS = OriginalSymbol(currExp->symbol());
if (currOrigArrayS->type()->variant() == T_ARRAY)
{
DIST::Array* currArray = getArrayFromDeclarated(declaratedInStmt(currOrigArrayS), currOrigArrayS->identifier());
checkNull(currArray, convertFileName(__FILE__).c_str(), __LINE__);
{
set<DIST::Array*> realArrayRefs;
getRealArrayRefs(currArray, currArray, realArrayRefs, arrayLinksByFuncCalls);
for (auto& array : realArrayRefs)
array->SetPrivateInLoopStatus(true);
}
for (auto& array : realArrayRefs)
array->SetPrivateInLoopStatus(true);
}
}
}
@@ -1384,7 +1395,7 @@ static void convertOneLoop(LoopGraph *currLoop, map<LoopGraph*, map<DIST::Array*
SgStatement *decl = declaratedInStmt(currentArray);
const char *symbIdent = currentArray->identifier();
if (privateArrays.find(symbIdent) == privateArrays.end())
if (privateArrays.find(symbIdent) == privateArrays.end() || sharedMemoryParallelization)
{
const tuple<int, string, string> uniqKey = getUniqName(commonBlocks, decl, currentArray);
@@ -1401,7 +1412,7 @@ static void convertOneLoop(LoopGraph *currLoop, map<LoopGraph*, map<DIST::Array*
else
arrayToAdd = itFound->second;
if (arrayToAdd->IsNotDistribute() == true)
if (!sharedMemoryParallelization && arrayToAdd->IsNotDistribute() == true)
continue;
set<DIST::Array*> links;
@@ -1502,7 +1513,7 @@ inline static void fillPrivatesFromDecl(SgExpression *ex, set<SgSymbol*> &delcsS
fillPrivatesFromDecl(ex->lhs(), delcsSymbViewed, delcsStatViewed, declaredArrays, declaratedArraysSt, privatesVars);
}
void changeLoopWeight(double &currentWeight, const map<int, LoopGraph*> &sortedLoopGraph, const int line, bool increase)
static void changeLoopWeight(double &currentWeight, const map<int, LoopGraph*> &sortedLoopGraph, const int line, bool increase = true)
{
auto loopIt = sortedLoopGraph.find(line);
if (loopIt == sortedLoopGraph.end())
@@ -1514,7 +1525,7 @@ void changeLoopWeight(double &currentWeight, const map<int, LoopGraph*> &sortedL
currentWeight /= loopIt->second->countOfIters;
}
bool hasNonPureFunctions(SgExpression *ex, LoopGraph *loopRef, vector<Messages> &messagesForFile, const int line, const map<string, FuncInfo*> &funcByName)
static bool hasNonPureFunctions(SgExpression *ex, LoopGraph *loopRef, vector<Messages> &messagesForFile, const int line, const map<string, FuncInfo*> &funcByName)
{
bool retVal = false;
@@ -1559,7 +1570,7 @@ void fillFromModule(SgSymbol* s, const map<string, set<string>>& privatesByModul
}
}
SgStatement* takeOutConditions(stack<SgExpression*>& conditions, stack<SgStatement*>& ifBlocks, SgStatement* st)
static SgStatement* takeOutConditions(stack<SgExpression*>& conditions, stack<SgStatement*>& ifBlocks, SgStatement* st)
{
auto res = createIfConditions(conditions, ifBlocks, st);
@@ -1609,8 +1620,9 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
modulesByName[modules[i]->symbol()->identifier()] = modules[i];
map<string, set<string>> privatesByModule;
for (int i = 0; i < modules.size(); ++i)
privatesByModule[modules[i]->symbol()->identifier()] = getPrivatesFromModule(modules[i], declaredArrays, declaratedArraysSt, modulesByName);
if(!sharedMemoryParallelization)
for (int i = 0; i < modules.size(); ++i)
privatesByModule[modules[i]->symbol()->identifier()] = getPrivatesFromModule(modules[i], declaredArrays, declaratedArraysSt, modulesByName);
map<string, FuncInfo*> funcByName;
createMapOfFunc(AllfuncInfo, funcByName);
@@ -1624,9 +1636,9 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
string fName = file->functions(i)->symbol()->identifier();
#if _WIN32
if (file->functions(i)->variant() != MODULE_STMT)
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + wstring(fName.begin(), fName.end()) + L"'");
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + wstring(fName.begin(), fName.end()) + L"'");
else
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + wstring(fName.begin(), fName.end()) + L"'");
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + wstring(fName.begin(), fName.end()) + L"'");
#else
if (file->functions(i)->variant() != MODULE_STMT)
sendMessage_2lvl(wstring(L"processing function '") + wstring(fName.begin(), fName.end()) + L"'");
@@ -1674,13 +1686,17 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
loopsForFunction.push_back(loop);
}
SgStatement* tmpModFind = st;
while (tmpModFind->variant() != GLOBAL)
if(!sharedMemoryParallelization)
{
tmpModFind = tmpModFind->controlParent();
if (tmpModFind->variant() == MODULE_STMT)
fillFromModule(tmpModFind->symbol(), privatesByModule, privatesVars);
SgStatement* tmpModFind = st;
while (tmpModFind->variant() != GLOBAL)
{
tmpModFind = tmpModFind->controlParent();
if (tmpModFind->variant() == MODULE_STMT)
fillFromModule(tmpModFind->symbol(), privatesByModule, privatesVars);
}
}
commonBlocks.clear();
getCommonBlocksRef(commonBlocks, st, st->lastNodeOfStmt());
__spf_print(PRINT_PROF_INFO, " number of common blocks %d\n", (int)commonBlocks.size());
@@ -1727,7 +1743,8 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
if (isSgExecutableStatement(st) == NULL)
delcsStatViewed.insert(st);
else if (!isDVM_stat(st) && !isSPF_stat(st))
else if (!sharedMemoryParallelization &&
!isDVM_stat(st) && !isSPF_stat(st))
for (int i = 0; i < 3; ++i)
fillPrivatesFromDecl(st->expr(i), delcsSymbViewed, delcsStatViewed, declaredArrays, declaratedArraysSt, privatesVars);
@@ -1735,9 +1752,12 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
const int currV = st->variant();
if (currV == FOR_NODE)
{
tryToFindPrivateInAttributes(st, privatesVars);
fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars);
if(!sharedMemoryParallelization)
{
tryToFindPrivateInAttributes(st, privatesVars);
fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars);
}
set<string> toAdd;
tryToFindPrivateInAttributes(st, toAdd);
@@ -1783,9 +1803,10 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
unitedPrivates.insert(privVar);
set<string> setDiff;
for (auto &privVars : privatesVars)
if (unitedPrivates.find(privVars) == unitedPrivates.end())
setDiff.insert(privVars);
if(!sharedMemoryParallelization)
for (auto &privVars : privatesVars)
if (unitedPrivates.find(privVars) == unitedPrivates.end())
setDiff.insert(privVars);
allLoops[contrlParent->lineNumber()] = make_pair((SgForStmt*)contrlParent, make_pair(unitedPrivates, setDiff));
parentLoops.pop_back();
@@ -2067,7 +2088,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
}
else if (currV == USE_STMT)
{
if (st->lineNumber() > 0)
if (st->lineNumber() > 0 && !sharedMemoryParallelization)
{
auto itF = privatesByModule.find(st->symbol()->identifier());
@@ -2084,14 +2105,18 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
for (auto it = itF->second.begin(); it != itF->second.end(); ++it)
privatesVars.insert(*it);
}
}
else
{
tryToFindPrivateInAttributes(st, privatesVars);
fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars);
if(!sharedMemoryParallelization)
{
tryToFindPrivateInAttributes(st, privatesVars);
fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars);
}
if (isDVM_stat(st) == false && isSgExecutableStatement(st))
{
@@ -2125,7 +2150,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
}
auto convertedLoopInfo = convertLoopInfo(loopInfo, sortedLoopGraph, privatesVars, commonBlocks, declaredArrays, arrayLinksByFuncCalls, createdArrays);
if (regime == DATA_DISTR)
if (regime == DATA_DISTR || regime == SHARED_MEMORY_PAR)
{
processLoopInformationForFunction(convertedLoopInfo);
@@ -2144,7 +2169,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
{
string fName = file->functions(i)->symbol()->identifier();
#ifdef _WIN32
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
#else
sendMessage_2lvl(wstring(L"processing loop ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
#endif
@@ -2184,16 +2209,19 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
}
}
}
addToDistributionGraph(convertedLoopInfo, arrayLinksByFuncCalls);
if(!sharedMemoryParallelization)
addToDistributionGraph(convertedLoopInfo, arrayLinksByFuncCalls);
for (auto &toDel : tmpLoops)
{
convertedLoopInfo.erase(toDel);
delete toDel;
}
tmpToConvert.clear();
if (!skipDeps)
{
for (auto &loopLine : loopWithOutArrays)
{
if (loopLine > 0)
@@ -2257,7 +2285,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
s = start->expr(0)->lhs()->symbol();
if (s && privates.find(s->identifier()) == privates.end())
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
hasWritesToArray = true;
}
}
@@ -2300,6 +2328,9 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
if (parallizeFreeLoops)
selectFreeLoopsForParallelization(loopsForFunction, funcName, (regime == DATA_DISTR), regions, messagesForFile);
}
if(regime == SHARED_MEMORY_PAR)
createParallelDirectives(convertedLoopInfo, regions, arrayLinksByFuncCalls, messagesForFile);
__spf_print(PRINT_PROF_INFO, "Function ended\n");
}
@@ -2776,7 +2807,7 @@ static void findArrayRefs(SgExpression *ex, SgStatement *st, string fName, int p
new DIST::Array(getShortName(uniqKey), symb->identifier(), ((SgArrayType*)(symb->type()))->dimension(),
getUniqArrayId(), decl->fileName(), decl->lineNumber(), arrayLocation, new Symbol(symb),
findOmpThreadPrivDecl(scope, ompThreadPrivate, symb), false, false,
inRegion, typeSize, mpiProgram ? DIST::NO_DISTR : DIST::DISTR);
inRegion, typeSize, sharedMemoryParallelization ? DIST::NO_DISTR : DIST::DISTR);
itNew = declaredArrays.insert(itNew, make_pair(uniqKey, make_pair(arrayToAdd, new DIST::ArrayAccessInfo())));
@@ -3350,7 +3381,7 @@ void insertSpfAnalysisBeforeParalleLoops(const vector<LoopGraph*> &loops)
{
loop->loop->addAttribute(SPF_ANALYSIS_DIR, spfStat, sizeof(SgStatement));
//uncomment it to debug private analysis
//loop->loop->insertStmtBefore(*spfStat);
//loop->loop->insertStmtBefore(*spfStat, *loop->loop->controlParent());
}
insertSpfAnalysisBeforeParalleLoops(loop->children);
}

View File

@@ -17,7 +17,7 @@
typedef std::pair<std::pair<int, int>, std::pair<int, int>> attrType;
namespace DIST = Distribution;
enum REGIME { DATA_DISTR, COMP_DISTR, REMOTE_ACC, ARRAY_ACC_CORNER, UNDEF };
enum REGIME { DATA_DISTR, COMP_DISTR, REMOTE_ACC, ARRAY_ACC_CORNER, SHARED_MEMORY_PAR, UNDEF };
// loop_analyzer.cpp
bool checkExistence(SgExpression *exp, const std::string& doName);

View File

@@ -1,70 +0,0 @@
#pragma once
#include "loop_analyzer.h"
#include <string>
#include <vector>
#include <map>
#include <set>
#include <tuple>
#include <stack>
#include "../Utils/leak_detector.h"
#if _WIN32 && NDEBUG && __BOOST
#include <boost/thread.hpp>
#endif
extern int passDone;
#include "../Distribution/Distribution.h"
#include "../Distribution/GraphCSR.h"
#include "../Distribution/Arrays.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "../Utils/errors.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../DirectiveProcessing/directive_creator.h"
#include "../Utils/SgUtils.h"
#include "../Utils/AstWrapper.h"
#include "../GraphCall/graph_calls_func.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../ParallelizationRegions/ParRegions_func.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "../ExpressionTransform/expr_transform.h"
#include "../SageAnalysisTool/depInterfaceExt.h"
#include "../VisualizerCalls/get_information.h"
#include "../VisualizerCalls/SendMessage.h"
#include "../Transformations/enddo_loop_converter.h"
#include "../DirectiveProcessing/remote_access.h"
#define PRINT_ARRAY_ARCS 0
#define PRINT_LOOP_STRUCT 0
#define PRINT_PROF_INFO 0
#define DEB 0
extern REGIME currRegime;
extern std::vector<Messages>* currMessages;
extern int mpiProgram;
extern int ignoreIO;
extern int parallizeFreeLoops;
void changeLoopWeight(double& currentWeight, const std::map<int, LoopGraph*>& sortedLoopGraph, const int line, bool increase = true);
SgStatement* takeOutConditions(std::stack<SgExpression*>& conditions, std::stack<SgStatement*>& ifBlocks, SgStatement* st);
enum { READ_OP, WRITE_OP, UNREC_OP };
void addInfoToVectors(std::map<SgForStmt*, std::map<SgSymbol*, ArrayInfo>>& loopInfo, SgForStmt* position, SgSymbol* symb,
const int dimNum, const std::pair<int, int> newCoef, int type, const int maxDimSize, const double currentW);
std::vector<int> matchSubscriptToLoopSymbols(const std::vector<SgForStmt*>& parentLoops, SgExpression* subscr,
SgArrayRefExp* arrayRefIn, const int side, const int dimNum,
std::map<SgForStmt*, std::map<SgSymbol*, ArrayInfo>>& loopInfo,
const int currLine, const int numOfSubscriptions, const double currentW);
bool hasNonPureFunctions(SgExpression* ex, LoopGraph* loopRef, std::vector<Messages>& messagesForFile, const int line, const std::map<std::string, FuncInfo*>& funcByName);

View File

@@ -1,667 +0,0 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <string>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <utility>
#include <assert.h>
#include "../DirectiveProcessing/directive_creator_nodist.h"
#include "loop_analyzer_internal.h"
#include "loop_analyzer_nodist.h"
using std::vector;
using std::pair;
using std::tuple;
using std::map;
using std::set;
using std::make_pair;
using std::make_tuple;
using std::get;
using std::string;
using std::wstring;
using std::stack;
extern void createMapLoopGraph(map<int, LoopGraph*>& sortedLoopGraph, const vector<LoopGraph*>* loopGraph);
extern map<DIST::Array*, std::tuple<int, string, string>> tableOfUniqNamesByArray;
static void convertOneLoopNoDist(LoopGraph* currLoop, map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>& outInfo,
const map<SgSymbol*, ArrayInfo>& toConvert,
const map<string, vector<SgExpression*>>& commonBlocks,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
map<tuple<int, string, string>, DIST::Array*>& createdArrays,
bool freeArrays = false)
{
map<DIST::Array*, ArrayInfo*> toAdd;
for (auto& conv : toConvert)
{
SgSymbol* currentArray = OriginalSymbol(conv.first);
ArrayInfo* currentInfo = (ArrayInfo*)(&conv.second);
DIST::Array* arrayToAdd;
SgStatement* decl = declaratedInStmt(currentArray);
const char* symbIdent = currentArray->identifier();
const tuple<int, string, string> uniqKey = getUniqName(commonBlocks, decl, currentArray);
auto itFound = createdArrays.find(uniqKey);
if (itFound == createdArrays.end())
{
auto itArray = declaredArrays.find(uniqKey);
if (itArray == declaredArrays.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
arrayToAdd = itArray->second.first;
itFound = createdArrays.insert(itFound, make_pair(uniqKey, arrayToAdd));
}
else
arrayToAdd = itFound->second;
set<DIST::Array*> links;
getRealArrayRefs(arrayToAdd, arrayToAdd, links, arrayLinksByFuncCalls);
int countOflinks = 0;
for (auto& linkedArray : links)
{
if (arrayToAdd == linkedArray)
continue;
++countOflinks;
auto key = tableOfUniqNamesByArray[linkedArray];
auto value = declaredArrays.find(key)->second;
if (value.second == 0 && createdArrays.find(key) == createdArrays.end())
createdArrays.insert(make_pair(key, linkedArray));
}
if (freeArrays)
if (countOflinks == 0)
continue;
toAdd[arrayToAdd] = currentInfo;
for (int z = 0; z < currentInfo->getDimSize(); ++z)
{
if (currentInfo->readOps[z].coefficients.size() || currentInfo->writeOps[z].coefficients.size())
{
arrayToAdd->SetMappedDim(z);
for (auto& realRef : links)
realRef->SetMappedDim(z);
}
}
}
outInfo[currLoop] = toAdd;
}
static map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>
convertLoopInfoNoDist(const map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo,
const map<int, LoopGraph*>& sortedLoopGraph,
const map<string, vector<SgExpression*>>& commonBlocks,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
map<tuple<int, string, string>, DIST::Array*>& createdArrays)
{
map<LoopGraph*, map<DIST::Array*, ArrayInfo*>> outInfo;
for (auto it = loopInfo.begin(); it != loopInfo.end(); ++it)
{
auto itGraph = sortedLoopGraph.find(it->first->lineNumber());
if (itGraph == sortedLoopGraph.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
convertOneLoopNoDist(itGraph->second, outInfo, it->second, commonBlocks, declaredArrays, arrayLinksByFuncCalls, createdArrays);
}
return outInfo;
}
static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops, vector<set<string>>& privatesVarsForLoop,
SgExpression *currExp, const int side,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, const int currLine,
map<int, LoopGraph*> &sortedLoopGraph, const ParallelRegion *reg, const double currentW,
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls)
{
SgArrayRefExp *arrayRef = (SgArrayRefExp*)currExp;
int numOfSubs = arrayRef->numberOfSubscripts();
currExp = currExp->lhs();
vector<int> wasFoundForLoop(parentLoops.size());
vector<int> matched(numOfSubs);
vector<int> matchedToDim(parentLoops.size());
std::fill(wasFoundForLoop.begin(), wasFoundForLoop.end(), 0);
std::fill(matched.begin(), matched.end(), -1);
std::fill(matchedToDim.begin(), matchedToDim.end(), -1);
int maxMatched = 0;
int sumMatched = 0;
for (int i = 0; i < numOfSubs; ++i)
{
vector<int> matchToLoops = matchSubscriptToLoopSymbols(parentLoops, currExp->lhs(), arrayRef, side, i, loopInfo, currLine, numOfSubs, currentW);
for (int k = 0; k < matchToLoops.size(); ++k)
{
wasFoundForLoop[matchToLoops[k]]++;
matchedToDim[matchToLoops[k]] = i;
}
matched[i] = matchToLoops.size();
sumMatched += matchToLoops.size();
maxMatched = std::max(maxMatched, (int)matchToLoops.size());
currExp = currExp->rhs();
}
//full array is used, add unknown operations to all loops
if (numOfSubs == 0)
{
SgSymbol *currOrigArrayS = OriginalSymbol(arrayRef->symbol());
auto arrType = isSgArrayType(currOrigArrayS->type());
if (arrType != NULL)
{
for (int d = 0; d < arrType->dimension(); ++d)
for (int i = 0; i < parentLoops.size(); ++i)
addInfoToVectors(loopInfo, parentLoops[i], currOrigArrayS, d, make_pair(0, 0), UNREC_OP, arrType->dimension(), currentW);
}
}
bool ifUnknownArrayAssignFound = false;
vector<int> canNotMapToLoop;
for (int i = 0; i < wasFoundForLoop.size(); ++i)
{
if (wasFoundForLoop[i] != 1 &&
privatesVarsForLoop[i].find(string(arrayRef->symbol()->identifier())) == privatesVarsForLoop[i].end())
{
auto itLoop = sortedLoopGraph.find(parentLoops[i]->lineNumber());
if (itLoop == sortedLoopGraph.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
ifUnknownArrayAssignFound = true;
if (side == LEFT)
itLoop->second->hasUnknownArrayAssigns = true;
itLoop->second->hasUnknownDistributedMap = true;
canNotMapToLoop.push_back(parentLoops[i]->lineNumber());
}
}
if (side == LEFT)
{
if (ifUnknownArrayAssignFound)
{
const string arrayRefS = arrayRef->unparse();
for (auto &line : canNotMapToLoop)
{
__spf_print(1, "WARN: can not map write to array '%s' to loop on line %d\n", arrayRefS.c_str(), line);
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"can not map write to array '%s' to this loop", to_wstring(arrayRefS).c_str());
__spf_printToLongBuf(messageR, R59, to_wstring(arrayRefS).c_str());
if (line > 0)
currMessages->push_back(Messages(WARR, line, messageR, messageE, 1025));
}
}
}
return wasFoundForLoop;
}
static void mapArrayRef(SgStatement* currentSt, SgExpression* currExp,
const vector<SgForStmt*>& parentLoops, const int side, const int lineNum,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo,
vector<set<string>>& privatesVarsForLoop,
map<int, LoopGraph*>& sortedLoopGraph, map<string, pair<SgSymbol*, SgStatement*>>& notMappedDistributedArrays,
set<string>& mappedDistrbutedArrays,
const ParallelRegion* reg, const double currentW, const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
const char* printSide = NULL;
if (PRINT_ARRAY_ARCS)
printBlanks(2, (int)parentLoops.size());
if (side == LEFT)
printSide = "W_OP";
else
printSide = "R_OP";
__spf_print(PRINT_ARRAY_ARCS, "%s to array <%s> on line %d: ", printSide, OriginalSymbol(currExp->symbol())->identifier(), lineNum);
bool wasMapped = false;
vector<int> matched = matchArrayToLoopSymbols(parentLoops, privatesVarsForLoop, currExp, side, loopInfo, lineNum, sortedLoopGraph, reg, currentW, arrayLinksByFuncCalls);
for (int z = 0; z < matched.size(); ++z)
wasMapped |= (matched[z] != 0);
if (parentLoops.size() == 0)
{
SgSymbol* symb = currExp->symbol();
if (symb->type()->variant() == T_ARRAY)
notMappedDistributedArrays[symb->identifier()] = make_pair(symb, currentSt);
}
else
{
if (wasMapped)
mappedDistrbutedArrays.insert(currExp->symbol()->identifier());
else
{
SgSymbol* symb = currExp->symbol();
if (symb->type()->variant() == T_ARRAY)
notMappedDistributedArrays[symb->identifier()] = make_pair(symb, currentSt);
}
}
__spf_print(PRINT_ARRAY_ARCS, "\n");
}
static void findArrayRef(const vector<SgForStmt*>& parentLoops, SgExpression* currExp, const int lineNum, const int side,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo,
vector<set<string>>& privatesVarsForLoop, map<int, LoopGraph*>& sortedLoopGraph,
map<string, pair<SgSymbol*, SgStatement*>>& notMappedDistributedArrays,
set<string>& mappedDistrbutedArrays, SgStatement* currentSt, const ParallelRegion* reg, const double currentW,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
int nextSide = side;
if (isArrayRef(currExp))
{
mapArrayRef(currentSt, currExp, parentLoops, side, lineNum, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, reg, currentW, arrayLinksByFuncCalls);
nextSide = (side == LEFT) ? RIGHT : side;
}
bool needToContinue = true;
if (currExp->variant() == FUNC_CALL)
{
SgFunctionCallExp* funcExp = (SgFunctionCallExp*)currExp;
auto currFunc = isUserFunctionInProject(funcExp->funName()->identifier());
if (currFunc)
{
for (int z = 0; z < funcExp->numberOfArgs(); ++z)
{
if ((currFunc->funcParams.inout_types[z] & OUT_BIT) != 0)
nextSide = LEFT;
else
nextSide = RIGHT;
findArrayRef(parentLoops, funcExp->arg(z), lineNum, nextSide, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, currentSt, reg, currentW, arrayLinksByFuncCalls);
}
needToContinue = false;
}
}
if (needToContinue)
{
if (currExp->lhs())
findArrayRef(parentLoops, currExp->lhs(), lineNum, nextSide, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, currentSt, reg, currentW, arrayLinksByFuncCalls);
if (currExp->rhs())
findArrayRef(parentLoops, currExp->rhs(), lineNum, nextSide, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, currentSt, reg, currentW, arrayLinksByFuncCalls);
}
}
void loopAnalyzerNoDist(SgFile* file, vector<ParallelRegion*>& regions, map<tuple<int, string, string>, DIST::Array*>& createdArrays,
vector<Messages>& messagesForFile, const map<string, vector<FuncInfo*>>& AllfuncInfo,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<SgStatement*, set<tuple<int, string, string>>>& declaratedArraysSt,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const map<SgStatement*, vector<DefUseList>>& defUseByPlace,
vector<LoopGraph*>* loopGraph)
{
currMessages = &messagesForFile;
currRegime = DATA_DISTR; //?
map<string, vector<SgExpression*>> commonBlocks;
map<int, LoopGraph*> sortedLoopGraph;
map<int, pair<SgForStmt*, pair<set<string>, set<string>>>> allLoops;
createMapLoopGraph(sortedLoopGraph, loopGraph);
int funcNum = file->numberOfFunctions();
__spf_print(PRINT_PROF_INFO, "functions num in file = %d\n", funcNum);
vector<SgStatement*> modules;
findModulesInFile(file, modules);
map<string, SgStatement*> modulesByName;
for (int i = 0; i < modules.size(); ++i)
modulesByName[modules[i]->symbol()->identifier()] = modules[i];
map<string, FuncInfo*> funcByName;
createMapOfFunc(AllfuncInfo, funcByName);
const vector<FuncInfo*>& funcInfo = AllfuncInfo.find(file->filename())->second;
for (int i = 0; i < funcNum; ++i)
{
createNeededException();
string fName = file->functions(i)->symbol()->identifier();
#if _WIN32
if (file->functions(i)->variant() != MODULE_STMT)
sendMessage_2lvl(wstring(L"обработка функции '") + wstring(fName.begin(), fName.end()) + L"'");
else
sendMessage_2lvl(wstring(L"обработка модуля '") + wstring(fName.begin(), fName.end()) + L"'");
#else
if (file->functions(i)->variant() != MODULE_STMT)
sendMessage_2lvl(wstring(L"processing function '") + wstring(fName.begin(), fName.end()) + L"'");
else
sendMessage_2lvl(wstring(L"processing module '") + wstring(fName.begin(), fName.end()) + L"'");
#endif
set<SgSymbol*> delcsSymbViewed;
set<SgStatement*> delcsStatViewed;
if (funcInfo[i]->doNotAnalyze)
continue;
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> loopInfo;
set<int> loopWithOutArrays;
SgStatement* st = file->functions(i);
string funcName = "";
if (st->variant() == PROG_HEDR)
{
SgProgHedrStmt* progH = (SgProgHedrStmt*)st;
__spf_print(PRINT_PROF_INFO, "*** Program <%s> started at line %d / %s\n", progH->symbol()->identifier(), st->lineNumber(), st->fileName());
funcName = progH->symbol()->identifier();
}
else if (st->variant() == PROC_HEDR)
{
SgProcHedrStmt* procH = (SgProcHedrStmt*)st;
__spf_print(PRINT_PROF_INFO, "*** Function <%s> started at line %d / %s\n", procH->symbol()->identifier(), st->lineNumber(), st->fileName());
funcName = procH->symbol()->identifier();
}
else if (st->variant() == FUNC_HEDR)
{
SgFuncHedrStmt* funcH = (SgFuncHedrStmt*)st;
__spf_print(PRINT_PROF_INFO, "*** Function <%s> started at line %d / %s\n", funcH->symbol()->identifier(), st->lineNumber(), st->fileName());
funcName = funcH->symbol()->identifier();
}
vector<LoopGraph*> loopsForFunction;
for (auto& loop : *loopGraph)
{
auto fStat = getFuncStat(loop->loop->GetOriginal());
if (fStat->symbol()->identifier() == funcName)
loopsForFunction.push_back(loop);
}
commonBlocks.clear();
getCommonBlocksRef(commonBlocks, st, st->lastNodeOfStmt());
__spf_print(PRINT_PROF_INFO, " number of common blocks %d\n", (int)commonBlocks.size());
SgStatement* lastNode = st->lastNodeOfStmt();
vector<SgForStmt*> parentLoops;
vector<set<string>> privatesVarsForLoop;
//For remote access
pair<SgForStmt*, LoopGraph*>* under_dvm_dir = NULL;
map<string, pair<SgSymbol*, SgStatement*>> notMappedDistributedArrays;
set<string> mappedDistrbutedArrays;
double currentWeight = 1.0;
while (st != lastNode)
{
createNeededException();
if (st == NULL)
{
currMessages->push_back(Messages(ERROR, 1, R128, L"internal error in analysis, parallel directives will not be generated for this file!", 3008));
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
break;
}
if (st->variant() == CONTAINS_STMT)
break;
if (!__gcov_doesThisLineExecuted(st->fileName(), st->lineNumber()))
{
st = st->lexNext();
continue;
}
const int currentLine = st->lineNumber() < -1 ? st->localLineNumber() : st->lineNumber();
ParallelRegion* currReg = getRegionByLine(regions, st->fileName(), currentLine);
if (currReg == NULL)
{
st = st->lexNext();
continue;
}
if (isSgExecutableStatement(st) == NULL)
delcsStatViewed.insert(st);
//printf("new st with var = %d, on line %d\n", st->variant(), st->lineNumber());
const int currV = st->variant();
if (currV == FOR_NODE)
{
//tryToFindPrivateInAttributes(st, privatesVars);
set<string> toAdd;
tryToFindPrivateInAttributes(st, toAdd);
if (PRINT_LOOP_STRUCT)
printBlanks(2, (int)parentLoops.size());
__spf_print(PRINT_LOOP_STRUCT, "FOR NODE on line %d\n", st->lineNumber());
parentLoops.push_back((SgForStmt*)st);
changeLoopWeight(currentWeight, sortedLoopGraph, st->lineNumber());
privatesVarsForLoop.push_back(toAdd);
}
else if (currV == CONTROL_END)
{
SgStatement* contrlParent = st->controlParent();
if (contrlParent)
{
if (contrlParent->variant() == FOR_NODE)
{
changeLoopWeight(currentWeight, sortedLoopGraph, contrlParent->lineNumber(), false);
if (loopInfo.find((SgForStmt*)contrlParent) == loopInfo.end() && !sortedLoopGraph[contrlParent->lineNumber()]->hasUnknownDistributedMap)
loopWithOutArrays.insert(contrlParent->lineNumber());
set<string> unitedPrivates;
for (int p = 0; p < parentLoops.size(); ++p)
for (auto& privVar : privatesVarsForLoop[p])
unitedPrivates.insert(privVar);
set<string> setDiff;
allLoops[contrlParent->lineNumber()] = make_pair((SgForStmt*)contrlParent, make_pair(unitedPrivates, setDiff));
parentLoops.pop_back();
privatesVarsForLoop.pop_back();
}
}
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
else if (currV == ASSIGN_STAT)
{
if (st->expr(0))
findArrayRef(parentLoops, st->expr(0), st->lineNumber(), LEFT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
if (st->expr(1))
findArrayRef(parentLoops, st->expr(1), st->lineNumber(), RIGHT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
else if (currV == IF_NODE || currV == ELSEIF_NODE || currV == LOGIF_NODE || currV == SWITCH_NODE)
{
SgStatement* before = NULL;
if (st->expr(0))
{
findArrayRef(parentLoops, st->expr(0), st->lineNumber(), RIGHT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
}
else if (currV == PROC_STAT)
{
auto func = isUserFunctionInProject(st->symbol()->identifier());
if (func != NULL)
{
SgExpression* parList = st->expr(0);
set<DIST::Array*> toRedistr;
if (parList)
{
SgExprListExp* list = isSgExprListExp(parList);
for (int z = 0; z < list->length(); ++z)
{
SgExpression* par = list->elem(z);
if ((func->funcParams.inout_types[z] & OUT_BIT) != 0)
findArrayRef(parentLoops, par, st->lineNumber(), LEFT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
else
findArrayRef(parentLoops, par, st->lineNumber(), RIGHT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
}
}
}
else if (currV == USE_STMT)
{
if (st->lineNumber() > 0)
{
auto itF = modulesByName.find(st->symbol()->identifier());
if (itF == modulesByName.end())
{
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"Module with name '%s' must be placed in current file", to_wstring(st->symbol()->identifier()).c_str());
__spf_printToLongBuf(messageR, R62, to_wstring(st->symbol()->identifier()).c_str());
currMessages->push_back(Messages(ERROR, st->lineNumber(), messageR, messageE, 1028));
__spf_print(1, "Module at line %d with name '%s' must be placed in current file\n", st->lineNumber(), st->symbol()->identifier());
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
}
else
{
if (isDVM_stat(st) == false && isSgExecutableStatement(st))
{
int const var = st->variant();
int side = (var == READ_STAT || var == WRITE_STAT || var == PRINT_STAT) ? LEFT : RIGHT;
for (int z = 0; z < 3; ++z)
if (st->expr(z))
findArrayRef(parentLoops, st->expr(z), st->lineNumber(), side, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
}
st = st->lexNext();
}
auto convertedLoopInfo = convertLoopInfoNoDist(loopInfo, sortedLoopGraph, commonBlocks, declaredArrays, arrayLinksByFuncCalls, createdArrays);
processLoopInformationForFunction(convertedLoopInfo);
//find dependencies for loops in function
initAnnotationsSysExt(0);
set<SgStatement*> funcWasInit;
map<SgExpression*, string> collection;
int idx = 0;
for (auto& loop : convertedLoopInfo)
{
++idx;
createNeededException();
string fName = file->functions(i)->symbol()->identifier();
#ifdef _WIN32
sendMessage_2lvl(wstring(L"обработка цикла ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
#else
sendMessage_2lvl(wstring(L"processing loop ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
#endif
tryToFindDependencies(loop.first, allLoops, funcWasInit, file, regions, currMessages, collection, funcByName, defUseByPlace);
}
for (auto& loopLine : loopWithOutArrays)
{
if (loopLine > 0)
{
tryToFindDependencies(sortedLoopGraph[loopLine], allLoops, funcWasInit, file, regions, currMessages, collection, funcByName, defUseByPlace);
sortedLoopGraph[loopLine]->withoutDistributedArrays = true;
//TODO: enable linear writes to non distr arrays for CONSISTENT
bool hasWritesToArray = false;
//TODO: add IPA for non pure
bool hasNonPureProcedures = false;
auto loopRef = sortedLoopGraph[loopLine];
SgStatement* loopSt = loopRef->loop;
for (SgStatement* start = loopSt->lexNext(); start != loopSt->lastNodeOfStmt(); start = start->lexNext())
{
if (start->variant() == PROC_STAT && isIntrinsicFunctionName(start->symbol()->identifier()) == 0)
{
checkNull(isSgCallStmt(start), convertFileName(__FILE__).c_str(), __LINE__);
auto itF = funcByName.find(isSgCallStmt(start)->name()->identifier());
bool isPure = false;
if (itF != funcByName.end())
isPure = itF->second->isPure;
if (!isPure)
{
hasNonPureProcedures = true;
loopRef->hasNonPureProcedures = true;
messagesForFile.push_back(Messages(WARR, start->lineNumber(), R80, L"Only pure procedures were supported", 1044));
}
}
for (int z = 1; z < 3; ++z)
if (hasNonPureFunctions(start->expr(z), loopRef, messagesForFile, start->lineNumber(), funcByName))
hasNonPureProcedures = true;
}
if (hasWritesToArray || hasNonPureProcedures)
loopRef->withoutDistributedArrays = false;
}
}
sendMessage_2lvl(L"");
createParallelDirectivesNoDist(convertedLoopInfo, regions, arrayLinksByFuncCalls, messagesForFile);
for (auto& loopLine : loopWithOutArrays)
{
auto loopRef = sortedLoopGraph[loopLine];
if (loopRef->withoutDistributedArrays && loopRef->region && !loopRef->hasLimitsToParallel() && loopRef->lineNum > 0)
{
int nesting = 0;
LoopGraph* it = loopRef;
for (int z = 0; z < loopRef->perfectLoop; ++z, it->children.size() ? it = it->children[0] : it)
if (it->withoutDistributedArrays && it->region && !it->hasLimitsToParallel() && it->lineNum > 0)
++nesting;
map<LoopGraph*, map<DIST::Array*, ArrayInfo*>> convertedLoopInfo;
it = loopRef;
for (int z = 0; z < nesting; ++z, it->children.size() ? it = it->children[0] : it)
convertedLoopInfo.insert(make_pair(it, map<DIST::Array*, ArrayInfo*>()));
createParallelDirectivesNoDist(convertedLoopInfo, regions, map<DIST::Array*, set<DIST::Array*>>(), messagesForFile);
}
}
__spf_print(PRINT_PROF_INFO, "Function ended\n");
}
}

View File

@@ -1,13 +0,0 @@
#include<map>
#include<string>
#include<set>
#include<vector>
#include<tuple>
void loopAnalyzerNoDist(SgFile* file, std::vector<ParallelRegion*>& regions, std::map<std::tuple<int, std::string, std::string>, DIST::Array*>& createdArrays,
std::vector<Messages>& messagesForFile, const std::map<std::string, std::vector<FuncInfo*>>& AllfuncInfo,
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const std::map<SgStatement*, std::set<std::tuple<int, std::string, std::string>>>& declaratedArraysSt,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
const std::map<SgStatement*, std::vector<DefUseList>>& defUseByPlace,
std::vector<LoopGraph*>* loopGraph);

View File

@@ -1251,7 +1251,7 @@ void fillUsedArraysInExp(const pair<Statement*, Statement*> &interval, const int
bool checkRegionsResolving(const vector<ParallelRegion*> &regions,
const map<string, vector<FuncInfo*>> &allFuncInfo,
const map<string, CommonBlock*> &commonBlocks,
map<string, vector<Messages>> &SPF_messages, bool mpiProgram)
map<string, vector<Messages>> &SPF_messages, bool sharedMemoryParallelization)
{
bool error = false;
@@ -1319,7 +1319,7 @@ bool checkRegionsResolving(const vector<ParallelRegion*> &regions,
}
}
if (mpiProgram)
if (sharedMemoryParallelization)
return error;
// check local arrays
@@ -1611,7 +1611,7 @@ static void compliteUseOnlyList(SgStatement *func, const string &location, const
}
int resolveParRegions(vector<ParallelRegion*> &regions, const map<string, vector<FuncInfo*>> &allFuncInfo,
map<string, vector<Messages>> &SPF_messages, bool mpiProgram,
map<string, vector<Messages>> &SPF_messages, bool sharedMemoryParallelization,
map<string, map<int, set<string>>> &newDeclsToInclude)
{
bool error = false;
@@ -1619,7 +1619,7 @@ int resolveParRegions(vector<ParallelRegion*> &regions, const map<string, vector
map<string, FuncInfo*> funcMap;
createMapOfFunc(allFuncInfo, funcMap);
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
{
map<string, map<int, set<string>>> copied;
@@ -1905,7 +1905,7 @@ int resolveParRegions(vector<ParallelRegion*> &regions, const map<string, vector
}
}
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
{
__spf_print(1, "insert DVM intervals\n");

View File

@@ -11,6 +11,6 @@ void fillRegionFunctions(std::vector<ParallelRegion*> &regions, const std::map<s
bool checkRegions(const std::vector<ParallelRegion*> &regions, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, std::map<std::string, std::vector<Messages>> &SPF_messages);
int printCheckRegions(const char *fileName, const std::vector<ParallelRegion*> &regions, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo);
bool checkRegionsResolving(const std::vector<ParallelRegion*> &regions, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, const std::map<std::string, CommonBlock*> &commonBlocks, std::map<std::string, std::vector<Messages>> &SPF_messages, bool mpiProgram);
int resolveParRegions(std::vector<ParallelRegion*>& regions, const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo, std::map<std::string, std::vector<Messages>>& SPF_messages, bool mpiProgram, std::map<std::string, std::map<int, std::set<std::string>>>& copyDecls);
bool checkRegionsResolving(const std::vector<ParallelRegion*> &regions, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, const std::map<std::string, CommonBlock*> &commonBlocks, std::map<std::string, std::vector<Messages>> &SPF_messages, bool sharedMemoryParallelization);
int resolveParRegions(std::vector<ParallelRegion*>& regions, const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo, std::map<std::string, std::vector<Messages>>& SPF_messages, bool sharedMemoryParallelization, std::map<std::string, std::map<int, std::set<std::string>>>& copyDecls);
void insertRealignsBeforeFragments(ParallelRegion* reg, SgFile* file, const std::set<DIST::Array*>& distrArrays, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);

View File

@@ -4,6 +4,7 @@
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <fstream>
#include <map>
#include <vector>
@@ -12,9 +13,16 @@
#include <queue>
#include "dvm.h"
#include "../DynamicAnalysis/gcov_info.h"
#include "PredictScheme.h"
#include "../Utils/SgUtils.h"
using std::map;
using std::string;
using std::vector;
using std::set;
using std::ofstream;
static void fillParallel(SgExpression *exp, ParallelStats &parStats, int &totalScoreComm)
{
if (exp)
@@ -116,3 +124,77 @@ void processFileToPredict(SgFile *file, PredictorStats &predictorCounts)
predictorCounts.TotalScorePar += predictorCounts.ParallelCount;
}
static void calculate_for_parallel_loop(SgStatement* loop, const map<int, Gcov_info>& gcov,
uint64_t& paralle_exec_count, uint64_t& count_of_parallel_lines) {
for (auto st = loop; st != loop->lastNodeOfStmt(); st = st->lexNext()) {
int line = st->lineNumber();
if (line <= 0)
continue;
auto it = gcov.find(line);
if (it == gcov.end()) {
__spf_print(1, "bad gcov info\n");
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
auto& info = it->second;
if (info.getNumLine() != line) {
__spf_print(1, "bad gcov info\n");
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
count_of_parallel_lines++;
paralle_exec_count += info.getExecutedCount();
}
}
void calculate_stats_for_predictor(const map<string, vector<FuncInfo*>>& allFuncInfo,
const map<string, map<int, Gcov_info>>& gCovInfo) {
uint64_t paralle_exec_count = 0;
uint64_t count_of_parallel_lines = 0;
for (auto& byFile : allFuncInfo) {
int ok = SgFile::switchToFile(byFile.first);
if (ok == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto it = gCovInfo.find(byFile.first);
if (it == gCovInfo.end()) {
__spf_print(1, "bad gcov info\n");
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
auto& gcov = it->second;
for (auto& func : byFile.second) {
SgStatement* stat = func->funcPointer->GetOriginal();
for (auto st = stat->lexNext(); st != stat->lastNodeOfStmt(); st = st->lexNext()) {
uint64_t paralle_exec = 0;
uint64_t lines_count = 0;
if (st->variant() == DVM_PARALLEL_ON_DIR) {
auto loop = st->lexNext();
checkNull(loop, convertFileName(__FILE__).c_str(), __LINE__);
if (loop->variant() != FOR_NODE)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
calculate_for_parallel_loop(loop, gcov, paralle_exec, lines_count);
st = loop->lastNodeOfStmt();
paralle_exec_count += paralle_exec;
count_of_parallel_lines += lines_count;
__spf_print(1, " PAR LOOP [%d %s] total exec %llu, total exec lines %llu, avg %.16e\n",
loop->lineNumber(), byFile.first.c_str(), paralle_exec, lines_count, paralle_exec / (double)lines_count);
}
}
}
}
__spf_print(1, " coverage_average %.16e\n", paralle_exec_count / (double)count_of_parallel_lines);
ofstream stats("stats.csv");
stats << "coverage_average;" << paralle_exec_count / (double)count_of_parallel_lines << std::endl;
stats.close();
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include <vector>
#include "dvm.h"
#include "../GraphCall/graph_calls.h"
class ParallelStats
{
@@ -51,4 +52,6 @@ public:
}
};
void processFileToPredict(SgFile *file, PredictorStats &predictorCounts);
void processFileToPredict(SgFile *file, PredictorStats &predictorCounts);
void calculate_stats_for_predictor(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo, const std::map<std::string, std::map<int, Gcov_info>>& gCovInfo);

View File

@@ -38,17 +38,14 @@
#include "ProjectManipulation/ConvertFiles.h"
#include "LoopAnalyzer/loop_analyzer.h"
#include "LoopAnalyzer/loop_analyzer_nodist.h"
#include "GraphCall/graph_calls_func.h"
#include "GraphCall/select_array_conf.h"
#include "GraphLoop/graph_loops_func.h"
#include "DynamicAnalysis/gCov_parser_func.h"
#include "DynamicAnalysis/createParallelRegions.h"
#include "DirectiveProcessing/directive_analyzer.h"
#include "DirectiveProcessing/directive_creator.h"
#include "DirectiveProcessing/directive_creator_nodist.h"
#include "DirectiveProcessing/insert_directive.h"
#include "DirectiveProcessing/directive_omp_parser.h"
#include "VerificationCode/verifications.h"
@@ -93,6 +90,7 @@
#include "CFGraph/IR.h"
#include "CFGraph/RD_subst.h"
#include "CFGraph/CFGraph.h"
#include "CFGraph/IRSSAForm.h"
#include "CFGraph/live_variable_analysis.h"
#include "CFGraph/private_variables_analysis.h"
@@ -329,7 +327,7 @@ static string unparseProjectIfNeed(SgFile* file, const int curr_regime, const bo
if (curr_regime == INSERT_INCLUDES && filesToInclude.find(file_name) != filesToInclude.end())
{
unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile,
moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, true);
moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, false, true);
auto itI = filesToInclude.find(file_name);
for (auto& incl : itI->second)
if (allIncludeFiles.find(incl) != allIncludeFiles.end())
@@ -338,7 +336,7 @@ static string unparseProjectIfNeed(SgFile* file, const int curr_regime, const bo
else
{
unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile,
moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString);
moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, (curr_regime == RENAME_INLCUDES), false);
// copy includes that have not changed
if (folderName != NULL)
@@ -362,7 +360,7 @@ static string unparseProjectIfNeed(SgFile* file, const int curr_regime, const bo
}
allIncludeFiles = allIncludeFilesFiltr;
copyIncludes(allIncludeFiles, commentsToInclude, newCopyDeclToIncl, folderName, keepSpfDirs, out_free_form == 1, removeDvmDirs);
copyIncludes(allIncludeFiles, commentsToInclude, newCopyDeclToIncl, folderName, keepSpfDirs, out_free_form == 1, (curr_regime == RENAME_INLCUDES), removeDvmDirs);
}
}
@@ -506,13 +504,13 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
insertIntrinsicStat(getObjectForFileFromMap(file_name, allFuncInfo));
}
else if (curr_regime == LOOP_GRAPH)
loopGraphAnalyzer(file, getObjectForFileFromMap(file_name, loopGraph), getObjectForFileFromMap(file_name, intervals), getObjectForFileFromMap(file_name, SPF_messages), mpiProgram);
loopGraphAnalyzer(file, getObjectForFileFromMap(file_name, loopGraph), getObjectForFileFromMap(file_name, intervals), getObjectForFileFromMap(file_name, SPF_messages), sharedMemoryParallelization);
else if (curr_regime == VERIFY_ENDDO)
{
bool res = EndDoLoopChecker(file, getObjectForFileFromMap(file_name, SPF_messages));
verifyOK &= res;
}
else if (curr_regime == VERIFY_INCLUDE)
else if (curr_regime == VERIFY_INCLUDES)
{
bool res = IncludeChecker(file, file_name, getObjectForFileFromMap(file_name, SPF_messages));
verifyOK &= res;
@@ -521,7 +519,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
{
bool res = DvmDirectiveChecker(file, dvmDirErrors, keepDvmDirectives, ignoreDvmChecker);
verifyOK &= res;
if (dvmDirErrors.size() != 0 && ignoreDvmChecker == 0)
if (dvmDirErrors.size() && ignoreDvmChecker == 0)
printDvmActiveDirsErrors();
}
else if (curr_regime == VERIFY_EQUIVALENCE)
@@ -541,7 +539,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
}
else if (curr_regime == CORRECT_FORMAT_PLACE)
checkAndMoveFormatOperators(file, getObjectForFileFromMap(file_name, SPF_messages), false);
else if (curr_regime == CREATE_PARALLEL_DIRS)
else if (curr_regime == CREATE_PARALLEL_DIRS || curr_regime == INSERT_PARALLEL_DIRS_NODIST)
{
auto &loopsInFile = getObjectForFileFromMap(file_name, loopGraph);
@@ -562,46 +560,14 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
else if (curr_regime == LOOP_ANALYZER_NODIST)
{
auto& loopsInFile = getObjectForFileFromMap(file_name, loopGraph);
loopAnalyzerNoDist(file, parallelRegions, createdArrays, getObjectForFileFromMap(file_name, SPF_messages),
parallizeFreeLoops = 1;
sharedMemoryParallelization = 1;
loopAnalyzer(file, parallelRegions, createdArrays, getObjectForFileFromMap(file_name, SPF_messages), SHARED_MEMORY_PAR,
allFuncInfo, declaredArrays, declaratedArraysSt, arrayLinksByFuncCalls, createDefUseMapByPlace(),
&(loopsInFile));
false, &(loopsInFile));
UniteNestedDirectives(loopsInFile);
}
else if (curr_regime == INSERT_PARALLEL_DIRS_NODIST)
{
auto& loopsInFile = getObjectForFileFromMap(file_name, loopGraph);
map<int, LoopGraph*> mapLoopsInFile;
createMapLoopGraph(loopsInFile, mapLoopsInFile);
map<string, FuncInfo*> mapFuncInfo;
createMapOfFunc(allFuncInfo, mapFuncInfo);
for (int z = 0; z < parallelRegions.size(); ++z)
{
vector<Directive*> toInsert;
DIST::Arrays<int>& allArrays = parallelRegions[z]->GetAllArraysToModify();
map<LoopGraph*, void*> depInfoForLoopGraphV;
for (auto& elem : depInfoForLoopGraph)
depInfoForLoopGraphV[elem.first] = elem.second;
selectParallelDirectiveForVariantNoDist(new File(file), parallelRegions[z], allArrays, loopsInFile, mapLoopsInFile, mapFuncInfo,
toInsert, arrayLinksByFuncCalls, depInfoForLoopGraphV, getObjectForFileFromMap(file_name, SPF_messages));
if (toInsert.size() > 0)
{
auto it = createdDirectives.find(file_name);
if (it == createdDirectives.end())
createdDirectives.insert(it, make_pair(file_name, toInsert));
else
for (int m = 0; m < toInsert.size(); ++m)
it->second.push_back(toInsert[m]);
}
}
}
else if (curr_regime == INSERT_SHADOW_DIRS || curr_regime == EXTRACT_SHADOW_DIRS)
{
const bool extract = (curr_regime == EXTRACT_SHADOW_DIRS);
@@ -1026,7 +992,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
else if (curr_regime == CONVERT_TO_C)
covertToC(file);
else if (curr_regime == SET_IMPLICIT_NONE)
implicitCheck(file);
implicitCheck(file, getObjectForFileFromMap(file_name, dvmDirErrors));
else if (curr_regime == INSERT_NO_DISTR_FLAGS_FROM_GUI)
addPrivatesToArraysFromGUI(file, declaredArrays, distrStateFromGUI);
else if (curr_regime == REMOVE_DEAD_CODE)
@@ -1038,6 +1004,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
}
else if (curr_regime == EXPLORE_IR_LOOPS)
testIR(fullIR);
else if (curr_regime == BUILD_IR_SSA_FORM)
buildIRSSAForm(fullIR);
else if (curr_regime == TEST_PASS)
{
//test pass
@@ -1078,7 +1046,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
if (curr_regime == ONLY_ARRAY_GRAPH)
keepFiles = 1;
if (mpiProgram)
if (sharedMemoryParallelization)
{
for (auto& byFile : loopGraph)
for (auto& loop : byFile.second)
@@ -1347,12 +1315,12 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
// copy includes that have not changed
if (folderName != NULL)
copyIncludes(allIncludeFiles, commentsToInclude, newCopyDeclToIncl, folderName, out_free_form == 1, keepSpfDirs);
copyIncludes(allIncludeFiles, commentsToInclude, newCopyDeclToIncl, folderName, out_free_form == 1, keepSpfDirs, false);
}
else if (curr_regime == EXTRACT_SHADOW_DIRS)
commentsToInclude.clear();
else if (curr_regime == VERIFY_ENDDO ||
curr_regime == VERIFY_INCLUDE ||
curr_regime == VERIFY_INCLUDES ||
curr_regime == VERIFY_DVM_DIRS ||
curr_regime == VERIFY_EQUIVALENCE ||
curr_regime == VERIFY_COMMON ||
@@ -1389,7 +1357,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
vector<string> result;
set<DIST::Array*> arraysDone;
if (mpiProgram)
if (sharedMemoryParallelization)
{
bool wasDone = false;
for (int z = 0; z < parallelRegions.size(); ++z)
@@ -1413,7 +1381,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
{
for (auto& byFile : loopGraph)
for (auto& loop : byFile.second)
loop->createVirtualTemplateLinks(arrayLinksByFuncCalls, SPF_messages, mpiProgram > 0);
loop->createVirtualTemplateLinks(arrayLinksByFuncCalls, SPF_messages, sharedMemoryParallelization > 0);
//add dummy array
DataDirective& dataDirectives = parallelRegions[0]->GetDataDirToModify();
@@ -1458,7 +1426,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
//recalculate array sizes after expression substitution
recalculateArraySizes(arraysDone, allArrays.GetArrays(), arrayLinksByFuncCalls, allFuncInfo);
createDistributionDirs(reducedG, allArrays, dataDirectives, SPF_messages, arrayLinksByFuncCalls, mpiProgram > 0);
createDistributionDirs(reducedG, allArrays, dataDirectives, SPF_messages, arrayLinksByFuncCalls, sharedMemoryParallelization > 0);
ALGORITHMS_DONE[CREATE_DISTIBUTION][z] = 1;
}
@@ -1548,6 +1516,18 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
printParalleRegions("_parallelRegions.txt", parallelRegions);
}
}
if (curr_regime == SET_IMPLICIT_NONE)
{
size_t total_s = 0;
for (auto& err : dvmDirErrors)
total_s += err.second.size();
if (total_s && ignoreDvmChecker == 0)
{
printDvmActiveDirsErrors();
throw(-1);
}
}
else if (curr_regime == FILL_PAR_REGIONS)
{
fillRegionIntervals(parallelRegions);
@@ -1576,7 +1556,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
}
else if (curr_regime == RESOLVE_PAR_REGIONS)
{
bool error = resolveParRegions(parallelRegions, allFuncInfo, SPF_messages, mpiProgram, newCopyDeclToIncl);
bool error = resolveParRegions(parallelRegions, allFuncInfo, SPF_messages, sharedMemoryParallelization, newCopyDeclToIncl);
if (error)
internalExit = 1;
}
@@ -1612,7 +1592,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
else if (curr_regime == INSERT_PARALLEL_DIRS || curr_regime == EXTRACT_PARALLEL_DIRS)
{
bool cond = (folderName != NULL) || (consoleMode) || (!consoleMode && curr_regime == EXTRACT_PARALLEL_DIRS);
if (cond && mpiProgram == 0)
if (cond && sharedMemoryParallelization == 0)
{
//insert template declaration to main program
const bool extract = (curr_regime == EXTRACT_PARALLEL_DIRS);
@@ -1661,7 +1641,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
printDefUseSets("_defUseList.txt", defUseByFunctions);
}
else if (curr_regime == LOOP_ANALYZER_DATA_DIST_S0)
excludeArraysFromDistribution(arrayLinksByFuncCalls, declaredArrays, loopGraph, parallelRegions, SPF_messages, createdArrays, mpiProgram);
excludeArraysFromDistribution(arrayLinksByFuncCalls, declaredArrays, loopGraph, parallelRegions, SPF_messages, createdArrays, sharedMemoryParallelization);
else if (curr_regime == LOOP_ANALYZER_DATA_DIST_S1)
{
for (int z = 0; z < parallelRegions.size(); ++z)
@@ -1673,7 +1653,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
}
else if (curr_regime == PRINT_PAR_REGIONS_ERRORS)
{
bool error = checkRegionsResolving(parallelRegions, allFuncInfo, commonBlocks, SPF_messages, mpiProgram);
bool error = checkRegionsResolving(parallelRegions, allFuncInfo, commonBlocks, SPF_messages, sharedMemoryParallelization);
if (error)
internalExit = 1;
}
@@ -1916,13 +1896,10 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
runPrivateVariableAnalysis(loopGraph, fullIR, commonBlocks, SPF_messages);
else if (curr_regime == FIX_COMMON_BLOCKS)
fixCommonBlocks(allFuncInfo, commonBlocks, &project);
else if (curr_regime == SELECT_ARRAY_DIM_CONF) {
;// SelectArrayConfForParallelization(&project, allFuncInfo, loopGraph, SPF_messages, arrayLinksByFuncCalls);
}
else if (curr_regime == GET_MIN_MAX_BLOCK_DIST)
{
__spf_print(1, "GET_MIN_MAX_BLOCK_DIST: %d %d\n", min_max_block.first, min_max_block.second);
}
else if (curr_regime == GET_STATS_FOR_PREDICTOR)
calculate_stats_for_predictor(allFuncInfo, gCovInfo);
const float elapsed = duration_cast<milliseconds>(high_resolution_clock::now() - timeForPass).count() / 1000.;
const float elapsedGlobal = duration_cast<milliseconds>(high_resolution_clock::now() - globalTime).count() / 1000.;
@@ -2103,7 +2080,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
if (project == NULL && curr_regime != PARSE_FILES)
{
project = createProject(proj_name, parallelRegions, subs_parallelRegions, hiddenData, filesNameWithoutExt, moduleUsesByFile, moduleDecls, exctactedModuleStats);
project = createProject(proj_name, parallelRegions, subs_parallelRegions, hiddenData, filesNameWithoutExt, moduleUsesByFile, moduleDecls, exctactedModuleStats, printSymbTable);
//first check correctness
runPass(VERIFY_FUNC_DECL, proj_name, folderName);
}
@@ -2137,11 +2114,11 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
case INSERT_PARALLEL_DIRS_NODIST:
{
mpiProgram = 1;
sharedMemoryParallelization = 1;
string additionalName = (consoleMode && folderName == NULL) ? "__shared" : "";
runAnalysis(*project, INSERT_PARALLEL_DIRS_NODIST, false);
runAnalysis(*project, CREATE_PARALLEL_DIRS, false);
runPass(REVERT_SUBST_EXPR_RD, proj_name, folderName);
@@ -2170,7 +2147,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
int maxDimsIdxReg = -1;
int lastI = 1;
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
lastI = countMaxValuesForParallelVariants(maxDims, maxDimsIdx, maxDimsIdxReg, currentVariants);
if (genAllVars == 0)
lastI = 1;
@@ -2178,7 +2155,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
for (int i = 0; i < lastI; ++i)
{
//if specific variant number is requested, skip all others
if (genSpecificVar >= 0 && i != genSpecificVar && mpiProgram == 0)
if (genSpecificVar >= 0 && i != genSpecificVar && sharedMemoryParallelization == 0)
continue;
string tmpFolder = "";
@@ -2205,7 +2182,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
runAnalysis(*project, INSERT_PARALLEL_DIRS, false, consoleMode ? additionalName.c_str() : NULL, folderName);
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
{
runPass(CREATE_REMOTES, proj_name, folderName);
runPass(REMOVE_AND_CALC_SHADOW, proj_name, folderName);
@@ -2216,11 +2193,11 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
runPass(RESTORE_LOOP_FROM_ASSIGN, proj_name, folderName);
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
runPass(ADD_TEMPL_TO_USE_ONLY, proj_name, folderName);
runAnalysis(*project, INSERT_REGIONS, false);
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
runPass(GROUP_ACTUAL_AND_REMOTE, proj_name, folderName);
runAnalysis(*project, CALCULATE_STATS_SCHEME, false);
@@ -2244,7 +2221,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
runPass(REVERSE_CREATED_NESTED_LOOPS, proj_name, folderName);
runPass(CLEAR_SPF_DIRS, proj_name, folderName);
runPass(RESTORE_LOOP_FROM_ASSIGN_BACK, proj_name, folderName);
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
runPass(GROUP_ACTUAL_AND_REMOTE_RESTORE, proj_name, folderName);
//clear shadow grouping
@@ -2338,6 +2315,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
case REMOVE_COMMENTS:
case INSERT_NO_DISTR_FLAGS_FROM_GUI:
case PRIVATE_REMOVING:
case RENAME_INLCUDES:
runAnalysis(*project, curr_regime, true, "", folderName);
break;
case INLINE_PROCEDURES:
@@ -2567,8 +2545,8 @@ int main(int argc, char **argv)
pppaAnalyzer(argc - i, argv + i);
else if (string(curr_arg) == "-fdvm")
convertFiles(argc - i, argv + i);
else if (string(curr_arg) == "-mpi") {
mpiProgram = 1;
else if (string(curr_arg) == "-mpi" || string(curr_arg) == "-shared") {
sharedMemoryParallelization = 1;
ignoreArrayDistributeState = true;
}
else if (string(curr_arg) == "-client")
@@ -2617,13 +2595,15 @@ int main(int argc, char **argv)
noLogo = true;
else if (string(curr_arg) == "-includeAll")
inlcudeAllFiles = true;
else if (string(curr_arg) == "-printSymbTable")
printSymbTable = true;
break;
default:
break;
}
}
if (mpiProgram == 1)
if (sharedMemoryParallelization == 1)
{
keepDvmDirectives = 0;
ignoreIO = 1;

View File

@@ -9,7 +9,7 @@ extern int automaticDeprecateArrays;
extern int maxShadowWidth;
extern int langOfMessages;
extern bool removeNestedIntervals;
extern int mpiProgram;
extern int sharedMemoryParallelization;
extern int parallizeFreeLoops;
extern int ignoreIO;
extern int parseForInlining;
@@ -53,7 +53,7 @@ enum passes {
CODE_CHECKER_PASSES,
VERIFY_ENDDO,
VERIFY_INCLUDE,
VERIFY_INCLUDES,
VERIFY_EQUIVALENCE,
VERIFY_COMMON,
VERIFY_FUNC_DECL,
@@ -67,7 +67,6 @@ enum passes {
CHECK_ARGS_DECL,
FIND_FUNC_TO_INCLUDE,
SELECT_ARRAY_DIM_CONF,
ONLY_ARRAY_GRAPH,
PRIVATE_ANALYSIS_SPF,
@@ -110,6 +109,7 @@ enum passes {
FILL_COMMON_BLOCKS,
PREDICT_SCHEME,
CALCULATE_STATS_SCHEME,
GET_STATS_FOR_PREDICTOR,
DEF_USE_STAGE1,
DEF_USE_STAGE2,
@@ -178,7 +178,9 @@ enum passes {
INSERT_NO_DISTR_FLAGS_FROM_GUI,
SET_IMPLICIT_NONE,
RENAME_INLCUDES,
EXPLORE_IR_LOOPS,
BUILD_IR_SSA_FORM,
TEST_PASS,
EMPTY_PASS
@@ -233,12 +235,11 @@ static void setPassValues()
passNames[CALL_GRAPH] = "CALL_GRAPH";
passNames[LOOP_GRAPH] = "LOOP_GRAPH";
passNames[VERIFY_ENDDO] = "VERIFY_ENDDO";
passNames[VERIFY_INCLUDE] = "VERIFY_INCLUDE";
passNames[VERIFY_INCLUDES] = "VERIFY_INCLUDES";
passNames[VERIFY_EQUIVALENCE] = "VERIFY_EQUIVALENCE";
passNames[VERIFY_COMMON] = "VERIFY_COMMON";
passNames[VERIFY_OPERATORS] = "VERIFY_OPERATORS";
passNames[FIND_FUNC_TO_INCLUDE] = "FIND_FUNC_TO_INCLUDE";
passNames[SELECT_ARRAY_DIM_CONF] = "SELECT_ARRAY_DIM_CONF";
passNames[CREATE_DISTR_DIRS] = "CREATE_DISTR_DIRS";
passNames[CREATE_PARALLEL_DIRS] = "CREATE_PARALLEL_DIRS";
passNames[INSERT_PARALLEL_DIRS] = "INSERT_PARALLEL_DIRS";
@@ -290,6 +291,7 @@ static void setPassValues()
passNames[ARRAY_ACCESS_ANALYSIS_FOR_CORNER] = "ARRAY_ACCESS_ANALYSIS_FOR_CORNER";
passNames[FILL_COMMON_BLOCKS] = "FILL_COMMON_BLOCKS";
passNames[PREDICT_SCHEME] = "PREDICT_SCHEME";
passNames[GET_STATS_FOR_PREDICTOR] = "GET_STATS_FOR_PREDICTOR";
passNames[DEF_USE_STAGE1] = "DEF_USE_STAGE1";
passNames[DEF_USE_STAGE2] = "DEF_USE_STAGE2";
passNames[REMOVE_DVM_DIRS_TO_COMMENTS] = "REMOVE_DVM_DIRS_TO_COMMENTS";
@@ -360,8 +362,10 @@ static void setPassValues()
passNames[GET_MIN_MAX_BLOCK_DIST] = "GET_MIN_MAX_BLOCK_DIST";
passNames[CONVERT_TO_C] = "CONVERT_TO_C";
passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE";
passNames[RENAME_INLCUDES] = "RENAME_INLCUDES";
passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI";
passNames[EXPLORE_IR_LOOPS] = "EXPLORE_IR_LOOPS";
passNames[BUILD_IR_SSA_FORM] = "BUILD_IR_SSA_FORM";
passNames[TEST_PASS] = "TEST_PASS";
}

View File

@@ -35,7 +35,7 @@ int intervals_threshold = 100; // threshold for intervals
bool removeNestedIntervals = false; // nested intervals removal flag
int langOfMessages = 1; // 0 - ENG, 1 - RUS
int parallizeFreeLoops = 0; // parallize free calculations
int mpiProgram = 0; // detected mpi calls
int sharedMemoryParallelization = 0; // detected mpi calls
int ignoreIO = 0; // ignore io checker for arrays (DVM IO limitations)
int parseForInlining = 0; // special regime for files parsing for inliner
int dumpIR = 0; // allow dump IR after BUILD_IR pass
@@ -48,6 +48,7 @@ bool noLogo = false;
bool withTemplateInfo = false;
bool inlcudeAllFiles = false; // for pass INSERT_INLCUDES
bool runAsClient = false; // run console project as client for Visualizer
bool printSymbTable = false;
uint64_t currentAvailMemory = 0;
int QUALITY; // quality of conflicts search in graph
@@ -106,7 +107,7 @@ std::map<std::string, CommonBlock*> commonBlocks; // name -> commonBlock
std::map<std::string, std::vector<Messages>> SPF_messages; //file ->messages
//for PARALLEL REGIONS + DVM_CHECKER
//for PARALLEL REGIONS + DVM_CHECKER + SET_IMPLICIT_NONE
std::map<std::string, std::vector<int>> dvmDirErrors; // file->lines
//

View File

@@ -92,6 +92,7 @@ void insertIntrinsicStat(const vector<FuncInfo*>& allFuncInfo)
SgStatement* intr = new SgStatement(INTRIN_STAT);
intr->setExpression(0, makeExprList(list));
intr->setlineNumber(st->lineNumber());
st->insertStmtBefore(*intr, *func->funcPointer);
}

View File

@@ -20,11 +20,12 @@ using UsersDirectives = map<pair<string, int>, set<SgStatement*>>;
// RegularExpr represents expressions like ( coefA * I + coefB ),
// where I is a variable and coefA or coefB can be equal to zero
struct RegularExpr {
int coefA = 0;
int coefA;
int coefB;
string var;
SgSymbol* varSymbol;
RegularExpr(): coefA(0), coefB(0), var("") {}
RegularExpr(): coefA(0), coefB(0), var(""), varSymbol(nullptr) {}
string toString() const
{
@@ -218,7 +219,10 @@ static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr
regularExpr.coefA = retCoefs.first;
regularExpr.coefB = retCoefs.second;
if (!deleteTmpVar)
{
regularExpr.var = iterationVar->identifier();
regularExpr.varSymbol = iterationVar;
}
if (deleteTmpVar)
delete iterationVar;
@@ -236,7 +240,7 @@ static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr
// getShortFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef
static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef,
const vector<bool>& fixedDimensionsMask,
Regime regime, vector<SgSymbol*> iterationVars)
Regime regime)
{
if (regime == Regime::DEFLT)
{
@@ -251,14 +255,12 @@ static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef,
{
vector<int> subscriptsVector;
SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs();
if (iterationVars.size() < indexExprList->length())
return vector<int>{};
for (int i = 0; i < indexExprList->length(); ++i)
{
SgExpression* indexExpr = indexExprList->elem(i);
RegularExpr regularExpr;
if (!checkAndFillRegularExpr(indexExpr, regularExpr, iterationVars[i]))
if (!checkAndFillRegularExpr(indexExpr, regularExpr, nullptr))
return vector<int>{};
subscriptsVector.push_back(regularExpr.coefA);
@@ -271,38 +273,15 @@ static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef,
return vector<int>{};
}
static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, const PrivateToRemove& varToRemove)
{
vector<SgSymbol*> iterationVars;
if (varToRemove.regime == Regime::REGULAR_INDEXES)
{
auto vars = varToRemove.arrayRefToIterationVarsMap.find(arrayRef);
if (vars != varToRemove.arrayRefToIterationVarsMap.end())
iterationVars = vars->second;
}
return getShortFixedSubscriptsVector(arrayRef, varToRemove.fixedDimensions,
varToRemove.regime, iterationVars);
}
// removeDuplicateArrayRefs returns unique array refereces in fixed dimensions
static vector<SgArrayRefExp*> removeDuplicateArrayRefs(const vector<SgArrayRefExp*>& arrayRefs,
const vector<bool>& fixedDimensionsMask,
Regime regime,
const map<SgArrayRefExp*, vector<SgSymbol*>>& arrayRefToIterVarsMap)
Regime regime)
{
map<vector<int>, SgArrayRefExp*> uniqueRefs;
for (SgArrayRefExp* arrayRef : arrayRefs)
{
vector<SgSymbol*> iterationVars;
if (regime == Regime::REGULAR_INDEXES)
{
auto vars = arrayRefToIterVarsMap.find(arrayRef);
if (vars != arrayRefToIterVarsMap.end())
iterationVars = vars->second;
}
vector<int> subscripts = getShortFixedSubscriptsVector(arrayRef, fixedDimensionsMask, regime, iterationVars);
vector<int> subscripts = getShortFixedSubscriptsVector(arrayRef, fixedDimensionsMask, regime);
if (uniqueRefs.find(subscripts) == uniqueRefs.end())
uniqueRefs.insert(make_pair(subscripts, arrayRef));
}
@@ -330,6 +309,7 @@ static bool isSymbolInExpression(SgSymbol* symbol, SgExpression* exp)
isSymbolInExpression(symbol, exp->rhs());
}
// findFuncByName searches function by its name among all functions (and subroutines) in program
static FuncInfo* findFuncByName(string funcName, const map<string, vector<FuncInfo*>>& allFuncInfo)
{
for (const auto& fileFuncs : allFuncInfo)
@@ -340,6 +320,7 @@ static FuncInfo* findFuncByName(string funcName, const map<string, vector<FuncIn
return nullptr;
}
// getCurrentFunc return FuncInfo about current function for stmt
static FuncInfo* getCurrentFunc(SgStatement* stmt, const map<string, vector<FuncInfo*>>& allFuncInfo)
{
auto fileInfo = allFuncInfo.find(stmt->fileName());
@@ -354,8 +335,9 @@ static FuncInfo* getCurrentFunc(SgStatement* stmt, const map<string, vector<Func
return nullptr;
}
// fillIterationVariables fill vars set with iteration variables of all loops
// from stmt to outerLoopStmt
// fillIterationVariables fills SgSymbol* set with iteration variables of all loops
// from stmt to outerLoopStmt. If outerLoopStmt is nullptr, it fill with iteration variables
// from all outer loops
static void fillIterationVars(SgStatement* stmt, SgStatement* outerLoopStmt, vector<SgSymbol*>& vars)
{
if (stmt == nullptr)
@@ -364,7 +346,7 @@ static void fillIterationVars(SgStatement* stmt, SgStatement* outerLoopStmt, vec
if (stmt->variant() == FOR_NODE)
vars.push_back(((SgForStmt*)stmt)->doName());
if (stmt->id() != outerLoopStmt->id())
if (stmt != outerLoopStmt)
fillIterationVars(stmt->controlParent(), outerLoopStmt, vars);
}
@@ -658,6 +640,11 @@ static bool isVarChangedBetween(string var, SgStatement* first, SgStatement* sec
return false;
}
static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, const PrivateToRemove& varToRemove)
{
return getShortFixedSubscriptsVector(arrayRef, varToRemove.fixedDimensions, varToRemove.regime);
}
// fillReadShortFixedSumscripts fills all short fixed subscripts vectors of array var,
// which are used for reading from array var in exp
static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemove& var,
@@ -764,12 +751,27 @@ static void removeVarFromPrivateAttributes(SgSymbol* var, LoopGraph* loop)
// getVarToExpMap returns map SgSymbol* from defRef -> SgExpression* from useRef
static map<SgSymbol*, SgExpression*> getVarToExpMap(SgArrayRefExp* defRef, SgArrayRefExp* useRef,
const vector<bool>& fixedDimensions)
const vector<bool>& fixedDimensions, Regime regime)
{
map<SgSymbol*, SgExpression*> varToExpMap;
for (int i = 0; i < fixedDimensions.size(); ++i)
if (!fixedDimensions[i])
{
if (fixedDimensions[i])
continue;
// check not fixed dimension:
if (regime == Regime::REGULAR_INDEXES)
{
RegularExpr useExpr;
checkAndFillRegularExpr(useRef->subscript(i), useExpr, nullptr);
RegularExpr defExpr;
checkAndFillRegularExpr(defRef->subscript(i), defExpr, nullptr);
varToExpMap.insert(make_pair(defExpr.varSymbol, new SgVarRefExp(useExpr.varSymbol)));
}
else
varToExpMap.insert(make_pair(defRef->subscript(i)->symbol(), useRef->subscript(i)));
}
return varToExpMap;
}
@@ -780,19 +782,6 @@ static set<vector<int>> removeArray(string filename, PrivateToRemove& arrayToRem
{
set<vector<int>> removedFixedSubscripts;
// again fill itaration vars:
arrayToRemove.arrayRefToIterationVarsMap.clear();
SgStatement* loopStmt = arrayToRemove.loop->loop->GetOriginal();
for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext())
{
vector<SgSymbol*> iterationVars;
fillIterationVars(st, loopStmt, iterationVars);
vector<SgArrayRefExp*> arrayRefs = getDirectArrayRefsFromSingleStmt(st, arrayToRemove.varSymbol);
for (SgArrayRefExp* arrayRef : arrayRefs)
arrayToRemove.arrayRefToIterationVarsMap.insert(make_pair(arrayRef, iterationVars));
}
auto& fixedDimensions = arrayToRemove.fixedDimensions;
for (auto& defUsePair : arrayToRemove.defUseStmtsPairs)
{
@@ -823,7 +812,7 @@ static set<vector<int>> removeArray(string filename, PrivateToRemove& arrayToRem
removedFixedSubscripts.insert(useFixedSubscripts);
auto varToExpMap = getVarToExpMap(defRef, useRef, fixedDimensions);
auto varToExpMap = getVarToExpMap(defRef, useRef, fixedDimensions, arrayToRemove.regime);
SgExpression* expToSubst = defStmt->rhs()->copyPtr();
expToSubst = replaceVarsWithExps(expToSubst, varToExpMap);
@@ -867,8 +856,7 @@ void removePrivates(string filename, vector<Messages>& messages,
}
else
{
varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions, varToRemove.regime,
varToRemove.arrayRefToIterationVarsMap);
varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions, varToRemove.regime);
for (auto& varRef : varRefs)
{
vector<int> subscripts = getShortFixedSubscriptsVector(varRef, varToRemove);
@@ -891,6 +879,7 @@ void removePrivates(string filename, vector<Messages>& messages,
}
}
// remove dead code from loop:
for (auto& dcLoopRem : removeDC)
{
auto loopStmt = dcLoopRem->loop->GetOriginal();
@@ -927,7 +916,6 @@ struct Context {
int dimensionsNum;
vector<SgArrayRefExp*> explicitArrayRefs;
vector<bool> fixedDimensionsMask;
map<SgArrayRefExp*, vector<SgSymbol*>> arrayRefToIterationVarsMap;
};
// ReducedArrayVars represents mapping of array reference to reduced scalar var:
@@ -994,15 +982,7 @@ static vector<InsertedStatement>::const_iterator findInsertedStmt(const vector<I
static vector<int> getShortFixedSubscriptsVector(Context* ctx, SgArrayRefExp* arrayRef)
{
vector<SgSymbol*> iterationVars;
if (ctx->regime == Regime::REGULAR_INDEXES)
{
auto vars = ctx->arrayRefToIterationVarsMap.find(arrayRef);
if (vars != ctx->arrayRefToIterationVarsMap.end())
iterationVars = vars->second;
}
return getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime, iterationVars);
return getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime);
}
// getLoopsInfo return vector of pair (string, int) - doName and level for each loop
@@ -1224,26 +1204,34 @@ static bool checkRegularIndexRefs(Context* ctx)
if (!isArrayRefInVector(arrayRef, ctx->explicitArrayRefs))
continue;
// check if unfixed dimension index contains iteration var:
SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs();
if (iterationVars.size() < indexExprList->length())
return false;
for (int i = 0; i < indexExprList->length(); ++i)
{
if (ctx->fixedDimensionsMask[i])
continue;
SgExpression* indexExpr = indexExprList->elem(i);
RegularExpr regularExpr;
if (!checkAndFillRegularExpr(indexExpr, regularExpr, iterationVars[i]))
if (!checkAndFillRegularExpr(indexExpr, regularExpr, nullptr))
return false;
if (regularExpr.coefA == 0)
return false;
bool isIterationVar = false;
for (SgSymbol* iterationVar : iterationVars)
{
if (iterationVar->identifier() == regularExpr.var)
{
isIterationVar = true;
break;
}
}
if (!isIterationVar)
return false;
}
// TODO: possibly can be removed:
if (st->variant() == ASSIGN_STAT && isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol))
for (auto iterationVar : iterationVars)
if (isSymbolInExpression(iterationVar, st->expr(1)))
return false;
iterationVars.resize(indexExprList->length());
ctx->arrayRefToIterationVarsMap.insert(make_pair(arrayRef, iterationVars));
}
}
@@ -1521,7 +1509,8 @@ static vector<vector<ArraySubscript>> checkIndirectUsage(Context* ctx)
if (currentFunc == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
vector<Variable*> commonBlockGroupedVar = getCommonBlockGroupedVar(currentFunc, ctx->arraySymbol, ctx->commonBlocks);
const auto& blocks = ctx->commonBlocks;
vector<Variable*> commonBlockGroupedVar = getCommonBlockGroupedVar(currentFunc, ctx->arraySymbol, blocks);
if (commonBlockGroupedVar.empty())
return indirectUsageMasks;
@@ -1622,9 +1611,11 @@ static ReducedArrayVarsMap getReducedArrayVars(Context* ctx)
{
string name = getReducedArrayVarName(arrayRef->symbol(), subscripts);
int nameNumber = checkSymbNameAndCorrect(name + "__", 0);
if (nameNumber != 0)
if (checkSymbNameAndCorrect(name, "_") != name)
{
int nameNumber = checkSymbNameAndCorrect(name + "__", 0);
name = name + "__" + std::to_string(nameNumber);
}
SgSymbol* newSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), type, scope);
reducedArrayVars.insert(subscripts, newSymbol);
@@ -1699,8 +1690,7 @@ static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx,
{
vector<SgArrayRefExp*> arrayRefs;
fillDirectArrayRefs(st->expr(i), ctx->arraySymbol, arrayRefs);
arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask, ctx->regime,
ctx->arrayRefToIterationVarsMap);
arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask, ctx->regime);
if (!arrayRefs.empty())
isUseStmt = true;
@@ -1773,7 +1763,7 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
set<int> RD_defArgs = RD_forUseArg->second; // make copy
// delete recursive and uninit definition from RD def args:
// delete recursive, uninit and definitions that cannot reach use stmt from RD def args:
set<int> tmpRD_defArgs;
for (int defArgNum : RD_defArgs)
{
@@ -1786,66 +1776,38 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
SgStatement* defStmt = defInsAndBlock.first->getOperator();
auto defInsertedStmt = findInsertedStmt(insertedStmts, defStmt);
if (useInsertedStmt.relatedToStmt == defInsertedStmt->relatedToStmt)
if (useLineNum <= defInsertedStmt->relatedToStmt->lineNumber())
continue;
tmpRD_defArgs.insert(defArgNum);
}
RD_defArgs.swap(tmpRD_defArgs);
if (RD_defArgs.size() == 0) // argument is not initialized
{
addMessageCannotFindRD(ctx->messages, arrayName, useLineNum);
continue;
}
SgStatement* defStmt = nullptr;
if (RD_defArgs.size() > 1)
if (RD_defArgs.size() != 1)
{
bool defIsFound = false;
for (int defArg : RD_defArgs) // try to find the real definition from RD_defArgs
// try to find definition not from RD_defArgs, by search in the block instructions:
string defVarName = useInsertedStmt.insertedStmt->expr(1)->symbol()->identifier();
const auto& blockInstructionsVector = useInsAndBlock.second->getInstructions();
for (auto& instruction : blockInstructionsVector)
{
if (defArg == SAPFOR::CFG_VAL::UNINIT)
continue;
SgStatement* stmt = instruction->getInstruction()->getOperator();
if (stmt == useInsertedStmt.insertedStmt)
break;
auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArg);
if (defInsAndBlock.first == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto defInsertedStmt = findInsertedStmt(insertedStmts, defInsAndBlock.first->getOperator());
if (defInsertedStmt->relatedToStmt->lineNumber() < useLineNum &&
useInsAndBlock.second->getNumber() == defInsAndBlock.second->getNumber())
if (stmt->variant() == ASSIGN_STAT
&& stmt->expr(0)->symbol()->identifier() == defVarName
&& !isVarChangedBetween(defVarName, stmt, useInsertedStmt.insertedStmt))
{
defIsFound = true;
auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArg);
defStmt = defInsAndBlock.first->getOperator();
defStmt = stmt;
break;
}
}
if (!defIsFound)
{
// try to find definition not from RD_defArgs, by search in the block instructions:
string defVarName = useInsertedStmt.insertedStmt->expr(1)->symbol()->identifier();
const auto& blockInstructionsVector = useInsAndBlock.second->getInstructions();
for (auto& instruction : blockInstructionsVector)
{
SgStatement* stmt = instruction->getInstruction()->getOperator();
if (stmt == useInsertedStmt.insertedStmt)
break;
if (stmt->variant() == ASSIGN_STAT
&& stmt->expr(0)->symbol()->identifier() == defVarName
&& !isVarChangedBetween(defVarName, stmt, useInsertedStmt.insertedStmt))
{
defIsFound = true;
defStmt = stmt;
break;
}
}
}
if (!defIsFound)
{
addMessageCannotFindRD(ctx->messages, arrayName, useLineNum);
@@ -1883,15 +1845,6 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
return defUsePairs;
}
//// getScopeLoopStmt returns least outer scope loop statement
//static SgForStmt* getScopeLoopStmt(SgStatement* stmt)
//{
// while (stmt != nullptr && stmt->variant() != FOR_NODE)
// stmt = stmt->controlParent();
//
// return (SgForStmt*)stmt;
//}
// findChildLoop returns LoopGraph for provided loop statement
static LoopGraph* findLoop(LoopGraph* outerLoop, SgForStmt* loopStmt)
{
@@ -2062,7 +2015,8 @@ static bool areDifferentRefs(Context* ctx, SgExpression* exp, const pair<string,
return false;
}
static pair<SAPFOR::Argument*, set<int>> findVarInRDSet(const map<SAPFOR::Argument*, set<int>>& RD_In, const string& var)
static pair<SAPFOR::Argument*, set<int>> findVarInRDSet(const map<SAPFOR::Argument*, set<int>>& RD_In,
const string& var)
{
for (auto& RD_InElem : RD_In)
{
@@ -2092,7 +2046,9 @@ static bool checkDefUsePair(Context* ctx, const DefUseStmtsPair& defUse, const C
vector<SgArrayRefExp*> arrayUseRefs = getDirectArrayRefsFromSingleStmt(defUse.second, ctx->arraySymbol);
for (auto useRef : arrayUseRefs)
{
map<SgSymbol*, SgExpression*> varToExpMap = getVarToExpMap(defRef, useRef, ctx->fixedDimensionsMask);
map<SgSymbol*, SgExpression*> varToExpMap;
varToExpMap = getVarToExpMap(defRef, useRef, ctx->fixedDimensionsMask, ctx->regime);
SgExpression* expToSubst = defUse.first->rhs()->copyPtr();
expToSubst = replaceVarsWithExps(expToSubst, varToExpMap);
@@ -2100,7 +2056,7 @@ static bool checkDefUsePair(Context* ctx, const DefUseStmtsPair& defUse, const C
}
vector<SgSymbol*> iterationVars{};
fillIterationVars(defUse.second, ctx->loopStmt, iterationVars);
fillIterationVars(defUse.second, nullptr, iterationVars);
auto defInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.first);
const auto& defRD_In = defInsAndBlock.second->getRD_In();
@@ -2281,7 +2237,6 @@ void removePrivateAnalyze(Context *ctx)
newPrivateToRemove.regime = ctx->regime;
newPrivateToRemove.defUseStmtsPairs.swap(resultDefUsePairs);
newPrivateToRemove.fixedDimensions.swap(ctx->fixedDimensionsMask);
newPrivateToRemove.arrayRefToIterationVarsMap = ctx->arrayRefToIterationVarsMap;
privatesToRemoveGlobal.push_back(newPrivateToRemove);
}
@@ -2348,6 +2303,8 @@ void removePrivatesAnalysis(string filename,
context.dimensionsNum = ((SgArrayType*)arrayToRemove->type())->dimension();
context.arraySymbol = arrayToRemove;
string arrayName = arrayToRemove->identifier();
auto filterMasks = checkImplicitAndIndirectUsage(&context);
filterArrayRefs(&context, arrayRefs, filterMasks);
@@ -2357,8 +2314,7 @@ void removePrivatesAnalysis(string filename,
if (!checkLoopAlignmentMatching(&context))
{
addMessageVarNotAlignedWithLoop(messages, context.arraySymbol->identifier(),
context.loop->lineNum);
addMessageVarNotAlignedWithLoop(messages, arrayName, context.loop->lineNum);
continue;
}
@@ -2373,14 +2329,10 @@ void removePrivatesAnalysis(string filename,
else if (checkRegularIndexRefs(&context))
{
context.regime = Regime::REGULAR_INDEXES;
context.fixedDimensionsMask = vector<bool>{};
removePrivateAnalyze(&context);
}
else
{
addMessageDoesNotMatchMask(messages, context.arraySymbol->identifier(),
context.loop->lineNum);
}
addMessageDoesNotMatchMask(messages, arrayName, context.loop->lineNum);
}
}

View File

@@ -17,7 +17,6 @@ struct PrivateToRemove {
Regime regime;
std::vector<std::pair<SgAssignStmt*, SgStatement*>> defUseStmtsPairs;
std::vector<bool> fixedDimensions;
std::map<SgArrayRefExp*, std::vector<SgSymbol*>> arrayRefToIterationVarsMap;
};
// removePrivates removes all privates from vector privatesToRemoveGloval

View File

@@ -30,6 +30,17 @@ static void FillCommonTypes(map<char, SgType*>& types)
types[letter.first] = new SgType(T_FLOAT);
}
static bool isByUse(SgSymbol* s, SgStatement* checkScope)
{
auto scope = s->scope();
auto isByUse_s = IS_BY_USE(s);
if (!isByUse_s && scope == checkScope)
return false;
else
return true;
}
static void FindAllVars(SgExpression* expr, set<SgSymbol*>& allVars, set<SgSymbol*>& allVarsConst, SgStatement* scope)
{
if (expr == NULL)
@@ -38,20 +49,25 @@ static void FindAllVars(SgExpression* expr, set<SgSymbol*>& allVars, set<SgSymbo
const int var = expr->variant();
if (var == VAR_REF || var == ARRAY_REF || var == FUNC_CALL)
{
auto s = expr->symbol();
auto s = expr->symbol();
const string ident(s->identifier());
if (var == FUNC_CALL /*(s->attributes() & EXTERNAL_BIT)*/)
{
if (!IS_BY_USE(s) /* && s->scope() == scope*/)
if (!IS_BY_USE(s) && ident.find("::") == string::npos /* && s->scope() == scope*/)
allVars.insert(s);
}
else
{
if (!IS_BY_USE(s) && s->scope() == scope)
if (!IS_BY_USE(s) && ident.find("::") == string::npos && s->scope() == scope)
allVars.insert(s);
}
}
else if (var == CONST_REF)
allVarsConst.insert(expr->symbol());
{
auto s = expr->symbol();
if (!isByUse(s, scope))
allVarsConst.insert(s);
}
FindAllVars(expr->lhs(), allVars, allVarsConst, scope);
FindAllVars(expr->rhs(), allVars, allVarsConst, scope);
@@ -98,7 +114,8 @@ static void AddLettersToMap(SgExpression* expr, SgType* type, map<char, SgType*>
}
static vector<SgSymbol*> getVars(const set<string>& functionSymbs, set<SgSymbol*>& toRename,
const set<SgSymbol*>& allVars, const map<char, SgType*>& types)
const set<SgSymbol*>& allVars, const map<char, SgType*>& types,
SgStatement* scope)
{
vector<SgSymbol*> varsWithoutDecl;
map<string, SgSymbol*> vars;
@@ -115,7 +132,7 @@ static vector<SgSymbol*> getVars(const set<string>& functionSymbs, set<SgSymbol*
continue;
vector<SgStatement*> allDecls;
declaratedInStmt(var, &allDecls, false);
declaratedInStmt(var, &allDecls, false, (var->variant() == FUNCTION_NAME) ? scope : NULL);
bool hasTypeDecls = false;
for (auto& decl : allDecls)
@@ -148,7 +165,8 @@ static vector<SgSymbol*> getVars(const set<string>& functionSymbs, set<SgSymbol*
return varsWithoutDecl;
}
static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map<SgStatement*, map<char, SgType*>>& typesByFunctions)
static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map<SgStatement*, map<char, SgType*>>& typesByFunctions,
vector<int>& dvmDirErrorsLines)
{
set<SgSymbol*> allVars, allVarsConst;
map<char, SgType*> types;
@@ -193,7 +211,7 @@ static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map
break;
}
set<int> skip = { EXTERN_STAT };
set<int> skip = { EXTERN_STAT, PRIVATE_STMT, PUBLIC_STMT };
set<SgSymbol*> allDataSymbols;
for (auto s = function->symbol()->next(); s; s = s->next())
@@ -222,6 +240,9 @@ static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map
if (skip.count(st->variant()))
continue;
if (isDVM_stat(st))
dvmDirErrorsLines.push_back(st->lineNumber());
if (isDVM_stat(st) || isSPF_stat(st))
continue;
@@ -246,11 +267,8 @@ static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map
FindAllVars(st->expr(i), allVars, allVarsConst, function);
if (st->variant() == FOR_NODE)
{
auto s = isSgForStmt(st)->doName();
if (!IS_BY_USE(s) && s->scope() == function)
allVars.insert(s);
}
if (!isByUse(isSgForStmt(st)->doName(), function))
allVars.insert(isSgForStmt(st)->doName());
}
//add parameters
@@ -264,8 +282,8 @@ static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map
}
}
varsWithoutDecl = getVars(functionSymbs, toRename, allVars, types);
varsWithoutDeclConst = getVars(functionSymbs, toRename, allVarsConst, types);
varsWithoutDecl = getVars(functionSymbs, toRename, allVars, types, function);
varsWithoutDeclConst = getVars(functionSymbs, toRename, allVarsConst, types, NULL);
if (!hasImplicitNone)
{
@@ -341,17 +359,20 @@ static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map
return types;
}
void implicitCheck(SgFile* file)
void implicitCheck(SgFile* file, vector<int>& dvmDirErrorsLines)
{
map<SgStatement*, map<char, SgType*>> typesByFunctions;
vector<SgStatement*> modulesAndFunctions;
getModulesAndFunctions(file, modulesAndFunctions);
const string currFile = file->filename();
for (int func = 0; func < modulesAndFunctions.size(); ++func)
{
SgStatement* function = modulesAndFunctions[func];
typesByFunctions[function] = FunctionImplicitCheck(function, typesByFunctions);
if (function->fileName() != currFile)
continue;
typesByFunctions[function] = FunctionImplicitCheck(function, typesByFunctions, dvmDirErrorsLines);
}
typesByFunctions.clear();

View File

@@ -1,3 +1,5 @@
#pragma once
void implicitCheck(SgFile* file);
#include <vector>
void implicitCheck(SgFile* file, std::vector<int>& dvmDirErrorsLines);

View File

@@ -223,23 +223,23 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
Pass(PRIVATE_ANALYSIS_IR) <= Pass(LOOP_ANALYZER_NODIST);
Pass(CORRECT_VAR_DECL) <= list({ VERIFY_DVM_DIRS, PREPROC_SPF, VERIFY_ENDDO, VERIFY_INCLUDE, PREPROC_ALLOCATES, CHECK_FUNC_TO_INCLUDE, FILL_PAR_REGIONS_LINES, CONVERT_ASSIGN_TO_LOOP, VERIFY_COMMON, VERIFY_EQUIVALENCE, PRINT_PAR_REGIONS_ERRORS, VERIFY_OPERATORS, VERIFY_FORMAT }) <= Pass(CODE_CHECKER_PASSES);
Pass(CORRECT_VAR_DECL) <= list({ VERIFY_DVM_DIRS, VERIFY_OPERATORS, VERIFY_FORMAT, VERIFY_ENDDO, PREPROC_SPF, VERIFY_INCLUDES, PREPROC_ALLOCATES, CHECK_FUNC_TO_INCLUDE, FILL_PAR_REGIONS_LINES, CONVERT_ASSIGN_TO_LOOP, VERIFY_COMMON, VERIFY_EQUIVALENCE, PRINT_PAR_REGIONS_ERRORS }) <= Pass(CODE_CHECKER_PASSES);
list({ VERIFY_ENDDO, VERIFY_INCLUDE, PREPROC_SPF, PREPROC_ALLOCATES, GET_ALL_ARRAY_DECL, GCOV_PARSER }) <= list({ CALL_GRAPH, MACRO_EXPANSION, DEF_USE_STAGE1 });
list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_INCLUDES, PREPROC_SPF, PREPROC_ALLOCATES, GET_ALL_ARRAY_DECL, GCOV_PARSER }) <= list({ CALL_GRAPH, MACRO_EXPANSION, DEF_USE_STAGE1 });
list({ VERIFY_ENDDO, VERIFY_INCLUDE, PREPROC_ALLOCATES, FILL_PARALLEL_REG_IR }) <= list({ GET_ALL_ARRAY_DECL, FILL_COMMON_BLOCKS, PARSE_OMP_DIRS }) <= Pass(PREPROC_SPF);
list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_INCLUDES, PREPROC_ALLOCATES, FILL_PARALLEL_REG_IR }) <= list({ GET_ALL_ARRAY_DECL, FILL_COMMON_BLOCKS, PARSE_OMP_DIRS }) <= Pass(PREPROC_SPF);
Pass(CHECK_PAR_REG_DIR) <= Pass(FILL_PARALLEL_REG_IR);
list({ GET_ALL_ARRAY_DECL, CALL_GRAPH2, CODE_CHECKER_PASSES, SUBST_EXPR_RD, ARRAY_ACCESS_ANALYSIS_FOR_CORNER }) <= list({ LOOP_ANALYZER_NODIST, LOOP_ANALYZER_DATA_DIST_S0, LOOP_ANALYZER_DATA_DIST_S1, ONLY_ARRAY_GRAPH });
list({ CODE_CHECKER_PASSES, GET_ALL_ARRAY_DECL, CALL_GRAPH2, SUBST_EXPR_RD, ARRAY_ACCESS_ANALYSIS_FOR_CORNER }) <= list({ LOOP_ANALYZER_NODIST, LOOP_ANALYZER_DATA_DIST_S0, LOOP_ANALYZER_DATA_DIST_S1, ONLY_ARRAY_GRAPH });
list({ LOOP_ANALYZER_NODIST, REMOVE_OMP_DIRS }) <= Pass(SELECT_ARRAY_DIM_CONF) <= Pass(INSERT_PARALLEL_DIRS_NODIST);
list({ LOOP_ANALYZER_NODIST, REMOVE_OMP_DIRS }) <= Pass(INSERT_PARALLEL_DIRS_NODIST);
Pass(CHECK_ARGS_DECL) <= Pass(CREATE_TEMPLATE_LINKS);
Pass(LOOP_ANALYZER_DATA_DIST_S0) <= Pass(LOOP_ANALYZER_DATA_DIST_S1) <= Pass(LOOP_ANALYZER_DATA_DIST_S2) <= Pass(CREATE_TEMPLATE_LINKS) <= Pass(LOOP_ANALYZER_COMP_DIST);
list({ VERIFY_ENDDO, VERIFY_FORMAT, SUBST_EXPR_RD, CONVERT_ASSIGN_TO_LOOP }) <= Pass(LOOP_GRAPH) <= Pass(CALL_GRAPH) <= Pass(CALL_GRAPH2);
list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_FORMAT, SUBST_EXPR_RD, CONVERT_ASSIGN_TO_LOOP }) <= Pass(LOOP_GRAPH) <= Pass(CALL_GRAPH) <= Pass(CALL_GRAPH2);
Pass(MACRO_EXPANSION) <= Pass(CALL_GRAPH);
@@ -265,13 +265,13 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
list({ LOOP_ANALYZER_COMP_DIST, REMOVE_OMP_DIRS }) <= list({ CREATE_DISTR_DIRS, CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS });
Pass(CALL_GRAPH2) <= list({ ONLY_ARRAY_GRAPH, CREATE_NESTED_LOOPS, FIND_FUNC_TO_INCLUDE, CHECK_FUNC_TO_INCLUDE, FIND_PARAMETERS });
Pass(CALL_GRAPH2) <= list({ ONLY_ARRAY_GRAPH, CREATE_NESTED_LOOPS, FIND_FUNC_TO_INCLUDE, CHECK_FUNC_TO_INCLUDE, FIND_PARAMETERS, GET_STATS_FOR_PREDICTOR });
Pass(CALL_GRAPH2) <= list({ PURE_SAVE_TO_PARAMS, PURE_MODULE_TO_PARAMS, PURE_COMMON_TO_PARAMS, PURE_INTENT_INSERT });
Pass(REVERT_SUBST_EXPR_RD) <= list({ PURE_SAVE_TO_PARAMS, PURE_MODULE_TO_PARAMS, PURE_COMMON_TO_PARAMS, PURE_INTENT_INSERT });
list({ CORRECT_VAR_DECL, REVERT_SUBST_EXPR_RD, VERIFY_INCLUDE }) <= list({ CONVERT_TO_ENDDO, CORRECT_CODE_STYLE, REMOVE_DVM_DIRS, REMOVE_DVM_DIRS_TO_COMMENTS, REMOVE_DVM_INTERVALS });
list({ CORRECT_VAR_DECL, REVERT_SUBST_EXPR_RD, VERIFY_INCLUDES }) <= list({ CONVERT_TO_ENDDO, CORRECT_CODE_STYLE, REMOVE_DVM_DIRS, REMOVE_DVM_DIRS_TO_COMMENTS, REMOVE_DVM_INTERVALS });
list({ CALL_GRAPH2, CONVERT_LOOP_TO_ASSIGN, REVERT_SUBST_EXPR_RD, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(INLINE_PROCEDURES);
@@ -310,9 +310,10 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
list({ CALL_GRAPH2, REVERT_SUBST_EXPR_RD }) <= Pass(REMOVE_DEAD_CODE);
list({ REMOVE_DEAD_CODE, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE);
Pass(CORRECT_VAR_DECL) <= Pass(SET_IMPLICIT_NONE);
list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE);
list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2 }) <= Pass(EXPLORE_IR_LOOPS);
list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2 }) <= Pass(BUILD_IR_SSA_FORM);
passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS,
EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW,

View File

@@ -276,6 +276,9 @@ static set<int> hideUnnecessary(SgFile* file, const string& fileN, const set<str
set<int> changedVars;
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
{
if (st->variant() == GLOBAL)
continue;
if (dontReplaceIncludes == false)
{
if (st->fileName() != fileN || st->getUnparseIgnore())
@@ -311,7 +314,7 @@ string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const ch
set<string> &allIncludeFiles, bool outFree,
const map<string, set<string>>& moduleUsesByFile, const map<string, string>& moduleDelcs,
const map<SgStatement*, vector<SgStatement*>>& exctactedModuleStats,
bool toString, bool dontReplaceIncludes)
bool toString, bool renameIncludes, bool dontReplaceIncludes)
{
removeSpecialCommentsFromProject(file);
@@ -572,7 +575,7 @@ string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const ch
string inlcude = "";
for (auto& inclByPos : toInsertIncludeComment)
for (auto& incl : inclByPos.second)
inlcude += incl;
inlcude += (renameIncludes ? renameInclude(incl) : incl);
if (st->comments())
st->setComments((inlcude + st->comments()).c_str());
@@ -658,7 +661,7 @@ string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const ch
strUnparse = string(file->firstStatement()->unparse());
else
{
auto tmp = string(file->firstStatement()->unparse());
const string tmp = file->firstStatement()->unparse();
if (tmp.size() > 0)
{
#ifdef _WIN32
@@ -1015,12 +1018,15 @@ static bool findSymbol(SgExpression *declLst, const string &toFind)
}
extern map<string, vector<Messages>> SPF_messages;
SgStatement* declaratedInStmt(SgSymbol *toFind, vector<SgStatement*> *allDecls, bool printInternal)
SgStatement* declaratedInStmt(SgSymbol *toFind, vector<SgStatement*> *allDecls, bool printInternal, SgStatement* scope)
{
//need to call this function for MODULE symbols!
toFind = OriginalSymbol(toFind);
vector<SgStatement*> inDecl;
SgStatement *start = toFind->scope();
if (toFind->variant() == FUNCTION_NAME && scope == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement *start = scope ? scope : toFind->scope();
if (start)
{
@@ -2373,7 +2379,7 @@ void printSymbolTable(SgFile *file, string filter, const set<int>& vars)
if (need)
{
int line = s->scope() ? s->scope()->lineNumber() : -1;
printf("[%d] '%s' type %d ('%s'), location %d line, variant %d, %0lx\n", s->id(), s->identifier(), t ? t->variant() : -1, t ? tag[t->variant()] : "", line, s->variant(), s->thesymb);
printf("[%d] '%s' type %d ('%s'), location %d line, variant %d, addr %p\n", s->id(), s->identifier(), t ? t->variant() : -1, t ? tag[t->variant()] : "", line, s->variant(), s->thesymb);
}
}
}
@@ -2718,7 +2724,7 @@ SgStatement* makeDeclaration(SgStatement* curr, const vector<SgSymbol*>& sIn, ve
decl->setFileName(place->fileName());
decl->setFileId(place->getFileId());
decl->setProject(place->getProject());
decl->setlineNumber(getNextNegativeLineNumber());
decl->setlineNumber(place->lineNumber());
place->insertStmtBefore(*decl, *scope);
}
@@ -3136,7 +3142,8 @@ SgProject* createProject(const char* proj_name,
map<string, int>& filesNameWithoutExt,
map<string, set<string>>& moduleUsesByFile,
map<string, string>& moduleDecls,
map<string, map<SgStatement*, vector<SgStatement*>>>& exctactedModuleStats)
map<string, map<SgStatement*, vector<SgStatement*>>>& exctactedModuleStats,
bool printSymbTable)
{
Statement::setSapforRegime();
Statement::deactiveConsistentchecker();
@@ -3144,7 +3151,14 @@ SgProject* createProject(const char* proj_name,
SgProject* project = new SgProject(proj_name);
addNumberOfFileToAttribute(project);
//printSymbolTable(&project->file(0), "");
if (printSymbTable) {
for (int z = 0; z < project->numberOfFiles(); ++z) {
SgFile* file = &(project->file(z));
printf("===== TABLE FOR FILE %s\n", file->filename());
printSymbolTable(file, "");
}
exit(0);
}
parallelRegions.push_back(new ParallelRegion(0, "DEFAULT"));
subs_parallelRegions.push_back(new ParallelRegion(0, "DEFAULT"));
@@ -3338,7 +3352,7 @@ SgProject* createProject(const char* proj_name,
if (detectMpiCalls(project, SPF_messages))
{
mpiProgram = 1;
sharedMemoryParallelization = 1;
keepDvmDirectives = 0;
ignoreIO = 1;
parallizeFreeLoops = 0;

View File

@@ -6,12 +6,12 @@
#include "../GraphCall/graph_calls.h"
#include "../DynamicAnalysis/gcov_info.h"
SgStatement* declaratedInStmt(SgSymbol *toFind, std::vector<SgStatement*> *allDecls = NULL, bool printInternal = true);
SgStatement* declaratedInStmt(SgSymbol *toFind, std::vector<SgStatement*> *allDecls = NULL, bool printInternal = true, SgStatement* scope = NULL);
#include "DefUseList.h"
#include "CommonBlock.h"
std::string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const char *fout, std::set<std::string> &allIncludeFiles, bool outFree, const std::map<std::string, std::set<std::string>> &moduleUsesByFile, const std::map<std::string, std::string>& moduleDelcs, const std::map<SgStatement*, std::vector<SgStatement*>>& exctactedModuleStats, bool toString, bool dontReplaceIncls = false);
std::string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const char *fout, std::set<std::string> &allIncludeFiles, bool outFree, const std::map<std::string, std::set<std::string>> &moduleUsesByFile, const std::map<std::string, std::string>& moduleDelcs, const std::map<SgStatement*, std::vector<SgStatement*>>& exctactedModuleStats, bool toString, bool renameIncludes, bool dontReplaceIncls);
SgSymbol* findSymbolOrCreate(SgFile *file, const std::string toFind, SgType *type = NULL, SgStatement *scope = NULL);
void recExpressionPrint(SgExpression *exp);
void removeSubstrFromStr(std::string &str, const std::string &del);
@@ -90,7 +90,7 @@ void getVariables(SgExpression* ex, std::set<SgSymbol*>& variables, const std::s
template<typename T>
std::set<T> getAllVariables(SgStatement* stFrom, SgStatement* stTo, const std::set<int>& variants);
SgProject* createProject(const char* proj_name, std::vector<ParallelRegion*>& parallelRegions, std::vector<ParallelRegion*>& subs_parallelRegions, std::map<std::string, std::vector<SgStatement*>>& hiddenData, std::map<std::string, int>& filesNameWithoutExt, std::map<std::string, std::set<std::string>>& moduleUsesByFile, std::map<std::string, std::string>& moduleDecls, std::map<std::string, std::map<SgStatement*, std::vector<SgStatement*>>>& exctactedModuleStats);
SgProject* createProject(const char* proj_name, std::vector<ParallelRegion*>& parallelRegions, std::vector<ParallelRegion*>& subs_parallelRegions, std::map<std::string, std::vector<SgStatement*>>& hiddenData, std::map<std::string, int>& filesNameWithoutExt, std::map<std::string, std::set<std::string>>& moduleUsesByFile, std::map<std::string, std::string>& moduleDecls, std::map<std::string, std::map<SgStatement*, std::vector<SgStatement*>>>& exctactedModuleStats, bool printSymbTable);
bool isArrayType(SgType* type);
bool isArrayRef(SgExpression* ex);

View File

@@ -159,7 +159,8 @@ void printHelp(const char **passNames, const int lastPass)
printf(" -passInfo print passes information\n");
printf(" -dumpIR print IR information (works only with BUILD_IR pass)\n");
printf(" -ignoreDistArray ingnore array distribution information (set to all arrays no distribution state\n");
printf(" -mpi shared memory and mpi programs parallelization\n");
printf(" -shared shared memory and mpi programs parallelization\n");
printf(" -printSymbTable print all symbol tables of project\n");
printf("\n");
printf(" -F <folderName> output to folder\n");
@@ -203,7 +204,7 @@ const string printVersionAsFortranComm()
ret += "! *** consider DVMH directives\n";
if (keepSpfDirs)
ret += "! *** save SPF directives\n";
if (mpiProgram)
if (sharedMemoryParallelization)
ret += "! *** MPI program regime (shared memory parallelization)\n";
if (ignoreIO)
ret += "! *** ignore I/O checker for arrays (DVM I/O limitations)\n";
@@ -520,16 +521,49 @@ bool isDVM_comment(const string& bufStr)
return dvmStart;
}
static string renameExtension(const string& inc)
{
string ret = inc;
if (ret.find(".") != string::npos)
ret = OnlyName(ret.c_str());
ret += ".h";
return ret;
}
string renameInclude(const string& inc)
{
auto posStart = inc.find("'");
auto posEnd = inc.find("'", posStart + 1);
if (posStart == string::npos || posEnd == string::npos)
{
posStart = inc.find("\"");
posEnd = inc.find("\"", posStart + 1);
if (posStart == string::npos || posEnd == string::npos) {
__spf_print(1, "incorrect include string <%s>\n", inc.c_str());
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
string substr = renameExtension(inc.substr(posStart + 1, posEnd - posStart - 1));
string ret = inc;
ret.replace(posStart + 1, posEnd - posStart - 1, substr);
return ret;
}
void copyIncludes(const set<string> &allIncludeFiles, const map<string, map<int, set<string>>> &commentsToInclude,
const map<string, map<int, set<string>>>& newCopyDeclToIncl,
const char *folderName, bool keepSpfDirs, bool isFreeStyle, int removeDvmDirs)
const char *folderName, bool keepSpfDirs, bool isFreeStyle, bool isRename,
int removeDvmDirs)
{
for (auto &include : allIncludeFiles)
{
if (commentsToInclude.find(include) != commentsToInclude.end())
continue;
string newCurrFile = string(folderName) + "/" + include;
string newCurrFile = string(folderName) + "/" + (isRename ? renameExtension(include) : include);
FILE *tryToOpen = fopen(newCurrFile.c_str(), "r");
if (tryToOpen == NULL)
@@ -1157,6 +1191,7 @@ objT& getObjectForFileFromMap(const char *fileName, map<string, objT> &mapObject
return it->second;
}
template vector<int>& getObjectForFileFromMap(const char* fileName, map<string, vector<int>>&);
template vector<Messages>& getObjectForFileFromMap(const char *fileName, map<string, vector<Messages>>&);
template vector<LoopGraph*>& getObjectForFileFromMap(const char *fileName, map<string, vector<LoopGraph*>>&);
template vector<FuncInfo*>& getObjectForFileFromMap(const char *fileName, map<string, vector<FuncInfo*>>&);

View File

@@ -33,7 +33,8 @@ const std::string& getGlobalBuffer();
std::wstring to_wstring(const std::string);
void convertBuffers(short*& resultM, int*& resultSizeM, short*& result, int*& resultSize);
void clearGlobalMessagesBuffer();
void copyIncludes(const std::set<std::string> &allIncludeFiles, const std::map<std::string, std::map<int, std::set<std::string>>> &commentsToInclude, const std::map<std::string, std::map<int, std::set<std::string>>>& newCopyDeclToIncl, const char *folderName, bool keepSpfDirs, bool isFreeStyle, int removeDvmDirs = 0);
std::string renameInclude(const std::string& inc);
void copyIncludes(const std::set<std::string> &allIncludeFiles, const std::map<std::string, std::map<int, std::set<std::string>>> &commentsToInclude, const std::map<std::string, std::map<int, std::set<std::string>>>& newCopyDeclToIncl, const char *folderName, bool keepSpfDirs, bool isFreeStyle, bool isRename, int removeDvmDirs = 0);
std::string splitDirective(const std::string &in);
std::string splitDirectiveFull(const std::string &in_);

View File

@@ -1,3 +1,3 @@
#pragma once
#define VERSION_SPF "2346"
#define VERSION_SPF "2362"

View File

@@ -554,11 +554,15 @@ bool OperatorChecker(SgFile* file, map<string, vector<Messages>>& currMessages)
SgStatement* st = file->firstStatement();
string currF = file->filename();
while (st)
{
int line = st->lineNumber();
if (line > 0 && st->fileName() == currF)
if (line > 0 && st->variant() == PROG_HEDR && st->symbol()->identifier() == string("_MAIN"))
; // skip
else if (line > 0 && st->fileName() == currF)
{
;
int var = st->controlParent()->variant();
bool cpWasAdded = (var == ARITHIF_NODE || var == LOGIF_NODE || var == GOTO_NODE || var == IF_NODE) && (usedLines.find(line) != usedLines.end());

View File

@@ -166,10 +166,10 @@ static void setOptions(const short* options, bool isBuildParallel = false, const
removeNestedIntervals = (intOptions[KEEP_LOOPS_CLOSE_NESTING] == 1);
showDebug = (intOptions[DEBUG_PRINT_ON] == 1);
mpiProgram = (mpiProgram != 1) ? intOptions[MPI_PROGRAM] : mpiProgram;
parallizeFreeLoops = (mpiProgram == 1) ? 0 : intOptions[PARALLIZE_FREE_LOOPS];
ignoreIO = (mpiProgram == 1) ? 1 : intOptions[IGNORE_IO_SAPFOR];
keepDvmDirectives = (mpiProgram == 1) ? 0 : intOptions[KEEP_DVM_DIRECTIVES];
sharedMemoryParallelization = (sharedMemoryParallelization != 1) ? intOptions[MPI_PROGRAM] : sharedMemoryParallelization;
parallizeFreeLoops = (sharedMemoryParallelization == 1) ? 0 : intOptions[PARALLIZE_FREE_LOOPS];
ignoreIO = (sharedMemoryParallelization == 1) ? 1 : intOptions[IGNORE_IO_SAPFOR];
keepDvmDirectives = (sharedMemoryParallelization == 1) ? 0 : intOptions[KEEP_DVM_DIRECTIVES];
parseForInlining = intOptions[PARSE_FOR_INLINE];
@@ -819,8 +819,8 @@ int SPF_GetArrayDistribution(void*& context, int winHandler, short *options, sho
runPassesForVisualizer(projName, { CREATE_TEMPLATE_LINKS });
else if (regime == 1)
{
if (mpiProgram)
runPassesForVisualizer(projName, { SELECT_ARRAY_DIM_CONF });
if (sharedMemoryParallelization)
runPassesForVisualizer(projName, { LOOP_ANALYZER_NODIST });
else
runPassesForVisualizer(projName, { LOOP_ANALYZER_DATA_DIST_S1 });
}
@@ -1061,7 +1061,7 @@ int SPF_CreateParallelVariant(void*& context, int winHandler, short *options, sh
throw (-5);
int countOfDist = 0;
if (mpiProgram == 0)
if (sharedMemoryParallelization == 0)
{
map<uint64_t, vector<pair<int64_t, int64_t>>> varLens;
for (int i = 0, k = 0; i < *varLen; i += 3, ++k)
@@ -1892,7 +1892,7 @@ int SPF_SharedMemoryParallelization(void*& context, int winHandler, short* optio
MessageManager::clearCache();
MessageManager::setWinHandler(winHandler);
ignoreArrayDistributeState = true;
mpiProgram = 1;
sharedMemoryParallelization = 1;
return simpleTransformPass(INSERT_PARALLEL_DIRS_NODIST, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize, true);
}
@@ -1920,6 +1920,14 @@ int SPF_InsertImplicitNone(void*& context, int winHandler, short* options, short
return simpleTransformPass(SET_IMPLICIT_NONE, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize);
}
int SPF_RenameIncludes(void*& context, int winHandler, short* options, short* projName, short* folderName, short*& output,
int*& outputSize, short*& outputMessage, int*& outputMessageSize)
{
MessageManager::clearCache();
MessageManager::setWinHandler(winHandler);
return simpleTransformPass(RENAME_INLCUDES, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize);
}
static inline void convertBackSlash(char *str, int strL)
{
for (int z = 0; z < strL; ++z)
@@ -2636,6 +2644,8 @@ const wstring Sapfor_RunTransformation(const char* transformName_c, const char*
retCode = SPF_RemoveDeadCode(context, winHandler, optSh, projSh, fold, output, outputSize, outputMessage, outputMessageSize);
else if (whichRun == "SPF_InsertImplicitNone")
retCode = SPF_InsertImplicitNone(context, winHandler, optSh, projSh, fold, output, outputSize, outputMessage, outputMessageSize);
else if (whichRun == "SPF_RenameIncludes")
retCode = SPF_RenameIncludes(context, winHandler, optSh, projSh, fold, output, outputSize, outputMessage, outputMessageSize);
else
{
if (showDebug)