@@ -201,17 +201,30 @@ static void addMessageDependOnNonInvariant(vector<Messages>& messages, string va
messages . push_back ( Messages ( typeMessage : : WARR , lineNum , messageR , messageE , 2017 ) ) ;
}
static void addMessageDoesNotMachMask ( vector < Messages > & messages , string varName , int loopLneNum )
static void addMessageDoesNotMachMask ( vector < Messages > & messages , string varName , int loopLi neNum )
{
__spf_print ( 1 , " WARR: cannot remove private var '%s' in loop %d - it doesn't match any fixed dimensions mask \n " ,
varName . c_str ( ) , loopLneNum ) ;
varName . c_str ( ) , loopLi neNum ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " Cannot remove private var '%s' - it doesn't match any fixed dimensions mask " ,
to_wstring ( varName ) . c_str ( ) ) ;
__spf_printToLongBuf ( messageR , R188 , to_wstring ( varName ) . c_str ( ) ) ;
messages . push_back ( Messages ( typeMessage : : WARR , loopLneNum , messageR , messageE , 2016 ) ) ;
messages . push_back ( Messages ( typeMessage : : WARR , loopLi neNum , messageR , messageE , 2016 ) ) ;
}
static void addMessageUsageInFunctionCall ( vector < Messages > & messages , string varName , int loopLineNum , int lineNum )
{
__spf_print ( 1 , " WARR: cannot remove private var '%s' in loop %d - it is used in function call in line %d \n " ,
varName . c_str ( ) , loopLineNum , lineNum ) ;
wstring messageE , messageR ;
__spf_printToLongBuf ( messageE , L " Cannot remove private var '%s' - it is used in function call in line %d " ,
to_wstring ( varName ) . c_str ( ) , lineNum ) ;
__spf_printToLongBuf ( messageR , R203 , to_wstring ( varName ) . c_str ( ) , lineNum ) ;
messages . push_back ( Messages ( typeMessage : : WARR , lineNum , messageR , messageE , 2025 ) ) ;
}
/* ****************************************** *
@@ -657,6 +670,46 @@ static vector<InsertedStatement>::const_iterator findInsertedStmt(const vector<I
return insertedStmts . end ( ) ;
}
// isVarUsedInFunctionCall checks if var is used in any function call in exp (as argument)
static bool isVarUsedInFunctionCall ( SgSymbol * var , SgExpression * exp )
{
if ( exp = = nullptr )
return false ;
if ( exp - > symbol ( ) ! = nullptr & & ( exp - > variant ( ) = = FUNC_CALL | | exp - > variant ( ) = = PROC_CALL ) )
return isSymbolInExpression ( var , exp ) ;
return isVarUsedInFunctionCall ( var , exp - > lhs ( ) ) | | isVarUsedInFunctionCall ( var , exp - > rhs ( ) ) ;
}
// isArrayUsedInFunctionCall checks if arraySym is used in any function call in stmt (as argument)
// and writes message if true
static bool isArrayUsedInFunctionCall ( SgSymbol * arraySym , SgStatement * stmt , vector < Messages > & messages )
{
for ( SgStatement * st = stmt ; st ! = stmt - > lastNodeOfStmt ( ) ; st = st - > lexNext ( ) )
{
bool isUsed = false ;
if ( st - > variant ( ) = = PROC_STAT )
for ( int i = 0 ; i < 3 ; + + i )
if ( isSymbolInExpression ( arraySym , st - > expr ( i ) ) )
isUsed = true ;
if ( ! isUsed )
for ( int i = 0 ; i < 3 ; + + i )
if ( isVarUsedInFunctionCall ( arraySym , st - > expr ( i ) ) )
isUsed = true ;
if ( isUsed )
{
addMessageUsageInFunctionCall ( messages , arraySym - > identifier ( ) ,
stmt - > lineNumber ( ) , st - > lineNumber ( ) ) ;
return true ;
}
}
return false ;
}
// matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension
// and writes found mismatches to messages
static bool matchesFixedDimensionsMask ( const vector < SgArrayRefExp * > & arrayRefs ,
@@ -675,6 +728,8 @@ static bool matchesFixedDimensionsMask(const vector<SgArrayRefExp*>& arrayRefs,
static bool defStmtRefsMatchesMask ( SgStatement * loopStmt , const vector < bool > & fixedDimensions ,
SgSymbol * arraySym )
{
// TODO: <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <20> <> <EFBFBD> VAR_REF - <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> a * i + b, <20> <> i <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD>
for ( SgStatement * st = loopStmt ; st ! = loopStmt - > lastNodeOfStmt ( ) ; st = st - > lexNext ( ) )
{
if ( st - > variant ( ) ! = ASSIGN_STAT )
@@ -715,7 +770,8 @@ static string sunparseFixedDimensionsVector(const vector<bool>& fixedDimensions)
{
string result = " < " ;
result . reserve ( result . size ( ) + 7 * fixedDimensions . size ( ) ) ;
for ( int i = 0 ; i < fixedDimensions . size ( ) ; + + i ) {
for ( int i = 0 ; i < fixedDimensions . size ( ) ; + + i )
{
if ( fixedDimensions [ i ] = = true )
result + = " true " ;
else
@@ -734,11 +790,19 @@ static string sunparseFixedDimensionsVector(const vector<bool>& fixedDimensions)
static vector < bool > getFixedDimensionsMask ( const vector < SgArrayRefExp * > & arrayRefs ,
vector < Messages > & messages , int loopLineNum )
{
int fixed DimensionsNumber = arrayRefs [ 0 ] - > numberOfSubscripts ( ) ;
vector < bool > resultMask ( fixedDimensionsNumber , true ) ;
for ( const auto arrayRef : arrayRefs ) {
int numberOf Dimensions = arrayRefs [ 0 ] - > numberOfSubscripts ( ) ;
if ( numberOfDimensions = = 0 ) // invalid array reference
return vector < bool > { } ;
for ( const auto arrayRef : arrayRefs )
if ( arrayRef - > numberOfSubscripts ( ) ! = numberOfDimensions ) // invalid array reference
return vector < bool > { } ;
vector < bool > resultMask ( numberOfDimensions , true ) ;
for ( const auto arrayRef : arrayRefs )
{
vector < bool > fixedDimensions = getFixedDimensionsVector ( arrayRef ) ;
for ( int i = 0 ; i < fixed DimensionsNumber ; + + i )
for ( int i = 0 ; i < numberOf Dimensions; + + i )
resultMask [ i ] = resultMask [ i ] & & fixedDimensions [ i ] ;
}
@@ -1073,10 +1137,22 @@ static void fillFixedSubscriptsVectorsOfAllVars(SgExpression* exp,
if ( exp - > symbol ( ) ! = nullptr )
{
if ( exp - > variant ( ) = = VAR_REF )
{
for ( const auto & elem : vec )
if ( elem . first = = exp - > symbol ( ) - > identifier ( ) )
return ;
vec . push_back ( make_pair ( exp - > symbol ( ) - > identifier ( ) , vector < FixedSubscript > { } ) ) ;
}
else if ( exp - > variant ( ) = = ARRAY_REF )
{
vec . push_back ( make_pair ( exp - > symbol ( ) - > identifier ( ) ,
getFixedSubscriptsVector ( ( SgArrayRefExp * ) exp ) ) ) ;
SgExprListExp * exprList = ( SgExprListExp * ) exp - > lhs ( ) ;
for ( int i = 0 ; i < exprList - > length ( ) ; + + i )
fillFixedSubscriptsVectorsOfAllVars ( exprList - > elem ( i ) , vec ) ;
}
return ;
}
@@ -1119,6 +1195,20 @@ pair<SAPFOR::Argument*, set<int>> findVarInRDSet(map<SAPFOR::Argument*, set<int>
return make_pair ( nullptr , set < int > { } ) ;
}
// fillIterationVariables fill vars set with iteration variables of all loops
// from stmt to outerLoopStmt
static void fillIterationVars ( SgStatement * stmt , SgStatement * outerLoopStmt , set < string > & vars )
{
if ( stmt = = nullptr )
return ;
if ( stmt - > variant ( ) = = FOR_NODE )
vars . insert ( ( ( SgForStmt * ) stmt ) - > doName ( ) - > identifier ( ) ) ;
if ( stmt - > id ( ) ! = outerLoopStmt - > id ( ) )
fillIterationVars ( stmt - > controlParent ( ) , outerLoopStmt , vars ) ;
}
// checkDefUsePair checks if def statement from pair can be substituted into use statement
// and creates messages
static bool checkDefUsePair ( DefUseStmtsPair defUse , LoopGraph * loop , const CFG_Type & CFGraph ,
@@ -1127,9 +1217,6 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T
if ( defUse . first - > lineNumber ( ) > defUse . second - > lineNumber ( ) )
return false ;
while ( loop - > perfectLoop ! = 1 )
loop = loop - > children [ 0 ] ;
vector < pair < string , vector < FixedSubscript > > > dependOnVars ;
SgArrayRefExp * defRef = ( SgArrayRefExp * ) defUse . first - > expr ( 0 ) ;
@@ -1145,14 +1232,21 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T
fillFixedSubscriptsVectorsOfAllVars ( expToSubst , dependOnVars ) ;
}
set < string > iterationVars { } ;
fillIterationVars ( defUse . second , loop - > loop - > GetOriginal ( ) , iterationVars ) ;
auto defInsAndBlock = getInstructionAndBlockByStatement ( CFGraph , defUse . first ) ;
const auto & defRD_In = defInsAndBlock . second - > getRD_In ( ) ;
auto useInsAndBlock = getInstructionAndBlockByStatement ( CFGraph , defUse . second ) ;
const auto & useRD_In = useInsAndBlock . second - > getRD_In ( ) ;
for ( const auto & var : dependOnVars ) // checking scalar vars
for ( const auto & var : dependOnVars )
{
if ( var . second . size ( ) = = 0 )
if ( var . second . size ( ) = = 0 ) // check scalar vars
{
// iteration var doesn't obstruct the removing:
if ( iterationVars . find ( var . first ) ! = iterationVars . end ( ) )
continue ;
auto defArg = findVarInRDSet ( defRD_In , var . first ) ;
if ( defArg . first = = nullptr ) // there is no any RD for common vars or parameters
continue ;
@@ -1185,6 +1279,9 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T
auto defLoopStmt = getScopeLoopStmt ( defUse . first ) ;
auto useLoopStmt = getScopeLoopStmt ( defUse . second ) ;
while ( loop - > perfectLoop ! = 1 ) // (what is it? - <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> )
loop = loop - > children [ 0 ] ;
auto defLoop = findLoop ( loop , defLoopStmt ) ;
auto useLoop = findLoop ( loop , useLoopStmt ) ;
@@ -1317,10 +1414,13 @@ void removePrivatesAnalysis(vector<LoopGraph*>& loopGraphs,
if ( arrayToRemove = = nullptr ) // no array to remove
break ;
vector < bool > fixedDimensionsMask = getFixedDimensionsMask ( arrayRefs , messages , loop - > lineNum ) ;
if ( isArrayUsedInFunctionCall ( arrayToRemove , loopStmt , messages ) )
continue ;
if ( ! matches FixedDimensionsMask( arrayRefs , fixedDimensionsMask )
| | ! defStmtRefsMatchesMask ( loopStmt , fixedDimensionsMask , arrayToRemove ) )
vector < bool > fixedDimensionsMask = get FixedDimensionsMask( arrayRefs , messages , loop - > lineNum ) ;
if ( fixedDimensionsMask . empty ( ) | |
! matchesFixedDimensionsMask ( arrayRefs , fixedDimensionsMask ) | |
! defStmtRefsMatchesMask ( loopStmt , fixedDimensionsMask , arrayToRemove ) )
{
addMessageDoesNotMachMask ( messages , arrayToRemove - > identifier ( ) , loop - > lineNum ) ;
continue ;