2025-06-02 19:08:09 +03:00
# include "leak_detector.h"
2023-09-14 19:43:13 +03:00
# include <string>
# include <vector>
# include <algorithm>
# include <set>
# include <map>
# include <stack>
# include <string.h>
# include "ParRegions_func.h"
# include "resolve_par_reg_conflicts.h"
2025-06-04 13:08:38 +03:00
# include "graph_calls_func.h"
# include "graph_loops_func.h"
2023-09-14 19:43:13 +03:00
# include "../LoopAnalyzer/loop_analyzer.h"
# include "../DirectiveProcessing/directive_creator.h"
# include "../DirectiveProcessing/insert_directive.h"
2025-06-04 13:08:38 +03:00
# include "SgUtils.h"
2025-06-02 19:08:09 +03:00
# include "expr_transform.h"
# include "../Transformations/FunctionPurifying/function_purifying.h"
2023-09-14 19:43:13 +03:00
using std : : map ;
using std : : pair ;
using std : : set ;
using std : : vector ;
using std : : stack ;
using std : : string ;
using std : : wstring ;
using std : : to_string ;
using std : : make_pair ;
static inline int getRegionExplicitLine ( SgStatement * startR )
{
checkNull ( startR , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
const string saveName = current_file - > filename ( ) ;
startR - > switchToFile ( ) ;
SgStatement * regSt = startR - > lexPrev ( ) ;
checkNull ( regSt , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SgFile : : switchToFile ( saveName ) ;
return regSt - > lineNumber ( ) ;
}
static int getIntervalNumber ( const int fileId , const int lineNumber , const uint64_t regionId )
{
int fileMask = 0xFF ;
int lineMask = 0x7FFFF ;
int regionMask = 0xF ;
int filePart = fileMask & fileId ;
int linePart = lineMask & lineNumber ;
int regionPart = regionMask & regionId ;
filePart = filePart < < 4 ;
linePart = linePart < < 12 ;
int number = 1 < < 31 ;
number = number | filePart | linePart | regionPart ;
return number ;
}
// array -> common-block
static map < DIST : : Array * , const CommonBlock * > allUsedCommonArrays ;
static bool isSPF_reg ( SgStatement * st )
{
return st - > variant ( ) = = SPF_PARALLEL_REG_DIR | | st - > variant ( ) = = SPF_END_PARALLEL_REG_DIR ;
}
static const vector < const Variable * > getArraySynonyms ( DIST : : Array * array )
{
auto arrayBlock = allUsedCommonArrays . find ( array ) ;
if ( arrayBlock = = allUsedCommonArrays . end ( ) )
{
auto location = array - > GetLocation ( ) ;
if ( location . first ! = DIST : : l_COMMON )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
//try to find synonym
for ( auto & elem : allUsedCommonArrays )
{
if ( elem . second - > getName ( ) = = location . second )
{
arrayBlock = allUsedCommonArrays . find ( elem . first ) ;
break ;
}
}
if ( arrayBlock = = allUsedCommonArrays . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
// find array position
int pos = - 1 ;
for ( auto & var : arrayBlock - > second - > getVariables ( ) )
{
if ( var - > getName ( ) = = arrayBlock - > first - > GetShortName ( ) & & var - > getType ( ) = = ARRAY )
pos = var - > getPosition ( ) ;
}
// get all variables with this position
return arrayBlock - > second - > getVariables ( pos ) ;
}
static string getStringDeclaration ( SgSymbol * symb )
{
string decl ;
SgFile * oldFile = current_file ;
if ( SgFile : : switchToFile ( symb - > getFile ( ) - > filename ( ) ) ! = - 1 )
{
auto stat = symb - > makeVarDeclStmt ( ) ;
2024-04-09 11:51:21 +03:00
auto res = CalculateInteger ( stat - > expr ( 0 ) - > copyPtr ( ) ) ;
2023-09-14 19:43:13 +03:00
stat - > setExpression ( 0 , res ) ;
decl = stat - > unparse ( ) ;
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( SgFile : : switchToFile ( oldFile - > filename ( ) ) = = - 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
return decl ;
}
static void insertStringDeclarations ( SgStatement * insertPlace , DIST : : Array * array )
{
auto varsOnPos = getArraySynonyms ( array ) ;
if ( varsOnPos . size ( ) & & varsOnPos [ 0 ] - > getName ( ) = = array - > GetShortName ( ) )
{
SgSymbol * varSymb = varsOnPos [ 0 ] - > getSymbol ( ) ;
string varName = varSymb - > identifier ( ) ;
string newName = varName + " _c " ;
varSymb - > changeName ( newName . c_str ( ) ) ;
string decl = getStringDeclaration ( varsOnPos [ 0 ] - > getSymbol ( ) ) ;
varSymb - > changeName ( varName . c_str ( ) ) ;
insertPlace - > addComment ( decl . c_str ( ) ) ;
}
}
static void createSetOfCalledFuncs ( const string & funcName , const map < string , FuncInfo * > & funcMap , set < FuncInfo * > & callSet )
{
set < string > queue ;
queue . insert ( funcName ) ;
while ( queue . size ( ) )
{
auto it = queue . begin ( ) ;
FuncInfo * func = getFuncInfo ( funcMap , * it ) ;
queue . erase ( it ) ;
for ( auto & call : func - > callsFrom )
{
FuncInfo * callFunc = getFuncInfo ( funcMap , call ) ;
auto it2 = callSet . find ( callFunc ) ;
if ( it2 = = callSet . end ( ) & & callFunc )
{
callSet . insert ( it2 , callFunc ) ;
queue . insert ( call ) ;
}
}
}
}
static void fillRegionCover ( FuncInfo * func , const map < string , FuncInfo * > & funcMap )
{
if ( func - > funcPointer - > variant ( ) ! = ENTRY_STAT )
{
if ( SgFile : : switchToFile ( func - > fileName ) ! = - 1 )
{
SgStatement * iterator = func - > funcPointer - > GetOriginal ( ) ;
FuncInfo * entry = NULL ;
bool isFuncCovered = true ;
bool isEntryCovered = false ;
bool isRegion = false ;
for ( ; ! isSgExecutableStatement ( iterator ) & & ! isSPF_reg ( iterator ) & & iterator - > variant ( ) ! = ENTRY_STAT ; iterator = iterator - > lexNext ( ) )
{
// skip not executable and not necessary statements
}
for ( ; iterator - > lineNumber ( ) < func - > linesNum . second ; iterator = iterator - > lexNext ( ) )
{
switch ( iterator - > variant ( ) )
{
case SPF_PARALLEL_REG_DIR :
isRegion = true ;
break ;
case SPF_END_PARALLEL_REG_DIR :
isRegion = false ;
break ;
case ENTRY_STAT :
entry = getFuncInfo ( funcMap , string ( iterator - > symbol ( ) - > identifier ( ) ) ) ;
isEntryCovered = true ;
break ;
default :
if ( isSPF_stat ( iterator ) | | isDVM_stat ( iterator ) )
break ;
if ( ! isRegion )
{
isFuncCovered = false ;
isEntryCovered = false ;
}
break ;
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
static void recursiveFill ( SgStatement * st ,
SgExpression * exp ,
ParallelRegion * region ,
const string & fileName ,
const string & funcName ,
const ParallelRegionLines & lines ,
const map < string , FuncInfo * > & funcMap ,
const map < string , CommonBlock * > & commonBlocks )
{
if ( exp )
{
if ( exp - > variant ( ) = = ARRAY_REF )
{
SgArrayRefExp * arrayRef = isSgArrayRefExp ( exp ) ;
SgType * type = exp - > symbol ( ) - > type ( ) ;
if ( isArrayRef ( arrayRef ) )
{
SgSymbol * arraySymbol = exp - > symbol ( ) ;
string arrayName = string ( arraySymbol - > identifier ( ) ) ;
DIST : : Array * array = getArrayFromDeclarated ( declaratedInStmt ( arraySymbol ) , arrayName ) ;
FuncInfo * func = getFuncInfo ( funcMap , funcName ) ;
checkNull ( array , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
checkNull ( func , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( ! array - > IsNotDistribute ( ) | | array - > GetLocation ( ) . first = = DIST : : l_PARAMETER )
{
auto commonBlock = isArrayInCommon ( commonBlocks , array ) ;
if ( commonBlock )
{
array = commonBlock - > getFirstSynonym ( array ) ;
if ( isSgExecutableStatement ( st ) )
region - > AddUsedCommonArray ( func , array , lines ) ;
allUsedCommonArrays . insert ( make_pair ( array , commonBlock ) ) ;
}
else if ( ! lines . isImplicit ( ) )
region - > AddUsedLocalArray ( func , array , lines ) ;
}
}
}
recursiveFill ( st , exp - > rhs ( ) , region , fileName , funcName , lines , funcMap , commonBlocks ) ;
recursiveFill ( st , exp - > lhs ( ) , region , fileName , funcName , lines , funcMap , commonBlocks ) ;
}
}
void fillRegionArrays ( vector < ParallelRegion * > & regions ,
const map < string , vector < FuncInfo * > > & allFuncInfo ,
const map < string , CommonBlock * > & commonBlocks )
{
if ( regions . size ( ) = = 1 & & regions [ 0 ] - > GetName ( ) = = " DEFAULT " ) // only default
return ;
map < string , FuncInfo * > funcMap ;
createMapOfFunc ( allFuncInfo , funcMap ) ;
for ( auto & region : regions )
{
for ( auto & fileLines : region - > GetAllLines ( ) )
{
// switch to current file
if ( SgFile : : switchToFile ( fileLines . first ) ! = - 1 )
{
for ( auto & regionLines : fileLines . second )
{
SgStatement * iterator = NULL ;
SgStatement * end = NULL ;
string funcName = " " ;
// implicit lines
if ( regionLines . isImplicit ( ) )
{
iterator = SgStatement : : getStatementByFileAndLine ( fileLines . first , regionLines . lines . first ) ;
end = SgStatement : : getStatementByFileAndLine ( fileLines . first , regionLines . lines . second ) ;
}
else
{
iterator = regionLines . stats . first - > GetOriginal ( ) ;
end = regionLines . stats . second - > GetOriginal ( ) ;
}
iterator = getFuncStat ( iterator ) ;
string containsPrefix = " " ;
SgStatement * st_cp = iterator - > controlParent ( ) ;
if ( st_cp - > variant ( ) = = PROC_HEDR | | st_cp - > variant ( ) = = PROG_HEDR | | st_cp - > variant ( ) = = FUNC_HEDR )
containsPrefix = st_cp - > symbol ( ) - > identifier ( ) + string ( " . " ) ;
funcName = containsPrefix + iterator - > symbol ( ) - > identifier ( ) ;
if ( regionLines . isImplicit ( ) )
iterator = SgStatement : : getStatementByFileAndLine ( fileLines . first , regionLines . lines . first ) ;
else
iterator = regionLines . stats . first - > GetOriginal ( ) ;
for ( ; iterator & & iterator ! = end - > lexNext ( ) ; iterator = iterator - > lexNext ( ) )
{
if ( isSPF_stat ( iterator ) | | isDVM_stat ( iterator ) )
continue ;
if ( iterator - > variant ( ) = = ALLOCATE_STMT | | iterator - > variant ( ) = = DEALLOCATE_STMT )
continue ;
for ( int i = 0 ; i < 3 ; + + i )
recursiveFill ( iterator , iterator - > expr ( i ) , region , fileLines . first , funcName , regionLines , funcMap , commonBlocks ) ;
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
}
void fillRegionFunctions ( vector < ParallelRegion * > & regions , const map < string , vector < FuncInfo * > > & allFuncInfo )
{
if ( regions . size ( ) = = 1 & & regions [ 0 ] - > GetName ( ) = = " DEFAULT " ) // only default
return ;
// funcName -> funcInfo
map < string , FuncInfo * > funcMap ;
createMapOfFunc ( allFuncInfo , funcMap ) ;
for ( auto & nameFunc : funcMap )
{
auto func = nameFunc . second ;
fillRegionCover ( func , funcMap ) ;
// add DEFAULT region (regionId == 0)
if ( func - > isIndirect ( ) )
{
2023-11-05 13:08:57 +03:00
for ( auto & callInfo : func - > callsFromDetailed )
2023-09-14 19:43:13 +03:00
{
2023-11-05 13:08:57 +03:00
auto & callFrom = callInfo . detailCallsFrom ;
auto line = callFrom . second ;
auto call = callFrom . first ;
2023-09-14 19:43:13 +03:00
auto callF = getFuncInfo ( funcMap , call ) ;
auto regs = getAllRegionsByLine ( regions , func - > fileName , line ) . size ( ) ;
if ( callF & & ! getAllRegionsByLine ( regions , func - > fileName , line ) . size ( ) )
callF - > callRegions . insert ( 0 ) ;
}
}
}
// move DEFAULT region (regionId == 0)
bool changes = true ;
while ( changes )
{
changes = false ;
for ( auto & nameFunc : funcMap )
{
auto func = nameFunc . second ;
if ( func - > callRegions . size ( ) > 1 & & func - > callRegions . find ( 0 ) ! = func - > callRegions . end ( ) )
{
for ( auto & call : func - > callsFrom )
{
auto callF = getFuncInfo ( funcMap , call ) ;
if ( callF & & callF - > callRegions . find ( 0 ) = = callF - > callRegions . end ( ) )
{
changes = true ;
callF - > callRegions . insert ( 0 ) ;
}
}
}
}
}
}
void fillRegionIntervals ( vector < ParallelRegion * > & regions )
{
if ( regions . size ( ) = = 1 & & regions [ 0 ] - > GetName ( ) = = " DEFAULT " ) // only default
return ;
for ( auto & region : regions )
{
for ( auto & fileLines : region - > GetAllLinesToModify ( ) )
{
// switch to current file
if ( SgFile : : switchToFile ( fileLines . first ) ! = - 1 )
{
for ( auto & lines : fileLines . second )
{
// explicit lines
if ( ! lines . isImplicit ( ) )
{
SgStatement * start = NULL ;
SgStatement * end = NULL ;
// try to find interval before explicit lines
end = lines . stats . first - > GetOriginal ( ) - > lexPrev ( ) - > lexPrev ( ) ; // before SPF_PARALLEL_REG_DIR
if ( end & & end - > variant ( ) = = DVM_ENDINTERVAL_DIR )
{
for ( auto st = end ; st ; st = st - > lexPrev ( ) )
{
if ( st - > variant ( ) = = DVM_INTERVAL_DIR )
{
start = st ;
Statement * intervalStart = new Statement ( start ) ;
Statement * intervalEnd = new Statement ( end ) ;
lines . intervalBefore = make_pair ( intervalStart , intervalEnd ) ;
break ;
}
}
}
// try to find interval after explicit lines
start = lines . stats . second - > GetOriginal ( ) - > lexNext ( ) - > lexNext ( ) ; // after SPF_END_PARALLEL_REG_DIR
if ( start & & start - > variant ( ) = = DVM_INTERVAL_DIR )
{
for ( auto st = start ; st ; st = st - > lexNext ( ) )
{
if ( st - > variant ( ) = = DVM_ENDINTERVAL_DIR )
{
end = st ;
Statement * intervalStart = new Statement ( start ) ;
Statement * intervalEnd = new Statement ( end ) ;
lines . intervalAfter = make_pair ( intervalStart , intervalEnd ) ;
break ;
}
}
}
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
}
bool checkRegions ( const vector < ParallelRegion * > & regions ,
const map < string , vector < FuncInfo * > > & allFuncInfo ,
map < string , vector < Messages > > & SPF_messages )
{
bool noError = true ;
// check if region includes itself
for ( auto & region : regions )
{
for ( auto & fileLines : region - > GetAllLines ( ) )
{
for ( auto & lines : fileLines . second )
{
if ( ! lines . isImplicit ( ) )
{
for ( auto & lines2 : fileLines . second )
{
if ( lines2 . isImplicit ( ) & & lines2 . lines . first < = lines . lines . first & & lines2 . lines . second > = lines . lines . second )
{
__spf_print ( 1 , " parallel region '%s' is included in file '%s' on line %d \n " , region - > GetName ( ) . c_str ( ) ,
fileLines . first . c_str ( ) , lines2 . lines . first ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " parallel region '%s' is included in file '%s' " ,
to_wstring ( region - > GetName ( ) ) . c_str ( ) , to_wstring ( fileLines . first ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R65 ,
to_wstring ( region - > GetName ( ) ) . c_str ( ) , to_wstring ( fileLines . first ) . c_str ( ) ) ;
getObjectForFileFromMap ( fileLines . first . c_str ( ) , SPF_messages ) . push_back ( Messages ( ERROR , lines2 . lines . first , messageR , messageE , 1033 ) ) ;
noError = false ;
}
}
}
}
}
}
// check if explicit region lines are included by another region
for ( auto & region : regions )
{
for ( auto & fileLines : region - > GetAllLines ( ) )
{
for ( auto & lines : fileLines . second )
{
if ( ! lines . isImplicit ( ) )
{
for ( auto line = lines . lines . first ; line < = lines . lines . second ; + + line )
{
auto inRegs = getAllRegionsByLine ( regions , fileLines . first , line ) ;
if ( inRegs . size ( ) > 1 )
{
__spf_print ( 1 , " parallel region '%s' has line included in another region on line %d \n " , region - > GetName ( ) . c_str ( ) , line ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " parallel region '%s' has line included in another region, try to run Region conflict resolving pass " , to_wstring ( region - > GetName ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R74 , to_wstring ( region - > GetName ( ) ) . c_str ( ) ) ;
getObjectForFileFromMap ( fileLines . first . c_str ( ) , SPF_messages ) . push_back ( Messages ( ERROR , line , messageR , messageE , 1041 ) ) ;
noError = false ;
}
}
}
}
}
}
// check if there are several entries in each fragment
map < string , FuncInfo * > funcMap ;
createMapOfFunc ( allFuncInfo , funcMap ) ;
for ( auto & region : regions )
{
for ( auto & fileLines : region - > GetAllLines ( ) )
{
if ( SgFile : : switchToFile ( fileLines . first ) ! = - 1 )
{
for ( auto & lines : fileLines . second )
{
if ( ! lines . isImplicit ( ) )
{
noError = noError & & checkRegionEntries ( lines . stats . first - > GetOriginal ( ) - > lexPrev ( ) , lines . stats . second - > GetOriginal ( ) - > lexNext ( ) , funcMap , regions , SPF_messages ) ;
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
return noError ;
}
static void recursiveReplace ( SgStatement * st , SgExpression * exp , const string & from , SgSymbol * to )
{
if ( exp )
{
if ( exp - > variant ( ) = = ARRAY_REF | | exp - > variant ( ) = = VAR_REF | | exp - > variant ( ) = = FUNC_CALL )
if ( exp - > symbol ( ) & & exp - > symbol ( ) - > identifier ( ) = = from )
exp - > setSymbol ( to ) ;
recursiveReplace ( st , exp - > lhs ( ) , from , to ) ;
recursiveReplace ( st , exp - > rhs ( ) , from , to ) ;
}
}
static void replaceSymbol ( const string & fileName , const ParallelRegionLines & lines , const string & origSymbName , SgSymbol * newSymb , bool replaceFunc = false )
{
if ( SgFile : : switchToFile ( fileName ) ! = - 1 )
{
// explicit lines
if ( ! lines . isImplicit ( ) )
{
SgStatement * iterator = lines . stats . first - > GetOriginal ( ) ;
SgStatement * end = lines . stats . second - > GetOriginal ( ) - > lexNext ( ) ;
for ( ; iterator ! = end ; iterator = iterator - > lexNext ( ) )
{
// skip not executable statements and change symbols only in executable section
if ( ! isSgExecutableStatement ( iterator ) & & ( iterator - > variant ( ) ! = VAR_DECL & & iterator - > variant ( ) ! = EXTERN_STAT ) )
continue ;
if ( iterator - > symbol ( ) & & iterator - > symbol ( ) - > identifier ( ) = = origSymbName )
iterator - > setSymbol ( * newSymb ) ;
for ( int i = 0 ; i < 3 ; + + i )
recursiveReplace ( iterator , iterator - > expr ( i ) , origSymbName , newSymb ) ;
if ( replaceFunc & & isSgExecutableStatement ( iterator ) )
break ;
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
static inline string getContains ( SgStatement * funcSt )
{
string containsName ;
SgStatement * st_cp = funcSt - > controlParent ( ) ;
if ( st_cp - > variant ( ) = = PROC_HEDR | | st_cp - > variant ( ) = = PROG_HEDR | | st_cp - > variant ( ) = = FUNC_HEDR )
containsName = st_cp - > symbol ( ) - > identifier ( ) + std : : string ( " . " ) ;
return containsName ;
}
static void recReplaceFuncCalls ( SgStatement * st , SgExpression * exp , const ParallelRegionLines & lines , const map < string , FuncInfo * > & funcMap , const uint64_t regionId )
{
if ( exp )
{
if ( exp - > variant ( ) = = FUNC_CALL )
{
SgStatement * externFuncSt = getFuncStat ( st ) ;
SgProcHedrStmt * procH = ( SgProcHedrStmt * ) externFuncSt ;
string contains = getContains ( procH ) ;
string funcName = exp - > symbol ( ) - > identifier ( ) ;
string fullFuncName = contains + funcName ;
FuncInfo * func = getFuncInfo ( funcMap , fullFuncName ) ;
if ( func )
{
string newFuncName = func - > getFuncNameByRegion ( funcName , regionId ) ;
SgSymbol * newSymb = new SgSymbol ( exp - > symbol ( ) - > variant ( ) ) ;
newSymb - > changeName ( newFuncName . c_str ( ) ) ;
exp - > setSymbol ( * newSymb ) ;
// for extern
replaceSymbol ( current_file - > filename ( ) , lines , funcName , newSymb , true ) ;
}
}
recReplaceFuncCalls ( st , exp - > rhs ( ) , lines , funcMap , regionId ) ;
recReplaceFuncCalls ( st , exp - > lhs ( ) , lines , funcMap , regionId ) ;
}
}
static void replaceFuncCalls ( const ParallelRegionLines & lines , const map < string , FuncInfo * > & funcMap , uint64_t regionId = 0 )
{
for ( auto st = lines . stats . first - > GetOriginal ( ) ;
st ! = lines . stats . second - > GetOriginal ( ) - > lexNext ( ) ;
st = st - > lexNext ( ) )
{
if ( st - > variant ( ) = = PROC_STAT )
{
SgStatement * externFuncSt = getFuncStat ( st ) ;
SgProcHedrStmt * procH = ( SgProcHedrStmt * ) externFuncSt ;
string contains = getContains ( procH ) ;
string funcName = st - > symbol ( ) - > identifier ( ) ;
string fullFuncName = contains + funcName ;
FuncInfo * func = getFuncInfo ( funcMap , fullFuncName ) ;
if ( func )
{
string newFuncName = func - > getFuncNameByRegion ( funcName , regionId ) ;
SgSymbol * newSymb = new SgSymbol ( st - > symbol ( ) - > variant ( ) ) ;
newSymb - > changeName ( newFuncName . c_str ( ) ) ;
st - > setSymbol ( * newSymb ) ;
}
}
for ( int i = 0 ; i < 3 ; + + i )
recReplaceFuncCalls ( st , st - > expr ( i ) , lines , funcMap , regionId ) ;
}
}
static map < string , map < DIST : : Array * , SgStatement * > > createdCommonBlocks ; // file -> array -> new common statement
static map < string , map < DIST : : Array * , pair < SgSymbol * , SgSymbol * > > > createdCommonArrays ; // file -> array -> (orig, copy)
static SgStatement * createCommonBlock ( SgFile * file , DIST : : Array * array )
{
auto varsOnPos = getArraySynonyms ( array ) ;
if ( ! varsOnPos . size ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
string fileName = file - > filename ( ) ;
if ( SgFile : : switchToFile ( fileName ) ! = - 1 )
{
auto fileArrayBlock = createdCommonBlocks . find ( fileName ) ;
if ( fileArrayBlock = = createdCommonBlocks . end ( ) )
fileArrayBlock = createdCommonBlocks . insert ( fileArrayBlock , make_pair ( fileName , map < DIST : : Array * , SgStatement * > ( ) ) ) ;
auto arrayBlock = fileArrayBlock - > second . find ( array ) ;
if ( arrayBlock = = fileArrayBlock - > second . end ( ) )
{
// new common-block is not created for array at this file, so create it
// creating new common-block statement
//TODO: consistence with declaration
//string commBlockName = checkSymbNameAndCorrect(array->GetShortName() + "_r");
string commBlockName = array - > GetShortName ( ) + " _r " ;
SgStatement * commDecl = new SgStatement ( COMM_STAT ) ;
SgSymbol * commSymb = new SgSymbol ( VARIABLE_NAME , commBlockName . c_str ( ) ) ;
SgExprListExp * commList = new SgExprListExp ( COMM_LIST ) ;
SgExprListExp * curNode = NULL ;
commDecl - > setExpression ( 0 , * commList ) ;
commList - > setSymbol ( commSymb ) ;
// need to add
// check if need to create new common array symbol
SgSymbol * newArrSymb = NULL ;
auto it = createdCommonArrays . find ( fileName ) ;
if ( it = = createdCommonArrays . end ( ) )
it = createdCommonArrays . insert ( it , make_pair ( fileName , map < DIST : : Array * , pair < SgSymbol * , SgSymbol * > > ( ) ) ) ;
auto itt = it - > second . find ( array ) ;
if ( itt = = it - > second . end ( ) ) // need to create symbol
{
//TODO: consistence with declaration
//string newArrName = checkSymbNameAndCorrect(varsOnPos[0]->getName() + "_c");
string newArrName = varsOnPos [ 0 ] - > getName ( ) + " _c " ;
newArrSymb = new SgSymbol ( VARIABLE_NAME , newArrName . c_str ( ) , file - > firstStatement ( ) ) ;
SgType * type = new SgType ( T_ARRAY ) ;
newArrSymb - > setType ( type ) ;
itt = it - > second . insert ( itt , make_pair ( array , make_pair ( ( SgSymbol * ) NULL , newArrSymb ) ) ) ;
}
else
// just use previous created symbol
newArrSymb = itt - > second . second ;
checkNull ( newArrSymb , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
// inserting newArrSymb to COMM_STAT
if ( ! curNode )
{
curNode = new SgExprListExp ( ) ;
commList - > setLhs ( curNode ) ;
}
else
{
SgExprListExp * newNode = new SgExprListExp ( ) ;
curNode - > setRhs ( newNode ) ;
curNode = ( SgExprListExp * ) curNode - > rhs ( ) ;
}
SgExpression * arrNode = new SgExpression ( VAR_REF , NULL , NULL , newArrSymb ) ;
curNode - > setLhs ( arrNode ) ;
fileArrayBlock - > second . insert ( make_pair ( array , commDecl ) ) ;
return commDecl ;
}
return arrayBlock - > second ;
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
return NULL ;
}
// func -> arrays; funcs where new common statement inserted
static map < FuncInfo * , set < DIST : : Array * > > insertedCommonBlocks ;
static void insertCommonBlock ( FuncInfo * func , DIST : : Array * array )
{
SgFile * file = func - > funcPointer - > GetOriginal ( ) - > getFile ( ) ;
SgStatement * insertPlace = NULL ;
for ( auto iterator = func - > funcPointer - > GetOriginal ( ) - > lexNext ( ) ;
! isSgExecutableStatement ( iterator ) | | isSPF_stat ( iterator ) & & ! isSPF_reg ( iterator ) ;
iterator = iterator - > lexNext ( ) )
{
insertPlace = iterator ;
}
//NULL - no decl stats in function!
if ( ! insertPlace )
insertPlace = func - > funcPointer - > GetOriginal ( ) ;
SgStatement * commDecl = createCommonBlock ( file , array ) ;
SgStatement * copyDecl = commDecl - > copyPtr ( ) ;
auto st = insertPlace - > controlParent ( ) ;
if ( st - > variant ( ) = = GLOBAL )
st = insertPlace ;
const int nextLine = insertPlace - > lexNext ( ) - > lineNumber ( ) ;
insertPlace - > insertStmtAfter ( * copyDecl , * st ) ;
insertPlace - > lexNext ( ) - > setlineNumber ( nextLine ) ;
// create declaration via comment
insertStringDeclarations ( insertPlace - > lexNext ( ) , array ) ;
}
// file -> lines -> arrays; lines where arrays copying is inserted
static map < string , map < ParallelRegionLines , set < string > > > copiedArrays ;
static void insertArrayCopying ( const string & fileName , const ParallelRegionLines & regionLines , SgSymbol * origSymb , SgSymbol * newSymb )
{
if ( SgFile : : switchToFile ( fileName ) ! = - 1 )
{
if ( regionLines . isImplicit ( ) )
return ;
auto it = copiedArrays . find ( fileName ) ;
if ( it = = copiedArrays . end ( ) )
it = copiedArrays . insert ( it , make_pair ( fileName , map < ParallelRegionLines , set < string > > ( ) ) ) ;
auto it2 = it - > second . find ( regionLines ) ;
if ( it2 = = it - > second . end ( ) )
it2 = it - > second . insert ( it2 , make_pair ( regionLines , set < string > ( ) ) ) ;
const string arrName = origSymb - > identifier ( ) ;
auto it3 = it2 - > second . find ( arrName ) ;
if ( it3 = = it2 - > second . end ( ) )
{
// A_reg = A
SgAssignStmt * assign = new SgAssignStmt ( * new SgArrayRefExp ( * newSymb ) , * new SgArrayRefExp ( * origSymb ) ) ;
assign - > setlineNumber ( getNextNegativeLineNumber ( ) ) ; // before region
regionLines . stats . first - > GetOriginal ( ) - > lexPrev ( ) - > insertStmtBefore ( * assign , * regionLines . stats . first - > GetOriginal ( ) - > controlParent ( ) ) ;
// A = A_reg
assign = new SgAssignStmt ( * new SgArrayRefExp ( * origSymb ) , * new SgArrayRefExp ( * newSymb ) ) ;
//TODO: bug with insertion
//assign->setlineNumber(getNextNegativeLineNumber()); // after region
regionLines . stats . second - > GetOriginal ( ) - > lexNext ( ) - > insertStmtAfter ( * assign , * regionLines . stats . first - > GetOriginal ( ) - > controlParent ( ) ) ;
it2 - > second . insert ( arrName ) ;
// TODO: SPF_ANALYSIS(decl)
if ( ( origSymb - > attributes ( ) & IN_BIT ) | | ( origSymb - > attributes ( ) & OUT_BIT ) )
{
auto func = getFuncStat ( regionLines . stats . first - > GetOriginal ( ) ) ;
auto fromIntent = fillFromIntent ( func ) ;
//TODO:
if ( fromIntent . size ( ) )
{
for ( auto & elem : fromIntent )
{
string ident = origSymb - > identifier ( ) ;
if ( elem . second . find ( ident ) ! = elem . second . end ( ) )
{
if ( elem . first - > variant ( ) = = INTENT_STMT )
{
SgIntentStmt * stat = ( SgIntentStmt * ) elem . first ;
if ( stat - > numberOfArgs ( ) = = 1 )
stat - > deleteStmt ( ) ;
else
{
SgExpression * par = NULL ;
SgExpression * ex = stat - > expr ( 0 ) ;
while ( ex )
{
if ( ex - > lhs ( ) - > symbol ( ) - > identifier ( ) = = ident )
{
if ( par )
par - > setRhs ( ex - > rhs ( ) ) ;
else
stat - > setExpression ( 0 , ex - > rhs ( ) ) ;
break ;
}
par = ex ;
ex = ex - > rhs ( ) ;
}
}
}
}
}
}
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
// return true if error exists
static bool replaceCommonArray ( const string & fileName ,
const set < string > & arraySynonymNames ,
const ParallelRegionLines & lines ,
map < string , vector < Messages > > & SPF_messages ,
const bool needInsertCopying = false )
{
auto it = createdCommonArrays . find ( fileName ) ;
if ( it = = createdCommonArrays . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SgStatement * begin = getFuncStat ( lines . stats . first - > GetOriginal ( ) ) ;
SgStatement * end = begin - > lastNodeOfStmt ( ) ;
if ( begin - > symbol ( ) = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
const string fName = begin - > symbol ( ) - > identifier ( ) ;
// get common-blocks ref
DIST : : Array * array = NULL ;
map < string , vector < SgExpression * > > commonBlocksRef ;
getCommonBlocksRef ( commonBlocksRef , begin , end ) ;
for ( auto & commonBlockRef : commonBlocksRef )
{
for ( auto & commExp : commonBlockRef . second )
{
for ( auto exp = commExp - > lhs ( ) ; exp ; exp = exp - > rhs ( ) )
{
SgSymbol * varSymb = exp - > lhs ( ) - > symbol ( ) ;
string varName = varSymb - > identifier ( ) ;
if ( arraySynonymNames . find ( varName ) ! = arraySynonymNames . end ( ) )
{
array = getArrayFromDeclarated ( declaratedInStmt ( varSymb ) , varName ) ;
if ( array )
{
auto varsOnPos = getArraySynonyms ( array ) ;
if ( ! varsOnPos . size ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
auto var = varsOnPos [ 0 ] ;
if ( SgFile : : switchToFile ( var - > getSymbol ( ) - > getFile ( ) - > filename ( ) ) ! = - 1 )
{
DIST : : Array * commArr = getArrayFromDeclarated ( declaratedInStmt ( var - > getSymbol ( ) ) , var - > getName ( ) ) ;
checkNull ( commArr , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
auto itt = it - > second . find ( commArr ) ;
if ( itt = = it - > second . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
replaceSymbol ( fileName , lines , varName , itt - > second . second ) ;
if ( needInsertCopying )
insertArrayCopying ( fileName , lines , varSymb , itt - > second . second ) ;
// no error
return false ;
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
}
}
}
if ( ! array )
{
string toPrint ;
for ( auto & arrayName : arraySynonymNames )
toPrint + = " ' " + arrayName + ' \' ' ;
__spf_print ( 1 , " wrong parallel region position, there is no common-block in current function '%s' with any of such arrays:%s on line %d \n " ,
fName . c_str ( ) , toPrint . c_str ( ) , lines . lines . first ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " wrong parallel region position, there is no common-block in current function '%s' with any of such arrays:%s " ,
to_wstring ( fName ) . c_str ( ) , to_wstring ( toPrint ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R66 , to_wstring ( fName ) . c_str ( ) , to_wstring ( toPrint ) . c_str ( ) ) ;
getObjectForFileFromMap ( fileName . c_str ( ) , SPF_messages ) . push_back ( Messages ( ERROR , lines . lines . first , messageR , messageE , 1034 ) ) ;
// error
return true ;
}
// no error
return false ;
}
2024-10-16 23:27:40 +03:00
pair < SgSymbol * , SgSymbol * > copyArray ( const pair < string , int > & place ,
const DIST : : Array * array ,
const vector < ParallelRegionLines > & lines ,
const string & suffix ,
string & filename ,
map < string , map < int , set < string > > > & newDeclsToInclude ,
map < string , map < int , set < string > > > & copied )
2023-09-14 19:43:13 +03:00
{
string fileName = place . first ;
int switchRes = SgFile : : switchToFile ( fileName ) ;
bool isIncludeFile = false ;
if ( switchRes = = - 1 )
{
isIncludeFile = true ;
set < string > files ;
for ( auto & elem : lines )
{
if ( elem . stats . first )
files . insert ( elem . stats . first - > fileName ( ) ) ;
else if ( elem . stats . second )
files . insert ( elem . stats . second - > fileName ( ) ) ;
}
if ( files . size ( ) ! = 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
else
{
switchRes = SgFile : : switchToFile ( * files . begin ( ) ) ;
if ( switchRes ! = - 1 )
filename = * files . begin ( ) ;
}
}
if ( switchRes ! = - 1 )
{
//TODO: consistence with declaration
//string newArrName = checkSymbNameAndCorrect(array->GetShortName() + suffix);
string newArrName = array - > GetShortName ( ) + suffix ;
SgStatement * decl = SgStatement : : getStatementByFileAndLine ( place . first , place . second ) ;
checkNull ( decl , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SgStatement * func = getFuncStat ( decl , { MODULE_STMT } ) ;
const auto range = make_pair ( func - > lineNumber ( ) , func - > lastNodeOfStmt ( ) - > lineNumber ( ) ) ;
SgSymbol * arrSymb = array - > GetDeclSymbol ( fileName , range , getAllFilesInProject ( ) ) - > GetOriginal ( ) ;
SgSymbol * newArrSymb = NULL ;
SgStatement * newDecl = NULL ;
// for what? to skip .h stats?
if ( decl - > fileName ( ) ! = fileName )
{
while ( ! isSgExecutableStatement ( decl ) | | isSPF_stat ( decl ) & & ! isSPF_reg ( decl ) )
decl = decl - > lexNext ( ) ;
decl = decl - > lexPrev ( ) ;
}
newArrSymb = & arrSymb - > copy ( ) ;
newArrSymb - > changeName ( newArrName . c_str ( ) ) ;
newDecl = makeDeclaration ( NULL , { newArrSymb } ) ;
if ( IS_ALLOCATABLE ( arrSymb ) )
{
newArrSymb - > setAttribute ( newArrSymb - > attributes ( ) | ALLOCATABLE_BIT ) ;
if ( ( ( SgVarDeclStmt * ) newDecl ) - > addAttributeExpression ( new SgExpression ( ALLOCATABLE_OP ) ) = = false )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
// add allocate/deallocate operators
for ( auto & data : getAttributes < SgStatement * , SgStatement * > ( decl , set < int > { ALLOCATE_STMT , DEALLOCATE_STMT } ) )
{
SgExpression * list = data - > expr ( 0 ) ;
set < string > allocated ;
while ( list )
{
SgArrayRefExp * arrayRef = isSgArrayRefExp ( list - > lhs ( ) ) ;
if ( arrayRef ! = NULL )
allocated . insert ( string ( OriginalSymbol ( arrayRef - > symbol ( ) ) - > identifier ( ) ) ) ;
list = list - > rhs ( ) ;
}
list = data - > expr ( 0 ) ;
while ( list )
{
SgArrayRefExp * arrayRef = isSgArrayRefExp ( list - > lhs ( ) ) ;
if ( arrayRef ! = NULL )
{
if ( string ( OriginalSymbol ( arrayRef - > symbol ( ) ) - > identifier ( ) ) = = arrSymb - > identifier ( ) & &
allocated . find ( newArrSymb - > identifier ( ) ) = = allocated . end ( ) )
{
// add parameter to allocate() operator
if ( data - > variant ( ) = = ALLOCATE_STMT )
{
while ( list - > rhs ( ) )
list = list - > rhs ( ) ;
auto copy = arrayRef - > copyPtr ( ) ;
copy - > setSymbol ( newArrSymb ) ;
list - > setRhs ( new SgExpression ( EXPR_LIST , copy ) ) ;
}
// add parameter to deallocate() operator
else if ( data - > variant ( ) = = DEALLOCATE_STMT )
{
SgExprListExp * newNode = new SgExprListExp ( ) ;
newNode - > setLhs ( new SgArrayRefExp ( * newArrSymb ) ) ;
newNode - > setRhs ( data - > expr ( 0 ) ) ;
data - > setExpression ( 0 , * newNode ) ;
}
break ;
}
}
list = list - > rhs ( ) ;
}
}
}
if ( ! isIncludeFile )
{
if ( ! ( copied . count ( decl - > fileName ( ) ) & &
copied [ decl - > fileName ( ) ] . count ( decl - > lineNumber ( ) ) & &
copied [ decl - > fileName ( ) ] [ decl - > lineNumber ( ) ] . count ( newDecl - > unparse ( ) ) ) )
{
decl - > insertStmtAfter ( * newDecl , * decl - > controlParent ( ) ) ;
copied [ decl - > fileName ( ) ] [ decl - > lineNumber ( ) ] . insert ( newDecl - > unparse ( ) ) ;
}
}
else
newDeclsToInclude [ decl - > fileName ( ) ] [ decl - > lineNumber ( ) ] . insert ( newDecl - > unparse ( ) ) ;
return make_pair ( arrSymb , newArrSymb ) ;
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
static void copyFunction ( ParallelRegion * region ,
FuncInfo * func ,
const map < string , FuncInfo * > & funcMap ,
const string & suffix = " " )
{
if ( SgFile : : switchToFile ( func - > fileName ) ! = - 1 )
{
SgStatement * funcStat = func - > funcPointer - > GetOriginal ( ) ;
SgStatement * newFuncStat = NULL ;
SgSymbol * funcSymb = func - > funcPointer - > GetOriginal ( ) - > symbol ( ) ;
SgSymbol * newFuncSymb = NULL ;
SgFile * file = func - > funcPointer - > GetOriginal ( ) - > getFile ( ) ;
string newFuncName = string ( funcSymb - > identifier ( ) ) + suffix ;
// create copy function symbol and copy function for original function
SgStatement * copyFunc = duplicateProcedure ( funcStat , & newFuncName , false , false , false ) ;
newFuncSymb = copyFunc - > symbol ( ) ;
if ( SgFile : : switchToFile ( func - > fileName ) = = - 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
// set line numbers
for ( auto origStat = funcStat , copyStat = copyFunc ;
origStat ! = funcStat - > lastNodeOfStmt ( ) - > lexNext ( ) ;
origStat = origStat - > lexNext ( ) , copyStat = copyStat - > lexNext ( ) )
{
if ( copyStat - > variant ( ) ! = origStat - > variant ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
copyStat - > setlineNumber ( origStat - > lineNumber ( ) ) ;
BIF_FILE_NAME ( copyStat - > thebif ) = BIF_FILE_NAME ( origStat - > thebif ) ;
}
// replace all func calls in copy function
Statement * begin = new Statement ( copyFunc ) ;
Statement * end = new Statement ( copyFunc - > lastNodeOfStmt ( ) ) ;
pair < Statement * , Statement * > beginEnd = make_pair ( begin , end ) ;
pair < int , int > newLines = make_pair ( beginEnd . first - > lineNumber ( ) , beginEnd . second - > lineNumber ( ) ) ;
ParallelRegionLines newFuncLines ( newLines , beginEnd ) ;
replaceFuncCalls ( newFuncLines , funcMap , region - > GetId ( ) ) ;
if ( funcStat - > variant ( ) = = FUNC_HEDR )
replaceSymbol ( current_file - > filename ( ) , newFuncLines , func - > funcName , newFuncSymb ) ;
// try to find common-block and add new if common-block exists
for ( auto origStat = funcStat , copyStat = copyFunc ;
origStat & & ( ! isSgExecutableStatement ( origStat ) | | isSPF_stat ( origStat ) ) ;
origStat = origStat - > lexNext ( ) , copyStat = copyStat - > lexNext ( ) )
{
if ( origStat - > variant ( ) = = COMM_STAT )
{
for ( auto & arrayBlock : allUsedCommonArrays )
createCommonBlock ( file , arrayBlock . first ) ;
auto usedCommonArrays = region - > GetUsedCommonArrays ( ) . find ( func ) ;
if ( usedCommonArrays ! = region - > GetUsedCommonArrays ( ) . end ( ) )
{
for ( auto & arrayLines : usedCommonArrays - > second )
{
SgStatement * commDecl = createCommonBlock ( file , arrayLines . first ) ;
SgStatement * copyDecl = commDecl - > copyPtr ( ) ;
while ( ! isSgExecutableStatement ( copyStat ) | | isSPF_stat ( copyStat ) )
copyStat = copyStat - > lexNext ( ) ;
copyStat = copyStat - > lexPrev ( ) ;
copyStat - > insertStmtAfter ( * copyDecl , * copyStat - > controlParent ( ) ) ;
// making declaration of new common array symbol via comment through files
insertStringDeclarations ( copyStat - > lexNext ( ) , arrayLines . first ) ;
}
auto it = createdCommonArrays . find ( file - > filename ( ) ) ;
if ( it = = createdCommonArrays . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
// replace common arrays to new common arrays in executable code section
SgStatement * iterator = begin - > GetOriginal ( ) ;
for ( ; iterator ! = end - > GetOriginal ( ) & & ( ! isSgExecutableStatement ( iterator ) | | isSPF_stat ( iterator ) ) ; iterator = iterator - > lexNext ( ) )
;
Statement * start = new Statement ( iterator ) ;
ParallelRegionLines lines ( make_pair ( start - > lineNumber ( ) , end - > lineNumber ( ) ) , make_pair ( start , end ) ) ;
// get common-blocks ref
map < string , vector < SgExpression * > > commonBlocksRef ;
getCommonBlocksRef ( commonBlocksRef , func - > funcPointer - > GetOriginal ( ) , func - > funcPointer - > GetOriginal ( ) - > lastNodeOfStmt ( ) ) ;
for ( auto & commonBlockRef : commonBlocksRef )
{
for ( auto & commExp : commonBlockRef . second )
{
for ( auto exp = commExp - > lhs ( ) ; exp ; exp = exp - > rhs ( ) )
{
SgSymbol * varSymb = exp - > lhs ( ) - > symbol ( ) ;
string varName = varSymb - > identifier ( ) ;
DIST : : Array * array = getArrayFromDeclarated ( declaratedInStmt ( varSymb ) , varName ) ;
if ( array & & ! array - > IsNotDistribute ( ) )
{
auto varsOnPos = getArraySynonyms ( array ) ;
if ( ! varsOnPos . size ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
auto var = varsOnPos [ 0 ] ;
if ( SgFile : : switchToFile ( var - > getSymbol ( ) - > getFile ( ) - > filename ( ) ) ! = - 1 )
{
DIST : : Array * commArr = getArrayFromDeclarated ( declaratedInStmt ( var - > getSymbol ( ) ) , var - > getName ( ) ) ;
checkNull ( commArr , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
auto itt = it - > second . find ( commArr ) ;
if ( itt = = it - > second . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
replaceSymbol ( func - > fileName , lines , varName , itt - > second . second ) ;
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
}
}
}
break ;
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
void fillUsedArraysInExp ( const pair < Statement * , Statement * > & interval , const int exp , set < DIST : : Array * > & varSet )
{
if ( exp > 2 | | exp < 0 )
return ;
for ( auto st = interval . first - > GetOriginal ( ) - > lexNext ( ) ; st ! = interval . second - > GetOriginal ( ) ; st = st - > lexNext ( ) )
{
// after CONVERT_ASSIGN_TO_LOOP
if ( st - > variant ( ) = = ASSIGN_STAT )
{
auto varSymb = st - > expr ( exp ) - > symbol ( ) ;
checkNull ( varSymb , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
auto array = getArrayFromDeclarated ( declaratedInStmt ( varSymb ) , varSymb - > identifier ( ) ) ;
checkNull ( array , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
varSet . insert ( array ) ;
}
}
}
bool checkRegionsResolving ( const vector < ParallelRegion * > & regions ,
const map < string , vector < FuncInfo * > > & allFuncInfo ,
const map < string , CommonBlock * > & commonBlocks ,
2024-06-19 18:08:27 +03:00
map < string , vector < Messages > > & SPF_messages , bool sharedMemoryParallelization )
2023-09-14 19:43:13 +03:00
{
bool error = false ;
if ( regions . size ( ) )
{
map < string , FuncInfo * > funcMap ;
createMapOfFunc ( allFuncInfo , funcMap ) ;
// check functions
for ( auto & nameFunc : funcMap )
{
auto func = nameFunc . second ;
if ( func - > callRegions . size ( ) > 1 )
{
string outText = " " ;
for ( auto & regId : func - > callRegions )
{
auto reg = getRegionById ( regions , regId ) ;
if ( ! reg & & regId )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( regId )
outText + = " ' " + reg - > GetName ( ) + " ' " ;
else
outText + = " 'DEFAULT' " ;
}
__spf_print ( 1 , " parallel regions %shave common function '%s' which is used inside them \n " , outText . c_str ( ) , nameFunc . first . c_str ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " parallel regions %shave common function '%s' which is used inside them " ,
to_wstring ( outText ) . c_str ( ) , to_wstring ( nameFunc . first ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R133 , to_wstring ( outText ) . c_str ( ) , to_wstring ( nameFunc . first ) . c_str ( ) ) ;
ParallelRegion * reg = NULL ;
for ( auto & regId : func - > callRegions )
{
if ( regId )
{
reg = getRegionById ( regions , regId ) ;
break ;
}
}
if ( ! reg )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
auto lines = reg - > GetAllLines ( ) ;
bool ok = false ;
for ( auto & linePair : lines )
{
for ( auto & line : linePair . second )
{
if ( line . stats . first & & line . stats . second )
{
getObjectForFileFromMap ( linePair . first . c_str ( ) , SPF_messages ) . push_back ( Messages ( ERROR , getRegionExplicitLine ( line . stats . first ) , messageR , messageE , 3012 ) ) ;
error = true ;
ok = true ;
break ;
}
}
if ( ok )
break ;
}
if ( ok = = false )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
2024-06-19 18:08:27 +03:00
if ( sharedMemoryParallelization )
2023-09-14 19:43:13 +03:00
return error ;
// check local arrays
for ( auto & reg : regions )
{
for ( auto & funcArrays : reg - > GetUsedLocalArrays ( ) )
{
if ( SgFile : : switchToFile ( funcArrays . first - > fileName ) ! = - 1 )
{
for ( auto & arrayLines : funcArrays . second )
{
auto regsByArr = arrayLines . first - > GetRegionsName ( ) ;
bool notResolved = false ;
if ( regsByArr . size ( ) > 1 )
{
// check if array is used only in region and its related interval
if ( regsByArr . size ( ) = = 2 & & regsByArr . find ( " default " ) ! = regsByArr . end ( ) )
{
auto array = arrayLines . first ;
for ( auto & line : array - > GetUsagePlaces ( funcArrays . first - > fileName , & funcArrays . first - > linesNum ) )
{
auto inRegs = getAllRegionsByLine ( regions , funcArrays . first - > fileName , line ) ;
if ( ! inRegs . size ( ) )
{
bool inInterval = false ;
for ( auto & regLines : arrayLines . second )
{
// check interval existing
if ( regLines . intervalBefore . first & & regLines . intervalBefore . second & & regLines . intervalAfter . first & & regLines . intervalAfter . second )
{
if ( line > regLines . intervalBefore . first - > lineNumber ( ) & & line < regLines . intervalAfter . second - > lineNumber ( ) )
inInterval = true ;
}
}
if ( ! inInterval )
notResolved = true ;
}
}
}
else
notResolved = true ;
}
if ( notResolved )
{
string regions = " " ;
for ( auto & reg : regsByArr )
regions + = " ' " + reg + " ' " ;
__spf_print ( 1 , " parallel regions %shave local array '%s' which is used inside them \n " ,
regions . c_str ( ) , arrayLines . first - > GetShortName ( ) . c_str ( ) ) ;
wstring messageE , messageR ;
if ( arrayLines . first - > GetLocation ( ) . first = = DIST : : l_MODULE )
__spf_printToLongBuf ( messageE , L " parallel regions %shave module array '%s' which is used inside them, try to run Region conflict resolving pass " ,
to_wstring ( regions ) . c_str ( ) , to_wstring ( arrayLines . first - > GetShortName ( ) ) . c_str ( ) ) ;
else
__spf_printToLongBuf ( messageE , L " parallel regions %shave local array '%s' which is used inside them, try to run Region conflict resolving pass " ,
to_wstring ( regions ) . c_str ( ) , to_wstring ( arrayLines . first - > GetShortName ( ) ) . c_str ( ) ) ;
if ( arrayLines . first - > GetLocation ( ) . first = = DIST : : l_MODULE )
__spf_printToLongBuf ( messageR , R152 , to_wstring ( regions ) . c_str ( ) , to_wstring ( arrayLines . first - > GetShortName ( ) ) . c_str ( ) ) ;
else
__spf_printToLongBuf ( messageR , R134 , to_wstring ( regions ) . c_str ( ) , to_wstring ( arrayLines . first - > GetShortName ( ) ) . c_str ( ) ) ;
auto lines = reg - > GetAllLines ( ) ;
bool ok = false ;
for ( auto & linePair : lines )
{
for ( auto & line : linePair . second )
{
if ( line . stats . first & & line . stats . second )
{
getObjectForFileFromMap ( linePair . first . c_str ( ) , SPF_messages ) . push_back ( Messages ( ERROR , getRegionExplicitLine ( line . stats . first ) , messageR , messageE , 3013 ) ) ;
error = true ;
ok = true ;
break ;
}
}
if ( ok )
break ;
}
if ( ok = = false )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
// check common arrays
for ( auto & reg : regions )
{
for ( auto & funcArrays : reg - > GetUsedCommonArrays ( ) )
{
for ( auto & arrayLines : funcArrays . second )
{
auto commonBlock = isArrayInCommon ( commonBlocks , arrayLines . first ) ;
checkNull ( commonBlock , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( ! arrayLines . second . size ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
// check common block name and variables count
auto lines = arrayLines . second [ 0 ] . lines ;
string commonBlockName = commonBlock - > getName ( ) ;
auto pos = commonBlockName . rfind ( " _r " ) ;
if ( ! arrayLines . second [ 0 ] . isImplicit ( ) & & ( pos ! = commonBlockName . length ( ) - 2 | | commonBlock - > getVariables ( ) . size ( ) ! = 1 ) )
{
__spf_print ( 1 , " parallel region '%s' has common array '%s' which is used inside and outside region on lines %d-%d \n " ,
reg - > GetName ( ) . c_str ( ) , arrayLines . first - > GetShortName ( ) . c_str ( ) , lines . first , lines . second ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " parallel region '%s' has common array '%s' which is used inside and outside region, try to run Region conflict resolving pass " ,
to_wstring ( reg - > GetName ( ) ) . c_str ( ) , to_wstring ( arrayLines . first - > GetShortName ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R135 , to_wstring ( reg - > GetName ( ) ) . c_str ( ) , to_wstring ( arrayLines . first - > GetShortName ( ) ) . c_str ( ) ) ;
getObjectForFileFromMap ( funcArrays . first - > fileName . c_str ( ) , SPF_messages ) . push_back ( Messages ( ERROR , getRegionExplicitLine ( arrayLines . second [ 0 ] . stats . first ) , messageR , messageE , 3014 ) ) ;
error = true ;
}
}
}
}
// check intervals and arrays copying
for ( auto & reg : regions )
{
for ( auto & fileLines : reg - > GetAllLines ( ) )
{
if ( SgFile : : switchToFile ( fileLines . first ) ! = - 1 )
{
// check array copying existing
for ( auto & lines : fileLines . second )
{
if ( ! lines . isImplicit ( ) )
{
// check interval existing
if ( ! lines . intervalBefore . first | | ! lines . intervalBefore . second | | ! lines . intervalAfter . first | | ! lines . intervalAfter . second )
{
__spf_print ( 1 , " parallel region '%s' does not have DVM interval for fragment on line %d \n " ,
reg - > GetName ( ) . c_str ( ) , lines . lines . first ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " parallel region '%s' does not have DVM interval for fragment, try to run Region conflict resolving pass " , to_wstring ( reg - > GetName ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R136 , to_wstring ( reg - > GetName ( ) ) . c_str ( ) ) ;
getObjectForFileFromMap ( fileLines . first . c_str ( ) , SPF_messages ) . push_back ( Messages ( ERROR , getRegionExplicitLine ( lines . stats . first ) , messageR , messageE , 3015 ) ) ;
error = true ;
}
// check arrays
else
{
set < DIST : : Array * > leftBefore ;
set < DIST : : Array * > rightAfter ;
fillUsedArraysInExp ( lines . intervalBefore , 0 , leftBefore ) ;
fillUsedArraysInExp ( lines . intervalAfter , 1 , rightAfter ) ;
// check left and right sets if common array is used at this lines
for ( auto funcArrays : reg - > GetUsedCommonArrays ( ) )
{
if ( funcArrays . first - > fileName = = fileLines . first )
{
for ( auto & arrayLines : funcArrays . second )
{
for ( auto & lines2 : arrayLines . second )
{
if ( lines = = lines2 )
{
if ( leftBefore . find ( arrayLines . first ) = = leftBefore . end ( ) | | rightAfter . find ( arrayLines . first ) = = rightAfter . end ( ) )
{
__spf_print ( 1 , " parallel region '%s' does not have copying of array '%s' in DVM interval on line %d \n " ,
reg - > GetName ( ) . c_str ( ) , arrayLines . first - > GetShortName ( ) . c_str ( ) , lines . lines . first ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " parallel region '%s' does not have copying of array '%s' in DVM interval, try to run Region conflict resolving pass " ,
to_wstring ( reg - > GetName ( ) ) . c_str ( ) , to_wstring ( arrayLines . first - > GetShortName ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R139 , to_wstring ( reg - > GetName ( ) ) . c_str ( ) , to_wstring ( arrayLines . first - > GetShortName ( ) ) . c_str ( ) ) ;
getObjectForFileFromMap ( fileLines . first . c_str ( ) , SPF_messages ) . push_back ( Messages ( ERROR , lines . lines . first , messageR , messageE , 3018 ) ) ;
error = true ;
}
}
}
}
}
}
// check left and right sets if local array is used at this lines
for ( auto funcArrays : reg - > GetUsedLocalArrays ( ) )
{
if ( funcArrays . first - > fileName = = fileLines . first )
{
for ( auto & arrayLines : funcArrays . second )
{
for ( auto & lines2 : arrayLines . second )
{
if ( lines = = lines2 )
{
if ( leftBefore . find ( arrayLines . first ) = = leftBefore . end ( ) | | rightAfter . find ( arrayLines . first ) = = rightAfter . end ( ) )
{
__spf_print ( 1 , " parallel region '%s' does not have copying of array '%s' in DVM interval on line %d \n " ,
reg - > GetName ( ) . c_str ( ) , arrayLines . first - > GetShortName ( ) . c_str ( ) , lines . lines . first ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " parallel region '%s' does not have copying of array '%s' in DVM interval, try to run Region conflict resolving pass " ,
to_wstring ( reg - > GetName ( ) ) . c_str ( ) , to_wstring ( arrayLines . first - > GetShortName ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R138 , to_wstring ( reg - > GetName ( ) ) . c_str ( ) , to_wstring ( arrayLines . first - > GetShortName ( ) ) . c_str ( ) ) ;
getObjectForFileFromMap ( fileLines . first . c_str ( ) , SPF_messages ) . push_back ( Messages ( ERROR , lines . lines . first , messageR , messageE , 3017 ) ) ;
error = true ;
}
}
}
}
}
}
}
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
}
return error ;
}
//check: A = B
static bool isArrayAssign ( SgStatement * st )
{
if ( st - > variant ( ) ! = ASSIGN_STAT )
return false ;
if ( st - > expr ( 0 ) - > variant ( ) ! = ARRAY_REF )
return false ;
if ( st - > expr ( 1 ) - > variant ( ) ! = ARRAY_REF )
return false ;
if ( st - > expr ( 0 ) - > lhs ( ) ! = NULL | | st - > expr ( 0 ) - > rhs ( ) ! = NULL )
return false ;
if ( st - > expr ( 1 ) - > lhs ( ) ! = NULL | | st - > expr ( 1 ) - > rhs ( ) ! = NULL )
return false ;
return true ;
}
static void compliteUseOnlyList ( SgStatement * func , const string & location , const string & s )
{
if ( isSgProgHedrStmt ( func ) = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
for ( SgStatement * st = func - > lexNext ( ) ; st ; st = st - > lexNext ( ) )
{
if ( isSgExecutableStatement ( st ) )
break ;
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
if ( st - > variant ( ) = = USE_STMT )
{
if ( st - > symbol ( ) - > identifier ( ) = = location )
{
SgExpression * ex = st - > expr ( 0 ) ;
if ( ex & & ex - > variant ( ) = = ONLY_NODE )
{
SgExpression * toInsert = new SgExpression ( RENAME_NODE ) ;
SgExpression * list = new SgExpression ( EXPR_LIST ) ;
toInsert - > setLhs ( new SgVarRefExp ( findSymbolOrCreate ( st - > getFile ( ) , s ) ) ) ;
list - > setRhs ( ex - > lhs ( ) ) ;
list - > setLhs ( toInsert ) ;
ex - > setLhs ( list ) ;
}
}
}
}
}
int resolveParRegions ( vector < ParallelRegion * > & regions , const map < string , vector < FuncInfo * > > & allFuncInfo ,
2024-06-19 18:08:27 +03:00
map < string , vector < Messages > > & SPF_messages , bool sharedMemoryParallelization ,
2023-09-14 19:43:13 +03:00
map < string , map < int , set < string > > > & newDeclsToInclude )
{
bool error = false ;
map < string , FuncInfo * > funcMap ;
createMapOfFunc ( allFuncInfo , funcMap ) ;
2024-06-19 18:08:27 +03:00
if ( sharedMemoryParallelization = = 0 )
2023-09-14 19:43:13 +03:00
{
map < string , map < int , set < string > > > copied ;
for ( auto & region : regions )
{
2023-11-28 12:58:22 +03:00
__spf_print ( 1 , " [%s]: create local arrays \n " , region - > GetName ( ) . c_str ( ) ) ;
2023-09-14 19:43:13 +03:00
// creating new local arrays
for ( auto & funcArrays : region - > GetUsedLocalArrays ( ) )
{
for ( auto & arrayLines : funcArrays . second )
{
if ( arrayLines . first - > GetRegionsName ( ) . size ( ) > 1 )
{
bool fromModule = ( arrayLines . first - > GetLocation ( ) . first = = DIST : : l_MODULE ) ;
const string locationName = arrayLines . first - > GetLocation ( ) . second ;
auto place = * arrayLines . first - > GetDeclInfo ( ) . begin ( ) ;
string fileName = place . first ;
string suffix = " _l " ;
if ( fromModule )
{
fileName = funcArrays . first - > fileName ;
suffix = " _m " ;
}
auto origCopy = copyArray ( place , arrayLines . first , arrayLines . second , suffix + to_string ( region - > GetId ( ) ) , fileName , newDeclsToInclude , copied ) ;
for ( auto & lines : arrayLines . second )
{
replaceSymbol ( fileName , lines , origCopy . first - > identifier ( ) , origCopy . second ) ;
insertArrayCopying ( fileName , lines , origCopy . first , origCopy . second ) ;
}
// complete USE ONLY list
if ( fromModule )
compliteUseOnlyList ( funcArrays . first - > funcPointer , locationName , origCopy . second - > identifier ( ) ) ;
}
}
}
2023-11-28 12:58:22 +03:00
__spf_print ( 1 , " [%s]: create common arrays \n " , region - > GetName ( ) . c_str ( ) ) ;
2023-09-14 19:43:13 +03:00
// creating new common-blocks for files with explicit lines
for ( auto & fileLines : region - > GetAllLines ( ) )
{
if ( SgFile : : switchToFile ( fileLines . first ) ! = - 1 )
{
for ( auto & lines : fileLines . second )
{
if ( ! lines . isImplicit ( ) )
{
SgStatement * iterator = getFuncStat ( lines . stats . first - > GetOriginal ( ) ) ;
string funcName = iterator - > symbol ( ) - > identifier ( ) ;
FuncInfo * func = getFuncInfo ( funcMap , funcName ) ;
auto it = insertedCommonBlocks . find ( func ) ;
if ( it = = insertedCommonBlocks . end ( ) )
it = insertedCommonBlocks . insert ( it , make_pair ( func , set < DIST : : Array * > ( ) ) ) ;
for ( auto & arrayBlock : allUsedCommonArrays )
{
auto varsOnPos = getArraySynonyms ( arrayBlock . first ) ;
auto itt = it - > second . find ( arrayBlock . first ) ;
// insert only one of all array synonyms
if ( itt = = it - > second . end ( ) & & arrayBlock . first - > GetShortName ( ) = = varsOnPos [ 0 ] - > getName ( ) )
{
// need to insert common-block
insertCommonBlock ( func , arrayBlock . first ) ;
it - > second . insert ( arrayBlock . first ) ;
}
}
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
// insert array copying in explicit lines (and replace common arrays in this lines)
for ( auto & funcArrays : region - > GetUsedCommonArrays ( ) )
{
for ( auto & arrayLines : funcArrays . second )
{
for ( auto & lines : arrayLines . second )
{
// get all synonyms for array
set < string > arraySynonyms ;
auto varsOnPos = getArraySynonyms ( arrayLines . first ) ;
for ( auto & var : varsOnPos )
arraySynonyms . insert ( var - > getName ( ) ) ;
// replace common arrays to new common arrays and insert copying in explicit lines
if ( lines . isImplicit ( ) )
{
// replace common arrays in explicit lines and insert copying
// finding explicit lines where implicit lines are called from
// forall lines, lines2: lines.isImplicit(), lines2.isExplicit ==>
// exists func, func2: lines in func, lines2 in func2, func2 calls func explicit or implicit ==>
// insert copying of common-arrays in lines2 used in lines
for ( auto & fileLines : region - > GetAllLines ( ) )
{
if ( SgFile : : switchToFile ( fileLines . first ) ! = - 1 )
{
for ( auto & lines2 : fileLines . second )
{
if ( ! lines2 . isImplicit ( ) )
{
SgStatement * iterator = getFuncStat ( lines2 . stats . first - > GetOriginal ( ) ) ;
string func2Name = iterator - > symbol ( ) - > identifier ( ) ;
set < FuncInfo * > callSet ;
createSetOfCalledFuncs ( func2Name , funcMap , callSet ) ;
auto it = callSet . find ( funcArrays . first ) ;
if ( it ! = callSet . end ( ) )
{
bool tempErr = replaceCommonArray ( fileLines . first , arraySynonyms , lines2 , SPF_messages , true ) ;
error = error | | tempErr ;
}
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
else
{
if ( SgFile : : switchToFile ( funcArrays . first - > fileName ) ! = - 1 )
{
bool tempErr = replaceCommonArray ( funcArrays . first - > fileName , arraySynonyms , lines , SPF_messages , true ) ;
error = error | | tempErr ;
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
}
}
}
// creating new common-blocks for main program unit
for ( auto & funcPair : funcMap )
{
auto func = funcPair . second ;
if ( func - > isMain )
{
if ( SgFile : : switchToFile ( func - > fileName ) ! = - 1 )
{
auto it = insertedCommonBlocks . find ( func ) ;
if ( it = = insertedCommonBlocks . end ( ) )
it = insertedCommonBlocks . insert ( it , make_pair ( func , set < DIST : : Array * > ( ) ) ) ;
for ( auto & arrayBlock : allUsedCommonArrays )
{
auto varsOnPos = getArraySynonyms ( arrayBlock . first ) ;
auto itt = it - > second . find ( arrayBlock . first ) ;
// insert only one of all array synonyms
if ( itt = = it - > second . end ( ) & & arrayBlock . first - > GetShortName ( ) = = varsOnPos [ 0 ] - > getName ( ) )
{
// need to insert common-block
insertCommonBlock ( func , arrayBlock . first ) ;
it - > second . insert ( arrayBlock . first ) ;
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
break ;
}
}
}
2023-11-28 12:58:22 +03:00
__spf_print ( 1 , " create functions \n " ) ;
2023-09-14 19:43:13 +03:00
// creating new functions
for ( auto & fileFuncs : allFuncInfo )
{
if ( SgFile : : switchToFile ( fileFuncs . first ) ! = - 1 )
{
for ( auto & func : fileFuncs . second )
{
// callRegions = {i}, i = 1, 2, ...
if ( func - > callRegions . size ( ) = = 1 & & * ( func - > callRegions . begin ( ) ) ! = 0 )
{
// need just create new common-blocks and replace arrays
SgFile * file = func - > funcPointer - > GetOriginal ( ) - > getFile ( ) ;
ParallelRegion * region = getRegionById ( regions , * ( func - > callRegions . begin ( ) ) ) ;
auto usedCommonArrays = region - > GetUsedCommonArrays ( ) . find ( func ) ;
if ( usedCommonArrays ! = region - > GetUsedCommonArrays ( ) . end ( ) )
{
for ( auto & arrayBlock : allUsedCommonArrays )
createCommonBlock ( file , arrayBlock . first ) ;
auto it = insertedCommonBlocks . find ( func ) ;
if ( it = = insertedCommonBlocks . end ( ) )
it = insertedCommonBlocks . insert ( it , make_pair ( func , set < DIST : : Array * > ( ) ) ) ;
for ( auto & arrayLines : usedCommonArrays - > second )
{
auto itt = it - > second . find ( arrayLines . first ) ;
if ( itt = = it - > second . end ( ) )
{
// need to insert common-block
insertCommonBlock ( func , arrayLines . first ) ;
it - > second . insert ( arrayLines . first ) ;
// replace common arrays to new common arrays in executable code section
SgStatement * iterator = func - > funcPointer - > GetOriginal ( ) ;
for ( ; iterator ! = func - > funcPointer - > GetOriginal ( ) - > lastNodeOfStmt ( ) & &
( ! isSgExecutableStatement ( iterator ) | | isSPF_stat ( iterator ) ) ; iterator = iterator - > lexNext ( ) )
;
// get all synonyms for array
set < string > arraySynonyms ;
auto varsOnPos = getArraySynonyms ( arrayLines . first ) ;
for ( auto & var : varsOnPos )
arraySynonyms . insert ( var - > getName ( ) ) ;
Statement * start = new Statement ( iterator ) ;
Statement * end = new Statement ( func - > funcPointer - > GetOriginal ( ) - > lastNodeOfStmt ( ) ) ;
pair < Statement * , Statement * > beginEnd = make_pair ( start , end ) ;
pair < int , int > funcLines = make_pair ( beginEnd . first - > GetOriginal ( ) - > lineNumber ( ) , beginEnd . second - > GetOriginal ( ) - > lineNumber ( ) ) ;
ParallelRegionLines lines ( funcLines , beginEnd ) ;
bool tempErr = replaceCommonArray ( fileFuncs . first , arraySynonyms , lines , SPF_messages ) ;
error = error | | tempErr ;
}
}
}
}
// callRegions = {i1, i2, ...}
else if ( func - > callRegions . size ( ) > 1 )
{
// need copy function for every region, the exeption is defalut region
for ( auto & regionId : func - > callRegions )
if ( regionId )
copyFunction ( getRegionById ( regions , regionId ) , func , funcMap , string ( " _r " ) + to_string ( regionId ) ) ;
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
// replace function calls in funcs with callRegions = {i}, i = 1, 2, ...
for ( auto & fileFuncs : allFuncInfo )
{
if ( SgFile : : switchToFile ( fileFuncs . first ) ! = - 1 )
{
for ( auto & func : fileFuncs . second )
{
if ( func - > callRegions . size ( ) = = 1 & & * ( func - > callRegions . begin ( ) ) )
{
int regionId = * ( func - > callRegions . begin ( ) ) ;
Statement * begin = func - > funcPointer ;
Statement * end = new Statement ( begin - > GetOriginal ( ) - > lastNodeOfStmt ( ) ) ;
ParallelRegionLines funcLines ( make_pair ( begin - > GetOriginal ( ) - > lineNumber ( ) , end - > GetOriginal ( ) - > lineNumber ( ) ) , make_pair ( func - > funcPointer , end ) ) ;
replaceFuncCalls ( funcLines , funcMap , regionId ) ;
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
// replace function calls in explicit lines
for ( auto & region : regions )
{
for ( auto & fileLines : region - > GetAllLines ( ) )
{
if ( SgFile : : switchToFile ( fileLines . first ) ! = - 1 )
{
for ( auto & lines : fileLines . second )
{
if ( ! lines . isImplicit ( ) )
replaceFuncCalls ( lines , funcMap , region - > GetId ( ) ) ;
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
2024-06-19 18:08:27 +03:00
if ( sharedMemoryParallelization = = 0 )
2023-09-14 19:43:13 +03:00
{
2023-11-28 12:58:22 +03:00
__spf_print ( 1 , " insert DVM intervals \n " ) ;
2023-09-14 19:43:13 +03:00
// inserting dvm intervals
for ( auto & region : regions )
{
for ( auto & fileLines : region - > GetAllLines ( ) )
{
if ( SgFile : : switchToFile ( fileLines . first ) ! = - 1 )
{
for ( auto & lines : fileLines . second )
{
if ( ! lines . isImplicit ( ) )
{
// create DVM INTERVAL before region
SgStatement * start = NULL ;
SgStatement * end = lines . stats . first - > GetOriginal ( ) - > lexPrev ( ) - > lexPrev ( ) ;
for ( SgStatement * st = end ; st & & st - > lineNumber ( ) < 0 & & isArrayAssign ( st ) ; st = st - > lexPrev ( ) )
start = st ;
// DVM END INTERVAL
SgStatement * interval = new SgStatement ( DVM_ENDINTERVAL_DIR ) ;
interval - > setlineNumber ( lines . stats . first - > GetOriginal ( ) - > lineNumber ( ) ) ;
end - > insertStmtAfter ( * interval , * end - > controlParent ( ) ) ;
// DVM INTERVAL N
interval = new SgStatement ( DVM_INTERVAL_DIR ) ;
SgExprListExp * newNode = new SgExprListExp ( ) ;
int val = getIntervalNumber ( current_file_id , lines . stats . first - > GetOriginal ( ) - > lexPrev ( ) - > lineNumber ( ) , region - > GetId ( ) ) ;
newNode - > setLhs ( new SgValueExp ( val ) ) ;
interval - > setExpression ( 0 , * newNode ) ;
interval - > setlineNumber ( lines . stats . first - > GetOriginal ( ) - > lineNumber ( ) ) ;
if ( start )
start - > insertStmtBefore ( * interval , * start - > controlParent ( ) ) ;
else
end - > insertStmtAfter ( * interval , * end - > controlParent ( ) ) ;
// create DVM INTERVAL after region
start = lines . stats . second - > GetOriginal ( ) - > lexNext ( ) - > lexNext ( ) ;
end = NULL ;
for ( SgStatement * st = start ; st & & ! st - > lineNumber ( ) & & isArrayAssign ( st ) ; st = st - > lexNext ( ) )
end = st ;
// DVM INTERVAL N
interval = new SgStatement ( DVM_INTERVAL_DIR ) ;
newNode = new SgExprListExp ( ) ;
val = getIntervalNumber ( current_file_id , lines . stats . second - > GetOriginal ( ) - > lexNext ( ) - > lineNumber ( ) , region - > GetId ( ) ) ;
newNode - > setLhs ( new SgValueExp ( val ) ) ;
interval - > setExpression ( 0 , * newNode ) ;
interval - > setlineNumber ( lines . stats . second - > GetOriginal ( ) - > lineNumber ( ) ) ;
start - > insertStmtBefore ( * interval , * start - > controlParent ( ) ) ;
// DVM END INTERVAL
interval = new SgStatement ( DVM_ENDINTERVAL_DIR ) ;
interval - > setlineNumber ( lines . stats . second - > GetOriginal ( ) - > lineNumber ( ) ) ;
if ( end )
end - > insertStmtAfter ( * interval , * end - > controlParent ( ) ) ;
else
start - > insertStmtBefore ( * interval , * start - > controlParent ( ) ) ;
}
}
}
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
}
return ( error ? 1 : 0 ) ;
}
int printCheckRegions ( const char * fileName , const vector < ParallelRegion * > & regions , const map < string , vector < FuncInfo * > > & allFuncInfo )
{
map < string , FuncInfo * > funcMap ;
createMapOfFunc ( allFuncInfo , funcMap ) ;
string outText = " " ;
string elems = " " ;
for ( auto & region : regions )
{
outText + = " *** REGION ' " + region - > GetName ( ) + " ' \n " ;
for ( auto & nameFunc : funcMap )
{
if ( nameFunc . second - > callRegions . size ( ) > 1 )
{
for ( auto & regId : nameFunc . second - > callRegions )
if ( region - > GetId ( ) = = regId )
elems + = " ' " + nameFunc . first + ' \' ' ;
}
}
if ( elems . size ( ) )
outText + = " COMMON FUNCTIONS: " + elems + ' \n ' ;
set < string > arrays ;
for ( auto & funcArrays : region - > GetUsedCommonArrays ( ) )
for ( auto & arrayLines : funcArrays . second )
arrays . insert ( arrayLines . first - > GetShortName ( ) ) ;
elems . clear ( ) ;
for ( auto & arrayName : arrays )
elems + = " ' " + arrayName + ' \' ' ;
if ( elems . size ( ) )
outText + = " COMMON ARRAYS: " + elems + ' \n ' ;
elems . clear ( ) ;
for ( auto & funcArrays : region - > GetUsedLocalArrays ( ) )
{
for ( auto & arrayLines : funcArrays . second )
{
string toPrint = " " ;
for ( auto & lines : arrayLines . second )
{
toPrint + = " [ " + to_string ( lines . lines . first ) ;
toPrint + = " - " + to_string ( lines . lines . second ) ;
toPrint + = " ] " ;
}
elems + = " [ " + funcArrays . first - > funcName + " , " + arrayLines . first - > GetShortName ( ) + " , " + toPrint + " ] \n " ;
}
}
if ( elems . size ( ) )
outText + = " LOCAL ARRAYS in [FUNC, ARRAY, [LINES]]: \n " + elems ;
}
outText + = " *** SUMMARY \n " ;
elems . clear ( ) ;
for ( auto & nameFunc : funcMap )
if ( nameFunc . second - > callRegions . size ( ) > 1 )
elems + = " ' " + nameFunc . first + ' \' ' ;
if ( elems . size ( ) )
outText + = " ALL COMMON FUNCTIONS : " + elems + ' \n ' ;
elems . clear ( ) ;
for ( auto & commonArrayCommonBlock : allUsedCommonArrays )
elems + = " ' " + commonArrayCommonBlock . first - > GetShortName ( ) + ' \' ' ;
if ( elems . size ( ) )
outText + = " ALL COMMON ARRAYS: " + elems + ' \n ' ;
if ( fileName = = NULL )
__spf_print ( 1 , " %s " , outText . c_str ( ) ) ;
else
{
FILE * file = fopen ( fileName , " w " ) ;
if ( file = = NULL )
{
__spf_print ( 1 , " can not open file '%s' \n " , fileName ) ;
return - 1 ;
}
fprintf ( file , " %s " , outText . c_str ( ) ) ;
fclose ( file ) ;
}
return 0 ;
}
void insertRealignsBeforeFragments ( ParallelRegion * reg , SgFile * file , const set < DIST : : Array * > & distrArrays , const map < DIST : : Array * ,
set < DIST : : Array * > > & arrayLinksByFuncCalls )
{
auto currFile = new File ( file ) ;
if ( distrArrays . size ( ) = = 0 )
return ;
if ( reg - > GetName ( ) = = " DEFAULT " )
return ;
auto lines = reg - > GetLines ( file - > filename ( ) ) ;
if ( lines )
{
set < DIST : : Array * > withoutTempl ;
for ( auto & elem : distrArrays )
if ( elem - > IsArray ( ) )
withoutTempl . insert ( elem ) ;
for ( auto & elem : * lines )
{
if ( ! elem . isImplicit ( ) )
{
checkNull ( elem . stats . first , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
checkNull ( elem . stats . second , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
checkNull ( elem . intervalBefore . first , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
checkNull ( elem . intervalBefore . second , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
auto toRealign = createRealignRules ( elem . intervalBefore . first , reg - > GetId ( ) , currFile , " " , arrayLinksByFuncCalls , withoutTempl , make_pair ( 0 , 0 ) ) ;
auto cp = elem . intervalBefore . first - > controlParent ( ) ;
if ( toRealign . second . size ( ) = = 0 )
break ;
for ( auto & rule : toRealign . second )
{
elem . intervalBefore . first - > insertStmtBefore ( * new SgStatement ( DVM_NEW_VALUE_DIR ) , * cp ) ;
elem . intervalBefore . first - > insertStmtBefore ( * createStatFromExprs ( ( ( CreatedDirective * ) rule ) - > sageData ) , * cp ) ;
}
}
}
}
delete currFile ;
}