2023-09-14 19:43:13 +03:00
# include "../Utils/leak_detector.h"
# include <cstdio>
# include <cstdlib>
# include <cstring>
# include <cstdint>
# include <string>
# include <fstream>
# include <sstream>
# include <iostream>
# include <vector>
# include <map>
2023-11-22 20:21:18 +03:00
# include <queue>
2023-09-14 19:43:13 +03:00
# include <set>
# include <utility>
# include <string>
# include <assert.h>
# include <locale>
# include <algorithm>
# include <fcntl.h>
# include <mutex>
# include <thread>
# include <stack>
2024-02-20 11:12:00 +03:00
2023-09-14 19:43:13 +03:00
# ifdef _WIN32
# include <direct.h>
# else
# include <unistd.h>
# endif
# include "SgUtils.h"
# include "errors.h"
# include "../Sapfor.h"
# include "../DirectiveProcessing/directive_parser.h"
# include "../Distribution/Distribution.h"
# include "../GraphCall/graph_calls.h"
# include "../GraphCall/graph_calls_func.h"
# include "../CreateInterTree/CreateInterTree.h"
# include "../Predictor/PredictScheme.h"
# include "../VisualizerCalls/get_information.h"
# include "../VisualizerCalls/SendMessage.h"
# include "../VerificationCode/verifications.h"
# include "../LoopAnalyzer/loop_analyzer.h"
using std : : map ;
2023-11-22 20:21:18 +03:00
using std : : queue ;
2023-09-14 19:43:13 +03:00
using std : : multimap ;
using std : : pair ;
using std : : tuple ;
using std : : set ;
using std : : vector ;
using std : : string ;
using std : : make_pair ;
using std : : make_tuple ;
using std : : wstring ;
using std : : stack ;
static bool ifIntervalExists ( const vector < pair < int , int > > & intervals , const pair < int , int > & toFind , pair < int , int > & inInterval )
{
bool retVal = false ;
for ( auto & elem : intervals )
{
if ( toFind . first < = elem . first & & toFind . second > = elem . second )
{
inInterval = elem ;
retVal = true ;
break ;
}
}
return retVal ;
}
static bool ifDir ( const string & line )
{
if ( line . size ( ) > = 10 & & ( line [ 0 ] = = ' ! ' | | line [ 0 ] = = ' c ' ) )
{
string dir ( line . begin ( ) + 1 , line . begin ( ) + 1 + 4 ) ;
if ( dir = = " $spf " | | dir = = " dvm$ " )
return true ;
}
return false ;
}
static string replaceTabsToSpaces ( const string & in )
{
string ret = " " ;
for ( auto & elem : in )
{
if ( elem = = ' \t ' )
ret + = " " ;
else
ret + = elem ;
}
return ret ;
}
static map < string , pair < string , vector < pair < int , int > > > > findIncludes ( FILE * currFile )
{
map < string , pair < string , vector < pair < int , int > > > > includeFiles ;
bool notClosed = false ;
// TODO: extend buff size in dynamic
char buf [ 8192 ] ;
int lineBefore = 0 ;
while ( ! feof ( currFile ) )
{
char * read = fgets ( buf , 8192 , currFile ) ;
if ( read )
{
const string orig ( replaceTabsToSpaces ( read ) ) ;
string line ( read ) ;
convertToLower ( line ) ;
line = replaceTabsToSpaces ( line ) ;
size_t posF = line . find ( " include " ) ;
if ( posF ! = string : : npos )
{
//check if 'inclide' - operator
for ( size_t k = 0 ; k < posF ; + + k )
{
if ( line [ k ] ! = ' ' )
{
posF = - 1 ;
break ;
}
}
if ( posF = = - 1 )
{
+ + lineBefore ;
continue ;
}
posF + = sizeof ( " include " ) - 1 ;
int tok = 0 ;
size_t st = string : : npos , en = string : : npos ;
for ( size_t k = posF ; k < line . size ( ) ; + + k )
{
bool isQuote = line [ k ] = = ' \' ' | | line [ k ] = = ' \" ' ;
if ( isQuote & & tok = = 1 )
break ;
else if ( isQuote )
tok + + ;
else if ( tok = = 1 & & st = = string : : npos )
st = k ;
else
en = k ;
}
if ( st = = string : : npos | | st > = line . size ( ) | | en = = string : : npos | | en > = line . size ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
const string inclName ( orig . begin ( ) + st , orig . begin ( ) + en + 1 ) ;
auto toInsert = includeFiles . find ( inclName ) ;
if ( toInsert = = includeFiles . end ( ) )
{
toInsert = includeFiles . insert ( toInsert , make_pair ( inclName , make_pair ( orig , vector < pair < int , int > > ( ) ) ) ) ;
toInsert - > second . second . push_back ( make_pair ( lineBefore , - 1 ) ) ;
notClosed = true ;
}
else
{
toInsert - > second . second . push_back ( make_pair ( lineBefore , - 1 ) ) ;
notClosed = true ;
}
//printf("insert %s -> %s\n", inclName.c_str(), line.c_str());
}
else if ( ( line [ 0 ] ! = ' c ' & & line [ 0 ] ! = ' ! ' & & line ! = " " & & line [ 0 ] ! = ' \n ' ) | | ifDir ( line ) )
{
if ( notClosed )
{
for ( auto & elem : includeFiles )
for ( auto & pair : elem . second . second )
if ( pair . second = = - 1 )
pair . second = lineBefore + 1 ;
notClosed = false ;
}
}
}
+ + lineBefore ;
}
return includeFiles ;
}
static vector < string > findCommentsInIncludes ( map < string , pair < string , vector < pair < int , int > > > > & includeFiles )
{
vector < string > foundComments ;
for ( auto & elem : includeFiles )
{
FILE * inclFile = fopen ( elem . first . c_str ( ) , " r " ) ;
if ( inclFile = = NULL )
{
char buf [ 256 ] ;
sprintf ( buf , " ERROR: Can't open inlcude file %s for read with err %d \n " , elem . first . c_str ( ) , errno ) ;
addToGlobalBufferAndPrint ( buf ) ;
continue ;
}
char buf [ 8192 ] ;
int lineBefore = 0 ;
string newComment = " " ;
while ( ! feof ( inclFile ) )
{
char * read = fgets ( buf , 8192 , inclFile ) ;
if ( read )
{
string orig ( replaceTabsToSpaces ( read ) ) ;
if ( orig . size ( ) & & ( orig [ 0 ] = = ' C ' | | orig [ 0 ] = = ' c ' ) )
{
orig [ 0 ] = ' ! ' ;
newComment + = orig ;
continue ;
}
int k = 0 ;
while ( k < orig . size ( ) )
{
if ( orig [ k ] = = ' ' )
+ + k ;
else
break ;
}
// remove first spaces
if ( k > 0 )
orig . erase ( orig . begin ( ) , orig . begin ( ) + k ) ;
if ( orig . size ( ) )
{
if ( orig [ 0 ] = = ' ! ' )
newComment + = read ;
else if ( newComment ! = " " )
{
foundComments . push_back ( newComment ) ;
newComment = " " ;
}
}
else if ( newComment ! = " " )
{
foundComments . push_back ( newComment ) ;
newComment = " " ;
}
}
}
if ( newComment ! = " " )
{
foundComments . push_back ( newComment ) ;
newComment = " " ;
}
fclose ( inclFile ) ;
}
return foundComments ;
}
static int reverseVar ( SgStatement * st )
{
st - > setVariant ( - 1 * st - > variant ( ) ) ;
return st - > id ( ) ;
}
static map < SgStatement * , map < int , set < string > > > insertedIncludes ;
static set < SgFile * > genVersionDone ;
2024-03-16 17:35:51 +03:00
static set < int > hideUnnecessary ( SgFile * file , const string & fileN , const set < string > & moduleDeclsInFiles , bool dontReplaceIncludes )
2024-02-28 17:38:02 +03:00
{
set < int > changedVars ;
for ( SgStatement * st = file - > firstStatement ( ) ; st ; st = st - > lexNext ( ) )
{
2024-06-10 09:16:15 +03:00
if ( st - > variant ( ) = = GLOBAL )
continue ;
2024-02-28 17:38:02 +03:00
if ( dontReplaceIncludes = = false )
{
if ( st - > fileName ( ) ! = fileN | | st - > getUnparseIgnore ( ) )
if ( st - > variant ( ) > 0 )
changedVars . insert ( reverseVar ( st ) ) ;
}
else
{
if ( st - > getUnparseIgnore ( ) )
{
if ( st - > variant ( ) > 0 )
changedVars . insert ( reverseVar ( st ) ) ;
}
else if ( st - > fileName ( ) ! = fileN )
{
if ( st - > variant ( ) = = MODULE_STMT & & moduleDeclsInFiles . find ( st - > fileName ( ) ) ! = moduleDeclsInFiles . end ( ) )
{
for ( auto mSt = st ; mSt ! = st - > lastNodeOfStmt ( ) ; mSt = mSt - > lexNext ( ) )
changedVars . insert ( reverseVar ( mSt ) ) ;
st = st - > lastNodeOfStmt ( ) ;
changedVars . insert ( reverseVar ( st ) ) ;
}
}
}
}
return changedVars ;
}
2023-09-14 19:43:13 +03:00
//TODO: read includes and find last lines, all included files
string removeIncludeStatsAndUnparse ( SgFile * file , const char * fileName , const char * fout ,
set < string > & allIncludeFiles , bool outFree ,
const map < string , set < string > > & moduleUsesByFile , const map < string , string > & moduleDelcs ,
const map < SgStatement * , vector < SgStatement * > > & exctactedModuleStats ,
2024-06-10 09:16:15 +03:00
bool toString , bool renameIncludes , bool dontReplaceIncludes )
2023-09-14 19:43:13 +03:00
{
removeSpecialCommentsFromProject ( file ) ;
if ( genVersionDone . find ( file ) = = genVersionDone . end ( ) )
{
auto firstStat = file - > firstStatement ( ) ;
auto com = printVersionAsFortranComm ( ) ;
if ( com ! = " " )
firstStat - > addComment ( com . c_str ( ) ) ;
genVersionDone . insert ( file ) ;
}
fflush ( NULL ) ;
const set < string > modulesExclude = getExcludedModules ( ) ;
set < string > moduleIncudeUses ;
auto itM = moduleUsesByFile . find ( fileName ) ;
if ( itM ! = moduleUsesByFile . end ( ) )
{
for ( auto & elem : itM - > second )
{
auto it2 = moduleDelcs . find ( elem ) ;
if ( it2 = = moduleDelcs . end ( ) )
{
if ( modulesExclude . find ( elem ) ! = modulesExclude . end ( ) )
continue ;
__spf_print ( 1 , " can not find module '%s' \n " , elem . c_str ( ) ) ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
string lowerInclude = it2 - > second ;
convertToLower ( lowerInclude ) ;
moduleIncudeUses . insert ( lowerInclude ) ;
}
}
int funcNum = file - > numberOfFunctions ( ) ;
FILE * currFile = fopen ( fileName , " r " ) ;
if ( currFile = = NULL )
{
char buf [ 256 ] ;
sprintf ( buf , " ERROR: Can't open file %s for read with err %d \n " , fileName , errno ) ;
addToGlobalBufferAndPrint ( buf ) ;
char buff [ 1024 ] ;
if ( getcwd ( buff , 1024 ) = = NULL )
; //
else
__spf_print ( 1 , " curr path %s \n " , buff ) ;
throw ( - 1 ) ;
}
// name -> unparse comment and position
map < string , pair < string , vector < pair < int , int > > > > includeFiles = findIncludes ( currFile ) ;
fclose ( currFile ) ;
const vector < string > commentsFromIncl = findCommentsInIncludes ( includeFiles ) ;
//add spaces if needed
if ( ! outFree )
{
for ( auto & elem : includeFiles )
{
int countSpaces = 0 ;
for ( int z = 0 ; z < elem . second . first . size ( ) & & elem . second . first [ z ] = = ' ' ; + + z , + + countSpaces ) { }
if ( countSpaces < 6 )
{
while ( countSpaces ! = 6 )
{
elem . second . first . insert ( elem . second . first . begin ( ) , ' ' ) ;
countSpaces + + ;
}
}
}
}
const string fileN = fileName ;
//insert comment
int lineBefore = - 1 ;
map < string , set < SgStatement * > > insertedIncludeFiles ;
map < int , vector < pair < int , int > > > placesForInsert ;
set < string > foundForIncludes ;
map < int , int > stIdByLine ;
for ( SgStatement * st = file - > firstStatement ( ) ; st ; st = st - > lexNext ( ) )
{
if ( st - > variant ( ) > 0 & & st - > lineNumber ( ) > 0 & & st - > fileName ( ) = = string ( file - > filename ( ) ) )
{
stIdByLine [ st - > lineNumber ( ) ] = st - > id ( ) ;
vector < SgStatement * > attr = getAttributes < SgStatement * , SgStatement * > ( st , set < int > { SPF_ANALYSIS_DIR , SPF_NOINLINE_OP } ) ;
for ( auto & elem : attr )
if ( stIdByLine . find ( elem - > lineNumber ( ) ) = = stIdByLine . end ( ) )
stIdByLine [ elem - > lineNumber ( ) ] = st - > id ( ) ;
}
}
auto fileInProject = getAllFilesInProject ( ) ;
for ( SgStatement * st = file - > firstStatement ( ) ; st ; st = st - > lexNext ( ) )
{
if ( st - > lineNumber ( ) < = 0 | | st - > variant ( ) < 0 )
continue ;
string currFileName = st - > fileName ( ) ;
// included for module use
if ( currFileName ! = fileN & & fileInProject . find ( currFileName ) ! = fileInProject . end ( ) )
{
st = st - > lastNodeOfStmt ( ) ;
continue ;
}
if ( currFileName ! = fileN )
{
allIncludeFiles . insert ( currFileName ) ;
auto it = includeFiles . find ( currFileName ) ;
if ( it ! = includeFiles . end ( ) )
{
foundForIncludes . insert ( currFileName ) ;
pair < int , int > lines = make_pair ( lineBefore , - 1 ) ;
SgStatement * locSt = st - > lexNext ( ) ;
set < string > nearIncludes ;
while ( locSt & & ( locSt - > fileName ( ) ! = fileN | | locSt - > lineNumber ( ) < = 0 ) )
{
const string locName = locSt - > fileName ( ) ;
if ( locName ! = fileN )
{
allIncludeFiles . insert ( locName ) ;
if ( locName ! = currFileName )
{
auto itNear = includeFiles . find ( locName ) ;
if ( itNear ! = includeFiles . end ( ) )
{
nearIncludes . insert ( locName ) ;
foundForIncludes . insert ( locName ) ;
}
}
}
locSt = locSt - > lexNext ( ) ;
}
if ( locSt )
{
lines . second = locSt - > lineNumber ( ) ;
st = locSt ;
bool change = true ;
while ( change )
{
change = false ;
SgStatement * prev = locSt - > lexPrev ( ) ;
if ( prev & &
( prev - > variant ( ) = = DVM_PARALLEL_ON_DIR | |
prev - > variant ( ) = = SPF_ANALYSIS_DIR | |
prev - > variant ( ) = = SPF_TRANSFORM_DIR | |
prev - > variant ( ) = = DVM_INTERVAL_DIR | |
prev - > variant ( ) = = ACC_REGION_DIR | |
prev - > variant ( ) = = DVM_REALIGN_DIR | |
prev - > variant ( ) = = DVM_REDISTRIBUTE_DIR ) )
{
locSt = prev ;
change = true ;
}
}
placesForInsert [ locSt - > id ( ) ] . push_back ( lines ) ;
}
}
}
else
lineBefore = st - > lineNumber ( ) ;
}
//if not found, it indicates that file contains of other include files
for ( auto & incl : includeFiles )
{
if ( foundForIncludes . find ( incl . first ) = = foundForIncludes . end ( ) )
{
for ( auto & interval : incl . second . second )
{
bool added = false ;
for ( int z = interval . second ; z > interval . first ; z - - )
{
auto it = stIdByLine . find ( z ) ;
if ( it ! = stIdByLine . end ( ) )
{
placesForInsert [ it - > second ] . push_back ( interval ) ;
added = true ;
break ;
}
}
if ( added = = false )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
}
for ( SgStatement * st = file - > firstStatement ( ) ; st ; st = st - > lexNext ( ) )
{
if ( st - > variant ( ) < 0 )
continue ;
auto itGlobal = insertedIncludes . find ( st ) ;
if ( itGlobal = = insertedIncludes . end ( ) )
itGlobal = insertedIncludes . insert ( itGlobal , make_pair ( st , map < int , set < string > > ( ) ) ) ;
map < int , set < string > > & toInsertIncludeComment = itGlobal - > second ;
bool needUpdated = false ;
for ( auto & it : includeFiles )
{
auto foundV = placesForInsert . find ( st - > id ( ) ) ;
if ( foundV ! = placesForInsert . end ( ) )
{
SgStatement * parent = getFuncStat ( st , { BLOCK_DATA , MODULE_STMT } ) ;
if ( ! parent )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
for ( auto & interval : foundV - > second )
{
pair < int , int > inInterval ;
if ( ifIntervalExists ( it . second . second , interval , inInterval ) & & insertedIncludeFiles [ it . first ] . find ( parent ) = = insertedIncludeFiles [ it . first ] . end ( ) )
{
allIncludeFiles . insert ( it . first ) ;
insertedIncludeFiles [ it . first ] . insert ( parent ) ;
string lowerInclude = it . first ;
convertToLower ( lowerInclude ) ;
if ( moduleIncudeUses . find ( lowerInclude ) = = moduleIncudeUses . end ( ) )
{
if ( dontReplaceIncludes = = false )
{
auto itI = toInsertIncludeComment . find ( inInterval . first ) ;
if ( itI = = toInsertIncludeComment . end ( ) | |
( itI ! = toInsertIncludeComment . end ( ) & & itI - > second . find ( it . second . first ) = = itI - > second . end ( ) ) )
{
toInsertIncludeComment [ inInterval . first ] . insert ( it . second . first ) ;
needUpdated = true ;
__spf_print ( 1 , " --> restore include '%s' before statement on line %d \n " , it . first . c_str ( ) , st - > lineNumber ( ) ) ;
}
}
}
}
}
}
}
if ( needUpdated )
{
string inlcude = " " ;
for ( auto & inclByPos : toInsertIncludeComment )
for ( auto & incl : inclByPos . second )
2024-06-10 09:16:15 +03:00
inlcude + = ( renameIncludes ? renameInclude ( incl ) : incl ) ;
2023-09-14 19:43:13 +03:00
if ( st - > comments ( ) )
st - > setComments ( ( inlcude + st - > comments ( ) ) . c_str ( ) ) ;
else
st - > addComment ( inlcude . c_str ( ) ) ;
}
}
for ( auto & inserted : insertedIncludeFiles )
{
auto it = includeFiles . find ( inserted . first ) ;
if ( it = = includeFiles . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
//TODO: dont work after subroutine copying
/*if (inserted.second.size() != it->second.second.size())
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ; */
}
set < string > moduleDeclsInFiles ;
for ( auto & elem : moduleDelcs )
moduleDeclsInFiles . insert ( elem . second ) ;
//restore hidden modules
vector < SgStatement * > toExtract ;
for ( auto & mod : exctactedModuleStats )
{
auto cp = mod . first - > controlParent ( ) ;
for ( auto & toInsert : mod . second )
{
mod . first - > insertStmtBefore ( * toInsert , * cp ) ;
toExtract . push_back ( toInsert ) ;
}
}
//remove unnecessary
//XXX: use Sage hack!!
2024-02-28 17:38:02 +03:00
set < int > changedVars = hideUnnecessary ( file , fileN , moduleDeclsInFiles , dontReplaceIncludes ) ;
2023-09-14 19:43:13 +03:00
set < int > checkPositions ;
for ( auto & elem : includeFiles )
for ( auto & interval : elem . second . second )
checkPositions . insert ( interval . second ) ;
// remove comments that were substituted from includes
for ( SgStatement * st = file - > firstStatement ( ) ; st ; st = st - > lexNext ( ) )
{
const char * comments = st - > comments ( ) ;
if ( st - > fileName ( ) = = fileN & & st - > variant ( ) > 0 & & comments & & ! dontReplaceIncludes )
{
if ( checkPositions . find ( st - > lineNumber ( ) ) ! = checkPositions . end ( ) )
{
//printf("%s\n", comments);
string str ( comments ) ;
bool wasDeleted = false ;
for ( auto & com : commentsFromIncl )
{
auto it = str . find ( com ) ;
while ( it ! = string : : npos )
{
wasDeleted = true ;
str . erase ( it , com . size ( ) ) ;
it = str . find ( com ) ;
}
if ( str . size ( ) = = 0 )
break ;
}
if ( wasDeleted )
{
2024-12-02 23:17:58 +03:00
if ( str . size ( ) | | str . back ( ) ! = ' \n ' )
2023-09-14 19:43:13 +03:00
str + = ' \n ' ;
st - > setComments ( str . c_str ( ) ) ;
}
}
}
}
2025-01-29 10:08:13 +03:00
//check for empty
string comm = " " ;
if ( file - > firstStatement ( ) - > comments ( ) )
{
comm = file - > firstStatement ( ) - > comments ( ) ;
file - > firstStatement ( ) - > delComments ( ) ;
}
const string tmp = file - > firstStatement ( ) - > unparse ( ) ;
bool isEmpty = ( tmp . size ( ) = = 0 ) ;
if ( comm . size ( ) )
file - > firstStatement ( ) - > addComment ( comm . c_str ( ) ) ;
2023-09-14 19:43:13 +03:00
string strUnparse = " " ;
if ( toString )
{
2025-01-29 10:08:13 +03:00
if ( ! isEmpty )
strUnparse = string ( file - > firstStatement ( ) - > unparse ( ) ) ;
}
else
{
if ( ! isEmpty )
2023-09-14 19:43:13 +03:00
{
# ifdef _WIN32
FILE * fOut ;
errno_t err = fopen_s ( & fOut , fout , " w " ) ;
# else
int err = 0 ;
FILE * fOut = fopen ( fout , " w " ) ;
# endif
if ( fOut = = NULL )
{
if ( fout )
__spf_print ( 1 , " can not open file to write with name '%s' with error %d \n " , fout , err ) ;
else
__spf_print ( 1 , " can not open file to write with name 'NULL' \n " ) ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
file - > unparse ( fOut ) ;
fclose ( fOut ) ;
}
}
//restore back
//XXX: use Sage hack!!
for ( SgStatement * st = file - > firstStatement ( ) ; st ; st = st - > lexNext ( ) )
if ( changedVars . find ( st - > id ( ) ) ! = changedVars . end ( ) )
st - > setVariant ( - 1 * st - > variant ( ) ) ;
for ( auto & elem : toExtract )
elem - > extractStmt ( ) ;
return strUnparse ;
}
static map < SgFile * , map < string , vector < SgSymbol * > > > allCreatedSymbols ;
SgSymbol * findSymbolOrCreate ( SgFile * file , const string toFind , SgType * type , SgStatement * scope )
{
auto createdSymbols = allCreatedSymbols . find ( file ) ;
if ( createdSymbols = = allCreatedSymbols . end ( ) )
createdSymbols = allCreatedSymbols . insert ( createdSymbols , make_pair ( file , map < string , vector < SgSymbol * > > ( ) ) ) ;
SgSymbol * symb = file - > firstSymbol ( ) ;
while ( symb )
{
if ( symb - > identifier ( ) = = toFind )
{
bool scopeC = false ;
bool typeC = false ;
if ( scope )
scopeC = ( symb - > scope ( ) = = scope ) ;
else
scopeC = true ;
if ( type )
typeC = ( symb - > type ( ) & & symb - > type ( ) - > equivalentToType ( type ) ) ;
else
typeC = true ;
if ( scopeC & & typeC )
return symb ;
}
symb = symb - > next ( ) ;
}
auto result = createdSymbols - > second . find ( toFind ) ;
if ( result = = createdSymbols - > second . end ( ) )
result = createdSymbols - > second . insert ( result , make_pair ( toFind , vector < SgSymbol * > ( ) ) ) ;
SgSymbol * newS = NULL ;
for ( auto & symbs : result - > second )
{
if ( ( symbs - > scope ( ) = = scope & & scope ) | | ( ! symbs - > scope ( ) & & ! scope ) )
{
if ( symbs - > type ( ) & & type )
{
if ( symbs - > type ( ) - > equivalentToType ( type ) )
{
newS = symbs ;
break ;
}
}
else if ( ! symbs - > type ( ) & & ! type )
{
newS = symbs ;
break ;
}
}
}
if ( newS = = NULL )
{
newS = new SgSymbol ( VARIABLE_NAME , toFind . c_str ( ) , type , scope ) ;
result - > second . push_back ( newS ) ;
}
return newS ;
}
static string getValue ( SgExpression * exp )
{
if ( exp = = NULL | | exp - > variant ( ) = = STMT_STR )
return " " ;
string ret = " " ;
if ( exp - > variant ( ) = = CONST_REF )
{
if ( exp - > symbol ( ) - > identifier ( ) )
{
ret = " ( " + string ( exp - > symbol ( ) - > identifier ( ) ) ;
auto sc = isSgConstantSymb ( exp - > symbol ( ) ) ;
if ( sc & & sc - > constantValue ( ) )
ret + = string ( " = " ) + sc - > constantValue ( ) - > unparse ( ) ;
ret + = " ) " ;
}
}
else if ( exp - > symbol ( ) )
{
if ( exp - > symbol ( ) - > identifier ( ) )
ret = " ( " + string ( exp - > symbol ( ) - > identifier ( ) ) + " ) " ;
}
else if ( exp - > variant ( ) = = INT_VAL )
ret = " ( " + std : : to_string ( exp - > valueInteger ( ) ) + " ) " ;
else if ( exp - > variant ( ) = = DOUBLE_VAL )
ret = string ( " ( " ) + ( ( ( SgValueExp * ) exp ) - > doubleValue ( ) ) + " ) " ;
else if ( exp - > variant ( ) = = FLOAT_VAL )
ret = string ( " ( " ) + ( ( ( SgValueExp * ) exp ) - > floatValue ( ) ) + " ) " ;
else if ( exp - > variant ( ) = = ADD_OP )
ret = " (+) " ;
else if ( exp - > variant ( ) = = SUBT_OP )
ret = " (-) " ;
else if ( exp - > variant ( ) = = MULT_OP )
ret = " (*) " ;
else if ( exp - > variant ( ) = = DIV_OP )
ret = " (/) " ;
else if ( exp - > variant ( ) = = MOD_OP )
ret = " (mod) " ;
else if ( exp - > variant ( ) = = EXP_OP )
ret = " (**) " ;
else if ( exp - > variant ( ) = = KEYWORD_VAL )
ret = " ( " + string ( ( ( SgKeywordValExp * ) exp ) - > value ( ) ) + " ) " ;
return ret ;
}
static void recExpressionPrint ( SgExpression * exp , const int lvl , const char * LR , const int currNum , int & allNum )
{
if ( exp )
{
SgExpression * lhs = exp - > lhs ( ) ;
SgExpression * rhs = exp - > rhs ( ) ;
int lNum , rNum ;
string vCurr = getValue ( exp ) ;
string vL = getValue ( lhs ) ;
string vR = getValue ( rhs ) ;
if ( lhs & & rhs )
{
lNum = allNum + 1 ;
rNum = allNum + 2 ;
allNum + = 2 ;
printf ( " \" %d_%d_%s_%s_%s \" -> \" %d_%d_L_%s_%s \" ; \n " , currNum , lvl , LR , tag [ exp - > variant ( ) ] , vCurr . c_str ( ) , lNum , lvl + 1 , tag [ lhs - > variant ( ) ] , vL . c_str ( ) ) ;
printf ( " \" %d_%d_%s_%s_%s \" -> \" %d_%d_R_%s_%s \" ; \n " , currNum , lvl , LR , tag [ exp - > variant ( ) ] , vCurr . c_str ( ) , rNum , lvl + 1 , tag [ rhs - > variant ( ) ] , vR . c_str ( ) ) ;
}
else if ( lhs )
{
lNum = allNum + 1 ;
allNum + + ;
printf ( " \" %d_%d_%s_%s_%s \" -> \" %d_%d_L_%s_%s \" ; \n " , currNum , lvl , LR , tag [ exp - > variant ( ) ] , vCurr . c_str ( ) , lNum , lvl + 1 , tag [ lhs - > variant ( ) ] , vL . c_str ( ) ) ;
}
else if ( rhs )
{
rNum = allNum + 1 ;
allNum + + ;
printf ( " \" %d_%d_%s_%s_%s \" -> \" %d_%d_R_%s_%s \" ; \n " , currNum , lvl , LR , tag [ exp - > variant ( ) ] , vCurr . c_str ( ) , rNum , lvl + 1 , tag [ rhs - > variant ( ) ] , vR . c_str ( ) ) ;
}
if ( lhs )
recExpressionPrint ( lhs , lvl + 1 , " L " , lNum , allNum ) ;
if ( rhs )
recExpressionPrint ( rhs , lvl + 1 , " R " , rNum , allNum ) ;
}
}
void recExpressionPrint ( SgExpression * exp )
{
printf ( " digraph G{ \n " ) ;
int allNum = 0 ;
recExpressionPrint ( exp , 0 , " L " , allNum , allNum ) ;
if ( allNum = = 0 & & exp )
printf ( " \" %d_%d_%s_%s_%s \" ; \n " , allNum , 0 , " L " , tag [ exp - > variant ( ) ] , getValue ( exp ) . c_str ( ) ) ;
printf ( " } \n " ) ;
fflush ( NULL ) ;
}
void initTags ( )
{
for ( int i = 0 ; i < MAXTAGS ; i + + )
tag [ i ] = NULL ;
# include "tag.h"
}
void tryToFindPrivateInAttributes ( SgStatement * st , set < string > & privates , bool onlyReduction , bool onlyUsers )
{
set < Symbol * > privatesVars ;
auto foundAttrs = getAttributes < SgStatement * , SgStatement * > ( st , set < int > { SPF_ANALYSIS_DIR , SPF_PARALLEL_DIR } ) ;
if ( onlyUsers )
foundAttrs = filterUserSpf ( foundAttrs ) ;
for ( auto & data : foundAttrs )
{
if ( data )
{
Statement * sData = new Statement ( data ) ;
if ( ! onlyReduction )
fillPrivatesFromComment ( sData , privatesVars ) ;
// try to find reductions and set its symbols as private in
// current loop analysis for correct scalar detection in
// tryToFindDependencies() function
map < string , set < Symbol * > > reductions ;
map < string , set < tuple < Symbol * , Symbol * , int > > > reductionsLoc ;
fillReductionsFromComment ( sData , reductions ) ;
fillReductionsFromComment ( sData , reductionsLoc ) ;
for ( auto & redList : reductions )
privatesVars . insert ( redList . second . begin ( ) , redList . second . end ( ) ) ;
for ( auto & redLocList : reductionsLoc )
{
for ( auto & groupList : redLocList . second )
{
privatesVars . insert ( std : : get < 0 > ( groupList ) ) ;
privatesVars . insert ( std : : get < 1 > ( groupList ) ) ;
}
}
}
}
for ( auto & elem : privatesVars )
privates . insert ( elem - > GetOriginal ( ) - > identifier ( ) ) ;
}
void fillNonDistrArraysAsPrivate ( SgStatement * st ,
const map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays ,
const map < SgStatement * , set < tuple < int , string , string > > > & declaratedArraysSt ,
set < string > & privatesVars )
{
// fill as private all non distributed arrays
auto it = declaratedArraysSt . find ( st ) ;
if ( it ! = declaratedArraysSt . end ( ) )
{
for ( auto itSet = it - > second . begin ( ) ; itSet ! = it - > second . end ( ) ; + + itSet )
{
auto itD = declaredArrays . find ( * itSet ) ;
if ( itD ! = declaredArrays . end ( ) )
if ( itD - > second . first - > IsNotDistribute ( ) )
privatesVars . insert ( itD - > second . first - > GetShortName ( ) ) ;
}
}
}
extern map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > declaredArrays ;
extern map < SgStatement * , set < tuple < int , string , string > > > declaratedArraysSt ;
DIST : : Array * getArrayFromDeclarated ( SgStatement * st , const string & arrayName )
{
DIST : : Array * found = NULL ;
auto it = declaratedArraysSt . find ( st ) ;
if ( it ! = declaratedArraysSt . end ( ) )
{
for ( auto itSet = it - > second . begin ( ) ; itSet ! = it - > second . end ( ) & & ! found ; + + itSet )
{
auto itD = declaredArrays . find ( * itSet ) ;
if ( itD ! = declaredArrays . end ( ) )
if ( itD - > second . first - > GetShortName ( ) = = arrayName )
found = itD - > second . first ;
}
}
return found ;
}
static bool findSymbol ( SgExpression * declLst , const string & toFind )
{
if ( declLst = = NULL )
return false ;
stack < SgExpression * > exs ;
exs . push ( declLst ) ;
while ( ! exs . empty ( ) )
{
SgExpression * ex = exs . top ( ) ;
exs . pop ( ) ;
2024-05-15 17:54:18 +03:00
if ( ex - > variant ( ) = = ARRAY_REF | | ex - > variant ( ) = = VAR_REF | | ex - > variant ( ) = = CONST_REF )
2023-09-14 19:43:13 +03:00
{
if ( ex - > symbol ( ) - > identifier ( ) = = toFind )
return true ;
}
2024-05-14 12:53:31 +03:00
else
{
if ( ex - > lhs ( ) )
exs . push ( ex - > lhs ( ) ) ;
2023-09-14 19:43:13 +03:00
2024-05-14 12:53:31 +03:00
if ( ex - > rhs ( ) )
exs . push ( ex - > rhs ( ) ) ;
}
2023-09-14 19:43:13 +03:00
}
return false ;
}
extern map < string , vector < Messages > > SPF_messages ;
2024-06-10 09:16:15 +03:00
SgStatement * declaratedInStmt ( SgSymbol * toFind , vector < SgStatement * > * allDecls , bool printInternal , SgStatement * scope )
2023-09-14 19:43:13 +03:00
{
//need to call this function for MODULE symbols!
toFind = OriginalSymbol ( toFind ) ;
vector < SgStatement * > inDecl ;
2024-06-10 09:16:15 +03:00
if ( toFind - > variant ( ) = = FUNCTION_NAME & & scope = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SgStatement * start = scope ? scope : toFind - > scope ( ) ;
2023-09-14 19:43:13 +03:00
if ( start )
{
SgStatement * end = start - > lastNodeOfStmt ( ) ;
const set < int > possibleVars = { VAR_DECL , VAR_DECL_90 , ALLOCATABLE_STMT , DIM_STAT , EXTERN_STAT ,
COMM_STAT , HPF_TEMPLATE_STAT , DVM_VAR_DECL , STRUCT_DECL } ;
while ( start ! = end )
{
//error ?
if ( start = = NULL )
break ;
if ( start - > variant ( ) = = INTERFACE_STMT )
start = start - > lastNodeOfStmt ( ) ;
//printf("%d on line %d\n", start->variant(), start->lineNumber());
if ( possibleVars . find ( start - > variant ( ) ) ! = possibleVars . end ( ) )
{
for ( int i = 0 ; i < 3 ; + + i )
{
SgExpression * declLst = start - > expr ( i ) ;
if ( findSymbol ( declLst , toFind - > identifier ( ) ) )
inDecl . push_back ( start ) ;
}
}
if ( ! isDVM_stat ( start ) & & ! isSPF_stat ( start ) & & isSgExecutableStatement ( start ) )
break ;
start = start - > lexNext ( ) ;
}
}
/*if (inDecl.size() == 0)
{
SgStatement * lowLevelDecl = toFind - > declaredInStmt ( ) ;
if ( lowLevelDecl )
inDecl . push_back ( lowLevelDecl ) ;
} */
if ( inDecl . size ( ) = = 0 )
{
if ( printInternal )
{
__spf_print ( 1 , " can not find declaration for symbol '%s' \n " , toFind - > identifier ( ) ) ;
auto itM = SPF_messages . find ( start - > fileName ( ) ) ;
if ( itM = = SPF_messages . end ( ) )
itM = SPF_messages . insert ( itM , make_pair ( start - > fileName ( ) , vector < Messages > ( ) ) ) ;
wstring bufE , bufR ;
__spf_printToLongBuf ( bufE , L " Can not find declaration for symbol '%s' in current scope " , to_wstring ( toFind - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( bufR , R49 , to_wstring ( toFind - > identifier ( ) ) . c_str ( ) ) ;
itM - > second . push_back ( Messages ( ERROR , toFind - > scope ( ) - > lineNumber ( ) , bufR , bufE , 1017 ) ) ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
return NULL ;
}
if ( allDecls )
* allDecls = inDecl ;
//return statement by priority: VAR_DECL, VAR_DECL_90, ALLOCATABLE_STMT, DIM_STAT, other
if ( inDecl . size ( ) > 1 )
{
for ( int i = 0 ; i < inDecl . size ( ) ; + + i )
if ( inDecl [ i ] - > variant ( ) = = VAR_DECL | | inDecl [ i ] - > variant ( ) = = VAR_DECL_90 )
return inDecl [ i ] ;
for ( int i = 0 ; i < inDecl . size ( ) ; + + i )
if ( inDecl [ i ] - > variant ( ) = = ALLOCATABLE_STMT )
return inDecl [ i ] ;
for ( int i = 0 ; i < inDecl . size ( ) ; + + i )
if ( inDecl [ i ] - > variant ( ) = = DIM_STAT )
return inDecl [ i ] ;
for ( int i = 0 ; i < inDecl . size ( ) ; + + i )
if ( inDecl [ i ] - > variant ( ) = = COMM_STAT )
return inDecl [ i ] ;
for ( int i = 0 ; i < inDecl . size ( ) ; + + i )
if ( inDecl [ i ] - > variant ( ) = = HPF_TEMPLATE_STAT )
return inDecl [ i ] ;
for ( int i = 0 ; i < inDecl . size ( ) ; + + i )
if ( inDecl [ i ] - > variant ( ) = = DVM_VAR_DECL )
return inDecl [ i ] ;
for ( int i = 0 ; i < inDecl . size ( ) ; + + i )
return inDecl [ i ] ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
return NULL ;
}
else
return inDecl [ 0 ] ;
}
bool isDVM_stat ( SgStatement * st )
{
if ( st = = NULL )
return false ;
bool ret = false ;
const int var = st - > variant ( ) ;
//for details see dvm_tag.h
if ( ( var > = DVM_INTERVAL_DIR & & var < = DVM_ENDINTERVAL_DIR ) | |
( var > = DVM_DEBUG_DIR & & var < = DVM_TRACEOFF_DIR ) | |
( var > = DVM_PARALLEL_ON_DIR & & var < = DVM_SHADOW_DIR ) | |
( var > = DVM_NEW_VALUE_DIR & & var < = DVM_POINTER_DIR ) | |
( var > = DVM_TASK_REGION_DIR & & var < FORALL_STAT ) | |
( var > FORALL_STAT & & var < = DVM_TEMPLATE_DELETE_DIR ) | |
( var > = ACC_REGION_DIR & & var < = ACC_ASYNC_OP ) | |
( var = = DVM_DISTRIBUTE_DIR ) | |
( var > = HPF_TEMPLATE_STAT & & var < = DVM_REDISTRIBUTE_DIR ) | |
( var > = BLOCK_OP & & var < = STAGE_OP ) | |
2023-11-05 13:08:57 +03:00
( var > = INDIRECT_OP & & var < = SHADOW_NAMES_OP ) | |
( var > = ACC_REGION_DIR & & var < = ACC_ASYNC_OP ) )
2023-09-14 19:43:13 +03:00
ret = true ;
return ret ;
}
bool isSPF_stat ( SgStatement * st )
{
if ( st = = NULL )
return false ;
bool ret = false ;
const int var = st - > variant ( ) ;
//for details see dvm_tag.h
2024-04-09 16:41:48 +03:00
if ( var > = SPF_ANALYSIS_DIR & & var < = SPF_PROCESS_PRIVATE_OP )
2023-09-14 19:43:13 +03:00
ret = true ;
return ret ;
}
static map < SgExpression * , string > : : const_iterator getStringExpr ( SgExpression * ex , map < SgExpression * , string > & collection )
{
auto it = collection . find ( ex ) ;
if ( it = = collection . end ( ) )
it = collection . insert ( it , make_pair ( ex , ex - > unparse ( ) ) ) ;
return it ;
}
bool isEqExpressions ( SgExpression * left , SgExpression * right , map < SgExpression * , string > & collection )
{
if ( left = = right )
return true ;
else if ( left = = NULL | | right = = NULL )
return false ;
else
return getStringExpr ( left , collection ) - > second = = getStringExpr ( right , collection ) - > second ;
}
static string getCommonName ( SgExpression * common )
{
if ( common - > symbol ( ) )
return string ( common - > symbol ( ) - > identifier ( ) ) ;
else
return string ( " spf_unnamed " ) ;
}
void getCommonBlocksRef ( map < string , vector < SgExpression * > > & commonBlocks , SgStatement * start , SgStatement * end , const string * nameToSkip )
{
while ( start ! = end )
{
if ( start - > variant ( ) = = CONTAINS_STMT )
break ;
if ( start - > variant ( ) = = COMM_STAT )
{
// fill all common blocks
for ( SgExpression * exp = start - > expr ( 0 ) ; exp ; exp = exp - > rhs ( ) )
{
const string commonName = getCommonName ( exp ) ;
if ( nameToSkip & & * nameToSkip = = commonName )
continue ;
auto it = commonBlocks . find ( commonName ) ;
if ( it = = commonBlocks . end ( ) )
it = commonBlocks . insert ( it , make_pair ( commonName , vector < SgExpression * > ( ) ) ) ;
it - > second . push_back ( exp ) ;
}
}
start = start - > lexNext ( ) ;
}
}
2025-01-13 18:16:11 +03:00
int checkCommonInMainUnit ( SgProject & project , map < string , vector < Messages > > & SPF_messages ,
const set < DIST : : Array * > & arrays , bool forDistrbuted )
{
int internalExit = 0 ;
SgStatement * mainUnit = findMainUnit ( & project , SPF_messages ) ;
checkNull ( mainUnit , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
map < string , vector < SgExpression * > > commonBlocks ;
getCommonBlocksRef ( commonBlocks , mainUnit , mainUnit - > lastNodeOfStmt ( ) ) ;
// check array declaration
for ( auto & array : arrays )
{
if ( array - > IsLoopArray ( ) | | array - > IsTemplate ( ) )
continue ;
if ( array - > GetLocation ( ) . first = = DIST : : l_COMMON )
{
auto nameOfCommon = array - > GetLocation ( ) . second ;
if ( commonBlocks . find ( nameOfCommon ) = = commonBlocks . end ( ) )
{
auto declPlaces = array - > GetDeclInfo ( ) ;
for ( auto & place : declPlaces )
{
vector < Messages > & currMessages = getObjectForFileFromMap ( place . first . c_str ( ) , SPF_messages ) ;
if ( forDistrbuted )
{
__spf_print ( 1 , " ERROR: distributed array '%s' in common block '%s' must have declaration in main unit \n " , array - > GetShortName ( ) . c_str ( ) , nameOfCommon . c_str ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " distributed array '%s' in common block '%s' must have declaration in main unit " ,
to_wstring ( array - > GetShortName ( ) ) . c_str ( ) , to_wstring ( nameOfCommon ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R75 ,
to_wstring ( array - > GetShortName ( ) ) . c_str ( ) , to_wstring ( nameOfCommon ) . c_str ( ) ) ;
currMessages . push_back ( Messages ( ERROR , place . second , messageR , messageE , 1042 ) ) ;
}
else
{
__spf_print ( 1 , " ERROR: array '%s' in common block '%s' must have declaration in main unit for DECLARE insertion \n " , array - > GetShortName ( ) . c_str ( ) , nameOfCommon . c_str ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " array '%s' in common block '%s' must have declaration in main unit for DECLARE insertion " ,
to_wstring ( array - > GetShortName ( ) ) . c_str ( ) , to_wstring ( nameOfCommon ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R205 ,
to_wstring ( array - > GetShortName ( ) ) . c_str ( ) , to_wstring ( nameOfCommon ) . c_str ( ) ) ;
currMessages . push_back ( Messages ( ERROR , place . second , messageR , messageE , 1062 ) ) ;
}
}
internalExit = 1 ;
}
}
}
return internalExit ;
}
2023-09-14 19:43:13 +03:00
static SgExpression * isInCommon ( const vector < SgExpression * > & commonBlocks , const char * arrayName , int & commonPos )
{
commonPos = 0 ;
for ( auto & common : commonBlocks )
{
for ( SgExpression * currCommon = common - > lhs ( ) ; currCommon ; currCommon = currCommon - > rhs ( ) )
{
if ( ! strcmp ( currCommon - > lhs ( ) - > symbol ( ) - > identifier ( ) , arrayName ) )
return common ;
commonPos + + ;
}
}
return NULL ;
}
static map < tuple < string , string , int > , tuple < int , string , string > > tableOfUniqNames ;
tuple < int , string , string > getUniqName ( const map < string , vector < SgExpression * > > & commonBlocks , SgStatement * decl , SgSymbol * symb )
{
bool inCommon = false ;
bool needtoCheck = true ;
int commonPos = 0 ;
SgExpression * foundCommon = NULL ;
SgStatement * declCP = decl - > controlParent ( ) ;
// find symbol in parameter list of functions
if ( declCP - > variant ( ) = = PROC_HEDR | | declCP - > variant ( ) = = FUNC_HEDR )
{
if ( declCP - > variant ( ) = = PROC_HEDR )
{
const int num = ( ( SgProcHedrStmt * ) declCP ) - > numberOfParameters ( ) ;
for ( int i = 0 ; i < num & & needtoCheck ; + + i )
if ( ! strcmp ( ( ( SgProcHedrStmt * ) declCP ) - > parameter ( i ) - > identifier ( ) , symb - > identifier ( ) ) )
needtoCheck = false ;
}
else
{
const int num = ( ( SgFuncHedrStmt * ) declCP ) - > numberOfParameters ( ) ;
for ( int i = 0 ; i < num & & needtoCheck ; + + i )
if ( ! strcmp ( ( ( SgFuncHedrStmt * ) declCP ) - > parameter ( i ) - > identifier ( ) , symb - > identifier ( ) ) )
needtoCheck = false ;
}
auto declCpCp = declCP - > controlParent ( ) ;
if ( declCpCp & & declCpCp - > variant ( ) = = INTERFACE_STMT & & needtoCheck )
needtoCheck = false ;
}
else if ( declCP - > variant ( ) = = INTERFACE_STMT )
needtoCheck = false ;
if ( needtoCheck )
{
for ( auto & common : commonBlocks )
{
foundCommon = isInCommon ( common . second , symb - > identifier ( ) , commonPos ) ;
if ( foundCommon )
{
inCommon = true ;
break ;
}
}
}
tuple < int , string , string > retVal ;
if ( inCommon )
retVal = make_tuple ( commonPos , string ( " common_ " ) + getCommonName ( foundCommon ) , string ( symb - > identifier ( ) ) ) ;
else
retVal = make_tuple ( decl - > lineNumber ( ) , string ( decl - > fileName ( ) ) , string ( symb - > identifier ( ) ) ) ;
auto key = make_tuple ( symb - > identifier ( ) , decl - > fileName ( ) , decl - > lineNumber ( ) ) ;
auto it = tableOfUniqNames . find ( key ) ;
if ( it = = tableOfUniqNames . end ( ) )
tableOfUniqNames . insert ( it , make_pair ( key , retVal ) ) ;
else
{
if ( it - > first ! = key )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
return retVal ;
}
tuple < int , string , string > getFromUniqTable ( SgSymbol * symb )
{
auto place = declaratedInStmt ( symb ) ;
auto localIt = tableOfUniqNames . find ( std : : make_tuple ( symb - > identifier ( ) , place - > fileName ( ) , place - > lineNumber ( ) ) ) ;
if ( localIt = = tableOfUniqNames . end ( ) )
{
auto place = declaratedInStmt ( symb ) ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
return localIt - > second ;
}
SgStatement * findMainUnit ( SgProject * proj , map < string , vector < Messages > > & SPF_messages )
{
SgStatement * mainUnit = NULL ;
vector < SgStatement * > mainUnits ;
for ( int i = proj - > numberOfFiles ( ) - 1 ; i > = 0 ; - - i )
{
SgFile * file = & ( proj - > file ( i ) ) ;
const string file_name = file - > filename ( ) ;
for ( int k = 0 ; k < file - > numberOfFunctions ( ) ; + + k )
{
SgStatement * func = file - > functions ( k ) ;
if ( func - > variant ( ) = = PROG_HEDR & & file_name = = func - > fileName ( ) )
{
mainUnit = func ;
mainUnits . push_back ( func ) ;
}
}
}
if ( mainUnits . size ( ) ! = 1 )
{
for ( auto & elem : mainUnits )
{
vector < Messages > & currMessages = getObjectForFileFromMap ( elem - > fileName ( ) , SPF_messages ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " more than one main unit was found " ) ;
__spf_printToLongBuf ( messageR , R146 ) ;
currMessages . push_back ( Messages ( ERROR , elem - > lineNumber ( ) , messageR , messageE , 1050 ) ) ;
}
if ( mainUnits . size ( ) = = 0 )
{
for ( int i = proj - > numberOfFiles ( ) - 1 ; i > = 0 ; - - i )
{
SgFile * file = & ( proj - > file ( i ) ) ;
const char * file_name = file - > filename ( ) ;
vector < Messages > & currMessages = getObjectForFileFromMap ( file_name , SPF_messages ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " main unit not found " ) ;
__spf_printToLongBuf ( messageR , R147 ) ;
currMessages . push_back ( Messages ( ERROR , file - > firstStatement ( ) - > lexNext ( ) - > lineNumber ( ) , messageR , messageE , 1050 ) ) ;
}
}
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
if ( ! mainUnit - > switchToFile ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
return mainUnit ;
}
template < typename IN_TYPE , typename OUT_TYPE >
const vector < OUT_TYPE > getAttributes ( IN_TYPE st , const set < int > dataType )
{
vector < OUT_TYPE > outData ;
for ( int i = 0 ; i < st - > numberOfAttributes ( ) ; + + i )
{
SgAttribute * attr = st - > getAttribute ( i ) ;
const int type = st - > attributeType ( i ) ;
if ( dataType . find ( type ) ! = dataType . end ( ) )
if ( attr - > getAttributeData ( ) )
outData . push_back ( ( OUT_TYPE ) ( attr - > getAttributeData ( ) ) ) ;
}
return outData ;
}
template < typename IN_TYPE >
void deleteAttributes ( IN_TYPE st , const set < int > dataType )
{
bool changed = true ;
while ( changed )
{
changed = false ;
int idxDel = - 1 ;
for ( int i = 0 ; i < st - > numberOfAttributes ( ) ; + + i )
{
SgAttribute * attr = st - > getAttribute ( i ) ;
const int type = st - > attributeType ( i ) ;
if ( dataType . find ( type ) ! = dataType . end ( ) )
{
if ( attr - > getAttributeData ( ) )
{
idxDel = i ;
break ;
}
}
}
if ( idxDel ! = - 1 )
{
st - > deleteAttribute ( idxDel ) ;
changed = true ;
}
}
}
template const vector < SgSymbol * > getAttributes ( SgSymbol * st , const set < int > dataType ) ;
template const vector < SgSymbol * > getAttributes ( SgStatement * st , const set < int > dataType ) ;
template const vector < SgSymbol * > getAttributes ( SgExpression * st , const set < int > dataType ) ;
template const vector < char * > getAttributes ( SgSymbol * st , const set < int > dataType ) ;
template const vector < int * > getAttributes ( SgSymbol * st , const set < int > dataType ) ;
template const vector < SgStatement * > getAttributes ( SgStatement * st , const set < int > dataType ) ;
template const vector < SgExpression * > getAttributes ( SgExpression * st , const set < int > dataType ) ;
template const vector < SgStatement * > getAttributes ( SgExpression * st , const set < int > dataType ) ;
template const vector < DIST : : Array * > getAttributes ( SgExpression * st , const set < int > dataType ) ;
template const vector < int * > getAttributes ( SgExpression * st , const set < int > dataType ) ;
template const vector < FuncInfo * > getAttributes ( SgStatement * st , const set < int > dataType ) ;
template void deleteAttributes ( SgStatement * st , const set < int > dataType ) ;
template void deleteAttributes ( SgExpression * st , const set < int > dataType ) ;
static int isParameterOneOfThese ( const string & name , const vector < string > & names )
{
int parameterOfFunctionItself = - 1 ;
for ( int i = 0 ; i < names . size ( ) ; + + i )
if ( name = = names [ i ] )
{
parameterOfFunctionItself = i ;
break ;
}
return parameterOfFunctionItself ;
}
# define DEF_T 0
# define USE_T 1
# define DEF_USE_T 2
static void processPartOfAssign ( int type , SgExpression * exp , vector < DefUseList > & currentLists , SgFile * file , SgStatement * inStat ,
vector < string > & parameterNames , pair < SgSymbol * , string > underCall , int funcPos ) ;
static void addSymbolsToDefUse ( const int type , SgExpression * ex , vector < DefUseList > & currentList ,
pair < SgSymbol * , string > underCall , int funcPos ,
SgFile * file , SgStatement * inStat , vector < string > & parameterNames )
{
if ( ex )
{
bool next = true ;
if ( ex - > variant ( ) = = VAR_REF | | ex - > variant ( ) = = ARRAY_REF )
{
if ( ex - > symbol ( ) )
{
string name = string ( ex - > symbol ( ) - > identifier ( ) ) ;
currentList . push_back ( DefUseList ( type , inStat , ex , file , underCall , make_pair ( ex - > symbol ( ) , name ) , funcPos , isParameterOneOfThese ( name , parameterNames ) ) ) ;
}
}
else if ( ex - > variant ( ) = = FUNC_CALL )
{
underCall = make_pair ( ex - > symbol ( ) , string ( ex - > symbol ( ) - > identifier ( ) ) ) ;
funcPos = 0 ;
bool isIntrinsic = isIntrinsicFunctionName ( ex - > symbol ( ) - > identifier ( ) ) ;
for ( SgExpression * list = ex - > lhs ( ) ; list ; list = list - > rhs ( ) , funcPos + + )
{
if ( ! isIntrinsic )
processPartOfAssign ( DEF_USE_T , list - > lhs ( ) , currentList , file , inStat , parameterNames , underCall , funcPos ) ;
else
addSymbolsToDefUse ( type , list - > lhs ( ) , currentList , underCall , funcPos , file , inStat , parameterNames ) ;
}
next = false ;
}
if ( next )
{
addSymbolsToDefUse ( type , ex - > lhs ( ) , currentList , underCall , funcPos , file , inStat , parameterNames ) ;
addSymbolsToDefUse ( type , ex - > rhs ( ) , currentList , underCall , funcPos , file , inStat , parameterNames ) ;
}
}
}
static void processPartOfAssign ( int type , SgExpression * exp , vector < DefUseList > & currentList , SgFile * file , SgStatement * inStat ,
vector < string > & parameterNames , pair < SgSymbol * , string > underCall , int funcPos )
{
if ( exp - > symbol ( ) & & exp - > variant ( ) = = VAR_REF ) // simple assign
{
SgSymbol * tmp = exp - > symbol ( ) ;
string name = string ( tmp - > identifier ( ) ) ;
if ( type = = DEF_USE_T )
{
currentList . push_back ( DefUseList ( DEF_T , inStat , exp , file , underCall , make_pair ( tmp , name ) , funcPos , isParameterOneOfThese ( name , parameterNames ) ) ) ;
currentList . push_back ( DefUseList ( USE_T , inStat , exp , file , underCall , make_pair ( tmp , name ) , funcPos , isParameterOneOfThese ( name , parameterNames ) ) ) ;
}
else
currentList . push_back ( DefUseList ( DEF_T , inStat , exp , file , underCall , make_pair ( tmp , name ) , funcPos , isParameterOneOfThese ( name , parameterNames ) ) ) ;
}
//TODO
else // array ref and etc.
{
if ( exp - > variant ( ) = = ARRAY_OP )
{
SgSymbol * tmp = exp - > lhs ( ) - > symbol ( ) ;
string name = string ( tmp - > identifier ( ) ) ;
if ( type = = DEF_USE_T )
{
currentList . push_back ( DefUseList ( DEF_T , inStat , exp , file , underCall , make_pair ( tmp , name ) , funcPos , isParameterOneOfThese ( name , parameterNames ) ) ) ;
currentList . push_back ( DefUseList ( USE_T , inStat , exp , file , underCall , make_pair ( tmp , name ) , funcPos , isParameterOneOfThese ( name , parameterNames ) ) ) ;
}
else
currentList . push_back ( DefUseList ( type , inStat , exp , file , underCall , make_pair ( tmp , name ) , funcPos , isParameterOneOfThese ( name , parameterNames ) ) ) ;
addSymbolsToDefUse ( 1 , exp - > lhs ( ) - > lhs ( ) , currentList , underCall , funcPos , file , inStat , parameterNames ) ;
addSymbolsToDefUse ( 1 , exp - > lhs ( ) - > rhs ( ) , currentList , underCall , funcPos , file , inStat , parameterNames ) ;
}
else if ( exp - > variant ( ) = = ARRAY_REF )
{
SgSymbol * tmp = exp - > symbol ( ) ;
string name = string ( tmp - > identifier ( ) ) ;
if ( type = = DEF_USE_T )
{
currentList . push_back ( DefUseList ( DEF_T , inStat , exp , file , underCall , make_pair ( tmp , name ) , funcPos , isParameterOneOfThese ( name , parameterNames ) ) ) ;
currentList . push_back ( DefUseList ( USE_T , inStat , exp , file , underCall , make_pair ( tmp , name ) , funcPos , isParameterOneOfThese ( name , parameterNames ) ) ) ;
}
else
currentList . push_back ( DefUseList ( type , inStat , exp , file , underCall , make_pair ( tmp , name ) , funcPos , isParameterOneOfThese ( name , parameterNames ) ) ) ;
addSymbolsToDefUse ( 1 , exp - > lhs ( ) , currentList , underCall , funcPos , file , inStat , parameterNames ) ;
addSymbolsToDefUse ( 1 , exp - > rhs ( ) , currentList , underCall , funcPos , file , inStat , parameterNames ) ;
}
else
{
addSymbolsToDefUse ( 1 , exp - > lhs ( ) , currentList , underCall , funcPos , file , inStat , parameterNames ) ;
addSymbolsToDefUse ( 1 , exp - > rhs ( ) , currentList , underCall , funcPos , file , inStat , parameterNames ) ;
}
}
}
static void inline addToLists ( map < string , vector < DefUseList > > & currentLists , const vector < DefUseList > & tmpList )
{
for ( auto & list : currentLists )
for ( auto & elem : tmpList )
list . second . push_back ( elem ) ;
}
void constructDefUseStep1 ( SgFile * file , map < string , vector < DefUseList > > & defUseByFunctions , map < string , vector < FuncInfo * > > & allFuncInfo , vector < Messages > & messages )
{
map < string , vector < FuncInfo * > > curFileFuncInfo ;
vector < LoopGraph * > tmpL ;
2024-05-11 15:38:41 +03:00
map < FuncInfo * , vector < SAPFOR : : BasicBlock * > > tmpIR ;
functionAnalyzer ( file , curFileFuncInfo , tmpL , messages , tmpIR ) ;
2023-09-14 19:43:13 +03:00
//functions not found
if ( curFileFuncInfo . size ( ) = = 0 )
return ;
auto whereToCopy = allFuncInfo . insert ( make_pair ( file - > filename ( ) , vector < FuncInfo * > ( ) ) ) ;
for ( auto & it : curFileFuncInfo . begin ( ) - > second )
whereToCopy . first - > second . push_back ( it ) ;
map < string , FuncInfo * > funcToFuncInfo = map < string , FuncInfo * > ( ) ;
for ( int i = 0 ; i < curFileFuncInfo . begin ( ) - > second . size ( ) ; + + i )
funcToFuncInfo . insert ( make_pair ( curFileFuncInfo . begin ( ) - > second [ i ] - > funcName , curFileFuncInfo . begin ( ) - > second [ i ] ) ) ;
for ( int f = 0 ; f < file - > numberOfFunctions ( ) ; + + f )
{
//function header and entry points
map < string , vector < DefUseList > > currentLists ;
vector < DefUseList > tmpList ;
vector < string > parameterNames = vector < string > ( ) ;
SgStatement * start = file - > functions ( f ) ;
SgStatement * end = start - > lastNodeOfStmt ( ) ;
int pos ;
auto founded = funcToFuncInfo . find ( ( ( SgProgHedrStmt * ) start ) - > nameWithContains ( ) ) ;
start - > addAttribute ( PROC_CALL , ( void * ) founded - > second , sizeof ( FuncInfo ) ) ;
SgProgHedrStmt * header = isSgProgHedrStmt ( start ) ;
if ( header & & start - > variant ( ) ! = PROG_HEDR )
for ( int i = 0 ; i < header - > numberOfParameters ( ) ; + + i )
parameterNames . push_back ( header - > parameter ( i ) - > identifier ( ) ) ;
currentLists [ string ( start - > symbol ( ) - > identifier ( ) ) ] = vector < DefUseList > ( ) ;
for ( SgStatement * st = start - > lexNext ( ) ; st ! = end ; st = st - > lexNext ( ) )
{
if ( isSgExecutableStatement ( st ) )
{
if ( isDVM_stat ( st ) )
{
if ( st - > variant ( ) ! = ACC_GET_ACTUAL_DIR & & st - > variant ( ) ! = ACC_ACTUAL_DIR )
continue ;
}
tmpList . clear ( ) ;
switch ( st - > variant ( ) )
{
case ASSIGN_STAT :
processPartOfAssign ( DEF_T , st - > expr ( 0 ) , tmpList , file , st , parameterNames , make_pair ( ( SgSymbol * ) NULL , string ( " " ) ) , - 1 ) ;
addSymbolsToDefUse ( USE_T , st - > expr ( 1 ) , tmpList , make_pair ( ( SgSymbol * ) NULL , string ( " " ) ) , - 1 , file , st , parameterNames ) ;
addToLists ( currentLists , tmpList ) ;
break ;
case FOR_NODE :
if ( st - > symbol ( ) )
for ( auto & list : currentLists )
{
string name = string ( st - > symbol ( ) - > identifier ( ) ) ;
auto vr = new SgVarRefExp ( * ( st - > symbol ( ) ) ) ;
list . second . push_back ( DefUseList ( 1 , st , vr , file , make_pair ( ( SgSymbol * ) NULL , string ( " " ) ) , make_pair ( st - > symbol ( ) , name ) , - 1 , isParameterOneOfThese ( name , parameterNames ) ) ) ;
list . second . push_back ( DefUseList ( 0 , st , vr , file , make_pair ( ( SgSymbol * ) NULL , string ( " " ) ) , make_pair ( st - > symbol ( ) , name ) , - 1 , isParameterOneOfThese ( name , parameterNames ) ) ) ;
}
for ( int i = 0 ; i < 3 ; + + i )
addSymbolsToDefUse ( USE_T , st - > expr ( i ) , tmpList , make_pair ( ( SgSymbol * ) NULL , string ( " " ) ) , - 1 , file , st , parameterNames ) ;
addToLists ( currentLists , tmpList ) ;
break ;
case READ_STAT :
{
SgInputOutputStmt * io = isSgInputOutputStmt ( st ) ;
auto list = io - > itemList ( ) ;
int pos = 0 ;
while ( list )
{
if ( list - > lhs ( ) )
processPartOfAssign ( DEF_T , list - > lhs ( ) , tmpList , file , st , parameterNames , make_pair ( io - > symbol ( ) , string ( " READ " ) ) , pos ) ;
pos + + ;
list = list - > rhs ( ) ;
}
}
addToLists ( currentLists , tmpList ) ;
break ;
case PROC_STAT :
pos = 0 ;
for ( SgExpression * ex = st - > expr ( 0 ) ; ex ; ex = ex - > rhs ( ) , pos + + )
processPartOfAssign ( DEF_USE_T , ex - > lhs ( ) , tmpList , file , st , parameterNames , make_pair ( st - > symbol ( ) , string ( st - > symbol ( ) - > identifier ( ) ) ) , pos ) ;
addToLists ( currentLists , tmpList ) ;
break ;
case ENTRY_STAT :
currentLists [ string ( st - > symbol ( ) - > identifier ( ) ) ] = vector < DefUseList > ( ) ;
break ;
case LOGIF_NODE :
case CONT_STAT :
case IF_NODE :
case WHILE_NODE :
case DO_WHILE_NODE :
case GOTO_NODE :
case STOP_STAT :
case RETURN_STAT :
case RETURN_NODE :
case ELSEIF_NODE :
case ARITHIF_NODE :
case WHERE_NODE :
case WHERE_BLOCK_STMT :
case SWITCH_NODE :
case CASE_NODE :
case BREAK_NODE :
case EXIT_STMT :
case ASSGOTO_NODE :
case COMGOTO_NODE :
case WRITE_STAT :
case PRINT_STAT :
default :
for ( int i = 0 ; i < 3 ; + + i )
addSymbolsToDefUse ( USE_T , st - > expr ( i ) , tmpList , make_pair ( ( SgSymbol * ) NULL , string ( " " ) ) , - 1 , file , st , parameterNames ) ;
addToLists ( currentLists , tmpList ) ;
break ;
}
}
}
for ( auto & list : currentLists )
{
auto it = defUseByFunctions . find ( list . first ) ;
if ( it = = defUseByFunctions . end ( ) )
it = defUseByFunctions . insert ( it , make_pair ( list . first , vector < DefUseList > ( ) ) ) ;
}
for ( auto & list : currentLists )
{
auto it = defUseByFunctions . find ( list . first ) ;
for ( auto & elem : list . second )
it - > second . push_back ( elem ) ;
}
}
}
# undef DEF_T
# undef USE_T
# undef DEF_USE_T
extern map < string , vector < DefUseList > > defUseByFunctions ;
set < string > getAllDefVars ( const string & funcName )
{
set < string > retVal ;
for ( auto & elem : defUseByFunctions [ funcName ] )
if ( elem . isDef ( ) )
retVal . insert ( elem . getVar ( ) ) ;
return retVal ;
}
set < string > getAllUseVars ( const string & funcName )
{
set < string > retVal ;
for ( auto & elem : defUseByFunctions [ funcName ] )
if ( elem . isUse ( ) )
retVal . insert ( elem . getVar ( ) ) ;
return retVal ;
}
const vector < DefUseList > & getAllDefUseVarsList ( const string & funcName )
{
return defUseByFunctions [ funcName ] ;
}
const vector < DefUseList > getAllDefUseVarsList ( const string & funcName , const string varName )
{
vector < DefUseList > retVal ;
for ( auto & elem : defUseByFunctions [ funcName ] )
if ( elem . getVar ( ) = = varName )
retVal . push_back ( elem ) ;
return retVal ;
}
map < SgStatement * , vector < DefUseList > > createDefUseMapByPlace ( )
{
map < SgStatement * , vector < DefUseList > > retVal ;
for ( auto & byFunc : defUseByFunctions )
for ( auto & elem : byFunc . second )
retVal [ elem . getPlace ( ) ] . push_back ( elem ) ;
return retVal ;
}
int printDefUseSets ( const char * fileName , const map < string , vector < DefUseList > > & defUseLists )
{
FILE * file = fopen ( fileName , " w " ) ;
if ( file = = NULL )
{
__spf_print ( 1 , " can not open file %s \n " , fileName ) ;
return - 1 ;
}
for ( auto & elem : defUseLists )
{
fprintf ( file , " *** Function %s \n " , elem . first . c_str ( ) ) ;
for ( auto & inList : elem . second )
inList . print ( file , true ) ;
fprintf ( file , " \n " ) ;
}
fclose ( file ) ;
return 0 ;
}
static bool isDefUseVar ( const int paramPosition , const string & funcName , map < string , vector < DefUseList > > & defUseByFunctions , bool defined )
{
auto founded = defUseByFunctions . find ( funcName ) ;
if ( founded = = defUseByFunctions . end ( ) )
return true ; //No information. Argument can be defined or used.
vector < DefUseList > & curDefUse = founded - > second ;
bool isDefUse = false ;
for ( int i = 0 ; i < curDefUse . size ( ) ; + + i )
{
if ( paramPosition = = curDefUse [ i ] . getParameterPositionInFunction ( ) )
{
if ( defined & & curDefUse [ i ] . isDef ( ) )
{
isDefUse = true ;
break ;
}
else if ( ! defined & & curDefUse [ i ] . isUse ( ) )
{
isDefUse = true ;
break ;
}
else
{
const string calledFuncName = curDefUse [ i ] . getParamOfFunction ( ) ;
if ( ! calledFuncName . empty ( ) )
{
isDefUse = isDefUseVar ( curDefUse [ i ] . getParameterPosition ( ) , calledFuncName , defUseByFunctions , defined ) ;
if ( isDefUse )
break ;
}
}
}
}
return isDefUse ;
}
static SgExpression * makeList ( const vector < SgExpression * > & list )
{
if ( list . size ( ) = = 0 )
return NULL ;
SgExpression * out = new SgExpression ( EXPR_LIST ) ;
SgExpression * ret = out ;
for ( int i = 0 ; i < list . size ( ) ; + + i )
{
out - > setLhs ( list [ i ] ) ;
if ( i ! = list . size ( ) - 1 )
{
out - > setRhs ( new SgExpression ( EXPR_LIST ) ) ;
out = out - > rhs ( ) ;
}
else
out - > setRhs ( NULL ) ;
}
return ret ;
}
static map < SgStatement * , pair < SgExpression * , SgExpression * > > buildLists ( const vector < DefUseList > & list )
{
map < SgStatement * , pair < vector < SgExpression * > , vector < SgExpression * > > > out ;
for ( auto & elem : list )
{
if ( elem . isDef ( ) )
out [ elem . getPlace ( ) ] . first . push_back ( elem . getExpr ( ) ) ;
if ( elem . isUse ( ) )
out [ elem . getPlace ( ) ] . second . push_back ( elem . getExpr ( ) ) ;
}
map < SgStatement * , pair < SgExpression * , SgExpression * > > ret ;
for ( auto & elem : out )
{
ret [ elem . first ] . first = makeList ( elem . second . first ) ;
ret [ elem . first ] . second = makeList ( elem . second . second ) ;
}
return ret ;
}
void constructDefUseStep2 ( SgFile * file , map < string , vector < DefUseList > > & defUseByFunctions )
{
for ( int f = 0 ; f < file - > numberOfFunctions ( ) ; + + f )
{
SgProgHedrStmt * header = isSgProgHedrStmt ( file - > functions ( f ) ) ;
if ( header = = NULL | | header - > variant ( ) = = PROG_HEDR )
continue ;
for ( int i = 0 ; i < header - > numberOfParameters ( ) ; + + i )
{
int currAttr = header - > parameter ( i ) - > attributes ( ) ;
if ( ( currAttr & OUT_BIT ) = = 0 & & ( currAttr & INOUT_BIT ) = = 0 & & ( currAttr & IN_BIT ) = = 0 )
{
bool isDef = isDefUseVar ( i , header - > symbol ( ) - > identifier ( ) , defUseByFunctions , true ) ;
bool isUse = isDefUseVar ( i , header - > symbol ( ) - > identifier ( ) , defUseByFunctions , false ) ;
if ( isDef & & isUse )
header - > parameter ( i ) - > setAttribute ( INOUT_BIT ) ;
else if ( isDef )
header - > parameter ( i ) - > setAttribute ( OUT_BIT ) ;
else
header - > parameter ( i ) - > setAttribute ( IN_BIT ) ;
}
//TODO: test and replace from defUseVar() in defUse.cpp
/*auto funcList = defUseByFunctions[header->symbol()->identifier()];
auto toAdd = buildLists ( funcList ) ;
for ( auto & elem : toAdd )
{
elem . first - > addAttribute ( DEFINEDLIST_ATTRIBUTE , ( void * ) elem . second . first , 0 ) ;
elem . first - > addAttribute ( USEDLIST_ATTRIBUTE , ( void * ) elem . second . second , 0 ) ;
} */
}
}
}
int printCommonBlocks ( const char * fileName , const map < string , CommonBlock * > & commonBlocks )
{
FILE * file = fopen ( fileName , " w " ) ;
if ( file = = NULL )
{
__spf_print ( 1 , " can not open file %s \n " , fileName ) ;
return - 1 ;
}
for ( auto & commonBlock : commonBlocks )
{
fprintf ( file , " *** COMMON BLOCK '%s' \n " , commonBlock . first . c_str ( ) ) ;
commonBlock . second - > print ( file ) ;
fprintf ( file , " \n " ) ;
}
fclose ( file ) ;
return 0 ;
}
// CommonBlock::
Variable * CommonBlock : : hasVariable ( const string & name , const varType type , const int position )
{
for ( auto & variable : variables )
if ( variable - > getName ( ) = = name & & variable - > getType ( ) = = type & & variable - > getPosition ( ) = = position )
return variable ;
return NULL ;
}
Variable * CommonBlock : : hasVariable ( SgSymbol * symbol , const varType type , const int position )
{
return hasVariable ( string ( symbol - > identifier ( ) ) , type , position ) ;
}
const vector < const Variable * > CommonBlock : : getVariables ( SgFile * file , SgStatement * function ) const
{
return getVariables ( string ( file - > filename ( ) ) , string ( function - > symbol ( ) - > identifier ( ) ) ) ;
}
const vector < const Variable * > CommonBlock : : getVariables ( const string & file , const string & function ) const
{
vector < const Variable * > retVariables ;
for ( auto & variable : variables )
if ( variable - > hasUse ( file , function ) )
retVariables . push_back ( variable ) ;
return retVariables ;
}
const vector < const Variable * > CommonBlock : : getVariables ( int position ) const
{
vector < const Variable * > retVariables ;
auto it = groupedVars . find ( position ) ;
if ( it ! = groupedVars . end ( ) )
for ( auto & variable : it - > second )
retVariables . push_back ( variable ) ;
return retVariables ;
}
static void findDeclType ( SgExpression * ex , varType & type , const string & toFind )
{
if ( ex )
{
if ( ex - > symbol ( ) & & ex - > symbol ( ) - > identifier ( ) = = toFind )
{
switch ( ex - > variant ( ) )
{
case VAR_REF :
if ( type ! = ARRAY )
type = SCALAR ;
break ;
case ARRAY_REF :
type = ARRAY ;
break ;
case INT_VAL :
case FLOAT_VAL :
case DOUBLE_VAL :
case BOOL_VAL :
case CHAR_VAL :
case STRING_VAL :
case CONST_REF :
type = CONST ;
break ;
case COMM_LIST :
break ;
default :
type = ANOTHER ;
break ;
}
}
findDeclType ( ex - > lhs ( ) , type , toFind ) ;
findDeclType ( ex - > rhs ( ) , type , toFind ) ;
}
}
void CommonBlock : : addVariables ( SgFile * file , SgStatement * function , const vector < pair < SgSymbol * , int > > & newVariables )
{
for ( auto & varPair : newVariables )
{
vector < SgStatement * > allDecls ;
declaratedInStmt ( varPair . first , & allDecls ) ;
varType type = ANOTHER ;
for ( auto & decl : allDecls )
for ( int i = 0 ; i < 3 ; + + i )
findDeclType ( decl - > expr ( i ) , type , varPair . first - > identifier ( ) ) ;
Variable * exist = hasVariable ( varPair . first , type , varPair . second ) ;
if ( exist )
exist - > addUse ( file , function , varPair . first ) ;
else
{
variables . push_back ( new Variable ( file , function , varPair . first , string ( varPair . first - > identifier ( ) ) , type , varPair . second ) ) ;
auto it = groupedVars . find ( varPair . second ) ;
if ( it = = groupedVars . end ( ) )
it = groupedVars . insert ( it , make_pair ( varPair . second , vector < Variable * > ( ) ) ) ;
it - > second . push_back ( variables . back ( ) ) ;
}
}
}
void CommonBlock : : print ( FILE * fileOut ) const
{
fprintf ( fileOut , " [POSITION], [VARIABLE NAME], [TYPE]: \n " ) ;
for ( auto & var : variables )
{
var - > print ( fileOut ) ;
fprintf ( fileOut , " USE in [FILE, FUNC / BLOCK_DATA]: " ) ;
for ( auto & use : var - > getAllUse ( ) )
fprintf ( fileOut , " [%s, %s] " , use . getFileName ( ) . c_str ( ) ,
use . isBlockDataUse ( ) ? ( " BD_ " + use . getFunctionName ( ) ) . c_str ( ) : ( " F_ " + use . getFunctionName ( ) ) . c_str ( ) ) ;
fprintf ( fileOut , " \n " ) ;
}
}
DIST : : Array * CommonBlock : : getFirstSynonym ( DIST : : Array * array ) const
{
if ( array - > GetLocation ( ) . first ! = DIST : : l_COMMON )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
for ( auto & var : variables )
{
if ( var - > getName ( ) = = array - > GetShortName ( ) )
{
int pos = var - > getPosition ( ) ;
auto it = groupedVars . find ( pos ) ;
if ( it = = groupedVars . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( it - > second . size ( ) = = 1 )
return array ;
else
{
const string currFile = current_file - > filename ( ) ;
auto s = it - > second [ 0 ] - > getSymbol ( ) ;
if ( SgFile : : switchToFile ( it - > second [ 0 ] - > getDeclarated ( ) - > fileName ( ) ) = = - 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
string arrayName = string ( s - > identifier ( ) ) ;
DIST : : Array * firstArray = getArrayFromDeclarated ( declaratedInStmt ( s ) , arrayName ) ;
checkNull ( firstArray , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( SgFile : : switchToFile ( currFile ) = = - 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
return firstArray ;
}
}
}
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
// END of CommonBlock::
void groupDeclarations ( SgFile * file )
{
for ( int i = 0 ; i < file - > numberOfFunctions ( ) ; + + i )
{
SgStatement * func = file - > functions ( i ) ;
SgStatement * lastNode = func - > lastNodeOfStmt ( ) ;
map < SgType * , pair < vector < SgStatement * > , vector < SgExpression * > > > refs ;
vector < SgStatement * > toDel ;
for ( auto st = func ; st ! = lastNode ; st = st - > lexNext ( ) )
{
if ( isSgExecutableStatement ( st ) )
break ;
if ( st - > variant ( ) = = VAR_DECL )
{
auto varDecl = isSgVarDeclStmt ( st ) ;
SgExpression * varList = varDecl - > varList ( ) ;
int count = 0 ;
for ( auto lst = varList ; lst ; lst = lst - > rhs ( ) )
count + + ;
vector < SgExpression * > notMoved ;
int countOfMoved = 0 ;
for ( auto lst = varList ; lst ; lst = lst - > rhs ( ) )
{
SgExpression * var = lst - > lhs ( ) ;
if ( var - > variant ( ) = = VAR_REF )
{
auto type = var - > symbol ( ) - > type ( ) ;
if ( type & & isSgArrayType ( type ) = = NULL & & type - > variant ( ) ! = T_STRING )
{
countOfMoved + + ;
refs [ type ] . second . push_back ( var ) ;
SgStatement * prev = st - > lexPrev ( ) ;
while ( prev & & prev - > variant ( ) = = SPF_ANALYSIS_DIR )
{
refs [ type ] . first . push_back ( prev - > extractStmt ( ) ) ;
prev = st - > lexPrev ( ) ;
}
}
else
notMoved . push_back ( var ) ;
}
else
notMoved . push_back ( var ) ;
}
if ( countOfMoved ! = count )
{
if ( countOfMoved ! = 0 )
{
SgExpression * varList = new SgExpression ( EXPR_LIST ) ;
SgExpression * pVar = varList ;
for ( int z = 0 ; z < notMoved . size ( ) ; z + + )
{
pVar - > setLhs ( notMoved [ z ] ) ;
if ( z ! = notMoved . size ( ) - 1 )
{
pVar - > setRhs ( new SgExpression ( EXPR_LIST ) ) ;
pVar = pVar - > rhs ( ) ;
}
}
st - > setExpression ( 0 , * varList ) ;
}
}
else
toDel . push_back ( st ) ;
}
}
for ( auto st = func ; st ! = lastNode ; st = st - > lexNext ( ) )
{
if ( isSgExecutableStatement ( st - > lexNext ( ) ) )
{
for ( auto & newDecl : refs )
{
SgVarDeclStmt * newDeclSt = newDecl . second . second [ 0 ] - > symbol ( ) - > makeVarDeclStmt ( ) ;
for ( int z = 1 ; z < newDecl . second . second . size ( ) ; + + z )
newDeclSt - > addVar ( * newDecl . second . second [ z ] ) ;
st - > insertStmtAfter ( * newDeclSt , * func ) ;
for ( auto & spf : newDecl . second . first )
st - > insertStmtAfter ( * spf , * func ) ;
}
break ;
}
}
//TODO: move comments
for ( auto & elem : toDel )
elem - > deleteStmt ( ) ;
}
}
bool ifSymbolExists ( SgFile * file , const string & symbName )
{
if ( SgFile : : switchToFile ( file - > filename ( ) ) ! = - 1 )
{
SgSymbol * symb = file - > firstSymbol ( ) ;
while ( symb )
{
if ( symb - > identifier ( ) = = symbName )
return true ;
symb = symb - > next ( ) ;
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
return false ;
}
int checkSymbNameAndCorrect ( const string & symbName , int complite )
{
set < string > existedSymbols ;
//if (existedSymbols.size() == 0)
{
SgFile * oldFile = current_file ;
for ( int i = 0 ; i < CurrentProject - > numberOfFiles ( ) ; + + i )
{
SgFile * file = & ( CurrentProject - > file ( i ) ) ;
SgSymbol * s = file - > firstSymbol ( ) ;
while ( s )
{
existedSymbols . insert ( s - > identifier ( ) ) ;
s = s - > next ( ) ;
}
}
if ( SgFile : : switchToFile ( oldFile - > filename ( ) ) = = - 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
string base = symbName ;
int retNum = complite ;
while ( existedSymbols . find ( base + std : : to_string ( retNum ) ) ! = existedSymbols . end ( ) )
retNum + + ;
//existedSymbols.insert(retName);
return retNum ;
}
string checkSymbNameAndCorrect ( const string & symbName , const string complite )
{
set < string > existedSymbols ;
//if (existedSymbols.size() == 0)
{
string oldFileName = current_file - > filename ( ) ;
for ( int i = 0 ; i < CurrentProject - > numberOfFiles ( ) ; + + i )
{
SgFile * file = & ( CurrentProject - > file ( i ) ) ;
SgSymbol * s = file - > firstSymbol ( ) ;
while ( s )
{
existedSymbols . insert ( s - > identifier ( ) ) ;
s = s - > next ( ) ;
}
}
if ( SgFile : : switchToFile ( oldFileName ) = = - 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
string retName = symbName ;
while ( existedSymbols . find ( retName ) ! = existedSymbols . end ( ) )
retName + = complite ;
//existedSymbols.insert(retName);
return retName ;
}
const CommonBlock * isArrayInCommon ( const map < string , CommonBlock * > & commonBlocks , const DIST : : Array * array )
{
for ( auto & commonBlockPair : commonBlocks )
for ( auto & variable : commonBlockPair . second - > getVariables ( ) )
if ( variable - > getName ( ) = = array - > GetShortName ( ) & & variable - > getType ( ) = = ARRAY & & array - > GetLocation ( ) . first = = DIST : : l_COMMON )
return commonBlockPair . second ;
return NULL ;
}
static void fillArraysFromDirsRec ( SgExpression * ex , vector < DIST : : Array * > & toAdd )
{
if ( ex )
{
if ( ex - > variant ( ) = = ARRAY_REF )
{
auto attributes = getAttributes < SgExpression * , DIST : : Array * > ( ex , { ARRAY_REF } ) ;
toAdd . insert ( toAdd . end ( ) , attributes . begin ( ) , attributes . end ( ) ) ;
}
if ( ex - > lhs ( ) )
fillArraysFromDirsRec ( ex - > lhs ( ) , toAdd ) ;
if ( ex - > rhs ( ) )
fillArraysFromDirsRec ( ex - > rhs ( ) , toAdd ) ;
}
}
vector < DIST : : Array * > fillArraysFromDir ( Statement * st )
{
vector < DIST : : Array * > retVal ;
for ( int z = 0 ; z < 3 ; + + z )
fillArraysFromDirsRec ( st - > GetOriginal ( ) - > lexPrev ( ) - > expr ( z ) , retVal ) ;
return retVal ;
}
template < typename objT >
objT & getObjectForFileFromMap ( const char * fileName , map < string , objT > & mapObject )
{
auto it = mapObject . find ( fileName ) ;
if ( it = = mapObject . end ( ) )
it = mapObject . insert ( it , std : : make_pair ( fileName , objT ( ) ) ) ;
return it - > second ;
}
template vector < SpfInterval * > & getObjectForFileFromMap ( const char * fileName , map < string , vector < SpfInterval * > > & ) ;
template PredictorStats & getObjectForFileFromMap ( const char * fileName , map < string , PredictorStats > & ) ;
void printSymbolTable ( SgFile * file , string filter , const set < int > & vars )
{
for ( auto s = file - > firstSymbol ( ) ; s ; s = s - > next ( ) )
{
if ( vars . size ( ) ! = 0 )
if ( vars . find ( s - > variant ( ) ) = = vars . end ( ) )
continue ;
auto t = s - > type ( ) ;
bool need = true ;
if ( filter ! = " " )
if ( filter ! = s - > identifier ( ) )
need = false ;
if ( need )
{
int line = s - > scope ( ) ? s - > scope ( ) - > lineNumber ( ) : - 1 ;
2024-07-24 12:07:29 +03:00
printf ( " [%d] '%s' type %d ('%s'), location %d line, variant %d, addr %p \n " , s - > id ( ) , s - > identifier ( ) , t ? t - > variant ( ) : - 1 , t ? tag [ t - > variant ( ) ] : " " , line , s - > variant ( ) , s - > thesymb ) ;
2023-09-14 19:43:13 +03:00
}
}
}
static bool checkAdd ( const int var , const set < int > & additional )
{
if ( additional . size ( ) )
{
if ( additional . find ( var ) = = additional . end ( ) )
return true ;
else
return false ;
}
else
return true ;
}
SgStatement * getFuncStat ( SgStatement * st , const set < int > additional )
{
if ( ! st )
return NULL ;
SgStatement * iterator = st ;
while ( iterator & & ! isSgProgHedrStmt ( iterator ) & & checkAdd ( iterator - > variant ( ) , additional ) )
iterator = iterator - > controlParent ( ) ;
if ( ! iterator )
checkNull ( iterator , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
return iterator ;
}
SgStatement * duplicateProcedure ( SgStatement * toDup , const string * newName , bool withAttributes , bool withComment , bool withSameLines , bool dontInsert )
{
if ( toDup = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( isSgProgHedrStmt ( toDup ) = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SgStatement * global = current_file - > firstStatement ( ) ;
if ( global - > variant ( ) ! = GLOBAL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SgSymbol * orig = toDup - > symbol ( ) ;
SgSymbol * copied = & orig - > copySubprogram ( * global ) ;
//XXX: remove all extra functions
if ( global - > lexNext ( ) - > symbol ( ) - > identifier ( ) ! = string ( copied - > identifier ( ) ) )
{
vector < SgStatement * > toDel ;
SgStatement * st = global - > lexNext ( ) ;
if ( ! isSgProgHedrStmt ( st ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
while ( st )
{
if ( st - > symbol ( ) = = copied )
break ;
toDel . push_back ( st ) ;
st = st - > lastNodeOfStmt ( ) - > lexNext ( ) ;
}
if ( st = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( ! isSgProgHedrStmt ( st ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( st - > symbol ( ) - > identifier ( ) ! = string ( copied - > identifier ( ) ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
for ( auto & elem : toDel )
elem - > extractStmt ( ) ;
if ( global - > lexNext ( ) - > symbol ( ) - > identifier ( ) ! = string ( copied - > identifier ( ) ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
//move
SgStatement * toMove = NULL ;
if ( dontInsert )
toMove = global - > lexNext ( ) - > extractStmt ( ) ;
else
{
if ( toDup - > controlParent ( ) )
{
toMove = global - > lexNext ( ) - > extractStmt ( ) ;
toDup - > insertStmtBefore ( * toMove , * toDup - > controlParent ( ) ) ;
}
else
toMove = global - > lexNext ( ) ;
}
//change name
if ( newName )
copied - > changeName ( newName - > c_str ( ) ) ;
// set line numbers, pointer to attributes, comments and unparseIgnore status
for ( auto origStat = toDup , copyStat = toMove ;
origStat ! = toDup - > lastNodeOfStmt ( ) - > lexNext ( ) ;
origStat = origStat - > lexNext ( ) , copyStat = copyStat - > lexNext ( ) )
{
if ( copyStat - > variant ( ) ! = origStat - > variant ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( withSameLines )
{
copyStat - > setlineNumber ( origStat - > lineNumber ( ) ) ;
BIF_FILE_NAME ( copyStat - > thebif ) = BIF_FILE_NAME ( origStat - > thebif ) ;
}
if ( withAttributes )
if ( origStat - > numberOfAttributes ( ) > 0 )
copyStat - > addAttributeTree ( origStat - > getAttribute ( 0 ) ) ;
if ( withComment )
{
if ( origStat - > comments ( ) )
copyStat - > setComments ( origStat - > comments ( ) ) ;
}
copyStat - > setUnparseIgnore ( origStat - > getUnparseIgnore ( ) ) ;
}
return toMove ;
}
SgExpression * makeExprList ( const vector < SgExpression * > & items , bool withSort )
{
SgExpression * list = NULL ;
if ( items . size ( ) = = 0 )
return list ;
list = new SgExpression ( EXPR_LIST ) ;
vector < SgExpression * > newItems ;
if ( withSort )
{
multimap < string , SgExpression * > sorted ;
int tmpVal = 0 ;
for ( auto & elem : items )
{
2023-11-15 11:13:26 +03:00
if ( elem - > variant ( ) = = VAR_REF | | elem - > variant ( ) = = ARRAY_REF | | elem - > variant ( ) = = CONST_REF )
2023-09-14 19:43:13 +03:00
sorted . insert ( make_pair ( elem - > unparse ( ) , elem ) ) ;
else if ( elem - > lhs ( ) & & elem - > lhs ( ) - > variant ( ) = = VAR_REF | | elem - > lhs ( ) - > variant ( ) = = ARRAY_REF )
sorted . insert ( make_pair ( elem - > lhs ( ) - > unparse ( ) , elem ) ) ;
else
sorted . insert ( make_pair ( std : : to_string ( tmpVal + + ) , elem ) ) ;
}
for ( auto & elem : sorted )
newItems . push_back ( elem . second ) ;
std : : reverse ( newItems . begin ( ) , newItems . end ( ) ) ;
}
else
newItems = items ;
for ( int z = 0 ; z < newItems . size ( ) ; + + z )
{
if ( z = = 0 )
list - > setLhs ( newItems [ z ] ) ;
else
{
SgExpression * tmp = new SgExpression ( EXPR_LIST ) ;
tmp - > setLhs ( newItems [ z ] ) ;
tmp - > setRhs ( list ) ;
list = tmp ;
}
}
return list ;
}
static bool sortByName ( const pair < SgSymbol * , SgExpression * > & l , const pair < SgSymbol * , SgExpression * > & r )
{
return string ( l . first - > identifier ( ) ) < r . first - > identifier ( ) ;
}
//if curr == NULL -> no insertion
//all vars in sIn must have the same type
SgStatement * makeDeclaration ( SgStatement * curr , const vector < SgSymbol * > & sIn , vector < SgExpression * > * inits )
{
if ( sIn . size ( ) = = 0 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SgStatement * place = curr ;
SgStatement * scope = NULL ;
vector < pair < SgSymbol * , SgExpression * > > s ;
if ( place )
{
//check same type
map < string , map < string , vector < SgSymbol * > > > groups ;
for ( auto & toDec : sIn )
{
string newDecl = makeDeclaration ( NULL , { toDec } ) - > unparse ( ) ;
auto it = newDecl . find ( " :: " ) ;
if ( it = = string : : npos )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
groups [ newDecl . substr ( 0 , it ) ] [ toDec - > identifier ( ) ] . push_back ( toDec ) ;
}
if ( groups . size ( ) > 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
while ( isSgProgHedrStmt ( place ) = = NULL & & place - > variant ( ) ! = BLOCK_DATA & & place - > variant ( ) ! = MODULE_STMT )
place = place - > controlParent ( ) ;
scope = place ;
set < string > declared ;
while ( isSgExecutableStatement ( place ) = = NULL & & place ! = scope - > lastNodeOfStmt ( ) )
{
if ( place - > variant ( ) = = VAR_DECL | | place - > variant ( ) = = VAR_DECL_90 )
{
SgExpression * ex = place - > expr ( 0 ) ;
while ( ex )
{
if ( ex - > lhs ( ) & & ex - > lhs ( ) - > symbol ( ) )
declared . insert ( ex - > lhs ( ) - > symbol ( ) - > identifier ( ) ) ;
ex = ex - > rhs ( ) ;
}
}
place = place - > lexNext ( ) ;
}
for ( int z = 0 ; z < sIn . size ( ) ; + + z )
if ( declared . find ( sIn [ z ] - > identifier ( ) ) = = declared . end ( ) )
s . push_back ( make_pair ( sIn [ z ] , ( inits ? ( * inits ) [ z ] : NULL ) ) ) ;
}
else
{
for ( int z = 0 ; z < sIn . size ( ) ; + + z )
s . push_back ( make_pair ( sIn [ z ] , ( inits ? ( * inits ) [ z ] : NULL ) ) ) ;
}
if ( s . size ( ) = = 0 )
return NULL ;
sort ( s . begin ( ) , s . end ( ) , sortByName ) ;
SgVarDeclStmt * decl = s [ 0 ] . first - > makeVarDeclStmt ( ) ;
if ( s [ 0 ] . second )
decl - > expr ( 0 ) - > setLhs ( new SgExpression ( ASSGN_OP , new SgVarRefExp ( s [ 0 ] . first ) , s [ 0 ] . second ) ) ;
for ( int z = 1 ; z < s . size ( ) ; + + z )
{
auto tmpDecl = s [ z ] . first - > makeVarDeclStmt ( ) ;
if ( s [ z ] . second )
decl - > addVar ( * new SgExpression ( ASSGN_OP , new SgVarRefExp ( s [ z ] . first ) , s [ z ] . second ) ) ;
else
decl - > addVar ( * tmpDecl - > expr ( 0 ) - > lhs ( ) ) ;
}
if ( place )
{
decl - > setFileName ( place - > fileName ( ) ) ;
decl - > setFileId ( place - > getFileId ( ) ) ;
decl - > setProject ( place - > getProject ( ) ) ;
2024-11-21 15:07:16 +03:00
decl - > setlineNumber ( getNextNegativeLineNumber ( ) ) ;
//decl->setlineNumber(place->lineNumber());
2023-09-14 19:43:13 +03:00
place - > insertStmtBefore ( * decl , * scope ) ;
}
decl - > setVariant ( VAR_DECL_90 ) ;
return decl ;
}
//vars in 'symbolsToDeclare' may be various type
//TODO add inits parameter
vector < SgStatement * > makeDeclaration ( const vector < SgSymbol * > & symbolsToDeclare , SgStatement * where , vector < SgExpression * > * inits )
{
vector < SgStatement * > allDecls ;
map < string , map < string , vector < SgSymbol * > > > groups ;
for ( auto & toDec : symbolsToDeclare )
{
string newDecl = makeDeclaration ( NULL , vector < SgSymbol * > { toDec } ) - > unparse ( ) ;
auto it = newDecl . find ( " :: " ) ;
if ( it = = string : : npos )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
groups [ newDecl . substr ( 0 , it ) ] [ toDec - > identifier ( ) ] . push_back ( toDec ) ;
}
for ( auto & toDecls : groups )
{
vector < SgSymbol * > unitedList ;
for ( auto & elem : toDecls . second )
unitedList . push_back ( elem . second [ 0 ] ) ;
allDecls . push_back ( makeDeclaration ( where , unitedList ) ) ;
}
return allDecls ;
}
int getNextFreeLabel ( )
{
PTR_LABEL lab ;
set < int > used ;
for ( lab = PROJ_FIRST_LABEL ( ) ; lab ; lab = LABEL_NEXT ( lab ) )
used . insert ( LABEL_STMTNO ( lab ) ) ;
for ( int z = 1 ; z < 99999 ; + + z )
if ( used . find ( z ) = = used . end ( ) )
return z ;
return - 1 ;
}
static void recFillUsedVars ( SgExpression * exp , map < string , SgSymbol * > & vars )
{
if ( exp )
{
if ( exp - > symbol ( ) & & ( exp - > variant ( ) = = VAR_REF | | exp - > variant ( ) = = ARRAY_REF | | exp - > variant ( ) = = CONST_REF )
& & ! ( exp - > symbol ( ) - > attributes ( ) & PRIVATE_BIT ) )
{
const auto key = exp - > symbol ( ) - > identifier ( ) ;
if ( vars . find ( key ) = = vars . end ( ) )
vars . insert ( make_pair ( key , exp - > symbol ( ) ) ) ;
}
recFillUsedVars ( exp - > lhs ( ) , vars ) ;
recFillUsedVars ( exp - > rhs ( ) , vars ) ;
}
}
static inline void fillUsedVars ( SgStatement * st , map < string , SgSymbol * > & vars )
{
if ( st )
{
for ( int i = 0 ; i < 3 ; + + i )
{
SgExpression * exp = st - > expr ( i ) ;
recFillUsedVars ( exp , vars ) ;
}
}
}
static inline void joinMaps ( map < string , SgSymbol * > & map1 , const map < string , SgSymbol * > & map2 , const map < string , SgSymbol * > & exept = map < string , SgSymbol * > ( ) )
{
for ( auto & pair : map2 )
if ( exept . find ( pair . first ) = = exept . end ( ) & & map1 . find ( pair . first ) = = map1 . end ( ) )
map1 . insert ( pair ) ;
}
void fillVisibleInUseVariables ( SgStatement * useSt , map < string , SgSymbol * > & vars )
{
if ( useSt )
{
if ( useSt - > variant ( ) = = USE_STMT )
{
bool only = false ;
map < string , SgSymbol * > localVars ; // local module variables
map < string , SgSymbol * > useVars ; // variables from other modules
map < string , SgSymbol * > renamedVas ; // renamed variables
map < string , SgSymbol * > originVars ; // origin variables names in USE_STAT
// check USE_STAT
// fill from ONLY_NODE and RENAME_NODE
SgExpression * ex = useSt - > expr ( 0 ) ;
if ( ex & & ex - > variant ( ) = = ONLY_NODE )
{
only = true ;
ex = ex - > lhs ( ) ;
}
for ( auto exI = ex ; exI ; exI = exI - > rhs ( ) )
{
if ( exI - > lhs ( ) - > variant ( ) = = RENAME_NODE )
{
SgExpression * ren = exI - > lhs ( ) ;
if ( ren - > lhs ( ) - > symbol ( ) & & ren - > rhs ( ) & & ren - > rhs ( ) - > symbol ( ) )
{
if ( renamedVas . find ( ren - > lhs ( ) - > symbol ( ) - > identifier ( ) ) = = renamedVas . end ( ) )
renamedVas . insert ( make_pair ( ren - > lhs ( ) - > symbol ( ) - > identifier ( ) , ren - > lhs ( ) - > symbol ( ) ) ) ;
if ( originVars . find ( ren - > rhs ( ) - > symbol ( ) - > identifier ( ) ) = = originVars . end ( ) )
originVars . insert ( make_pair ( ren - > rhs ( ) - > symbol ( ) - > identifier ( ) , ren - > rhs ( ) - > symbol ( ) ) ) ;
}
else if ( only & & ren - > lhs ( ) - > symbol ( ) )
{
if ( renamedVas . find ( ren - > lhs ( ) - > symbol ( ) - > identifier ( ) ) = = renamedVas . end ( ) )
renamedVas . insert ( make_pair ( ren - > lhs ( ) - > symbol ( ) - > identifier ( ) , ren - > lhs ( ) - > symbol ( ) ) ) ;
}
}
}
if ( ! only )
{
// check module
const string modName ( useSt - > symbol ( ) - > identifier ( ) ) ;
vector < SgStatement * > modules ;
findModulesInFile ( useSt - > getFile ( ) , modules ) ;
bool found = false ;
for ( auto i = 0 ; i < modules . size ( ) ; + + i )
{
if ( modName = = modules [ i ] - > symbol ( ) - > identifier ( ) )
{
found = true ;
vector < SgStatement * > useStats ;
for ( SgStatement * st = modules [ i ] - > lexNext ( ) ; st ! = modules [ i ] - > lastNodeOfStmt ( ) ; st = st - > lexNext ( ) )
{
if ( st - > variant ( ) = = USE_STMT )
useStats . push_back ( st ) ;
else if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
else
fillUsedVars ( st , localVars ) ;
}
for ( auto & useSt : useStats )
{
map < string , SgSymbol * > visibleVars ;
fillVisibleInUseVariables ( useSt , visibleVars ) ;
joinMaps ( useVars , visibleVars ) ;
}
break ;
}
}
if ( ! found )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
// fill vars
// TODO: check renaming
joinMaps ( vars , useVars , originVars ) ;
joinMaps ( vars , localVars , originVars ) ;
joinMaps ( vars , renamedVas ) ;
}
}
}
Variable : : Variable ( SgFile * file , SgStatement * function , SgSymbol * symbol , const std : : string & name , const varType type , const int position ) :
symbol ( symbol ) , name ( name ) , type ( type ) , position ( position )
{
declPace = declaratedInStmt ( symbol ) ;
allUse . push_back ( CommonVariableUse ( file , function , symbol ) ) ;
}
string preprocDataString ( string data , bool full )
{
string ret = " " ;
for ( int z = 0 ; z < data . size ( ) ; + + z )
{
if ( data [ z ] = = ' \t ' )
data [ z ] = ' ' ;
else if ( data [ z ] = = ' \r ' )
data [ z ] = ' ' ;
}
auto it = data . find ( " DATA " ) ;
if ( it = = string : : npos )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
else
it + = 4 ;
if ( data [ it ] ! = ' ' )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
else
it + + ;
if ( full )
ret = " DATA " ;
int i = it ;
while ( i ! = data . size ( ) )
{
if ( data [ i ] ! = ' ' )
ret + = data [ i + + ] ;
else
i + + ;
}
return ret ;
}
map < string , string > splitData ( const set < SgValueExp * > & dataStats )
{
map < string , string > result ;
for ( auto & dataV : dataStats )
{
char * value = dataV - > thellnd - > entry . string_val ;
string dataS ( value ) ;
convertToUpper ( dataS ) ;
dataS = preprocDataString ( dataS , false ) ;
convertToLower ( dataS ) ;
string currS = " " ;
string currV = " " ;
int startV = - 1 ;
for ( int z = 0 ; z < dataS . size ( ) ; + + z )
{
if ( startV = = - 1 )
{
if ( dataS [ z ] = = ' / ' )
startV = 0 ;
else if ( dataS [ z ] ! = ' ' & & dataS [ z ] ! = ' , ' )
currS + = dataS [ z ] ;
}
else if ( startV = = 0 )
{
if ( dataS [ z ] = = ' / ' )
{
startV = - 1 ;
result [ currS ] = currV ;
currS = currV = " " ;
}
else if ( dataS [ z ] ! = ' ' )
currV + = dataS [ z ] ;
}
}
}
return result ;
}
void extractComments ( SgStatement * where , const string & what )
{
if ( BIF_CMNT ( where - > thebif ) & & CMNT_STRING ( BIF_CMNT ( where - > thebif ) ) )
{
char * str = CMNT_STRING ( BIF_CMNT ( where - > thebif ) ) ;
string source ( str ) ;
removeSubstrFromStr ( source , what . c_str ( ) ) ;
sprintf ( str , " %s " , source . c_str ( ) ) ;
}
}
void getVariables ( SgExpression * ex , set < string > & variables , const set < int > variants )
{
if ( ex )
{
if ( variants . find ( ex - > variant ( ) ) ! = variants . end ( ) )
variables . insert ( OriginalSymbol ( ex - > symbol ( ) ) - > identifier ( ) ) ;
getVariables ( ex - > rhs ( ) , variables , variants ) ;
getVariables ( ex - > lhs ( ) , variables , variants ) ;
}
}
void getVariables ( SgExpression * ex , set < SgSymbol * > & variables , const set < int > variants )
{
if ( ex )
{
if ( variants . find ( ex - > variant ( ) ) ! = variants . end ( ) )
variables . insert ( OriginalSymbol ( ex - > symbol ( ) ) ) ;
getVariables ( ex - > rhs ( ) , variables , variants ) ;
getVariables ( ex - > lhs ( ) , variables , variants ) ;
}
}
template < typename T >
set < T > getAllVariables ( SgStatement * stFrom , SgStatement * stTo , const set < int > & variants )
{
set < T > vars ;
for ( auto stmt = stFrom ; stmt ! = stTo ; stmt = stmt - > lexNext ( ) )
for ( int i = 0 ; i < 3 ; + + i )
getVariables ( stmt - > expr ( i ) , vars , variants ) ;
return vars ;
}
template set < string > getAllVariables ( SgStatement * stFrom , SgStatement * stTo , const set < int > & variants ) ;
template set < SgSymbol * > getAllVariables ( SgStatement * stFrom , SgStatement * stTo , const set < int > & variants ) ;
2024-02-28 17:38:02 +03:00
void shiftLines ( SgProject * project , bool print )
{
map < string , int > shifts ;
//shift lines if modules included
const string shiftInfo = " !SPF NUM FILES " ;
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z )
{
SgFile * file = & ( project - > file ( z ) ) ;
const string fileN = file - > filename ( ) ;
int shiftN = 0 ;
for ( auto st = file - > firstStatement ( ) ; st ; st = st - > lexNext ( ) )
{
if ( st - > comments ( ) )
{
string comms = st - > comments ( ) ;
auto it = comms . find ( shiftInfo ) ;
if ( it ! = string : : npos )
{
it + = shiftInfo . size ( ) + 1 ;
if ( sscanf ( comms . c_str ( ) + it , " %d " , & shiftN ) = = - 1 )
{
__spf_print ( print , " comm %s, shifted %s \n " , comms . c_str ( ) , comms . c_str ( ) + it ) ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
break ;
}
}
}
if ( shiftN = = 0 )
continue ;
shifts [ fileN ] = shiftN + 1 ; // with comment !SPF NUM FILES
__spf_print ( print , " shift by %d for %s \n " , shiftN , fileN . c_str ( ) ) ;
}
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z )
{
SgFile * file = & ( project - > file ( z ) ) ;
for ( SgStatement * st = file - > firstStatement ( ) - > lexNext ( ) ; st ; st = st - > lexNext ( ) )
{
string currF = st - > fileName ( ) ;
auto it = shifts . find ( currF ) ;
if ( it ! = shifts . end ( ) & & file - > filename ( ) = = currF )
st - > setlineNumber ( st - > lineNumber ( ) - it - > second ) ;
}
}
}
2023-09-14 19:43:13 +03:00
SgProject * createProject ( const char * proj_name ,
vector < ParallelRegion * > & parallelRegions ,
vector < ParallelRegion * > & subs_parallelRegions ,
map < string , vector < SgStatement * > > & hiddenData ,
map < string , int > & filesNameWithoutExt ,
map < string , set < string > > & moduleUsesByFile ,
map < string , string > & moduleDecls ,
2024-07-24 12:07:29 +03:00
map < string , map < SgStatement * , vector < SgStatement * > > > & exctactedModuleStats ,
bool printSymbTable )
2023-09-14 19:43:13 +03:00
{
2024-02-28 17:38:02 +03:00
Statement : : setSapforRegime ( ) ;
2023-09-14 19:43:13 +03:00
Statement : : deactiveConsistentchecker ( ) ;
sortFilesBySize ( proj_name ) ;
SgProject * project = new SgProject ( proj_name ) ;
addNumberOfFileToAttribute ( project ) ;
2024-07-24 12:07:29 +03:00
if ( printSymbTable ) {
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z ) {
SgFile * file = & ( project - > file ( z ) ) ;
printf ( " ===== TABLE FOR FILE %s \n " , file - > filename ( ) ) ;
printSymbolTable ( file , " " ) ;
}
exit ( 0 ) ;
}
2023-09-14 19:43:13 +03:00
parallelRegions . push_back ( new ParallelRegion ( 0 , " DEFAULT " ) ) ;
subs_parallelRegions . push_back ( new ParallelRegion ( 0 , " DEFAULT " ) ) ;
Statement : : activeConsistentchecker ( ) ;
Statement : : activeDeprecatedchecker ( ) ;
//hide duplicated functions
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z )
{
SgFile * file = & ( project - > file ( z ) ) ;
2023-11-28 12:58:22 +03:00
//file->unparsestdout();
2023-09-14 19:43:13 +03:00
const string fileN = file - > filename ( ) ;
auto first = file - > firstStatement ( ) ;
SgStatement * lastValid = NULL ;
const string toFind = " !SPF SHADOW FILES " ;
for ( SgStatement * st = first - > lexNext ( ) , * stPrev = first ;
st ;
st = st - > lexNext ( ) , stPrev = stPrev - > lexNext ( ) )
{
if ( st - > comments ( ) )
{
string comm ( st - > comments ( ) ) ;
if ( comm . find ( toFind ) ! = string : : npos )
{
if ( st - > variant ( ) = = CONTROL_END )
{
extractComments ( st , toFind ) ;
lastValid = st ;
}
else
lastValid = stPrev ;
break ;
}
}
}
if ( lastValid )
{
vector < SgStatement * > toExtract ;
auto st = lastValid - > lexNext ( ) ;
while ( st )
{
toExtract . push_back ( st ) ;
st = st - > lastNodeOfStmt ( ) ;
st = st - > lexNext ( ) ;
}
__spf_print ( 1 , " hidden data for file '%s' \n " , file - > filename ( ) ) ;
set < int > validVars = { PROG_HEDR , FUNC_HEDR , PROC_HEDR , BLOCK_DATA , MODULE_STMT } ;
for ( auto & elem : toExtract )
{
int var = elem - > variant ( ) ;
if ( validVars . find ( var ) = = validVars . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
__spf_print ( 1 , " [%s, %d] \n " , elem - > fileName ( ) , elem - > lineNumber ( ) ) ;
hiddenData [ fileN ] . push_back ( elem - > extractStmt ( ) ) ;
}
lastValid - > setLexNext ( ( SgStatement * ) NULL ) ;
}
}
//hide excluded modules
const set < string > excludedMods = getExcludedModules ( ) ;
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z )
{
SgFile * file = & ( project - > file ( z ) ) ;
const string fileN = file - > filename ( ) ;
auto first = file - > firstStatement ( ) ;
SgStatement * lastValid = NULL ;
vector < SgStatement * > toExtract ;
for ( SgStatement * st = first - > lexNext ( ) ; st ; st = st - > lexNext ( ) )
{
if ( st - > variant ( ) = = USE_STMT )
{
string name = st - > symbol ( ) - > identifier ( ) ;
if ( excludedMods . find ( name ) ! = excludedMods . end ( ) )
{
SgStatement * before = st - > lexNext ( ) ;
do
{
if ( before - > variant ( ) = = USE_STMT )
{
if ( excludedMods . find ( before - > symbol ( ) - > identifier ( ) ) ! = excludedMods . end ( ) )
{
before = before - > lexNext ( ) ;
continue ;
}
}
break ;
} while ( true ) ;
exctactedModuleStats [ fileN ] [ before ] . push_back ( st ) ;
toExtract . push_back ( st ) ;
}
}
}
for ( auto & elem : toExtract )
elem - > extractStmt ( ) ;
}
//dump symbol table and symbol use
/*printSymbolTable(current_file);
for ( auto st = current_file - > firstStatement ( ) - > lexNext ( ) ; st ; st = st - > lexNext ( ) )
{
if ( st - > variant ( ) ! = MODULE_STMT & & isSgProgHedrStmt ( st ) = = NULL )
{
set < SgSymbol * > refs ;
for ( int z = 0 ; z < 3 ; + + z )
if ( st - > expr ( z ) )
fillAllSymbs ( st - > expr ( z ) , refs ) ;
if ( refs . size ( ) )
{
printf ( " FOR STATEMENT ON LINE %d: \n " , st - > lineNumber ( ) ) ;
st - > unparsestdout ( ) ;
printf ( " refs ids: " ) ;
for ( auto & elem : refs )
printf ( " %d (%s) " , elem - > id ( ) , elem - > identifier ( ) ) ;
printf ( " ; \n \n " ) ;
}
}
} */
set < string > filesInProj ;
//preprocess module includes
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z )
filesInProj . insert ( ( project - > file ( z ) ) . filename ( ) ) ;
//check main unit
findMainUnit ( project , SPF_messages ) ;
set < string > globalFunctions ;
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z )
{
SgFile * file = & ( project - > file ( z ) ) ;
string name = OnlyName ( file - > filename ( ) ) ;
if ( filesNameWithoutExt . find ( name ) = = filesNameWithoutExt . end ( ) )
filesNameWithoutExt [ name ] = 1 ;
else
filesNameWithoutExt [ name ] + + ;
fillModuleUse ( file , moduleUsesByFile , moduleDecls ) ;
int funcCount = file - > numberOfFunctions ( ) ;
for ( int k = 0 ; k < funcCount ; + + k )
{
auto func = file - > functions ( k ) ;
if ( func - > controlParent ( ) - > variant ( ) = = GLOBAL )
globalFunctions . insert ( func - > symbol ( ) - > identifier ( ) ) ;
}
}
filterModuleUse ( moduleUsesByFile , moduleDecls ) ;
2024-02-28 17:38:02 +03:00
//shift lines if modules included
shiftLines ( project ) ;
2023-09-14 19:43:13 +03:00
map < string , vector < Function > > functions ;
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z )
fillFunctionInfo ( & ( project - > file ( z ) ) , functions ) ;
set < string > needToResolve ;
for ( auto & func : functions )
if ( func . second . size ( ) > 1 )
needToResolve . insert ( func . first ) ;
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z )
resolveFunctionCalls ( & ( project - > file ( z ) ) , needToResolve , functions ) ;
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z )
correctModuleProcNames ( & ( project - > file ( z ) ) , globalFunctions ) ;
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z )
2023-11-05 18:20:31 +03:00
removeExecutableFromModuleDeclaration ( & ( project - > file ( z ) ) , filesInProj , hiddenData [ project - > file ( z ) . filename ( ) ] ) ;
2023-09-14 19:43:13 +03:00
for ( int z = 0 ; z < project - > numberOfFiles ( ) ; + + z )
{
SgFile * file = & ( project - > file ( z ) ) ;
correctModuleSymbols ( file ) ;
//file->unparsestdout();
}
if ( detectMpiCalls ( project , SPF_messages ) )
{
2024-06-19 18:08:27 +03:00
sharedMemoryParallelization = 1 ;
2023-09-14 19:43:13 +03:00
keepDvmDirectives = 0 ;
ignoreIO = 1 ;
parallizeFreeLoops = 0 ;
}
return project ;
}
static bool isIntrinsic ( SgType * base )
{
switch ( base - > variant ( ) )
{
case T_INT :
case T_FLOAT :
case T_BOOL :
case T_DOUBLE :
case T_COMPLEX :
case T_DCOMPLEX :
case T_CHAR :
return true ;
default :
break ;
}
return false ;
}
bool isArrayType ( SgType * type )
{
if ( type )
{
SgType * base = type - > baseType ( ) ;
if ( base & &
type - > variant ( ) ! = T_STRING & &
base - > variant ( ) ! = T_STRING & &
( IS_INTRINSIC_TYPE ( base ) | | isIntrinsic ( base ) ) )
return true ;
}
return false ;
}
bool isArrayRef ( SgExpression * ex )
{
if ( ex & & ex - > variant ( ) = = ARRAY_REF )
{
SgArrayRefExp * arrayRef = isSgArrayRefExp ( ex ) ;
if ( arrayRef )
if ( isArrayType ( ex - > symbol ( ) - > type ( ) ) )
{
auto type = isSgArrayType ( ex - > symbol ( ) - > type ( ) ) ;
if ( type & & type - > dimension ( ) )
return true ;
}
}
return false ;
}
bool isStringArrayType ( SgType * type )
{
if ( type )
{
SgType * base = type - > baseType ( ) ;
if ( base & & ( type - > variant ( ) = = T_STRING | | base - > variant ( ) = = T_STRING ) )
return true ;
}
return false ;
}
void moveLabelBefore ( SgStatement * st , SgStatement * next )
{
SgLabel * lab = next ? next - > label ( ) : st - > label ( ) ;
if ( lab )
{
SgStatement * cont = new SgContinueStmt ( ) ;
cont - > setLabel ( * lab ) ;
if ( next )
next - > deleteLabel ( true ) ;
else
st - > deleteLabel ( true ) ;
if ( next )
{
cont - > setFileName ( next - > fileName ( ) ) ;
cont - > setProject ( next - > getProject ( ) ) ;
cont - > setFileId ( next - > getFileId ( ) ) ;
cont - > setlineNumber ( next - > lineNumber ( ) ) ;
}
else
{
cont - > setFileName ( st - > fileName ( ) ) ;
cont - > setProject ( st - > getProject ( ) ) ;
cont - > setFileId ( st - > getFileId ( ) ) ;
cont - > setlineNumber ( getNextNegativeLineNumber ( ) ) ;
}
st - > insertStmtBefore ( * cont , * st - > controlParent ( ) ) ;
}
}
bool isEqSymbols ( SgSymbol * sym1 , SgSymbol * sym2 )
{
if ( ! sym1 | | ! sym2 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
return string ( OriginalSymbol ( sym1 ) - > identifier ( ) ) = = string ( OriginalSymbol ( sym2 ) - > identifier ( ) ) ;
}
set < string > getAllFilesInProject ( )
{
set < string > res ;
const string currId = current_file - > filename ( ) ;
for ( int z = 0 ; z < CurrentProject - > numberOfFiles ( ) ; + + z )
res . insert ( CurrentProject - > file ( z ) . filename ( ) ) ;
if ( SgFile : : switchToFile ( currId ) = = - 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
return res ;
}
void LogIftoIfThen ( SgStatement * stmt )
{
SgControlEndStmt * control = new SgControlEndStmt ( ) ;
stmt - > setVariant ( IF_NODE ) ;
stmt - > lexNext ( ) - > insertStmtAfter ( * control , * stmt ) ;
if ( stmt - > numberOfAttributes ( OMP_MARK ) > 0 )
control - > addAttribute ( OMP_MARK ) ;
}
void removeSpecialCommentsFromProject ( SgFile * file )
{
//remove SAPFOR comment with version
SgStatement * stF = file - > firstStatement ( ) - > lexNext ( ) ;
while ( stF )
{
if ( stF & & stF - > comments ( ) )
{
string oldComment ( stF - > comments ( ) ) ;
auto it = oldComment . find ( " ! *** generated by SAPFOR " ) ;
if ( it ! = string : : npos )
{
auto endIt = oldComment . find ( " ! *** generated by SAPFOR " , it + 1 ) ;
endIt = oldComment . find ( " \n " , ( endIt ! = string : : npos ) ? endIt : it ) ;
string newComment = oldComment . substr ( 0 , it ) + oldComment . substr ( endIt + 1 ) ;
stF - > delComments ( ) ;
if ( newComment ! = " " )
stF - > setComments ( newComment . c_str ( ) ) ;
if ( genVersionDone . find ( file ) ! = genVersionDone . end ( ) )
genVersionDone . erase ( file ) ;
}
}
stF = stF - > lexNext ( ) ;
}
}
2023-11-22 20:21:18 +03:00
2023-12-27 12:57:00 +03:00
//TODO: for gen_block and other variations, and redistributions dirs
2023-11-22 20:21:18 +03:00
void getMaxMinBlockDistribution ( SgFile * file , pair < int , int > & min_max )
{
SgStatement * st = file - > firstStatement ( ) ;
while ( st )
{
if ( isDVM_stat ( st ) )
{
if ( st - > variant ( ) = = DVM_DISTRIBUTE_DIR | | st - > variant ( ) = = DVM_VAR_DECL )
{
for ( int z = 0 ; z < 3 ; + + z )
{
SgExpression * ex = st - > expr ( z ) ;
queue < SgExpression * > q ;
if ( ex )
{
q . push ( ex ) ;
int blockCount = 0 ;
while ( q . size ( ) )
{
ex = q . front ( ) ;
q . pop ( ) ;
if ( ex - > rhs ( ) )
q . push ( ex - > rhs ( ) ) ;
if ( ex - > lhs ( ) )
q . push ( ex - > lhs ( ) ) ;
if ( ex - > variant ( ) = = BLOCK_OP )
blockCount + + ;
}
if ( blockCount )
{
if ( min_max = = make_pair ( - 1 , - 1 ) )
min_max = make_pair ( blockCount , blockCount ) ;
else
{
min_max . first = std : : min ( min_max . first , blockCount ) ;
min_max . second = std : : max ( min_max . second , blockCount ) ;
}
}
}
}
}
}
st = st - > lexNext ( ) ;
}
}
2023-12-27 12:57:00 +03:00
2024-04-10 13:42:49 +03:00
//TODO: need to add to includes
2023-12-27 12:57:00 +03:00
void addPrivatesToArraysFromGUI ( SgFile * file , const map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays ,
const map < string , int > & distrStateFromGUI )
{
2024-04-10 13:42:49 +03:00
map < SgStatement * , set < SgSymbol * > > added ;
2023-12-27 12:57:00 +03:00
for ( auto & arrayPair : declaredArrays )
{
DIST : : Array * array = arrayPair . second . first ;
string key = array - > GetIndepUniqName ( ) ;
auto it = distrStateFromGUI . find ( key ) ;
if ( it = = distrStateFromGUI . end ( ) )
continue ;
if ( it - > second ! = DIST : : NO_DISTR )
continue ;
for ( auto & decl : array - > GetDeclInfoWithSymb ( ) )
{
auto & place = decl . first ;
const auto & symb = decl . second - > GetOriginal ( ) ;
if ( place . first ! = file - > filename ( ) )
continue ;
SgStatement * declSt = SgStatement : : getStatementByFileAndLine ( place . first , place . second ) ;
checkNull ( declSt , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
2024-04-10 13:42:49 +03:00
added [ declSt ] . insert ( symb ) ;
2023-12-27 12:57:00 +03:00
}
}
for ( auto & toInsert : added )
2024-04-10 13:42:49 +03:00
{
vector < SgExpression * > list ;
2023-12-27 12:57:00 +03:00
for ( auto & elem : toInsert . second )
2024-04-10 13:42:49 +03:00
list . push_back ( new SgVarRefExp ( elem ) ) ;
SgStatement * op = new SgStatement ( SPF_ANALYSIS_DIR ) ;
op - > setExpression ( 0 , new SgExpression ( SPF_PROCESS_PRIVATE_OP , makeExprList ( list ) ) ) ;
toInsert . first - > insertStmtBefore ( * op , * toInsert . first - > controlParent ( ) ) ;
}
2024-05-02 11:05:56 +03:00
}