2023-09-14 19:43:13 +03:00
# include " ../Utils/leak_detector.h "
# include <cstdio>
# include <cstdlib>
# include <cstring>
# include <cstdint>
# include <assert.h>
# include <string>
# include <vector>
# include <map>
# include <set>
# include "dvm.h"
# include "../Sapfor.h"
# include "../GraphLoop/graph_loops.h"
# include "../GraphCall/graph_calls_func.h"
# include "../SageAnalysisTool/depInterfaceExt.h"
# include "../Utils/SgUtils.h"
# include "../Utils/errors.h"
# include "directive_parser.h"
# include "../ExpressionTransform/expr_transform.h"
# include "../LoopAnalyzer/loop_analyzer.h"
2024-04-12 16:36:37 +03:00
# include "../DirectiveProcessing/directive_omp_parser.h"
2023-09-14 19:43:13 +03:00
using std : : string ;
using std : : wstring ;
using std : : vector ;
using std : : map ;
using std : : set ;
using std : : pair ;
using std : : tuple ;
static void addToattribute ( SgStatement * toAttr , SgStatement * curr , const int variant )
{
// move SgStatement to attribute
SgStatement * toAdd = new SgStatement ( toAttr - > variant ( ) , NULL , toAttr - > symbol ( ) , toAttr - > expr ( 0 ) , toAttr - > expr ( 1 ) , toAttr - > expr ( 2 ) ) ;
toAdd - > setlineNumber ( toAttr - > lineNumber ( ) ) ;
2024-04-12 16:36:37 +03:00
toAdd - > setLocalLineNumber ( SPF_USER_DIR ) ;
2023-09-14 19:43:13 +03:00
curr - > addAttribute ( variant , toAdd , sizeof ( SgStatement ) ) ;
//copy comments to st
if ( toAttr - > comments ( ) & & variant ! = SPF_END_PARALLEL_REG_DIR & & variant ! = SPF_PARALLEL_REG_DIR )
{
string comments ( toAttr - > comments ( ) ) ;
if ( curr - > comments ( ) )
comments + = " \n " + string ( curr - > comments ( ) ) ;
if ( comments . size ( ) ! = 0 )
curr - > setComments ( comments . c_str ( ) ) ;
}
}
void fillVars ( SgExpression * exp , const set < int > & types , set < string > & identifierList , vector < SgExpression * > & funcCalls )
{
if ( exp )
{
if ( exp - > variant ( ) = = FUNC_CALL )
funcCalls . push_back ( exp ) ;
if ( types . find ( exp - > variant ( ) ) ! = types . end ( ) )
{
if ( exp - > symbol ( ) )
identifierList . insert ( OriginalSymbol ( exp - > symbol ( ) ) - > identifier ( ) ) ;
else if ( exp - > variant ( ) = = DDOT )
identifierList . insert ( exp - > symbol ( ) - > identifier ( ) ) ; // BAD solution
}
fillVars ( exp - > lhs ( ) , types , identifierList , funcCalls ) ;
fillVars ( exp - > rhs ( ) , types , identifierList , funcCalls ) ;
}
}
void fillVars ( SgExpression * exp , const set < int > & types , set < SgSymbol * > & identifierList , vector < SgExpression * > & funcCalls )
{
if ( exp )
{
if ( exp - > variant ( ) = = FUNC_CALL )
funcCalls . push_back ( exp ) ;
if ( types . find ( exp - > variant ( ) ) ! = types . end ( ) )
{
if ( exp - > symbol ( ) )
identifierList . insert ( OriginalSymbol ( exp - > symbol ( ) ) ) ;
else if ( exp - > variant ( ) = = DDOT )
identifierList . insert ( ( SgSymbol * ) exp ) ; // BAD solution
}
fillVars ( exp - > lhs ( ) , types , identifierList , funcCalls ) ;
fillVars ( exp - > rhs ( ) , types , identifierList , funcCalls ) ;
}
}
static bool isPrivateVar ( SgStatement * st , SgSymbol * symbol )
{
bool retVal = false ;
for ( auto & data : getAttributes < SgStatement * , SgStatement * > ( st , set < int > { SPF_ANALYSIS_DIR } ) )
{
set < string > privates ;
fillPrivatesFromComment ( new Statement ( data ) , privates ) ;
retVal = retVal | | privates . find ( symbol - > identifier ( ) ) ! = privates . end ( ) ;
if ( retVal )
break ;
}
return retVal ;
}
2024-04-10 13:42:49 +03:00
# define BAD_POSITION_FULL(ERR_TYPE, PLACE_E, PLACE_R, BEFORE_VAR_E, BEFORE_VAR_R, BEFORE_DO_E, BEFORE_DO_R, LINE) do { \
2023-09-14 19:43:13 +03:00
__spf_print ( 1 , " bad directive position on line %d, it can be placed only %s %s %s \n " , LINE , PLACE_E , BEFORE_VAR_E , BEFORE_DO_E ) ; \
wstring messageE , messageR ; \
__spf_printToLongBuf ( messageE , L " bad directive position, it can be placed only %s %s %s " , to_wstring ( PLACE_E ) . c_str ( ) , to_wstring ( BEFORE_VAR_E ) . c_str ( ) , to_wstring ( BEFORE_DO_E ) . c_str ( ) ) ; \
__spf_printToLongBuf ( messageR , R1 , PLACE_R , BEFORE_VAR_R , BEFORE_DO_R ) ; \
messagesForFile . push_back ( Messages ( ERR_TYPE , LINE , messageR , messageE , 1001 ) ) ; \
} while ( 0 )
static SgStatement * skipDvmDirs ( SgStatement * st )
{
while ( isDVM_stat ( st ) )
st = st - > lexNext ( ) ;
return st ;
}
static void fillVarsSets ( SgStatement * iterator , SgStatement * end , set < string > & varDef , set < string > & varUse )
{
for ( ; iterator ! = end ; iterator = iterator - > lexNext ( ) )
{
vector < SgExpression * > funcCalls ;
if ( iterator - > variant ( ) = = PROC_STAT )
{ // TODO: procedures may have IN, INOUT, OUT parameters
fillVars ( iterator - > expr ( 0 ) , { ARRAY_REF , VAR_REF } , varDef , funcCalls ) ;
fillVars ( iterator - > expr ( 0 ) , { ARRAY_REF , VAR_REF } , varUse , funcCalls ) ;
}
else
{
if ( iterator - > variant ( ) = = ASSIGN_STAT | | isSgExecutableStatement ( iterator ) = = NULL )
fillVars ( iterator - > expr ( 0 ) , { ARRAY_REF , VAR_REF } , varDef , funcCalls ) ;
else
fillVars ( iterator - > expr ( 0 ) , { ARRAY_REF , VAR_REF } , varUse , funcCalls ) ;
fillVars ( iterator - > expr ( 1 ) , { ARRAY_REF , VAR_REF } , varUse , funcCalls ) ;
fillVars ( iterator - > expr ( 2 ) , { ARRAY_REF , VAR_REF } , varUse , funcCalls ) ;
if ( iterator - > variant ( ) = = FOR_NODE )
{
auto loop = isSgForStmt ( iterator ) ;
varDef . insert ( loop - > doName ( ) - > identifier ( ) ) ;
varUse . insert ( loop - > doName ( ) - > identifier ( ) ) ;
}
vector < SgExpression * > dummy ;
// TODO: functions may have IN, INOUT, OUT parameters
for ( auto & func : funcCalls )
fillVars ( func , { ARRAY_REF , VAR_REF } , varDef , dummy ) ;
}
}
}
2024-04-09 16:41:48 +03:00
static bool checkCover ( SgStatement * st ,
SgStatement * attributeStatement ,
const int coverLoops ,
vector < Messages > & messagesForFile )
{
// COVER(VALUE)
const int var = st - > variant ( ) ;
bool retVal = true ;
SgForStmt * forSt = ( SgForStmt * ) st ;
const int nestedCount = countPerfectLoopNest ( forSt ) ;
if ( coverLoops > nestedCount | | coverLoops = = 0 )
{
__spf_print ( 1 , " bad directive expression: expected %d nested loops on line %d but got %d on line %d \n " ,
coverLoops , attributeStatement - > lineNumber ( ) , nestedCount , st - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive expression: expected %d nested loops on line %d but got %d " ,
coverLoops , attributeStatement - > lineNumber ( ) , nestedCount ) ;
__spf_printToLongBuf ( messageR , R77 , coverLoops , attributeStatement - > lineNumber ( ) , nestedCount ) ;
messagesForFile . push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1043 ) ) ;
retVal = false ;
}
return retVal ;
}
static bool checkProcessPrivate ( SgStatement * st ,
SgStatement * attributeStatement ,
const set < Symbol * > & privates ,
vector < Messages > & messagesForFile )
{
// PROCESS_PRIVATE(VAR)
const int var = st - > variant ( ) ;
bool retVal = true ;
if ( ! isSgExecutableStatement ( st ) )
{
st = skipDvmDirs ( st ) ;
SgStatement * iterator = st ;
SgStatement * end = st - > lexNext ( ) ;
set < string > varDef , varUse ;
fillVarsSets ( iterator , end , varDef , varUse ) ;
for ( auto & privElemS : privates )
{
const string privElem = privElemS - > GetOriginal ( ) - > identifier ( ) ;
bool defCond = true ;
if ( varDef . find ( privElem ) = = varDef . end ( ) )
defCond = false ;
if ( ! defCond )
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " before " , RR1_1 , " variable declaration " , RR1_2 , " " , L " " , attributeStatement - > lineNumber ( ) ) ;
2024-04-09 16:41:48 +03:00
retVal = false ;
}
}
}
else
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " before " , RR1_1 , " variable declaration " , RR1_2 , " " , L " " , attributeStatement - > lineNumber ( ) ) ;
2024-04-09 16:41:48 +03:00
retVal = false ;
}
return retVal ;
}
2023-09-14 19:43:13 +03:00
static bool checkPrivate ( SgStatement * st ,
SgStatement * attributeStatement ,
const set < Symbol * > & privates ,
vector < Messages > & messagesForFile )
{
// PRIVATE(VAR)
const int var = st - > variant ( ) ;
bool retVal = true ;
2024-04-09 16:41:48 +03:00
if ( var = = FOR_NODE )
2023-09-14 19:43:13 +03:00
{
st = skipDvmDirs ( st ) ;
SgStatement * iterator = st ;
2024-04-09 16:41:48 +03:00
SgStatement * end = st - > lastNodeOfStmt ( ) ;
set < string > varDef , varUse ;
2023-09-14 19:43:13 +03:00
set < string > wrongPrivFromOmpParallel ;
2024-04-09 16:41:48 +03:00
fillVarsSets ( iterator , end , varDef , varUse ) ;
for ( auto & privElemS : privates )
2023-09-14 19:43:13 +03:00
{
const string privElem = privElemS - > GetOriginal ( ) - > identifier ( ) ;
bool defCond = true ;
bool useCond = true ;
if ( varDef . find ( privElem ) = = varDef . end ( ) )
defCond = false ;
if ( varUse . find ( privElem ) = = varUse . end ( ) )
useCond = false ;
2024-04-09 16:41:48 +03:00
if ( ! defCond & & ! useCond )
2023-09-14 19:43:13 +03:00
{
2024-04-12 16:36:37 +03:00
if ( attributeStatement - > localLineNumber ( ) ! = SPF_OMP_DIR )
2023-09-14 19:43:13 +03:00
{
2024-04-09 16:41:48 +03:00
__spf_print ( 1 , " variable '%s' is not used in loop on line %d \n " , privElem . c_str ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " variable '%s' is not used in loop " , to_wstring ( privElem . c_str ( ) ) . c_str ( ) ) ;
2023-09-14 19:43:13 +03:00
2024-04-09 16:41:48 +03:00
__spf_printToLongBuf ( messageR , R21 , to_wstring ( privElem . c_str ( ) ) . c_str ( ) ) ;
2023-09-14 19:43:13 +03:00
2024-04-09 16:41:48 +03:00
messagesForFile . push_back ( Messages ( WARR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1002 ) ) ;
2023-09-14 19:43:13 +03:00
}
2024-04-09 16:41:48 +03:00
else
wrongPrivFromOmpParallel . insert ( privElem ) ;
2023-09-14 19:43:13 +03:00
}
2024-04-09 16:41:48 +03:00
else if ( ! defCond & & useCond )
2023-09-14 19:43:13 +03:00
{
2024-04-12 16:36:37 +03:00
if ( attributeStatement - > localLineNumber ( ) ! = SPF_OMP_DIR )
2023-09-14 19:43:13 +03:00
{
2024-04-09 16:41:48 +03:00
__spf_print ( 1 , " variable '%s' is not changed in loop on line %d \n " , privElem . c_str ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " variable '%s' is not changed in loop " , to_wstring ( privElem . c_str ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R23 , to_wstring ( privElem . c_str ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1003 ) ) ;
2023-09-14 19:43:13 +03:00
retVal = false ;
}
2024-04-09 16:41:48 +03:00
else
wrongPrivFromOmpParallel . insert ( privElem ) ;
2023-09-14 19:43:13 +03:00
}
}
2024-04-09 16:41:48 +03:00
if ( wrongPrivFromOmpParallel . size ( ) ) // remove unnecessary
2023-09-14 19:43:13 +03:00
{
if ( wrongPrivFromOmpParallel . size ( ) = = privates . size ( ) ) // remove all
attributeStatement - > expr ( 0 ) - > lhs ( ) - > setLhs ( NULL ) ;
else
{
SgExpression * list = attributeStatement - > expr ( 0 ) - > lhs ( ) - > lhs ( ) ;
vector < SgExpression * > newList ;
for ( auto ex = list ; ex ; ex = ex - > rhs ( ) )
{
string currV = ex - > lhs ( ) - > symbol ( ) - > identifier ( ) ;
if ( wrongPrivFromOmpParallel . find ( currV ) = = wrongPrivFromOmpParallel . end ( ) )
newList . push_back ( ex - > lhs ( ) ) ;
}
attributeStatement - > expr ( 0 ) - > lhs ( ) - > setLhs ( makeExprList ( newList ) ) ;
}
}
}
else
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " before " , RR1_1 , " " , L " " , " DO statement " , RR1_3 , attributeStatement - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
retVal = false ;
}
return retVal ;
}
static bool checkReduction ( SgStatement * st ,
SgStatement * attributeStatement ,
const map < string , set < Symbol * > > & reduction ,
vector < Messages > & messagesForFile )
{
// REDUCTION(OP(VAR))
const int var = st - > variant ( ) ;
bool retVal = true ;
if ( var = = FOR_NODE )
{
SgStatement * iterator = st - > lexNext ( ) ;
SgStatement * end = st - > lastNodeOfStmt ( ) ;
set < string > varDef ;
set < string > varUse ;
fillVarsSets ( iterator , end , varDef , varUse ) ;
for ( auto & redElem : reduction )
{
for ( auto & setElemS : redElem . second )
{
const string setElem = setElemS - > GetOriginal ( ) - > identifier ( ) ;
bool defCond = true ;
bool useCond = true ;
if ( varDef . find ( setElem ) = = varDef . end ( ) )
defCond = false ;
if ( varUse . find ( setElem ) = = varUse . end ( ) )
useCond = false ;
if ( var = = FOR_NODE & & ! defCond & & ! useCond )
{
__spf_print ( 1 , " variable '%s' is not used in loop on line %d \n " , setElem . c_str ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " variable '%s' is not used in loop " , to_wstring ( setElem . c_str ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R22 , to_wstring ( setElem . c_str ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( WARR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1002 ) ) ;
}
if ( var = = FOR_NODE & & ! defCond & & useCond )
{
__spf_print ( 1 , " variable '%s' is not changed in loop on line %d \n " , setElem . c_str ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " variable '%s' is not changed in loop " , to_wstring ( setElem . c_str ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R24 , to_wstring ( setElem . c_str ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1003 ) ) ;
retVal = false ;
}
}
}
}
else
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " before " , RR1_1 , " " , L " " , " DO statement " , RR1_3 , attributeStatement - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
retVal = false ;
}
return retVal ;
}
static bool checkReduction ( SgStatement * st ,
SgStatement * attributeStatement ,
const map < string , set < tuple < Symbol * , Symbol * , int > > > & reduction ,
vector < Messages > & messagesForFile )
{
// REDUCTION(MIN/MAXLOC(VAR, ARRAY, CONST))
bool retVal = true ;
for ( auto & redElem : reduction )
{
set < Symbol * > vars ;
set < Symbol * > arrs ;
set < string > varsS ;
set < string > arrsS ;
for ( auto & setElem : redElem . second )
{
vars . insert ( std : : get < 0 > ( setElem ) ) ;
varsS . insert ( std : : get < 0 > ( setElem ) - > GetOriginal ( ) - > identifier ( ) ) ;
arrs . insert ( std : : get < 1 > ( setElem ) ) ;
arrsS . insert ( std : : get < 1 > ( setElem ) - > GetOriginal ( ) - > identifier ( ) ) ;
// CHECK ARRAY DECLARATION && DIMENTION
SgSymbol * arraySymbol = std : : get < 1 > ( setElem ) - > GetOriginal ( ) ;
SgStatement * declStatement = declaratedInStmt ( arraySymbol ) ;
SgArrayType * arrayType = NULL ;
int count = std : : get < 2 > ( setElem ) ;
if ( arraySymbol - > type ( ) )
arrayType = isSgArrayType ( arraySymbol - > type ( ) ) ;
if ( arrayType )
{
const int dim = arrayType - > dimension ( ) ;
if ( dim ! = 1 )
{
__spf_print ( 1 , " dimention of array '%s' is %d, but must be 1 on line %d \n " , arraySymbol - > identifier ( ) , dim , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " dimention of array '%s' is %d, but must be 1 " , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) , dim ) ;
__spf_printToLongBuf ( messageR , R25 , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) , dim ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1004 ) ) ;
retVal = false ;
}
if ( ! arrayType - > baseType ( ) - > equivalentToType ( SgTypeInt ( ) ) )
{
__spf_print ( 1 , " type of array '%s' must be INTEGER on line %d \n " , arraySymbol - > identifier ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " type of array '%s' but must be INTEGER " , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R26 , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1005 ) ) ;
retVal = false ;
}
}
else
{
__spf_print ( 1 , " type of variable '%s' must be array on line %d \n " , arraySymbol - > identifier ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " type of variable '%s' must be array " , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R27 , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1006 ) ) ;
retVal = false ;
}
SgStatement * iterator = st ;
SgStatement * end = st ;
vector < SgExpression * > dimentions ;
while ( iterator - > variant ( ) ! = PROG_HEDR & & iterator - > variant ( ) ! = PROC_HEDR & & iterator - > variant ( ) ! = FUNC_HEDR )
iterator = iterator - > controlParent ( ) ;
while ( iterator ! = end )
{
if ( isSPF_stat ( iterator ) | | isDVM_stat ( iterator ) )
{
iterator = iterator - > lexNext ( ) ;
continue ;
}
if ( ! isSgExecutableStatement ( iterator ) )
{
for ( SgExpression * exp = iterator - > expr ( 0 ) ; exp ; exp = exp - > rhs ( ) )
if ( exp - > lhs ( ) - > symbol ( ) = = arraySymbol )
for ( SgExpression * list = exp - > lhs ( ) - > lhs ( ) ; list ; list = list - > rhs ( ) )
dimentions . push_back ( list - > lhs ( ) ) ;
if ( dimentions . size ( ) )
{
if ( dimentions . size ( ) ! = 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
int size ;
int err = CalculateInteger ( dimentions [ 0 ] , size ) ;
if ( err ! = 0 )
{
// Expression can not be computed
__spf_print ( 1 , " array size can't be computed on line %d \n " , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " array size can't be computed " ) ;
__spf_printToLongBuf ( messageR , R30 ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1007 ) ) ;
retVal = false ;
}
else if ( size ! = count )
{
__spf_print ( 1 , " size of array '%s' is %d, but you enter %d on line %d \n " ,
arraySymbol - > identifier ( ) , size , count , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " size of array '%s' is %d, but you enter %d " , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) , size , count ) ;
__spf_printToLongBuf ( messageR , R31 , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) , size , count ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1008 ) ) ;
retVal = false ;
}
break ;
}
}
else
break ;
iterator = iterator - > lexNext ( ) ;
}
}
map < string , set < Symbol * > > reductionVar ;
map < string , set < Symbol * > > reductionArr ;
reductionVar [ redElem . first ] = vars ;
reductionArr [ redElem . first ] = arrs ;
retVal = checkReduction ( st , attributeStatement , reductionVar , messagesForFile ) & & checkReduction ( st , attributeStatement , reductionArr , messagesForFile ) ;
}
return retVal ;
}
static bool findSymbolInExpressionRec ( SgExpression * exp , SgSymbol * s )
{
if ( exp )
{
//if (exp->symbol() && string(exp->symbol()->identifier()) == s->identifier())
if ( exp - > symbol ( ) & & exp - > symbol ( ) = = s )
return true ;
return findSymbolInExpressionRec ( exp - > lhs ( ) , s ) | | findSymbolInExpressionRec ( exp - > rhs ( ) , s ) ;
}
return false ;
}
static bool findSymbolInStatement ( SgStatement * st , SgSymbol * s )
{
if ( ! st | | ! s )
return false ;
bool found = false ;
for ( int i = 0 ; ! found & & i < 3 ; + + i )
found = found | | findSymbolInExpressionRec ( st - > expr ( i ) , s ) ;
return found ;
}
static bool checkParametersExpressionRec ( SgStatement * st , SgStatement * attributeStatement , SgExpression * exp , vector < Messages > & messagesForFile )
{
bool retVal = true ;
if ( exp & & exp - > variant ( ) = = VAR_REF & & exp - > symbol ( ) )
{
auto declStatement = declaratedInStmt ( OriginalSymbol ( exp - > symbol ( ) ) , NULL , false ) ;
// check all used modules in function
auto moduleVar = false ;
vector < SgStatement * > useStats ;
fillUsedModulesInFunction ( st , useStats ) ;
for ( auto & useSt : useStats )
{
map < string , SgSymbol * > visibleVars ;
fillVisibleInUseVariables ( useSt , visibleVars ) ;
if ( visibleVars . find ( exp - > symbol ( ) - > identifier ( ) ) ! = visibleVars . end ( ) )
moduleVar = true ;
}
if ( ! declStatement & & ! moduleVar )
{
__spf_print ( 1 , " Variable '%s' in %s clause must be declared at the same module in file '%s' on line %d. \n " ,
exp - > symbol ( ) - > identifier ( ) , " PARAMETER " , st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " Variable '%s' in %s clause must be declared at the same module. " ,
to_wstring ( exp - > symbol ( ) - > identifier ( ) ) . c_str ( ) , to_wstring ( " PARAMETER " ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R168 , to_wstring ( exp - > symbol ( ) - > identifier ( ) ) . c_str ( ) , to_wstring ( " PARAMETER " ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 5004 ) ) ;
retVal = false ;
}
}
bool leftResult , rightResult ;
leftResult = rightResult = true ;
if ( exp - > lhs ( ) )
leftResult = checkParametersExpressionRec ( st , attributeStatement , exp - > lhs ( ) , messagesForFile ) ;
if ( exp - > rhs ( ) )
rightResult = checkParametersExpressionRec ( st , attributeStatement , exp - > rhs ( ) , messagesForFile ) ;
retVal = retVal & & leftResult & & rightResult ;
return retVal ;
}
static bool checkParameter ( SgStatement * st , SgStatement * attributeStatement , const vector < pair < Expression * , Expression * > > & assigns , vector < Messages > & messagesForFile )
{
bool retVal = true ;
if ( ! isSgExecutableStatement ( st ) )
{
wstring messageE , messageR ;
__spf_print ( 1 , " ANALYSIS directive with PARAMETER clause can be only at executable code section in file '%s' on line %d. \n " ,
st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
__spf_printToLongBuf ( messageE , L " ANALYSIS directive with PARAMETER clause can be only at executable code section. " ) ;
__spf_printToLongBuf ( messageR , R166 , L " ANALYSIS " , L " PARAMETER " ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 5002 ) ) ;
retVal = false ;
}
for ( auto & assign : assigns )
{
auto assignVarExp = assign . first - > GetOriginal ( ) ;
auto assignVarVar = assignVarExp - > variant ( ) ;
if ( ! findSymbolInStatement ( st , assignVarExp - > symbol ( ) ) )
{
__spf_print ( 1 , " Variable '%s' in %s clause must be used in next statement in file '%s' on line %d. \n " ,
assignVarExp - > symbol ( ) - > identifier ( ) , " PARAMETER " , st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " Variable '%s' in %s clause must be used in next statement. " ,
to_wstring ( assignVarExp - > symbol ( ) - > identifier ( ) ) . c_str ( ) , to_wstring ( " PARAMETER " ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R175 , to_wstring ( assignVarExp - > symbol ( ) - > identifier ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1057 ) ) ;
retVal = false ;
}
if ( assignVarVar ! = VAR_REF )
{
__spf_print ( 1 , " Left part of PARAMETER clause must be a variable in file '%s' on line %d. \n " ,
st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " Left part of PARAMETER clause must be a variable. " ) ;
__spf_printToLongBuf ( messageR , R176 ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1058 ) ) ;
retVal = false ;
}
auto assignExp = assign . second - > GetOriginal ( ) ;
auto result = checkParametersExpressionRec ( st , attributeStatement , assignExp , messagesForFile ) ;
retVal = retVal & & result ;
}
return retVal ;
}
static bool checkShadowAcross ( SgStatement * st ,
SgStatement * attributeStatement ,
const vector < pair < pair < Symbol * , string > , vector < pair < int , int > > > > & data ,
vector < Messages > & messagesForFile )
{
// SHADOW (VAR(list of shadows)) / ACROSS (VAR(list of shadows))
const int var = st - > variant ( ) ;
bool retVal = true ;
if ( var = = FOR_NODE )
{
for ( int i = 0 ; i < data . size ( ) ; + + i )
{
SgSymbol * arraySymbol = data [ i ] . first . first - > GetOriginal ( ) ;
SgStatement * declStatement = declaratedInStmt ( arraySymbol ) ;
const vector < pair < int , int > > & arrayDisc = data [ i ] . second ;
bool notPrivCond = true ;
if ( arraySymbol - > type ( ) - > variant ( ) ! = T_ARRAY )
{
__spf_print ( 1 , " variable '%s' is not array on line %d \n " , arraySymbol - > identifier ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " variable '%s' is not array " , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R28 , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1006 ) ) ;
retVal = false ;
}
notPrivCond = ! isPrivateVar ( st , arraySymbol ) & & ! isPrivateVar ( declStatement , arraySymbol ) ;
if ( ! notPrivCond )
{
__spf_print ( 1 , " array '%s' on line %d is private \n " , arraySymbol - > identifier ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " array '%s' is private " , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R33 , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1009 ) ) ;
retVal = false ;
}
SgArrayType * arrayType = NULL ;
if ( arraySymbol - > type ( ) )
arrayType = isSgArrayType ( arraySymbol - > type ( ) ) ;
if ( arrayType )
{
int dim = arrayType - > dimension ( ) ;
if ( dim ! = arrayDisc . size ( ) )
{
__spf_print ( 1 , " dimention of array '%s' is %d, but you enter %d on line %d \n " ,
arraySymbol - > identifier ( ) , arrayType - > dimension ( ) , ( int ) arrayDisc . size ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " dimention of array '%s' is %d, but you enter %d " ,
to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) , arrayType - > dimension ( ) , ( int ) arrayDisc . size ( ) ) ;
__spf_printToLongBuf ( messageR , R32 ,
to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) , arrayType - > dimension ( ) , ( int ) arrayDisc . size ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1008 ) ) ;
retVal = false ;
}
}
else
{
__spf_print ( 1 , " variable '%s' is not array on line %d \n " , arraySymbol - > identifier ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " variable '%s' is not array " , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R29 , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1006 ) ) ;
retVal = false ;
}
for ( auto & array : arrayDisc )
{
if ( array . first < 0 | | array . second < 0 )
{
__spf_print ( 1 , " only positive numbers are supported on line %d \n " , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " only positive numbers are supported " ) ;
__spf_printToLongBuf ( messageR , R35 ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1010 ) ) ;
retVal = false ;
}
}
}
}
else
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " before " , RR1_1 , " " , L " " , " DO statement " , RR1_3 , attributeStatement - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
retVal = false ;
}
return retVal ;
}
static int hasName ( SgExpression * exp , const string & varName )
{
if ( exp )
{
SgSymbol * symb = exp - > symbol ( ) ;
SgExpression * lhs = exp - > lhs ( ) ;
SgExpression * rhs = exp - > rhs ( ) ;
if ( symb )
if ( string ( symb - > identifier ( ) ) = = varName )
return 1 ;
return hasName ( lhs , varName ) + hasName ( rhs , varName ) ;
}
return 0 ;
}
static bool isRemoteExpressions ( SgExpression * exp , SgExpression * remoteExp , map < SgExpression * , string > & collection )
{
if ( exp = = remoteExp )
return true ;
bool retVal = true ;
while ( retVal & & exp ! = NULL & & remoteExp ! = NULL )
{
if ( remoteExp - > lhs ( ) )
if ( remoteExp - > lhs ( ) - > variant ( ) ! = DDOT )
retVal = retVal & & isEqExpressions ( exp - > lhs ( ) , remoteExp - > lhs ( ) , collection ) ;
exp = exp - > rhs ( ) ;
remoteExp = remoteExp - > rhs ( ) ;
}
return retVal ;
}
static bool hasRemoteExpressions ( SgExpression * exp , SgExpression * remoteExp , map < SgExpression * , string > & collection )
{
if ( exp )
{
SgExpression * lhs = exp - > lhs ( ) ;
SgExpression * rhs = exp - > rhs ( ) ;
if ( exp - > variant ( ) = = ARRAY_REF & & string ( exp - > symbol ( ) - > identifier ( ) ) = = remoteExp - > symbol ( ) - > identifier ( ) )
if ( isRemoteExpressions ( exp - > lhs ( ) , remoteExp - > lhs ( ) , collection ) )
return true ;
return hasRemoteExpressions ( lhs , remoteExp , collection ) | | hasRemoteExpressions ( rhs , remoteExp , collection ) ;
}
return false ;
}
static bool checkRemote ( SgStatement * st ,
SgStatement * attributeStatement ,
const map < pair < Symbol * , string > , Expression * > & remote ,
vector < Messages > & messagesForFile )
{
// REMOTE_ACCESS (EXPR)
const int var = st - > variant ( ) ;
bool retVal = true ;
if ( var = = FOR_NODE | | isSgExecutableStatement ( st ) )
{
for ( auto & remElem : remote )
{
bool cond = false ;
SgStatement * declStatement = declaratedInStmt ( remElem . first . first - > GetOriginal ( ) ) ;
set < SgSymbol * > arraySymbols ;
vector < SgExpression * > dummy ;
fillVars ( remElem . second , { ARRAY_REF } , arraySymbols , dummy ) ;
for ( auto & arraySymbol : arraySymbols )
{
declStatement = declaratedInStmt ( arraySymbol ) ;
bool notPrivCond = ! isPrivateVar ( st , arraySymbol ) & & ! isPrivateVar ( declStatement , arraySymbol ) ;
if ( ! notPrivCond )
{
__spf_print ( 1 , " array '%s' is private on line %d \n " , arraySymbol - > identifier ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " array '%s' is private " , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R34 , to_wstring ( arraySymbol - > identifier ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1009 ) ) ;
retVal = false ;
}
}
if ( var = = FOR_NODE )
{
SgStatement * iterator = st ;
SgStatement * end = st - > lastNodeOfStmt ( ) ;
map < string , int > forVars ;
while ( iterator ! = end )
{
SgForStmt * forSt = isSgForStmt ( iterator ) ;
if ( forSt )
{
SgSymbol * forName = forSt - > doName ( ) ;
forVars . insert ( make_pair ( string ( forName - > identifier ( ) ) , 0 ) ) ;
}
iterator = iterator - > lexNext ( ) ;
}
// CHECK: i AND a * i + b
// remElem.second links to b(i,j,k)
// remElem.second->lhs() links to i,j,k
SgExpression * remoteExp = remElem . second - > lhs ( ) ;
while ( remoteExp )
{
int forVarsCount = 0 ;
for ( auto & forVar : forVars )
{
if ( hasName ( remoteExp - > lhs ( ) , forVar . first ) )
{
+ + forVarsCount ;
+ + forVar . second ;
if ( retVal & & forVarsCount > 1 | | forVar . second > 1 )
{
__spf_print ( 1 , " bad directive expression: too many DO variables on line %d \n " , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive expression: too many DO variables " ) ;
__spf_printToLongBuf ( messageR , R2 ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1001 ) ) ;
retVal = false ;
}
// CHECK TREE: i OR a * i OR a * i + b
SgExpression * list = remoteExp - > lhs ( ) ;
bool isRemoteSubTreeCond = false ;
if ( list - > variant ( ) = = ADD_OP )
{
if ( list - > lhs ( ) - > variant ( ) = = MULT_OP & & ! hasName ( list - > rhs ( ) , forVar . first ) )
{
if ( hasName ( list - > lhs ( ) , forVar . first ) = = 1 )
isRemoteSubTreeCond = true ;
}
else if ( list - > rhs ( ) - > variant ( ) = = MULT_OP & & ! hasName ( list - > lhs ( ) , forVar . first ) )
{
if ( hasName ( list - > rhs ( ) , forVar . first ) = = 1 )
isRemoteSubTreeCond = true ;
}
else if ( hasName ( list , forVar . first ) = = 1 )
isRemoteSubTreeCond = true ;
}
else if ( list - > variant ( ) = = MULT_OP )
{
if ( ! hasName ( list - > lhs ( ) , forVar . first ) & & hasName ( list - > rhs ( ) , forVar . first ) = = 1 | |
! hasName ( list - > rhs ( ) , forVar . first ) & & hasName ( list - > lhs ( ) , forVar . first ) = = 1 )
isRemoteSubTreeCond = true ;
}
else if ( hasName ( list , forVar . first ) = = 1 )
isRemoteSubTreeCond = true ;
if ( ! isRemoteSubTreeCond )
{
__spf_print ( 1 , " bad directive expression: only a * i + b on line %d \n " , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive expression: only a * i + b " ) ;
__spf_printToLongBuf ( messageR , R3 ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1001 ) ) ;
retVal = false ;
}
}
}
remoteExp = remoteExp - > rhs ( ) ;
}
}
st = skipDvmDirs ( st ) ;
SgStatement * iterator = st ;
SgStatement * end = ( var = = FOR_NODE ) ? st - > lastNodeOfStmt ( ) : st - > lexNext ( ) ;
while ( iterator ! = end )
{
map < SgExpression * , string > collection ;
for ( int i = 0 ; i < 3 ; + + i )
if ( hasRemoteExpressions ( iterator - > expr ( i ) , remElem . second , collection ) )
cond = true ;
iterator = iterator - > lexNext ( ) ;
}
if ( ! cond )
{
__spf_print ( 1 , " no such expression '%s' on line %d \n " , remElem . second - > unparse ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " no such expression '%s' on loop " , to_wstring ( remElem . second - > unparse ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R36 , to_wstring ( remElem . second - > unparse ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1011 ) ) ;
retVal = false ;
}
}
}
else
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " before " , RR1_1 , " " , L " " , " DO statement " , RR1_3 , attributeStatement - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
retVal = false ;
}
return retVal ;
}
static void findAllRefs ( SgExpression * ex , set < string > & names )
{
if ( ex )
{
if ( ex - > variant ( ) = = VAR_REF | | ex - > variant ( ) = = ARRAY_REF )
if ( ex - > symbol ( ) )
names . insert ( ex - > symbol ( ) - > identifier ( ) ) ;
findAllRefs ( ex - > lhs ( ) , names ) ;
findAllRefs ( ex - > rhs ( ) , names ) ;
}
}
static bool checkParallelRegions ( SgStatement * st ,
const map < string , CommonBlock * > * commonBlocks ,
vector < Messages > & messagesForFile )
{
bool retVal = true ;
bool execNext = isSgExecutableStatement ( st - > lexNext ( ) ) ;
if ( execNext | | st - > lexNext ( ) - > variant ( ) = = ENTRY_STAT )
{
if ( st - > variant ( ) = = SPF_PARALLEL_REG_DIR )
{
SgSymbol * identSymbol = st - > symbol ( ) ;
// declaration checking
SgStatement * iterator = st ;
SgStatement * end = st ;
while ( iterator - > variant ( ) ! = PROG_HEDR & & iterator - > variant ( ) ! = PROC_HEDR & & iterator - > variant ( ) ! = FUNC_HEDR )
iterator = iterator - > controlParent ( ) ;
for ( ; iterator ! = end & & retVal ; iterator = iterator - > lexNext ( ) )
{
if ( isSPF_stat ( iterator ) | | isDVM_stat ( iterator ) )
continue ;
if ( ! isSgExecutableStatement ( iterator ) )
{
if ( iterator - > variant ( ) = = VAR_DECL | | iterator - > variant ( ) = = VAR_DECL_90 )
{
set < string > names ;
findAllRefs ( iterator - > expr ( 0 ) , names ) ;
if ( names . find ( identSymbol - > identifier ( ) ) ! = names . end ( ) )
{
__spf_print ( 1 , " wrong parallel region identifier: variable '%s' was declared on line %d on line %d \n " ,
identSymbol - > identifier ( ) , iterator - > lineNumber ( ) , st - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " wrong parallel region identifier: variable '%s' was declared on line %d " ,
to_wstring ( identSymbol - > identifier ( ) ) . c_str ( ) , iterator - > lineNumber ( ) ) ;
__spf_printToLongBuf ( messageR , R63 ,
to_wstring ( identSymbol - > identifier ( ) ) . c_str ( ) , iterator - > lineNumber ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1031 ) ) ;
retVal = false ;
}
}
}
else
break ;
}
if ( commonBlocks )
{
// common blocks checking
for ( auto & commonBlockPair : * commonBlocks )
{
for ( auto & variable : commonBlockPair . second - > getVariables ( ) )
{
if ( variable - > getName ( ) = = identSymbol - > identifier ( ) )
{
__spf_print ( 1 , " wrong parallel region identifier: variable '%s' was declared in common block '%s' on line %d \n " ,
identSymbol - > identifier ( ) , commonBlockPair . first . c_str ( ) , st - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " wrong parallel region identifier: variable '%s' was declared in common block '%s' " ,
to_wstring ( identSymbol - > identifier ( ) ) . c_str ( ) , to_wstring ( commonBlockPair . first ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R64 ,
to_wstring ( identSymbol - > identifier ( ) ) . c_str ( ) , to_wstring ( commonBlockPair . first ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1032 ) ) ;
retVal = false ;
}
}
}
}
// try to find SPF_END_PARALLEL_REG_DIR
iterator = st - > lexNext ( ) ;
bool found = false ;
for ( ; iterator & & ! found ; iterator = iterator - > lexNext ( ) )
{
const int var = iterator - > variant ( ) ;
if ( var = = SPF_PARALLEL_REG_DIR )
{
// intersection
__spf_print ( 1 , " bad directive position: expected 'SPF END PARALLEL_REG_DIR' for identificator '%s', but got 'SPF PARALLEL_REG_DIR' on line %d \n " ,
identSymbol - > identifier ( ) , st - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive position: expected 'SPF END PARALLEL_REG_DIR' for identificator '%s', but got 'SPF PARALLEL_REG_DIR' " ,
to_wstring ( identSymbol - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R4 ,
to_wstring ( identSymbol - > identifier ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1001 ) ) ;
retVal = false ;
break ;
}
else if ( var = = SPF_END_PARALLEL_REG_DIR )
{
found = true ;
if ( iterator - > controlParent ( ) ! = st - > controlParent ( ) )
{
__spf_print ( 1 , " bad directive position: expected 'SPF END PARALLEL_REG_DIR' for identificator '%s' at the same scope on line %d \n " ,
identSymbol - > identifier ( ) , st - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive position: expected 'SPF END PARALLEL_REG_DIR' for identificator '%s' at the same scope " ,
to_wstring ( identSymbol - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R5 ,
to_wstring ( identSymbol - > identifier ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1001 ) ) ;
retVal = false ;
}
break ;
}
}
if ( ! found & & retVal )
{
__spf_print ( 1 , " bad directive position: expected 'SPF END PARALLEL_REG_DIR' for identificator '%s' on line %d \n " , identSymbol - > identifier ( ) , st - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive position: expected 'SPF END PARALLEL_REG_DIR' for identificator '%s' " ,
to_wstring ( identSymbol - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R6 ,
to_wstring ( identSymbol - > identifier ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1001 ) ) ;
retVal = false ;
}
}
else
{
// type == SPF_END_PARALLEL_REG_DIR
// try to find SPF_PARALLEL_REG_DIR
SgStatement * iterator = st - > lexPrev ( ) ;
SgStatement * end = st - > controlParent ( ) ;
bool found = false ;
for ( ; iterator ! = end & & retVal & & ! found ; iterator = iterator - > lexPrev ( ) )
{
const int var = iterator - > variant ( ) ;
if ( var = = SPF_END_PARALLEL_REG_DIR )
{
// intersection
__spf_print ( 1 , " bad directive position: expected 'SPF PARALLEL_REG_DIR', but got 'SPF END PARALLEL_REG_DIR' on line %d \n " , st - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive position: expected 'SPF PARALLEL_REG_DIR', but got 'SPF END PARALLEL_REG_DIR' " ) ;
__spf_printToLongBuf ( messageR , R7 ) ;
messagesForFile . push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1001 ) ) ;
retVal = false ;
break ;
}
else if ( var = = SPF_PARALLEL_REG_DIR )
{
found = true ;
if ( iterator - > controlParent ( ) ! = st - > controlParent ( ) )
{
__spf_print ( 1 , " bad directive position: expected 'SPF PARALLEL_REG_DIR' at the same scope on line %d \n " , st - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive position: expected 'SPF PARALLEL_REG_DIR' at the same scope " ) ;
__spf_printToLongBuf ( messageR , R8 ) ;
messagesForFile . push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1001 ) ) ;
retVal = false ;
}
break ;
}
}
if ( ! found & & retVal )
{
__spf_print ( 1 , " bad directive position: expected 'SPF PARALLEL_REG_DIR' on line %d \n " , st - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive position: expected 'SPF PARALLEL_REG_DIR' " ) ;
__spf_printToLongBuf ( messageR , R9 ) ;
messagesForFile . push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1001 ) ) ;
retVal = false ;
}
}
}
else
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " after " , RR1_4 , " " , L " " , " all declaration statements " , RR1_5 , st - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
retVal = false ;
}
return retVal ;
}
static inline void addSPFtoAttr ( SgStatement * st , const string & currFile , map < pair < string , int > , set < SgStatement * > > & usersDirectives )
{
bool cond = false ;
SgStatement * iterator = skipDvmDirs ( st ) ;
vector < pair < SgStatement * , bool > > attributesToProcess ;
do
{
SgStatement * prev = iterator - > lexPrev ( ) ;
const int prevVar = prev - > variant ( ) ;
cond = ( isSPF_stat ( prev ) & & prevVar ! = SPF_END_PARALLEL_REG_DIR ) ;
if ( cond )
{
if ( ( prev - > fileName ( ) = = currFile ) & & prevVar ! = SPF_PARALLEL_REG_DIR )
attributesToProcess . push_back ( std : : make_pair ( prev , true ) ) ;
else
attributesToProcess . push_back ( std : : make_pair ( prev , false ) ) ;
iterator = prev ;
}
} while ( cond ) ;
//save direct order of SPF from source code
std : : reverse ( attributesToProcess . begin ( ) , attributesToProcess . end ( ) ) ;
for ( auto & attr : attributesToProcess )
{
addToattribute ( attr . first , st , attr . first - > variant ( ) ) ;
auto copy = attr . first - > copyPtr ( ) ;
copy - > setlineNumber ( attr . first - > lineNumber ( ) ) ;
copy - > setLocalLineNumber ( attr . first - > localLineNumber ( ) ) ;
usersDirectives [ std : : make_pair ( st - > fileName ( ) , st - > lineNumber ( ) ) ] . insert ( copy ) ;
if ( attr . second )
attr . first - > deleteStmt ( ) ;
}
}
static bool checkFissionPrivatesExpansion ( SgStatement * st ,
SgStatement * attributeStatement ,
const string & currFile ,
vector < Messages > & messagesForFile ,
map < pair < string , int > , set < SgStatement * > > & usersDirectives ,
bool checkVars = false )
{
bool retVal = true ;
if ( attributeStatement )
{
vector < string > vars ;
fillFissionPrivatesExpansionFromComment ( new Statement ( attributeStatement ) , vars ) ;
if ( checkVars & & ! vars . size ( ) )
{
__spf_print ( 1 , " bad directive expression: expected list of variables on line %d \n " , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive expression: expected list of variables " ) ;
__spf_printToLongBuf ( messageR , R76 ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1043 ) ) ;
retVal = false ;
}
if ( vars . size ( ) )
{
// move next SPF directives to atributes
for ( auto s = st ; s ! = st - > lastNodeOfStmt ( ) - > lexNext ( ) ; s = s - > lexNext ( ) )
addSPFtoAttr ( s , currFile , usersDirectives ) ;
SgForStmt * forSt = ( SgForStmt * ) st ;
2024-04-09 16:41:48 +03:00
const int nestedCount = countPerfectLoopNest ( forSt ) ;
if ( vars . size ( ) > nestedCount )
2023-09-14 19:43:13 +03:00
{
__spf_print ( 1 , " bad directive expression: expected %d nested loops on line %d but got %d on line %d \n " ,
2024-04-09 16:41:48 +03:00
( int ) vars . size ( ) , attributeStatement - > lineNumber ( ) , nestedCount , st - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive expression: expected %d nested loops on line %d but got %d " ,
2024-04-09 16:41:48 +03:00
( int ) vars . size ( ) , attributeStatement - > lineNumber ( ) , nestedCount ) ;
2023-09-14 19:43:13 +03:00
2024-04-09 16:41:48 +03:00
__spf_printToLongBuf ( messageR , R77 , ( int ) vars . size ( ) , attributeStatement - > lineNumber ( ) , nestedCount ) ;
2023-09-14 19:43:13 +03:00
messagesForFile . push_back ( Messages ( ERROR , st - > lineNumber ( ) , messageR , messageE , 1043 ) ) ;
retVal = false ;
}
}
for ( int i = 0 ; retVal & & i < vars . size ( ) ; + + i )
{
SgForStmt * forSt = ( SgForStmt * ) st ;
if ( forSt - > doName ( ) - > identifier ( ) ! = vars [ i ] )
{
__spf_print ( 1 , " bad directive expression: expected variable '%s' at %d position on line %d \n " ,
forSt - > doName ( ) - > identifier ( ) , i + 1 , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " bad directive expression: expected variable '%s' at %d position " ,
to_wstring ( forSt - > doName ( ) - > identifier ( ) ) . c_str ( ) , i + 1 ) ;
__spf_printToLongBuf ( messageR , R78 ,
to_wstring ( forSt - > doName ( ) - > identifier ( ) ) . c_str ( ) , i + 1 ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1043 ) ) ;
retVal = false ;
}
st = st - > lexNext ( ) ;
}
}
return retVal ;
}
static bool checkShrink ( SgStatement * st ,
SgStatement * attributeStatement ,
const string & currFile ,
vector < Messages > & messagesForFile )
{
bool retVal = true ;
vector < pair < Symbol * , vector < int > > > varDims ;
fillShrinkFromComment ( new Statement ( attributeStatement ) , varDims ) ;
for ( auto & p : varDims )
{
auto var = p . first - > GetOriginal ( ) ;
auto dims = p . second ;
// check variable type
SgArrayType * arrType = isSgArrayType ( var - > type ( ) ) ;
if ( ! arrType )
{
__spf_print ( 1 , " variable in shrink clause must be array in file '%s' on line %d \n " , st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " variable in shrink clause must be array in file '%s' " , to_wstring ( st - > fileName ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R154 , to_wstring ( st - > fileName ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1053 ) ) ;
retVal = false ;
}
else
{
// check private directives
set < Symbol * > privatesS ;
set < SgSymbol * > privates ;
for ( int i = 0 ; i < st - > numberOfAttributes ( ) ; + + i )
{
SgAttribute * attr = st - > getAttribute ( i ) ;
SgStatement * attributeStatement = ( SgStatement * ) ( attr - > getAttributeData ( ) ) ;
fillPrivatesFromComment ( new Statement ( attributeStatement ) , privatesS ) ;
}
for ( auto & elem : privatesS )
privates . insert ( elem - > GetOriginal ( ) ) ;
auto it = privates . find ( var ) ;
if ( it = = privates . end ( ) )
{
__spf_print ( 1 , " array '%s' in shrink clause must be also declared in private clause in file '%s' on line %d \n " ,
var - > identifier ( ) , st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " array '%s' in shrink clause must be also declared in private clause in file '%s' " ,
to_wstring ( var - > identifier ( ) ) . c_str ( ) , to_wstring ( st - > fileName ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R157 , to_wstring ( var - > identifier ( ) ) . c_str ( ) , to_wstring ( st - > fileName ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1056 ) ) ;
retVal = false ;
}
// check mask dimensions
if ( dims . size ( ) ! = arrType - > dimension ( ) )
{
__spf_print ( 1 , " length of mask for array '%s' must be %d, but you enter only %d dimenions in file '%s' on line %d \n " ,
var - > identifier ( ) , arrType - > dimension ( ) , dims . size ( ) , st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " length of mask for array '%s' must be %d, but you enter only %d dimenions in file '%s' " ,
to_wstring ( var - > identifier ( ) ) . c_str ( ) , arrType - > dimension ( ) , dims . size ( ) ,
to_wstring ( st - > fileName ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R155 , to_wstring ( var - > identifier ( ) ) . c_str ( ) , arrType - > dimension ( ) , dims . size ( ) , to_wstring ( st - > fileName ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1054 ) ) ;
retVal = false ;
}
for ( auto i = 0 ; i < dims . size ( ) ; + + i )
{
auto dimVal = dims [ i ] ;
if ( dimVal ! = 0 & & dimVal ! = 1 )
{
__spf_print ( 1 , " wrong mask value in %d position for array '%s': it can be only 0 or 1 in file '%s' on line %d \n " ,
i + 1 , var - > identifier ( ) , st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " wrong mask value in %d position of array '%s': it can be only 0 or 1 in file '%s' " ,
i + 1 , to_wstring ( var - > identifier ( ) ) . c_str ( ) , to_wstring ( st - > fileName ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R156 , i + 1 , to_wstring ( var - > identifier ( ) ) . c_str ( ) , to_wstring ( st - > fileName ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 1055 ) ) ;
retVal = false ;
}
}
}
}
return retVal ;
}
static bool recIsVarUsed ( SgStatement * st , SgExpression * exp , const string & varName )
{
if ( exp )
{
if ( exp - > symbol ( ) & & exp - > symbol ( ) - > identifier ( ) = = varName )
return true ;
return recIsVarUsed ( st , exp - > lhs ( ) , varName ) | | recIsVarUsed ( st , exp - > rhs ( ) , varName ) ;
}
return false ;
}
static bool isVarUsed ( SgStatement * st , const string & varName , bool doNotGetFuncStat = false )
{
if ( st )
{
auto funcSt = doNotGetFuncStat ? st : getFuncStat ( st ) ;
checkNull ( funcSt , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
for ( auto st = funcSt ; st ! = funcSt - > lastNodeOfStmt ( ) ; st = st - > lexNext ( ) )
{
for ( auto i = 0 ; i < 3 ; + + i )
{
bool found = recIsVarUsed ( st , st - > expr ( i ) , varName ) ;
if ( found )
return true ;
}
}
}
return false ;
}
static bool isModuleVar ( SgStatement * st ,
SgStatement * attributeStatement ,
const string & varName )
{
auto moduleSymbols = moduleRefsByUseInFunction ( st ) ;
// check renamed vars
for ( auto & elem : moduleSymbols )
for ( auto & var : elem . second )
if ( varName = = var - > identifier ( ) )
return true ;
// check all used modules in function
vector < SgStatement * > useStats ;
fillUsedModulesInFunction ( st , useStats ) ;
for ( auto & useSt : useStats )
{
map < string , SgSymbol * > visibleVars ;
fillVisibleInUseVariables ( useSt , visibleVars ) ;
if ( visibleVars . find ( varName ) ! = visibleVars . end ( ) )
return true ;
}
return false ;
}
static bool checkCheckpointVarsDecl ( SgStatement * st ,
SgStatement * attributeStatement ,
const set < Symbol * > & vars ,
const string & op ,
vector < Messages > & messagesForFile )
{
bool retVal = true ;
for ( auto & varS : vars )
{
auto var = varS - > GetOriginal ( ) ;
bool module = isModuleVar ( st , attributeStatement , var - > identifier ( ) ) ;
if ( ! module )
{
bool local = isVarUsed ( st , var - > identifier ( ) ) ;
if ( ! local )
{
__spf_print ( 1 , " Variable '%s' in %s clause must be declared at the same module in file '%s' on line %d. \n " ,
var - > identifier ( ) , op . c_str ( ) , st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " Variable '%s' in %s clause must be declared at the same module. " ,
to_wstring ( var - > identifier ( ) ) . c_str ( ) , to_wstring ( op ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R168 , to_wstring ( var - > identifier ( ) ) . c_str ( ) , to_wstring ( op ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 5004 ) ) ;
retVal = false ;
}
}
}
return retVal ;
}
static bool checkCheckpoint ( SgStatement * st ,
SgStatement * attributeStatement ,
const map < int , Expression * > & clauses ,
const set < Symbol * > & vars ,
const set < Symbol * > & expt ,
vector < Messages > & messagesForFile )
{
bool retVal = true ;
bool hasInterval = clauses . find ( SPF_INTERVAL_OP ) = = clauses . end ( ) ;
bool isExecutable = isSgExecutableStatement ( st ) ;
for ( auto & p : clauses )
{
auto op = p . first ;
SgExpression * exprList = p . second - > GetOriginal ( ) ;
switch ( op )
{
case SPF_INTERVAL_OP :
{
int count = 0 ;
while ( exprList )
{
if ( exprList - > lhs ( ) )
+ + count ;
exprList = exprList - > rhs ( ) ;
}
if ( count ! = 1 )
{
wstring messageE , messageR ;
__spf_print ( 1 , " INTERVAL clause can be used only once in file '%s' on line %d. \n " , st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
__spf_printToLongBuf ( messageE , L " INTERVAL clause can be used only once. " ) ;
__spf_printToLongBuf ( messageR , R170 , L " INTERVAL " ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 5006 ) ) ;
retVal = false ;
}
exprList = p . second - > lhs ( ) ;
if ( ! exprList | | exprList - > rhs ( ) - > variant ( ) ! = INT_VAL | |
exprList - > lhs ( ) - > variant ( ) ! = SPF_TIME_OP & & exprList - > lhs ( ) - > variant ( ) ! = SPF_ITER_OP )
{
wstring messageE , messageR ;
__spf_print ( 1 , " The first argument must be TIME or ITER and the second must be integer in INTERVAL clause in file '%s' on line %d. \n " ,
st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
__spf_printToLongBuf ( messageE , L " The first argument must be TIME or ITER and the second must be integer in INTERVAL clause. " ) ;
__spf_printToLongBuf ( messageR , R165 ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 5001 ) ) ;
retVal = false ;
}
if ( ! isExecutable )
{
wstring messageE , messageR ;
__spf_print ( 1 , " CHECKPOINT directive with INTERVAL clause can be only at executable code section in file '%s' on line %d. \n " ,
st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
__spf_printToLongBuf ( messageE , L " CHECKPOINT directive with INTERVAL clause can be only at executable code section. " ) ;
__spf_printToLongBuf ( messageR , R166 , L " INTERVAL " ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 5002 ) ) ;
retVal = false ;
}
break ;
}
case SPF_FILES_COUNT_OP :
{
if ( ! isExecutable )
{
wstring messageE , messageR ;
__spf_print ( 1 , " CHECKPOINT directive with FILES clause can be only at executable code section in file '%s' on line %d. \n " ,
st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
__spf_printToLongBuf ( messageE , L " CHECKPOINT directive with FILES clause can be only at executable code section. " ) ;
__spf_printToLongBuf ( messageR , R166 , L " CHECKPOINT " , L " FILES " ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 5002 ) ) ;
retVal = false ;
}
int count = 0 ;
while ( exprList )
{
if ( exprList - > lhs ( ) )
+ + count ;
exprList = exprList - > rhs ( ) ;
}
exprList = p . second ;
if ( count ! = 1 )
{
wstring messageE , messageR ;
__spf_print ( 1 , " FILES clause can be used only once in file '%s' on line %d. \n " ,
st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
__spf_printToLongBuf ( messageE , L " FILES clause can be used only once. " ) ;
__spf_printToLongBuf ( messageR , R170 , L " FILES " ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 5006 ) ) ;
retVal = false ;
}
if ( exprList & & exprList - > lhs ( ) - > variant ( ) ! = INT_VAL )
{
wstring messageE , messageR ;
__spf_print ( 1 , " CHECKPOINT directive with FILES clause must contain integer value in file '%s' on line %d. \n " ,
st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
__spf_printToLongBuf ( messageE , L " CHECKPOINT directive with FILES clause must contain integer value. " ) ;
__spf_printToLongBuf ( messageR , R167 ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 5003 ) ) ;
retVal = false ;
}
break ;
}
case SPF_VARLIST_OP :
{
retVal = retVal & & checkCheckpointVarsDecl ( st , attributeStatement , vars , string ( " VARLIST " ) , messagesForFile ) ;
for ( auto & varS : vars )
{
if ( expt . find ( varS ) ! = expt . end ( ) )
{
wstring messageE , messageR ;
__spf_print ( 1 , " Variable '%s' can't be used in FILES and EXCEPT clauses at the same time in file '%s' on line %d. \n " ,
varS - > GetOriginal ( ) - > identifier ( ) , st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
__spf_printToLongBuf ( messageE , L " Variable '%s' can't be used in FILES and EXCEPT clauses at the same time. " ,
to_wstring ( varS - > GetOriginal ( ) - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R172 , to_wstring ( varS - > GetOriginal ( ) - > identifier ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 5007 ) ) ;
retVal = false ;
}
}
break ;
}
case SPF_EXCEPT_OP :
{
retVal = retVal & & checkCheckpointVarsDecl ( st , attributeStatement , vars , string ( " EXEPT " ) , messagesForFile ) ;
break ;
}
case SPF_TYPE_OP :
{
int count = 0 ;
exprList = exprList - > rhs ( ) ;
while ( exprList )
{
if ( exprList - > lhs ( ) & & exprList - > lhs ( ) - > variant ( ) ! = ACC_ASYNC_OP & & exprList - > lhs ( ) - > variant ( ) ! = SPF_FLEXIBLE_OP )
{
wstring messageE , messageR ;
__spf_print ( 1 , " Illegal option in TYPE clause in file '%s' on line %d. \n " , st - > fileName ( ) , attributeStatement - > lineNumber ( ) ) ;
__spf_printToLongBuf ( messageE , L " Illegal option in TYPE clause. " ) ;
__spf_printToLongBuf ( messageR , R169 ) ;
messagesForFile . push_back ( Messages ( ERROR , attributeStatement - > lineNumber ( ) , messageR , messageE , 5005 ) ) ;
retVal = false ;
}
+ + count ;
exprList = exprList - > rhs ( ) ;
}
break ;
}
default :
retVal = false ;
break ;
}
}
return retVal ;
}
static int countSPF_OP ( SgStatement * st , const int type , const int op )
{
int count = 0 ;
if ( st )
{
for ( auto & data : getAttributes < SgStatement * , SgStatement * > ( st , set < int > { type } ) )
{
SgExpression * exprList = data - > expr ( 0 ) ;
while ( exprList )
{
if ( exprList - > lhs ( ) - > variant ( ) = = op )
+ + count ;
exprList = exprList - > rhs ( ) ;
}
}
}
return count ;
}
static bool isSPF_OP ( SgStatement * st , const int op )
{
if ( st )
{
SgExpression * exprList = st - > expr ( 0 ) ;
while ( exprList )
{
if ( exprList - > lhs ( ) & & exprList - > lhs ( ) - > variant ( ) = = op )
return true ;
exprList = exprList - > rhs ( ) ;
}
}
return false ;
}
static inline bool processStat ( SgStatement * st , const string & currFile ,
const map < string , CommonBlock * > * commonBlocks ,
vector < Messages > & messagesForFile ,
map < pair < string , int > , set < SgStatement * > > & usersDirectives )
{
bool retVal = true ;
if ( st - > variant ( ) = = SPF_PARALLEL_REG_DIR | | st - > variant ( ) = = SPF_END_PARALLEL_REG_DIR )
{
bool result = checkParallelRegions ( st , commonBlocks , messagesForFile ) ;
retVal = retVal & & result ;
}
// ignore SPF statements
if ( isSPF_stat ( st ) )
return retVal ;
addSPFtoAttr ( st , currFile , usersDirectives ) ;
for ( int i = 0 ; i < st - > numberOfAttributes ( ) ; + + i )
{
SgAttribute * attr = st - > getAttribute ( i ) ;
SgStatement * attributeStatement = ( SgStatement * ) ( attr - > getAttributeData ( ) ) ;
int type = st - > attributeType ( i ) ;
2024-04-09 16:41:48 +03:00
int count ;
2023-09-14 19:43:13 +03:00
if ( type = = SPF_ANALYSIS_DIR )
{
// !$SPF ANALYSIS
// PRIVATE(VAR)
set < Symbol * > privates ;
2024-04-09 16:41:48 +03:00
fillPrivatesFromComment ( new Statement ( attributeStatement ) , privates , ACC_PRIVATE_OP ) ;
2023-09-14 19:43:13 +03:00
if ( privates . size ( ) )
{
bool result = checkPrivate ( st , attributeStatement , privates , messagesForFile ) ;
retVal = retVal & & result ;
}
2024-04-09 16:41:48 +03:00
// PROCESS_PRIVATE(VAR)
privates . clear ( ) ;
fillPrivatesFromComment ( new Statement ( attributeStatement ) , privates , SPF_PROCESS_PRIVATE_OP ) ;
if ( privates . size ( ) )
{
bool result = checkProcessPrivate ( st , attributeStatement , privates , messagesForFile ) ;
retVal = retVal & & result ;
}
2023-09-14 19:43:13 +03:00
// REDUCTION(OP(VAR), MIN/MAXLOC(VAR, ARRAY, CONST))
map < string , set < Symbol * > > reduction ;
map < string , set < tuple < Symbol * , Symbol * , int > > > reductionLoc ;
fillReductionsFromComment ( new Statement ( attributeStatement ) , reduction ) ;
fillReductionsFromComment ( new Statement ( attributeStatement ) , reductionLoc ) ;
if ( reduction . size ( ) )
{
bool result = checkReduction ( st , attributeStatement , reduction , messagesForFile ) ;
bool resultLoc = checkReduction ( st , attributeStatement , reductionLoc , messagesForFile ) ;
retVal = retVal & & result & & resultLoc ;
}
// PARAMETER(ident=expr)
vector < pair < Expression * , Expression * > > assigns ;
fillParameterFromComment ( new Statement ( attributeStatement ) , assigns ) ;
if ( assigns . size ( ) )
{
bool result = checkParameter ( st , attributeStatement , assigns , messagesForFile ) ;
retVal = retVal & & result ;
}
2024-04-09 16:41:48 +03:00
// COVER
if ( isSPF_OP ( attributeStatement , SPF_COVER_OP ) & & ( count = countSPF_OP ( st , SPF_ANALYSIS_DIR , SPF_COVER_OP ) ) )
{
attributeStatement - > setLocalLineNumber ( - 1 ) ;
if ( count > 1 | | st - > variant ( ) ! = FOR_NODE )
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " once " , RR1_7 , " before " , RR1_1 , " DO statement " , RR1_3 , attributeStatement - > lineNumber ( ) ) ;
2024-04-09 16:41:48 +03:00
retVal = false ;
}
else
{
bool result = checkCover ( st , attributeStatement , getCoverPropertyFromComment ( new Statement ( attributeStatement ) ) , messagesForFile ) ;
retVal = retVal & & result ;
}
}
2023-09-14 19:43:13 +03:00
}
else if ( type = = SPF_PARALLEL_DIR )
{
// !$SPF PARALLEL
2024-04-09 16:41:48 +03:00
2023-09-14 19:43:13 +03:00
// SHADOW (VAR(list of shadows)) / ACROSS (VAR(list of shadows))
vector < pair < pair < Symbol * , string > , vector < pair < int , int > > > > data ;
fillShadowAcrossFromComment ( SHADOW_OP , new Statement ( attributeStatement ) , data ) ;
fillShadowAcrossFromComment ( ACROSS_OP , new Statement ( attributeStatement ) , data ) ;
if ( data . size ( ) )
{
bool result = checkShadowAcross ( st , attributeStatement , data , messagesForFile ) ;
retVal = retVal & & result ;
}
// REMOTE_ACCESS (EXPR)
map < pair < Symbol * , string > , Expression * > remote ;
fillRemoteFromComment ( new Statement ( attributeStatement ) , remote , true ) ;
if ( remote . size ( ) )
{
bool result = checkRemote ( st , attributeStatement , remote , messagesForFile ) ;
retVal = retVal & & result ;
}
}
else if ( type = = SPF_TRANSFORM_DIR )
{
// !$SPF TRANSFORM
// NOINLINE
if ( isSPF_NoInline ( new Statement ( st ) ) )
{
SgStatement * prev = st - > lexPrev ( ) ;
const int prevVar = prev - > variant ( ) ;
if ( prevVar ! = PROC_HEDR & & prevVar ! = FUNC_HEDR )
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " after " , RR1_4 , " " , L " " , " function statements " , RR1_6 , attributeStatement - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
retVal = false ;
}
}
// FISSION
if ( isSPF_OP ( attributeStatement , SPF_FISSION_OP ) & & ( count = countSPF_OP ( st , SPF_TRANSFORM_DIR , SPF_FISSION_OP ) ) )
{
attributeStatement - > setLocalLineNumber ( - 1 ) ;
if ( count > 1 | | st - > variant ( ) ! = FOR_NODE )
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " once " , RR1_7 , " before " , RR1_1 , " DO statement " , RR1_3 , attributeStatement - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
retVal = false ;
}
else
{
bool result = checkFissionPrivatesExpansion ( st , attributeStatement , currFile , messagesForFile , usersDirectives , true ) ;
retVal = retVal & & result ;
}
}
// PRIVATES_EXPANSION
if ( isSPF_OP ( attributeStatement , SPF_EXPAND_OP ) & & ( count = countSPF_OP ( st , SPF_TRANSFORM_DIR , SPF_EXPAND_OP ) ) )
{
attributeStatement - > setLocalLineNumber ( - 1 ) ;
if ( count > 1 | | st - > variant ( ) ! = FOR_NODE )
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " once " , RR1_7 , " before " , RR1_1 , " DO statement " , RR1_3 , attributeStatement - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
retVal = false ;
}
else
{
bool result = checkFissionPrivatesExpansion ( st , attributeStatement , currFile , messagesForFile , usersDirectives ) ;
retVal = retVal & & result ;
}
}
// SHRINK
if ( isSPF_OP ( attributeStatement , SPF_SHRINK_OP ) )
{
2024-04-09 16:41:48 +03:00
attributeStatement - > setLocalLineNumber ( - 1 ) ;
2023-09-14 19:43:13 +03:00
if ( st - > variant ( ) ! = FOR_NODE )
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " " , " " , " before " , RR1_1 , " DO statement " , RR1_3 , attributeStatement - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
retVal = false ;
}
else
{
bool result = checkShrink ( st , attributeStatement , currFile , messagesForFile ) ;
retVal = retVal & & result ;
}
}
// UNROLL
if ( isSPF_OP ( attributeStatement , SPF_UNROLL_OP ) )
{
attributeStatement - > setLocalLineNumber ( - 1 ) ;
if ( st - > variant ( ) ! = FOR_NODE )
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " " , " " , " before " , RR1_1 , " DO statement " , RR1_3 , attributeStatement - > lineNumber ( ) ) ;
2023-09-14 19:43:13 +03:00
retVal = false ;
}
}
2024-04-09 16:41:48 +03:00
// MERGE
if ( isSPF_OP ( attributeStatement , SPF_MERGE_OP ) )
{
attributeStatement - > setLocalLineNumber ( - 1 ) ;
if ( st - > variant ( ) ! = FOR_NODE )
{
2024-04-10 13:42:49 +03:00
BAD_POSITION_FULL ( ERROR , " " , " " , " before " , RR1_1 , " DO statement " , RR1_3 , attributeStatement - > lineNumber ( ) ) ;
2024-04-09 16:41:48 +03:00
retVal = false ;
}
}
2023-09-14 19:43:13 +03:00
}
else if ( type = = SPF_CHECKPOINT_DIR )
{
map < int , Expression * > clauses ;
set < Symbol * > vars , expt ;
fillCheckpointFromComment ( new Statement ( attributeStatement ) , clauses , vars , expt ) ;
if ( clauses . size ( ) )
{
bool result = checkCheckpoint ( st , attributeStatement , clauses , vars , expt , messagesForFile ) ;
retVal = retVal & & result ;
}
}
}
return retVal ;
}
static bool checkContainsRegion ( SgStatement * st , const string & currFile ,
const map < string , CommonBlock * > * commonBlocks , vector < Messages > & messagesForFile ,
map < pair < string , int > , set < SgStatement * > > & usersDirectives )
{
bool retVal = true ;
if ( st - > variant ( ) ! = CONTAINS_STMT )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
do
{
st = st - > lexNext ( ) ;
bool result = processStat ( st , currFile , commonBlocks , messagesForFile , usersDirectives ) ;
retVal = retVal & & result ;
} while ( ! isSgProgHedrStmt ( st ) & & st - > variant ( ) ! = CONTROL_END ) ;
return retVal ;
}
static bool processModules ( vector < SgStatement * > & modules , const string & currFile , const map < string , CommonBlock * > * commonBlocks ,
vector < Messages > & messagesForFile , const set < string > & allFileNames ,
map < pair < string , int > , set < SgStatement * > > & usersDirectives )
{
bool retVal = true ;
for ( int i = 0 ; i < modules . size ( ) ; + + i )
{
SgStatement * modIterator = modules [ i ] ;
SgStatement * modEnd = modules [ i ] - > lastNodeOfStmt ( ) ;
// skip included file
const string modFile = modIterator - > fileName ( ) ;
if ( modFile ! = currFile & & allFileNames . find ( modFile ) ! = allFileNames . end ( ) )
continue ;
do
{
modIterator = modIterator - > lexNext ( ) ;
if ( modIterator - > variant ( ) = = CONTAINS_STMT )
{
bool result = checkContainsRegion ( modIterator , currFile , commonBlocks , messagesForFile , usersDirectives ) ;
retVal = retVal & & result ;
break ;
}
bool result = processStat ( modIterator , currFile , commonBlocks , messagesForFile , usersDirectives ) ;
retVal = retVal & & result ;
SgStatement * next = modIterator - > lexNext ( ) ;
if ( next )
if ( next - > variant ( ) = = SPF_END_PARALLEL_REG_DIR )
addToattribute ( next , modIterator , SPF_END_PARALLEL_REG_DIR ) ;
} while ( modIterator ! = modEnd ) ;
}
return retVal ;
}
bool check_par_reg_dirs ( SgFile * file , vector < Messages > & messagesForFile )
{
int funcNum = file - > numberOfFunctions ( ) ;
const string currFile = file - > filename ( ) ;
bool noError = true ;
for ( int i = 0 ; i < funcNum ; + + i )
{
SgStatement * st = file - > functions ( i ) ;
SgStatement * lastNode = st - > lastNodeOfStmt ( ) ;
while ( st ! = lastNode )
{
if ( st = = NULL )
{
__spf_print ( 1 , " internal error in analysis, parallel directives will not be generated for this file! \n " ) ;
break ;
}
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
if ( st - > variant ( ) = = SPF_PARALLEL_REG_DIR | | st - > variant ( ) = = SPF_END_PARALLEL_REG_DIR )
{
bool result = checkParallelRegions ( st , NULL , messagesForFile ) ;
noError = noError & & result ;
}
st = st - > lexNext ( ) ;
}
}
return noError ;
}
2024-04-12 16:36:37 +03:00
static void distributeAnalysisWithCover ( SgFile * file )
{
int funcNum = file - > numberOfFunctions ( ) ;
const string currFile = file - > filename ( ) ;
for ( int i = 0 ; i < funcNum ; + + i )
{
SgStatement * st = file - > functions ( i ) ;
SgStatement * lastNode = st - > lastNodeOfStmt ( ) ;
map < SgStatement * , pair < set < SgStatement * > , int > > spfAnalysis ;
do
{
st = st - > lexNext ( ) ;
if ( st = = NULL )
{
__spf_print ( 1 , " internal error in analysis, parallel directives will not be generated for this file! \n " ) ;
break ;
}
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
if ( st - > variant ( ) = = FOR_NODE )
{
pair < set < SgStatement * > , int > newData = { set < SgStatement * > ( ) , 0 } ;
for ( auto & data : getAttributes < SgStatement * , SgStatement * > ( st , set < int > { SPF_ANALYSIS_DIR } ) )
{
newData . first . insert ( data ) ;
int cover = getCoverPropertyFromComment ( new Statement ( data ) ) ;
if ( cover ! = 0 )
newData . second = cover ;
}
if ( newData . first . size ( ) )
spfAnalysis [ st ] = newData ;
}
} while ( st ! = lastNode ) ;
for ( auto & data : spfAnalysis )
{
SgForStmt * st = isSgForStmt ( data . first ) ;
checkNull ( st , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
int level = st - > isPerfectLoopNest ( ) ;
if ( data . second . second < level & & data . second . second ! = 0 )
level = data . second . second ;
for ( int z = 0 ; z < level - 1 ; + + z )
{
st = isSgForStmt ( st - > lexNext ( ) ) ;
checkNull ( st , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
for ( auto & dirs : data . second . first )
{
auto copy = dirs - > copyPtr ( ) ;
copy - > setLocalLineNumber ( SPF_USER_DIR_COPY ) ;
st - > addAttribute ( copy - > variant ( ) , copy , sizeof ( SgStatement ) ) ;
}
}
}
}
}
2023-09-14 19:43:13 +03:00
bool preprocess_spf_dirs ( SgFile * file , const map < string , CommonBlock * > & commonBlocks , vector < Messages > & messagesForFile , const set < string > & allFileNames ,
map < pair < string , int > , set < SgStatement * > > & usersDirectives )
{
int funcNum = file - > numberOfFunctions ( ) ;
const string currFile = file - > filename ( ) ;
bool noError = true ;
for ( int i = 0 ; i < funcNum ; + + i )
{
SgStatement * st = file - > functions ( i ) ;
SgStatement * lastNode = st - > lastNodeOfStmt ( ) ;
do
{
st = st - > lexNext ( ) ;
if ( st = = NULL )
{
__spf_print ( 1 , " internal error in analysis, parallel directives will not be generated for this file! \n " ) ;
break ;
}
if ( st - > variant ( ) = = CONTAINS_STMT )
{
bool result = checkContainsRegion ( st , currFile , & commonBlocks , messagesForFile , usersDirectives ) ;
noError = noError & & result ;
break ;
}
bool result = processStat ( st , currFile , & commonBlocks , messagesForFile , usersDirectives ) ;
noError = noError & & result ;
SgStatement * next = st - > lexNext ( ) ;
if ( next )
if ( next - > variant ( ) = = SPF_END_PARALLEL_REG_DIR )
addToattribute ( next , st , SPF_END_PARALLEL_REG_DIR ) ;
} while ( st ! = lastNode ) ;
}
vector < SgStatement * > modules ;
findModulesInFile ( file , modules ) ;
bool result = processModules ( modules , currFile , & commonBlocks , messagesForFile , allFileNames , usersDirectives ) ;
noError = noError & & result ;
2024-04-12 16:36:37 +03:00
if ( noError )
distributeAnalysisWithCover ( file ) ;
2023-09-14 19:43:13 +03:00
return noError ;
}
static void LinkTree ( SgExpression * mainExp , SgExpression * exp )
{
SgExpression * copyExp = & ( exp - > copy ( ) ) ;
SgExpression * rhs = mainExp - > rhs ( ) ;
while ( rhs )
{
SgExpression * a = rhs ;
rhs = mainExp - > rhs ( ) ;
mainExp = a ;
}
mainExp - > setRhs ( copyExp ) ;
}
static void OptimizeTree ( SgExpression * exp )
{
while ( exp )
{
SgExpression * checkExp = exp - > lhs ( ) ;
SgExpression * currExp = exp - > rhs ( ) ;
SgExpression * prevExp = exp ;
int var = checkExp - > variant ( ) ;
while ( currExp )
{
SgExpression * lhs = currExp - > lhs ( ) ;
SgExpression * rhs = currExp - > rhs ( ) ;
if ( lhs )
{
if ( lhs - > variant ( ) = = var )
{
prevExp - > setRhs ( rhs ) ;
LinkTree ( checkExp - > lhs ( ) , lhs - > lhs ( ) ) ;
}
else
prevExp = currExp ;
currExp = rhs ;
}
}
exp = exp - > rhs ( ) ;
}
}
static SgStatement * UniteAttributes ( const vector < SgStatement * > & sameAtt )
{
set < string > uniqAttrs ;
SgStatement * toAddExp = NULL ;
for ( auto & elem : sameAtt )
{
if ( elem - > expr ( 0 ) = = NULL )
continue ;
const string currAtr ( elem - > unparse ( ) ) ;
auto it = uniqAttrs . find ( currAtr ) ;
if ( it = = uniqAttrs . end ( ) )
uniqAttrs . insert ( it , currAtr ) ;
else
continue ;
if ( toAddExp )
{
SgExpression * exp = elem - > expr ( 0 ) ;
LinkTree ( toAddExp - > expr ( 0 ) , exp ) ;
}
else
toAddExp = & ( elem - > copy ( ) ) ;
}
if ( toAddExp )
OptimizeTree ( toAddExp - > expr ( 0 ) ) ;
//check null of expressions
if ( toAddExp )
{
vector < SgExpression * > list ;
SgExpression * ex = toAddExp - > expr ( 0 ) ;
bool deleted = false ;
while ( ex )
{
if ( ex - > lhs ( ) - > lhs ( ) )
list . push_back ( ex - > lhs ( ) ) ;
else
deleted = true ;
ex = ex - > rhs ( ) ;
}
if ( deleted )
toAddExp - > setExpression ( 0 , makeExprList ( list ) ) ;
}
return toAddExp ;
}
vector < SgStatement * > filterUserSpf ( const vector < SgStatement * > & toFilter , bool with_omp )
{
vector < SgStatement * > ret ;
for ( auto & elem : toFilter )
2024-04-12 16:36:37 +03:00
if ( elem - > localLineNumber ( ) = = SPF_USER_DIR | | ( elem - > localLineNumber ( ) = = SPF_OMP_DIR & & with_omp ) ) // user and omp
2023-09-14 19:43:13 +03:00
ret . push_back ( elem ) ;
return ret ;
}
//move PARAMETER to operator after a(1:N) = 0 to loop convertation
static bool moveSpfParameterForImplicitLoops ( SgStatement * st , SgStatement * toAdd )
{
bool moveNext = false ;
if ( st - > lineNumber ( ) < 0 & & st - > variant ( ) = = FOR_NODE )
{
for ( auto ex = toAdd - > expr ( 0 ) ; ex ; ex = ex - > rhs ( ) )
if ( ex - > lhs ( ) & & ex - > lhs ( ) - > variant ( ) = = SPF_PARAMETER_OP )
moveNext = true ;
if ( moveNext )
{
int countOp = 0 ;
for ( auto t = st - > lexNext ( ) ; t ! = st - > lastNodeOfStmt ( ) ; t = t - > lexNext ( ) )
countOp + + ;
if ( countOp = = 1 )
st - > lexNext ( ) - > insertStmtBefore ( * toAdd , * st - > lexNext ( ) - > controlParent ( ) ) ;
else
moveNext = false ;
}
}
return moveNext ;
}
2024-04-02 17:48:48 +03:00
static void insertBefore ( SgStatement * st , SgStatement * toAdd )
{
if ( toAdd = = NULL )
return ;
st - > insertStmtBefore ( * toAdd , * st - > controlParent ( ) ) ;
if ( st - > variant ( ) = = FOR_NODE )
{
auto com = st - > comments ( ) ;
if ( com )
{
st - > lexPrev ( ) - > addComment ( com ) ;
st - > delComments ( ) ;
}
}
}
2023-09-14 19:43:13 +03:00
void revertion_spf_dirs ( SgFile * file ,
map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > declaredArrays ,
map < SgStatement * , set < tuple < int , string , string > > > declaratedArraysSt )
{
const string fileName ( file - > filename ( ) ) ;
vector < SgStatement * > units ;
getModulesAndFunctions ( file , units ) ;
for ( int i = 0 ; i < units . size ( ) ; + + i )
{
SgStatement * st = units [ i ] ;
SgStatement * lastNode = st - > lastNodeOfStmt ( ) ;
for ( ; st ! = lastNode ; st = st - > lexNext ( ) )
{
if ( st = = NULL )
{
__spf_print ( 1 , " internal error in analysis, spf directives will not be returned for this file! \n " ) ;
break ;
}
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
if ( st - > variant ( ) < 0 )
continue ;
//analyze attributes
SgAttribute * atrib = st - > getAttribute ( 0 ) ;
SgStatement * toAdd = NULL ;
if ( atrib & & st - > fileName ( ) = = fileName )
{
//check previosly directives SPF_ANALYSIS
vector < SgStatement * > sameAtt = filterUserSpf ( getAttributes < SgStatement * , SgStatement * > ( st , set < int > { SPF_ANALYSIS_DIR } ) ) ;
if ( sameAtt . size ( ) )
{
toAdd = UniteAttributes ( sameAtt ) ;
if ( toAdd )
if ( ! moveSpfParameterForImplicitLoops ( st , toAdd ) )
2024-04-02 17:48:48 +03:00
insertBefore ( st , toAdd ) ;
2023-09-14 19:43:13 +03:00
}
//check previosly directives SPF_PARALLEL
if ( sameAtt . size ( ) )
{
sameAtt = filterUserSpf ( getAttributes < SgStatement * , SgStatement * > ( st , set < int > { SPF_PARALLEL_DIR } ) ) ;
for ( auto & elem : sameAtt )
{
if ( toAdd )
toAdd = UniteAttributes ( sameAtt ) ;
2024-04-02 17:48:48 +03:00
insertBefore ( st , toAdd ) ;
2023-09-14 19:43:13 +03:00
}
}
//remaining directives
sameAtt = filterUserSpf ( getAttributes < SgStatement * , SgStatement * > ( st , set < int > { SPF_CHECKPOINT_DIR , SPF_TRANSFORM_DIR , SPF_NOINLINE_OP , SPF_REGION_NAME } ) ) ;
if ( sameAtt . size ( ) )
{
for ( auto & elem : sameAtt )
{
SgStatement * data = ( SgStatement * ) atrib - > getAttributeData ( ) ;
SgStatement * toAdd = & ( data - > copy ( ) ) ;
if ( toAdd )
2024-04-02 17:48:48 +03:00
insertBefore ( st , toAdd ) ;
2023-09-14 19:43:13 +03:00
}
}
}
}
}
}
void addAcrossToLoops ( LoopGraph * topLoop ,
const map < SgSymbol * , tuple < int , int , int > > & acrossToAdd ,
const map < int , SgForStmt * > & allLoops ,
vector < Messages > & currMessages )
{
if ( acrossToAdd . size ( ) ! = 0 )
{
SgStatement * acrSpf = new SgStatement ( SPF_PARALLEL_DIR , NULL , NULL , NULL , NULL , NULL ) ;
SgExpression * exprList = new SgExpression ( EXPR_LIST , new SgExpression ( ACROSS_OP ) , NULL , NULL ) ;
acrSpf - > setExpression ( 0 , * exprList ) ;
exprList = exprList - > lhs ( ) ;
SgExpression * newList = new SgExpression ( EXPR_LIST ) ;
exprList - > setLhs ( newList ) ;
exprList = exprList - > lhs ( ) ;
int k = 0 ;
for ( auto it = acrossToAdd . begin ( ) ; it ! = acrossToAdd . end ( ) ; + + it , + + k )
{
SgSymbol * arrayS = it - > first ;
int pos = std : : get < 2 > ( it - > second ) ;
pair < int , int > ref = std : : make_pair ( std : : get < 0 > ( it - > second ) , std : : get < 1 > ( it - > second ) ) ;
SgArrayType * arrType = isSgArrayType ( arrayS - > type ( ) ) ;
if ( ! arrType )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( arrType - > dimension ( ) < = pos )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SgArrayRefExp * toAdd = new SgArrayRefExp ( * arrayS ) ;
for ( int z = 0 ; z < arrType - > dimension ( ) ; + + z )
{
if ( z = = pos )
{
SgValueExp * tmp = new SgValueExp ( ref . first ) ;
SgValueExp * tmp1 = new SgValueExp ( ref . second ) ;
SgExpression * tmp2 = new SgExpression ( DDOT , tmp , tmp1 , NULL ) ;
toAdd - > addSubscript ( * tmp2 ) ;
}
else
{
SgValueExp * tmp = new SgValueExp ( 0 ) ;
SgValueExp * tmp1 = new SgValueExp ( 0 ) ;
SgExpression * tmp2 = new SgExpression ( DDOT , tmp , tmp1 , NULL ) ;
toAdd - > addSubscript ( * tmp2 ) ;
}
}
exprList - > setLhs ( toAdd ) ;
if ( consoleMode )
printf ( " add across dependencies by array '%s' for loop on line %d \n " , arrayS - > identifier ( ) , topLoop - > lineNum ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " add across dependencies by array '%s' to loop " , to_wstring ( arrayS - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R108 , to_wstring ( arrayS - > identifier ( ) ) . c_str ( ) ) ;
currMessages . push_back ( Messages ( NOTE , topLoop - > lineNum , messageR , messageE , 3001 ) ) ;
if ( k ! = acrossToAdd . size ( ) - 1 )
{
SgExpression * tmp = new SgExpression ( EXPR_LIST ) ;
exprList - > setRhs ( tmp ) ;
exprList = exprList - > rhs ( ) ;
}
}
auto it = allLoops . find ( topLoop - > lineNum ) ;
if ( it = = allLoops . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
it - > second - > addAttribute ( SPF_PARALLEL_DIR , acrSpf , sizeof ( SgStatement ) ) ;
}
}
void addPrivatesToLoops ( LoopGraph * topLoop ,
const vector < const depNode * > & privatesToAdd ,
const map < int , SgForStmt * > & allLoops ,
vector < Messages > & currMessages )
{
if ( privatesToAdd . size ( ) ! = 0 )
{
vector < const depNode * > addForCurrLoop ;
for ( int i = 0 ; i < privatesToAdd . size ( ) ; + + i )
{
const int privLine = privatesToAdd [ i ] - > stmtin - > lineNumber ( ) ;
if ( topLoop - > lineNum < = privLine & & topLoop - > lineNumAfterLoop > privLine )
addForCurrLoop . push_back ( privatesToAdd [ i ] ) ;
}
if ( addForCurrLoop . size ( ) )
{
SgStatement * privSpf = new SgStatement ( SPF_ANALYSIS_DIR , NULL , NULL , NULL , NULL , NULL ) ;
SgExpression * tmp = new SgExpression ( ACC_PRIVATE_OP ) ;
SgExpression * exprList = new SgExpression ( EXPR_LIST , tmp , NULL , NULL ) ;
privSpf - > setExpression ( 0 , * exprList ) ;
exprList = exprList - > lhs ( ) ;
SgExpression * tmp1 = new SgExpression ( EXPR_LIST ) ;
exprList - > setLhs ( tmp1 ) ;
exprList = exprList - > lhs ( ) ;
auto itLoop = allLoops . find ( topLoop - > lineNum ) ;
if ( itLoop = = allLoops . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
set < string > added ;
for ( auto & data : getAttributes < SgStatement * , SgStatement * > ( itLoop - > second , set < int > { SPF_ANALYSIS_DIR } ) )
fillPrivatesFromComment ( new Statement ( data ) , added ) ;
int uniq = 0 ;
int k = 0 ;
while ( k ! = addForCurrLoop . size ( ) )
{
string identifier = addForCurrLoop [ k ] - > varin - > symbol ( ) - > identifier ( ) ;
auto itF = added . find ( identifier ) ;
if ( itF = = added . end ( ) )
itF = added . insert ( itF , identifier ) ;
else
{
addForCurrLoop . erase ( addForCurrLoop . begin ( ) + k ) ;
continue ;
}
k + + ;
uniq + + ;
}
for ( int k = 0 ; k < addForCurrLoop . size ( ) ; + + k )
{
string identifier = addForCurrLoop [ k ] - > varin - > symbol ( ) - > identifier ( ) ;
exprList - > setLhs ( addForCurrLoop [ k ] - > varin ) ;
if ( consoleMode )
printf ( " add private scalar '%s' for loop on line %d \n " , identifier . c_str ( ) , topLoop - > lineNum ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " add private scalar '%s' to loop on line %d " , to_wstring ( identifier ) . c_str ( ) , topLoop - > lineNum ) ;
__spf_printToLongBuf ( messageR , R109 , to_wstring ( identifier ) . c_str ( ) , topLoop - > lineNum ) ;
currMessages . push_back ( Messages ( NOTE , addForCurrLoop [ k ] - > stmtin - > lineNumber ( ) , messageR , messageE , 3002 ) ) ;
if ( k ! = addForCurrLoop . size ( ) - 1 )
{
SgExpression * tmp = new SgExpression ( EXPR_LIST ) ;
exprList - > setRhs ( tmp ) ;
exprList = exprList - > rhs ( ) ;
}
}
if ( uniq > 0 )
itLoop - > second - > addAttribute ( SPF_ANALYSIS_DIR , privSpf , sizeof ( SgStatement ) ) ;
}
}
}
static bool addReductionToList ( const char * oper , SgExpression * exprList , SgExpression * varin )
{
SgExpression * tmp3 = new SgKeywordValExp ( oper ) ;
SgExpression * tmp4 = new SgExpression ( ARRAY_OP , tmp3 , varin , NULL ) ;
exprList - > setLhs ( tmp4 ) ;
return true ;
}
void addReductionsToLoops ( LoopGraph * topLoop ,
const vector < const depNode * > & reductionsToAdd ,
const map < int , SgForStmt * > & allLoops ,
vector < Messages > & currMessages )
{
if ( reductionsToAdd . size ( ) ! = 0 )
{
vector < const depNode * > addForCurrLoop ;
for ( int i = 0 ; i < reductionsToAdd . size ( ) ; + + i )
{
const int privLine = reductionsToAdd [ i ] - > stmtin - > lineNumber ( ) ;
if ( topLoop - > lineNum < privLine & & topLoop - > lineNumAfterLoop > privLine )
addForCurrLoop . push_back ( reductionsToAdd [ i ] ) ;
}
if ( addForCurrLoop . size ( ) )
{
SgStatement * redSpf = new SgStatement ( SPF_ANALYSIS_DIR , NULL , NULL , NULL , NULL , NULL ) ;
SgExpression * tmp = new SgExpression ( REDUCTION_OP ) ;
SgExpression * exprList = new SgExpression ( EXPR_LIST , tmp , NULL , NULL ) ;
redSpf - > setExpression ( 0 , * exprList ) ;
exprList = exprList - > lhs ( ) ;
SgExpression * tmp1 = new SgExpression ( EXPR_LIST ) ;
exprList - > setLhs ( tmp1 ) ;
exprList = exprList - > lhs ( ) ;
bool wasAdd = false ;
for ( int k = 0 ; k < addForCurrLoop . size ( ) ; + + k )
{
if ( k ! = 0 & & wasAdd )
{
SgExpression * tmp = new SgExpression ( EXPR_LIST ) ;
exprList - > setRhs ( tmp ) ;
exprList = exprList - > rhs ( ) ;
}
wasAdd = false ;
const char * oper = NULL ;
switch ( addForCurrLoop [ k ] - > kinddep )
{
case SADDREDUCTION :
case DADDREDUCTION :
case IADDREDUCTION :
oper = " sum " ;
wasAdd = addReductionToList ( oper , exprList , addForCurrLoop [ k ] - > varin ) ;
break ;
case SMULREDUCTION :
case DMULREDUCTION :
case IMULREDUCTION :
oper = " product " ;
wasAdd = addReductionToList ( oper , exprList , addForCurrLoop [ k ] - > varin ) ;
break ;
case SDIVREDUCTION :
case DDIVREDUCTION :
case IDIVREDUCTION :
break ;
case SMAXREDUCTION :
case DMAXREDUCTION :
case IMAXREDUCTION :
oper = " max " ;
wasAdd = addReductionToList ( oper , exprList , addForCurrLoop [ k ] - > varin ) ;
break ;
case SMINREDUCTION :
case DMINREDUCTION :
case IMINREDUCTION :
oper = " min " ;
wasAdd = addReductionToList ( oper , exprList , addForCurrLoop [ k ] - > varin ) ;
break ;
case ANDREDUCTION :
oper = " and " ;
wasAdd = addReductionToList ( oper , exprList , addForCurrLoop [ k ] - > varin ) ;
break ;
case ORREDUCTION :
oper = " or " ;
wasAdd = addReductionToList ( oper , exprList , addForCurrLoop [ k ] - > varin ) ;
break ;
case EQVREDUCTION :
oper = " eqv " ;
wasAdd = addReductionToList ( oper , exprList , addForCurrLoop [ k ] - > varin ) ;
break ;
case NEQVREDUCTION :
oper = " neqv " ;
wasAdd = addReductionToList ( oper , exprList , addForCurrLoop [ k ] - > varin ) ;
break ;
default :
break ;
}
if ( wasAdd )
{
if ( consoleMode )
printf ( " add reduction scalar '%s' with operation '%s' to loop on line %d \n " , addForCurrLoop [ k ] - > varin - > symbol ( ) - > identifier ( ) , oper , topLoop - > lineNum ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " add reduction scalar '%s' with operation '%s' to loop on line %d " ,
to_wstring ( addForCurrLoop [ k ] - > varin - > symbol ( ) - > identifier ( ) ) . c_str ( ) , to_wstring ( oper ) . c_str ( ) , topLoop - > lineNum ) ;
__spf_printToLongBuf ( messageR , R110 ,
to_wstring ( addForCurrLoop [ k ] - > varin - > symbol ( ) - > identifier ( ) ) . c_str ( ) , to_wstring ( oper ) . c_str ( ) , topLoop - > lineNum ) ;
currMessages . push_back ( Messages ( NOTE , addForCurrLoop [ k ] - > stmtin - > lineNumber ( ) , messageR , messageE , 3003 ) ) ;
}
else
{
if ( consoleMode )
printf ( " unknown type of reduction scalar '%s' on line %d \n " , addForCurrLoop [ k ] - > varin - > symbol ( ) - > identifier ( ) , addForCurrLoop [ k ] - > stmtin - > lineNumber ( ) ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " unknown type of reduction scalar '%s' " , to_wstring ( addForCurrLoop [ k ] - > varin - > symbol ( ) - > identifier ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R111 , to_wstring ( addForCurrLoop [ k ] - > varin - > symbol ( ) - > identifier ( ) ) . c_str ( ) ) ;
currMessages . push_back ( Messages ( WARR , addForCurrLoop [ k ] - > stmtin - > lineNumber ( ) , messageR , messageE , 3004 ) ) ;
topLoop - > hasUnknownScalarDep = true ;
topLoop - > linesOfScalarDep . push_back ( addForCurrLoop [ k ] - > stmtin - > lineNumber ( ) ) ;
}
}
auto it = allLoops . find ( topLoop - > lineNum ) ;
if ( it = = allLoops . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
it - > second - > addAttribute ( SPF_ANALYSIS_DIR , redSpf , sizeof ( SgStatement ) ) ;
}
}
}