2023-09-14 19:43:13 +03:00
# include <cstdio>
# include <cstdlib>
# include <cstring>
# include <cstdint>
# include <string>
# include <fstream>
# include <iostream>
# include <algorithm>
# include <vector>
# include <map>
# include <set>
# include <utility>
# include <assert.h>
# include "loop_analyzer.h"
2024-07-06 14:27:00 +03:00
# include <tuple>
# include <stack>
# include "../Utils/leak_detector.h"
# if _WIN32 && NDEBUG && __BOOST
# include <boost/thread.hpp>
# endif
extern int passDone ;
# include "../Distribution/Distribution.h"
# include "../Distribution/GraphCSR.h"
# include "../Distribution/Arrays.h"
# include "../ParallelizationRegions/ParRegions.h"
# include "../Utils/errors.h"
# include "../DirectiveProcessing/directive_parser.h"
# include "../DirectiveProcessing/directive_creator.h"
# include "../Utils/SgUtils.h"
# include "../Utils/AstWrapper.h"
# include "../GraphCall/graph_calls_func.h"
# include "../GraphLoop/graph_loops_func.h"
# include "../ParallelizationRegions/ParRegions_func.h"
# include "../DynamicAnalysis/gCov_parser_func.h"
# include "../ExpressionTransform/expr_transform.h"
# include "../SageAnalysisTool/depInterfaceExt.h"
# include "../VisualizerCalls/get_information.h"
# include "../VisualizerCalls/SendMessage.h"
# include "../Transformations/enddo_loop_converter.h"
# include "../DirectiveProcessing/remote_access.h"
2024-04-02 17:48:48 +03:00
# include "../DirectiveProcessing/directive_omp_parser.h"
2023-09-14 19:43:13 +03:00
2024-07-06 14:27:00 +03:00
# define PRINT_ARRAY_ARCS 0
# define PRINT_LOOP_STRUCT 0
# define PRINT_PROF_INFO 0
# define DEB 0
extern REGIME currRegime ;
extern std : : vector < Messages > * currMessages ;
extern int sharedMemoryParallelization ;
extern int parallizeFreeLoops ;
2023-09-14 19:43:13 +03:00
using std : : vector ;
using std : : pair ;
using std : : tuple ;
using std : : map ;
using std : : set ;
using std : : make_pair ;
using std : : make_tuple ;
using std : : get ;
using std : : string ;
using std : : wstring ;
using std : : stack ;
REGIME currRegime = UNDEF ;
std : : vector < Messages > * currMessages ;
static bool hasArrayAccessInSubscr ( SgExpression * exp )
{
bool retVal = false ;
if ( exp - > variant ( ) = = ARRAY_REF )
return true ;
if ( exp - > lhs ( ) )
retVal | = hasArrayAccessInSubscr ( exp - > lhs ( ) ) ;
if ( exp - > rhs ( ) )
retVal | = hasArrayAccessInSubscr ( exp - > rhs ( ) ) ;
return retVal ;
}
bool checkExistence ( SgExpression * exp , const string & doName )
{
bool retVal = false ;
if ( exp - > variant ( ) = = VAR_REF )
if ( exp - > symbol ( ) - > identifier ( ) = = doName )
retVal = true ;
if ( exp - > lhs ( ) )
retVal | = checkExistence ( exp - > lhs ( ) , doName ) ;
if ( exp - > rhs ( ) )
retVal | = checkExistence ( exp - > rhs ( ) , doName ) ;
return retVal ;
}
static pair < bool , string > constructArrayRefForPrint ( SgArrayRefExp * arrayRef , const int dimNum , SgExpression * subscr )
{
bool needToPrint = true ;
const int num = arrayRef - > numberOfSubscripts ( ) ;
string ref ( arrayRef - > symbol ( ) - > identifier ( ) ) ;
ref + = " ( " ;
for ( int i = 0 ; i < num ; + + i )
{
if ( i = = dimNum )
{
char * copySub = copyOfUnparse ( subscr - > unparse ( ) ) ;
ref + = copySub ;
if ( subscr - > variant ( ) = = INT_VAL )
needToPrint = false ;
removeFromCollection ( copySub ) ;
delete [ ] copySub ;
}
else
ref + = " * " ;
if ( i ! = num - 1 )
ref + = " , " ;
else
ref + = " ) " ;
}
std : : transform ( ref . begin ( ) , ref . end ( ) , ref . begin ( ) , : : toupper ) ;
return make_pair ( needToPrint , ref ) ;
}
static void addInfoToMap ( map < SgForStmt * , map < SgSymbol * , ArrayInfo > > & loopInfo , SgForStmt * position , SgSymbol * symb ,
SgArrayRefExp * arrayRefIn , const int dimNum , const REMOTE_TYPE & value , const int currLine ,
const int maxDimSize )
{
ArrayRefExp * arrayRef = new ArrayRefExp ( arrayRefIn ) ;
auto it = loopInfo . find ( position ) ;
if ( loopInfo . end ( ) = = it )
it = loopInfo . insert ( it , make_pair ( position , map < SgSymbol * , ArrayInfo > ( ) ) ) ;
auto it1 = it - > second . find ( symb ) ;
if ( it1 = = it - > second . end ( ) )
it1 = it - > second . insert ( it1 , make_pair ( symb , ArrayInfo ( ) ) ) ;
auto it2 = it1 - > second . arrayAccessUnrec . find ( arrayRef ) ;
if ( it2 = = it1 - > second . arrayAccessUnrec . end ( ) )
{
it2 = it1 - > second . arrayAccessUnrec . insert ( it2 , make_pair ( arrayRef , make_pair ( currLine , vector < REMOTE_TYPE > ( ) ) ) ) ;
it2 - > second . second . resize ( maxDimSize ) ;
std : : fill ( it2 - > second . second . begin ( ) , it2 - > second . second . end ( ) , REMOTE_NONE ) ;
}
if ( dimNum = = - 1 )
{
for ( int z = 0 ; z < it2 - > second . second . size ( ) ; + + z )
it2 - > second . second [ z ] | = value ;
}
else
it2 - > second . second [ dimNum ] | = value ;
if ( value = = REMOTE_TRUE )
__spf_print ( DEB , " RemoteAccess[%d]: true for dim %d and array %s, loop line %d \n " , __LINE__ , dimNum , symb - > identifier ( ) , position - > lineNumber ( ) ) ;
}
2024-07-06 14:27:00 +03:00
enum { READ_OP , WRITE_OP , UNREC_OP } ;
static void addInfoToVectors ( map < SgForStmt * , map < SgSymbol * , ArrayInfo > > & loopInfo , SgForStmt * position , SgSymbol * symb ,
2024-03-26 13:59:48 +03:00
const int dimNum , const pair < int , int > newCoef , int type , const int maxDimSize , const double currentW )
2023-09-14 19:43:13 +03:00
{
auto itLoop = loopInfo . find ( position ) ;
if ( itLoop = = loopInfo . end ( ) )
itLoop = loopInfo . insert ( itLoop , make_pair ( position , map < SgSymbol * , ArrayInfo > ( ) ) ) ;
auto itSymb = itLoop - > second . find ( symb ) ;
if ( itSymb = = itLoop - > second . end ( ) )
itSymb = itLoop - > second . insert ( itSymb , make_pair ( symb , ArrayInfo ( ) ) ) ;
itSymb - > second . setDimSize ( maxDimSize ) ;
if ( type = = READ_OP )
{
auto itAdd = itSymb - > second . readOps [ dimNum ] . coefficients . find ( newCoef ) ;
//add only uniq
if ( itAdd = = itSymb - > second . readOps [ dimNum ] . coefficients . end ( ) )
itAdd = itSymb - > second . readOps [ dimNum ] . coefficients . insert ( itAdd , make_pair ( newCoef , currentW ) ) ;
}
else if ( type = = WRITE_OP )
{
auto itAdd = itSymb - > second . writeOps [ dimNum ] . coefficients . find ( newCoef ) ;
if ( itAdd = = itSymb - > second . writeOps [ dimNum ] . coefficients . end ( ) )
itAdd = itSymb - > second . writeOps [ dimNum ] . coefficients . insert ( itAdd , make_pair ( newCoef , currentW ) ) ;
}
else if ( type = = UNREC_OP )
itSymb - > second . unrecReadOps [ dimNum ] = true ;
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
2024-07-06 14:27:00 +03:00
static vector < int > matchSubscriptToLoopSymbols ( const vector < SgForStmt * > & parentLoops , SgExpression * subscr ,
SgArrayRefExp * arrayRefIn , const int side , const int dimNum ,
map < SgForStmt * , map < SgSymbol * , ArrayInfo > > & loopInfo ,
const int currLine , const int numOfSubscriptions , const double currentW )
2023-09-14 19:43:13 +03:00
{
SgExpression * origSubscr = subscr ;
ArrayRefExp * arrayRef = new ArrayRefExp ( arrayRefIn ) ;
// REVERT_SUBS has been done before REMOTE_ACC PASS
if ( currRegime = = REMOTE_ACC )
{
auto data = getAttributes < SgExpression * , SgExpression * > ( arrayRefIn , set < int > { ARRAY_REF } ) ;
if ( data . size ( ) = = 1 )
{
SgExpression * dataS = data [ 0 ] - > lhs ( ) ;
for ( int z = 0 ; z < dimNum ; + + z )
dataS = dataS - > rhs ( ) ;
subscr = dataS - > lhs ( ) ;
}
}
int countOfSymbols = 0 ;
int position = - 1 ;
vector < int > allPositions ;
bool hasArrayAcc = hasArrayAccessInSubscr ( subscr ) ;
SgSymbol * currOrigArrayS = OriginalSymbol ( arrayRef - > symbol ( ) ) ;
if ( ! hasArrayAcc )
{
for ( int i = 0 ; i < ( int ) parentLoops . size ( ) ; + + i )
{
if ( checkExistence ( subscr , parentLoops [ i ] - > doName ( ) - > identifier ( ) ) )
{
countOfSymbols + + ;
position = i ;
allPositions . push_back ( i ) ;
}
}
}
pair < int , int > coefs = pair < int , int > ( 0 , 0 ) ;
// more than one loop symbol in subscription
if ( countOfSymbols > 1 )
{
__spf_print ( PRINT_ARRAY_ARCS , " <%d|%d> " , 0 , 0 ) ;
2024-06-20 13:00:01 +03:00
if ( currRegime = = DATA_DISTR | | currRegime = = SHARED_MEMORY_PAR )
2023-09-14 19:43:13 +03:00
{
const pair < bool , string > & arrayRefString = constructArrayRefForPrint ( arrayRef , dimNum , origSubscr ) ;
__spf_print ( 1 , " WARN: array ref '%s' at line %d has more than one loop's variables \n " , arrayRefString . second . c_str ( ) , currLine ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " array ref '%s' has more than one loop's variables " , to_wstring ( arrayRefString . second ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R54 , to_wstring ( arrayRefString . second ) . c_str ( ) ) ;
if ( currLine > 0 )
currMessages - > push_back ( Messages ( WARR , currLine , messageR , messageE , 1021 ) ) ;
}
for ( int i = 0 ; i < allPositions . size ( ) ; + + i )
{
if ( currRegime = = REMOTE_ACC )
{
if ( side = = RIGHT )
addInfoToMap ( loopInfo , parentLoops [ allPositions [ i ] ] , currOrigArrayS , arrayRef , dimNum , REMOTE_TRUE , currLine , numOfSubscriptions ) ;
}
else
addInfoToVectors ( loopInfo , parentLoops [ allPositions [ i ] ] , currOrigArrayS , dimNum , make_pair ( 0 , 0 ) , UNREC_OP , numOfSubscriptions , currentW ) ;
}
}
// no loop symbol in subscription
else if ( countOfSymbols = = 0 )
{
__spf_print ( PRINT_ARRAY_ARCS , " <%d|%d> " , 0 , 0 ) ;
if ( currRegime = = REMOTE_ACC )
{
if ( side = = RIGHT )
for ( int i = 0 ; i < ( int ) parentLoops . size ( ) ; + + i )
addInfoToMap ( loopInfo , parentLoops [ i ] , currOrigArrayS , arrayRef , dimNum , REMOTE_TRUE , currLine , numOfSubscriptions ) ;
}
2024-06-20 13:00:01 +03:00
else if ( currRegime = = DATA_DISTR | | currRegime = = SHARED_MEMORY_PAR )
2023-09-14 19:43:13 +03:00
{
const pair < bool , string > & arrayRefString = constructArrayRefForPrint ( arrayRef , dimNum , origSubscr ) ;
if ( ! hasArrayAcc )
{
if ( parentLoops . size ( ) ! = 0 & & ( arrayRefString . first | | side = = LEFT ) )
{
__spf_print ( 1 , " WARN: array ref '%s' in %d dimension at line %d does not have loop variables \n " , arrayRefString . second . c_str ( ) , dimNum + 1 , currLine ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " array ref '%s' in %d dimension does not have loop variables " , to_wstring ( arrayRefString . second ) . c_str ( ) , dimNum + 1 ) ;
__spf_printToLongBuf ( messageR , R55 , to_wstring ( arrayRefString . second ) . c_str ( ) , dimNum + 1 ) ;
if ( currLine > 0 )
currMessages - > push_back ( Messages ( WARR , currLine , messageR , messageE , 1021 ) ) ;
}
}
else
{
__spf_print ( 1 , " WARN: array ref '%s' at line %d has indirect access \n " , arrayRefString . second . c_str ( ) , currLine ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " array ref '%s' has indirect access " , to_wstring ( arrayRefString . second ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R56 , to_wstring ( arrayRefString . second ) . c_str ( ) ) ;
if ( currLine > 0 )
currMessages - > push_back ( Messages ( WARR , currLine , messageR , messageE , 1022 ) ) ;
}
}
}
else
{
bool needToCacl = true ;
if ( subscr - > variant ( ) = = VAR_REF )
{
if ( subscr - > symbol ( ) - > id ( ) = = ( parentLoops [ position ] - > doName ( ) ) - > id ( ) )
{
coefs . first = 1 ;
needToCacl = false ;
}
}
if ( needToCacl )
getCoefsOfSubscript ( coefs , subscr , parentLoops [ position ] - > doName ( ) ) ;
__spf_print ( PRINT_ARRAY_ARCS , " <%d %d> " , coefs . first , coefs . second ) ;
if ( coefs . first = = 0 ) // && coefs.second == 0)
{
if ( currRegime = = REMOTE_ACC )
{
if ( side = = RIGHT )
addInfoToMap ( loopInfo , parentLoops [ position ] , currOrigArrayS , arrayRef , dimNum , REMOTE_TRUE , currLine , numOfSubscriptions ) ;
}
2024-06-20 13:00:01 +03:00
else if ( currRegime = = DATA_DISTR | | currRegime = = SHARED_MEMORY_PAR )
2023-09-14 19:43:13 +03:00
{
const pair < bool , string > & arrayRefString = constructArrayRefForPrint ( arrayRef , dimNum , origSubscr ) ;
__spf_print ( 1 , " WARN: can not calculate index expression for array ref '%s' at line %d \n " , arrayRefString . second . c_str ( ) , currLine ) ;
addInfoToVectors ( loopInfo , parentLoops [ position ] , currOrigArrayS , dimNum , coefs , UNREC_OP , numOfSubscriptions , currentW ) ;
if ( side = = LEFT )
allPositions . clear ( ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " can not calculate index expression for array ref '%s' " , to_wstring ( arrayRefString . second ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R57 , to_wstring ( arrayRefString . second ) . c_str ( ) ) ;
if ( currLine > 0 )
currMessages - > push_back ( Messages ( WARR , currLine , messageR , messageE , 1023 ) ) ;
}
}
else
{
if ( currRegime = = REMOTE_ACC )
{
if ( side = = RIGHT )
{
vector < ArrayOp > & currOp = loopInfo [ parentLoops [ position ] ] [ currOrigArrayS ] . arrayAccess [ arrayRef ] . second ;
if ( currOp . size ( ) < numOfSubscriptions )
currOp . resize ( numOfSubscriptions ) ;
//add only uniq
auto itAdd = currOp [ dimNum ] . coefficients . find ( coefs ) ;
if ( itAdd = = currOp [ dimNum ] . coefficients . end ( ) )
itAdd = currOp [ dimNum ] . coefficients . insert ( itAdd , make_pair ( coefs , currentW ) ) ;
}
if ( coefs . first < 0 )
addInfoToMap ( loopInfo , parentLoops [ position ] , currOrigArrayS , arrayRef , dimNum , REMOTE_TRUE , currLine , numOfSubscriptions ) ;
else
//if we found regular access to array - set it false
addInfoToMap ( loopInfo , parentLoops [ position ] , currOrigArrayS , arrayRef , dimNum , REMOTE_FALSE , currLine , numOfSubscriptions ) ;
}
2024-06-19 18:08:27 +03:00
if ( coefs . first < 0 & & sharedMemoryParallelization = = 0 )
2023-09-14 19:43:13 +03:00
{
if ( currRegime = = DATA_DISTR )
{
const pair < bool , string > & arrayRefString = constructArrayRefForPrint ( arrayRef , dimNum , origSubscr ) ;
const int line = ( currLine < 0 ) ? parentLoops [ position ] - > localLineNumber ( ) : currLine ;
__spf_print ( 1 , " WARN: coefficient A in A*x+B is not positive for array ref '%s' at line %d, inverse distribution in not supported yet \n " , arrayRefString . second . c_str ( ) , line ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " coefficient A in A*x+B is not positive for array ref '%s', inverse distribution in not supported yet " , to_wstring ( arrayRefString . second ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R58 , to_wstring ( arrayRefString . second ) . c_str ( ) ) ;
if ( line > 0 )
currMessages - > push_back ( Messages ( WARR , line , messageR , messageE , 1024 ) ) ;
if ( side = = LEFT )
allPositions . clear ( ) ;
else
addInfoToVectors ( loopInfo , parentLoops [ position ] , currOrigArrayS , dimNum , coefs , UNREC_OP , numOfSubscriptions , currentW ) ;
}
}
else
{
if ( side = = LEFT )
addInfoToVectors ( loopInfo , parentLoops [ position ] , currOrigArrayS , dimNum , coefs , WRITE_OP , numOfSubscriptions , currentW ) ;
else
addInfoToVectors ( loopInfo , parentLoops [ position ] , currOrigArrayS , dimNum , coefs , READ_OP , numOfSubscriptions , currentW ) ;
}
}
}
if ( currRegime = = ARRAY_ACC_CORNER )
{
int * valueSubs = new int [ 2 ] ;
valueSubs [ 0 ] = coefs . first ;
valueSubs [ 1 ] = coefs . second ;
# ifdef __SPF
addToCollection ( __LINE__ , __FILE__ , valueSubs , 2 ) ;
# endif
const vector < int * > & coefs = getAttributes < SgExpression * , int * > ( subscr , set < int > { INT_VAL } ) ;
if ( coefs . size ( ) = = 0 )
{
subscr - > addAttribute ( INT_VAL , valueSubs , sizeof ( int * ) ) ;
if ( position ! = - 1 & & allPositions . size ( ) = = 1 & & position < parentLoops . size ( ) )
subscr - > addAttribute ( FOR_NODE , parentLoops [ position ] , sizeof ( SgStatement ) ) ;
}
}
return allPositions ;
}
2024-06-20 13:00:01 +03:00
static vector < int > matchArrayToLoopSymbols ( const vector < SgForStmt * > & parentLoops , vector < set < string > > & privatesVarsForLoop ,
SgExpression * currExp , const int side ,
2023-09-14 19:43:13 +03:00
map < SgForStmt * , map < SgSymbol * , ArrayInfo > > & loopInfo , const int currLine ,
map < int , LoopGraph * > & sortedLoopGraph , const ParallelRegion * reg , const double currentW ,
const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls )
{
SgArrayRefExp * arrayRef = ( SgArrayRefExp * ) currExp ;
int numOfSubs = arrayRef - > numberOfSubscripts ( ) ;
currExp = currExp - > lhs ( ) ;
vector < int > wasFoundForLoop ( parentLoops . size ( ) ) ;
vector < int > matched ( numOfSubs ) ;
vector < int > matchedToDim ( parentLoops . size ( ) ) ;
std : : fill ( wasFoundForLoop . begin ( ) , wasFoundForLoop . end ( ) , 0 ) ;
std : : fill ( matched . begin ( ) , matched . end ( ) , - 1 ) ;
std : : fill ( matchedToDim . begin ( ) , matchedToDim . end ( ) , - 1 ) ;
int maxMatched = 0 ;
int sumMatched = 0 ;
for ( int i = 0 ; i < numOfSubs ; + + i )
{
vector < int > matchToLoops = matchSubscriptToLoopSymbols ( parentLoops , currExp - > lhs ( ) , arrayRef , side , i , loopInfo , currLine , numOfSubs , currentW ) ;
for ( int k = 0 ; k < matchToLoops . size ( ) ; + + k )
{
wasFoundForLoop [ matchToLoops [ k ] ] + + ;
matchedToDim [ matchToLoops [ k ] ] = i ;
}
matched [ i ] = matchToLoops . size ( ) ;
sumMatched + = matchToLoops . size ( ) ;
maxMatched = std : : max ( maxMatched , ( int ) matchToLoops . size ( ) ) ;
currExp = currExp - > rhs ( ) ;
}
//full array is used, add unknown operations to all loops
if ( numOfSubs = = 0 )
{
SgSymbol * currOrigArrayS = OriginalSymbol ( arrayRef - > symbol ( ) ) ;
auto arrType = isSgArrayType ( currOrigArrayS - > type ( ) ) ;
if ( arrType ! = NULL )
{
for ( int d = 0 ; d < arrType - > dimension ( ) ; + + d )
for ( int i = 0 ; i < parentLoops . size ( ) ; + + i )
addInfoToVectors ( loopInfo , parentLoops [ i ] , currOrigArrayS , d , make_pair ( 0 , 0 ) , UNREC_OP , arrType - > dimension ( ) , currentW ) ;
}
}
if ( currRegime = = ARRAY_ACC_CORNER )
return wasFoundForLoop ;
bool ifUnknownArrayAssignFound = false ;
vector < int > canNotMapToLoop ;
for ( int i = 0 ; i < wasFoundForLoop . size ( ) ; + + i )
{
2024-06-20 13:00:01 +03:00
if ( wasFoundForLoop [ i ] ! = 1 & &
// always true for distributed data case
privatesVarsForLoop [ i ] . find ( string ( arrayRef - > symbol ( ) - > identifier ( ) ) ) = = privatesVarsForLoop [ i ] . end ( ) )
2023-09-14 19:43:13 +03:00
{
auto itLoop = sortedLoopGraph . find ( parentLoops [ i ] - > lineNumber ( ) ) ;
if ( itLoop = = sortedLoopGraph . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
ifUnknownArrayAssignFound = true ;
2024-07-16 20:35:33 +03:00
if ( side = = LEFT & & ( currRegime = = DATA_DISTR | | currRegime = = COMP_DISTR | | currRegime = = SHARED_MEMORY_PAR ) )
2023-09-14 19:43:13 +03:00
itLoop - > second - > hasUnknownArrayAssigns = true ;
itLoop - > second - > hasUnknownDistributedMap = true ;
canNotMapToLoop . push_back ( parentLoops [ i ] - > lineNumber ( ) ) ;
}
}
if ( side = = LEFT )
{
2024-06-20 13:00:01 +03:00
if ( ifUnknownArrayAssignFound & & ( currRegime = = DATA_DISTR | | currRegime = = SHARED_MEMORY_PAR ) )
2023-09-14 19:43:13 +03:00
{
const string arrayRefS = arrayRef - > unparse ( ) ;
for ( auto & line : canNotMapToLoop )
{
__spf_print ( 1 , " WARN: can not map write to array '%s' to loop on line %d \n " , arrayRefS . c_str ( ) , line ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " can not map write to array '%s' to this loop " , to_wstring ( arrayRefS ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R59 , to_wstring ( arrayRefS ) . c_str ( ) ) ;
if ( line > 0 )
currMessages - > push_back ( Messages ( WARR , line , messageR , messageE , 1025 ) ) ;
}
}
}
else if ( side = = RIGHT )
{
SgSymbol * currOrigArrayS = OriginalSymbol ( arrayRef - > symbol ( ) ) ;
if ( currRegime = = REMOTE_ACC )
{
DIST : : Array * currArray = getArrayFromDeclarated ( declaratedInStmt ( currOrigArrayS ) , currOrigArrayS - > identifier ( ) ) ;
if ( ! currArray & & currOrigArrayS - > type ( ) - > variant ( ) = = T_ARRAY )
checkNull ( currArray , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( currArray )
{
// for integration with SAPFOR-C
map < LoopGraph * , map < DIST : : Array * , ArrayInfo * > > tmpInfo ;
vector < LoopGraph * > parentGraphLoops ;
auto tmpRef = new ArrayRefExp ( arrayRef ) ;
for ( auto & loop : parentLoops )
{
auto it = sortedLoopGraph . find ( loop - > lineNumber ( ) ) ;
if ( it = = sortedLoopGraph . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
parentGraphLoops . push_back ( it - > second ) ;
}
auto requests = checkArrayRefInLoopForRemoteStatus ( ifUnknownArrayAssignFound , sumMatched , numOfSubs , maxMatched ,
currLine , currArray , wasFoundForLoop , tmpRef ,
tmpInfo , matchedToDim , sortedLoopGraph , arrayLinksByFuncCalls ,
reg , parentGraphLoops ) ;
//clean memory
for ( auto & loop : tmpInfo )
for ( auto & array : loop . second )
delete array . second ;
for ( auto & req : requests )
addInfoToMap ( loopInfo , ( SgForStmt * ) req . position - > loop - > GetOriginal ( ) , currOrigArrayS , arrayRef , req . dimNum , req . value , req . currLine , req . maxDimSize ) ;
}
}
}
return wasFoundForLoop ;
}
static void mapArrayRef ( SgStatement * currentSt , SgExpression * currExp ,
2024-06-20 13:00:01 +03:00
const vector < SgForStmt * > & parentLoops , vector < set < string > > & privatesVarsForLoop ,
const int side , const int lineNum ,
2023-09-14 19:43:13 +03:00
map < SgForStmt * , map < SgSymbol * , ArrayInfo > > & loopInfo ,
map < int , LoopGraph * > & sortedLoopGraph , map < string , pair < SgSymbol * , SgStatement * > > & notMappedDistributedArrays ,
set < string > & mappedDistrbutedArrays ,
const ParallelRegion * reg , const double currentW , const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls )
{
const char * printSide = NULL ;
if ( PRINT_ARRAY_ARCS )
printBlanks ( 2 , ( int ) parentLoops . size ( ) ) ;
if ( side = = LEFT )
printSide = " W_OP " ;
else
printSide = " R_OP " ;
__spf_print ( PRINT_ARRAY_ARCS , " %s to array <%s> on line %d: " , printSide , OriginalSymbol ( currExp - > symbol ( ) ) - > identifier ( ) , lineNum ) ;
bool wasMapped = false ;
2024-06-20 13:00:01 +03:00
vector < int > matched = matchArrayToLoopSymbols ( parentLoops , privatesVarsForLoop , currExp , side , loopInfo , lineNum , sortedLoopGraph , reg , currentW , arrayLinksByFuncCalls ) ;
2023-09-14 19:43:13 +03:00
for ( int z = 0 ; z < matched . size ( ) ; + + z )
wasMapped | = ( matched [ z ] ! = 0 ) ;
if ( parentLoops . size ( ) = = 0 )
{
SgSymbol * symb = currExp - > symbol ( ) ;
if ( symb - > type ( ) - > variant ( ) = = T_ARRAY )
notMappedDistributedArrays [ symb - > identifier ( ) ] = make_pair ( symb , currentSt ) ;
}
else
{
if ( wasMapped )
mappedDistrbutedArrays . insert ( currExp - > symbol ( ) - > identifier ( ) ) ;
else
{
SgSymbol * symb = currExp - > symbol ( ) ;
if ( symb - > type ( ) - > variant ( ) = = T_ARRAY )
notMappedDistributedArrays [ symb - > identifier ( ) ] = make_pair ( symb , currentSt ) ;
}
}
__spf_print ( PRINT_ARRAY_ARCS , " \n " ) ;
}
2024-03-26 13:59:48 +03:00
static void findArrayRef ( const vector < SgForStmt * > & parentLoops , SgExpression * currExp , const int lineNum , const int side ,
2023-09-14 19:43:13 +03:00
map < SgForStmt * , map < SgSymbol * , ArrayInfo > > & loopInfo , const set < string > & privatesVars ,
vector < set < string > > & privatesVarsForLoop , map < int , LoopGraph * > & sortedLoopGraph ,
const map < string , vector < SgExpression * > > & commonBlocks ,
const map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays ,
bool wasDistributedArrayRef , map < string , pair < SgSymbol * , SgStatement * > > & notMappedDistributedArrays ,
set < string > & mappedDistrbutedArrays , SgStatement * currentSt , const ParallelRegion * reg , const double currentW ,
const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls )
{
int nextSide = side ;
if ( isArrayRef ( currExp ) )
{
//... and current array is not in private list
2024-06-20 13:00:01 +03:00
if ( sharedMemoryParallelization | |
privatesVars . find ( string ( OriginalSymbol ( currExp - > symbol ( ) ) - > identifier ( ) ) ) = = privatesVars . end ( ) )
2023-09-14 19:43:13 +03:00
{
if ( wasDistributedArrayRef )
{
int depth = 1 ;
for ( int i = parentLoops . size ( ) - 1 ; i > = 0 ; - - i , + + depth )
{
auto itLoop = sortedLoopGraph . find ( parentLoops [ i ] - > lineNumber ( ) ) ;
if ( itLoop = = sortedLoopGraph . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( itLoop - > second - > perfectLoop ! = depth )
break ;
2024-06-20 13:00:01 +03:00
if ( ! ( sharedMemoryParallelization & & side = = RIGHT ) )
itLoop - > second - > hasIndirectAccess = true ;
2023-09-14 19:43:13 +03:00
}
2024-06-20 13:00:01 +03:00
mapArrayRef ( currentSt , currExp , parentLoops , privatesVarsForLoop , side , lineNum , loopInfo , sortedLoopGraph ,
2023-09-14 19:43:13 +03:00
notMappedDistributedArrays , mappedDistrbutedArrays , reg , currentW , arrayLinksByFuncCalls ) ;
}
else
{
wasDistributedArrayRef = true ;
2024-06-20 13:00:01 +03:00
mapArrayRef ( currentSt , currExp , parentLoops , privatesVarsForLoop , side , lineNum , loopInfo , sortedLoopGraph ,
2023-09-14 19:43:13 +03:00
notMappedDistributedArrays , mappedDistrbutedArrays , reg , currentW , arrayLinksByFuncCalls ) ;
}
}
2024-06-20 13:00:01 +03:00
else if ( currRegime = = DATA_DISTR & & side = = LEFT )
2023-09-14 19:43:13 +03:00
{
2024-06-20 13:00:01 +03:00
auto symb = OriginalSymbol ( currExp - > symbol ( ) ) ;
SgStatement * decl = declaratedInStmt ( symb ) ;
auto uniqKey = getUniqName ( commonBlocks , decl , symb ) ;
2023-09-14 19:43:13 +03:00
2024-06-20 13:00:01 +03:00
auto itFound = declaredArrays . find ( uniqKey ) ;
if ( itFound = = declaredArrays . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
2023-09-14 19:43:13 +03:00
2024-06-20 13:00:01 +03:00
//TODO: array access to non distributed arrays, add CONSISTENT
if ( itFound - > second . first - > GetDistributeFlagVal ( ) ! = DIST : : DISTR )
{
set < string > loopsPrivates ;
set < Symbol * > loopsPrivatesS ;
set < string > loopsRedUnited ;
map < string , set < Symbol * > > loopsReductions ;
map < string , set < tuple < Symbol * , Symbol * , int > > > loopsReductionsLoc ;
2023-09-14 19:43:13 +03:00
2024-06-20 13:00:01 +03:00
for ( int z = 0 ; z < parentLoops . size ( ) ; + + z )
2023-09-14 19:43:13 +03:00
{
2024-06-20 13:00:01 +03:00
auto & loop = parentLoops [ z ] ;
for ( auto & data : getAttributes < SgStatement * , SgStatement * > ( loop , set < int > { SPF_ANALYSIS_DIR } ) )
2023-09-14 19:43:13 +03:00
{
2024-06-20 13:00:01 +03:00
fillPrivatesFromComment ( new Statement ( data ) , loopsPrivatesS ) ;
for ( auto & elem : loopsPrivatesS )
loopsPrivates . insert ( elem - > GetOriginal ( ) - > identifier ( ) ) ;
fillReductionsFromComment ( new Statement ( data ) , loopsReductions ) ;
fillReductionsFromComment ( new Statement ( data ) , loopsReductionsLoc ) ;
2023-09-14 19:43:13 +03:00
}
2024-06-20 13:00:01 +03:00
}
2023-09-14 19:43:13 +03:00
2024-06-20 13:00:01 +03:00
for ( auto & elem : loopsReductions )
{
for ( auto & setElem : elem . second )
2023-09-14 19:43:13 +03:00
{
2024-06-20 13:00:01 +03:00
loopsPrivates . insert ( setElem - > GetOriginal ( ) - > identifier ( ) ) ;
loopsRedUnited . insert ( setElem - > GetOriginal ( ) - > identifier ( ) ) ;
2023-09-14 19:43:13 +03:00
}
2024-06-20 13:00:01 +03:00
}
2023-09-14 19:43:13 +03:00
2024-06-20 13:00:01 +03:00
for ( auto & elem : loopsReductionsLoc )
{
for ( auto & setElem : elem . second )
2023-09-14 19:43:13 +03:00
{
2024-06-20 13:00:01 +03:00
loopsPrivates . insert ( get < 0 > ( setElem ) - > GetOriginal ( ) - > identifier ( ) ) ;
loopsPrivates . insert ( get < 1 > ( setElem ) - > GetOriginal ( ) - > identifier ( ) ) ;
loopsRedUnited . insert ( get < 0 > ( setElem ) - > GetOriginal ( ) - > identifier ( ) ) ;
loopsRedUnited . insert ( get < 1 > ( setElem ) - > GetOriginal ( ) - > identifier ( ) ) ;
2023-09-14 19:43:13 +03:00
}
2024-06-20 13:00:01 +03:00
}
2023-09-14 19:43:13 +03:00
2024-06-20 13:00:01 +03:00
const string key = string ( OriginalSymbol ( currExp - > symbol ( ) ) - > identifier ( ) ) ;
if ( loopsPrivates . find ( key ) = = loopsPrivates . end ( ) )
{
for ( auto & loop : parentLoops )
2023-09-14 19:43:13 +03:00
{
2024-06-20 13:00:01 +03:00
__spf_print ( 1 , " WARN: write to non distributed array '%s' in loop on line %d \n " , symb - > identifier ( ) , loop - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
2024-06-20 13:00:01 +03:00
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " write to non distributed array '%s' in this loop " , to_wstring ( symb - > identifier ( ) ) . c_str ( ) ) ;
2023-09-14 19:43:13 +03:00
2024-06-20 13:00:01 +03:00
__spf_printToLongBuf ( messageR , R61 , to_wstring ( symb - > identifier ( ) ) . c_str ( ) ) ;
2023-09-14 19:43:13 +03:00
2024-06-20 13:00:01 +03:00
if ( loop - > lineNumber ( ) > 0 )
currMessages - > push_back ( Messages ( WARR , loop - > lineNumber ( ) , messageR , messageE , 1026 ) ) ;
sortedLoopGraph [ loop - > lineNumber ( ) ] - > hasWritesToNonDistribute = true ;
2023-09-14 19:43:13 +03:00
}
2024-06-20 13:00:01 +03:00
}
2023-09-14 19:43:13 +03:00
2024-06-20 13:00:01 +03:00
if ( loopsPrivates . find ( key ) ! = loopsPrivates . end ( ) | | loopsRedUnited . find ( key ) ! = loopsRedUnited . end ( ) )
{
auto currOrigArrayS = OriginalSymbol ( currExp - > symbol ( ) ) ;
if ( currOrigArrayS - > type ( ) - > variant ( ) = = T_ARRAY )
2023-09-14 19:43:13 +03:00
{
2024-06-20 13:00:01 +03:00
DIST : : Array * currArray = getArrayFromDeclarated ( declaratedInStmt ( currOrigArrayS ) , currOrigArrayS - > identifier ( ) ) ;
checkNull ( currArray , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
2023-09-14 19:43:13 +03:00
{
2024-06-20 13:00:01 +03:00
set < DIST : : Array * > realArrayRefs ;
getRealArrayRefs ( currArray , currArray , realArrayRefs , arrayLinksByFuncCalls ) ;
2023-09-14 19:43:13 +03:00
2024-06-20 13:00:01 +03:00
for ( auto & array : realArrayRefs )
array - > SetPrivateInLoopStatus ( true ) ;
2023-09-14 19:43:13 +03:00
}
}
}
}
}
nextSide = ( side = = LEFT ) ? RIGHT : side ;
}
bool needToContinue = true ;
if ( currExp - > variant ( ) = = FUNC_CALL )
{
SgFunctionCallExp * funcExp = ( SgFunctionCallExp * ) currExp ;
auto currFunc = isUserFunctionInProject ( funcExp - > funName ( ) - > identifier ( ) ) ;
if ( currFunc )
{
for ( int z = 0 ; z < funcExp - > numberOfArgs ( ) ; + + z )
{
if ( ( currFunc - > funcParams . inout_types [ z ] & OUT_BIT ) ! = 0 )
nextSide = LEFT ;
else
nextSide = RIGHT ;
findArrayRef ( parentLoops , funcExp - > arg ( z ) , lineNum , nextSide , loopInfo , privatesVars , privatesVarsForLoop , sortedLoopGraph ,
commonBlocks , declaredArrays , wasDistributedArrayRef , notMappedDistributedArrays ,
mappedDistrbutedArrays , currentSt , reg , currentW , arrayLinksByFuncCalls ) ;
}
needToContinue = false ;
}
}
if ( needToContinue )
{
if ( currExp - > lhs ( ) )
findArrayRef ( parentLoops , currExp - > lhs ( ) , lineNum , nextSide , loopInfo , privatesVars , privatesVarsForLoop , sortedLoopGraph ,
commonBlocks , declaredArrays , wasDistributedArrayRef , notMappedDistributedArrays ,
mappedDistrbutedArrays , currentSt , reg , currentW , arrayLinksByFuncCalls ) ;
if ( currExp - > rhs ( ) )
findArrayRef ( parentLoops , currExp - > rhs ( ) , lineNum , nextSide , loopInfo , privatesVars , privatesVarsForLoop , sortedLoopGraph ,
commonBlocks , declaredArrays , wasDistributedArrayRef , notMappedDistributedArrays ,
mappedDistrbutedArrays , currentSt , reg , currentW , arrayLinksByFuncCalls ) ;
}
}
# define FIRST(x) get<0>(x)
# define SECOND(x) get<1>(x)
# define THIRD(x) get<2>(x)
map < string , string > shortFileNames ;
static int uniqfileNames = 0 ;
string getShortName ( const tuple < int , string , string > & uniqKey )
{
const char * declFileName = SECOND ( uniqKey ) . c_str ( ) ;
const char * varName = THIRD ( uniqKey ) . c_str ( ) ;
const int position = FIRST ( uniqKey ) ;
map < string , string > : : iterator it ;
it = shortFileNames . find ( string ( declFileName ) ) ;
string retVal = " " ;
if ( it = = shortFileNames . end ( ) )
{
retVal = string ( " f " ) + std : : to_string ( uniqfileNames ) + string ( " _ " ) ;
shortFileNames [ string ( declFileName ) ] = retVal ;
uniqfileNames + + ;
}
else
retVal = it - > second ;
return retVal + std : : to_string ( position ) + string ( " _ " ) + string ( varName ) ;
}
static int fillSizes ( SgExpression * res , int & left , int & right )
{
int err = 0 ;
if ( res - > lhs ( ) - > variant ( ) = = INT_VAL )
left = res - > lhs ( ) - > valueInteger ( ) ;
else if ( res - > lhs ( ) - > variant ( ) = = MINUS_OP )
left = - 1 * res - > lhs ( ) - > lhs ( ) - > valueInteger ( ) ;
else
err = - 1 ;
if ( res - > rhs ( ) - > variant ( ) = = INT_VAL )
right = res - > rhs ( ) - > valueInteger ( ) ;
else if ( res - > rhs ( ) - > variant ( ) = = MINUS_OP )
right = - 1 * res - > rhs ( ) - > lhs ( ) - > valueInteger ( ) ;
else
err = - 1 ;
return err ;
}
static pair < Expression * , Expression * > getElem ( SgExpression * exp )
{
if ( exp - > lhs ( ) & & exp - > rhs ( ) )
return make_pair ( new Expression ( exp - > lhs ( ) ) , new Expression ( exp - > rhs ( ) ) ) ;
else if ( exp - > lhs ( ) )
return make_pair ( new Expression ( exp - > lhs ( ) ) , ( Expression * ) NULL ) ;
else if ( exp - > rhs ( ) )
return make_pair ( ( Expression * ) NULL , new Expression ( exp - > rhs ( ) ) ) ;
else
return make_pair ( ( Expression * ) NULL , ( Expression * ) NULL ) ;
}
static void fillIdsFromEx ( SgExpression * ex , set < string > & ids )
{
if ( ex )
{
if ( ex - > variant ( ) = = VAR_REF )
ids . insert ( ex - > symbol ( ) - > identifier ( ) ) ;
fillIdsFromEx ( ex - > lhs ( ) , ids ) ;
fillIdsFromEx ( ex - > rhs ( ) , ids ) ;
}
}
static void doReplacement ( SgExpression * ex , const map < string , int > & idsToIdx , const map < int , set < int > > & values )
{
if ( ex )
{
if ( ex - > lhs ( ) & & ex - > lhs ( ) - > variant ( ) = = VAR_REF )
{
string key = ex - > lhs ( ) - > symbol ( ) - > identifier ( ) ;
auto it = idsToIdx . find ( key ) ;
if ( it ! = idsToIdx . end ( ) )
{
if ( values . find ( it - > second ) ! = values . end ( ) )
{
const int value = * values . find ( it - > second ) - > second . begin ( ) ;
ex - > setLhs ( * new SgValueExp ( value ) ) ;
}
}
}
if ( ex - > rhs ( ) & & ex - > rhs ( ) - > variant ( ) = = VAR_REF )
{
string key = ex - > rhs ( ) - > symbol ( ) - > identifier ( ) ;
auto it = idsToIdx . find ( key ) ;
if ( it ! = idsToIdx . end ( ) )
{
const int value = * values . find ( it - > second ) - > second . begin ( ) ;
ex - > setRhs ( * new SgValueExp ( value ) ) ;
}
}
doReplacement ( ex - > lhs ( ) , idsToIdx , values ) ;
doReplacement ( ex - > rhs ( ) , idsToIdx , values ) ;
}
}
static SgExpression * replaceConstatantProcedurePars ( SgExpression * dimList , SgStatement * proc , const map < string , vector < FuncInfo * > > & allFuncInfo )
{
if ( proc = = NULL )
return dimList ;
if ( allFuncInfo . size ( ) = = 0 )
return dimList ;
const string procN = proc - > symbol ( ) - > identifier ( ) ;
map < string , FuncInfo * > mapFunc ;
createMapOfFunc ( allFuncInfo , mapFunc ) ;
auto it = mapFunc . find ( procN ) ;
if ( it = = mapFunc . end ( ) )
return dimList ;
FuncInfo * currF = it - > second ;
if ( currF - > funcParams . countOfPars = = 0 )
return dimList ;
set < string > ids ;
fillIdsFromEx ( dimList , ids ) ;
if ( ids . size ( ) = = 0 )
return dimList ;
set < int > idxFound ;
map < string , int > idsToIdx ;
for ( int z = 0 ; z < currF - > funcParams . countOfPars ; + + z )
{
if ( ids . find ( currF - > funcParams . identificators [ z ] ) ! = ids . end ( ) )
{
idxFound . insert ( z ) ;
idsToIdx [ currF - > funcParams . identificators [ z ] ] = z ;
}
}
if ( idxFound . size ( ) = = 0 | | currF - > callsTo . size ( ) = = 0 )
return dimList ;
map < int , set < int > > values ;
//TODO: many call levels of functions
for ( int z = 0 ; z < currF - > callsTo . size ( ) ; + + z )
{
FuncInfo * callOfThis = currF - > callsTo [ z ] ;
2023-11-05 13:08:57 +03:00
for ( int p = 0 ; p < callOfThis - > callsFromDetailed . size ( ) ; + + p )
2023-09-14 19:43:13 +03:00
{
2023-11-05 13:08:57 +03:00
if ( callOfThis - > callsFromDetailed [ p ] . detailCallsFrom . first = = procN )
2023-09-14 19:43:13 +03:00
{
for ( auto & par : idxFound )
{
2023-11-05 13:08:57 +03:00
auto parType = callOfThis - > callsFromDetailed [ p ] . actualParams . parametersT [ par ] ;
2023-09-14 19:43:13 +03:00
if ( parType ! = SCALAR_INT_T )
return dimList ;
else
{
2023-11-05 13:08:57 +03:00
if ( callOfThis - > callsFromDetailed [ p ] . actualParams . parameters [ par ] = = NULL )
2023-09-14 19:43:13 +03:00
return dimList ;
2023-11-05 13:08:57 +03:00
values [ par ] . insert ( ( ( int * ) ( callOfThis - > callsFromDetailed [ p ] . actualParams . parameters [ par ] ) ) [ 0 ] ) ;
2023-09-14 19:43:13 +03:00
}
}
}
}
}
for ( auto & elem : values )
if ( elem . second . size ( ) ! = 1 )
return dimList ;
doReplacement ( dimList , idsToIdx , values ) ;
return dimList ;
}
2024-11-21 15:07:16 +03:00
vector < pair < Expression * , Expression * > > getArraySizes ( vector < pair < int , int > > & sizes , SgSymbol * symb , SgStatement * decl ,
const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls ,
const map < string , vector < FuncInfo * > > & allFuncInfo )
2023-09-14 19:43:13 +03:00
{
SgArrayType * type = isSgArrayType ( symb - > type ( ) ) ;
vector < pair < Expression * , Expression * > > retVal ;
if ( type ! = NULL )
{
SgExpression * dimList = type - > getDimList ( ) - > copyPtr ( ) ;
int consistInAllocates = 0 ;
set < string > allocValues ;
SgExpression * alloc = NULL ;
dimList = replaceConstatantProcedurePars ( dimList , getFuncStat ( decl , { MODULE_STMT , BLOCK_DATA } ) , allFuncInfo ) ;
while ( dimList )
{
SgExpression * res = ReplaceArrayBoundSizes ( dimList - > lhs ( ) - > copyPtr ( ) ) ;
if ( res & & res - > variant ( ) = = INT_VAL )
{
sizes . push_back ( make_pair ( 1 , res - > valueInteger ( ) ) ) ;
retVal . push_back ( make_pair ( ( Expression * ) NULL , new Expression ( dimList - > lhs ( ) ) ) ) ;
}
else if ( res & & res - > variant ( ) = = DDOT )
{
int err , tmpRes ;
if ( res - > lhs ( ) )
{
err = CalculateInteger ( res - > lhs ( ) , tmpRes ) ;
if ( err ! = - 1 )
res - > setLhs ( new SgValueExp ( tmpRes ) ) ;
}
if ( res - > rhs ( ) )
{
err = CalculateInteger ( res - > rhs ( ) , tmpRes ) ;
if ( err ! = - 1 )
res - > setRhs ( new SgValueExp ( tmpRes ) ) ;
}
int left , right ;
bool ok = res - > lhs ( ) & & res - > rhs ( ) ;
if ( ok )
{
int err = fillSizes ( res , left , right ) ;
ok = ( err = = 0 ) ;
}
if ( ok )
{
sizes . push_back ( make_pair ( left , right ) ) ;
retVal . push_back ( getElem ( dimList - > lhs ( ) ) ) ;
}
else
{
if ( alloc = = NULL )
{
for ( auto & data : getAttributes < SgStatement * , SgStatement * > ( decl , set < int > { ALLOCATE_STMT } ) )
{
if ( data - > variant ( ) ! = ALLOCATE_STMT )
continue ;
//TODO:
if ( string ( data - > fileName ( ) ) ! = current_file - > filename ( ) )
continue ;
SgExpression * list = data - > expr ( 0 ) ;
while ( list )
{
SgArrayRefExp * arrayRef = isSgArrayRefExp ( list - > lhs ( ) ) ;
if ( arrayRef ! = NULL )
{
SgSymbol * origS = OriginalSymbol ( arrayRef - > symbol ( ) ) ;
DIST : : Array * currArray = getArrayFromDeclarated ( declaratedInStmt ( origS ) , origS - > identifier ( ) ) ;
string toCmp = string ( origS - > identifier ( ) ) ;
//TODO: extend
if ( currArray & & currArray - > GetLocation ( ) . first = = DIST : : l_PARAMETER )
{
auto it = arrayLinksByFuncCalls . find ( currArray ) ;
if ( it ! = arrayLinksByFuncCalls . end ( ) )
{
bool found = false ;
for ( auto & elem : it - > second )
{
if ( elem - > GetLocation ( ) . first ! = DIST : : l_PARAMETER )
{
if ( elem - > GetShortName ( ) = = string ( symb - > identifier ( ) ) )
{
consistInAllocates + + ;
alloc = list - > lhs ( ) - > lhs ( ) ;
allocValues . insert ( alloc - > unparse ( ) ) ;
found = true ;
break ;
}
}
}
if ( found )
break ;
}
}
else
{
if ( toCmp = = string ( symb - > identifier ( ) ) )
{
consistInAllocates + + ;
alloc = list - > lhs ( ) - > lhs ( ) ;
allocValues . insert ( alloc - > unparse ( ) ) ;
break ;
}
}
}
list = list - > rhs ( ) ;
}
}
}
else // set next in list
alloc = alloc - > rhs ( ) ;
//TODO: dont check string representations of alloc expression!! check integer result, if all strings are equal
if ( consistInAllocates ! = 1 & & allocValues . size ( ) ! = 1 )
{
sizes . push_back ( make_pair ( - 1 , - 1 ) ) ;
retVal . push_back ( make_pair ( ( Expression * ) NULL , ( Expression * ) NULL ) ) ;
}
else
{
SgExpression * result = ReplaceArrayBoundSizes ( alloc - > lhs ( ) - > copyPtr ( ) ) ;
if ( result - > lhs ( ) )
{
err = CalculateInteger ( result - > lhs ( ) , tmpRes ) ;
if ( err ! = - 1 )
result - > setLhs ( new SgValueExp ( tmpRes ) ) ;
}
if ( result - > rhs ( ) )
{
err = CalculateInteger ( result - > rhs ( ) , tmpRes ) ;
if ( err ! = - 1 )
result - > setRhs ( new SgValueExp ( tmpRes ) ) ;
}
if ( result - > variant ( ) = = INT_VAL )
{
sizes . push_back ( make_pair ( 1 , result - > valueInteger ( ) ) ) ;
retVal . push_back ( make_pair ( ( Expression * ) NULL , new Expression ( alloc - > lhs ( ) ) ) ) ;
}
else if ( result - > variant ( ) = = DDOT )
{
retVal . push_back ( getElem ( alloc - > lhs ( ) ) ) ;
int left = 0 , right = 0 ;
bool ok = result - > lhs ( ) & & result - > rhs ( ) ;
if ( ok )
{
int err = fillSizes ( result , left , right ) ;
ok = ( err = = 0 ) ;
}
if ( ok )
sizes . push_back ( make_pair ( left , right ) ) ;
else
sizes . push_back ( make_pair ( - 1 , - 1 ) ) ;
}
else
{
sizes . push_back ( make_pair ( - 1 , - 1 ) ) ;
retVal . push_back ( make_pair ( ( Expression * ) NULL , ( Expression * ) NULL ) ) ;
}
}
}
}
else
{
sizes . push_back ( make_pair ( - 1 , - 1 ) ) ;
retVal . push_back ( make_pair ( ( Expression * ) NULL , ( Expression * ) NULL ) ) ;
}
dimList = dimList - > rhs ( ) ;
}
}
return retVal ;
}
void recalculateArraySizes ( set < DIST : : Array * > & arraysDone , const set < DIST : : Array * > & allArrays ,
const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls ,
const map < string , vector < FuncInfo * > > & allFuncInfo )
{
for ( auto & array : allArrays )
{
auto itF = arraysDone . find ( array ) ;
if ( itF ! = arraysDone . end ( ) )
continue ;
itF = arraysDone . insert ( itF , array ) ;
if ( array - > IsTemplate ( ) )
continue ;
SgSymbol * symb = array - > GetDeclSymbol ( ) - > GetOriginal ( ) ;
if ( ! symb )
continue ;
auto & sizeInfo = array - > GetSizes ( ) ;
bool needToUpdate = false ;
for ( auto & elem : sizeInfo )
{
if ( elem . first = = elem . second )
{
needToUpdate = true ;
break ;
}
}
if ( ! needToUpdate )
continue ;
auto & declInfo = array - > GetDeclInfo ( ) ;
bool wasSelect = false ;
vector < int > files ;
pair < string , int > mainDecl ;
for ( auto & elem : declInfo )
{
int fileId = SgFile : : switchToFile ( elem . first ) ;
if ( fileId ! = - 1 )
{
files . push_back ( fileId ) ;
mainDecl = elem ;
SgFile * tmpfile = & ( CurrentProject - > file ( fileId ) ) ;
wasSelect = true ;
break ;
}
}
if ( ! wasSelect )
{
//try to find in includes
for ( int i = CurrentProject - > numberOfFiles ( ) - 1 ; i > = 0 ; - - i )
{
SgFile * file = & ( CurrentProject - > file ( i ) ) ;
for ( SgStatement * st = file - > firstStatement ( ) ; st ; st = st - > lexNext ( ) )
{
for ( auto & elem : declInfo )
{
if ( make_pair ( string ( st - > fileName ( ) ) , st - > lineNumber ( ) ) = = elem )
{
wasSelect = true ;
break ;
}
}
if ( wasSelect )
{
//wasSelect = false;
SgStatement * decl = declaratedInStmt ( symb ) ;
vector < pair < int , int > > sizes ;
auto sizesEx = getArraySizes ( sizes , symb , decl , arrayLinksByFuncCalls , allFuncInfo ) ;
array - > SetSizes ( sizes ) ;
array - > SetSizesExpr ( sizesEx ) ;
}
}
if ( wasSelect )
break ;
}
if ( ! wasSelect )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
else
{
if ( wasSelect )
{
if ( array - > GetLocation ( ) . first = = DIST : : l_MODULE )
{
files . clear ( ) ;
for ( int i = CurrentProject - > numberOfFiles ( ) - 1 ; i > = 0 ; - - i )
files . push_back ( i ) ;
}
for ( auto & file : files )
{
CurrentProject - > file ( file ) ;
SgStatement * decl = NULL ;
string currF = current_file - > filename ( ) ;
if ( array - > GetLocation ( ) . first = = DIST : : l_MODULE )
{
SgStatement * st = current_file - > firstStatement ( ) ;
while ( st )
{
if ( st - > lineNumber ( ) = = mainDecl . second & & st - > fileName ( ) = = mainDecl . first )
{
decl = st ;
symb = NULL ;
SgExpression * ex = decl - > expr ( 0 ) ;
while ( ex )
{
if ( ex - > lhs ( ) & & isArrayRef ( ex - > lhs ( ) ) )
{
auto s = ex - > lhs ( ) - > symbol ( ) ;
if ( s & & s - > identifier ( ) = = array - > GetShortName ( ) )
{
symb = s ;
break ;
}
}
ex = ex - > rhs ( ) ;
}
break ;
}
st = st - > lexNext ( ) ;
}
}
else
{
if ( symb - > getFileId ( ) ! = current_file_id )
{
SgStatement * st = current_file - > firstStatement ( ) ;
int lastLine = 1 ;
while ( st )
{
if ( st - > lineNumber ( ) > lastLine )
lastLine = st - > lineNumber ( ) ;
st = st - > lexNext ( ) ;
}
symb = array - > GetDeclSymbol ( currF , make_pair ( 1 , lastLine ) , getAllFilesInProject ( ) ) - > GetOriginal ( ) ;
}
decl = declaratedInStmt ( symb , NULL , false ) ;
}
if ( decl = = NULL )
continue ;
if ( symb = = NULL )
{
decl - > unparsestdout ( ) ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
vector < pair < int , int > > sizes ;
auto sizesEx = getArraySizes ( sizes , symb , decl , arrayLinksByFuncCalls , allFuncInfo ) ;
if ( array - > GetDimSize ( ) ! = sizes . size ( ) )
{
sizes . clear ( ) ;
auto sizesEx = getArraySizes ( sizes , symb , decl , arrayLinksByFuncCalls , allFuncInfo ) ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
array - > SetSizes ( sizes ) ;
array - > SetSizesExpr ( sizesEx ) ;
bool needToContinue = false ;
for ( auto & elem : sizes )
{
if ( elem . first = = elem . second )
{
needToContinue = true ;
break ;
}
}
if ( ! needToContinue )
break ;
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
}
bool isIntrinsic ( const char * funName )
{
if ( intrinsicF . find ( funName ) = = intrinsicF . end ( ) )
return false ;
else
return true ;
}
static set < string > getPrivatesFromModule ( SgStatement * mod ,
const map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays ,
const map < SgStatement * , set < tuple < int , string , string > > > & declaratedArraysSt ,
const map < string , SgStatement * > & modulesByName )
{
set < string > privates ;
SgStatement * end = mod - > lastNodeOfStmt ( ) ;
while ( mod ! = end & & mod - > lineNumber ( ) > 0 )
{
if ( mod - > variant ( ) = = CONTAINS_STMT )
break ;
if ( mod - > variant ( ) = = USE_STMT )
{
auto itF = modulesByName . find ( mod - > symbol ( ) - > identifier ( ) ) ;
if ( itF = = modulesByName . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
const set < string > recPrivates = getPrivatesFromModule ( itF - > second , declaredArrays , declaratedArraysSt , modulesByName ) ;
for ( auto it = recPrivates . begin ( ) ; it ! = recPrivates . end ( ) ; + + it )
privates . insert ( * it ) ;
}
else
{
tryToFindPrivateInAttributes ( mod , privates ) ;
fillNonDistrArraysAsPrivate ( mod , declaredArrays , declaratedArraysSt , privates ) ;
}
mod = mod - > lexNext ( ) ;
}
return privates ;
}
extern map < DIST : : Array * , std : : tuple < int , string , string > > tableOfUniqNamesByArray ;
static void convertOneLoop ( LoopGraph * currLoop , map < LoopGraph * , map < DIST : : Array * , ArrayInfo * > > & outInfo ,
const map < SgSymbol * , ArrayInfo > & toConvert ,
const set < string > & privateArrays ,
const map < string , vector < SgExpression * > > & commonBlocks ,
const map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays ,
const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls ,
map < tuple < int , string , string > , DIST : : Array * > & createdArrays ,
bool freeArrays = false )
{
map < DIST : : Array * , ArrayInfo * > toAdd ;
for ( auto & conv : toConvert )
{
SgSymbol * currentArray = OriginalSymbol ( conv . first ) ;
ArrayInfo * currentInfo = ( ArrayInfo * ) ( & conv . second ) ;
DIST : : Array * arrayToAdd ;
SgStatement * decl = declaratedInStmt ( currentArray ) ;
const char * symbIdent = currentArray - > identifier ( ) ;
2024-06-20 13:00:01 +03:00
if ( privateArrays . find ( symbIdent ) = = privateArrays . end ( ) | | sharedMemoryParallelization )
2023-09-14 19:43:13 +03:00
{
const tuple < int , string , string > uniqKey = getUniqName ( commonBlocks , decl , currentArray ) ;
auto itFound = createdArrays . find ( uniqKey ) ;
if ( itFound = = createdArrays . end ( ) )
{
auto itArray = declaredArrays . find ( uniqKey ) ;
if ( itArray = = declaredArrays . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
arrayToAdd = itArray - > second . first ;
itFound = createdArrays . insert ( itFound , make_pair ( uniqKey , arrayToAdd ) ) ;
}
else
arrayToAdd = itFound - > second ;
2024-06-20 13:00:01 +03:00
if ( ! sharedMemoryParallelization & & arrayToAdd - > IsNotDistribute ( ) = = true )
2023-09-14 19:43:13 +03:00
continue ;
set < DIST : : Array * > links ;
getRealArrayRefs ( arrayToAdd , arrayToAdd , links , arrayLinksByFuncCalls ) ;
int countOflinks = 0 ;
for ( auto & linkedArray : links )
{
if ( arrayToAdd = = linkedArray )
continue ;
+ + countOflinks ;
auto key = tableOfUniqNamesByArray [ linkedArray ] ;
auto value = declaredArrays . find ( key ) - > second ;
if ( value . second = = 0 & & createdArrays . find ( key ) = = createdArrays . end ( ) )
createdArrays . insert ( make_pair ( key , linkedArray ) ) ;
}
if ( freeArrays )
if ( countOflinks = = 0 )
continue ;
toAdd [ arrayToAdd ] = currentInfo ;
for ( int z = 0 ; z < currentInfo - > getDimSize ( ) ; + + z )
{
if ( currentInfo - > readOps [ z ] . coefficients . size ( ) | | currentInfo - > writeOps [ z ] . coefficients . size ( ) )
{
arrayToAdd - > SetMappedDim ( z ) ;
for ( auto & realRef : links )
realRef - > SetMappedDim ( z ) ;
}
}
}
}
outInfo [ currLoop ] = toAdd ;
}
static map < LoopGraph * , map < DIST : : Array * , ArrayInfo * > >
convertLoopInfo ( const map < SgForStmt * , map < SgSymbol * , ArrayInfo > > & loopInfo ,
const map < int , LoopGraph * > & sortedLoopGraph ,
const set < string > & privateArrays ,
const map < string , vector < SgExpression * > > & commonBlocks ,
const map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays ,
const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls ,
map < tuple < int , string , string > , DIST : : Array * > & createdArrays )
{
map < LoopGraph * , map < DIST : : Array * , ArrayInfo * > > outInfo ;
for ( auto it = loopInfo . begin ( ) ; it ! = loopInfo . end ( ) ; + + it )
{
auto itGraph = sortedLoopGraph . find ( it - > first - > lineNumber ( ) ) ;
if ( itGraph = = sortedLoopGraph . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
convertOneLoop ( itGraph - > second , outInfo , it - > second , privateArrays , commonBlocks , declaredArrays , arrayLinksByFuncCalls , createdArrays ) ;
}
return outInfo ;
}
inline static void fillPrivatesFromDecl ( SgExpression * ex , set < SgSymbol * > & delcsSymbViewed , set < SgStatement * > & delcsStatViewed ,
const map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays ,
const map < SgStatement * , set < tuple < int , string , string > > > & declaratedArraysSt ,
set < string > & privatesVars )
{
if ( ! ex )
return ;
if ( isArrayRef ( ex ) )
{
SgSymbol * symb = ex - > symbol ( ) ;
if ( symb - > type ( ) )
{
if ( symb - > type ( ) - > variant ( ) = = T_ARRAY )
{
SgSymbol * s = ex - > symbol ( ) ;
auto it = delcsSymbViewed . find ( s ) ;
if ( it = = delcsSymbViewed . end ( ) )
{
delcsSymbViewed . insert ( it , s ) ;
SgStatement * decl = declaratedInStmt ( s ) ;
auto itD = delcsStatViewed . find ( decl ) ;
if ( itD = = delcsStatViewed . end ( ) )
{
delcsStatViewed . insert ( itD , decl ) ;
tryToFindPrivateInAttributes ( decl , privatesVars ) ;
fillNonDistrArraysAsPrivate ( decl , declaredArrays , declaratedArraysSt , privatesVars ) ;
}
}
}
}
}
fillPrivatesFromDecl ( ex - > rhs ( ) , delcsSymbViewed , delcsStatViewed , declaredArrays , declaratedArraysSt , privatesVars ) ;
fillPrivatesFromDecl ( ex - > lhs ( ) , delcsSymbViewed , delcsStatViewed , declaredArrays , declaratedArraysSt , privatesVars ) ;
}
2024-07-06 14:27:00 +03:00
static void changeLoopWeight ( double & currentWeight , const map < int , LoopGraph * > & sortedLoopGraph , const int line , bool increase = true )
2023-09-14 19:43:13 +03:00
{
auto loopIt = sortedLoopGraph . find ( line ) ;
if ( loopIt = = sortedLoopGraph . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( increase )
currentWeight * = loopIt - > second - > countOfIters ;
else
currentWeight / = loopIt - > second - > countOfIters ;
}
2024-07-06 14:27:00 +03:00
static bool hasNonPureFunctions ( SgExpression * ex , LoopGraph * loopRef , vector < Messages > & messagesForFile , const int line , const map < string , FuncInfo * > & funcByName )
2023-09-14 19:43:13 +03:00
{
bool retVal = false ;
if ( ex = = NULL )
return retVal ;
if ( ex - > variant ( ) = = FUNC_CALL )
{
if ( isIntrinsicFunctionName ( ex - > symbol ( ) - > identifier ( ) ) = = 0 )
{
auto itF = funcByName . find ( ex - > symbol ( ) - > identifier ( ) ) ;
bool isPure = false ;
if ( itF ! = funcByName . end ( ) )
isPure = itF - > second - > isPure ;
if ( ! isPure )
{
retVal = true ;
loopRef - > hasNonPureProcedures = true ;
messagesForFile . push_back ( Messages ( WARR , line , R79 , L " Only pure procedures were supported " , 1044 ) ) ;
}
}
}
bool retL = false , retR = false ;
if ( ex - > lhs ( ) )
retL = hasNonPureFunctions ( ex - > lhs ( ) , loopRef , messagesForFile , line , funcByName ) ;
if ( ex - > rhs ( ) )
retR = hasNonPureFunctions ( ex - > rhs ( ) , loopRef , messagesForFile , line , funcByName ) ;
return retVal | | retL | | retR ;
}
void fillFromModule ( SgSymbol * s , const map < string , set < string > > & privatesByModule , set < string > & privates )
{
if ( s )
{
auto it = privatesByModule . find ( s - > identifier ( ) ) ;
if ( it ! = privatesByModule . end ( ) )
privates . insert ( it - > second . begin ( ) , it - > second . end ( ) ) ;
}
}
2024-07-06 14:27:00 +03:00
static SgStatement * takeOutConditions ( stack < SgExpression * > & conditions , stack < SgStatement * > & ifBlocks , SgStatement * st )
2023-09-14 19:43:13 +03:00
{
auto res = createIfConditions ( conditions , ifBlocks , st ) ;
auto before = st - > lexPrev ( ) ;
for ( auto & elem : res )
if ( elem )
st - > insertStmtBefore ( * elem , * st - > controlParent ( ) ) ;
SgLabel * lab = st - > label ( ) ;
if ( lab ) // move lab to first condition
{
st - > deleteLabel ( true ) ;
if ( res . size ( ) = = 0 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
res [ 0 ] - > setLabel ( * lab ) ;
}
return before ;
}
extern void createMapLoopGraph ( map < int , LoopGraph * > & sortedLoopGraph , const vector < LoopGraph * > * loopGraph ) ;
void loopAnalyzer ( SgFile * file , vector < ParallelRegion * > & regions , map < tuple < int , string , string > , DIST : : Array * > & createdArrays ,
vector < Messages > & messagesForFile , REGIME regime , const map < string , vector < FuncInfo * > > & AllfuncInfo ,
const map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays ,
const map < SgStatement * , set < tuple < int , string , string > > > & declaratedArraysSt ,
const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls ,
const map < SgStatement * , vector < DefUseList > > & defUseByPlace ,
bool skipDeps , vector < LoopGraph * > * loopGraph )
{
currMessages = & messagesForFile ;
currRegime = regime ;
map < string , vector < SgExpression * > > commonBlocks ;
map < int , LoopGraph * > sortedLoopGraph ;
map < int , pair < SgForStmt * , pair < set < string > , set < string > > > > allLoops ;
createMapLoopGraph ( sortedLoopGraph , loopGraph ) ;
int funcNum = file - > numberOfFunctions ( ) ;
__spf_print ( PRINT_PROF_INFO , " functions num in file = %d \n " , funcNum ) ;
vector < SgStatement * > modules ;
findModulesInFile ( file , modules ) ;
map < string , SgStatement * > modulesByName ;
for ( int i = 0 ; i < modules . size ( ) ; + + i )
modulesByName [ modules [ i ] - > symbol ( ) - > identifier ( ) ] = modules [ i ] ;
map < string , set < string > > privatesByModule ;
2024-06-20 13:00:01 +03:00
if ( ! sharedMemoryParallelization )
for ( int i = 0 ; i < modules . size ( ) ; + + i )
privatesByModule [ modules [ i ] - > symbol ( ) - > identifier ( ) ] = getPrivatesFromModule ( modules [ i ] , declaredArrays , declaratedArraysSt , modulesByName ) ;
2023-09-14 19:43:13 +03:00
map < string , FuncInfo * > funcByName ;
createMapOfFunc ( AllfuncInfo , funcByName ) ;
const vector < FuncInfo * > & funcInfo = AllfuncInfo . find ( file - > filename ( ) ) - > second ;
for ( int i = 0 ; i < funcNum ; + + i )
{
createNeededException ( ) ;
string fName = file - > functions ( i ) - > symbol ( ) - > identifier ( ) ;
# if _WIN32
if ( file - > functions ( i ) - > variant ( ) ! = MODULE_STMT )
2024-11-14 15:28:51 +03:00
sendMessage_2lvl ( wstring ( L " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> '" ) + wstring ( fName . begin ( ) , fName . end ( ) ) + L " ' " ) ;
2023-09-14 19:43:13 +03:00
else
2024-11-14 15:28:51 +03:00
sendMessage_2lvl ( wstring ( L " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> '" ) + wstring ( fName . begin ( ) , fName . end ( ) ) + L " ' " ) ;
2023-09-14 19:43:13 +03:00
# else
if ( file - > functions ( i ) - > variant ( ) ! = MODULE_STMT )
sendMessage_2lvl ( wstring ( L " processing function ' " ) + wstring ( fName . begin ( ) , fName . end ( ) ) + L " ' " ) ;
else
sendMessage_2lvl ( wstring ( L " processing module ' " ) + wstring ( fName . begin ( ) , fName . end ( ) ) + L " ' " ) ;
# endif
set < SgSymbol * > delcsSymbViewed ;
set < SgStatement * > delcsStatViewed ;
if ( funcInfo [ i ] - > doNotAnalyze )
continue ;
map < SgForStmt * , map < SgSymbol * , ArrayInfo > > loopInfo ;
set < int > loopWithOutArrays ;
set < string > privatesVars ;
SgStatement * st = file - > functions ( i ) ;
string funcName = " " ;
if ( st - > variant ( ) = = PROG_HEDR )
{
SgProgHedrStmt * progH = ( SgProgHedrStmt * ) st ;
__spf_print ( PRINT_PROF_INFO , " *** Program <%s> started at line %d / %s \n " , progH - > symbol ( ) - > identifier ( ) , st - > lineNumber ( ) , st - > fileName ( ) ) ;
funcName = progH - > symbol ( ) - > identifier ( ) ;
}
else if ( st - > variant ( ) = = PROC_HEDR )
{
SgProcHedrStmt * procH = ( SgProcHedrStmt * ) st ;
__spf_print ( PRINT_PROF_INFO , " *** Function <%s> started at line %d / %s \n " , procH - > symbol ( ) - > identifier ( ) , st - > lineNumber ( ) , st - > fileName ( ) ) ;
funcName = procH - > symbol ( ) - > identifier ( ) ;
}
else if ( st - > variant ( ) = = FUNC_HEDR )
{
SgFuncHedrStmt * funcH = ( SgFuncHedrStmt * ) st ;
__spf_print ( PRINT_PROF_INFO , " *** Function <%s> started at line %d / %s \n " , funcH - > symbol ( ) - > identifier ( ) , st - > lineNumber ( ) , st - > fileName ( ) ) ;
funcName = funcH - > symbol ( ) - > identifier ( ) ;
}
vector < LoopGraph * > loopsForFunction ;
for ( auto & loop : * loopGraph )
{
auto fStat = getFuncStat ( loop - > loop - > GetOriginal ( ) ) ;
if ( fStat - > symbol ( ) - > identifier ( ) = = funcName )
loopsForFunction . push_back ( loop ) ;
}
2024-06-20 13:00:01 +03:00
if ( ! sharedMemoryParallelization )
2023-09-14 19:43:13 +03:00
{
2024-06-20 13:00:01 +03:00
SgStatement * tmpModFind = st ;
while ( tmpModFind - > variant ( ) ! = GLOBAL )
{
tmpModFind = tmpModFind - > controlParent ( ) ;
if ( tmpModFind - > variant ( ) = = MODULE_STMT )
fillFromModule ( tmpModFind - > symbol ( ) , privatesByModule , privatesVars ) ;
}
2023-09-14 19:43:13 +03:00
}
2024-06-20 13:00:01 +03:00
2023-09-14 19:43:13 +03:00
commonBlocks . clear ( ) ;
getCommonBlocksRef ( commonBlocks , st , st - > lastNodeOfStmt ( ) ) ;
__spf_print ( PRINT_PROF_INFO , " number of common blocks %d \n " , ( int ) commonBlocks . size ( ) ) ;
SgStatement * lastNode = st - > lastNodeOfStmt ( ) ;
vector < SgForStmt * > parentLoops ;
vector < set < string > > privatesVarsForLoop ;
//For remote access
pair < SgForStmt * , LoopGraph * > * under_dvm_dir = NULL ;
map < string , pair < SgSymbol * , SgStatement * > > notMappedDistributedArrays ;
set < string > mappedDistrbutedArrays ;
double currentWeight = 1.0 ;
while ( st ! = lastNode )
{
createNeededException ( ) ;
if ( st = = NULL )
{
currMessages - > push_back ( Messages ( ERROR , 1 , R128 , L " internal error in analysis, parallel directives will not be generated for this file! " , 3008 ) ) ;
__spf_print ( 1 , " internal error in analysis, parallel directives will not be generated for this file! \n " ) ;
break ;
}
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
if ( ! __gcov_doesThisLineExecuted ( st - > fileName ( ) , st - > lineNumber ( ) ) )
{
st = st - > lexNext ( ) ;
continue ;
}
const int currentLine = st - > lineNumber ( ) < - 1 ? st - > localLineNumber ( ) : st - > lineNumber ( ) ;
ParallelRegion * currReg = getRegionByLine ( regions , st - > fileName ( ) , currentLine ) ;
if ( currReg = = NULL )
{
st = st - > lexNext ( ) ;
continue ;
}
if ( isSgExecutableStatement ( st ) = = NULL )
delcsStatViewed . insert ( st ) ;
2024-06-20 13:00:01 +03:00
else if ( ! sharedMemoryParallelization & &
! isDVM_stat ( st ) & & ! isSPF_stat ( st ) )
2023-09-14 19:43:13 +03:00
for ( int i = 0 ; i < 3 ; + + i )
fillPrivatesFromDecl ( st - > expr ( i ) , delcsSymbViewed , delcsStatViewed , declaredArrays , declaratedArraysSt , privatesVars ) ;
//printf("new st with var = %d, on line %d\n", st->variant(), st->lineNumber());
const int currV = st - > variant ( ) ;
if ( currV = = FOR_NODE )
{
2024-06-20 13:00:01 +03:00
if ( ! sharedMemoryParallelization )
{
tryToFindPrivateInAttributes ( st , privatesVars ) ;
fillNonDistrArraysAsPrivate ( st , declaredArrays , declaratedArraysSt , privatesVars ) ;
}
2023-09-14 19:43:13 +03:00
set < string > toAdd ;
tryToFindPrivateInAttributes ( st , toAdd ) ;
if ( PRINT_LOOP_STRUCT )
printBlanks ( 2 , ( int ) parentLoops . size ( ) ) ;
__spf_print ( PRINT_LOOP_STRUCT , " FOR NODE on line %d \n " , st - > lineNumber ( ) ) ;
parentLoops . push_back ( ( SgForStmt * ) st ) ;
changeLoopWeight ( currentWeight , sortedLoopGraph , st - > lineNumber ( ) ) ;
privatesVarsForLoop . push_back ( toAdd ) ;
if ( regime = = REMOTE_ACC )
{
SgStatement * prev = st - > lexPrev ( ) ;
if ( prev )
{
if ( prev - > variant ( ) = = DVM_PARALLEL_ON_DIR )
{
auto it = sortedLoopGraph . find ( st - > lineNumber ( ) ) ;
if ( it = = sortedLoopGraph . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
under_dvm_dir = new pair < SgForStmt * , LoopGraph * > ( ( SgForStmt * ) st , it - > second ) ;
}
}
}
}
else if ( currV = = CONTROL_END )
{
SgStatement * contrlParent = st - > controlParent ( ) ;
if ( contrlParent )
{
if ( contrlParent - > variant ( ) = = FOR_NODE )
{
changeLoopWeight ( currentWeight , sortedLoopGraph , contrlParent - > lineNumber ( ) , false ) ;
if ( loopInfo . find ( ( SgForStmt * ) contrlParent ) = = loopInfo . end ( ) & & ! sortedLoopGraph [ contrlParent - > lineNumber ( ) ] - > hasUnknownDistributedMap )
loopWithOutArrays . insert ( contrlParent - > lineNumber ( ) ) ;
set < string > unitedPrivates ;
for ( int p = 0 ; p < parentLoops . size ( ) ; + + p )
for ( auto & privVar : privatesVarsForLoop [ p ] )
unitedPrivates . insert ( privVar ) ;
set < string > setDiff ;
2024-06-20 13:00:01 +03:00
if ( ! sharedMemoryParallelization )
for ( auto & privVars : privatesVars )
if ( unitedPrivates . find ( privVars ) = = unitedPrivates . end ( ) )
setDiff . insert ( privVars ) ;
2023-09-14 19:43:13 +03:00
allLoops [ contrlParent - > lineNumber ( ) ] = make_pair ( ( SgForStmt * ) contrlParent , make_pair ( unitedPrivates , setDiff ) ) ;
parentLoops . pop_back ( ) ;
privatesVarsForLoop . pop_back ( ) ;
if ( regime = = REMOTE_ACC )
{
if ( under_dvm_dir )
{
if ( contrlParent = = under_dvm_dir - > first & & under_dvm_dir - > second - > userDvmDirective = = NULL )
{
ParallelRegion * currReg = getRegionByLine ( regions , under_dvm_dir - > first - > fileName ( ) , under_dvm_dir - > first - > lineNumber ( ) ) ;
if ( currReg )
{
const DIST : : Arrays < int > & allArrays = currReg - > GetAllArrays ( ) ;
DIST : : GraphCSR < int , double , attrType > & reducedG = currReg - > GetReducedGraphToModify ( ) ;
const DataDirective & data = currReg - > GetDataDir ( ) ;
const vector < int > & currVar = currReg - > GetCurrentVariant ( ) ;
const pair < LoopGraph * , const ParallelDirective * > currDir = make_pair ( under_dvm_dir - > second , under_dvm_dir - > second - > directive ) ;
auto convertedLoopInfo = convertLoopInfo ( loopInfo , sortedLoopGraph , privatesVars , commonBlocks , declaredArrays , arrayLinksByFuncCalls , createdArrays ) ;
auto uniqRemotes = createRemoteInParallel ( currDir , allArrays , convertedLoopInfo , reducedG , data , currVar , messagesForFile , currReg - > GetId ( ) , arrayLinksByFuncCalls , funcByName ) ;
addRemotesToDir ( under_dvm_dir , uniqRemotes ) ;
}
delete under_dvm_dir ;
under_dvm_dir = NULL ;
}
}
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
else if ( currV = = ASSIGN_STAT )
{
if ( st - > expr ( 0 ) )
findArrayRef ( parentLoops , st - > expr ( 0 ) , st - > lineNumber ( ) , LEFT , loopInfo , privatesVars , privatesVarsForLoop ,
sortedLoopGraph , commonBlocks , declaredArrays , false , notMappedDistributedArrays ,
mappedDistrbutedArrays , st , currReg , currentWeight , arrayLinksByFuncCalls ) ;
if ( st - > expr ( 1 ) )
findArrayRef ( parentLoops , st - > expr ( 1 ) , st - > lineNumber ( ) , RIGHT , loopInfo , privatesVars , privatesVarsForLoop ,
sortedLoopGraph , commonBlocks , declaredArrays , false , notMappedDistributedArrays ,
mappedDistrbutedArrays , st , currReg , currentWeight , arrayLinksByFuncCalls ) ;
if ( regime = = REMOTE_ACC )
{
if ( st - > expr ( 1 ) )
{
bool cond = true ;
if ( st - > expr ( 1 ) - > variant ( ) = = FUNC_CALL )
{
string fName = ( ( SgFunctionCallExp * ) st - > expr ( 1 ) ) - > funName ( ) - > identifier ( ) ;
cond = ( fName ! = " allocated " ) ;
}
// detect copy operator: A(:, :, :) = B(:, :, :)
if ( st - > expr ( 1 ) - > variant ( ) = = ARRAY_REF & & st - > expr ( 0 ) - > variant ( ) = = ARRAY_REF )
{
set < SgSymbol * > ddots ;
vector < SgExpression * > dummy ;
fillVars ( st - > expr ( 0 ) , { DDOT } , ddots , dummy ) ;
fillVars ( st - > expr ( 1 ) , { DDOT } , ddots , dummy ) ;
if ( ddots . size ( ) ! = 0 )
cond = false ;
}
// detect copy operator: A = B
if ( st - > expr ( 1 ) - > variant ( ) = = ARRAY_REF & & st - > expr ( 0 ) - > variant ( ) = = ARRAY_REF )
{
SgExpression * left = st - > expr ( 0 ) ;
SgExpression * right = st - > expr ( 1 ) ;
if ( left - > lhs ( ) = = NULL & & left - > rhs ( ) = = NULL & &
right - > lhs ( ) = = NULL & & right - > rhs ( ) = = NULL )
cond = false ;
}
// detect operator: A[(:,:,:)] = F(X[(:,:,:)], Y[(:,:,:)], Z[(:,:,:)], ...)
//TODO: check right part
if ( st - > expr ( 0 ) - > variant ( ) = = ARRAY_REF )
{
SgExpression * left = st - > expr ( 0 ) ;
set < SgSymbol * > ddots ;
vector < SgExpression * > dummy ;
fillVars ( st - > expr ( 0 ) , { DDOT } , ddots , dummy ) ;
if ( ( left - > lhs ( ) = = NULL & & left - > rhs ( ) = = NULL ) | | ddots . size ( ) ! = 0 )
cond = false ;
}
if ( cond )
{
const DIST : : Arrays < int > & allArrays = currReg - > GetAllArrays ( ) ;
if ( under_dvm_dir = = NULL )
createRemoteDir < 1 > ( st , funcByName , sortedLoopGraph , allArrays , currReg - > GetDataDir ( ) , currReg - > GetCurrentVariant ( ) , currReg - > GetId ( ) , * currMessages , arrayLinksByFuncCalls ) ;
}
}
if ( st - > expr ( 0 ) )
{
const DIST : : Arrays < int > & allArrays = currReg - > GetAllArrays ( ) ;
if ( under_dvm_dir = = NULL )
createRemoteDir < 0 > ( st , funcByName , sortedLoopGraph , allArrays , currReg - > GetDataDir ( ) , currReg - > GetCurrentVariant ( ) , currReg - > GetId ( ) , * currMessages , arrayLinksByFuncCalls ) ;
}
}
}
else if ( currV = = IF_NODE | | currV = = ELSEIF_NODE | | currV = = LOGIF_NODE | | currV = = SWITCH_NODE )
{
SgStatement * before = NULL ;
// convert IF conditions if access to dist array appears
if ( regime = = REMOTE_ACC & & under_dvm_dir = = NULL )
{
stack < SgExpression * > conditions ;
stack < SgStatement * > ifBlocks ;
bool needToConv = false ;
bool prevWithSameLine = ( st - > lexPrev ( ) - > lineNumber ( ) = = st - > lineNumber ( ) ) ;
if ( currV = = IF_NODE )
{
needToConv = isNeedToConvertIfCondition ( st - > expr ( 0 ) ) ;
conditions . push ( st - > expr ( 0 ) ) ;
ifBlocks . push ( st ) ;
SgIfStmt * ifS = ( SgIfStmt * ) st ;
auto body = ifS - > falseBody ( ) ;
while ( body )
{
if ( body - > variant ( ) = = ELSEIF_NODE )
{
needToConv = needToConv | | isNeedToConvertIfCondition ( body - > expr ( 0 ) - > copyPtr ( ) ) ;
conditions . push ( body - > expr ( 0 ) ) ;
ifBlocks . push ( body ) ;
}
else
break ;
body = body - > lastNodeOfStmt ( ) ;
}
needToConv = needToConv & & ! prevWithSameLine ;
}
else if ( currV = = LOGIF_NODE )
{
needToConv = isNeedToConvertIfCondition ( st - > expr ( 0 ) ) & & ! prevWithSameLine ;
conditions . push ( st - > expr ( 0 ) ) ;
ifBlocks . push ( st ) ;
}
else if ( currV = = SWITCH_NODE )
{
needToConv = isNeedToConvertIfCondition ( st - > expr ( 0 ) ) & & ! prevWithSameLine ;
conditions . push ( st - > expr ( 0 ) ) ;
ifBlocks . push ( st ) ;
}
if ( needToConv & & ! conditions . empty ( ) )
st = before = takeOutConditions ( conditions , ifBlocks , st ) ;
}
if ( st - > expr ( 0 ) )
{
findArrayRef ( parentLoops , st - > expr ( 0 ) , st - > lineNumber ( ) , RIGHT , loopInfo , privatesVars , privatesVarsForLoop ,
sortedLoopGraph , commonBlocks , declaredArrays , false , notMappedDistributedArrays ,
mappedDistrbutedArrays , st , currReg , currentWeight , arrayLinksByFuncCalls ) ;
if ( regime = = REMOTE_ACC )
if ( under_dvm_dir = = NULL )
createRemoteDir < 0 > ( st , funcByName , sortedLoopGraph , currReg - > GetAllArrays ( ) , currReg - > GetDataDir ( ) , currReg - > GetCurrentVariant ( ) , currReg - > GetId ( ) , * currMessages , arrayLinksByFuncCalls ) ;
}
if ( regime = = REMOTE_ACC & & before )
st = before ;
}
else if ( currV = = PROC_STAT )
{
auto func = isUserFunctionInProject ( st - > symbol ( ) - > identifier ( ) ) ;
if ( func ! = NULL )
{
SgExpression * parList = st - > expr ( 0 ) ;
set < DIST : : Array * > toRedistr ;
if ( parList )
{
SgExprListExp * list = isSgExprListExp ( parList ) ;
for ( int z = 0 ; z < list - > length ( ) ; + + z )
{
SgExpression * par = list - > elem ( z ) ;
if ( ( func - > funcParams . inout_types [ z ] & OUT_BIT ) ! = 0 )
findArrayRef ( parentLoops , par , st - > lineNumber ( ) , LEFT , loopInfo , privatesVars , privatesVarsForLoop ,
sortedLoopGraph , commonBlocks , declaredArrays , false , notMappedDistributedArrays ,
mappedDistrbutedArrays , st , currReg , currentWeight , arrayLinksByFuncCalls ) ;
else
findArrayRef ( parentLoops , par , st - > lineNumber ( ) , RIGHT , loopInfo , privatesVars , privatesVarsForLoop ,
sortedLoopGraph , commonBlocks , declaredArrays , false , notMappedDistributedArrays ,
mappedDistrbutedArrays , st , currReg , currentWeight , arrayLinksByFuncCalls ) ;
if ( regime = = REMOTE_ACC )
{
if ( isArrayRef ( par ) & & isPassFullArray ( par ) )
{
SgSymbol * s = OriginalSymbol ( par - > symbol ( ) ) ;
DIST : : Array * inPar = getArrayFromDeclarated ( declaratedInStmt ( s ) , s - > identifier ( ) ) ;
if ( inPar & & ! inPar - > IsNotDistribute ( ) )
{
if ( func - > funcParams . parametersT [ z ] ! = ARRAY_T )
toRedistr . insert ( inPar - > GetTemplateArray ( currReg - > GetId ( ) ) ) ;
else
{
if ( inPar - > GetDimSize ( ) ! = ( ( DIST : : Array * ) func - > funcParams . parameters [ z ] ) - > GetDimSize ( ) )
toRedistr . insert ( inPar - > GetTemplateArray ( currReg - > GetId ( ) ) ) ;
}
}
}
}
}
if ( regime = = REMOTE_ACC & & list - > length ( ) )
if ( under_dvm_dir = = NULL )
createRemoteDir < 0 > ( st , funcByName , sortedLoopGraph , currReg - > GetAllArrays ( ) , currReg - > GetDataDir ( ) , currReg - > GetCurrentVariant ( ) , currReg - > GetId ( ) , * currMessages , arrayLinksByFuncCalls ) ;
}
if ( regime = = REMOTE_ACC )
{
const DataDirective & dataDirectives = currReg - > GetDataDir ( ) ;
const vector < int > & currentVariant = currReg - > GetCurrentVariant ( ) ;
auto & tmp = dataDirectives . distrRules ;
std : : vector < std : : pair < DIST : : Array * , const DistrVariant * > > currentVar ;
for ( int z1 = 0 ; z1 < currentVariant . size ( ) ; + + z1 )
currentVar . push_back ( make_pair ( tmp [ z1 ] . first , & tmp [ z1 ] . second [ currentVariant [ z1 ] ] ) ) ;
for ( auto & toRed : toRedistr )
{
auto cp = st - > controlParent ( ) ;
auto redist = new SgStatement ( DVM_REDISTRIBUTE_DIR ) ;
auto newRule = new SgExprListExp ( ) ;
newRule - > setLhs ( * new SgExpression ( KEYWORD_VAL , " * " ) ) ;
for ( int z = 1 ; z < toRed - > GetDimSize ( ) ; + + z )
newRule - > append ( * new SgExpression ( KEYWORD_VAL , " * " ) ) ;
auto templS = new SgSymbol ( VARIABLE_NAME , toRed - > GetShortName ( ) . c_str ( ) ) ;
redist - > setExpression ( 0 , * new SgVarRefExp ( * templS ) ) ;
redist - > setExpression ( 1 , * newRule ) ;
st - > insertStmtBefore ( * redist , * cp ) ;
redist = new SgStatement ( DVM_REDISTRIBUTE_DIR ) ;
newRule = new SgExprListExp ( ) ;
const DistrVariant * varD = NULL ;
for ( auto & elem : currentVar )
{
if ( elem . first = = toRed )
{
varD = elem . second ;
break ;
}
}
if ( ! varD )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
for ( int z = 0 ; z < toRed - > GetDimSize ( ) ; + + z )
{
char * type = " * " ;
if ( varD - > distRule [ z ] = = distType : : BLOCK )
type = " BLOCK " ;
if ( z = = 0 )
newRule - > setLhs ( * new SgExpression ( KEYWORD_VAL , type ) ) ;
else
newRule - > append ( * new SgExpression ( KEYWORD_VAL , type ) ) ;
}
redist - > setExpression ( 0 , * new SgVarRefExp ( * templS ) ) ;
redist - > setExpression ( 1 , * newRule ) ;
st - > insertStmtAfter ( * redist , * cp ) ;
}
}
}
}
else if ( currV = = USE_STMT )
{
2024-07-06 18:09:59 +03:00
if ( st - > lineNumber ( ) > 0 & & ! sharedMemoryParallelization )
2023-09-14 19:43:13 +03:00
{
auto itF = privatesByModule . find ( st - > symbol ( ) - > identifier ( ) ) ;
if ( itF = = privatesByModule . end ( ) )
{
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " Module with name '%s' must be placed in current file " , to_wstring ( st - > symbol ( ) - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R62 , to_wstring ( st - > symbol ( ) - > identifier ( ) ) . c_str ( ) ) ;
currMessages - > push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1028 ) ) ;
__spf_print ( 1 , " Module at line %d with name '%s' must be placed in current file \n " , st - > lineNumber ( ) , st - > symbol ( ) - > identifier ( ) ) ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
2024-07-06 18:09:59 +03:00
2023-09-14 19:43:13 +03:00
for ( auto it = itF - > second . begin ( ) ; it ! = itF - > second . end ( ) ; + + it )
privatesVars . insert ( * it ) ;
}
}
else
{
2024-06-20 13:00:01 +03:00
if ( ! sharedMemoryParallelization )
{
tryToFindPrivateInAttributes ( st , privatesVars ) ;
fillNonDistrArraysAsPrivate ( st , declaredArrays , declaratedArraysSt , privatesVars ) ;
}
2023-09-14 19:43:13 +03:00
if ( isDVM_stat ( st ) = = false & & isSgExecutableStatement ( st ) )
{
if ( regime = = REMOTE_ACC )
{
if ( st - > expr ( 0 ) & &
( currV = = SWITCH_NODE | | currV = = FORALL_STAT | | currV = = WHILE_NODE | |
currV = = WHERE_NODE | | currV = = ALLDO_NODE | | currV = = ARITHIF_NODE | |
currV = = ASSGOTO_NODE | | currV = = COMGOTO_NODE ) )
{
const DIST : : Arrays < int > & allArrays = currReg - > GetAllArrays ( ) ;
if ( under_dvm_dir = = NULL )
createRemoteDir < 0 > ( st , funcByName , sortedLoopGraph , allArrays , currReg - > GetDataDir ( ) , currReg - > GetCurrentVariant ( ) , currReg - > GetId ( ) , * currMessages , arrayLinksByFuncCalls ) ;
}
}
else
{
int const var = st - > variant ( ) ;
int side = ( var = = READ_STAT | | var = = WRITE_STAT | | var = = PRINT_STAT ) ? LEFT : RIGHT ;
for ( int z = 0 ; z < 3 ; + + z )
if ( st - > expr ( z ) )
findArrayRef ( parentLoops , st - > expr ( z ) , st - > lineNumber ( ) , side , loopInfo , privatesVars , privatesVarsForLoop ,
sortedLoopGraph , commonBlocks , declaredArrays , false , notMappedDistributedArrays ,
mappedDistrbutedArrays , st , currReg , currentWeight , arrayLinksByFuncCalls ) ;
}
}
}
st = st - > lexNext ( ) ;
}
auto convertedLoopInfo = convertLoopInfo ( loopInfo , sortedLoopGraph , privatesVars , commonBlocks , declaredArrays , arrayLinksByFuncCalls , createdArrays ) ;
2024-06-20 13:00:01 +03:00
if ( regime = = DATA_DISTR | | regime = = SHARED_MEMORY_PAR )
2023-09-14 19:43:13 +03:00
{
processLoopInformationForFunction ( convertedLoopInfo ) ;
//find dependencies for loops in function
initAnnotationsSysExt ( 0 ) ;
set < SgStatement * > funcWasInit ;
map < SgExpression * , string > collection ;
int idx = 0 ;
for ( auto & loop : convertedLoopInfo )
{
+ + idx ;
createNeededException ( ) ;
if ( ! skipDeps )
{
string fName = file - > functions ( i ) - > symbol ( ) - > identifier ( ) ;
# ifdef _WIN32
2024-11-14 15:28:51 +03:00
sendMessage_2lvl ( wstring ( L " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> " ) + std : : to_wstring ( idx ) + L " / " + std : : to_wstring ( convertedLoopInfo . size ( ) ) ) ;
2023-09-14 19:43:13 +03:00
# else
sendMessage_2lvl ( wstring ( L " processing loop " ) + std : : to_wstring ( idx ) + L " / " + std : : to_wstring ( convertedLoopInfo . size ( ) ) ) ;
# endif
tryToFindDependencies ( loop . first , allLoops , funcWasInit , file , regions , currMessages , collection , funcByName , defUseByPlace ) ;
}
}
vector < LoopGraph * > tmpLoops ;
map < SgSymbol * , ArrayInfo > tmpToConvert ;
if ( file - > functions ( i ) - > variant ( ) ! = PROG_HEDR )
{
for ( auto & notMapped : notMappedDistributedArrays )
{
if ( mappedDistrbutedArrays . find ( notMapped . first ) = = mappedDistrbutedArrays . end ( ) )
{
auto reg = getRegionByLine ( regions , notMapped . second . second - > fileName ( ) , notMapped . second . second - > lineNumber ( ) ) ;
if ( reg )
{
LoopGraph * tmpLoop = new LoopGraph ( ) ;
tmpLoop - > region = reg ;
tmpLoop - > isFor = true ;
tmpLoops . push_back ( tmpLoop ) ;
ArrayInfo toAdd ;
SgSymbol * arrayS = notMapped . second . first ;
toAdd . setDimSize ( ( ( SgArrayType * ) arrayS - > type ( ) ) - > dimension ( ) ) ;
for ( int z = 0 ; z < toAdd . getDimSize ( ) ; + + z )
toAdd . readOps [ z ] = ArrayOp ( make_pair ( make_pair ( 1 , 0 ) , 1.0 ) ) ;
tmpToConvert [ arrayS ] = toAdd ;
convertOneLoop ( tmpLoop , convertedLoopInfo , tmpToConvert , privatesVars , commonBlocks , declaredArrays , arrayLinksByFuncCalls , createdArrays , true ) ;
}
}
}
}
2024-06-20 13:00:01 +03:00
if ( ! sharedMemoryParallelization )
addToDistributionGraph ( convertedLoopInfo , arrayLinksByFuncCalls ) ;
2023-09-14 19:43:13 +03:00
for ( auto & toDel : tmpLoops )
2024-07-06 14:27:00 +03:00
{
convertedLoopInfo . erase ( toDel ) ;
2023-09-14 19:43:13 +03:00
delete toDel ;
2024-07-06 14:27:00 +03:00
}
2023-09-14 19:43:13 +03:00
tmpToConvert . clear ( ) ;
if ( ! skipDeps )
{
for ( auto & loopLine : loopWithOutArrays )
{
if ( loopLine > 0 )
{
tryToFindDependencies ( sortedLoopGraph [ loopLine ] , allLoops , funcWasInit , file , regions , currMessages , collection , funcByName , defUseByPlace ) ;
sortedLoopGraph [ loopLine ] - > withoutDistributedArrays = true ;
}
}
// TODO: add messages!
for ( auto & loopLine : loopWithOutArrays )
{
if ( sortedLoopGraph [ loopLine ] - > withoutDistributedArrays & & loopLine > 0 )
{
//TODO: enable linear writes to non distr arrays for CONSISTENT
bool hasWritesToArray = false ;
//TODO: add IPA for non pure
bool hasNonPureProcedures = false ;
auto loopRef = sortedLoopGraph [ loopLine ] ;
SgStatement * loopSt = loopRef - > loop ;
map < string , set < Symbol * > > reductions ;
map < string , set < tuple < Symbol * , Symbol * , int > > > reductionsLoc ;
set < Symbol * > privatesS ;
for ( auto & data : getAttributes < SgStatement * , SgStatement * > ( loopSt , set < int > { SPF_ANALYSIS_DIR , SPF_PARALLEL_DIR } ) )
{
Statement * dataSt = new Statement ( data ) ;
fillReductionsFromComment ( dataSt , reductions ) ;
fillReductionsFromComment ( dataSt , reductionsLoc ) ;
fillPrivatesFromComment ( dataSt , privatesS ) ;
}
for ( auto & red : reductions )
privatesS . insert ( red . second . begin ( ) , red . second . end ( ) ) ;
for ( auto & red : reductionsLoc )
{
for ( auto & elem : red . second )
{
privatesS . insert ( get < 0 > ( elem ) ) ;
privatesS . insert ( get < 1 > ( elem ) ) ;
}
}
set < string > privates ;
for ( auto & elem : privatesS )
privates . insert ( elem - > GetOriginal ( ) - > identifier ( ) ) ;
for ( SgStatement * start = loopSt - > lexNext ( ) ; start ! = loopSt - > lastNodeOfStmt ( ) ; start = start - > lexNext ( ) )
{
//TODO: detect write in proc calls
if ( start - > variant ( ) = = ASSIGN_STAT )
{
if ( start - > expr ( 0 ) - > variant ( ) = = ARRAY_REF | | start - > expr ( 0 ) - > variant ( ) = = ARRAY_OP )
{
SgSymbol * s = NULL ;
if ( start - > expr ( 0 ) - > variant ( ) = = ARRAY_REF )
s = start - > expr ( 0 ) - > symbol ( ) ;
else if ( start - > expr ( 0 ) - > variant ( ) = = ARRAY_OP )
s = start - > expr ( 0 ) - > lhs ( ) - > symbol ( ) ;
if ( s & & privates . find ( s - > identifier ( ) ) = = privates . end ( ) )
2024-06-19 18:08:27 +03:00
if ( sharedMemoryParallelization = = 0 )
2023-09-14 19:43:13 +03:00
hasWritesToArray = true ;
}
}
if ( start - > variant ( ) = = PROC_STAT & & isIntrinsicFunctionName ( start - > symbol ( ) - > identifier ( ) ) = = 0 )
{
checkNull ( isSgCallStmt ( start ) , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
auto itF = funcByName . find ( isSgCallStmt ( start ) - > name ( ) - > identifier ( ) ) ;
bool isPure = false ;
if ( itF ! = funcByName . end ( ) )
isPure = itF - > second - > isPure ;
if ( ! isPure )
{
hasNonPureProcedures = true ;
loopRef - > hasNonPureProcedures = true ;
messagesForFile . push_back ( Messages ( WARR , start - > lineNumber ( ) , R80 , L " Only pure procedures were supported " , 1044 ) ) ;
}
}
for ( int z = 1 ; z < 3 ; + + z )
if ( hasNonPureFunctions ( start - > expr ( z ) , loopRef , messagesForFile , start - > lineNumber ( ) , funcByName ) )
hasNonPureProcedures = true ;
}
if ( hasWritesToArray | | hasNonPureProcedures )
loopRef - > withoutDistributedArrays = false ;
}
}
if ( parallizeFreeLoops )
selectFreeLoopsForParallelization ( loopsForFunction , funcName , ( regime = = DATA_DISTR ) , regions , messagesForFile ) ;
}
sendMessage_2lvl ( L " " ) ;
}
else if ( regime = = COMP_DISTR )
{
createParallelDirectives ( convertedLoopInfo , regions , arrayLinksByFuncCalls , messagesForFile ) ;
if ( parallizeFreeLoops )
selectFreeLoopsForParallelization ( loopsForFunction , funcName , ( regime = = DATA_DISTR ) , regions , messagesForFile ) ;
}
2024-06-20 13:00:01 +03:00
if ( regime = = SHARED_MEMORY_PAR )
createParallelDirectives ( convertedLoopInfo , regions , arrayLinksByFuncCalls , messagesForFile ) ;
2023-09-14 19:43:13 +03:00
__spf_print ( PRINT_PROF_INFO , " Function ended \n " ) ;
}
}
void arrayAccessAnalyzer ( SgFile * file , vector < Messages > & messagesForFile , const map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays , REGIME regime )
{
currMessages = & messagesForFile ;
currRegime = regime ;
map < string , vector < SgExpression * > > commonBlocks ;
map < int , LoopGraph * > sortedLoopGraph ;
map < int , pair < SgForStmt * , pair < set < string > , set < string > > > > allLoops ;
map < string , pair < SgSymbol * , SgStatement * > > notMappedDistributedArrays ;
set < string > mappedDistrbutedArrays ;
int funcNum = file - > numberOfFunctions ( ) ;
__spf_print ( PRINT_PROF_INFO , " functions num in file = %d \n " , funcNum ) ;
const map < DIST : : Array * , set < DIST : : Array * > > arrayLinksByFuncCalls ;
for ( int i = 0 ; i < funcNum ; + + i )
{
map < SgForStmt * , map < SgSymbol * , ArrayInfo > > loopInfo ;
set < string > privatesVars ;
vector < set < string > > privatesVarsForLoop ;
SgStatement * st = file - > functions ( i ) ;
string funcName = " " ;
if ( st - > variant ( ) = = PROG_HEDR )
{
SgProgHedrStmt * progH = ( SgProgHedrStmt * ) st ;
__spf_print ( PRINT_PROF_INFO , " *** Program <%s> started at line %d / %s \n " , progH - > symbol ( ) - > identifier ( ) , st - > lineNumber ( ) , st - > fileName ( ) ) ;
funcName = progH - > symbol ( ) - > identifier ( ) ;
}
else if ( st - > variant ( ) = = PROC_HEDR )
{
SgProcHedrStmt * procH = ( SgProcHedrStmt * ) st ;
__spf_print ( PRINT_PROF_INFO , " *** Function <%s> started at line %d / %s \n " , procH - > symbol ( ) - > identifier ( ) , st - > lineNumber ( ) , st - > fileName ( ) ) ;
funcName = procH - > symbol ( ) - > identifier ( ) ;
}
else if ( st - > variant ( ) = = FUNC_HEDR )
{
SgFuncHedrStmt * funcH = ( SgFuncHedrStmt * ) st ;
__spf_print ( PRINT_PROF_INFO , " *** Function <%s> started at line %d / %s \n " , funcH - > symbol ( ) - > identifier ( ) , st - > lineNumber ( ) , st - > fileName ( ) ) ;
funcName = funcH - > symbol ( ) - > identifier ( ) ;
}
commonBlocks . clear ( ) ;
getCommonBlocksRef ( commonBlocks , st , st - > lastNodeOfStmt ( ) ) ;
__spf_print ( PRINT_PROF_INFO , " number of common blocks %d \n " , ( int ) commonBlocks . size ( ) ) ;
SgStatement * lastNode = st - > lastNodeOfStmt ( ) ;
vector < SgForStmt * > parentLoops ;
double currentWeight = 1.0 ;
while ( st ! = lastNode )
{
createNeededException ( ) ;
if ( st = = NULL )
{
currMessages - > push_back ( Messages ( ERROR , 1 , R128 , L " internal error in analysis, parallel directives will not be generated for this file! " , 3008 ) ) ;
__spf_print ( 1 , " internal error in analysis, parallel directives will not be generated for this file! \n " ) ;
break ;
}
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
const int currV = st - > variant ( ) ;
if ( currV = = FOR_NODE )
{
if ( PRINT_LOOP_STRUCT )
printBlanks ( 2 , ( int ) parentLoops . size ( ) ) ;
__spf_print ( PRINT_LOOP_STRUCT , " FOR NODE on line %d \n " , st - > lineNumber ( ) ) ;
parentLoops . push_back ( ( SgForStmt * ) st ) ;
sortedLoopGraph [ st - > lineNumber ( ) ] = new LoopGraph ( ) ;
privatesVarsForLoop . push_back ( set < string > ( ) ) ;
}
else if ( currV = = CONTROL_END )
{
SgStatement * contrlParent = st - > controlParent ( ) ;
if ( contrlParent )
{
if ( contrlParent - > variant ( ) = = FOR_NODE )
{
parentLoops . pop_back ( ) ;
delete sortedLoopGraph [ contrlParent - > lineNumber ( ) ] ;
sortedLoopGraph . erase ( contrlParent - > lineNumber ( ) ) ;
privatesVarsForLoop . pop_back ( ) ;
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
else if ( currV = = ASSIGN_STAT )
{
if ( st - > expr ( 0 ) )
findArrayRef ( parentLoops , st - > expr ( 0 ) , st - > lineNumber ( ) , LEFT , loopInfo , privatesVars , privatesVarsForLoop ,
sortedLoopGraph , commonBlocks , declaredArrays , false , notMappedDistributedArrays ,
mappedDistrbutedArrays , st , NULL , currentWeight , arrayLinksByFuncCalls ) ;
if ( st - > expr ( 1 ) )
findArrayRef ( parentLoops , st - > expr ( 1 ) , st - > lineNumber ( ) , RIGHT , loopInfo , privatesVars , privatesVarsForLoop ,
sortedLoopGraph , commonBlocks , declaredArrays , false , notMappedDistributedArrays ,
mappedDistrbutedArrays , st , NULL , currentWeight , arrayLinksByFuncCalls ) ;
}
else if ( currV = = IF_NODE | | currV = = ELSEIF_NODE | | currV = = LOGIF_NODE | | currV = = SWITCH_NODE )
{
if ( st - > expr ( 0 ) )
findArrayRef ( parentLoops , st - > expr ( 0 ) , st - > lineNumber ( ) , RIGHT , loopInfo , privatesVars , privatesVarsForLoop ,
sortedLoopGraph , commonBlocks , declaredArrays , false , notMappedDistributedArrays ,
mappedDistrbutedArrays , st , NULL , currentWeight , arrayLinksByFuncCalls ) ;
}
else if ( currV = = PROC_STAT )
{
if ( st - > expr ( 0 ) )
{
if ( isIntrinsicFunctionName ( st - > symbol ( ) - > identifier ( ) ) )
findArrayRef ( parentLoops , st - > expr ( 0 ) , st - > lineNumber ( ) , RIGHT , loopInfo , privatesVars , privatesVarsForLoop ,
sortedLoopGraph , commonBlocks , declaredArrays , false , notMappedDistributedArrays ,
mappedDistrbutedArrays , st , NULL , currentWeight , arrayLinksByFuncCalls ) ;
else
{
SgExpression * listEx = st - > expr ( 0 ) ;
while ( listEx )
{
findArrayRef ( parentLoops , listEx - > lhs ( ) , st - > lineNumber ( ) , LEFT , loopInfo , privatesVars , privatesVarsForLoop ,
sortedLoopGraph , commonBlocks , declaredArrays , false , notMappedDistributedArrays ,
mappedDistrbutedArrays , st , NULL , currentWeight , arrayLinksByFuncCalls ) ;
listEx = listEx - > rhs ( ) ;
}
}
}
}
st = st - > lexNext ( ) ;
}
__spf_print ( PRINT_PROF_INFO , " Function ended \n " ) ;
}
}
//TODO: copy all functions from FDVM and fix them
static inline int getStructureSize ( SgSymbol * s )
{
return 0 ;
//printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
static inline int getNumericTypeLength ( SgType * t )
{
SgExpression * le ;
SgValueExp * ve ;
if ( t - > variant ( ) = = T_STRING )
return ( 0 ) ;
if ( TYPE_RANGES ( t - > thetype ) )
{
le = t - > length ( ) ;
if ( ve = isSgValueExp ( le ) )
return ve - > intValue ( ) ;
else
return 0 ;
}
if ( TYPE_KIND_LEN ( t - > thetype ) )
{
le = t - > selector ( ) - > lhs ( ) ;
if ( ve = isSgValueExp ( le ) )
if ( t - > variant ( ) = = T_COMPLEX | | t - > variant ( ) = = T_DCOMPLEX )
return 2 * ve - > intValue ( ) ;
else
return ve - > intValue ( ) ;
else
return 0 ;
}
return 0 ;
}
static inline int getIntrinsicTypeSize ( SgType * t )
{
const int default_real_size = 4 ;
const int default_integer_size = 4 ;
switch ( t - > variant ( ) )
{
case T_INT :
case T_BOOL :
return default_integer_size ;
case T_FLOAT :
return default_real_size ;
case T_COMPLEX :
return 2 * default_real_size ;
case T_DOUBLE :
return 2 * default_real_size ;
case T_DCOMPLEX :
return 4 * default_real_size ;
case T_STRING :
case T_CHAR :
return 1 ;
default :
return 0 ;
}
}
static SgExpression * getLengthOfKindExpr ( SgType * t , SgExpression * se , SgExpression * le )
{
switch ( t - > variant ( ) )
{
case T_INT :
case T_FLOAT :
case T_BOOL :
case T_DOUBLE :
return se - > lhs ( ) ;
case T_COMPLEX :
case T_DCOMPLEX :
return & ( * new SgValueExp ( 2 ) * ( * ( se - > lhs ( ) ) ) ) ;
case T_CHAR :
case T_STRING :
{
SgExpression * length , * kind ;
if ( se - > rhs ( ) & & se - > rhs ( ) - > variant ( ) = = LENGTH_OP )
{
length = se - > rhs ( ) - > lhs ( ) ;
kind = se - > lhs ( ) - > lhs ( ) ;
}
else if ( se - > rhs ( ) & & se - > rhs ( ) - > variant ( ) ! = LENGTH_OP )
{
length = se - > lhs ( ) - > lhs ( ) ;
kind = se - > rhs ( ) - > lhs ( ) ;
}
else
{
length = se - > lhs ( ) ;
kind = NULL ;
}
length = le ? le : length ;
if ( kind )
return & ( * length * ( * kind ) ) ;
else
return length ;
}
default :
return ( NULL ) ;
}
}
SgExpression * getTypeLengthExpr ( SgType * t )
{
SgExpression * len ;
SgExpression * selector ;
if ( t - > variant ( ) = = T_DERIVED_TYPE )
return new SgValueExp ( getStructureSize ( t - > symbol ( ) ) ) ;
len = TYPE_RANGES ( t - > thetype ) ? t - > length ( ) : NULL ;
selector = TYPE_KIND_LEN ( t - > thetype ) ? t - > selector ( ) : NULL ;
if ( ! len & & ! selector ) //the number of bytes is not specified in type declaration statement
return ( new SgValueExp ( getIntrinsicTypeSize ( t ) ) ) ;
else if ( len & & ! selector ) //INTEGER*2,REAL*8,CHARACTER*(N+1)
2024-04-09 11:51:21 +03:00
return CalculateInteger ( len - > copyPtr ( ) ) ;
2023-09-14 19:43:13 +03:00
else
2024-04-09 11:51:21 +03:00
return CalculateInteger ( getLengthOfKindExpr ( t , selector , len ) - > copyPtr ( ) ) ; //specified kind or/and len
2023-09-14 19:43:13 +03:00
}
int getSizeOfType ( SgType * t )
{
int len = - 1 ;
if ( IS_INTRINSIC_TYPE ( t ) )
return getIntrinsicTypeSize ( t ) ;
if ( t - > variant ( ) = = T_DERIVED_TYPE )
return getStructureSize ( t - > symbol ( ) ) ;
if ( len = getNumericTypeLength ( t ) )
return len ;
SgExpression * le = getTypeLengthExpr ( t ) ;
if ( le - > isInteger ( ) )
{
len = le - > valueInteger ( ) ;
len = len < 0 ? 0 : len ; //according to standard F90
}
else
len = - 1 ; //may be error situation
return len ;
}
void insertSpfAnalysisBeforeParalleLoops ( const vector < LoopGraph * > & loops )
{
for ( auto & loop : loops )
{
SgStatement * spfStat = new SgStatement ( SPF_ANALYSIS_DIR ) ;
spfStat - > setlineNumber ( loop - > lineNum ) ;
spfStat - > setLocalLineNumber ( 0 ) ;
spfStat - > setFileName ( ( char * ) current_file - > filename ( ) ) ;
if ( ! loop - > hasLimitsToParallel ( ) )
{
loop - > loop - > addAttribute ( SPF_ANALYSIS_DIR , spfStat , sizeof ( SgStatement ) ) ;
//uncomment it to debug private analysis
2024-07-24 12:07:29 +03:00
//loop->loop->insertStmtBefore(*spfStat, *loop->loop->controlParent());
2023-09-14 19:43:13 +03:00
}
insertSpfAnalysisBeforeParalleLoops ( loop - > children ) ;
}
}
# undef PRINT_ARRAY_ARCS
# undef PRINT_LOOP_STRUCT
# undef PRINT_PROF_INFO
# undef FIRST
# undef SECOND
# undef THIRD