2024-11-21 15:07:16 +03:00
# include "Array.h"
2025-06-04 13:08:38 +03:00
# include "errors.h"
# include "utils.h"
2025-06-02 19:08:09 +03:00
# include "graph_calls.h"
2025-06-04 13:08:38 +03:00
# include "SgUtils.h"
2024-11-21 15:07:16 +03:00
# include "../DirectiveProcessing/directive_parser.h"
# include "../DirectiveProcessing/directive_omp_parser.h"
# include "../LoopAnalyzer/loop_analyzer.h"
using namespace std ;
extern int ignoreIO ;
extern map < DIST : : Array * , std : : tuple < int , string , string > > tableOfUniqNamesByArray ;
static set < tuple < int , string , string > > checkedArraysForWrongLocation ;
static bool findOmpThreadPrivDecl ( SgStatement * st , map < SgStatement * , set < string > > & ompThreadPrivate , SgSymbol * toFind )
{
auto it = ompThreadPrivate . find ( st ) ;
if ( it = = ompThreadPrivate . end ( ) )
{
it = ompThreadPrivate . insert ( it , make_pair ( st , set < string > ( ) ) ) ;
SgStatement * lastN = st - > lastNodeOfStmt ( ) ;
set < string > dummy ;
do
{
st = st - > lexNext ( ) ;
auto res = parseOmpInStatement ( st , dummy ) ;
for ( auto & dir : res )
for ( auto & var : dir . threadPrivVars )
it - > second . insert ( var ) ;
} while ( st ! = lastN & & ! isSgExecutableStatement ( st ) & & st - > variant ( ) ! = CONTAINS_STMT ) ;
}
if ( it - > second . find ( toFind - > identifier ( ) ) ! = it - > second . end ( ) )
return true ;
else
return false ;
}
static bool hasAssingOpInDecl ( SgSymbol * symb )
{
vector < SgStatement * > allDecls ;
SgStatement * decl = declaratedInStmt ( symb , & allDecls ) ;
for ( auto & elem : allDecls )
{
if ( elem - > variant ( ) = = VAR_DECL_90 )
{
SgExpression * list = elem - > expr ( 0 ) ;
while ( list )
{
if ( list - > lhs ( ) - > variant ( ) = = ASSGN_OP )
if ( list - > lhs ( ) - > lhs ( ) - > symbol ( ) & & OriginalSymbol ( list - > lhs ( ) - > lhs ( ) - > symbol ( ) ) = = symb )
return true ;
list = list - > rhs ( ) ;
}
}
}
return false ;
}
static string getNameWithScope ( SgStatement * scope , const string & currFunctionName )
{
if ( scope & & isSgProgHedrStmt ( scope ) & & scope - > symbol ( ) - > identifier ( ) ! = currFunctionName )
return scope - > symbol ( ) - > identifier ( ) ;
else
return currFunctionName ;
}
struct findInfo
{
findInfo ( const string fName , SgExpression * ex , int parN , bool isWrite ) :
fName ( fName ) , ex ( ex ) , parN ( parN ) , isWrite ( isWrite )
{ }
SgExpression * ex ;
string fName ;
int parN ;
bool isWrite ;
} ;
static void findArrayRefs ( SgExpression * ex , SgStatement * st , string fName , int parN , bool isWrite ,
const map < string , vector < SgExpression * > > & commonBlocks ,
map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays ,
map < SgStatement * , set < tuple < int , string , string > > > & declaratedArraysSt ,
const set < string > & privates , const set < string > & deprecatedByIO ,
bool isExecutable , const string & currFunctionName ,
const vector < string > & inRegion ,
const set < string > & funcParNames ,
map < SgStatement * , set < string > > & ompThreadPrivate ,
const map < string , int > & distrStateFromGUI ,
const bool saveAllLocals ,
map < string , vector < Messages > > & currMessages ,
int & errorCount )
{
const string globalFile = current_file - > filename ( ) ;
const set < string > filesInProj = getAllFilesInProject ( ) ;
if ( ex = = NULL )
return ;
stack < findInfo > queue ;
queue . push ( findInfo ( fName , ex , parN , isWrite ) ) ;
while ( ! queue . empty ( ) )
{
const findInfo & curQ = queue . top ( ) ;
ex = curQ . ex ;
fName = curQ . fName ;
parN = curQ . parN ;
isWrite = curQ . isWrite ;
queue . pop ( ) ;
if ( isArrayRef ( ex ) )
{
SgSymbol * symb = OriginalSymbol ( ex - > symbol ( ) ) ;
const bool inDataStat = ( symb - > attributes ( ) & DATA_BIT ) ! = 0 | | ( ( ex - > symbol ( ) ) - > attributes ( ) & DATA_BIT ) ;
checkNull ( symb - > type ( ) , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
const int typeSize = getSizeOfType ( symb - > type ( ) - > baseType ( ) ) ;
if ( typeSize = = 0 )
{
//__spf_print(1, "Wrong type size for array %s\n", symb->identifier());
//printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
SgStatement * decl = declaratedInStmt ( symb ) ;
if ( decl - > variant ( ) = = DVM_VAR_DECL | | decl - > variant ( ) = = HPF_TEMPLATE_STAT )
{
const string tmp ( decl - > unparse ( ) ) ;
if ( tmp . find ( " !DVM$ TEMPLATE " ) ! = string : : npos )
{
auto sTemp = symb - > identifier ( ) ;
tuple < int , string , string > uniqKey ;
bool found = false ;
for ( auto & elem : declaredArrays )
{
if ( elem . second . first - > GetShortName ( ) = = sTemp )
{
uniqKey = elem . first ;
found = true ;
}
}
if ( found )
{
auto itDecl = declaratedArraysSt . find ( decl ) ;
if ( itDecl = = declaratedArraysSt . end ( ) )
itDecl = declaratedArraysSt . insert ( itDecl , make_pair ( decl , set < tuple < int , string , string > > ( ) ) ) ;
itDecl - > second . insert ( uniqKey ) ;
return ;
}
}
}
auto uniqKey = getUniqName ( commonBlocks , decl , symb ) ;
SgStatement * scope = symb - > scope ( ) ;
pair < DIST : : arrayLocType , string > arrayLocation ;
string typePrefix = " " ;
while ( scope & & scope - > variant ( ) = = STRUCT_DECL )
{
if ( typePrefix = = " " )
typePrefix = scope - > symbol ( ) - > identifier ( ) ;
else
typePrefix + = scope - > symbol ( ) - > identifier ( ) + string ( " :: " ) ;
scope = scope - > controlParent ( ) ;
}
if ( ( ex - > symbol ( ) & & symb ! = ex - > symbol ( ) ) | | ( scope & & scope - > variant ( ) = = MODULE_STMT ) )
{
if ( scope )
{
string modName = scope - > symbol ( ) - > identifier ( ) ;
arrayLocation = make_pair ( DIST : : l_MODULE , ( typePrefix = = " " ) ? modName : modName + " :: " + typePrefix ) ;
}
else //TODO: find module name with another way
arrayLocation = make_pair ( DIST : : l_MODULE , " UNREC_MODULE_NAME " ) ;
}
else if ( get < 1 > ( uniqKey ) . find ( " common_ " ) ! = string : : npos )
arrayLocation = make_pair ( DIST : : l_COMMON , get < 1 > ( uniqKey ) . substr ( strlen ( " common_ " ) ) ) ;
else if ( funcParNames . find ( symb - > identifier ( ) ) ! = funcParNames . end ( ) )
arrayLocation = make_pair ( DIST : : l_PARAMETER , getNameWithScope ( scope , currFunctionName ) ) ;
else
{
if ( saveAllLocals | | ( ( symb - > attributes ( ) & SAVE_BIT ) ! = 0 ) | | hasAssingOpInDecl ( symb ) )
arrayLocation = make_pair ( DIST : : l_LOCAL_SAVE , getNameWithScope ( scope , currFunctionName ) ) ;
else
arrayLocation = make_pair ( DIST : : l_LOCAL , getNameWithScope ( scope , currFunctionName ) ) ;
}
auto itNew = declaredArrays . find ( uniqKey ) ;
if ( itNew = = declaredArrays . end ( ) )
{
DIST : : Array * arrayToAdd =
new DIST : : Array ( getShortName ( uniqKey ) , symb - > identifier ( ) , ( ( SgArrayType * ) ( symb - > type ( ) ) ) - > dimension ( ) ,
getUniqArrayId ( ) , decl - > fileName ( ) , decl - > lineNumber ( ) , arrayLocation , new Symbol ( symb ) ,
findOmpThreadPrivDecl ( scope , ompThreadPrivate , symb ) , false , false ,
inRegion , typeSize , sharedMemoryParallelization ? DIST : : NO_DISTR : DIST : : DISTR ) ;
itNew = declaredArrays . insert ( itNew , make_pair ( uniqKey , make_pair ( arrayToAdd , new DIST : : ArrayAccessInfo ( ) ) ) ) ;
vector < pair < int , int > > sizes ;
map < DIST : : Array * , set < DIST : : Array * > > arrayLinksByFuncCallsNotReady ;
map < string , vector < FuncInfo * > > allFuncInfoNoReady ;
auto sizesExpr = getArraySizes ( sizes , symb , decl , arrayLinksByFuncCallsNotReady , allFuncInfoNoReady ) ;
arrayToAdd - > SetSizes ( sizes ) ;
arrayToAdd - > SetSizesExpr ( sizesExpr ) ;
tableOfUniqNamesByArray [ arrayToAdd ] = uniqKey ;
}
else // check the same location from include!
{
auto prevLocation = itNew - > second . first - > GetLocation ( ) ;
if ( prevLocation ! = arrayLocation )
{
if ( checkedArraysForWrongLocation . find ( uniqKey ) = = checkedArraysForWrongLocation . end ( ) )
{
checkedArraysForWrongLocation . insert ( uniqKey ) ;
__spf_print ( 1 , " can not change declaration area of array '%s' on line %d \n " , symb - > identifier ( ) , st - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " Array '%s' has declaration area conflict, it might be worth applying the Include inlining pass " , to_wstring ( symb - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R184 , to_wstring ( symb - > identifier ( ) ) . c_str ( ) ) ;
currMessages [ st - > fileName ( ) ] . push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1061 ) ) ;
}
errorCount + + ;
}
}
if ( ( symb - > attributes ( ) & EQUIVALENCE_BIT ) ! = 0 )
itNew - > second . first - > SetEquvalence ( true ) ;
for ( auto & reg : inRegion )
itNew - > second . first - > SetRegionPlace ( reg ) ;
const auto oldVal = itNew - > second . first - > GetDistributeFlagVal ( ) ;
2025-09-11 08:07:14 +03:00
bool isArrayInModule = ( itNew - > second . first - > GetLocation ( ) . first = = DIST : : l_MODULE ) ;
2024-11-21 15:07:16 +03:00
if ( oldVal = = DIST : : DISTR | | oldVal = = DIST : : NO_DISTR )
{
if ( itNew - > second . first - > IsOmpThreadPrivate ( ) )
itNew - > second . first - > SetDistributeFlag ( DIST : : SPF_PRIV ) ;
2025-09-11 08:07:14 +03:00
else if ( deprecatedByIO . find ( symb - > identifier ( ) ) ! = deprecatedByIO . end ( ) )
itNew - > second . first - > SetDistributeFlag ( DIST : : IO_PRIV ) ;
else if ( isArrayInModule | | privates . find ( symb - > identifier ( ) ) ! = privates . end ( ) )
2024-11-21 15:07:16 +03:00
{
//check in module
if ( itNew - > second . first - > GetLocation ( ) . first = = DIST : : l_MODULE )
{
for ( auto & data : getAttributes < SgStatement * , SgStatement * > ( decl , set < int > { SPF_ANALYSIS_DIR } ) )
{
set < string > privatesS ;
fillPrivatesFromComment ( new Statement ( data ) , privatesS ) ;
if ( privatesS . find ( symb - > identifier ( ) ) ! = privatesS . end ( ) )
{
itNew - > second . first - > SetDistributeFlag ( DIST : : SPF_PRIV ) ;
break ;
}
}
auto prev = decl - > lexPrev ( ) ;
checkNull ( prev , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
set < string > privatesS ;
fillPrivatesFromComment ( new Statement ( prev ) , privatesS ) ;
if ( privatesS . find ( symb - > identifier ( ) ) ! = privatesS . end ( ) )
itNew - > second . first - > SetDistributeFlag ( DIST : : SPF_PRIV ) ;
}
else
itNew - > second . first - > SetDistributeFlag ( DIST : : SPF_PRIV ) ;
}
else if ( isSgConstantSymb ( symb ) | | inDataStat )
itNew - > second . first - > SetDistributeFlag ( DIST : : SPF_PRIV ) ;
else
{
auto it = distrStateFromGUI . find ( itNew - > second . first - > GetIndepUniqName ( ) ) ;
if ( it ! = distrStateFromGUI . end ( ) )
{
if ( it - > second ! = oldVal )
{
itNew - > second . first - > SetDistributeFlag ( ( DIST : : distFlag ) it - > second ) ;
__spf_print ( 1 , " change flag for array from cache '%s': %d -> %d \n " , it - > first . c_str ( ) , oldVal , it - > second ) ;
}
}
else
itNew - > second . first - > SetDistributeFlag ( DIST : : DISTR ) ;
}
}
if ( typeSize = = 0 ) // unknown
itNew - > second . first - > SetDistributeFlag ( DIST : : SPF_PRIV ) ;
if ( ! isExecutable )
itNew - > second . first - > AddDeclInfo ( make_pair ( st - > fileName ( ) , st - > lineNumber ( ) ) , filesInProj , globalFile , new Symbol ( symb ) ) ;
if ( isExecutable )
{
if ( st - > variant ( ) ! = ALLOCATE_STMT & & st - > variant ( ) ! = DEALLOCATE_STMT )
{
itNew - > second . second - > AddAccessInfo ( st - > fileName ( ) , make_pair ( st - > lineNumber ( ) , isWrite ? 1 : 0 ) , fName , parN ) ;
itNew - > second . first - > AddUsagePlace ( st - > fileName ( ) , st - > lineNumber ( ) ) ;
}
}
auto itDecl = declaratedArraysSt . find ( decl ) ;
if ( itDecl = = declaratedArraysSt . end ( ) )
itDecl = declaratedArraysSt . insert ( itDecl , make_pair ( decl , set < tuple < int , string , string > > ( ) ) ) ;
itDecl - > second . insert ( uniqKey ) ;
if ( decl - > variant ( ) = = DVM_VAR_DECL | | decl - > variant ( ) = = HPF_TEMPLATE_STAT )
{
const string tmp ( decl - > unparse ( ) ) ;
if ( tmp . find ( " !DVM$ TEMPLATE " ) ! = string : : npos )
{
itNew - > second . first - > SetTemplateFlag ( true ) ;
//TODO: analyze align mapping
for ( int z = 0 ; z < itNew - > second . first - > GetDimSize ( ) ; + + z )
itNew - > second . first - > SetMappedDim ( z ) ;
}
}
}
if ( ex - > variant ( ) = = FUNC_CALL )
{
SgFunctionCallExp * funcExp = ( SgFunctionCallExp * ) ex ;
const string fName = funcExp - > funName ( ) - > identifier ( ) ;
bool intr = ( isIntrinsicFunctionName ( fName . c_str ( ) ) = = 1 ) ;
for ( int z = 0 ; z < funcExp - > numberOfArgs ( ) ; + + z )
{
//assume all arguments of function as OUT, except for inctrinsics
bool isWriteN = intr ? false : true ;
//need to correct W/R usage with GraphCall map later
findArrayRefs ( funcExp - > arg ( z ) , st , fName , z , isWriteN , commonBlocks , declaredArrays , declaratedArraysSt , privates , deprecatedByIO , isExecutable , currFunctionName , inRegion , funcParNames , ompThreadPrivate , distrStateFromGUI , saveAllLocals , currMessages , errorCount ) ;
}
}
else
{
bool isWriteN = false ;
if ( ex - > lhs ( ) )
queue . push ( findInfo ( " " , ex - > lhs ( ) , - 1 , isWriteN ) ) ;
if ( ex - > rhs ( ) )
queue . push ( findInfo ( " " , ex - > rhs ( ) , - 1 , isWriteN ) ) ;
//findArrayRefs(ex->lhs(), st, "", -1, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, currMessages, errorCount);
//findArrayRefs(ex->rhs(), st, "", -1, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, currMessages, errorCount);
}
}
}
static void findArrayRefInIO ( SgExpression * ex , set < string > & deprecatedByIO , SgStatement * st , map < string , vector < Messages > > & currMessages )
{
if ( ex )
{
if ( ex - > variant ( ) = = ARRAY_REF )
{
auto symb = ex - > symbol ( ) ;
if ( symb - > type ( ) )
{
if ( symb - > type ( ) - > variant ( ) = = T_ARRAY )
{
auto found = deprecatedByIO . find ( OriginalSymbol ( symb ) - > identifier ( ) ) ;
if ( found = = deprecatedByIO . end ( ) )
{
deprecatedByIO . insert ( found , OriginalSymbol ( symb ) - > identifier ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " Array '%s' can not be distributed because of DVM's I/O constraints " , to_wstring ( symb - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R68 , to_wstring ( symb - > identifier ( ) ) . c_str ( ) ) ;
currMessages [ st - > fileName ( ) ] . push_back ( Messages ( WARR , st - > lineNumber ( ) , messageR , messageE , 1037 ) ) ;
__spf_print ( 1 , " Array '%s' at line %d can not be distributed because of DVM's I/O constraints \n " , symb - > identifier ( ) , st - > lineNumber ( ) ) ;
}
}
}
}
findArrayRefInIO ( ex - > lhs ( ) , deprecatedByIO , st , currMessages ) ;
findArrayRefInIO ( ex - > rhs ( ) , deprecatedByIO , st , currMessages ) ;
}
}
static void findReshape ( SgStatement * st , set < string > & privates , map < string , vector < Messages > > & currMessages )
{
if ( st - > variant ( ) = = ASSIGN_STAT )
{
SgExpression * exL = st - > expr ( 0 ) ;
SgExpression * exR = st - > expr ( 1 ) ;
if ( exR - > variant ( ) = = FUNC_CALL & & exL - > variant ( ) = = ARRAY_REF )
{
if ( exR - > symbol ( ) - > identifier ( ) = = string ( " reshape " ) )
{
if ( privates . find ( exL - > symbol ( ) - > identifier ( ) ) = = privates . end ( ) )
{
privates . insert ( exL - > symbol ( ) - > identifier ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " Array '%s' can not be distributed because of RESHAPE " , to_wstring ( exL - > symbol ( ) - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R90 , to_wstring ( exL - > symbol ( ) - > identifier ( ) ) . c_str ( ) ) ;
currMessages [ st - > fileName ( ) ] . push_back ( Messages ( NOTE , st - > lineNumber ( ) , messageR , messageE , 1047 ) ) ;
}
}
}
}
}
static void findConstructorRef ( SgStatement * st , set < string > & privates , map < string , vector < Messages > > & currMessages )
{
if ( st - > variant ( ) = = ASSIGN_STAT )
{
SgExpression * exL = st - > expr ( 0 ) ;
SgExpression * exR = st - > expr ( 1 ) ;
if ( exR - > variant ( ) = = CONSTRUCTOR_REF & & exL - > variant ( ) = = ARRAY_REF )
{
if ( privates . find ( exL - > symbol ( ) - > identifier ( ) ) = = privates . end ( ) )
{
privates . insert ( exL - > symbol ( ) - > identifier ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " Array '%s' can not be distributed because of initializer list " , to_wstring ( exL - > symbol ( ) - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R164 , to_wstring ( exL - > symbol ( ) - > identifier ( ) ) . c_str ( ) ) ;
currMessages [ st - > fileName ( ) ] . push_back ( Messages ( NOTE , st - > lineNumber ( ) , messageR , messageE , 1047 ) ) ;
}
}
}
}
static void addPrivates ( SgStatement * st , set < string > & privates , map < string , set < Symbol * > > & reductions ,
map < string , set < tuple < Symbol * , Symbol * , int > > > & reductionsLoc )
{
//after SPF preprocessing
for ( auto & data : getAttributes < SgStatement * , SgStatement * > ( st , set < int > { SPF_ANALYSIS_DIR } ) )
{
set < Symbol * > privatesS ;
fillPrivatesFromComment ( new Statement ( data ) , privatesS ) ;
fillReductionsFromComment ( new Statement ( data ) , reductions ) ;
fillReductionsFromComment ( new Statement ( data ) , reductionsLoc ) ;
for ( auto & elem : privatesS )
privates . insert ( elem - > GetOriginal ( ) - > identifier ( ) ) ;
}
//before SPF preprocessing
if ( st - > variant ( ) = = SPF_ANALYSIS_DIR )
{
set < Symbol * > privatesS ;
fillPrivatesFromComment ( new Statement ( st ) , privatesS ) ;
fillReductionsFromComment ( new Statement ( st ) , reductions ) ;
fillReductionsFromComment ( new Statement ( st ) , reductionsLoc ) ;
for ( auto & elem : privatesS )
privates . insert ( elem - > GetOriginal ( ) - > identifier ( ) ) ;
}
}
int getAllDeclaredArrays ( SgFile * file , map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays ,
map < SgStatement * , set < tuple < int , string , string > > > & declaratedArraysSt , map < string , vector < Messages > > & currMessages ,
const vector < ParallelRegion * > & regions , const map < string , int > & distrStateFromGUI )
{
int countErrors = 0 ;
vector < SgStatement * > modules ;
findModulesInFile ( file , modules ) ;
map < string , set < string > > privatesByModule ;
for ( auto & mod : modules )
{
const string modName = mod - > symbol ( ) - > identifier ( ) ;
privatesByModule [ modName ] = set < string > ( ) ;
auto it = privatesByModule . find ( modName ) ;
for ( SgStatement * iter = mod ; iter ! = mod - > lastNodeOfStmt ( ) ; iter = iter - > lexNext ( ) )
{
if ( iter - > variant ( ) = = CONTAINS_STMT )
break ;
//after SPF preprocessing
for ( auto & data : getAttributes < SgStatement * , SgStatement * > ( iter , set < int > { SPF_ANALYSIS_DIR } ) )
fillPrivatesFromComment ( new Statement ( data ) , it - > second ) ;
//before SPF preprocessing
if ( iter - > variant ( ) = = SPF_ANALYSIS_DIR )
fillPrivatesFromComment ( new Statement ( iter ) , it - > second ) ;
}
}
map < SgStatement * , set < string > > ompThreadPrivate ;
for ( int i = 0 ; i < file - > numberOfFunctions ( ) ; + + i )
{
bool saveAllLocals = false ;
SgStatement * st = file - > functions ( i ) ;
SgStatement * lastNode = st - > lastNodeOfStmt ( ) ;
map < string , vector < SgExpression * > > commonBlocks ;
const string currFunctionName = st - > symbol ( ) - > identifier ( ) ;
getCommonBlocksRef ( commonBlocks , st , lastNode ) ;
set < string > privates ;
set < string > deprecatedByIO ;
map < string , set < Symbol * > > reductions ;
map < string , set < tuple < Symbol * , Symbol * , int > > > reductionsLoc ;
set < string > funcParNames ;
if ( st - > variant ( ) ! = PROG_HEDR )
{
SgProcHedrStmt * func = ( SgProcHedrStmt * ) st ;
for ( int z = 0 ; z < func - > numberOfParameters ( ) ; + + z )
funcParNames . insert ( func - > parameter ( z ) - > identifier ( ) ) ;
if ( func - > nameWithContains ( ) ! = func - > name ( ) . identifier ( ) ) // added contains args
{
SgProcHedrStmt * cp = ( SgProcHedrStmt * ) func - > controlParent ( ) ;
checkNull ( cp , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
for ( int z = 0 ; z < cp - > numberOfParameters ( ) ; + + z )
funcParNames . insert ( cp - > parameter ( z ) - > identifier ( ) ) ;
}
}
for ( SgStatement * iter = st ; iter ! = lastNode ; iter = iter - > lexNext ( ) )
{
if ( iter - > variant ( ) = = CONTAINS_STMT )
break ;
addPrivates ( iter , privates , reductions , reductionsLoc ) ;
if ( iter - > variant ( ) = = USE_STMT )
fillFromModule ( iter - > symbol ( ) , privatesByModule , privates ) ;
if ( iter - > variant ( ) = = SAVE_DECL )
if ( ! iter - > expr ( 0 ) & & ! iter - > expr ( 1 ) & & ! iter - > expr ( 2 ) )
saveAllLocals = true ;
}
for ( SgStatement * iter = st ; iter ! = lastNode ; iter = iter - > lexNext ( ) )
{
if ( iter - > variant ( ) = = CONTAINS_STMT )
break ;
findReshape ( iter , privates , currMessages ) ;
findConstructorRef ( iter , privates , currMessages ) ;
}
SgStatement * tmpModFind = st ;
while ( tmpModFind - > variant ( ) ! = GLOBAL )
{
tmpModFind = tmpModFind - > controlParent ( ) ;
if ( tmpModFind - > variant ( ) = = MODULE_STMT )
fillFromModule ( tmpModFind - > symbol ( ) , privatesByModule , privates ) ;
}
SgStatement * currF = st ;
SgStatement * contains = isSgProgHedrStmt ( currF - > controlParent ( ) ) ;
if ( contains )
{
for ( SgStatement * loc = contains ; loc ; loc = loc - > lexNext ( ) )
{
if ( isSgExecutableStatement ( loc ) )
break ;
if ( loc - > variant ( ) = = CONTAINS_STMT )
break ;
if ( loc - > variant ( ) = = USE_STMT )
fillFromModule ( loc - > symbol ( ) , privatesByModule , privates ) ;
}
}
for ( auto & elem : reductions )
for ( auto & setElem : elem . second )
privates . insert ( setElem - > identifier ( ) ) ;
for ( auto & elem : reductionsLoc )
{
for ( auto & setElem : elem . second )
{
privates . insert ( get < 0 > ( setElem ) - > identifier ( ) ) ;
privates . insert ( get < 1 > ( setElem ) - > identifier ( ) ) ;
}
}
//analyze IO operations
if ( ! ignoreIO )
{
for ( SgStatement * iter = st ; iter ! = lastNode ; iter = iter - > lexNext ( ) )
{
if ( iter - > variant ( ) = = CONTAINS_STMT )
break ;
SgInputOutputStmt * stIO = isSgInputOutputStmt ( iter ) ;
set < ParallelRegion * > currRegs = getAllRegionsByLine ( regions , iter - > fileName ( ) , iter - > lineNumber ( ) ) ;
if ( stIO & & currRegs . size ( ) ) // deprecate to distribute arrays only in regions
{
int countOfItems = 0 ;
for ( SgExpression * items = stIO - > itemList ( ) ; items ; items = items - > rhs ( ) , + + countOfItems ) ;
//TODO: need to add more checkers!
if ( countOfItems > 1 )
{
for ( SgExpression * items = stIO - > itemList ( ) ; items ; items = items - > rhs ( ) )
findArrayRefInIO ( items - > lhs ( ) , deprecatedByIO , stIO , currMessages ) ;
}
else if ( countOfItems = = 1 )
{
auto list = stIO - > specList ( ) ;
bool ok = true ;
//exclude FMT='format'
while ( list )
{
if ( list - > lhs ( ) & & list - > lhs ( ) - > variant ( ) = = SPEC_PAIR )
{
auto ex = list - > lhs ( ) ;
if ( ex - > lhs ( ) & & ex - > rhs ( ) )
{
if ( ex - > lhs ( ) - > variant ( ) = = KEYWORD_VAL )
{
SgKeywordValExp * key = ( SgKeywordValExp * ) ( ex - > lhs ( ) ) ;
if ( key - > value ( ) = = string ( " fmt " ) )
if ( ex - > rhs ( ) - > variant ( ) = = STRING_VAL )
ok = false ;
}
}
}
if ( ! ok )
break ;
list = list - > rhs ( ) ;
}
//check A(i,j) for example
auto item = stIO - > itemList ( ) - > lhs ( ) ;
if ( item - > rhs ( ) | | item - > lhs ( ) )
ok = false ;
if ( ! ok )
findArrayRefInIO ( item , deprecatedByIO , stIO , currMessages ) ;
}
}
}
}
while ( st ! = lastNode )
{
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
if ( ! isSPF_stat ( st ) & & ! isDVM_stat ( st ) )
{
set < ParallelRegion * > currRegs = getAllRegionsByLine ( regions , st - > fileName ( ) , st - > lineNumber ( ) ) ;
vector < string > regNames ;
for ( auto & reg : currRegs )
regNames . push_back ( reg - > GetName ( ) ) ;
if ( regNames . size ( ) = = 0 )
regNames . push_back ( " default " ) ;
if ( st - > variant ( ) = = PROC_STAT )
{
SgCallStmt * funcExp = ( SgCallStmt * ) st ;
const string fName = funcExp - > symbol ( ) - > identifier ( ) ;
for ( int z = 0 ; z < funcExp - > numberOfArgs ( ) ; + + z )
{
findArrayRefs ( funcExp - > arg ( z ) , st , fName , z , true ,
commonBlocks , declaredArrays , declaratedArraysSt , privates , deprecatedByIO ,
isSgExecutableStatement ( st ) ? true : false , currFunctionName ,
regNames , funcParNames , ompThreadPrivate , distrStateFromGUI , saveAllLocals ,
currMessages , countErrors ) ;
}
}
else
{
for ( int i = 0 ; i < 3 ; + + i )
findArrayRefs ( st - > expr ( i ) , st , " " , - 1 , ( st - > variant ( ) = = ASSIGN_STAT & & i = = 0 ) ? true : false ,
commonBlocks , declaredArrays , declaratedArraysSt , privates , deprecatedByIO ,
isSgExecutableStatement ( st ) ? true : false , currFunctionName ,
regNames , funcParNames , ompThreadPrivate , distrStateFromGUI , saveAllLocals ,
currMessages , countErrors ) ;
}
}
st = st - > lexNext ( ) ;
}
}
//preprocess only module declaration
for ( auto & mod : modules )
{
SgStatement * st = mod - > lexNext ( ) ;
SgStatement * lastNode = mod - > lastNodeOfStmt ( ) ;
map < string , vector < SgExpression * > > commonBlocks ;
set < string > privates ;
set < string > deprecatedByIO ;
set < string > funcParNames ;
fillFromModule ( st - > symbol ( ) , privatesByModule , privates ) ;
while ( st ! = lastNode )
{
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
if ( ! isSPF_stat ( st ) & & ! isDVM_stat ( st ) )
{
//TODO: set clear regions for modules
set < ParallelRegion * > currRegs = getAllRegionsByLine ( regions , st - > fileName ( ) , st - > lineNumber ( ) ) ;
vector < string > regNames ;
for ( auto & reg : currRegs )
regNames . push_back ( reg - > GetName ( ) ) ;
if ( regNames . size ( ) = = 0 )
regNames . push_back ( " default " ) ;
for ( int i = 0 ; i < 3 ; + + i )
findArrayRefs ( st - > expr ( i ) , st , " " , - 1 , false , commonBlocks , declaredArrays , declaratedArraysSt , privates , deprecatedByIO ,
false , " NULL " , regNames , funcParNames , ompThreadPrivate , distrStateFromGUI , false ,
currMessages , countErrors ) ;
}
st = st - > lexNext ( ) ;
}
}
//preprocess only block data declaration
for ( SgStatement * st = file - > firstStatement ( ) - > lexNext ( ) ; st ; st = st - > lastNodeOfStmt ( ) , st = st - > lexNext ( ) )
{
if ( st - > variant ( ) = = BLOCK_DATA )
{
SgStatement * last = st - > lastNodeOfStmt ( ) ;
SgStatement * curr = st ;
map < string , vector < SgExpression * > > commonBlocks ;
getCommonBlocksRef ( commonBlocks , st , last ) ;
set < string > privates ;
set < string > deprecatedByIO ;
set < string > funcParNames ;
string blockName = " BLOCK DATA " ;
if ( st - > symbol ( ) )
blockName = st - > symbol ( ) - > identifier ( ) ;
while ( curr & & curr ! = last )
{
//TODO: set clear regions for block data
set < ParallelRegion * > currRegs = getAllRegionsByLine ( regions , curr - > fileName ( ) , curr - > lineNumber ( ) ) ;
vector < string > regNames ;
for ( auto & reg : currRegs )
regNames . push_back ( reg - > GetName ( ) ) ;
if ( regNames . size ( ) = = 0 )
regNames . push_back ( " default " ) ;
for ( int i = 0 ; i < 3 ; + + i )
findArrayRefs ( curr - > expr ( i ) , curr , " " , - 1 , false , commonBlocks , declaredArrays , declaratedArraysSt , privates , deprecatedByIO ,
false , blockName , regNames , funcParNames , ompThreadPrivate , distrStateFromGUI , false ,
currMessages , countErrors ) ;
curr = curr - > lexNext ( ) ;
}
}
}
return countErrors ;
}