Compare commits
7 Commits
30b2248e39
...
962b89f502
| Author | SHA1 | Date | |
|---|---|---|---|
| 962b89f502 | |||
| f42ed16096 | |||
| b35886bf0e | |||
|
|
184a83ee58 | ||
|
|
2540237e42 | ||
|
|
09c7885849 | ||
|
|
f08f46a536 |
@@ -243,9 +243,9 @@ public:
|
|||||||
inline void replaceSymbBySymb(SgSymbol &symb, SgSymbol &newsymb);
|
inline void replaceSymbBySymb(SgSymbol &symb, SgSymbol &newsymb);
|
||||||
inline void replaceSymbBySymbSameName(SgSymbol &symb, SgSymbol &newsymb);
|
inline void replaceSymbBySymbSameName(SgSymbol &symb, SgSymbol &newsymb);
|
||||||
inline void replaceTypeInStmt(SgType &old, SgType &newtype);
|
inline void replaceTypeInStmt(SgType &old, SgType &newtype);
|
||||||
char* unparse(int lang = 2); // FORTRAN_LANG
|
char* unparse(int lang = 0); // FORTRAN_LANG
|
||||||
inline void unparsestdout();
|
inline void unparsestdout();
|
||||||
std::string sunparse(int lang = 2); // FORTRAN_LANG
|
std::string sunparse(int lang = 0); // FORTRAN_LANG
|
||||||
inline char *comments(); //preceding comment lines.
|
inline char *comments(); //preceding comment lines.
|
||||||
void addComment(const char *com);
|
void addComment(const char *com);
|
||||||
void addComment(char *com);
|
void addComment(char *com);
|
||||||
@@ -3684,7 +3684,7 @@ inline char* SgStatement::unparse(int lang)
|
|||||||
#ifdef __SPF
|
#ifdef __SPF
|
||||||
checkConsistence();
|
checkConsistence();
|
||||||
#endif
|
#endif
|
||||||
return UnparseBif_Char(thebif, lang); //2 - fortran language
|
return UnparseBif_Char(thebif, lang); //0 - fortran language
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SgStatement::unparsestdout()
|
inline void SgStatement::unparsestdout()
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ mkC++extern $SAGEROOT/lib/newsrc/low_level.c > ! $SAGEROOT/lib/include/extcxx_lo
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h> /* ANSI variable argument header */
|
#include <stdarg.h> /* ANSI variable argument header */
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "compatible.h" /* Make different system compatible... (PHB) */
|
#include "compatible.h" /* Make different system compatible... (PHB) */
|
||||||
#ifdef SYS5
|
#ifdef SYS5
|
||||||
@@ -1028,7 +1029,7 @@ void UnparseBif(bif)
|
|||||||
/* podd 28.01.07 */ /*change podd 16.12.11*/
|
/* podd 28.01.07 */ /*change podd 16.12.11*/
|
||||||
char *UnparseBif_Char(bif,lang)
|
char *UnparseBif_Char(bif,lang)
|
||||||
PTR_BFND bif;
|
PTR_BFND bif;
|
||||||
int lang; /* 0 - undefined, 1 - C language, 2 - Fortran language */
|
int lang; /* ForSrc=0 - Fortran language, CSrc=1 - C language */
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
/* PTR_BLOB b, bl;
|
/* PTR_BLOB b, bl;
|
||||||
@@ -8932,7 +8933,7 @@ void updateSymbInInterfaceBlock(PTR_BFND block)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSymbolsOfList(PTR_LLND slist, PTR_BFND struct_stmt)
|
void updateSymbolsOfList(PTR_LLND slist, PTR_BFND struct_stmt)
|
||||||
{
|
{
|
||||||
PTR_LLND ll;
|
PTR_LLND ll;
|
||||||
PTR_SYMB symb, newsymb;
|
PTR_SYMB symb, newsymb;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h> /* podd 15.03.99*/
|
#include <stdlib.h> /* podd 15.03.99*/
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "compatible.h" /* Make different system compatible... (PHB) */
|
#include "compatible.h" /* Make different system compatible... (PHB) */
|
||||||
#ifdef SYS5
|
#ifdef SYS5
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ static map<SgStatement*, vector<SgStatement*> > insertAfter;
|
|||||||
|
|
||||||
static map<SgStatement*, SgStatement*> replaced;
|
static map<SgStatement*, SgStatement*> replaced;
|
||||||
static int arrayGenNum;
|
static int arrayGenNum;
|
||||||
|
static int SAPFOR_CONV = 0;
|
||||||
|
|
||||||
#if TRACE
|
#if TRACE
|
||||||
static int lvl_convert_st = 0;
|
static int lvl_convert_st = 0;
|
||||||
@@ -2301,6 +2302,16 @@ static bool convertStmt(SgStatement* &st, pair<SgStatement*, SgStatement*> &retS
|
|||||||
tt3->setRhs(new SgExprListExp());
|
tt3->setRhs(new SgExprListExp());
|
||||||
tt3->rhs()->setLhs(&SgAssignOp(*new SgVarRefExp(newVar), *new SgVarRefExp(newVar) + *new SgValueExp(1)));
|
tt3->rhs()->setLhs(&SgAssignOp(*new SgVarRefExp(newVar), *new SgVarRefExp(newVar) + *new SgValueExp(1)));
|
||||||
|
|
||||||
|
if (SAPFOR_CONV) // TODO: negative step
|
||||||
|
{
|
||||||
|
SgExprListExp* start = new SgExprListExp();
|
||||||
|
start->setLhs(SgAssignOp(*new SgVarRefExp(it), *ex1));
|
||||||
|
|
||||||
|
SgExprListExp* step = new SgExprListExp();
|
||||||
|
step->setLhs(&SgAssignOp(*new SgVarRefExp(it), *new SgVarRefExp(it) + *ex3));
|
||||||
|
retSt = new SgForStmt(start, &(*new SgVarRefExp(it) <= ex2->copy()), step, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
retSt = new SgForStmt(tt, &(*new SgVarRefExp(*newVar) < *new SgVarRefExp(cond)), tt3, NULL);
|
retSt = new SgForStmt(tt, &(*new SgVarRefExp(*newVar) < *new SgVarRefExp(cond)), tt3, NULL);
|
||||||
|
|
||||||
if (cycleName)
|
if (cycleName)
|
||||||
@@ -2321,7 +2332,7 @@ static bool convertStmt(SgStatement* &st, pair<SgStatement*, SgStatement*> &retS
|
|||||||
int sizeStack = bodySt.size();
|
int sizeStack = bodySt.size();
|
||||||
for (int i = 0; i < sizeStack; ++i)
|
for (int i = 0; i < sizeStack; ++i)
|
||||||
{
|
{
|
||||||
retSt->insertStmtAfter(*bodySt.top());
|
retSt->insertStmtAfter(*bodySt.top(), *retSt);
|
||||||
bodySt.pop();
|
bodySt.pop();
|
||||||
}
|
}
|
||||||
newVars.push_back(cond);
|
newVars.push_back(cond);
|
||||||
@@ -2434,7 +2445,7 @@ static bool convertStmt(SgStatement* &st, pair<SgStatement*, SgStatement*> &retS
|
|||||||
int sizeStack = bodySt.size();
|
int sizeStack = bodySt.size();
|
||||||
for (int i = 0; i < sizeStack; ++i)
|
for (int i = 0; i < sizeStack; ++i)
|
||||||
{
|
{
|
||||||
retSt->insertStmtAfter(*bodySt.top());
|
retSt->insertStmtAfter(*bodySt.top(), *retSt);
|
||||||
bodySt.pop();
|
bodySt.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2557,7 +2568,7 @@ static bool convertStmt(SgStatement* &st, pair<SgStatement*, SgStatement*> &retS
|
|||||||
int sizeStack = bodySt.size();
|
int sizeStack = bodySt.size();
|
||||||
for (int i = 0; i < sizeStack; ++i)
|
for (int i = 0; i < sizeStack; ++i)
|
||||||
{
|
{
|
||||||
newIfStmt->insertStmtAfter(*bodySt.top());
|
newIfStmt->insertStmtAfter(*bodySt.top(), *newIfStmt);
|
||||||
bodySt.pop();
|
bodySt.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2695,6 +2706,30 @@ static bool convertStmt(SgStatement* &st, pair<SgStatement*, SgStatement*> &retS
|
|||||||
needReplace = true;
|
needReplace = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if (st->variant() == PRINT_STAT) // only for SAPFOR
|
||||||
|
{
|
||||||
|
if (SAPFOR_CONV == 0)
|
||||||
|
Error("Internal inconsistency in F->C convertation", "", 654, first_do_par);
|
||||||
|
|
||||||
|
SgInputOutputStmt* outStat = (SgInputOutputStmt*)st;
|
||||||
|
SgExpression* lhs = outStat->itemList();
|
||||||
|
convertExpr(lhs, lhs);
|
||||||
|
|
||||||
|
SgExpression* list = lhs;
|
||||||
|
while (list)
|
||||||
|
{
|
||||||
|
SgExpression* item = list->lhs();
|
||||||
|
if (item && item->variant() == STRING_VAL)
|
||||||
|
{
|
||||||
|
SgValueExp* exp = (SgValueExp*)item;
|
||||||
|
string str = exp->stringValue();
|
||||||
|
str += "\\n";
|
||||||
|
exp->setValue(strdup(str.c_str()));
|
||||||
|
}
|
||||||
|
list = list->rhs();
|
||||||
|
}
|
||||||
|
retSt = new SgCExpStmt(*new SgFunctionCallExp(*new SgSymbol(FUNCTION_NAME, "printf"), *lhs));
|
||||||
|
}
|
||||||
else if (st->variant() == PROC_STAT)
|
else if (st->variant() == PROC_STAT)
|
||||||
{
|
{
|
||||||
#if TRACE
|
#if TRACE
|
||||||
@@ -2705,8 +2740,13 @@ static bool convertStmt(SgStatement* &st, pair<SgStatement*, SgStatement*> &retS
|
|||||||
SgExpression *lhs = st->expr(0);
|
SgExpression *lhs = st->expr(0);
|
||||||
convertExpr(lhs, lhs);
|
convertExpr(lhs, lhs);
|
||||||
|
|
||||||
if (lhs == NULL)
|
if (lhs == NULL || SAPFOR_CONV)
|
||||||
|
{
|
||||||
|
if (lhs)
|
||||||
|
retSt = new SgCExpStmt(*new SgFunctionCallExp(*st->symbol(), *lhs));
|
||||||
|
else
|
||||||
retSt = new SgCExpStmt(*new SgFunctionCallExp(*st->symbol()));
|
retSt = new SgCExpStmt(*new SgFunctionCallExp(*st->symbol()));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (st->symbol()->identifier() == string("random_number"))
|
if (st->symbol()->identifier() == string("random_number"))
|
||||||
@@ -2810,7 +2850,7 @@ static bool convertStmt(SgStatement* &st, pair<SgStatement*, SgStatement*> &retS
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
retSt = st;
|
retSt = st;
|
||||||
if (st->variant() != CONTROL_END && st->variant() != EXPR_STMT_NODE)
|
if (st->variant() != CONTROL_END && st->variant() != EXPR_STMT_NODE && first_do_par)
|
||||||
{
|
{
|
||||||
printf(" [STMT ERROR: %s, line %d, user line %d] unsupported variant of node: %s\n", __FILE__, __LINE__, first_do_par->lineNumber(), tag[st->variant()]);
|
printf(" [STMT ERROR: %s, line %d, user line %d] unsupported variant of node: %s\n", __FILE__, __LINE__, first_do_par->lineNumber(), tag[st->variant()]);
|
||||||
if (unSupportedVars.size() != 0)
|
if (unSupportedVars.size() != 0)
|
||||||
@@ -3177,11 +3217,18 @@ static void correctLabelsUse(SgStatement *firstStmt, SgStatement *lastStmt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translate_Fortran_To_C(SgStatement *Stmt)
|
SgStatement* Translate_Fortran_To_C(SgStatement *Stmt, bool isSapforConv)
|
||||||
{
|
{
|
||||||
#if TRACE
|
#if TRACE
|
||||||
printf("START: CONVERTION OF BODY ON LINE %d\n", number_of_loop_line);
|
printf("START: CONVERTION OF BODY ON LINE %d\n", number_of_loop_line);
|
||||||
#endif
|
#endif
|
||||||
|
if (isSapforConv)
|
||||||
|
{
|
||||||
|
SAPFOR_CONV = 1;
|
||||||
|
if (handlersOfFunction.size() == 0)
|
||||||
|
initF2C_FunctionCalls();
|
||||||
|
}
|
||||||
|
|
||||||
map<string, int> redArraysWithUnknownSize;
|
map<string, int> redArraysWithUnknownSize;
|
||||||
SgExpression* er = red_list;
|
SgExpression* er = red_list;
|
||||||
for (reduction_operation_list* rsl = red_struct_list; rsl && er; rsl = rsl->next, er = er->rhs())
|
for (reduction_operation_list* rsl = red_struct_list; rsl && er; rsl = rsl->next, er = er->rhs())
|
||||||
@@ -3189,6 +3236,8 @@ void Translate_Fortran_To_C(SgStatement *Stmt)
|
|||||||
redArraysWithUnknownSize[rsl->redvar->identifier()] = RedFuncNumber(er->lhs()->lhs());
|
redArraysWithUnknownSize[rsl->redvar->identifier()] = RedFuncNumber(er->lhs()->lhs());
|
||||||
|
|
||||||
SgStatement *copyFSt = Stmt;
|
SgStatement *copyFSt = Stmt;
|
||||||
|
SgStatement* last = (Stmt == Stmt->lastNodeOfStmt()) ? Stmt->lastNodeOfStmt() : Stmt->lastExecutable();
|
||||||
|
|
||||||
vector<stack<SgStatement*> > copyBlock;
|
vector<stack<SgStatement*> > copyBlock;
|
||||||
labelsExitCycle.clear();
|
labelsExitCycle.clear();
|
||||||
autoTfmReplacing.clear();
|
autoTfmReplacing.clear();
|
||||||
@@ -3196,41 +3245,47 @@ void Translate_Fortran_To_C(SgStatement *Stmt)
|
|||||||
cond_generator = 0;
|
cond_generator = 0;
|
||||||
unSupportedVars.clear();
|
unSupportedVars.clear();
|
||||||
bool needReplace = false;
|
bool needReplace = false;
|
||||||
pair<SgStatement*, SgStatement*> tmp;
|
pair<SgStatement*, SgStatement*> converted;
|
||||||
|
|
||||||
#if TRACE
|
#if TRACE
|
||||||
printfSpaces(lvl_convert_st);
|
printfSpaces(lvl_convert_st);
|
||||||
printf("convert Stmt\n");
|
printf("convert Stmt\n");
|
||||||
lvl_convert_st += 2;
|
lvl_convert_st += 2;
|
||||||
#endif
|
#endif
|
||||||
needReplace = convertStmt(copyFSt, tmp, copyBlock, 0, 0, redArraysWithUnknownSize);
|
needReplace = convertStmt(copyFSt, converted, copyBlock, 0, 0, redArraysWithUnknownSize);
|
||||||
#if TRACE
|
#if TRACE
|
||||||
lvl_convert_st-=2;
|
lvl_convert_st-=2;
|
||||||
printfSpaces(lvl_convert_st);
|
printfSpaces(lvl_convert_st);
|
||||||
printf("end of convert Stmt\n");
|
printf("end of convert Stmt\n");
|
||||||
#endif
|
#endif
|
||||||
if (needReplace)
|
|
||||||
|
if (needReplace && !isSapforConv)
|
||||||
{
|
{
|
||||||
char *comm = copyFSt->comments();
|
char *comm = copyFSt->comments();
|
||||||
if (comm)
|
if (comm)
|
||||||
tmp.first->addComment(comm);
|
converted.first->addComment(comm);
|
||||||
|
|
||||||
if (tmp.first)
|
if (converted.first)
|
||||||
copyFSt->insertStmtBefore(*tmp.first, *copyFSt->controlParent());
|
copyFSt->insertStmtBefore(*converted.first, *copyFSt->controlParent());
|
||||||
|
|
||||||
copyFSt->deleteStmt();
|
copyFSt->deleteStmt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (first_do_par)
|
||||||
|
{
|
||||||
for (set<int>::iterator i = unSupportedVars.begin(); i != unSupportedVars.end(); i++)
|
for (set<int>::iterator i = unSupportedVars.begin(); i != unSupportedVars.end(); i++)
|
||||||
printf(" [EXPR ERROR: %s, line %d, %d] unsupported variant of node: %s\n", __FILE__, __LINE__, first_do_par->lineNumber(), tag[*i]);
|
printf(" [EXPR ERROR: %s, line %d, %d] unsupported variant of node: %s\n", __FILE__, __LINE__, first_do_par->lineNumber(), tag[*i]);
|
||||||
if (unSupportedVars.size() != 0)
|
if (unSupportedVars.size() != 0)
|
||||||
Error("Internal inconsistency in F->C convertation", "", 654, first_do_par);
|
Error("Internal inconsistency in F->C convertation", "", 654, first_do_par);
|
||||||
|
}
|
||||||
|
|
||||||
correctLabelsUse(Stmt, Stmt->lastExecutable());
|
correctLabelsUse(Stmt, last);
|
||||||
|
|
||||||
#if TRACE
|
#if TRACE
|
||||||
printf("END: CONVERTION OF BODY ON LINE %d\n", number_of_loop_line);
|
printf("END: CONVERTION OF BODY ON LINE %d\n", number_of_loop_line);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return converted.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3265,13 +3320,13 @@ void Translate_Fortran_To_C(SgStatement *firstStmt, SgStatement *lastStmt, vecto
|
|||||||
while (copyFSt != lastStmt)
|
while (copyFSt != lastStmt)
|
||||||
{
|
{
|
||||||
bool needReplace = false;
|
bool needReplace = false;
|
||||||
pair<SgStatement*, SgStatement*> tmp;
|
pair<SgStatement*, SgStatement*> converted;
|
||||||
#if TRACE
|
#if TRACE
|
||||||
printfSpaces(lvl_convert_st);
|
printfSpaces(lvl_convert_st);
|
||||||
printf("convert Stmt\n");
|
printf("convert Stmt\n");
|
||||||
lvl_convert_st += 2;
|
lvl_convert_st += 2;
|
||||||
#endif
|
#endif
|
||||||
needReplace = convertStmt(copyFSt, tmp, copyBlock, countOfCopy, 0, redArraysWithUnknownSize);
|
needReplace = convertStmt(copyFSt, converted, copyBlock, countOfCopy, 0, redArraysWithUnknownSize);
|
||||||
#if TRACE
|
#if TRACE
|
||||||
lvl_convert_st-=2;
|
lvl_convert_st-=2;
|
||||||
printfSpaces(lvl_convert_st);
|
printfSpaces(lvl_convert_st);
|
||||||
@@ -3279,16 +3334,16 @@ void Translate_Fortran_To_C(SgStatement *firstStmt, SgStatement *lastStmt, vecto
|
|||||||
#endif
|
#endif
|
||||||
if (needReplace)
|
if (needReplace)
|
||||||
{
|
{
|
||||||
if (tmp.first)
|
if (converted.first)
|
||||||
{
|
{
|
||||||
char *comm = copyFSt->comments();
|
char *comm = copyFSt->comments();
|
||||||
if (comm)
|
if (comm)
|
||||||
tmp.first->addComment(comm);
|
converted.first->addComment(comm);
|
||||||
|
|
||||||
copyFSt->insertStmtBefore(*tmp.first, *copyFSt->controlParent());
|
copyFSt->insertStmtBefore(*converted.first, *copyFSt->controlParent());
|
||||||
replaced[tmp.first] = copyFSt;
|
replaced[converted.first] = copyFSt;
|
||||||
for (int i = 0; i < countOfCopy; ++i)
|
for (int i = 0; i < countOfCopy; ++i)
|
||||||
copyBlock[i].push(&tmp.first->copy());
|
copyBlock[i].push(&converted.first->copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
SgStatement *tmp1 = copyFSt;
|
SgStatement *tmp1 = copyFSt;
|
||||||
|
|||||||
@@ -2075,7 +2075,7 @@ char *Check_Correct_Name(const char *name);
|
|||||||
char *Check_Correct_Name(const char *name);
|
char *Check_Correct_Name(const char *name);
|
||||||
|
|
||||||
/* acc_f2c.cpp */
|
/* acc_f2c.cpp */
|
||||||
void Translate_Fortran_To_C(SgStatement *stat, SgStatement *last, std::vector <std::stack <SgStatement*> > &, int);
|
void Translate_Fortran_To_C(SgStatement *stat, SgStatement *last, std::vector <std::stack <SgStatement*> > &, int);
|
||||||
SgStatement* Translate_Fortran_To_C(SgStatement* Stmt, bool isSapforConv = false);
|
SgStatement* Translate_Fortran_To_C(SgStatement* Stmt, bool isSapforConv = false);
|
||||||
|
|
||||||
SgSymbol* createNewFunctionSymbol(const char *name);
|
SgSymbol* createNewFunctionSymbol(const char *name);
|
||||||
|
|||||||
@@ -404,6 +404,7 @@ void startioctl();
|
|||||||
void endioctl();
|
void endioctl();
|
||||||
void redefine_func_arg_type();
|
void redefine_func_arg_type();
|
||||||
int isResultVar();
|
int isResultVar();
|
||||||
|
int yylex();
|
||||||
|
|
||||||
/* used by FORTRAN M */
|
/* used by FORTRAN M */
|
||||||
PTR_BFND make_processdo();
|
PTR_BFND make_processdo();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -756,6 +756,7 @@ void startioctl();
|
|||||||
void endioctl();
|
void endioctl();
|
||||||
void redefine_func_arg_type();
|
void redefine_func_arg_type();
|
||||||
int isResultVar();
|
int isResultVar();
|
||||||
|
int yylex();
|
||||||
|
|
||||||
/* used by FORTRAN M */
|
/* used by FORTRAN M */
|
||||||
PTR_BFND make_processdo();
|
PTR_BFND make_processdo();
|
||||||
|
|||||||
@@ -14,7 +14,352 @@
|
|||||||
#include "dvm.h"
|
#include "dvm.h"
|
||||||
#include "convert_to_c.h"
|
#include "convert_to_c.h"
|
||||||
|
|
||||||
|
#include "Utils/utils.h"
|
||||||
|
#include "Utils/SgUtils.h"
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
using std::string;
|
||||||
|
using std::set;
|
||||||
|
|
||||||
|
extern "C" void Set_Function_Language(int);
|
||||||
|
extern "C" void Unset_Function_Language();
|
||||||
|
extern "C" int out_upper_case;
|
||||||
|
|
||||||
|
static SgStatement* createNewFunc(SgSymbol* sF, SgFile* file, SgProgHedrStmt* prog)
|
||||||
|
{
|
||||||
|
SgStatement* st_hedr, * st_end;
|
||||||
|
SgExpression* fe, *arg_list = NULL;
|
||||||
|
|
||||||
|
bool isMain = sF == NULL;
|
||||||
|
if (!sF)
|
||||||
|
sF = findSymbolOrCreate(file, "main", C_VoidType());
|
||||||
|
else
|
||||||
|
sF->setType(C_VoidType());
|
||||||
|
|
||||||
|
// create fuction header
|
||||||
|
st_hedr = new SgStatement(FUNC_HEDR);
|
||||||
|
st_hedr->setSymbol(*sF);
|
||||||
|
fe = new SgFunctionRefExp(*sF);
|
||||||
|
fe->setSymbol(*sF);
|
||||||
|
st_hedr->setExpression(0, *fe);
|
||||||
|
|
||||||
|
// create end of function
|
||||||
|
st_end = new SgStatement(CONTROL_END);
|
||||||
|
st_end->setSymbol(*sF);
|
||||||
|
|
||||||
|
if (!isMain)
|
||||||
|
{
|
||||||
|
//fill global
|
||||||
|
first_do_par = prog;
|
||||||
|
|
||||||
|
fe = st_hedr->expr(0);
|
||||||
|
int num = prog->numberOfParameters();
|
||||||
|
for (int z = 0; z < num; ++z)
|
||||||
|
{
|
||||||
|
SgSymbol* arg = prog->parameter(z);
|
||||||
|
auto typ = C_Type(arg->type());
|
||||||
|
if (arg->type()->variant() == T_STRING)
|
||||||
|
typ = C_PointerType(SgTypeChar());
|
||||||
|
auto s = new SgSymbol(VARIABLE_NAME, arg->identifier(), *typ, *st_hedr);
|
||||||
|
|
||||||
|
SgExpression* ae = new SgVarRefExp(s);
|
||||||
|
ae->setType(typ);
|
||||||
|
if (arg->type()->variant() == T_STRING)
|
||||||
|
ae = new SgPointerDerefExp(*ae);
|
||||||
|
|
||||||
|
if (z == 0)
|
||||||
|
{
|
||||||
|
arg_list = new SgExprListExp(*ae);
|
||||||
|
fe->setLhs(arg_list);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto el = new SgExpression(EXPR_LIST);
|
||||||
|
el->setLhs(NULL);
|
||||||
|
ae->setLhs(*el);
|
||||||
|
|
||||||
|
arg_list->setRhs(*new SgExprListExp(*ae));
|
||||||
|
arg_list = arg_list->rhs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
first_do_par = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return st_hedr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shiftIntValue(SgExpression* ex, SgExpression* par, bool isLeft, const set<string>& for_vars, bool& rep)
|
||||||
|
{
|
||||||
|
if (ex)
|
||||||
|
{
|
||||||
|
if (ex->variant() == VAR_REF && for_vars.find(ex->symbol()->identifier()) != for_vars.end())
|
||||||
|
{
|
||||||
|
if (isLeft)
|
||||||
|
par->setLhs(*new SgExpression(SUBT_OP, ex->copyPtr(), new SgValueExp(1)));
|
||||||
|
else
|
||||||
|
par->setRhs(*new SgExpression(SUBT_OP, ex->copyPtr(), new SgValueExp(1)));
|
||||||
|
rep = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
shiftIntValue(ex->lhs(), ex, true, for_vars, rep);
|
||||||
|
shiftIntValue(ex->rhs(), ex, false, for_vars, rep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void findArrayRef(SgExpression* ex, const set<string>& for_vars)
|
||||||
|
{
|
||||||
|
if (ex)
|
||||||
|
{
|
||||||
|
if (ex->variant() == ARRAY_REF)
|
||||||
|
{
|
||||||
|
SgArrayRefExp* ref = (SgArrayRefExp*)ex;
|
||||||
|
SgExpression* list = ex->lhs();
|
||||||
|
for (int z = 0; z < ref->numberOfSubscripts(); ++z)
|
||||||
|
{
|
||||||
|
bool rep = false;
|
||||||
|
if (for_vars.size())
|
||||||
|
shiftIntValue(ref->subscript(z), list, true, for_vars, rep);
|
||||||
|
|
||||||
|
if (!rep || for_vars.size() == 0)
|
||||||
|
{
|
||||||
|
auto sub = ref->subscript(z);
|
||||||
|
auto val = isSgValueExp(sub);
|
||||||
|
if (val && val->isInteger())
|
||||||
|
val->setValue(val->intValue() - 1);
|
||||||
|
else
|
||||||
|
list->setLhs(*new SgExpression(SUBT_OP, sub->copyPtr(), new SgValueExp(1)));
|
||||||
|
|
||||||
|
}
|
||||||
|
list = list->rhs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
findArrayRef(ex->lhs(), for_vars);
|
||||||
|
findArrayRef(ex->rhs(), for_vars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void findLoopSymbols(SgExpression* ex, set<string>& vars)
|
||||||
|
{
|
||||||
|
if (ex)
|
||||||
|
{
|
||||||
|
if (ex->variant() == VAR_REF)
|
||||||
|
vars.insert(ex->symbol()->identifier());
|
||||||
|
findLoopSymbols(ex->lhs(), vars);
|
||||||
|
findLoopSymbols(ex->rhs(), vars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void covertToC(SgFile* file)
|
void covertToC(SgFile* file)
|
||||||
{
|
{
|
||||||
printf("%s\n", file->firstStatement()->unparse(C_LANG));
|
out_upper_case = 0;
|
||||||
|
|
||||||
|
int funcNum = file->numberOfFunctions();
|
||||||
|
SgStatement* global = file->firstStatement();
|
||||||
|
|
||||||
|
vector<SgStatement*> funcs;
|
||||||
|
|
||||||
|
for (int i = 0; i < funcNum; ++i)
|
||||||
|
funcs.push_back(file->functions(i));
|
||||||
|
|
||||||
|
for (int i = funcs.size() - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
SgStatement* st = funcs[i];
|
||||||
|
SgStatement* last = st->lastNodeOfStmt();
|
||||||
|
|
||||||
|
//fill global dvm variables
|
||||||
|
cur_func = st;
|
||||||
|
bind_ = 1;
|
||||||
|
//
|
||||||
|
|
||||||
|
SgStatement* func = createNewFunc(st->variant() == PROG_HEDR ? NULL : st->symbol()->copyPtr(), file, isSgProgHedrStmt(st));
|
||||||
|
SgStatement* lastOfFunc = func->lastNodeOfStmt();
|
||||||
|
global->insertStmtAfter(*func, *global);
|
||||||
|
|
||||||
|
set<string> for_vars;
|
||||||
|
vector<SgStatement*> dvm_dirs;
|
||||||
|
for (SgStatement* st = funcs[i]; st != last; )
|
||||||
|
{
|
||||||
|
if (st->variant() == FOR_NODE)
|
||||||
|
for_vars.insert(isSgForStmt(st)->doName()->identifier());
|
||||||
|
else if (st->variant() == CONTROL_END)
|
||||||
|
{
|
||||||
|
auto cp = st->controlParent();
|
||||||
|
if (cp->variant() == FOR_NODE)
|
||||||
|
for_vars.erase(isSgForStmt(cp)->doName()->identifier());
|
||||||
|
}
|
||||||
|
else if (st->variant() == DVM_PARALLEL_ON_DIR)
|
||||||
|
{
|
||||||
|
SgExpression* rule = st->expr(2);
|
||||||
|
findLoopSymbols(rule, for_vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int z = 0; z < 3; ++z)
|
||||||
|
findArrayRef(st->expr(z), for_vars);
|
||||||
|
|
||||||
|
if (isDVM_stat(st))
|
||||||
|
{
|
||||||
|
SgStatement* next = st->lexNext();
|
||||||
|
dvm_dirs.push_back(st->extractStmt());
|
||||||
|
st = next;
|
||||||
|
}
|
||||||
|
else if(st->variant() == ALLOCATE_STMT ||
|
||||||
|
st->variant() == DEALLOCATE_STMT)
|
||||||
|
{
|
||||||
|
SgStatement* next = st->lexNext();
|
||||||
|
st->extractStmt();
|
||||||
|
st = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
st = st->lexNext();
|
||||||
|
|
||||||
|
if (st->variant() == DVM_PARALLEL_ON_DIR)
|
||||||
|
for_vars.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
string dvm_comm = "";
|
||||||
|
int dir_pos = 0;
|
||||||
|
int dir_line = dvm_dirs.size() ? dvm_dirs[dir_pos]->lineNumber() : -1;
|
||||||
|
|
||||||
|
for (SgStatement* st = funcs[i]; st != last; st = st->lexNext())
|
||||||
|
{
|
||||||
|
int curr_line = st->lineNumber();
|
||||||
|
while (dir_line < curr_line && dir_line != -1)
|
||||||
|
{
|
||||||
|
SgStatement* dir = dvm_dirs[dir_pos];
|
||||||
|
if (dir->variant() == DVM_PARALLEL_ON_DIR)
|
||||||
|
{
|
||||||
|
vector<SgStatement*> rems;
|
||||||
|
vector<string> addS;
|
||||||
|
|
||||||
|
SgStatement* tmp0 = new SgAssignStmt(*new SgVarRefExp(*new SgSymbol(VARIABLE_NAME, "tmp0")), *dir->expr(0));
|
||||||
|
SgStatement* tmp2 = new SgAssignStmt(*new SgVarRefExp(*new SgSymbol(VARIABLE_NAME, "tmp2")), *dir->expr(2));
|
||||||
|
|
||||||
|
SgExpression* list = dir->expr(1);
|
||||||
|
while (list)
|
||||||
|
{
|
||||||
|
SgExpression* item = list->lhs();
|
||||||
|
if (item->variant() != REMOTE_ACCESS_OP)
|
||||||
|
{
|
||||||
|
string s = item->unparse();
|
||||||
|
convertToLower(s);
|
||||||
|
addS.push_back(s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rems.push_back(new SgAssignStmt(*new SgVarRefExp(*new SgSymbol(VARIABLE_NAME, "tmp1")), *item->lhs()));
|
||||||
|
list = list->rhs();
|
||||||
|
}
|
||||||
|
|
||||||
|
SgCExpStmt* conv0 = (SgCExpStmt*)Translate_Fortran_To_C(tmp0, true);
|
||||||
|
SgCExpStmt* conv2 = (SgCExpStmt*)Translate_Fortran_To_C(tmp2, true);
|
||||||
|
|
||||||
|
Set_Function_Language(C_LANG);
|
||||||
|
string array = conv0->expr()->rhs()->unparse();
|
||||||
|
string rule = conv2->expr()->rhs()->unparse();
|
||||||
|
|
||||||
|
for (auto& conv : rems)
|
||||||
|
{
|
||||||
|
SgCExpStmt* convE = (SgCExpStmt*)Translate_Fortran_To_C(conv, true);
|
||||||
|
string s = convE->expr()->rhs()->unparse();
|
||||||
|
convertToLower(s);
|
||||||
|
addS.push_back(string("remote_access(") + s + ")");
|
||||||
|
}
|
||||||
|
Unset_Function_Language();
|
||||||
|
|
||||||
|
char buf[1024];
|
||||||
|
sprintf(buf, "#pragma dvm parallel([%s] on %s) ", rule.c_str(), array.c_str());
|
||||||
|
string pragma = buf;
|
||||||
|
|
||||||
|
for (int z = 0; z < addS.size(); ++z)
|
||||||
|
{
|
||||||
|
pragma += addS[z];
|
||||||
|
if (z != addS.size() - 1)
|
||||||
|
pragma += ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvm_comm.size())
|
||||||
|
dvm_comm += "\n";
|
||||||
|
dvm_comm += pragma;
|
||||||
|
}
|
||||||
|
else if (dir->variant() == ACC_END_REGION_DIR)
|
||||||
|
{
|
||||||
|
if (dvm_comm.size())
|
||||||
|
dvm_comm += "\n";
|
||||||
|
dvm_comm += " }";
|
||||||
|
}
|
||||||
|
else if (dir->variant() == ACC_REGION_DIR)
|
||||||
|
{
|
||||||
|
if (dvm_comm.size())
|
||||||
|
dvm_comm += "\n";
|
||||||
|
|
||||||
|
string type = "";
|
||||||
|
if (dir->expr(0))
|
||||||
|
{
|
||||||
|
type = dir->expr(0)->unparse();
|
||||||
|
convertToLower(type);
|
||||||
|
}
|
||||||
|
dvm_comm += string("#pragma dvm region ") + type + "\n";
|
||||||
|
dvm_comm += " {";
|
||||||
|
}
|
||||||
|
else if (dir->variant() == ACC_GET_ACTUAL_DIR)
|
||||||
|
{
|
||||||
|
if (dvm_comm.size())
|
||||||
|
dvm_comm += "\n";
|
||||||
|
|
||||||
|
SgStatement* tmp0 = new SgAssignStmt(*new SgVarRefExp(*new SgSymbol(VARIABLE_NAME, "tmp0")), *dir->expr(0));
|
||||||
|
SgCExpStmt* conv0 = (SgCExpStmt*)Translate_Fortran_To_C(tmp0, true);
|
||||||
|
|
||||||
|
Set_Function_Language(C_LANG);
|
||||||
|
string array = conv0->expr()->rhs()->unparse();
|
||||||
|
Unset_Function_Language();
|
||||||
|
|
||||||
|
dvm_comm += "#pragma dvm get_actual(" + array + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
dir_pos++;
|
||||||
|
dir_line = (dir_pos < dvm_dirs.size()) ? dvm_dirs[dir_pos]->lineNumber() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSgExecutableStatement(st))
|
||||||
|
{
|
||||||
|
SgStatement* conv = Translate_Fortran_To_C(st, true);
|
||||||
|
if (st->comments())
|
||||||
|
{
|
||||||
|
string str(st->comments());
|
||||||
|
vector<string> result;
|
||||||
|
splitString(str, '\n', result);
|
||||||
|
str = "";
|
||||||
|
for (int z = 0; z < result.size(); ++z)
|
||||||
|
{
|
||||||
|
str += "//" + result[z].substr(1, result[z].size());
|
||||||
|
if (z != result.size() - 1)
|
||||||
|
str += "\n";
|
||||||
|
}
|
||||||
|
conv->addComment(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvm_comm.size())
|
||||||
|
{
|
||||||
|
conv->addComment(dvm_comm.c_str());
|
||||||
|
dvm_comm.clear();
|
||||||
|
}
|
||||||
|
lastOfFunc->insertStmtBefore(*conv, *func);
|
||||||
|
//printf("on line %d\n%s\n", st->lineNumber(), conv->unparse(C_LANG));
|
||||||
|
st = st->lastNodeOfStmt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
funcs[i]->extractStmt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*string includes;
|
||||||
|
includes += "#include <math.h>\n";
|
||||||
|
includes += "#include <stdlib.h>\n";
|
||||||
|
includes += "#include <stdio.h>\n";
|
||||||
|
|
||||||
|
global->addComment(includes.c_str());*/
|
||||||
|
|
||||||
|
FILE* file_out = fopen((OnlyName(file->filename()) + ".cdv").c_str(), "w");
|
||||||
|
fprintf(file_out, "%s\n", global->unparse(C_LANG));
|
||||||
|
fclose(file_out);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "../Utils/errors.h"
|
#include "../Utils/errors.h"
|
||||||
#include "../Utils/SgUtils.h"
|
#include "../Utils/SgUtils.h"
|
||||||
#include "../Utils/utils.h"
|
#include "../Utils/utils.h"
|
||||||
|
#include "../ExpressionTransform/expr_transform.h"
|
||||||
|
|
||||||
using std::make_pair;
|
using std::make_pair;
|
||||||
using std::map;
|
using std::map;
|
||||||
@@ -21,6 +22,13 @@ struct FixedSubscript {
|
|||||||
int value;
|
int value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// RegularExpr represents expressions like ( coefA * I + coefB ),
|
||||||
|
// where I is a variable and coefA or coefB can be equal to zero
|
||||||
|
struct RegularExpr {
|
||||||
|
int coefA;
|
||||||
|
int coefB;
|
||||||
|
};
|
||||||
|
|
||||||
// DefUseStmtsPair represents pair of DEF and USE statements for private variable
|
// DefUseStmtsPair represents pair of DEF and USE statements for private variable
|
||||||
using DefUseStmtsPair = pair<SgAssignStmt*, SgStatement*>;
|
using DefUseStmtsPair = pair<SgAssignStmt*, SgStatement*>;
|
||||||
|
|
||||||
@@ -28,21 +36,6 @@ using DefUseStmtsPair = pair<SgAssignStmt*, SgStatement*>;
|
|||||||
// used in PRIVATE_REMOVING pass - private vars that can be removed
|
// used in PRIVATE_REMOVING pass - private vars that can be removed
|
||||||
static vector<PrivateToRemove> privatesToRemoveGlobal;
|
static vector<PrivateToRemove> privatesToRemoveGlobal;
|
||||||
|
|
||||||
// Context stores general info about current loop and array to remove
|
|
||||||
struct Context {
|
|
||||||
const map<string, vector<FuncInfo*>>& allFuncInfo;
|
|
||||||
const map<string, CommonBlock*>& commonBlocks;
|
|
||||||
vector<Messages>& messages;
|
|
||||||
|
|
||||||
LoopGraph* loop;
|
|
||||||
SgForStmt* loopStmt;
|
|
||||||
SgSymbol* arraySymbol;
|
|
||||||
int dimensionsNum;
|
|
||||||
// string arrayName; // TODO: <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> arraySym <20><> arrayName
|
|
||||||
vector<SgArrayRefExp*> explicitArrayRefs;
|
|
||||||
vector<bool> fixedDimensionsMask;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ******************************* *
|
/* ******************************* *
|
||||||
* Block of common used functions: *
|
* Block of common used functions: *
|
||||||
@@ -64,7 +57,7 @@ static void fillDirectArrayRefs(SgExpression* exp, SgSymbol* arraySym, vector<Sg
|
|||||||
fillDirectArrayRefs(exp->rhs(), arraySym, refs);
|
fillDirectArrayRefs(exp->rhs(), arraySym, refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// getDirectArrayRefs returns all direct arraySym references in stmt,
|
// getDirectArrayRefs returns all direct arraySym references in compound stmt,
|
||||||
// except VAR_DECL statements
|
// except VAR_DECL statements
|
||||||
static vector<SgArrayRefExp*> getDirectArrayRefs(SgStatement* stmt, SgSymbol* arraySym)
|
static vector<SgArrayRefExp*> getDirectArrayRefs(SgStatement* stmt, SgSymbol* arraySym)
|
||||||
{
|
{
|
||||||
@@ -88,6 +81,22 @@ static vector<SgArrayRefExp*> getDirectArrayRefs(SgStatement* stmt, SgSymbol* ar
|
|||||||
return arrayRefs;
|
return arrayRefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getDirectArrayRefs returns all direct arraySym references in single stmt,
|
||||||
|
// except VAR_DECL statements
|
||||||
|
static vector<SgArrayRefExp*> getDirectArrayRefsFromSingleStmt(SgStatement* stmt, SgSymbol* arraySym)
|
||||||
|
{
|
||||||
|
vector<SgArrayRefExp*> arrayRefs;
|
||||||
|
if (stmt == nullptr)
|
||||||
|
return arrayRefs;
|
||||||
|
|
||||||
|
if (stmt->variant() != VAR_DECL && stmt->variant() != VAR_DECL_90) // skip var declaration stmt
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
fillDirectArrayRefs(stmt->expr(i), arraySym, arrayRefs);
|
||||||
|
|
||||||
|
|
||||||
|
return arrayRefs;
|
||||||
|
}
|
||||||
|
|
||||||
static bool isArrayRefInVector(SgArrayRefExp* ref, const vector<SgArrayRefExp*>& arrayRefs)
|
static bool isArrayRefInVector(SgArrayRefExp* ref, const vector<SgArrayRefExp*>& arrayRefs)
|
||||||
{
|
{
|
||||||
for (SgArrayRefExp* arrayRef : arrayRefs)
|
for (SgArrayRefExp* arrayRef : arrayRefs)
|
||||||
@@ -97,28 +106,97 @@ static bool isArrayRefInVector(SgArrayRefExp* ref, const vector<SgArrayRefExp*>&
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkAndFillRegularExpr checks if expr is regular and fills regularExpr struct
|
||||||
|
// with info about expr
|
||||||
|
static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr, SgSymbol* iterationVar)
|
||||||
|
{
|
||||||
|
pair<int, int> retCoefs;
|
||||||
|
getCoefsOfSubscript(retCoefs, expr, iterationVar);
|
||||||
|
|
||||||
|
regularExpr.coefA = retCoefs.first;
|
||||||
|
regularExpr.coefB = retCoefs.second;
|
||||||
|
|
||||||
|
if (retCoefs.first != 0 || retCoefs.second != 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// check if expr is like ( 0 ), because we cannot separate zero const int expr from incorrect expr:
|
||||||
|
if (expr->variant() == INT_VAL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// getShortFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef
|
// getShortFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef
|
||||||
static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef,
|
static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef,
|
||||||
const vector<bool>& fixedDimensions)
|
const vector<bool>& fixedDimensionsMask,
|
||||||
|
Regime regime, vector<SgSymbol*> iterationVars)
|
||||||
|
{
|
||||||
|
if (regime == Regime::DEFLT)
|
||||||
{
|
{
|
||||||
vector<int> subscriptsVector;
|
vector<int> subscriptsVector;
|
||||||
for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i)
|
for (int i = 0; i < fixedDimensionsMask.size(); ++i)
|
||||||
if (fixedDimensions[i])
|
if (fixedDimensionsMask[i])
|
||||||
subscriptsVector.push_back(arrayRef->subscript(i)->valueInteger());
|
subscriptsVector.push_back(arrayRef->subscript(i)->valueInteger());
|
||||||
|
|
||||||
return subscriptsVector;
|
return subscriptsVector;
|
||||||
}
|
}
|
||||||
|
else if (regime == Regime::REGULAR_INDEXES)
|
||||||
|
{
|
||||||
|
vector<int> subscriptsVector;
|
||||||
|
SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs();
|
||||||
|
if (iterationVars.size() < indexExprList->length())
|
||||||
|
return vector<int>{};
|
||||||
|
|
||||||
|
for (int i = 0; i < indexExprList->length(); ++i)
|
||||||
|
{
|
||||||
|
SgExpression* indexExpr = indexExprList->elem(i);
|
||||||
|
RegularExpr regularExpr;
|
||||||
|
if (!checkAndFillRegularExpr(indexExpr, regularExpr, iterationVars[i]))
|
||||||
|
return vector<int>{};
|
||||||
|
|
||||||
|
subscriptsVector.push_back(regularExpr.coefA);
|
||||||
|
subscriptsVector.push_back(regularExpr.coefB);
|
||||||
|
}
|
||||||
|
|
||||||
|
return subscriptsVector;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vector<int>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, const PrivateToRemove& varToRemove)
|
||||||
|
{
|
||||||
|
vector<SgSymbol*> iterationVars;
|
||||||
|
if (varToRemove.regime == Regime::REGULAR_INDEXES)
|
||||||
|
{
|
||||||
|
auto vars = varToRemove.arrayRefToIterationVarsMap.find(arrayRef);
|
||||||
|
if (vars != varToRemove.arrayRefToIterationVarsMap.end())
|
||||||
|
iterationVars = vars->second;
|
||||||
|
}
|
||||||
|
return getShortFixedSubscriptsVector(arrayRef, varToRemove.fixedDimensions,
|
||||||
|
varToRemove.regime, iterationVars);
|
||||||
|
}
|
||||||
|
|
||||||
// removeDuplicateArrayRefs returns unique array refereces in fixed dimensions
|
// removeDuplicateArrayRefs returns unique array refereces in fixed dimensions
|
||||||
static vector<SgArrayRefExp*> removeDuplicateArrayRefs(const vector<SgArrayRefExp*>& arrayRefs,
|
static vector<SgArrayRefExp*> removeDuplicateArrayRefs(const vector<SgArrayRefExp*>& arrayRefs,
|
||||||
const vector<bool>& fixedDimensions)
|
const vector<bool>& fixedDimensionsMask,
|
||||||
|
Regime regime,
|
||||||
|
const map<SgArrayRefExp*, vector<SgSymbol*>>& arrayRefToIterVarsMap)
|
||||||
{
|
{
|
||||||
map<vector<int>, SgArrayRefExp*> uniqueRefs;
|
map<vector<int>, SgArrayRefExp*> uniqueRefs;
|
||||||
for (SgArrayRefExp* ref : arrayRefs)
|
for (SgArrayRefExp* arrayRef : arrayRefs)
|
||||||
{
|
{
|
||||||
vector<int> subscripts = getShortFixedSubscriptsVector(ref, fixedDimensions);
|
vector<SgSymbol*> iterationVars;
|
||||||
|
if (regime == Regime::REGULAR_INDEXES)
|
||||||
|
{
|
||||||
|
auto vars = arrayRefToIterVarsMap.find(arrayRef);
|
||||||
|
if (vars != arrayRefToIterVarsMap.end())
|
||||||
|
iterationVars = vars->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<int> subscripts = getShortFixedSubscriptsVector(arrayRef, fixedDimensionsMask, regime, iterationVars);
|
||||||
if (uniqueRefs.find(subscripts) == uniqueRefs.end())
|
if (uniqueRefs.find(subscripts) == uniqueRefs.end())
|
||||||
uniqueRefs.insert(make_pair(subscripts, ref));
|
uniqueRefs.insert(make_pair(subscripts, arrayRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<SgArrayRefExp*> result;
|
vector<SgArrayRefExp*> result;
|
||||||
@@ -274,11 +352,13 @@ static void addMessageUsageInFunctionCall(vector<Messages>& messages, string var
|
|||||||
|
|
||||||
// getDimensionVarName returns var name in style A(1, 2, *)
|
// getDimensionVarName returns var name in style A(1, 2, *)
|
||||||
static string getDimensionVarName(SgSymbol* var, const vector<int>& subscripts,
|
static string getDimensionVarName(SgSymbol* var, const vector<int>& subscripts,
|
||||||
const vector<bool>& fixedDimensions)
|
const vector<bool>& fixedDimensions, Regime regime)
|
||||||
{
|
{
|
||||||
string result = var->identifier();
|
string result = var->identifier();
|
||||||
|
|
||||||
result += "(";
|
result += "(";
|
||||||
|
if (regime == Regime::DEFLT)
|
||||||
|
{
|
||||||
for (int i = 0; i < fixedDimensions.size(); ++i)
|
for (int i = 0; i < fixedDimensions.size(); ++i)
|
||||||
{
|
{
|
||||||
if (fixedDimensions[i])
|
if (fixedDimensions[i])
|
||||||
@@ -289,6 +369,36 @@ static string getDimensionVarName(SgSymbol* var, const vector<int>& subscripts,
|
|||||||
if (i != fixedDimensions.size() - 1)
|
if (i != fixedDimensions.size() - 1)
|
||||||
result += ", ";
|
result += ", ";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (regime == Regime::REGULAR_INDEXES)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < subscripts.size(); i += 2) {
|
||||||
|
if (subscripts[i] == 0 && subscripts[(size_t)i + 1] == 0)
|
||||||
|
result += "0";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (subscripts[i] != 0)
|
||||||
|
{
|
||||||
|
if (subscripts[i] != 1)
|
||||||
|
result += "I_" + std::to_string(i / 2 + 1);
|
||||||
|
else
|
||||||
|
result += std::to_string(subscripts[i]) + " * I_" + std::to_string(i / 2 + 1);
|
||||||
|
|
||||||
|
if (subscripts[(size_t)i + 1] > 0)
|
||||||
|
result += " + ";
|
||||||
|
else if (subscripts[(size_t)i + 1] < 0)
|
||||||
|
result += " - ";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (subscripts[(size_t)i + 1] != 0)
|
||||||
|
result += std::to_string(std::abs(subscripts[(size_t)i + 1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != subscripts.size() - 2)
|
||||||
|
result += ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
result += ")";
|
result += ")";
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -358,9 +468,7 @@ static SgExpression* substituteExpressions(SgExpression* exp,
|
|||||||
if (exp->variant() == ARRAY_REF)
|
if (exp->variant() == ARRAY_REF)
|
||||||
{
|
{
|
||||||
const auto& refToExp = refToExpMap.find(exp->unparse());
|
const auto& refToExp = refToExpMap.find(exp->unparse());
|
||||||
if (refToExp == refToExpMap.end())
|
if (refToExp != refToExpMap.end())
|
||||||
return exp;
|
|
||||||
|
|
||||||
return refToExp->second;
|
return refToExp->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,6 +494,17 @@ static bool isVarReadInLoop(SgSymbol* var, SgForStmt* loopStmt)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isVarChangedBetween checks if the var is changed between first and second statement
|
||||||
|
// by assignment to var (it doesn't check if the var is indirectly or implicitly by function call)
|
||||||
|
static bool isVarChangedBetween(string var, SgStatement* first, SgStatement* second)
|
||||||
|
{
|
||||||
|
for (SgStatement* st = first->lexNext(); st != second; st = st->lexNext())
|
||||||
|
if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol()->identifier() == var)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// removeDeadCodeFromLoop removes assign statements to private scalar vars which are not read in loop
|
// removeDeadCodeFromLoop removes assign statements to private scalar vars which are not read in loop
|
||||||
static void removeDeadCodeFromLoop(LoopGraph* loop)
|
static void removeDeadCodeFromLoop(LoopGraph* loop)
|
||||||
{
|
{
|
||||||
@@ -421,7 +540,7 @@ static void removeDeadCodeFromLoop(LoopGraph* loop)
|
|||||||
|
|
||||||
// fillReadShortFixedSumscripts fills all short fixed subscripts vectors of array var,
|
// fillReadShortFixedSumscripts fills all short fixed subscripts vectors of array var,
|
||||||
// which are used for reading from array var in exp
|
// which are used for reading from array var in exp
|
||||||
static void fillReadShortFixedSumscripts(SgExpression* exp, const PrivateToRemove& var,
|
static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemove& var,
|
||||||
set<vector<int>>& fixedSubscripts)
|
set<vector<int>>& fixedSubscripts)
|
||||||
{
|
{
|
||||||
if (exp == nullptr)
|
if (exp == nullptr)
|
||||||
@@ -431,19 +550,19 @@ static void fillReadShortFixedSumscripts(SgExpression* exp, const PrivateToRemov
|
|||||||
{
|
{
|
||||||
if (isEqSymbols(exp->symbol(), var.varSymbol))
|
if (isEqSymbols(exp->symbol(), var.varSymbol))
|
||||||
{
|
{
|
||||||
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var.fixedDimensions);
|
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var);
|
||||||
fixedSubscripts.insert(subscripts);
|
fixedSubscripts.insert(subscripts);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fillReadShortFixedSumscripts(exp->lhs(), var, fixedSubscripts);
|
fillReadShortFixedSubscripts(exp->lhs(), var, fixedSubscripts);
|
||||||
fillReadShortFixedSumscripts(exp->rhs(), var, fixedSubscripts);
|
fillReadShortFixedSubscripts(exp->rhs(), var, fixedSubscripts);
|
||||||
}
|
}
|
||||||
|
|
||||||
// getReadShortFixedSumscripts return set of all short fixed subscripts vectors of array var from loop,
|
// getReadShortFixedSubscripts return set of all short fixed subscripts vectors of array var from loop,
|
||||||
// which are used for reading from array var
|
// which are used for reading from array var
|
||||||
static set<vector<int>> getReadShortFixedSumscripts(const PrivateToRemove& var, SgForStmt* loopStmt)
|
static set<vector<int>> getReadShortFixedSubscripts(const PrivateToRemove& var, SgForStmt* loopStmt)
|
||||||
{
|
{
|
||||||
set<vector<int>> fixedSubscripts;
|
set<vector<int>> fixedSubscripts;
|
||||||
for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext())
|
for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext())
|
||||||
@@ -453,7 +572,7 @@ static set<vector<int>> getReadShortFixedSumscripts(const PrivateToRemove& var,
|
|||||||
i = 1;
|
i = 1;
|
||||||
|
|
||||||
for (; i < 3; ++i)
|
for (; i < 3; ++i)
|
||||||
fillReadShortFixedSumscripts(st->expr(i), var, fixedSubscripts);
|
fillReadShortFixedSubscripts(st->expr(i), var, fixedSubscripts);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fixedSubscripts;
|
return fixedSubscripts;
|
||||||
@@ -464,7 +583,7 @@ static set<vector<int>> getReadShortFixedSumscripts(const PrivateToRemove& var,
|
|||||||
static void removeExcessiveDefs(const PrivateToRemove& var)
|
static void removeExcessiveDefs(const PrivateToRemove& var)
|
||||||
{
|
{
|
||||||
SgForStmt* loopStmt = (SgForStmt*)var.loop->loop->GetOriginal();
|
SgForStmt* loopStmt = (SgForStmt*)var.loop->loop->GetOriginal();
|
||||||
set<vector<int>> usedFixedSubscripts = getReadShortFixedSumscripts(var, loopStmt);
|
set<vector<int>> usedFixedSubscripts = getReadShortFixedSubscripts(var, loopStmt);
|
||||||
|
|
||||||
vector<SgStatement*> stmtsToRemove;
|
vector<SgStatement*> stmtsToRemove;
|
||||||
for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext())
|
for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext())
|
||||||
@@ -475,7 +594,7 @@ static void removeExcessiveDefs(const PrivateToRemove& var)
|
|||||||
if (st->expr(0)->symbol() == nullptr || !isEqSymbols(st->expr(0)->symbol(), var.varSymbol))
|
if (st->expr(0)->symbol() == nullptr || !isEqSymbols(st->expr(0)->symbol(), var.varSymbol))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*) st->expr(0), var.fixedDimensions);
|
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*) st->expr(0), var);
|
||||||
if (usedFixedSubscripts.find(subscripts) == usedFixedSubscripts.end())
|
if (usedFixedSubscripts.find(subscripts) == usedFixedSubscripts.end())
|
||||||
stmtsToRemove.push_back(st);
|
stmtsToRemove.push_back(st);
|
||||||
}
|
}
|
||||||
@@ -576,7 +695,7 @@ static set<vector<int>> removeArray(string filename, const PrivateToRemove& arra
|
|||||||
SgStatement* useStmt = defUsePair.second;
|
SgStatement* useStmt = defUsePair.second;
|
||||||
|
|
||||||
SgArrayRefExp* defRef = (SgArrayRefExp*)defStmt->lhs();
|
SgArrayRefExp* defRef = (SgArrayRefExp*)defStmt->lhs();
|
||||||
vector<int> defFixedSubscripts = getShortFixedSubscriptsVector(defRef, fixedDimensions);
|
vector<int> defFixedSubscripts = getShortFixedSubscriptsVector(defRef, arrayToRemove);
|
||||||
|
|
||||||
int startIndex = 0;
|
int startIndex = 0;
|
||||||
if (useStmt->variant() == ASSIGN_STAT)
|
if (useStmt->variant() == ASSIGN_STAT)
|
||||||
@@ -591,7 +710,7 @@ static set<vector<int>> removeArray(string filename, const PrivateToRemove& arra
|
|||||||
|
|
||||||
for (SgArrayRefExp* useRef : arrayUseRefs)
|
for (SgArrayRefExp* useRef : arrayUseRefs)
|
||||||
{
|
{
|
||||||
vector<int> useFixedSubscripts = getShortFixedSubscriptsVector(useRef, fixedDimensions);
|
vector<int> useFixedSubscripts = getShortFixedSubscriptsVector(useRef, arrayToRemove);
|
||||||
if (defFixedSubscripts != useFixedSubscripts)
|
if (defFixedSubscripts != useFixedSubscripts)
|
||||||
continue; // because useRef and defRef can be different in subscripts of fixed dimensions
|
continue; // because useRef and defRef can be different in subscripts of fixed dimensions
|
||||||
|
|
||||||
@@ -626,7 +745,7 @@ void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransf
|
|||||||
auto removedDimensions = removeArray(file->filename(), varToRemove);
|
auto removedDimensions = removeArray(file->filename(), varToRemove);
|
||||||
countOfTransform++;
|
countOfTransform++;
|
||||||
|
|
||||||
removeDeadCodeFromLoop(varToRemove.loop);
|
//removeDeadCodeFromLoop(varToRemove.loop); // TODO: problem with reverting substitution
|
||||||
removeExcessiveDefs(varToRemove);
|
removeExcessiveDefs(varToRemove);
|
||||||
removeEmptyLoops(varToRemove.loop, messages);
|
removeEmptyLoops(varToRemove.loop, messages);
|
||||||
|
|
||||||
@@ -642,13 +761,15 @@ void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransf
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions);
|
varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions, varToRemove.regime,
|
||||||
|
varToRemove.arrayRefToIterationVarsMap);
|
||||||
for (auto& varRef : varRefs)
|
for (auto& varRef : varRefs)
|
||||||
{
|
{
|
||||||
vector<int> subscripts = getShortFixedSubscriptsVector(varRef, fixedDimensions);
|
vector<int> subscripts = getShortFixedSubscriptsVector(varRef, varToRemove);
|
||||||
if (removedDimensions.find(subscripts) != removedDimensions.end())
|
if (removedDimensions.find(subscripts) != removedDimensions.end())
|
||||||
{
|
{
|
||||||
varName = getDimensionVarName(varToRemove.varSymbol, subscripts, fixedDimensions);
|
varName = getDimensionVarName(varToRemove.varSymbol, subscripts,
|
||||||
|
fixedDimensions, varToRemove.regime);
|
||||||
addMessageRemovePrivateVarPart(messages, varName, loopLineNum);
|
addMessageRemovePrivateVarPart(messages, varName, loopLineNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,8 +778,9 @@ void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransf
|
|||||||
|
|
||||||
for (auto& removedDimension : removedDimensions)
|
for (auto& removedDimension : removedDimensions)
|
||||||
{
|
{
|
||||||
varName = getDimensionVarName(varToRemove.varSymbol, removedDimension, fixedDimensions);
|
varName = getDimensionVarName(varToRemove.varSymbol, removedDimension,
|
||||||
addMessageRemovePrivateVar(messages, varName, loopLineNum);
|
fixedDimensions, varToRemove.regime);
|
||||||
|
addMessageRemovePrivateVarPart(messages, varName, loopLineNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -673,9 +795,25 @@ void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransf
|
|||||||
* PRIVATE_REMOVING_ANALYSIS block of functions: *
|
* PRIVATE_REMOVING_ANALYSIS block of functions: *
|
||||||
* ********************************************* */
|
* ********************************************* */
|
||||||
|
|
||||||
|
// Context stores general info about current loop and array to remove
|
||||||
|
struct Context {
|
||||||
|
const map<string, vector<FuncInfo*>>& allFuncInfo;
|
||||||
|
const map<string, CommonBlock*>& commonBlocks;
|
||||||
|
vector<Messages>& messages;
|
||||||
|
|
||||||
|
Regime regime;
|
||||||
|
LoopGraph* loop;
|
||||||
|
SgForStmt* loopStmt;
|
||||||
|
SgSymbol* arraySymbol;
|
||||||
|
int dimensionsNum;
|
||||||
|
vector<SgArrayRefExp*> explicitArrayRefs;
|
||||||
|
vector<bool> fixedDimensionsMask;
|
||||||
|
map<SgArrayRefExp*, vector<SgSymbol*>> arrayRefToIterationVarsMap;
|
||||||
|
};
|
||||||
|
|
||||||
// ReducedArrayVars represents mapping of array reference to reduced scalar var:
|
// ReducedArrayVars represents mapping of array reference to reduced scalar var:
|
||||||
// arr(1, i) -> pair<vector<int>, SgSymbol*>: [1], arr_1
|
// arr(1, i) -> pair<vector<int>, SgSymbol*>: [1], arr_1
|
||||||
class ReducedArrayVars {
|
class ReducedArrayVarsMap {
|
||||||
map<vector<int>, SgSymbol*> arrayMap;
|
map<vector<int>, SgSymbol*> arrayMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -735,6 +873,33 @@ static vector<InsertedStatement>::const_iterator findInsertedStmt(const vector<I
|
|||||||
return insertedStmts.end();
|
return insertedStmts.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static vector<int> getShortFixedSubscriptsVector(Context* ctx, SgArrayRefExp* arrayRef)
|
||||||
|
{
|
||||||
|
vector<SgSymbol*> iterationVars;
|
||||||
|
if (ctx->regime == Regime::REGULAR_INDEXES)
|
||||||
|
{
|
||||||
|
auto vars = ctx->arrayRefToIterationVarsMap.find(arrayRef);
|
||||||
|
if (vars != ctx->arrayRefToIterationVarsMap.end())
|
||||||
|
iterationVars = vars->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime, iterationVars);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fillIterationVariables fill vars set with iteration variables of all loops
|
||||||
|
// from stmt to outerLoopStmt
|
||||||
|
static void fillIterationVars(SgStatement* stmt, SgStatement* outerLoopStmt, vector<SgSymbol*>& vars)
|
||||||
|
{
|
||||||
|
if (stmt == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (stmt->variant() == FOR_NODE)
|
||||||
|
vars.push_back(((SgForStmt*)stmt)->doName());
|
||||||
|
|
||||||
|
if (stmt->id() != outerLoopStmt->id())
|
||||||
|
fillIterationVars(stmt->controlParent(), outerLoopStmt, vars);
|
||||||
|
}
|
||||||
|
|
||||||
// matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension
|
// matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension
|
||||||
static bool checkFixedDimensionsMaskMatching(Context* ctx)
|
static bool checkFixedDimensionsMaskMatching(Context* ctx)
|
||||||
{
|
{
|
||||||
@@ -750,13 +915,14 @@ static bool checkFixedDimensionsMaskMatching(Context* ctx)
|
|||||||
// and VAR_REF in non-fixed dimensions
|
// and VAR_REF in non-fixed dimensions
|
||||||
static bool checkDefStmtRefsMatchesMask(Context* ctx)
|
static bool checkDefStmtRefsMatchesMask(Context* ctx)
|
||||||
{
|
{
|
||||||
// TODO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD> VAR_REF - <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> a * i + b, <20><> i <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext())
|
for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext())
|
||||||
{
|
{
|
||||||
if (st->variant() != ASSIGN_STAT)
|
if (st->variant() != ASSIGN_STAT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
vector<SgSymbol*> iterationVars;
|
||||||
|
fillIterationVars(st, ctx->loopStmt, iterationVars);
|
||||||
|
|
||||||
if (isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol)) // DEF statement
|
if (isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol)) // DEF statement
|
||||||
{
|
{
|
||||||
SgArrayRefExp* ref = (SgArrayRefExp*)st->expr(0);
|
SgArrayRefExp* ref = (SgArrayRefExp*)st->expr(0);
|
||||||
@@ -764,8 +930,19 @@ static bool checkDefStmtRefsMatchesMask(Context* ctx)
|
|||||||
{
|
{
|
||||||
if (ctx->fixedDimensionsMask[i] && ref->subscript(i)->variant() == INT_VAL)
|
if (ctx->fixedDimensionsMask[i] && ref->subscript(i)->variant() == INT_VAL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!ctx->fixedDimensionsMask[i] && ref->subscript(i)->variant() == VAR_REF)
|
if (!ctx->fixedDimensionsMask[i] && ref->subscript(i)->variant() == VAR_REF)
|
||||||
|
{
|
||||||
|
bool isIterationVar = false;
|
||||||
|
for (auto iterationvVar : iterationVars)
|
||||||
|
if (isEqSymbols(ref->subscript(i)->symbol(), iterationvVar))
|
||||||
|
isIterationVar = true;
|
||||||
|
|
||||||
|
if (!isIterationVar)
|
||||||
|
return false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -807,6 +984,45 @@ static string sunparseFixedDimensionsVector(const vector<bool>& fixedDimensions)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool checkRegularIndexRefs(Context* ctx)
|
||||||
|
{
|
||||||
|
vector<SgArrayRefExp*> newArrayRefsVector;
|
||||||
|
for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext())
|
||||||
|
{
|
||||||
|
vector<SgSymbol*> iterationVars;
|
||||||
|
fillIterationVars(st, ctx->loopStmt, iterationVars);
|
||||||
|
|
||||||
|
vector<SgArrayRefExp*> arrayRefs = getDirectArrayRefsFromSingleStmt(st, ctx->arraySymbol);
|
||||||
|
for (auto arrayRef : arrayRefs)
|
||||||
|
{
|
||||||
|
if (!isArrayRefInVector(arrayRef, ctx->explicitArrayRefs))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs();
|
||||||
|
if (iterationVars.size() < indexExprList->length())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < indexExprList->length(); ++i)
|
||||||
|
{
|
||||||
|
SgExpression* indexExpr = indexExprList->elem(i);
|
||||||
|
RegularExpr regularExpr;
|
||||||
|
if (!checkAndFillRegularExpr(indexExpr, regularExpr, iterationVars[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st->variant() == ASSIGN_STAT && isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol))
|
||||||
|
for (auto iterationVar : iterationVars)
|
||||||
|
if (isSymbolInExpression(iterationVar, st->expr(1)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
iterationVars.resize(indexExprList->length());
|
||||||
|
ctx->arrayRefToIterationVarsMap.insert(make_pair(arrayRef, iterationVars));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// getFixedDimensionsMask finds fixed dimensions vector with minimum number of fixed dimensions
|
// getFixedDimensionsMask finds fixed dimensions vector with minimum number of fixed dimensions
|
||||||
// and writes messages if array doesn't have fixed dimensions
|
// and writes messages if array doesn't have fixed dimensions
|
||||||
static vector<bool> getFixedDimensionsMask(Context* ctx)
|
static vector<bool> getFixedDimensionsMask(Context* ctx)
|
||||||
@@ -927,8 +1143,6 @@ static vector<vector<FixedSubscript>> checkImplicitDirectUsage(Context* ctx)
|
|||||||
SgCallStmt* callStmt = (SgCallStmt*)st;
|
SgCallStmt* callStmt = (SgCallStmt*)st;
|
||||||
string procName = callStmt->name()->identifier();
|
string procName = callStmt->name()->identifier();
|
||||||
FuncInfo* funcInfo = findFunc(callStmt->fileName(), procName, ctx->allFuncInfo);
|
FuncInfo* funcInfo = findFunc(callStmt->fileName(), procName, ctx->allFuncInfo);
|
||||||
if (funcInfo == nullptr)
|
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
|
|
||||||
for (int i = 0; i < callStmt->numberOfArgs(); ++i)
|
for (int i = 0; i < callStmt->numberOfArgs(); ++i)
|
||||||
{
|
{
|
||||||
@@ -936,7 +1150,8 @@ static vector<vector<FixedSubscript>> checkImplicitDirectUsage(Context* ctx)
|
|||||||
if (callArg->symbol() == nullptr || !isEqSymbols(callArg->symbol(), ctx->arraySymbol))
|
if (callArg->symbol() == nullptr || !isEqSymbols(callArg->symbol(), ctx->arraySymbol))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (funcInfo->funcParams.isArgOut(i) || // implicit direct usage
|
if (funcInfo == nullptr || // no info about function
|
||||||
|
funcInfo->funcParams.isArgOut(i) || // implicit direct usage
|
||||||
callArg->lhs() == nullptr) // reference to whole array
|
callArg->lhs() == nullptr) // reference to whole array
|
||||||
{
|
{
|
||||||
auto mask = getFixedSubscriptsVector((SgArrayRefExp*)callArg, ctx->dimensionsNum);
|
auto mask = getFixedSubscriptsVector((SgArrayRefExp*)callArg, ctx->dimensionsNum);
|
||||||
@@ -1084,24 +1299,29 @@ static string getReducedArrayVarName(SgSymbol* symbol, const vector<int>& subscr
|
|||||||
|
|
||||||
name.reserve(name.size() + subscripts.size() * 3);
|
name.reserve(name.size() + subscripts.size() * 3);
|
||||||
for (int i : subscripts)
|
for (int i : subscripts)
|
||||||
|
{
|
||||||
|
if (i < 0)
|
||||||
|
name += "_M" + std::to_string((-1) * i);
|
||||||
|
else
|
||||||
name += "_" + std::to_string(i);
|
name += "_" + std::to_string(i);
|
||||||
|
}
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// getReducedArrayVars makes reduced array vars for arrayRefs
|
// getReducedArrayVars makes reduced array vars for arrayRefs
|
||||||
static ReducedArrayVars getReducedArrayVars(Context* ctx)
|
static ReducedArrayVarsMap getReducedArrayVars(Context* ctx)
|
||||||
{
|
{
|
||||||
ReducedArrayVars reducedArrayVars;
|
ReducedArrayVarsMap reducedArrayVars;
|
||||||
|
|
||||||
SgType* type = ctx->explicitArrayRefs[0]->type();
|
SgType* type = ctx->explicitArrayRefs[0]->type();
|
||||||
SgStatement* scope = ctx->loopStmt->getScopeForDeclare();
|
SgStatement* scope = ctx->loopStmt->getScopeForDeclare();
|
||||||
for (SgArrayRefExp* ref : ctx->explicitArrayRefs)
|
for (SgArrayRefExp* arrayRef : ctx->explicitArrayRefs)
|
||||||
{
|
{
|
||||||
vector<int> subscripts = getShortFixedSubscriptsVector(ref, ctx->fixedDimensionsMask);
|
vector<int> subscripts = getShortFixedSubscriptsVector(ctx, arrayRef);
|
||||||
if (reducedArrayVars.find(subscripts) == nullptr)
|
if (reducedArrayVars.find(subscripts) == nullptr)
|
||||||
{
|
{
|
||||||
string name = getReducedArrayVarName(ref->symbol(), subscripts);
|
string name = getReducedArrayVarName(arrayRef->symbol(), subscripts);
|
||||||
|
|
||||||
int nameNumber = checkSymbNameAndCorrect(name + "__", 0);
|
int nameNumber = checkSymbNameAndCorrect(name + "__", 0);
|
||||||
if (nameNumber != 0)
|
if (nameNumber != 0)
|
||||||
@@ -1127,11 +1347,10 @@ static set<string> getVarsToDependOn(SgForStmt* loopStmt, SgSymbol* var)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getDefStmtForReducedArray returns DFE statement for reduced array variable
|
// getDefStmtForReducedArray returns DFE statement for reduced array variable
|
||||||
static InsertedStatement getDefStmtForReducedArray(SgArrayRefExp* arrayRef,
|
static InsertedStatement getDefStmtForReducedArray(Context* ctx, SgArrayRefExp* arrayRef,
|
||||||
const vector<bool>& fixedDimensions,
|
const ReducedArrayVarsMap& reducedArrayVars)
|
||||||
const ReducedArrayVars& reducedArrayVars)
|
|
||||||
{
|
{
|
||||||
vector<int> subscriptVector = getShortFixedSubscriptsVector(arrayRef, fixedDimensions);
|
vector<int> subscriptVector = getShortFixedSubscriptsVector(ctx, arrayRef);
|
||||||
SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector);
|
SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector);
|
||||||
if (reducedVar == nullptr)
|
if (reducedVar == nullptr)
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
@@ -1145,12 +1364,11 @@ static InsertedStatement getDefStmtForReducedArray(SgArrayRefExp* arrayRef,
|
|||||||
|
|
||||||
// getUseStmtForReducedArray returns USE statement for reduced array variable
|
// getUseStmtForReducedArray returns USE statement for reduced array variable
|
||||||
// (assignment to receiverVar)
|
// (assignment to receiverVar)
|
||||||
static InsertedStatement getUseStmtForReducedArray(SgArrayRefExp* arrayRef,
|
static InsertedStatement getUseStmtForReducedArray(Context* ctx, SgArrayRefExp* arrayRef,
|
||||||
const vector<bool>& fixedDimensions,
|
const ReducedArrayVarsMap& reducedArrayVars,
|
||||||
const ReducedArrayVars& reducedArrayVars,
|
|
||||||
SgSymbol* receiverVar)
|
SgSymbol* receiverVar)
|
||||||
{
|
{
|
||||||
vector<int> subscriptVector = getShortFixedSubscriptsVector(arrayRef, fixedDimensions);
|
vector<int> subscriptVector = getShortFixedSubscriptsVector(ctx, arrayRef);
|
||||||
SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector);
|
SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector);
|
||||||
if (reducedVar == nullptr)
|
if (reducedVar == nullptr)
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
@@ -1165,7 +1383,7 @@ static InsertedStatement getUseStmtForReducedArray(SgArrayRefExp* arrayRef,
|
|||||||
// insertReducedArrayVarStmts inserts in loop assignment statements with reduced vars,
|
// insertReducedArrayVarStmts inserts in loop assignment statements with reduced vars,
|
||||||
// returns vector of inserted statements
|
// returns vector of inserted statements
|
||||||
static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx,
|
static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx,
|
||||||
const ReducedArrayVars& reducedArrayVars,
|
const ReducedArrayVarsMap& reducedArrayVars,
|
||||||
SgSymbol* receiverVar)
|
SgSymbol* receiverVar)
|
||||||
{
|
{
|
||||||
vector<InsertedStatement> insertedStmts;
|
vector<InsertedStatement> insertedStmts;
|
||||||
@@ -1182,7 +1400,8 @@ static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx,
|
|||||||
{
|
{
|
||||||
vector<SgArrayRefExp*> arrayRefs;
|
vector<SgArrayRefExp*> arrayRefs;
|
||||||
fillDirectArrayRefs(st->expr(i), ctx->arraySymbol, arrayRefs);
|
fillDirectArrayRefs(st->expr(i), ctx->arraySymbol, arrayRefs);
|
||||||
arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask);
|
arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask, ctx->regime,
|
||||||
|
ctx->arrayRefToIterationVarsMap);
|
||||||
if (!arrayRefs.empty())
|
if (!arrayRefs.empty())
|
||||||
isUseStmt = true;
|
isUseStmt = true;
|
||||||
|
|
||||||
@@ -1191,7 +1410,7 @@ static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx,
|
|||||||
if (!isArrayRefInVector(arrayRef, ctx->explicitArrayRefs))
|
if (!isArrayRefInVector(arrayRef, ctx->explicitArrayRefs))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
InsertedStatement useStmt = getUseStmtForReducedArray(arrayRef, ctx->fixedDimensionsMask,
|
InsertedStatement useStmt = getUseStmtForReducedArray(ctx, arrayRef,
|
||||||
reducedArrayVars, receiverVar);
|
reducedArrayVars, receiverVar);
|
||||||
useStmt.relatedToStmt = st;
|
useStmt.relatedToStmt = st;
|
||||||
st->insertStmtBefore(*useStmt.insertedStmt, *st->controlParent());
|
st->insertStmtBefore(*useStmt.insertedStmt, *st->controlParent());
|
||||||
@@ -1204,8 +1423,8 @@ static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx,
|
|||||||
isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol) && // assignment to array - DEF stmt
|
isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol) && // assignment to array - DEF stmt
|
||||||
isArrayRefInVector((SgArrayRefExp*)st->expr(0), ctx->explicitArrayRefs))
|
isArrayRefInVector((SgArrayRefExp*)st->expr(0), ctx->explicitArrayRefs))
|
||||||
{
|
{
|
||||||
InsertedStatement defStmt = getDefStmtForReducedArray((SgArrayRefExp*)st->expr(0),
|
InsertedStatement defStmt = getDefStmtForReducedArray(ctx, (SgArrayRefExp*)st->expr(0),
|
||||||
ctx->fixedDimensionsMask, reducedArrayVars);
|
reducedArrayVars);
|
||||||
defStmt.relatedToStmt = st;
|
defStmt.relatedToStmt = st;
|
||||||
defStmt.isRecursive = isUseStmt;
|
defStmt.isRecursive = isUseStmt;
|
||||||
st->insertStmtBefore(*defStmt.insertedStmt, *st->controlParent());
|
st->insertStmtBefore(*defStmt.insertedStmt, *st->controlParent());
|
||||||
@@ -1233,6 +1452,7 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
|
|||||||
{
|
{
|
||||||
vector<DefUseStmtsPair> defUsePairs;
|
vector<DefUseStmtsPair> defUsePairs;
|
||||||
|
|
||||||
|
string arrayName = ctx->arraySymbol->identifier();
|
||||||
for (const InsertedStatement& useInsertedStmt : insertedStmts)
|
for (const InsertedStatement& useInsertedStmt : insertedStmts)
|
||||||
{
|
{
|
||||||
if (useInsertedStmt.type != TypeOfInsertedStmt::USE) // analysis for USE stmt
|
if (useInsertedStmt.type != TypeOfInsertedStmt::USE) // analysis for USE stmt
|
||||||
@@ -1248,7 +1468,7 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
|
|||||||
const auto& RD_forUseArg = RD_In.find(useArg);
|
const auto& RD_forUseArg = RD_In.find(useArg);
|
||||||
if (RD_forUseArg == RD_In.end()) // cannot find reaching definitions for argument
|
if (RD_forUseArg == RD_In.end()) // cannot find reaching definitions for argument
|
||||||
{
|
{
|
||||||
addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum);
|
addMessageCannotFindRD(ctx->messages, arrayName, useLineNum);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1275,19 +1495,21 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
|
|||||||
|
|
||||||
if (RD_defArgs.size() == 0) // argument is not initialized
|
if (RD_defArgs.size() == 0) // argument is not initialized
|
||||||
{
|
{
|
||||||
addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum);
|
addMessageCannotFindRD(ctx->messages, arrayName, useLineNum);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RD_defArgs.find(SAPFOR::CFG_VAL::UNINIT) != RD_defArgs.end()) // argument is not initialized
|
SgStatement* defStmt = nullptr;
|
||||||
{
|
|
||||||
bool uninitArgIsOk = false;
|
|
||||||
if (RD_defArgs.size() == 2)
|
|
||||||
{
|
|
||||||
RD_defArgs.erase(SAPFOR::CFG_VAL::UNINIT);
|
|
||||||
int defArgNum = *RD_defArgs.begin();
|
|
||||||
|
|
||||||
auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArgNum);
|
if (RD_defArgs.size() > 1)
|
||||||
|
{
|
||||||
|
bool defIsFound = false;
|
||||||
|
for (int defArg : RD_defArgs) // try to find the real definition from RD_defArgs
|
||||||
|
{
|
||||||
|
if (defArg == SAPFOR::CFG_VAL::UNINIT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArg);
|
||||||
if (defInsAndBlock.first == nullptr)
|
if (defInsAndBlock.first == nullptr)
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
@@ -1295,38 +1517,54 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
|
|||||||
if (defInsertedStmt->relatedToStmt->lineNumber() < useLineNum &&
|
if (defInsertedStmt->relatedToStmt->lineNumber() < useLineNum &&
|
||||||
useInsAndBlock.second->getNumber() == defInsAndBlock.second->getNumber())
|
useInsAndBlock.second->getNumber() == defInsAndBlock.second->getNumber())
|
||||||
{
|
{
|
||||||
uninitArgIsOk = true; // argument isn't really uninitialized
|
defIsFound = true;
|
||||||
|
auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArg);
|
||||||
|
defStmt = defInsAndBlock.first->getOperator();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!uninitArgIsOk)
|
if (!defIsFound)
|
||||||
{
|
{
|
||||||
addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum);
|
// try to find definition not from RD_defArgs:
|
||||||
|
string defVarName = useInsertedStmt.insertedStmt->expr(1)->symbol()->identifier();
|
||||||
|
SgStatement* blockStart = useInsAndBlock.second->getInstructions().front()->getInstruction()->getOperator();
|
||||||
|
SgStatement* blockEnd = useInsAndBlock.second->getInstructions().back()->getInstruction()->getOperator();
|
||||||
|
for (SgStatement* st = blockStart; st != blockEnd; st = st->lexNext())
|
||||||
|
{
|
||||||
|
if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol()->identifier() == defVarName &&
|
||||||
|
!isVarChangedBetween(defVarName, st, useInsertedStmt.insertedStmt))
|
||||||
|
{
|
||||||
|
defIsFound = true;
|
||||||
|
defStmt = st;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!defIsFound)
|
||||||
|
{
|
||||||
|
addMessageCannotFindRD(ctx->messages, arrayName, useLineNum);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (RD_defArgs.size() > 1) // more than one reaching definition
|
|
||||||
{
|
{
|
||||||
addMessageMoreThanOneRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum);
|
auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, *RD_defArgs.begin());
|
||||||
continue;
|
defStmt = defInsAndBlock.first->getOperator();
|
||||||
}
|
}
|
||||||
|
|
||||||
int defArgNum = *RD_defArgs.begin();
|
|
||||||
|
|
||||||
auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArgNum);
|
|
||||||
SgStatement* defStmt = defInsAndBlock.first->getOperator();
|
|
||||||
auto defInsertedStmt = findInsertedStmt(insertedStmts, defStmt);
|
auto defInsertedStmt = findInsertedStmt(insertedStmts, defStmt);
|
||||||
if (defInsertedStmt == insertedStmts.end())
|
if (defInsertedStmt == insertedStmts.end())
|
||||||
{
|
{
|
||||||
addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum);
|
addMessageCannotFindRD(ctx->messages, arrayName, useLineNum);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//don't substitute def stmt into use, if def is recursive
|
//don't substitute def stmt into use, if def is recursive
|
||||||
if (defInsertedStmt->isRecursive)
|
if (defInsertedStmt->isRecursive)
|
||||||
{
|
{
|
||||||
addMessageRecursiveDependency(ctx->messages, ctx->arraySymbol->identifier(), useLineNum);
|
addMessageRecursiveDependency(ctx->messages, arrayName, useLineNum);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1347,18 +1585,6 @@ static SgForStmt* getScopeLoopStmt(SgStatement* stmt)
|
|||||||
return (SgForStmt*)stmt;
|
return (SgForStmt*)stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getDimension(SgSymbol* arraySym)
|
|
||||||
{
|
|
||||||
SgExpression* declExpr = arraySym->makeDeclExpr();
|
|
||||||
if (declExpr == nullptr)
|
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
|
|
||||||
int dimensionNum = ((SgExprListExp*)declExpr->lhs())->length();
|
|
||||||
delete declExpr;
|
|
||||||
|
|
||||||
return dimensionNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
// findChildLoop returns LoopGraph for provided loop statement
|
// findChildLoop returns LoopGraph for provided loop statement
|
||||||
static LoopGraph* findLoop(LoopGraph* outerLoop, SgForStmt* loopStmt)
|
static LoopGraph* findLoop(LoopGraph* outerLoop, SgForStmt* loopStmt)
|
||||||
{
|
{
|
||||||
@@ -1489,20 +1715,6 @@ pair<SAPFOR::Argument*, set<int>> findVarInRDSet(map<SAPFOR::Argument*, set<int>
|
|||||||
return make_pair(nullptr, set<int>{});
|
return make_pair(nullptr, set<int>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
// fillIterationVariables fill vars set with iteration variables of all loops
|
|
||||||
// from stmt to outerLoopStmt
|
|
||||||
static void fillIterationVars(SgStatement *stmt, SgStatement* outerLoopStmt, set<string>& vars)
|
|
||||||
{
|
|
||||||
if (stmt == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (stmt->variant() == FOR_NODE)
|
|
||||||
vars.insert(((SgForStmt*)stmt)->doName()->identifier());
|
|
||||||
|
|
||||||
if (stmt->id() != outerLoopStmt->id())
|
|
||||||
fillIterationVars(stmt->controlParent(), outerLoopStmt, vars);
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkDefUsePair checks if def statement from pair can be substituted into use statement
|
// checkDefUsePair checks if def statement from pair can be substituted into use statement
|
||||||
// and creates messages
|
// and creates messages
|
||||||
static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type& CFGraph)
|
static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type& CFGraph)
|
||||||
@@ -1514,7 +1726,7 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type
|
|||||||
|
|
||||||
vector<pair<string, vector<FixedSubscript>>> dependOnVars;
|
vector<pair<string, vector<FixedSubscript>>> dependOnVars;
|
||||||
SgArrayRefExp* defRef = (SgArrayRefExp*)defUse.first->expr(0);
|
SgArrayRefExp* defRef = (SgArrayRefExp*)defUse.first->expr(0);
|
||||||
vector<SgArrayRefExp*> arrayUseRefs = getDirectArrayRefs(defUse.second, ctx->arraySymbol);
|
vector<SgArrayRefExp*> arrayUseRefs = getDirectArrayRefsFromSingleStmt(defUse.second, ctx->arraySymbol);
|
||||||
for (auto useRef : arrayUseRefs)
|
for (auto useRef : arrayUseRefs)
|
||||||
{
|
{
|
||||||
map<SgSymbol*, SgExpression*> varToExpMap = getVarToExpMap(defRef, useRef, ctx->fixedDimensionsMask);
|
map<SgSymbol*, SgExpression*> varToExpMap = getVarToExpMap(defRef, useRef, ctx->fixedDimensionsMask);
|
||||||
@@ -1524,7 +1736,7 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type
|
|||||||
fillFixedSubscriptsVectorsOfAllVars(expToSubst, dependOnVars);
|
fillFixedSubscriptsVectorsOfAllVars(expToSubst, dependOnVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
set<string> iterationVars{};
|
vector<SgSymbol*> iterationVars{};
|
||||||
fillIterationVars(defUse.second, ctx->loopStmt, iterationVars);
|
fillIterationVars(defUse.second, ctx->loopStmt, iterationVars);
|
||||||
|
|
||||||
auto defInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.first);
|
auto defInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.first);
|
||||||
@@ -1536,7 +1748,17 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type
|
|||||||
if (var.second.size() == 0) // check scalar vars
|
if (var.second.size() == 0) // check scalar vars
|
||||||
{
|
{
|
||||||
// iteration var doesn't obstruct the removing:
|
// iteration var doesn't obstruct the removing:
|
||||||
if (iterationVars.find(var.first) != iterationVars.end())
|
bool isIterationVar = false;
|
||||||
|
for (auto iterationVar : iterationVars)
|
||||||
|
{
|
||||||
|
if (iterationVar->identifier() == var.first)
|
||||||
|
{
|
||||||
|
isIterationVar = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isIterationVar)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto defArg = findVarInRDSet(defRD_In, var.first);
|
auto defArg = findVarInRDSet(defRD_In, var.first);
|
||||||
@@ -1547,6 +1769,10 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type
|
|||||||
if (defArg.second.size() != 1 || useArg.second.size() != 1
|
if (defArg.second.size() != 1 || useArg.second.size() != 1
|
||||||
|| *defArg.second.begin() != *useArg.second.begin())
|
|| *defArg.second.begin() != *useArg.second.begin())
|
||||||
{
|
{
|
||||||
|
if (defInsAndBlock.second->getNumber() == useInsAndBlock.second->getNumber())
|
||||||
|
if (!isVarChangedBetween(var.first, defUse.first, defUse.second))
|
||||||
|
continue;
|
||||||
|
|
||||||
addMessageDependOnNonInvariant(ctx->messages, arrayName,
|
addMessageDependOnNonInvariant(ctx->messages, arrayName,
|
||||||
var.first, defUse.first->lineNumber());
|
var.first, defUse.first->lineNumber());
|
||||||
return false;
|
return false;
|
||||||
@@ -1656,6 +1882,55 @@ static set<SgSymbol*> getPrivateArraysForLoop(LoopGraph* loop, const UsersDirect
|
|||||||
return privateArrays;
|
return privateArrays;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removePrivateAnalyze(Context *ctx)
|
||||||
|
{
|
||||||
|
// inserting assignment to reduced array variables for getting reaching definitions analysis:
|
||||||
|
auto reducedArrayVars = getReducedArrayVars(ctx);
|
||||||
|
SgSymbol* receiverVar = makeTmpVar(ctx);
|
||||||
|
auto insertedStmts = insertReducedArrayVarStmts(ctx, reducedArrayVars, receiverVar);
|
||||||
|
|
||||||
|
// declare reduced array variables and receiver:
|
||||||
|
insertedStmts.push_back(InsertedStatement(
|
||||||
|
TypeOfInsertedStmt::DECLARATION,
|
||||||
|
makeDeclaration(ctx->loopStmt, reducedArrayVars.getAllVars(), nullptr)
|
||||||
|
));
|
||||||
|
insertedStmts.push_back(InsertedStatement(
|
||||||
|
TypeOfInsertedStmt::DECLARATION,
|
||||||
|
makeDeclaration(ctx->loopStmt, vector<SgSymbol*> {receiverVar}, nullptr)
|
||||||
|
));
|
||||||
|
|
||||||
|
CFG_Type CFG_ForFunc = buildCFGforCurrentFunc(ctx->loopStmt,
|
||||||
|
SAPFOR::CFG_Settings(true, true),
|
||||||
|
ctx->commonBlocks, ctx->allFuncInfo);
|
||||||
|
if (CFG_ForFunc.empty())
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
|
auto defUseStmtsPairs = buildDefUsePairs(ctx, CFG_ForFunc, insertedStmts);
|
||||||
|
if (!defUseStmtsPairs.empty()) // DEF-USE pairs were build successfully
|
||||||
|
{
|
||||||
|
vector<DefUseStmtsPair> resultDefUsePairs;
|
||||||
|
for (auto& pair : defUseStmtsPairs)
|
||||||
|
if (checkDefUsePair(ctx, pair, CFG_ForFunc))
|
||||||
|
resultDefUsePairs.push_back(pair);
|
||||||
|
|
||||||
|
PrivateToRemove newPrivateToRemove;
|
||||||
|
newPrivateToRemove.loop = ctx->loop;
|
||||||
|
newPrivateToRemove.varSymbol = ctx->arraySymbol;
|
||||||
|
newPrivateToRemove.regime = ctx->regime;
|
||||||
|
newPrivateToRemove.defUseStmtsPairs.swap(resultDefUsePairs);
|
||||||
|
newPrivateToRemove.fixedDimensions.swap(ctx->fixedDimensionsMask);
|
||||||
|
newPrivateToRemove.arrayRefToIterationVarsMap = ctx->arrayRefToIterationVarsMap;
|
||||||
|
|
||||||
|
privatesToRemoveGlobal.push_back(newPrivateToRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete inserted statements:
|
||||||
|
for (auto& stmt : insertedStmts)
|
||||||
|
stmt.insertedStmt->deleteStmt();
|
||||||
|
|
||||||
|
deleteCFG(CFG_ForFunc);
|
||||||
|
}
|
||||||
|
|
||||||
void removePrivatesAnalysis(vector<LoopGraph*>& loopGraphs,
|
void removePrivatesAnalysis(vector<LoopGraph*>& loopGraphs,
|
||||||
vector<Messages>& messages,
|
vector<Messages>& messages,
|
||||||
const UsersDirectives& usersDirectives,
|
const UsersDirectives& usersDirectives,
|
||||||
@@ -1704,9 +1979,10 @@ void removePrivatesAnalysis(vector<LoopGraph*>& loopGraphs,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
Context context = Context{allFuncInfo, commonBlocks, messages};
|
Context context = Context{allFuncInfo, commonBlocks, messages};
|
||||||
|
context.regime = Regime::DEFLT;
|
||||||
context.loop = loop;
|
context.loop = loop;
|
||||||
context.loopStmt = loopStmt;
|
context.loopStmt = loopStmt;
|
||||||
context.dimensionsNum = getDimension(arrayToRemove);
|
context.dimensionsNum = ((SgArrayType*)arrayToRemove->type())->dimension();
|
||||||
context.arraySymbol = arrayToRemove;
|
context.arraySymbol = arrayToRemove;
|
||||||
|
|
||||||
auto filterMasks = checkImplicitAndIndirectUsage(&context);
|
auto filterMasks = checkImplicitAndIndirectUsage(&context);
|
||||||
@@ -1718,57 +1994,23 @@ void removePrivatesAnalysis(vector<LoopGraph*>& loopGraphs,
|
|||||||
|
|
||||||
context.fixedDimensionsMask = getFixedDimensionsMask(&context);
|
context.fixedDimensionsMask = getFixedDimensionsMask(&context);
|
||||||
|
|
||||||
if (context.fixedDimensionsMask.empty() ||
|
if (!context.fixedDimensionsMask.empty() &&
|
||||||
!checkFixedDimensionsMaskMatching(&context) ||
|
checkFixedDimensionsMaskMatching(&context) &&
|
||||||
!checkDefStmtRefsMatchesMask(&context))
|
checkDefStmtRefsMatchesMask(&context))
|
||||||
{
|
{
|
||||||
|
removePrivateAnalyze(&context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (checkRegularIndexRefs(&context))
|
||||||
|
{
|
||||||
|
context.regime = Regime::REGULAR_INDEXES;
|
||||||
|
context.fixedDimensionsMask = vector<bool>{};
|
||||||
|
removePrivateAnalyze(&context);
|
||||||
|
}
|
||||||
|
else
|
||||||
addMessageDoesNotMatchMask(messages, context.arraySymbol->identifier(), context.loop->lineNum);
|
addMessageDoesNotMatchMask(messages, context.arraySymbol->identifier(), context.loop->lineNum);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// inserting assignment to reduced array variables for getting reaching definitions analysis:
|
|
||||||
auto reducedArrayVars = getReducedArrayVars(&context);
|
|
||||||
SgSymbol* receiverVar = makeTmpVar(&context);
|
|
||||||
auto insertedStmts = insertReducedArrayVarStmts(&context, reducedArrayVars, receiverVar);
|
|
||||||
|
|
||||||
// declare reduced array variables and receiver:
|
|
||||||
insertedStmts.push_back(InsertedStatement(
|
|
||||||
TypeOfInsertedStmt::DECLARATION,
|
|
||||||
makeDeclaration(context.loopStmt, reducedArrayVars.getAllVars(), nullptr)
|
|
||||||
));
|
|
||||||
insertedStmts.push_back(InsertedStatement(
|
|
||||||
TypeOfInsertedStmt::DECLARATION,
|
|
||||||
makeDeclaration(context.loopStmt, vector<SgSymbol*> {receiverVar}, nullptr)
|
|
||||||
));
|
|
||||||
|
|
||||||
CFG_Type CFG_ForFunc = buildCFGforCurrentFunc(context.loopStmt,
|
|
||||||
SAPFOR::CFG_Settings(true, true),
|
|
||||||
commonBlocks, context.allFuncInfo);
|
|
||||||
if (CFG_ForFunc.empty())
|
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
|
|
||||||
auto defUseStmtsPairs = buildDefUsePairs(&context, CFG_ForFunc, insertedStmts);
|
|
||||||
if (!defUseStmtsPairs.empty()) // DEF-USE pairs were build successfully
|
|
||||||
{
|
|
||||||
vector<DefUseStmtsPair> resultDefUsePairs;
|
|
||||||
for (auto& pair : defUseStmtsPairs)
|
|
||||||
if (checkDefUsePair(&context, pair, CFG_ForFunc))
|
|
||||||
resultDefUsePairs.push_back(pair);
|
|
||||||
|
|
||||||
PrivateToRemove newPrivateToRemove;
|
|
||||||
newPrivateToRemove.loop = context.loop;
|
|
||||||
newPrivateToRemove.varSymbol = context.arraySymbol;
|
|
||||||
newPrivateToRemove.defUseStmtsPairs.swap(resultDefUsePairs);
|
|
||||||
newPrivateToRemove.fixedDimensions.swap(context.fixedDimensionsMask);
|
|
||||||
|
|
||||||
privatesToRemoveGlobal.push_back(newPrivateToRemove);
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete inserted statements:
|
|
||||||
for (auto& stmt : insertedStmts)
|
|
||||||
stmt.insertedStmt->deleteStmt();
|
|
||||||
|
|
||||||
deleteCFG(CFG_ForFunc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,19 @@
|
|||||||
#include "../CFGraph/CFGraph.h"
|
#include "../CFGraph/CFGraph.h"
|
||||||
#include "../CFGraph/RD_subst.h"
|
#include "../CFGraph/RD_subst.h"
|
||||||
|
|
||||||
|
// Regime defines the regime of private removing
|
||||||
|
enum class Regime { DEFLT = 1, REGULAR_INDEXES };
|
||||||
|
|
||||||
// PrivateToRemove represents private variable of loop, that can be removed
|
// PrivateToRemove represents private variable of loop, that can be removed
|
||||||
// by substitution of its definition statements (DEF) into usage statements (USE).
|
// by substitution of its definition statements (DEF) into usage statements (USE).
|
||||||
// fixedDimensions is used for comparison of DEF and USE statements
|
// fixedDimensions is used for comparison of DEF and USE statements
|
||||||
struct PrivateToRemove {
|
struct PrivateToRemove {
|
||||||
LoopGraph* loop;
|
LoopGraph* loop;
|
||||||
SgSymbol* varSymbol;
|
SgSymbol* varSymbol;
|
||||||
|
Regime regime;
|
||||||
std::vector<std::pair<SgAssignStmt*, SgStatement*>> defUseStmtsPairs;
|
std::vector<std::pair<SgAssignStmt*, SgStatement*>> defUseStmtsPairs;
|
||||||
std::vector<bool> fixedDimensions;
|
std::vector<bool> fixedDimensions;
|
||||||
|
std::map<SgArrayRefExp*, std::vector<SgSymbol*>> arrayRefToIterationVarsMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
// removePrivates removes all privates from vector privatesToRemoveGloval
|
// removePrivates removes all privates from vector privatesToRemoveGloval
|
||||||
|
|||||||
@@ -2920,6 +2920,7 @@ private:
|
|||||||
ret = pipe(pipes, 1024 * 1024 * 20, O_BINARY); // 20 MB
|
ret = pipe(pipes, 1024 * 1024 * 20, O_BINARY); // 20 MB
|
||||||
#else
|
#else
|
||||||
ret = pipe(pipes) == -1;
|
ret = pipe(pipes) == -1;
|
||||||
|
fcntl(*pipes, F_SETPIPE_SZ, 1024 * 1024 * 20);
|
||||||
#endif
|
#endif
|
||||||
fd_blocked = (errno == EINTR || errno == EBUSY);
|
fd_blocked = (errno == EINTR || errno == EBUSY);
|
||||||
if (fd_blocked)
|
if (fd_blocked)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VERSION_SPF "2254"
|
#define VERSION_SPF "2255"
|
||||||
|
|||||||
Reference in New Issue
Block a user