Files
SAPFOR/src/Transformations/array_assign_to_loop.cpp
2025-03-25 21:09:12 +03:00

2245 lines
84 KiB
C++

#include "../Utils/leak_detector.h"
#include <cstdio>
#include <cstring>
#include <cstring>
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <set>
#include <vector>
#include <algorithm>
#include "dvm.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "array_assign_to_loop.h"
#include "../Utils/SgUtils.h"
#include "../ExpressionTransform/expr_transform.h"
#include "../GraphCall/graph_calls_func.h"
#include "../VerificationCode/verifications.h"
using std::vector;
using std::set;
using std::map;
using std::pair;
using std::tuple;
using std::make_pair;
using std::make_tuple;
using std::string;
using std::to_string;
using std::get;
static void checkAlloc(SgExpression* toCheck, SgExpression*& alloc, const string& toFind)
{
if (toCheck->lhs()->symbol()->identifier() == toFind)
alloc = toCheck->lhs()->lhs();
}
static bool fillBounds(SgSymbol* symb, vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& bounds)
{
SgStatement* decl = declaratedInStmt(symb);
int consistInAllocates = 0;
SgExpression* alloc = NULL;
for (auto& data : getAttributes<SgStatement*, SgStatement*>(decl, set<int>{ ALLOCATE_STMT }))
{
SgExpression* list = data->expr(0);
if (data->variant() != ALLOCATE_STMT)
continue;
while (list)
{
SgArrayRefExp* arrayRef = isSgArrayRefExp(list->lhs());
if (arrayRef != NULL)
{
if (string(OriginalSymbol(arrayRef->symbol())->identifier()) == string(symb->identifier()))
{
consistInAllocates++;
alloc = list->lhs()->lhs();
break;
}
}
list = list->rhs();
}
}
if (consistInAllocates > 1)
return false;
if (IS_ALLOCATABLE(symb) && consistInAllocates == 0)
return false;
bool symbFound = false;
if (consistInAllocates == 0)
{
const string toFind = string(symb->identifier());
for (SgExpression* ex = decl->expr(0); ex && (alloc == NULL); ex = ex->rhs())
{
if (ex->lhs()->variant() == ASSGN_OP)
{
if (ex->lhs()->lhs() && ex->lhs()->lhs()->symbol())
checkAlloc(ex->lhs(), alloc, toFind);
}
else if (ex->lhs() && ex->lhs()->symbol())
{
symbFound |= (ex->lhs()->symbol()->identifier() == toFind);
checkAlloc(ex, alloc, toFind);
}
}
}
if (symbFound && alloc == NULL)
{
for (SgExpression* ex = decl->expr(2); ex; ex = ex->rhs())
{
if (ex->lhs() && ex->lhs()->variant() == DIMENSION_OP)
{
alloc = ex->lhs()->lhs();
break;
}
}
}
if (alloc == NULL)
return false;
for (; alloc; alloc = alloc->rhs())
{
const int var = alloc->lhs()->variant();
if (var == DDOT)
{
if (alloc->lhs()->lhs() == NULL || alloc->lhs()->rhs() == NULL)
return false;
bounds.push_back(make_tuple(alloc->lhs()->lhs()->copyPtr(), alloc->lhs()->rhs()->copyPtr(), (SgExpression*)NULL));
}
else if (var == STAR_RANGE)
return false;
else
bounds.push_back(make_tuple(new SgValueExp(1), alloc->lhs()->copyPtr(), (SgExpression*)NULL));
}
for (auto& bound : bounds)
get<0>(bound) = CalculateInteger(get<0>(bound));
return true;
}
static bool fillSectionInfo(SgExpression* subs, tuple<SgExpression*, SgExpression*, SgExpression*>& section)
{
if (subs->lhs())
{
if (subs->lhs()->variant() == DDOT)
{
if (subs->lhs()->lhs() && subs->lhs()->lhs()->variant() == DDOT)
{
if (subs->lhs()->lhs()->lhs() != NULL) // low section
get<0>(section) = CalculateInteger(subs->lhs()->lhs()->lhs()->copyPtr());
if (subs->lhs()->lhs()->rhs() != NULL) // high section
get<1>(section) = CalculateInteger(subs->lhs()->lhs()->rhs()->copyPtr());
if (subs->lhs()->rhs() != NULL) // step of section
get<2>(section) = CalculateInteger(subs->lhs()->rhs()->copyPtr());
}
else
{
if (subs->lhs()->lhs() != NULL) // low section
get<0>(section) = CalculateInteger(subs->lhs()->lhs()->copyPtr());
if (subs->lhs()->rhs() != NULL) // high section
get<1>(section) = CalculateInteger(subs->lhs()->rhs()->copyPtr());
}
}
else
{ // low and high sections
get<0>(section) = CalculateInteger(subs->lhs()->copyPtr());
get<1>(section) = CalculateInteger(subs->lhs()->copyPtr());
}
return true;
}
else
return false;
}
static bool hasSections(SgArrayRefExp* array)
{
const int subs = array->numberOfSubscripts();
if (subs == 0)
return true;
else
{
for (int i = 0; i < subs; ++i)
if (array->subscript(i)->variant() == DDOT)
return true;
}
return false;
}
static map<SgFile*, map<SgStatement*, map<string, map<int, int>>>> cacheNameShiftAll; // by file and func -> [by base -> [old, new]]
static map<string, map<int, int>>* cacheNameShift; // by base -> [old, new]
static string createNewName(const string& base, int num)
{
int nextNum = 0;
if (cacheNameShift->count(base) && (*cacheNameShift)[base].count(num))
nextNum = (*cacheNameShift)[base][num];
else
{
nextNum = checkSymbNameAndCorrect(base, num);
(*cacheNameShift)[base][num] = nextNum;
}
string ret = base + to_string(nextNum);
return ret;
}
static void insertMainPart(SgExpression* subsL, SgFile* file, const int deep, SgExpression* shift, SgExpression* step, SgStatement* scope)
{
auto varRef = new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", deep), SgTypeInt(), scope));
bool isNull = false;
if (shift->isInteger())
if (shift->valueInteger() == 0)
isNull = true;
if (step)
{
if (step->variant() == INT_VAL)
{
//TODO: move negative step to DO bounds
/*const int stepVal = abs(step->valueInteger());
SgExpression *stepAbs = new SgValueExp(stepVal);*/
const int stepVal = step->valueInteger();
SgExpression* stepAbs = step;
if (stepVal != 1)
{
if (isNull)
subsL->setLhs(*varRef * *stepAbs);
else
subsL->setLhs(*varRef * *stepAbs + *shift);
}
else
{
if (isNull)
subsL->setLhs(*varRef);
else
subsL->setLhs(*varRef + *shift);
}
}
else
{
if (isNull)
subsL->setLhs(*varRef * *step);
else
subsL->setLhs(*varRef * *step + *shift);
}
}
else
{
if (isNull)
subsL->setLhs(*varRef);
else
subsL->setLhs(*varRef + *shift);
}
}
static bool isNonDistrArray(SgSymbol* symb, const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
SgStatement* decl = declaratedInStmt(symb);
SgType* type = symb->type();
if (type && type->variant() == T_STRING)
return false;
DIST::Array* array = getArrayFromDeclarated(decl, OriginalSymbol(symb)->identifier());
checkNull(array, convertFileName(__FILE__).c_str(), __LINE__);
set<DIST::Array*> realRefs;
getRealArrayRefs(array, array, realRefs, arrayLinksByFuncCalls);
bool fullNotDistr = true;
for (auto& real : realRefs)
fullNotDistr &= real->IsNotDistribute();
return fullNotDistr;
}
static void fillArgs(SgExpression* ref,
vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& bounds,
const vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& b)
{
for (int i = 0; ref; ref = ref->rhs(), ++i)
{
if (ref->lhs()->variant() == DDOT)
{
auto left = ref->lhs()->lhs();
auto right = ref->lhs()->rhs();
SgExpression* declLeft = (SgExpression*)get<0>(b[i]);
SgExpression* declRight = (SgExpression*)get<1>(b[i]);
if (left == NULL && right == NULL)
bounds.push_back(make_tuple(declLeft, declRight, (SgExpression*)NULL));
else if (left == NULL && right != NULL)
bounds.push_back(make_tuple(declLeft, right->copyPtr(), (SgExpression*)NULL));
else if (right == NULL && left != NULL)
bounds.push_back(make_tuple(left->copyPtr(), declRight, (SgExpression*)NULL));
else if (left->variant() == DDOT)
{
if (left->lhs() == NULL && left->rhs() == NULL)
bounds.push_back(make_tuple(declLeft, declRight, right));
else if (left->lhs() == NULL && left->rhs() != NULL)
bounds.push_back(make_tuple(declLeft, left->rhs(), right));
else if (left->rhs() == NULL && left->lhs() != NULL)
bounds.push_back(make_tuple(left->lhs(), declRight, right));
else
bounds.push_back(make_tuple(left->copyPtr(), right->copyPtr(), right));
}
else
bounds.push_back(make_tuple(left->copyPtr(), right->copyPtr(), (SgExpression*)NULL));
}
/*else if (ref->lhs()->variant() == INT_VAL)
bounds.push_back(make_tuple(ref->lhs()->copyPtr(), ref->lhs()->copyPtr(), (SgExpression*)NULL));
else if (ref->lhs()->variant() == CONST_REF)
bounds.push_back(make_tuple(ref->lhs()->copyPtr(), ref->lhs()->copyPtr(), (SgExpression*)NULL)); */
else
bounds.push_back(make_tuple(ref->lhs()->copyPtr(), ref->lhs()->copyPtr(), (SgExpression*)NULL));
}
for (auto& bound : bounds)
get<0>(bound) = CalculateInteger(get<0>(bound));
}
static SgExpression* changeNode(SgExpression* ex, const int i, SgExpression* right)
{
if (i == 0) {
SgExpression* tmp = ex->lhs()->lhs();
ex->setLhs(*tmp);
} else if (i == 1) {
SgExpression* tmp = ex->rhs()->lhs();
ex->setRhs(*tmp);
} else if (i == 2) {
SgExpression* tmp = ex->lhs()->rhs();
ex->setLhs(*tmp);
} else if (i == 4) {
ex->lhs()->setLhs(new SgValueExp(1));
ex->lhs()->setRhs(right);
} else if (i == 5) {
ex->rhs()->setLhs(new SgValueExp(1));
ex->rhs()->setRhs(right);
} else {
SgExpression* tmp = ex->rhs()->rhs();
ex->setRhs(*tmp);
}
return ex;
}
static int constsInArgs(SgExpression* ex, int i, SgExpression* right)
{
if (i == 0) {
while (ex) {
if (ex->lhs()->variant() == INT_VAL || ex->lhs()->variant() == CONST_REF) {
return 1;
}
else if (ex->lhs()->variant() == DDOT) {
if (ex->lhs()->lhs() && ex->lhs()->rhs() && string(ex->lhs()->lhs()->unparse()) == string(ex->lhs()->rhs()->unparse())) {
ex = changeNode(ex, 0, NULL);
return 1;
}
else if (ex->lhs()->lhs() && ex->lhs()->rhs() == NULL && string(right->unparse()) == string(ex->lhs()->lhs()->unparse())) {
ex = changeNode(ex, 0, NULL);
return 1;
}
else if (ex->lhs()->lhs() == NULL && ex->lhs()->rhs() != NULL && ex->lhs()->rhs()->valueInteger() == 1) {
ex = changeNode(ex, 2, NULL);
return 1;
}
else if (ex->lhs()->lhs() == NULL && ex->lhs()->rhs() == NULL) {
ex = changeNode(ex, 4, right);
if (string(ex->lhs()->lhs()->unparse()) == string(ex->lhs()->rhs()->unparse()))
return 1;
else
return 0;
}
return 0;
}
else if (ex->variant() == INT_VAL || ex->variant() == CONST_REF)
return 1;
ex = ex->rhs();
}
}
else {
if (ex->rhs()->lhs() && ex->rhs()->rhs() && ex->rhs()->lhs()->valueInteger() - ex->rhs()->rhs()->valueInteger() == 0) {
ex = changeNode(ex, 1, NULL);
return 1;
}
else if (ex->rhs()->lhs() && ex->rhs()->rhs() == NULL && string(right->unparse()) == string(ex->lhs()->lhs()->unparse())) {
ex = changeNode(ex, 1, NULL);
return 1;
}
else if (ex->rhs()->lhs() == NULL && ex->lhs()->rhs() && ex->rhs()->rhs()->valueInteger() == 1) {
ex = changeNode(ex, 3, NULL);
return 1;
}
else if (ex->rhs()->lhs() == NULL && ex->rhs()->rhs() == NULL) {
ex = changeNode(ex, 5, right);
if (string(ex->rhs()->lhs()->unparse()) == string(ex->rhs()->rhs()->unparse()))
return 1;
else
return 0;
}
return 0;
}
return 0;
}
static SgForStmt* constructDoBounds(const vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& leftSections,
const vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& rightSections,
SgStatement* copy, SgFile* file, SgStatement* scope, bool mainSymbolsAreEq = false, int* nestCount = NULL)
{
SgForStmt* retVal = NULL;
SgStatement* body = NULL;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> forBounds;
const vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& mainSection = leftSections.size() ? leftSections : rightSections;
bool onlyRight = leftSections.size() == 0 && rightSections.size() != 0;
for (int i = 0; i < mainSection.size(); ++i)
{
SgExpression* maxBound = NULL;
if (get<2>(mainSection[i]))
maxBound = &((*(get<1>(mainSection[i])) - *get<0>(mainSection[i])) / *get<2>(mainSection[i]));
else
maxBound = &(*(get<1>(mainSection[i])) - *get<0>(mainSection[i]));
//TODO: dont calculate in parallel loops
maxBound = CalculateInteger(maxBound);
if (onlyRight) // for SUM, WHERE,
forBounds.push_back(make_tuple(new SgValueExp(0), maxBound, (SgExpression*)NULL));
else
{
//TODO:
if (mainSymbolsAreEq && get<1>(leftSections[i])->isInteger() && get<1>(rightSections[i])->isInteger() &&
get<1>(leftSections[i])->valueInteger() > get<1>(rightSections[i])->valueInteger())
forBounds.push_back(make_tuple(maxBound, new SgValueExp(0), new SgValueExp(-1)));
else
forBounds.push_back(make_tuple(new SgValueExp(0), maxBound, (SgExpression*)NULL));
}
}
int loopsCount = 0;
for (int i = 0; i < forBounds.size(); ++i)
{
if (body == NULL)
body = copy;
else
body = retVal;
if (get<2>(forBounds[i])) // has step
{
SgExpression* step = get<2>(forBounds[i]);
bool inverse = false;
if (step->variant() == INT_VAL)
if (step->valueInteger() < 0)
inverse = true;
++loopsCount;
retVal = new SgForStmt(*findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope), get<0>(forBounds[i])->copy(), get<1>(forBounds[i])->copy(), get<2>(forBounds[i])->copy(), *body);
}
else
{
++loopsCount;
retVal = new SgForStmt(*findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope), get<0>(forBounds[i])->copy(), get<1>(forBounds[i])->copy(), *body);
}
}
if (nestCount)
nestCount[0] = loopsCount;
return retVal;
}
static bool hasArrayRef(SgExpression* ex)
{
bool result = false;
if (ex)
{
if (isArrayRef(ex))
result = true;
bool lR = hasArrayRef(ex->lhs());
bool rR = hasArrayRef(ex->rhs());
result = result || lR || rR;
}
return result;
}
static SgStatement* convertFromAssignExpressionToLoop(SgStatement* assign, SgFile* file, vector<Messages>& messagesForFile,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
SgStatement* result = NULL;
SgArrayRefExp* leftPart = (SgArrayRefExp*)assign->expr(0);
if (!hasSections(leftPart))
return result;
if (isNonDistrArray(assign->expr(0)->symbol(), arrayLinksByFuncCalls))
return result;
const int leftSubs = leftPart->numberOfSubscripts();
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> leftBound;
bool resL = fillBounds(OriginalSymbol(leftPart->symbol()), leftBound);
if (!resL)
{
__spf_print(1, "WARN: can not convert array assign to loop on line %d\n", assign->lineNumber());
messagesForFile.push_back(Messages(WARR, assign->lineNumber(), R94, L"can not convert array assign to loop", 2001));
return result;
}
SgForStmt* retVal = NULL;
SgStatement* copy = assign->copyPtr();
if (copy->label())
copy->deleteLabel();
SgArrayRefExp* leftArrayRef = (SgArrayRefExp*)copy->expr(0);
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> leftArgs;
fillArgs(leftArrayRef->lhs(), leftArgs, leftBound);
SgExpression* subsL = leftArrayRef->lhs();
int lIdx = 0;
bool bodyInserted = false;
SgStatement* scope = assign;
while (true)
{
if (scope->variant() == PROG_HEDR || scope->variant() == FUNC_HEDR || scope->variant() == PROC_HEDR)
break;
scope = scope->controlParent();
}
vector<bool> fixedLeft(leftBound.size());
for (int i = 0; i < leftBound.size(); ++i)
fixedLeft[i] = false;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> leftSections;
SgExpression* ex = subsL;
for (int i = 0; i < leftSubs; ++i)
{
tuple<SgExpression*, SgExpression*, SgExpression*> bounds = leftBound[i];
if (!fillSectionInfo(ex, bounds)) {
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
if (get<0>(bounds) && get<1>(bounds))
if (string(get<0>(bounds)->unparse()) == string(get<1>(bounds)->unparse())) // fixed dimension value
fixedLeft[i] = true;
if (!fixedLeft[i])
leftSections.push_back(bounds);
ex = ex->rhs();
}
//fill default
if (leftSubs == 0)
leftSections = leftBound;
__spf_print(1, "was on line %d file %s\n", assign->lineNumber(), assign->fileName());
__spf_print(1, "%s", string(assign->unparse()).c_str());
// create DO bounds
if (!leftSections.size())
leftSections = leftBound;
retVal = constructDoBounds(leftSections, { }, copy, file, scope);
if (leftSubs == 0)
{
// A = expr
for (int i = 0; i < leftSections.size(); ++i)
{
SgExpression* shiftA = get<0>(leftBound[i]);
shiftA = CalculateInteger(shiftA);
leftArrayRef->addSubscript(*new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope)) + *shiftA);
}
}
else if (leftSubs != 0 && !hasArrayRef(assign->expr(1)))
{
// A( : : : ) = expr
ex = subsL;
for (int i = 0, freeIdx = 0; i < leftSubs; ++i, subsL = subsL->rhs())
{
if (!fixedLeft[i])
{
SgExpression* shiftA = get<0>(leftSections[freeIdx]);
if (shiftA == NULL)
shiftA = get<0>(leftBound[freeIdx]);
shiftA = CalculateInteger(shiftA);
SgExpression* stepA = get<2>(leftSections[freeIdx]);
if (stepA != NULL)
stepA = CalculateInteger(stepA);
insertMainPart(subsL, file, freeIdx, shiftA, stepA, scope);
++freeIdx;
}
}
}
else
{
//A( : : : ) = B( : : : ) + C( : : :)
ex = subsL;
for (int i = 0, freeIdx = 0; i < leftSubs; ++i, subsL = subsL->rhs())
{
tuple<SgExpression*, SgExpression*, SgExpression*> leftSect = std::make_tuple((SgExpression*)NULL, (SgExpression*)NULL, (SgExpression*)NULL);
if (freeIdx < leftSections.size())
leftSect = leftSections[freeIdx];
SgExpression* rightB = get<1>(leftArgs[i]);
int flag = 0;
if (!fillSectionInfo(subsL, leftSect))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgExpression* shiftA = get<0>(leftSect);
if (shiftA == NULL)
shiftA = get<0>(leftBound[freeIdx]);
shiftA = CalculateInteger(shiftA);
SgExpression* stepA = get<2>(leftSect);
if (stepA != NULL)
stepA = CalculateInteger(stepA);
if (subsL->rhs() && subsL->rhs()->variant() != DDOT)
flag = constsInArgs(subsL, 0, rightB);
else if (subsL->rhs() && subsL->rhs()->variant() == DDOT)
flag = constsInArgs(subsL, 1, rightB);
if (flag != 1)
{
insertMainPart(subsL, file, freeIdx, shiftA, stepA, scope);
++freeIdx;
}
}
}
__spf_print(1, "%s", string(retVal->unparse()).c_str());
result = retVal;
return result;
}
static vector<SgExpression*> fillSteps(SgExpression* subsL, int leftSubs,
vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& leftArgs,
const vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& leftSections,
const vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& leftBound)
{
vector<SgExpression*> steps;
for (int i = 0, freeIdx = 0, j = 0; i < leftSubs; ++i, subsL = subsL->rhs())
{
if (!fillSectionInfo(subsL, leftArgs[i]))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgExpression* tmp1 = NULL;
if (freeIdx < leftSections.size())
tmp1 = get<0>(leftSections[freeIdx]);
SgExpression* rightB = get<1>(leftArgs[i]);
if (tmp1 && string(get<0>(leftArgs[i])->unparse()) == string(tmp1->unparse()) && subsL->lhs()->variant() != INT_VAL)
{
SgExpression* shiftA = get<0>(leftSections[freeIdx]);
if (shiftA == NULL)
shiftA = get<0>(leftBound[freeIdx]);
shiftA = CalculateInteger(shiftA);
SgExpression* stepA = get<2>(leftSections[freeIdx]);
if (stepA != NULL)
stepA = CalculateInteger(stepA);
steps.push_back(stepA);
++freeIdx;
j++;
}
}
return steps;
}
static vector<bool> insertPartOfAssign(SgFile* file, SgStatement* scope, SgExpression* subsL, int leftSubs,
const vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& leftArgs,
const vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& leftSections,
const vector<tuple<SgExpression*, SgExpression*, SgExpression*>>& leftBound,
const vector<SgExpression*>& stepsR, const bool symbsAreEq,
const bool isRight, const vector<bool>& changeLoopSignLeft)
{
vector<bool> changeLoopSign;
for (int i = 0, freeIdx = 0, j = 0; i < leftSubs; ++i, subsL = subsL->rhs())
{
SgExpression* tmp1 = NULL;
if (freeIdx < leftSections.size())
tmp1 = get<0>(leftSections[freeIdx]);
SgExpression* rightB = get<1>(leftArgs[i]);
if (tmp1 && string(get<0>(leftArgs[i])->unparse()) == string(tmp1->unparse()) && subsL->lhs()->variant() != INT_VAL)
{
SgExpression* stepA = get<2>(leftSections[freeIdx]);
if (stepA != NULL)
stepA = CalculateInteger(stepA);
bool needToChange = false;
bool singChanged = false;
if (!symbsAreEq)
{
bool stepEq = false;
if (stepA && stepsR[j])
{
string sA = stepA->unparse();
string sR = stepsR[j]->unparse();
if (sA == sR)
{
stepEq = true;
if (stepA->isInteger() && stepA->valueInteger() < 0 && abs(stepA->valueInteger()) == 1)
{
stepA = new SgValueExp(stepA->valueInteger() * -1);
needToChange = true;
}
}
}
if (!stepEq)
{
if (isRight)
{
if (stepA == NULL)
{
if (changeLoopSignLeft.size() && changeLoopSignLeft[j])
stepA = new SgValueExp(-1);
}
else if (stepA)
{
if (changeLoopSignLeft.size() && changeLoopSignLeft[j])
{
singChanged = true;
stepA = new SgValueExp(stepA->valueInteger() * -1);
}
}
}
else
{
if (stepA && stepA->isInteger() && stepA->valueInteger() < 0 && abs(stepA->valueInteger()) == 1)
{
stepA = new SgValueExp(stepA->valueInteger() * -1);
needToChange = true;
}
}
}
}
changeLoopSign.push_back(needToChange);
if (isRight && changeLoopSignLeft.size() && changeLoopSignLeft[j])
needToChange = true;
SgExpression* shiftA = needToChange ? get<1>(leftSections[freeIdx]) : get<0>(leftSections[freeIdx]);
if (shiftA == NULL)
shiftA = needToChange ? get<1>(leftBound[freeIdx]) : get<0>(leftBound[freeIdx]);
if (isRight && needToChange && singChanged)
{
SgExpression* a = get<0>(leftSections[freeIdx]);
SgExpression* b = get<1>(leftSections[freeIdx]);
SgExpression* c = get<2>(leftSections[freeIdx]);
checkNull(a, convertFileName(__FILE__).c_str(), __LINE__);
checkNull(b, convertFileName(__FILE__).c_str(), __LINE__);
checkNull(c, convertFileName(__FILE__).c_str(), __LINE__);
SgExpression* ex = &(*a + ((*b - *a + *c) / *c - *new SgValueExp(1)) * *c - *get<1>(leftSections[freeIdx]));
shiftA = &(*shiftA + *ex);
}
shiftA = CalculateInteger(shiftA);
insertMainPart(subsL, file, j, shiftA, stepA, scope);
++freeIdx;
j++;
}
else
{
if (subsL->rhs() && subsL->rhs()->variant() != DDOT)
constsInArgs(subsL, 0, rightB);
else if (subsL->rhs() && subsL->rhs()->variant() == DDOT)
constsInArgs(subsL, 1, rightB);
}
}
return changeLoopSign;
}
static void swapLoopBounds(SgForStmt* loop, const vector<bool>& changeLoopSign)
{
for (int z = 0; z < changeLoopSign.size(); ++z)
{
checkNull(loop, convertFileName(__FILE__).c_str(), __LINE__);
if (changeLoopSign[z])
{
if (loop->step() == NULL)
loop->setStep(*new SgValueExp(-1));
else
{
auto step = loop->step();
if (!step->isInteger())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
loop->setStep(*new SgValueExp(-1 * step->valueInteger()));
}
loop->swapStartEnd();
}
loop = isSgForStmt(loop->lexNext());
}
}
static void doReplace(SgExpression* prev, SgExpression* ex, bool isLeft, const string& s, SgExpression* with)
{
if (ex)
{
if (ex->variant() == VAR_REF && ex->symbol() && ex->symbol()->identifier() == s)
{
if (prev == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (isLeft)
prev->setLhs(with->copyPtr());
else
prev->setRhs(with->copyPtr());
}
doReplace(ex, ex->lhs(), true, s, with);
doReplace(ex, ex->rhs(), false, s, with);
}
}
static SgStatement* removeOneCycleLoops(SgForStmt* retVal, const int nestCount)
{
vector<bool> needToDel(nestCount, false);
vector<pair<string, SgExpression*>> replace(nestCount);
SgForStmt* loop = retVal;
SgStatement* last = NULL;
for (int z = 0; z < nestCount; ++z, loop = (SgForStmt*) loop->lexNext(), last = loop)
{
string start = loop->start()->unparse();
string end = loop->end()->unparse();
if (start == end)
{
needToDel[z] = true;
replace[z] = make_pair(loop->doName()->identifier(), loop->start()->copyPtr());
}
}
checkNull(last, convertFileName(__FILE__).c_str(), __LINE__);
for (int z = 0; z < nestCount; ++z)
if (needToDel[z])
for (int p = 0; p < 3; ++p)
doReplace(NULL, last->expr(p), true, replace[z].first, replace[z].second);
return retVal;
}
static SgStatement* convertFromAssignToLoop(SgStatement* assign, SgFile* file, vector<Messages> &messagesForFile,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
SgStatement* result = NULL;
if (assign->variant() != ASSIGN_STAT)
return result;
if (assign->expr(0) == NULL || assign->expr(1) == NULL)
return result;
if (assign->expr(1)->variant() == CONSTRUCTOR_REF)
{
__spf_print(1, "WARN: can not convert array assign to loop on line %d\n", assign->lineNumber());
messagesForFile.push_back(Messages(WARR, assign->lineNumber(), R94, L"can not convert array assign to loop", 2001));
return result;
}
if (isArrayRef(assign->expr(0)) && !isArrayRef(assign->expr(1)))
{
result = convertFromAssignExpressionToLoop(assign, file, messagesForFile, arrayLinksByFuncCalls);
return result;
}
if (!isArrayRef(assign->expr(0)) || !isArrayRef(assign->expr(1)))
return result;
bool fullPrivate = true;
if (isArrayRef(assign->expr(0)) && !isNonDistrArray(assign->expr(0)->symbol(), arrayLinksByFuncCalls))
fullPrivate = false;
if (isArrayRef(assign->expr(1)) && !isNonDistrArray(assign->expr(1)->symbol(), arrayLinksByFuncCalls))
fullPrivate = false;
if (fullPrivate)
return result;
SgArrayRefExp* leftPart = (SgArrayRefExp*)assign->expr(0);
SgArrayRefExp* rightPart = (SgArrayRefExp*)assign->expr(1);
if (!hasSections(leftPart) || !hasSections(rightPart))
return result;
const int leftSubs = leftPart->numberOfSubscripts();
const int rightSubs = rightPart->numberOfSubscripts();
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> leftBound;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> rightBound;
bool resL = fillBounds(OriginalSymbol(leftPart->symbol()), leftBound);
bool resR = fillBounds(OriginalSymbol(rightPart->symbol()), rightBound);
if (!resL || !resR)
{
__spf_print(1, "WARN: can not convert array assign to loop on line %d\n", assign->lineNumber());
messagesForFile.push_back(Messages(WARR, assign->lineNumber(), R94, L"can not convert array assign to loop", 2001));
return result;
}
SgForStmt* retVal = NULL;
SgStatement* retValSt = NULL;
SgStatement* copy = assign->copyPtr();
if (copy->label())
copy->deleteLabel();
SgArrayRefExp* leftArrayRef = (SgArrayRefExp*)copy->expr(0);
SgArrayRefExp* rightArrayRef = (SgArrayRefExp*)copy->expr(1);
SgExpression* subsL = leftArrayRef->lhs();
SgExpression* subsR = rightArrayRef->lhs();
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> leftArgs;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> rightArgs;
fillArgs(subsL, leftArgs, leftBound);
fillArgs(subsR, rightArgs, rightBound);
int lIdx = 0;
int rIdx = 0;
bool bodyInserted = false;
SgStatement* scope = assign;
while (true)
{
if (scope->variant() == PROG_HEDR || scope->variant() == FUNC_HEDR || scope->variant() == PROC_HEDR)
break;
scope = scope->controlParent();
}
vector<bool> fixedLeft(leftBound.size()), fixedRight(rightBound.size());
for (int i = 0; i < fixedLeft.size(); ++i)
fixedLeft[i] = false;
for (int i = 0; i < fixedRight.size(); ++i)
fixedRight[i] = false;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> leftSections, rightSections;
SgExpression* ex = subsL;
for (int i = 0; i < leftSubs; ++i)
{
tuple<SgExpression*, SgExpression*, SgExpression*> bounds = leftArgs[i];
if (!fillSectionInfo(ex, bounds))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
// fixed dimension value
if (get<0>(bounds) && get<1>(bounds))
if ((string(get<0>(bounds)->unparse()) == get<1>(bounds)->unparse()) && ex->lhs()->variant() != DDOT)
fixedLeft[i] = true;
if (!fixedLeft[i])
leftSections.push_back(bounds);
ex = ex->rhs();
}
//fill default
if (leftSubs == 0)
leftSections = leftBound;
ex = subsR;
for (int i = 0; i < rightSubs; ++i)
{
tuple<SgExpression*, SgExpression*, SgExpression*> bounds = rightArgs[i];
if (!fillSectionInfo(ex, bounds))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
// fixed dimension value
if (get<0>(bounds) && get<1>(bounds))
if (string(get<0>(bounds)->unparse()) == get<1>(bounds)->unparse() && ex->lhs()->variant() != DDOT)
fixedRight[i] = true;
if (!fixedRight[i])
rightSections.push_back(bounds);
ex = ex->rhs();
}
//fill default
if (rightSubs == 0)
rightSections = rightBound;
if (leftSections.size() != rightSections.size())
{
__spf_print(1, "WARN: can not convert array assign to loop on line %d\n", assign->lineNumber());
messagesForFile.push_back(Messages(WARR, assign->lineNumber(), R94, L"can not convert array assign to loop", 2001));
}
else
{
__spf_print(1, "was on line %d file %s\n", assign->lineNumber(), assign->fileName());
__spf_print(1, "%s", string(assign->unparse()).c_str());
bool symbsAreEq = false;
if (leftPart->symbol() && rightPart->symbol())
symbsAreEq = strcmp(OriginalSymbol(leftPart->symbol())->identifier(), OriginalSymbol(rightPart->symbol())->identifier()) == 0;
int nestCount = 0;
retValSt = retVal = constructDoBounds(leftSections, rightSections, copy, file, scope, symbsAreEq, &nestCount);
if (leftSubs == 0 && rightSubs == 0)
{
// A = B
for (int i = 0; i < leftSections.size(); ++i)
{
SgExpression* shiftA = get<0>(leftBound[i]);
shiftA = CalculateInteger(shiftA);
leftArrayRef->addSubscript(*new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope)) + *shiftA);
}
for (int i = 0; i < rightSections.size(); ++i)
{
SgExpression* shiftB = get<0>(rightBound[i]);
shiftB = CalculateInteger(shiftB);
rightArrayRef->addSubscript(*new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope)) + *shiftB);
}
}
else if (leftSubs == 0 && rightSubs != 0)
{
// A = B( : : : )
for (int i = 0; i < leftSections.size(); ++i)
{
SgExpression* shiftA = get<0>(leftBound[i]);
shiftA = CalculateInteger(shiftA);
leftArrayRef->addSubscript(*new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope)) + *shiftA);
}
ex = subsR;
int flag;
for (int i = 0, freeIdx = 0; i < rightSubs; ++i, subsR = subsR->rhs())
{
flag = 0;
if (!fixedRight[i])
{
SgExpression* shiftB = get<0>(rightSections[freeIdx]);
SgExpression* rightB = get<1>(rightArgs[freeIdx]);
if (rightB == NULL)
rightB = get<1>(rightBound[freeIdx]);
if (shiftB == NULL)
shiftB = get<0>(rightBound[freeIdx]);
shiftB = CalculateInteger(shiftB);
SgExpression* stepB = get<2>(rightSections[freeIdx]);
if (stepB != NULL)
stepB = CalculateInteger(stepB);
if (subsR->rhs() && subsR->rhs()->variant() != DDOT)
flag = constsInArgs(subsR, 0, rightB);
else if (subsR->rhs() && subsR->rhs()->variant() == DDOT)
flag = constsInArgs(subsR, 1, rightB);
else
flag = constsInArgs(subsR, 0, rightB);
if (flag != 1)
insertMainPart(subsR, file, freeIdx, shiftB, stepB, scope);
++freeIdx;
}
}
}
else if (leftSubs != 0 && rightSubs == 0)
{
// A( : : : ) = B
ex = subsL;
vector<bool> changeLoopSign;
for (int i = 0, freeIdx = 0; i < leftSubs; ++i, subsL = subsL->rhs())
{
if (!fixedLeft[i])
{
SgExpression* stepA = get<2>(leftSections[freeIdx]);
if (stepA != NULL)
stepA = CalculateInteger(stepA);
bool needToChange = false;
if (!symbsAreEq && stepA)
if (stepA->isInteger() && stepA->valueInteger() < 0 && abs(stepA->valueInteger()) == 1)
{
stepA = new SgValueExp(stepA->valueInteger() * -1);
needToChange = true;
}
changeLoopSign.push_back(needToChange);
SgExpression* shiftA = needToChange ? get<1>(leftSections[freeIdx]) : get<0>(leftSections[freeIdx]);
if (shiftA == NULL)
shiftA = needToChange ? get<1>(leftBound[freeIdx]) : get<0>(leftBound[freeIdx]);
shiftA = CalculateInteger(shiftA);
insertMainPart(subsL, file, freeIdx, shiftA, stepA, scope);
++freeIdx;
}
}
if (changeLoopSign.size() != rightSections.size())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (int i = 0; i < rightSections.size(); ++i)
{
bool invert = changeLoopSign[i];
SgExpression* shiftB = invert ? get<1>(rightBound[i]) : get<0>(rightBound[i]);
shiftB = CalculateInteger(shiftB);
if (invert)
rightArrayRef->addSubscript(*new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope)) * *new SgValueExp(-1) + *shiftB);
else
rightArrayRef->addSubscript(*new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope)) + *shiftB);
}
std::reverse(changeLoopSign.begin(), changeLoopSign.end());
swapLoopBounds(retVal, changeLoopSign);
}
else
{
//A( : : : ) = B( : : : )
auto stepsA = fillSteps(subsL, leftSubs, leftArgs, leftSections, leftBound);
auto stepsB = fillSteps(subsR, rightSubs, rightArgs, rightSections, rightBound);
if (stepsA.size() != stepsB.size())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto changeLoopSign = insertPartOfAssign(file, scope, subsL, leftSubs, leftArgs, leftSections, leftBound, stepsB, symbsAreEq, false, vector<bool>());
changeLoopSign = insertPartOfAssign(file, scope, subsR, rightSubs, rightArgs, rightSections, rightBound, stepsA, symbsAreEq, true, changeLoopSign);
if (changeLoopSign.size() != nestCount)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
std::reverse(changeLoopSign.begin(), changeLoopSign.end());
swapLoopBounds(retVal, changeLoopSign);
//bad solution
//retValSt = removeOneCycleLoops(retVal, nestCount);
}
__spf_print(1, "%s", string(retValSt->unparse()).c_str());
}
result = retValSt;
return result;
}
static SgStatement* convertFromStmtToLoop(SgStatement* assign, SgFile* file, vector<Messages>& messagesForFile,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
SgStatement* result = NULL;
if (assign->variant() != ASSIGN_STAT)
return result;
if (assign->expr(0) == NULL || assign->expr(1) == NULL)
return result;
if (assign->expr(1)->lhs() == NULL || assign->expr(1)->rhs() == NULL)
return result;
if (!isArrayRef(assign->expr(0)) ||
!isArrayRef(assign->expr(1)->rhs()) ||
!isArrayRef(assign->expr(1)->lhs()))
return result;
if (isNonDistrArray(assign->expr(0)->symbol(), arrayLinksByFuncCalls) &&
isNonDistrArray(assign->expr(1)->rhs()->symbol(), arrayLinksByFuncCalls) &&
isNonDistrArray(assign->expr(1)->lhs()->symbol(), arrayLinksByFuncCalls))
return result;
SgArrayRefExp* leftPart = (SgArrayRefExp*)assign->expr(1)->lhs();
SgArrayRefExp* rightPart = (SgArrayRefExp*)assign->expr(1)->rhs();
SgArrayRefExp* assignPart = (SgArrayRefExp*)assign->expr(0);
if (!hasSections(leftPart) || !hasSections(rightPart) || !hasSections(assignPart))
return result;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> leftBound;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> rightBound;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> assignBound;
bool resL = fillBounds(OriginalSymbol(leftPart->symbol()), leftBound);
bool resR = fillBounds(OriginalSymbol(rightPart->symbol()), rightBound);
bool resA = fillBounds(OriginalSymbol(assignPart->symbol()), assignBound);
if (!resL || !resR || !resA)
return result;
SgForStmt* retVal = NULL;
SgStatement* copy = assign->copyPtr();
if (copy->label())
copy->deleteLabel();
SgArrayRefExp* leftArrayRef = (SgArrayRefExp*)copy->expr(1)->lhs();
SgArrayRefExp* rightArrayRef = (SgArrayRefExp*)copy->expr(1)->rhs();
SgArrayRefExp* assignArrayRef = (SgArrayRefExp*)copy->expr(0);
SgExpression* subsL = leftArrayRef->lhs();
SgExpression* subsR = rightArrayRef->lhs();
SgExpression* subsA = assignArrayRef->lhs();
int lIdx = 0;
int rIdx = 0;
int aIdx = 0;
bool bodyInserted = false;
SgStatement* scope = assign;
const int leftSubs = leftPart->numberOfSubscripts();
const int rightSubs = rightPart->numberOfSubscripts();
const int assignSubs = assignPart->numberOfSubscripts();
while (true)
{
if (scope->variant() == PROG_HEDR || scope->variant() == FUNC_HEDR || scope->variant() == PROC_HEDR)
break;
scope = scope->controlParent();
}
vector<bool> fixedLeft(leftBound.size()), fixedRight(rightBound.size()), fixedAssign(assignBound.size());
for (int i = 0; i < leftBound.size(); ++i)
fixedLeft[i] = false;
for (int i = 0; i < fixedRight.size(); ++i)
fixedRight[i] = false;
for (int i = 0; i < fixedAssign.size(); ++i)
fixedAssign[i] = false;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> leftSections, rightSections, assignSections;
SgExpression* ex = subsL;
for (int i = 0; i < leftSubs; ++i)
{
tuple<SgExpression*, SgExpression*, SgExpression*> bounds = leftBound[lIdx];
if (!fillSectionInfo(ex, bounds))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (get<0>(bounds) && get<1>(bounds))
if (string(get<0>(bounds)->unparse()) == string(get<1>(bounds)->unparse())) // fixed dimension value
fixedLeft[i] = true;
if (!fixedLeft[i])
leftSections.push_back(bounds);
ex = ex->rhs();
}
//fill default
if (leftSubs == 0)
leftSections = leftBound;
ex = subsR;
for (int i = 0; i < rightSubs; ++i)
{
tuple<SgExpression*, SgExpression*, SgExpression*> bounds = rightBound[rIdx];
if (!fillSectionInfo(ex, bounds))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (get<0>(bounds) && get<1>(bounds))
if (string(get<0>(bounds)->unparse()) == string(get<1>(bounds)->unparse())) // fixed dimension value
fixedRight[i] = true;
if (!fixedRight[i])
rightSections.push_back(bounds);
ex = ex->rhs();
}
//fill default
if (rightSubs == 0)
rightSections = rightBound;
ex = subsA;
for (int i = 0; i < assignSubs; ++i)
{
tuple<SgExpression*, SgExpression*, SgExpression*> bounds = assignBound[aIdx];
if (!fillSectionInfo(ex, bounds))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (get<0>(bounds) && get<1>(bounds))
if (string(get<0>(bounds)->unparse()) == string(get<1>(bounds)->unparse())) // fixed dimension value
fixedAssign[i] = true;
if (!fixedAssign[i])
assignSections.push_back(bounds);
ex = ex->rhs();
}
//fill default
if (assignSubs == 0)
assignSections = assignBound;
if (leftSections.size() != rightSections.size() ||
leftSections.size() != assignSections.size() ||
rightSections.size() != assignSections.size())
{
__spf_print(1, "WARN: can not convert array assign to loop on line %d\n", assign->lineNumber());
messagesForFile.push_back(Messages(WARR, assign->lineNumber(), R95, L"can not convert array assign to loop", 2001));
}
else
{
__spf_print(1, "was on line %d file %s\n", assign->lineNumber(), assign->fileName());
__spf_print(1, "%s", string(assign->unparse()).c_str());
if (!leftSections.size())
leftSections = leftBound;
if (!rightSections.size())
rightSections = rightBound;
if (!assignSections.size())
assignSections = assignBound;
bool symbsAreEq = false;
if (leftPart->symbol() && rightPart->symbol())
symbsAreEq = strcmp(OriginalSymbol(leftPart->symbol())->identifier(), OriginalSymbol(rightPart->symbol())->identifier()) == 0;
retVal = constructDoBounds(leftSections, rightSections, copy, file, scope, symbsAreEq);
if (leftSubs == 0)
{
for (int i = 0; i < leftSections.size(); ++i)
{
SgExpression* shiftA = get<0>(leftBound[i]);
shiftA = CalculateInteger(shiftA);
leftArrayRef->addSubscript(*new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope)) + *shiftA);
}
}
else
{
ex = subsL;
for (int i = 0, freeIdx = 0; i < leftSubs; ++i, subsL = subsL->rhs())
{
if (!fixedLeft[i])
{
SgExpression* shiftA = get<0>(leftSections[freeIdx]);
if (shiftA == NULL)
shiftA = get<0>(leftBound[freeIdx]);
shiftA = CalculateInteger(shiftA);
SgExpression* stepA = get<2>(leftSections[freeIdx]);
if (stepA != NULL)
stepA = CalculateInteger(stepA);
insertMainPart(subsL, file, freeIdx, shiftA, stepA, scope);
++freeIdx;
}
}
}
if (rightSubs == 0)
{
for (int i = 0; i < rightSections.size(); ++i)
{
SgExpression* shiftB = get<0>(rightBound[i]);
shiftB = CalculateInteger(shiftB);
rightArrayRef->addSubscript(*new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope)) + *shiftB);
}
}
else
{
ex = subsR;
for (int i = 0, freeIdx = 0; i < rightSubs; ++i, subsR = subsR->rhs())
{
if (!fixedRight[i])
{
SgExpression* shiftB = get<0>(rightSections[freeIdx]);
if (shiftB == NULL)
shiftB = get<0>(rightBound[freeIdx]);
shiftB = CalculateInteger(shiftB);
SgExpression* stepB = get<2>(rightSections[freeIdx]);
if (stepB != NULL)
stepB = CalculateInteger(stepB);
insertMainPart(subsR, file, freeIdx, shiftB, stepB, scope);
++freeIdx;
}
}
}
if (assignSubs == 0)
{
for (int i = 0; i < assignSections.size(); ++i)
{
SgExpression* shiftC = get<0>(assignBound[i]);
shiftC = CalculateInteger(shiftC);
assignArrayRef->addSubscript(*new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope)) + *shiftC);
}
}
else
{
ex = subsA;
for (int i = 0, freeIdx = 0; i < assignSubs; ++i, subsA = subsA->rhs())
{
if (!fixedAssign[i])
{
SgExpression* shiftC = get<0>(assignSections[freeIdx]);
if (shiftC == NULL)
shiftC = get<0>(assignBound[freeIdx]);
shiftC = CalculateInteger(shiftC);
SgExpression* stepC = get<2>(assignSections[freeIdx]);
if (stepC != NULL)
stepC = CalculateInteger(stepC);
insertMainPart(subsA, file, freeIdx, shiftC, stepC, scope);
++freeIdx;
}
}
}
}
__spf_print(1, "%s", string(retVal->unparse()).c_str());
result = retVal;
return result;
}
static SgStatement* convertFromSumToLoop(SgStatement * assign, SgFile * file, vector<Messages> &messagesForFile,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
SgStatement* result = NULL;
if (assign->expr(0) == NULL || assign->expr(1) == NULL)
return result;
if (assign->expr(1)->lhs() == NULL || assign->expr(1)->lhs()->lhs() == NULL ||
isArrayRef(assign->expr(1)->lhs()->lhs()))
return result;
if (isNonDistrArray(assign->expr(1)->lhs()->lhs()->symbol(), arrayLinksByFuncCalls))
return result;
SgForStmt* retVal = NULL;
SgStatement* copy = assign->copyPtr();
if (copy->label())
copy->deleteLabel();
copy->setExpression(1, assign->expr(1)->lhs()->lhs()->copy());
SgExpression* leftPart = assign->expr(0);
SgArrayRefExp* rightPart = (SgArrayRefExp*)assign->expr(1)->lhs()->lhs();
const int Subs = rightPart->numberOfSubscripts();
if (!hasSections(rightPart))
return result;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> rightBound;
bool resR = fillBounds(OriginalSymbol(rightPart->symbol()), rightBound);
if (!resR)
return result;
SgArrayRefExp* rightArrayRef = (SgArrayRefExp*)copy->expr(1);
SgExpression* subsR = rightArrayRef->lhs();
int rIdx = 0;
bool bodyInserted = false;
SgStatement* scope = assign;
const int rightSubs = rightPart->numberOfSubscripts();
while (true)
{
if (scope->variant() == PROG_HEDR || scope->variant() == FUNC_HEDR || scope->variant() == PROC_HEDR)
break;
scope = scope->controlParent();
}
vector<bool> fixedRight(rightBound.size());
for (int i = 0; i < fixedRight.size(); ++i)
fixedRight[i] = false;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> rightSections;
SgExpression* ex = subsR;
for (int i = 0; i < rightSubs; ++i)
{
tuple<SgExpression*, SgExpression*, SgExpression*> bounds = rightBound[rIdx];
if (!fillSectionInfo(ex, bounds))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (get<0>(bounds) && get<1>(bounds))
if (string(get<0>(bounds)->unparse()) == string(get<1>(bounds)->unparse())) // fixed dimension value
fixedRight[i] = true;
if (!fixedRight[i])
rightSections.push_back(bounds);
ex = ex->rhs();
}
//fill default
if (rightSubs == 0)
rightSections = rightBound;
__spf_print(1, "was on line %d file %s\n", assign->lineNumber(), assign->fileName());
__spf_print(1, "%s", string(assign->unparse()).c_str());
if (!rightSections.size())
rightSections = rightBound;
retVal = constructDoBounds({ }, rightSections, copy, file, scope);
if (rightSubs == 0)
{
for (int i = 0; i < rightSections.size(); ++i)
{
SgExpression* shiftB = get<0>(rightBound[i]);
shiftB = CalculateInteger(shiftB);
rightArrayRef->addSubscript(*new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope)) + *shiftB);
}
}
else
{
ex = subsR;
for (int i = 0, freeIdx = 0; i < rightSubs; ++i, subsR = subsR->rhs())
{
if (!fixedRight[i])
{
SgExpression* shiftB = get<0>(rightSections[freeIdx]);
if (shiftB == NULL)
shiftB = get<0>(rightBound[freeIdx]);
shiftB = CalculateInteger(shiftB);
SgExpression* stepB = get<2>(rightSections[freeIdx]);
if (stepB != NULL)
stepB = CalculateInteger(stepB);
insertMainPart(subsR, file, freeIdx, shiftB, stepB, scope);
++freeIdx;
}
}
}
SgAssignStmt* init = new SgAssignStmt(*(assign->expr(0)), *(new SgValueExp(0))); // sum = 0
SgExpression* newRightPart = new SgExpression(ADD_OP);
newRightPart->setLhs(copy->expr(0)->copyPtr());
newRightPart->setRhs(copy->expr(1));
copy->setExpression(1, *newRightPart);
result = new SgIfStmt(*new SgValueExp(true));
result->insertStmtAfter(*retVal, *result);
result->insertStmtAfter(*init, *result);
__spf_print(1, "%s\n", " ----------- ");
__spf_print(1, "%s", string(result->unparse()).c_str());
// add SPF ANALYSIS REDUCTION(SUM(<var>)) after convertion
SgStatement* redDir = new SgStatement(SPF_ANALYSIS_DIR);
SgExpression* list = new SgExpression(EXPR_LIST,
new SgExpression(REDUCTION_OP,
new SgExpression(EXPR_LIST,
new SgExpression(ARRAY_OP, new SgKeywordValExp("sum"), new SgVarRefExp(init->expr(0)->symbol())))));
redDir->setExpression(0, list);
retVal->addAttribute(SPF_ANALYSIS_DIR, redDir, sizeof(SgStatement));
return result;
}
static SgStatement* convertFromWhereToLoop(SgStatement * assign, SgFile * file, vector<Messages> &messagesForFile)
{
SgStatement* result = NULL;
if (assign->expr(0) == NULL || assign->expr(1) == NULL)
return result;
if (assign->expr(0)->lhs() == NULL ||
isArrayRef(assign->expr(0)->lhs()) ||
isArrayRef(assign->expr(1)))
return result;
/*
if (!strcmp(assign->expr(0)->lhs()->symbol()->identifier(),
assign->expr(1)->symbol()->identifier()))
return result;
*/
__spf_print(1, "%s\n", " ----------- ");
SgForStmt* retVal = NULL;
SgStatement* copy = assign->copyPtr();
if (copy->label())
copy->deleteLabel();
SgExpression* leftPart = assign->expr(0);
SgArrayRefExp* rightPart = (SgArrayRefExp*)assign->expr(1);
const int Subs = rightPart->numberOfSubscripts();
if (!hasSections(rightPart))
return result;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> rightBound;
bool resR = fillBounds(OriginalSymbol(rightPart->symbol()), rightBound);
if (!resR)
return result;
SgArrayRefExp* rightArrayRef = (SgArrayRefExp*)copy->expr(1);
SgExpression* subsR = rightArrayRef->lhs();
int rIdx = 0;
bool bodyInserted = false;
SgStatement* scope = assign;
const int rightSubs = rightPart->numberOfSubscripts();
while (true)
{
if (scope->variant() == PROG_HEDR || scope->variant() == FUNC_HEDR || scope->variant() == PROC_HEDR)
break;
scope = scope->controlParent();
}
vector<bool> fixedRight(rightBound.size());
for (int i = 0; i < fixedRight.size(); ++i)
fixedRight[i] = false;
vector<tuple<SgExpression*, SgExpression*, SgExpression*>> rightSections;
SgExpression* ex = subsR;
for (int i = 0; i < rightSubs; ++i)
{
tuple<SgExpression*, SgExpression*, SgExpression*> bounds = rightBound[rIdx];
if (!fillSectionInfo(ex, bounds))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (get<0>(bounds) && get<1>(bounds))
if (string(get<0>(bounds)->unparse()) == string(get<1>(bounds)->unparse())) // fixed dimension value
fixedRight[i] = true;
if (!fixedRight[i])
rightSections.push_back(bounds);
ex = ex->rhs();
}
//fill default
if (rightSubs == 0)
rightSections = rightBound;
__spf_print(1, "was on line %d file %s\n", assign->lineNumber(), assign->fileName());
__spf_print(1, "%s", string(assign->unparse()).c_str());
if (!rightSections.size())
rightSections = rightBound;
retVal = constructDoBounds({ }, rightSections, copy, file, scope);
if (rightSubs == 0)
{
for (int i = 0; i < rightSections.size(); ++i)
{
SgExpression* shiftB = get<0>(rightBound[i]);
shiftB = CalculateInteger(shiftB);
rightArrayRef->addSubscript(*new SgVarRefExp(findSymbolOrCreate(file, createNewName("i_", i), SgTypeInt(), scope)) + *shiftB);
}
}
else
{
ex = subsR;
for (int i = 0, freeIdx = 0; i < rightSubs; ++i, subsR = subsR->rhs())
{
if (!fixedRight[i])
{
SgExpression* shiftB = get<0>(rightSections[freeIdx]);
if (shiftB == NULL)
shiftB = get<0>(rightBound[freeIdx]);
shiftB = CalculateInteger(shiftB);
SgExpression* stepB = get<2>(rightSections[freeIdx]);
if (stepB != NULL)
stepB = CalculateInteger(stepB);
insertMainPart(subsR, file, freeIdx, shiftB, stepB, scope);
++freeIdx;
}
}
}
SgIfStmt* ret = (SgIfStmt*) new SgStatement(EXPR_IF);
ret->setExpression(0, *retVal->lexNext()->expr(0));
ret->expr(0)->setLhs(retVal->lexNext()->expr(1));
ret->setExpression(1, *retVal->lexNext()->expr(1));
ret->setExpression(2, *retVal->lexNext()->expr(2));
retVal->setLexNext(*ret);
__spf_print(1, "%s\n", " ----------- ");
__spf_print(1, "%s", string(retVal->unparse()).c_str());
result = retVal;
return result;
}
bool notDeletedVectorAssign(SgStatement* st)
{
if (!st)
return false;
SgExpression* rPart = st->expr(1);
if (!rPart)
return false;
const int var = rPart->variant();
return (var == ADD_OP || var == MULT_OP || var == DIV_OP || var == INT_VAL || var == FLOAT_VAL || var == DOUBLE_VAL ||
var == BOOL_VAL || var == CHAR_VAL || var == STRING_VAL || var == COMPLEX_VAL || var == SUBT_OP || var == MINUS_OP ||
var == FUNC_CALL && !strcmp(rPart->symbol()->identifier(), "sum") ||
isArrayRef(rPart) || var == VAR_REF || var == CONST_REF);
}
static SgStatement* runConversion(SgStatement* st, SgFile* file, vector<Messages>& messagesForFile,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
int oldVar = st->variant();
st->setVariant(abs(st->variant()));
SgStatement* conv = NULL;
if (st->expr(1)->variant() == FUNC_CALL)
{
const string fName = st->expr(1)->symbol()->identifier();
if (fName == "sum")
conv = convertFromSumToLoop(st, file, messagesForFile, arrayLinksByFuncCalls);
}
else
{
if ((st->expr(1)->variant() == ADD_OP || st->expr(1)->variant() == MULT_OP || st->expr(1)->variant() == SUBT_OP))
conv = convertFromStmtToLoop(st, file, messagesForFile, arrayLinksByFuncCalls);
else
{
if (st->variant() == WHERE_NODE)
conv = convertFromWhereToLoop(st, file, messagesForFile);
else
conv = convertFromAssignToLoop(st, file, messagesForFile, arrayLinksByFuncCalls);
}
}
//move label if converted
if (conv)
moveLabelBefore(st);
st->setVariant(oldVar);
return conv;
}
// functionality: convert A[(...)] = B[(...)] to loop
// move (create copy) init assigns in DECL before the first executable
// move SPF ANALYSIS PARAMETER to assigns
void convertFromAssignToLoop(SgFile *file, const vector<ParallelRegion*>& regions, vector<Messages> &messagesForFile,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
if (cacheNameShiftAll.find(file) == cacheNameShiftAll.end())
cacheNameShiftAll[file] = map<SgStatement*, map<string, map<int, int>>>();
int funcNum = file->numberOfFunctions();
auto useMapMod = createMapOfModuleUses(file);
vector<SgStatement*> modules;
findModulesInFile(file, modules);
map<string, SgStatement*> modMap;
for (auto& elem : modules)
modMap[elem->symbol()->identifier()] = elem;
for (int i = 0; i < funcNum; ++i)
{
SgStatement* st = file->functions(i);
if (cacheNameShiftAll[file].find(st) == cacheNameShiftAll[file].end())
cacheNameShiftAll[file][st] = map<string, map<int, int>>();
cacheNameShift = &cacheNameShiftAll[file][st];
SgStatement* lastNode = st->lastNodeOfStmt();
vector<pair<SgStatement*, SgStatement*>> toMove;
SgStatement* firstExec = NULL;
SgStatement* controlParFristExec = NULL;
for (SgStatement* st1 = file->functions(i); st1 != lastNode && !firstExec; st1 = st1->lexNext())
{
const int var = st1->variant();
if (isSgExecutableStatement(st1))
firstExec = st1;
if ((var == CONTAINS_STMT || var == PROC_HEDR || var == FUNC_HEDR) && st1 != file->functions(i))
break;
}
if (firstExec)
controlParFristExec = firstExec->controlParent();
set<SgStatement*> useMods;
map<string, set<SgSymbol*>> byUse = moduleRefsByUseInFunction(st);
map<string, SgStatement*> derivedTypesDecl = createDerivedTypeDeclMap(st);
bool isInTypeDecl = false;
for (; st != lastNode; st = st->lexNext())
{
if (st->variant() == CONTAINS_STMT)
break;
if (st->variant() == STRUCT_DECL)
isInTypeDecl = true;
if (st->variant() == CONTROL_END && st->controlParent()->variant() == STRUCT_DECL)
isInTypeDecl = false;
//move init assigns before the first statement
// skip if in TYPE-END_TYPE construction
if (firstExec && isSgDeclarationStatement(st) && !isInTypeDecl)
{
SgVarDeclStmt* declStat = (SgVarDeclStmt*)st;
for (int k = 0; k < declStat->numberOfSymbols(); ++k)
{
SgExpression* completeInit = declStat->completeInitialValue(k);
if (completeInit)
{
auto copyLeft = completeInit->lhs()->copyPtr();
auto copyRight = completeInit->rhs()->copyPtr();
SgStatement* toAdd = new SgStatement(ASSIGN_STAT, NULL, NULL, copyLeft, copyRight, NULL);
if (isDerivedAssign(toAdd))
replaceDerivedAssigns(file, toAdd, firstExec, derivedTypesDecl);
else
{
toAdd->setFileId(controlParFristExec->getFileId());
toAdd->setProject(controlParFristExec->getProject());
firstExec->insertStmtBefore(*toAdd, *controlParFristExec);
toAdd->setlineNumber(getNextNegativeLineNumber());
toAdd->setLocalLineNumber(st->lineNumber());
}
toMove.push_back(make_pair(st, toAdd));
}
}
}
//move SPF ANALYSIS PARAMETER before current statement
vector<SgStatement*> parameters;
for (auto& attr : getAttributes<SgStatement*, SgStatement*>(st, set<int>{ SPF_ANALYSIS_DIR }))
{
SgExpression* exprList = attr->expr(0);
while (exprList)
{
if (exprList->lhs()->variant() == SPF_PARAMETER_OP)
{
SgExpression* list = exprList->lhs()->lhs();
while (list)
{
if (list->lhs()->variant() != ASSGN_OP)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
parameters.push_back(new SgStatement(ASSIGN_STAT, NULL, NULL, list->lhs()->lhs()->copyPtr(), list->lhs()->rhs()->copyPtr(), NULL));
parameters.back()->setFileId(st->getFileId());
parameters.back()->setProject(st->getProject());
parameters.back()->setlineNumber(getNextNegativeLineNumber());
parameters.back()->setLocalLineNumber(attr->lineNumber());
list = list->rhs();
}
}
exprList = exprList->rhs();
}
}
for (auto& par : parameters)
{
st->insertStmtBefore(*par, *st->controlParent());
auto inserted = st->lexPrev();
inserted->setUnparseIgnore(true);
inserted->addAttribute(SPF_PARAMETER_OP, st, sizeof(SgStatement*));
}
if (firstExec && st->variant() == USE_STMT)
useMods.insert(st);
//TODO: change names by use
//TODO: create init of decl for all USE map
if (firstExec && isSgExecutableStatement(st))
{
for (auto& elem : useMods)
{
auto it = modMap.find(elem->symbol()->identifier());
if (it == modMap.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (SgStatement* stM = it->second->lexNext(); stM != it->second->lastNodeOfStmt(); stM = stM->lexNext())
{
if (isSgExecutableStatement(stM))
break;
const int var = stM->variant();
if (var == PROC_HEDR || var == FUNC_HEDR)
break;
if (isSgDeclarationStatement(stM))
{
SgVarDeclStmt* declStat = (SgVarDeclStmt*)stM;
bool ifHasParameterAttr = false;
for (int z = 0; z < declStat->numberOfAttributes(); ++z)
if (declStat->attribute(z)->variant() == PARAMETER_OP)
ifHasParameterAttr = true;
if (ifHasParameterAttr)
{
for (int k = 0; k < declStat->numberOfSymbols(); ++k)
{
SgExpression* completeInit = declStat->completeInitialValue(k);
if (completeInit)
{
SgStatement* toAdd = new SgStatement(ASSIGN_STAT, NULL, NULL, completeInit->lhs()->copyPtr(), completeInit->rhs()->copyPtr(), NULL);
toAdd->setFileId(controlParFristExec->getFileId());
toAdd->setProject(controlParFristExec->getProject());
firstExec->insertStmtBefore(*toAdd, *controlParFristExec);
toMove.push_back(make_pair(elem, toAdd));
toAdd->setlineNumber(getNextNegativeLineNumber());
toAdd->setLocalLineNumber(elem->lineNumber());
}
}
}
}
}
}
firstExec = NULL;
}
if (getRegionByLine(regions, st->fileName(), st->lineNumber()) &&
(st->variant() == ASSIGN_STAT || st->variant() == WHERE_NODE))
{
SgStatement* conv = runConversion(st, file, messagesForFile, arrayLinksByFuncCalls);
if (conv)
{
auto currFile = st->getFileId();
auto currProj = st->getProject();
st->insertStmtBefore(*conv, *st->controlParent());
toMove.push_back(make_pair(st, conv));
if (conv->variant() != ASSIGN_STAT)
{
SgStatement* end = conv->lastNodeOfStmt();
for (SgStatement* st1 = conv; st1 != end; st1 = st1->lexNext())
{
st1->setlineNumber(getNextNegativeLineNumber());
st1->setLocalLineNumber(st->lineNumber());
st1->setFileId(currFile);
st1->setProject(currProj);
}
end->setlineNumber(getNextNegativeLineNumber());
end->setLocalLineNumber(st->lineNumber());
end->setFileId(currFile);
end->setProject(currProj);
}
else
{
conv->setlineNumber(getNextNegativeLineNumber());
conv->setLocalLineNumber(st->lineNumber());
conv->setFileId(currFile);
conv->setProject(currProj);
}
//TODO: may be need to move more attributes
//move only SPF_ANALYSIS_DIR attributes
for (auto& attr : getAttributes<SgStatement*, SgStatement*>(st, set<int>{ SPF_ANALYSIS_DIR }))
conv->addAttribute(SPF_ANALYSIS_DIR, attr, sizeof(SgStatement*));
}
}
}
for (auto& move : toMove)
{
move.first->addAttribute(ASSIGN_STAT, move.second, sizeof(SgStatement*));
char* comments = move.first->comments();
if (comments)
move.second->setComments(comments);
}
}
}
static bool isUnderParallelLoop(SgStatement * st)
{
bool isUnder = false;
while (st)
{
const int var = st->variant();
if (var == FUNC_HEDR || var == PROG_HEDR || var == PROC_HEDR)
break;
if (var == FOR_NODE)
{
auto prev = st->lexPrev();
if (prev->variant() == DVM_PARALLEL_ON_DIR)
{
isUnder = true;
break;
}
}
st = st->controlParent();
}
return isUnder;
}
static bool hasParallelDir(SgStatement * st)
{
bool has = false;
SgStatement* last = st->lastNodeOfStmt();
while (st != last)
{
int var = st->variant();
if ((var == FOR_NODE || var == -FOR_NODE) && st->lexPrev()->variant() == DVM_PARALLEL_ON_DIR)
has = true;
st = st->lexNext();
}
return has;
}
static void addToDeclSet(SgExpression* exp, set<string> &symbolSet)
{
if (exp)
{
if (exp->symbol())
symbolSet.insert(OriginalSymbol(exp->symbol())->identifier());
if (exp->lhs())
addToDeclSet(exp->lhs(), symbolSet);
if (exp->rhs())
addToDeclSet(exp->rhs(), symbolSet);
}
}
void restoreConvertedLoopForParallelLoops(SgFile* file, const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls, bool reversed)
{
if (cacheNameShiftAll.find(file) == cacheNameShiftAll.end())
cacheNameShiftAll[file] = map<SgStatement*, map<string, map<int, int>>>();
int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; ++i)
{
SgStatement* st = file->functions(i);
SgStatement* lastNode = st->lastNodeOfStmt();
if (cacheNameShiftAll[file].find(st) == cacheNameShiftAll[file].end())
cacheNameShiftAll[file][st] = map<string, map<int, int>>();
cacheNameShift = &cacheNameShiftAll[file][st];
map<string, SgSymbol*> newDeclarations;
set<string> declaratedInFunction;
SgStatement* lastDeclarated = NULL;
for (st = file->functions(i); st != lastNode; st = st->lexNext())
{
if (isSgExecutableStatement(st))
break;
if (st->variant() == CONTAINS_STMT)
break;
if (st->variant() != DATA_DECL && st->variant() != FORMAT_STAT)
for (int i = 0; i < 3; ++i)
addToDeclSet(st->expr(i), declaratedInFunction);
if (st->fileName() == file->filename())
lastDeclarated = st;
}
vector<SgStatement*> toDel;
vector<Messages> messagesForFileTmp;
for (st = file->functions(i); st != lastNode; st = st->lexNext())
{
for (auto& data : getAttributes<SgStatement*, SgStatement*>(st, set<int>{ ASSIGN_STAT }))
{
if (reversed)
{
if (data->lineNumber() < 0)
{
data->setVariant(abs(data->variant()));
auto secondConv = runConversion(st, file, messagesForFileTmp, arrayLinksByFuncCalls);
if (secondConv && notDeletedVectorAssign(st))
st->setVariant(-abs(st->variant()));
else
st->setVariant(abs(st->variant()));
}
}
else
{
if (data->lineNumber() < 0)
{
auto secondConv = runConversion(st, file, messagesForFileTmp, arrayLinksByFuncCalls);
if (isUnderParallelLoop(st) || secondConv && notDeletedVectorAssign(st))
{
st->setVariant(-abs(st->variant()));
auto prev = st->lexPrev();
if (prev->variant() == DVM_REMOTE_ACCESS_DIR)
toDel.push_back(prev);
data->setVariant(abs(data->variant()));
if (data->variant() == FOR_NODE || data->variant() == IF_NODE)
{
for (auto st_loc = data; st_loc != data->lastNodeOfStmt(); st_loc = st_loc->lexNext())
if (st_loc->variant() == FOR_NODE)
newDeclarations[st_loc->symbol()->identifier()] = st_loc->symbol();
}
else if (data->variant() == ASSIGN_STAT && data->lexNext()->variant() == FOR_NODE)
{
for (auto st_loc = data->lexNext(); st_loc != data->lexNext()->lastNodeOfStmt(); st_loc = st_loc->lexNext())
if (st_loc->variant() == FOR_NODE)
newDeclarations[st_loc->symbol()->identifier()] = st_loc->symbol();
}
}
else
data->setVariant(-abs(data->variant()));
}
}
}
}
for (auto& elem : toDel)
elem->extractStmt();
//insert new declaration of symbols for converted loops
for (auto& toDecl : newDeclarations)
{
auto found = declaratedInFunction.find(toDecl.first);
if (found == declaratedInFunction.end())
{
declaratedInFunction.insert(toDecl.first);
auto toInsert = toDecl.second->makeVarDeclStmt();
lastDeclarated->insertStmtAfter(*toInsert, *st->controlParent());
}
}
}
}
static map<SgStatement*, set<string>> newSymbDeclaredInFunction;
bool needDeclare(SgStatement* start, SgStatement* end)
{
bool isImplicit = false;
for (auto st = start; st != end && st; st = st->lexNext())
{
if (isSgExecutableStatement(st) && !isDVM_stat(st) && !isSPF_stat(st))
break;
if (st->variant() == CONTAINS_STMT)
break;
if (st->variant() == IMPL_DECL)
isImplicit = true;
if (st->variant() == VAR_DECL || st->variant() == VAR_DECL_90)
{
SgExpression* list = st->expr(0);
while (list)
{
if (list->lhs()->variant() == VAR_REF)
newSymbDeclaredInFunction[start].insert(list->lhs()->symbol()->identifier());
list = list->rhs();
}
}
}
return isImplicit;
}
set<SgSymbol*> findLoopSymbolsToDecl(SgStatement* stat, const set<string>& declared)
{
set<SgSymbol*> retVal;
set<string> added;
SgStatement* last = stat->lastNodeOfStmt();
for (auto st = stat; st != last; st = st->lexNext())
{
auto isFor = isSgForStmt(st);
if (isFor)
{
auto s = isFor->doName();
string ident = s->identifier();
if (ident.find("i_") != string::npos && s->type()->variant() == T_INT)
{
if (declared.find(ident) == declared.end() && added.find(ident) == added.end())
{
retVal.insert(s);
added.insert(ident);
}
}
}
}
return retVal;
}
void restoreAssignsFromLoop(SgFile* file, const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
if (cacheNameShiftAll.find(file) == cacheNameShiftAll.end())
cacheNameShiftAll[file] = map<SgStatement*, map<string, map<int, int>>>();
int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; ++i)
{
SgStatement* currF = file->functions(i);
if (cacheNameShiftAll[file].find(currF) == cacheNameShiftAll[file].end())
cacheNameShiftAll[file][currF] = map<string, map<int, int>>();
cacheNameShift = &cacheNameShiftAll[file][currF];
SgStatement* lastNode = currF->lastNodeOfStmt();
bool needDecl = needDeclare(currF, lastNode);
vector<pair<SgStatement*, SgStatement*>> toMove;
for (auto st = file->functions(i); st != lastNode; st = st->lexNext())
{
if (st->variant() == CONTAINS_STMT)
break;
for (auto& data : getAttributes<SgStatement*, SgStatement*>(st, set<int>{ ASSIGN_STAT }))
if (data->lineNumber() < 0)
toMove.push_back(make_pair(st, data));
}
vector<Messages> messagesForFileTmp;
for (auto& move : toMove)
{
auto secondConv = runConversion(move.first, file, messagesForFileTmp, arrayLinksByFuncCalls);
if (secondConv && notDeletedVectorAssign(move.first))
{
move.first->setVariant(-abs(move.first->variant()));
if (needDecl) // declare loops symbol
{
auto it = newSymbDeclaredInFunction.find(currF);
set<string> empty;
set<SgSymbol*> newDecl;
if (it != newSymbDeclaredInFunction.end())
newDecl = findLoopSymbolsToDecl(secondConv, it->second);
else
newDecl = findLoopSymbolsToDecl(secondConv, empty);
if (newDecl.size())
{
vector<SgSymbol*> newDeclV(newDecl.begin(), newDecl.end());
makeDeclaration(currF, newDeclV);
for (auto& elem : newDecl)
newSymbDeclaredInFunction[currF].insert(elem->identifier());
}
}
}
else
move.second->setVariant(-abs(move.second->variant()));
}
}
}