2245 lines
84 KiB
C++
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()));
|
|
}
|
|
}
|
|
}
|