2023-09-14 19:43:13 +03:00
# include "loops_splitter.h"
# include <string>
# include <vector>
# include "../LoopAnalyzer/loop_analyzer.h"
2025-06-02 19:08:09 +03:00
# include "expr_transform.h"
2025-06-04 13:08:38 +03:00
# include "errors.h"
2023-09-14 19:43:13 +03:00
# include "../CFGraph/CFGraph.h"
# include "../SageAnalysisTool/OmegaForSage/include/lang-interf.h"
# include "../DirectiveProcessing/directive_parser.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 : : vector ;
using std : : map ;
using std : : set ;
using std : : pair ;
using std : : make_pair ;
using std : : wstring ;
using std : : stack ;
# define PRINT_SPLITTED_FRAGMENTS 0
static map < FuncInfo * , vector < SAPFOR : : BasicBlock * > > currIR ;
static inline bool lineInsideBorder ( int lineNumber , const pair < SgStatement * , SgStatement * > & border )
{
return lineNumber > = border . first - > lineNumber ( ) & & lineNumber < border . second - > lineNumber ( ) ;
}
static vector < SAPFOR : : BasicBlock * > filterByBlock ( SgStatement * block )
{
int blockStart = block - > lineNumber ( ) ;
int blockEnd = block - > lastNodeOfStmt ( ) - > lineNumber ( ) ;
if ( blockEnd < blockStart )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( blockEnd < = 0 | | blockStart < = 0 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SgStatement * funcStat = getFuncStat ( block ) ;
int lineStart = funcStat - > lineNumber ( ) ;
vector < SAPFOR : : BasicBlock * > currBlocks ;
for ( auto & func : currIR )
{
if ( func . first - > linesNum . first = = lineStart )
{
currBlocks = func . second ;
break ;
}
}
if ( currBlocks . size ( ) = = 0 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
vector < SAPFOR : : BasicBlock * > filtered ;
for ( auto & block : currBlocks )
{
bool needToAdd = false ;
for ( auto & ir : block - > getInstructions ( ) )
{
int line = ir - > getInstruction ( ) - > getOperator ( ) - > lineNumber ( ) ;
if ( blockStart < = line & & blockEnd > = line )
needToAdd = true ;
}
if ( needToAdd )
filtered . push_back ( block ) ;
}
return filtered ;
}
static int getIntervalIdx ( const vector < pair < int , int > > & intervals , int line )
{
int id = - 1 ;
for ( int z = 0 ; z < intervals . size ( ) ; + + z )
{
if ( intervals [ z ] . first < = line & & line < = intervals [ z ] . second )
{
id = z ;
break ;
}
}
return id ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> map <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> :
* < <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> : <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> < <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> : <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> > >
* <EFBFBD> since <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <EFBFBD> <EFBFBD> till <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
static map < const LoopGraph * , map < SgStatement * , pair < set < SgStatement * > , set < SgStatement * > > > > cacheDeps ;
//TODO: added lines for function calls
static map < SgStatement * , pair < set < SgStatement * > , set < SgStatement * > > >
buildReachMapForLoop ( const LoopGraph * parentGraphUpest , const LoopGraph * parentGraph , SgStatement * since , SgStatement * till ,
const set < string > & privates , const vector < depGraph * > & depGraphs )
{
if ( cacheDeps . count ( parentGraph ) )
return cacheDeps . at ( parentGraph ) ;
const int sinceLine = since - > lineNumber ( ) ;
const int tillLine = till - > lineNumber ( ) ;
map < SgStatement * , pair < set < SgStatement * > , set < SgStatement * > > > result ;
set < string > privArrays ;
for ( auto & elem : parentGraph - > usedArraysAll )
if ( privates . find ( elem - > GetShortName ( ) ) ! = privates . end ( ) )
privArrays . insert ( elem - > GetShortName ( ) ) ;
map < string , set < SgStatement * > > defInBlocks ;
map < string , set < SgStatement * > > useInBlocks ;
vector < SgStatement * > blocks ;
for ( SgStatement * cur = since ; cur ! = till ; cur = cur - > lexNext ( ) )
{
blocks . push_back ( cur ) ;
cur = cur - > lastNodeOfStmt ( ) ;
}
//TODO: <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> .
if ( privArrays . size ( ) ! = 0 )
{
for ( auto & block : blocks )
{
auto filtered = filterByBlock ( block ) ;
int blockStart = block - > lineNumber ( ) ;
int blockEnd = block - > lastNodeOfStmt ( ) - > lineNumber ( ) ;
for ( auto & blockIR : filtered )
{
for ( auto & ir : blockIR - > getInstructions ( ) )
{
auto inst = ir - > getInstruction ( ) ;
int inLine = inst - > getOperator ( ) - > lineNumber ( ) ;
if ( inLine < blockStart | | inLine > blockEnd )
continue ;
if ( inst - > getOperation ( ) = = SAPFOR : : CFG_OP : : LOAD | |
inst - > getOperation ( ) = = SAPFOR : : CFG_OP : : STORE )
{
auto name = getNameByArg ( inst - > getArg1 ( ) ) ;
if ( privArrays . find ( name ) ! = privArrays . end ( ) )
{
if ( inst - > getOperation ( ) = = SAPFOR : : CFG_OP : : LOAD )
useInBlocks [ name ] . insert ( block ) ;
else
defInBlocks [ name ] . insert ( block ) ;
}
}
}
}
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> IR, <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ,
// <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> goto.
for ( int z = 0 ; z < blocks . size ( ) ; + + z )
{
for ( auto & data : useInBlocks )
{
const string array = data . first ;
if ( data . second . find ( blocks [ z ] ) ! = data . second . end ( ) )
{
if ( defInBlocks . find ( array ) ! = defInBlocks . end ( ) )
{
bool defFound = false ;
for ( int t = z - 1 ; t > = 0 ; - - t )
{
if ( defInBlocks [ array ] . find ( blocks [ t ] ) ! = defInBlocks [ array ] . end ( ) )
{
result [ blocks [ z ] ] . first . insert ( blocks [ t ] ) ;
result [ blocks [ t ] ] . second . insert ( blocks [ z ] ) ;
defFound = true ;
}
if ( defFound & & useInBlocks [ array ] . find ( blocks [ t ] ) ! = useInBlocks [ array ] . end ( ) )
break ;
}
}
}
}
}
}
vector < pair < pair < string , string > , vector < pair < int , int > > > > data ;
const LoopGraph * lp = parentGraphUpest ;
while ( lp )
{
auto attrsTr = getAttributes < SgStatement * , SgStatement * > ( lp - > loop - > GetOriginal ( ) , set < int > { SPF_PARALLEL_DIR } ) ;
for ( auto attr : attrsTr )
fillShadowAcrossFromComment ( ACROSS_OP , new Statement ( attr ) , data ) ;
if ( lp = = parentGraph )
break ;
lp = lp - > children [ 0 ] ;
}
set < string > arraysWithAcross ;
for ( auto & elem : data )
arraysWithAcross . insert ( elem . first . first ) ;
for ( depGraph * dependencyGraph : depGraphs )
{
if ( dependencyGraph = = NULL )
continue ;
for ( depNode * node : dependencyGraph - > getNodes ( ) )
{
if ( node - > typedep = = PRIVATEDEP )
continue ;
if ( node - > typedep = = REDUCTIONDEP )
continue ;
if ( node - > varin ! = node - > varout )
{
bool isPrivateArray = false ;
if ( node - > typedep = = ARRAYDEP )
if ( privates . find ( node - > varin - > symbol ( ) - > identifier ( ) ) ! = privates . end ( ) | |
privates . find ( node - > varout - > symbol ( ) - > identifier ( ) ) ! = privates . end ( ) )
isPrivateArray = true ;
if ( isPrivateArray )
continue ;
SgStatement * statIn = node - > stmtin ;
SgStatement * statOut = node - > stmtout ;
checkNull ( statIn , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
checkNull ( statOut , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( statOut ! = statIn )
{
int inLine = node - > stmtin - > lineNumber ( ) ;
int outLine = node - > stmtout - > lineNumber ( ) ;
if ( inLine = = outLine )
continue ;
const string nameIn = node - > varin - > symbol ( ) - > identifier ( ) ;
const string nameOut = node - > varout - > symbol ( ) - > identifier ( ) ;
bool isAcross = arraysWithAcross . count ( nameIn ) | | arraysWithAcross . count ( nameOut ) ;
bool hasDependency = false ;
for ( int i = 1 ; i < node - > knowndist . size ( ) ; + + i )
{
//ANTI and REDUCE
hasDependency | = ( node - > knowndist [ i ] = = 0 ) | |
( ( node - > knowndist [ i ] = = 1 ) & &
( node - > distance [ i ] ! = 0 | | ( isAcross & & ( node - > kinddep = = ddanti ) ) ) ) ;
}
if ( hasDependency )
{
bool inIncluded = false , outIncluded = false ;
if ( lineInsideBorder ( inLine , make_pair ( since , till ) ) )
inIncluded = true ;
if ( lineInsideBorder ( outLine , make_pair ( since , till ) ) )
outIncluded = true ;
if ( ! inIncluded & & ! outIncluded )
continue ;
if ( inIncluded & & outIncluded )
{
result [ node - > stmtin ] . first . insert ( node - > stmtout ) ;
result [ node - > stmtout ] . second . insert ( node - > stmtin ) ;
}
}
}
}
}
}
// added scalar dependencies
vector < SAPFOR : : BasicBlock * > bblocks ;
vector < pair < int , int > > startEndBlock ;
for ( auto & block : blocks )
{
auto filtered = filterByBlock ( block ) ;
bblocks . insert ( bblocks . end ( ) , filtered . begin ( ) , filtered . end ( ) ) ;
int blockStart = block - > lineNumber ( ) ;
int blockEnd = block - > lastNodeOfStmt ( ) - > lineNumber ( ) ;
startEndBlock . push_back ( make_pair ( blockStart , blockEnd ) ) ;
}
map < FuncInfo * , set < FuncInfo * > > callDeps ;
map < string , FuncInfo * > funcByName ;
map < FuncInfo * , map < SAPFOR : : Argument * , set < int > > > outForFunc ;
// create gen kill for blocks
map < SAPFOR : : BasicBlock * , map < SAPFOR : : Argument * , set < int > > > gen , kill ;
map < SAPFOR : : Instruction * , map < SAPFOR : : Argument * , set < int > > > genForIR , killForIR ;
map < SAPFOR : : BasicBlock * , set < SAPFOR : : Argument * > > notInitedGlobals ;
for ( auto & byFunc : currIR )
{
callDeps [ byFunc . first ] . insert ( byFunc . first - > callsFromV . begin ( ) , byFunc . first - > callsFromV . end ( ) ) ;
funcByName [ byFunc . first - > funcName ] = byFunc . first ;
}
vector < set < FuncInfo * > > ssc ;
vector < set < FuncInfo * > > callLvls = groupByCallDependencies ( callDeps , ssc ) ;
//TODO: take into account ssc structure
for ( auto & byLvl : callLvls )
{
for ( auto & byFunc : byLvl )
{
auto itCFG = currIR . find ( byFunc ) ;
if ( itCFG = = currIR . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
map < SAPFOR : : Argument * , set < int > > outForCurr ;
buildGenKillForCFG ( itCFG - > second , funcByName , outForFunc , gen , kill , & genForIR , & killForIR , notInitedGlobals , SAPFOR : : CFG_Settings ( 0 ) ) ;
if ( outForFunc . count ( byFunc ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
outForFunc [ byFunc ] = outForCurr ;
}
}
for ( auto & bblock : bblocks )
{
auto rd_in = bblock - > getRD_In ( ) ;
for ( auto & ir : bblock - > getInstructions ( ) )
{
auto istr = ir - > getInstruction ( ) ;
int line = istr - > getOperator ( ) - > lineNumber ( ) ;
if ( line < = 0 )
continue ;
if ( line < sinceLine | | line > = tillLine )
continue ;
int idOperator = getIntervalIdx ( startEndBlock , line ) ;
if ( idOperator = = - 1 )
continue ;
set < SAPFOR : : Argument * > use ;
if ( istr - > getArg1 ( ) & & istr - > getArg1 ( ) - > getType ( ) = = SAPFOR : : CFG_ARG_TYPE : : VAR )
use . insert ( istr - > getArg1 ( ) ) ;
if ( istr - > getArg2 ( ) & & istr - > getArg2 ( ) - > getType ( ) = = SAPFOR : : CFG_ARG_TYPE : : VAR )
use . insert ( istr - > getArg2 ( ) ) ;
for ( auto & varUse : use )
{
auto it = rd_in . find ( varUse ) ;
if ( it ! = rd_in . end ( ) )
{
for ( auto & num : it - > second )
{
if ( num = = SAPFOR : : UNINIT )
continue ;
auto whereByNum = getInstructionAndBlockByNumber ( currIR , num ) ;
if ( whereByNum . first = = NULL )
continue ;
int line = whereByNum . first - > getOperator ( ) - > lineNumber ( ) ;
if ( idOperator ! = getIntervalIdx ( startEndBlock , line ) )
{
if ( line > = sinceLine & & line < tillLine )
{
result [ istr - > getOperator ( ) ] . first . insert ( whereByNum . first - > getOperator ( ) ) ;
result [ whereByNum . first - > getOperator ( ) ] . second . insert ( istr - > getOperator ( ) ) ;
}
}
}
}
//else err?
}
auto itGen = genForIR . find ( istr ) ;
if ( itGen ! = genForIR . end ( ) )
for ( auto & elem : itGen - > second )
if ( elem . first - > getType ( ) = = SAPFOR : : CFG_ARG_TYPE : : VAR )
rd_in [ elem . first ] = elem . second ;
}
}
if ( 0 ) // deb print
{
for ( auto & array : defInBlocks )
{
printf ( " %s defs in: \n " , array . first . c_str ( ) ) ;
for ( auto & place : array . second )
printf ( " -- %d \n " , place - > lineNumber ( ) ) ;
printf ( " \n " ) ;
}
for ( auto & array : useInBlocks )
{
printf ( " %s uses in: \n " , array . first . c_str ( ) ) ;
for ( auto & place : array . second )
printf ( " -- %d \n " , place - > lineNumber ( ) ) ;
printf ( " \n " ) ;
}
for ( auto & it : result )
{
printf ( " st: %d: \n " , it . first - > lineNumber ( ) ) ;
printf ( " Depends on: \n " ) ;
for ( auto & itt : it . second . first )
printf ( " %d " , itt - > lineNumber ( ) ) ;
printf ( " \n " ) ;
printf ( " Used in: \n " ) ;
for ( auto & itt : it . second . second )
printf ( " %d " , itt - > lineNumber ( ) ) ;
printf ( " \n " ) ;
printf ( " \n " ) ;
}
}
cacheDeps [ parentGraph ] = result ;
return result ;
}
static SgForStmt * createNewLoop ( const LoopGraph * globalLoop )
{
SgStatement * insertBeforeThis = globalLoop - > loop - > GetOriginal ( ) ;
SgStatement * newLoop = NULL ;
const LoopGraph * curLoopGraph = globalLoop ;
vector < const LoopGraph * > graphs ( globalLoop - > perfectLoop ) ;
for ( int i = 0 ; i < globalLoop - > perfectLoop ; + + i )
{
graphs [ i ] = curLoopGraph ;
if ( curLoopGraph - > children . size ( ) )
curLoopGraph = curLoopGraph - > children [ 0 ] ;
}
for ( int i = graphs . size ( ) - 1 ; i > 0 ; - - i )
{
SgForStmt * curForStmt = ( SgForStmt * ) graphs [ i ] - > loop - > GetOriginal ( ) ;
newLoop = new SgForStmt ( curForStmt - > doName ( ) , curForStmt - > start ( ) , curForStmt - > end ( ) , curForStmt - > step ( ) , newLoop ) ;
}
SgForStmt * curForStmt = ( SgForStmt * ) graphs [ 0 ] - > loop - > GetOriginal ( ) ;
SgForStmt * newGlobalLoop = new SgForStmt ( curForStmt - > doName ( ) , curForStmt - > start ( ) , curForStmt - > end ( ) , curForStmt - > step ( ) , newLoop ) ;
insertBeforeThis - > insertStmtBefore ( * newGlobalLoop , * insertBeforeThis - > controlParent ( ) ) ;
for ( int z = 0 ; z < insertBeforeThis - > numberOfAttributes ( ) ; + + z )
newGlobalLoop - > addAttribute ( new SgAttribute ( * insertBeforeThis - > getAttribute ( z ) ) ) ;
SgStatement * lowestInsertedFor = insertBeforeThis ;
for ( int i = 0 ; i < globalLoop - > perfectLoop ; + + i ) //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> enddo
lowestInsertedFor = lowestInsertedFor - > lexPrev ( ) ;
return ( SgForStmt * ) lowestInsertedFor - > lexPrev ( ) ; //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
}
static void setupOpenDependencies ( set < int > & openDependencies , const vector < pair < SgStatement * , SgStatement * > > & borders ,
const set < string > & loopsPrivates , const vector < depGraph * > & depGraphs )
{
for ( depGraph * dependencyGraph : depGraphs )
{
if ( dependencyGraph = = NULL )
continue ;
for ( depNode * node : dependencyGraph - > getNodes ( ) )
{
if ( node - > typedep = = PRIVATEDEP )
continue ;
if ( node - > typedep = = REDUCTIONDEP )
continue ;
if ( node - > varin ! = node - > varout )
{
bool isPrivateArray = false ;
if ( node - > typedep = = ARRAYDEP )
if ( loopsPrivates . find ( node - > varin - > symbol ( ) - > identifier ( ) ) ! = loopsPrivates . end ( ) | |
loopsPrivates . find ( node - > varout - > symbol ( ) - > identifier ( ) ) ! = loopsPrivates . end ( ) )
isPrivateArray = true ;
if ( isPrivateArray )
continue ;
SgStatement * statIn = node - > stmtin ;
SgStatement * statOut = node - > stmtout ;
checkNull ( statIn , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
checkNull ( statOut , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SgStatement * sInFor = statIn ;
while ( sInFor & & sInFor - > variant ( ) ! = FOR_NODE )
sInFor = sInFor - > controlParent ( ) ;
SgStatement * sOutFor = statOut ;
while ( sOutFor & & sOutFor - > variant ( ) ! = FOR_NODE )
sOutFor = sOutFor - > controlParent ( ) ;
if ( statOut ! = statIn )
{
bool hasDependency = false ;
for ( int i = 1 ; i < node - > knowndist . size ( ) ; + + i )
{
//ANTI and REDUCE
hasDependency | = ( node - > knowndist [ i ] = = 0 ) | | ( ( node - > knowndist [ i ] = = 1 ) & & ( node - > distance [ i ] ! = 0 ) ) ;
}
if ( hasDependency )
{
int inLine = node - > stmtin - > lineNumber ( ) ;
int outLine = node - > stmtout - > lineNumber ( ) ;
bool inIncluded = false , outIncluded = false ;
for ( const auto & border : borders )
{
if ( lineInsideBorder ( inLine , border ) )
inIncluded = true ;
if ( lineInsideBorder ( outLine , border ) )
outIncluded = true ;
}
if ( ! inIncluded & & ! outIncluded )
continue ;
if ( ! inIncluded & & openDependencies . find ( inLine ) = = openDependencies . end ( ) )
openDependencies . insert ( inLine ) ;
if ( ! outIncluded & & openDependencies . find ( outLine ) = = openDependencies . end ( ) )
openDependencies . insert ( outLine ) ;
}
}
}
}
}
}
static void addReachingDefinitionsDependencies ( set < int > & openDependencies , const vector < pair < SgStatement * , SgStatement * > > & borders ,
const map < SgStatement * , pair < set < SgStatement * > , set < SgStatement * > > > & requireReachMap )
{
for ( const auto & border : borders )
{
for ( SgStatement * current = border . first ; current ! = border . second ; current = current - > lexNext ( ) )
{
auto found = requireReachMap . find ( current ) ;
if ( found ! = requireReachMap . end ( ) )
{
for ( auto it = found - > second . first . begin ( ) ; it ! = found - > second . first . end ( ) ; + + it )
{
int lineNumber = ( * it ) - > lineNumber ( ) ;
bool included = false ;
for ( const auto & b : borders )
{
if ( lineInsideBorder ( lineNumber , b ) )
{
included = true ;
break ;
}
}
if ( ! included & & openDependencies . find ( lineNumber ) = = openDependencies . end ( ) )
openDependencies . insert ( lineNumber ) ;
}
for ( auto it = found - > second . second . begin ( ) ; it ! = found - > second . second . end ( ) ; + + it )
{
int lineNumber = ( * it ) - > lineNumber ( ) ;
bool included = false ;
for ( const auto & b : borders )
{
if ( lineInsideBorder ( lineNumber , b ) )
{
included = true ;
break ;
}
}
if ( ! included & & openDependencies . find ( lineNumber ) = = openDependencies . end ( ) )
openDependencies . insert ( lineNumber ) ;
}
}
}
}
}
static bool dependencyAlreadyEnclosed ( int lineNum , const vector < pair < SgStatement * , SgStatement * > > & borders )
{
for ( const auto & border : borders )
if ( lineInsideBorder ( lineNum , border ) )
return true ;
return false ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> openDependencies <20> borders
static void expandCopyBorders ( SgStatement * globalSince , SgStatement * globalTill , vector < pair < SgStatement * , SgStatement * > > & borders ,
const set < int > & openDependencies )
{
for ( int lineNumOfDependency : openDependencies )
{
if ( dependencyAlreadyEnclosed ( lineNumOfDependency , borders ) )
continue ;
SgStatement * since = NULL , * till = NULL ;
since = globalSince ;
for ( since = globalSince ; since ! = globalTill ; since = since - > lastNodeOfStmt ( ) - > lexNext ( ) )
{
if ( since - > lineNumber ( ) < = lineNumOfDependency & & since - > lastNodeOfStmt ( ) - > lineNumber ( ) > = lineNumOfDependency )
{
till = since - > lastNodeOfStmt ( ) - > lexNext ( ) ;
break ;
}
}
if ( since = = globalTill ) //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ? <20> <> <20> <> <20> <> <EFBFBD> .
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
borders . push_back ( make_pair ( since , till ) ) ;
}
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> borders
static void glueBorders ( vector < pair < SgStatement * , SgStatement * > > & borders )
{
if ( borders . size ( ) < = 1 )
return ;
map < pair < int , int > , pair < SgStatement * , SgStatement * > > bordersMap ;
for ( int z = 0 ; z < borders . size ( ) ; + + z )
bordersMap [ make_pair ( borders [ z ] . first - > lineNumber ( ) , borders [ z ] . second - > lineNumber ( ) ) ] = borders [ z ] ;
borders . clear ( ) ;
for ( auto & elem : bordersMap )
borders . push_back ( elem . second ) ;
bool needToUpdate = true ;
while ( needToUpdate )
{
needToUpdate = false ;
vector < pair < SgStatement * , SgStatement * > > newBorders ;
newBorders . push_back ( borders [ 0 ] ) ;
int lastIdx = 0 ;
for ( int z = 1 ; z < borders . size ( ) ; + + z )
{
if ( newBorders [ lastIdx ] . second = = borders [ z ] . first )
newBorders [ lastIdx ] . second = borders [ z ] . second ;
else
{
newBorders . push_back ( borders [ z ] ) ;
lastIdx + + ;
}
}
if ( newBorders . size ( ) ! = borders . size ( ) )
{
borders = newBorders ;
needToUpdate = ( borders . size ( ) > 1 ) ;
}
}
}
static vector < LoopGraph * > getLoopsFrom ( const vector < pair < SgStatement * , SgStatement * > > & borders , LoopGraph * parentGraph , LoopGraph * parentGraphUpest )
{
vector < LoopGraph * > result ;
while ( parentGraphUpest ! = parentGraph )
{
result . push_back ( parentGraphUpest ) ;
if ( parentGraphUpest - > children . size ( ) = = 0 | | parentGraphUpest - > children . size ( ) > 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
parentGraphUpest = parentGraphUpest - > children [ 0 ] ;
}
result . push_back ( parentGraph ) ;
for ( LoopGraph * loop : parentGraph - > children )
for ( const auto & frag : borders )
if ( loop - > lineNum > = frag . first - > lineNumber ( ) & & loop - > lineNumAfterLoop < = frag . second - > lineNumber ( ) )
result . push_back ( loop ) ;
return result ;
}
static vector < depGraph * > getDepGraphsFor ( const vector < LoopGraph * > & loops , LoopGraph * parentGraph , const map < LoopGraph * , depGraph * > & depInfoForLoopGraph )
{
vector < depGraph * > result ;
for ( auto & loop : loops )
{
if ( depInfoForLoopGraph . count ( loop ) )
result . push_back ( depInfoForLoopGraph . at ( loop ) ) ;
else
result . push_back ( NULL ) ;
}
return result ;
}
static bool continueSplitting ( SgStatement * globalSince , SgStatement * globalTill , const vector < pair < SgStatement * , SgStatement * > > & borders )
{
//<2F> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
return ! ( borders . size ( ) = = 1 & & borders [ 0 ] . first = = globalSince & & borders [ 0 ] . second = = globalTill ) ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> borders - <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
static bool setupSplitBorders ( LoopGraph * parentGraphUpest , LoopGraph * parentGraph , SgStatement * globalSince , SgStatement * globalTill ,
vector < pair < SgStatement * , SgStatement * > > & borders ,
const set < string > & privates ,
const map < LoopGraph * , depGraph * > & depInfoForLoopGraph )
{
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> -<2D> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> .
if ( globalSince = = globalTill )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
borders . clear ( ) ;
SgStatement * since , * till ;
since = globalSince ;
till = since - > lastNodeOfStmt ( ) - > lexNext ( ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> borders - <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD>
borders . push_back ( make_pair ( since , till ) ) ;
vector < LoopGraph * > loops = getLoopsFrom ( borders , parentGraph , parentGraphUpest ) ;
vector < depGraph * > depGraphs = getDepGraphsFor ( loops , parentGraph , depInfoForLoopGraph ) ;
__spf_print ( PRINT_SPLITTED_FRAGMENTS , " Initial fragment: %d - %d \n " , since - > lineNumber ( ) , till - > lineNumber ( ) ) ;
const auto requireReachMap = buildReachMapForLoop ( parentGraphUpest , parentGraph , globalSince , globalTill , privates , depGraphs ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> borders
set < int > openDependencies ;
setupOpenDependencies ( openDependencies , borders , privates , depGraphs ) ;
addReachingDefinitionsDependencies ( openDependencies , borders , requireReachMap ) ;
while ( openDependencies . size ( ) > 0 )
{
# if PRINT_SPLITTED_FRAGMENTS == 1
__spf_print ( PRINT_SPLITTED_FRAGMENTS , " Line dependencies: \n " , globalSince - > lineNumber ( ) , globalTill - > lineNumber ( ) ) ;
for ( auto & it : openDependencies )
__spf_print ( PRINT_SPLITTED_FRAGMENTS , " %d, " , it ) ;
__spf_print ( PRINT_SPLITTED_FRAGMENTS , " \n " ) ;
# endif
expandCopyBorders ( globalSince , globalTill , borders , openDependencies ) ;
openDependencies . clear ( ) ;
loops = getLoopsFrom ( borders , parentGraph , parentGraphUpest ) ;
depGraphs = getDepGraphsFor ( loops , parentGraph , depInfoForLoopGraph ) ;
setupOpenDependencies ( openDependencies , borders , privates , depGraphs ) ;
addReachingDefinitionsDependencies ( openDependencies , borders , requireReachMap ) ;
}
# if PRINT_SPLITTED_FRAGMENTS == 1
for ( auto & fragment : borders )
__spf_print ( PRINT_SPLITTED_FRAGMENTS , " fragment %d - %d \n " , fragment . first - > lineNumber ( ) , fragment . second - > lineNumber ( ) ) ;
# endif
glueBorders ( borders ) ;
return continueSplitting ( globalSince , globalTill , borders ) ;
}
static void filterSpfAttributes ( SgStatement * stat )
{
int count = stat - > numberOfAttributes ( ) ;
if ( count )
{
SgStatement * lastNode = stat - > lastNodeOfStmt ( ) ;
//TODO: added filter for private, reduction and ...
for ( int z = 0 ; z < count ; + + z )
{
SgAttribute * attr = stat - > getAttribute ( z ) ;
if ( attr - > getAttributeType ( ) = = SPF_ANALYSIS_DIR )
{
SgStatement * data = ( SgStatement * ) attr - > getAttributeData ( ) ;
2024-04-12 16:36:37 +03:00
if ( data - > localLineNumber ( ) ! = SPF_USER_DIR )
2023-09-14 19:43:13 +03:00
continue ;
//__spf_print(1, "%s", data->unparse());
set < string > privates ;
fillPrivatesFromComment ( new Statement ( data ) , privates ) ;
if ( privates . size ( ) )
{
set < string > assignTo ;
for ( SgStatement * st = stat ; st ! = lastNode ; st = st - > lexNext ( ) )
{
if ( st - > variant ( ) = = ASSIGN_STAT )
{
auto ex = st - > expr ( 0 ) - > symbol ( ) ;
if ( ex )
assignTo . insert ( ex - > identifier ( ) ) ;
}
}
set < string > actualPrivate ;
for ( auto & elem : privates )
if ( assignTo . find ( elem ) ! = assignTo . end ( ) )
actualPrivate . insert ( elem ) ;
if ( actualPrivate . size ( ) ! = privates . size ( ) )
{
__spf_print ( 1 , " actual private size %d, in dir %d \n " , actualPrivate . size ( ) , privates . size ( ) ) ;
SgExpression * exprList = data - > expr ( 0 ) ;
vector < SgExpression * > newData ;
while ( exprList )
{
if ( exprList - > lhs ( ) - > variant ( ) = = ACC_PRIVATE_OP )
{
if ( actualPrivate . size ( ) )
{
SgExpression * list = exprList - > lhs ( ) - > lhs ( ) ;
vector < SgExpression * > newList ;
while ( list )
{
if ( actualPrivate . find ( list - > lhs ( ) - > symbol ( ) - > identifier ( ) ) ! = actualPrivate . end ( ) )
newList . push_back ( list - > lhs ( ) ) ;
list = list - > rhs ( ) ;
}
if ( newList . size ( ) )
{
exprList - > lhs ( ) - > setLhs ( makeExprList ( newList ) ) ;
newData . push_back ( exprList - > lhs ( ) ) ;
}
}
}
else
newData . push_back ( exprList - > lhs ( ) ) ;
exprList = exprList - > rhs ( ) ;
}
if ( newData . size ( ) = = 0 )
{
__spf_print ( 1 , " remove attribute on line %d \n " , stat - > lineNumber ( ) ) ;
stat - > deleteAttribute ( z ) ;
count - - ;
}
else
{
__spf_print ( 1 , " set new data size %d \n " , newData . size ( ) ) ;
data - > setExpression ( 0 , makeExprList ( newData ) ) ;
}
}
}
}
}
}
}
static void moveStatements ( SgForStmt * newLoop , const vector < pair < SgStatement * , SgStatement * > > & fragments , int deep )
{
//newLoop is lowest
SgStatement * lastInserted = newLoop - > lastNodeOfStmt ( ) ;
SgStatement * cp = lastInserted - > controlParent ( ) ;
for ( const auto & fragment : fragments )
{
SgStatement * toMoveStmt = fragment . first ;
while ( toMoveStmt ! = fragment . second )
{
SgStatement * st = toMoveStmt ;
toMoveStmt = toMoveStmt - > lastNodeOfStmt ( ) - > lexNext ( ) ;
lastInserted - > insertStmtBefore ( * st - > extractStmt ( ) , * cp ) ;
}
}
for ( int z = 0 ; z < deep - 1 ; + + z )
{
newLoop = isSgForStmt ( newLoop - > controlParent ( ) ) ;
checkNull ( newLoop , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
filterSpfAttributes ( newLoop ) ;
}
static bool hasIndirectChildLoops ( const LoopGraph * parentGraph , vector < Messages > & messages )
{
SgStatement * st = parentGraph - > loop - > GetOriginal ( ) - > lexNext ( ) ;
int directLoops = 0 ;
while ( st - > variant ( ) ! = CONTROL_END )
{
if ( st - > variant ( ) = = FOR_NODE )
directLoops + + ;
st = st - > lastNodeOfStmt ( ) - > lexNext ( ) ;
}
if ( directLoops ! = parentGraph - > children . size ( ) )
{
messages . push_back ( Messages ( ERROR , parentGraph - > loop - > GetOriginal ( ) - > lineNumber ( ) , R105 ,
L " This loop has indirect child loops and can not be splitted " , 2010 ) ) ;
__spf_print ( 1 , " This loop has indirect child loops and can not be splitted on line %d \n " , parentGraph - > lineNum ) ;
return true ;
}
else
return false ;
}
static bool hasUnexpectedDependencies ( const LoopGraph * parentGraph , const depGraph * parentDepGraph ,
const set < string > & privateVars , vector < Messages > & messages )
{
bool has = false ;
int countOfMessages = 10 ;
int idxOfMessages = 0 ;
if ( parentDepGraph = = NULL )
return false ;
for ( depNode * node : parentDepGraph - > getNodes ( ) )
{
if ( node - > typedep ! = ARRAYDEP )
{
bool privateInChild = false ;
for ( LoopGraph * childGraph : parentGraph - > children )
{
SgStatement * childLoop = childGraph - > loop - > GetOriginal ( ) ;
if ( lineInsideBorder ( node - > stmtin - > lineNumber ( ) , make_pair ( childLoop , childLoop - > lastNodeOfStmt ( ) - > lexNext ( ) ) ) )
privateInChild = ( node - > typedep = = PRIVATEDEP ) ;
}
// is it private for this loop
if ( ! privateInChild )
if ( node - > varin - > symbol ( ) & & privateVars . find ( node - > varin - > symbol ( ) - > identifier ( ) ) ! = privateVars . end ( ) )
privateInChild = true ;
has | = ! privateInChild ;
if ( ! privateInChild )
{
if ( idxOfMessages < countOfMessages )
{
idxOfMessages + + ;
string str ;
__spf_printToBuf ( str , " Can not split this loop because of dependency: %s " , node - > displayDepToStr ( ) . c_str ( ) ) ;
__spf_print ( 1 , " %s on line %d \n " , str . c_str ( ) , parentGraph - > lineNum ) ;
wstring strR , strE ;
__spf_printToLongBuf ( strE , L " Can not split this loop because of dependency: %s " ,
to_wstring ( node - > displayDepToStr ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( strR , R104 , to_wstring ( node - > displayDepToStr ( ) ) . c_str ( ) ) ;
messages . push_back ( Messages ( WARR , parentGraph - > lineNum , strR , strE , 2009 ) ) ;
}
}
}
}
return has ;
}
static int splitLoop ( LoopGraph * loopGraph , vector < Messages > & messages , int deep , const map < LoopGraph * , depGraph * > & depInfoForLoopGraph )
{
LoopGraph * lowestParentGraph = loopGraph ;
for ( int i = 0 ; i < std : : min ( loopGraph - > perfectLoop , deep ) - 1 ; + + i )
{
if ( lowestParentGraph - > children . size ( ) = = 1 )
lowestParentGraph = lowestParentGraph - > children [ 0 ] ;
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
if ( hasIndirectChildLoops ( lowestParentGraph , messages ) )
return - 1 ;
if ( lowestParentGraph - > hasLimitsToSplit ( ) )
{
messages . push_back ( Messages ( ERROR , loopGraph - > lineNum ,
R106 + std : : to_wstring ( lowestParentGraph - > lineNum ) ,
L " This loop has limits (goto, print, stops or not DO-ENDDO) for splitting (reason: loop on line " + std : : to_wstring ( lowestParentGraph - > lineNum ) + L " ) " ,
2010 ) ) ;
__spf_print ( 1 , " %d loop has limits (goto, print, stops or not DO-ENDDO) for splitting (reason: loop on line %d) \n " , loopGraph - > lineNum , lowestParentGraph - > lineNum ) ;
return - 1 ;
}
set < string > privates ;
tryToFindPrivateInAttributes ( loopGraph - > loop , privates ) ;
const set < string > privVars ;
const depGraph * lowestParentDepGraph = NULL ;
if ( depInfoForLoopGraph . count ( lowestParentGraph ) )
lowestParentDepGraph = depInfoForLoopGraph . at ( lowestParentGraph ) ;
if ( hasUnexpectedDependencies ( lowestParentGraph , lowestParentDepGraph , privates , messages ) )
{
messages . push_back ( Messages ( ERROR , loopGraph - > lineNum ,
R107 + std : : to_wstring ( lowestParentGraph - > lineNum ) ,
L " This loop has unexpected dependencies and can not be splitted (reason: loop on line " + std : : to_wstring ( lowestParentGraph - > lineNum ) + L " ) " ,
2010 ) ) ;
__spf_print ( 1 , " %d loop has unexpected dependencies and can not be splitted (reason: loop on line %d) \n " ,
loopGraph - > lineNum , lowestParentGraph - > lineNum ) ;
return - 1 ;
}
SgStatement * globalSince , * globalTill ;
globalSince = lowestParentGraph - > loop - > GetOriginal ( ) - > lexNext ( ) ;
globalTill = lowestParentGraph - > loop - > GetOriginal ( ) - > lastNodeOfStmt ( ) ;
vector < pair < SgStatement * , SgStatement * > > borders ;
bool setup = setupSplitBorders ( loopGraph , lowestParentGraph , globalSince , globalTill , borders , privates , depInfoForLoopGraph ) ;
SgStatement * prev = loopGraph - > loop - > lexPrev ( ) ;
bool hasSplited = false ;
while ( setup & & borders . size ( ) > 0 ) // <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
{
hasSplited = true ;
# if PRINT_SPLITTED_FRAGMENTS == 1
__spf_print ( PRINT_SPLITTED_FRAGMENTS , " global since %d, global till %d \n " , globalSince - > lineNumber ( ) , globalTill - > lineNumber ( ) ) ;
__spf_print ( PRINT_SPLITTED_FRAGMENTS , " result fragment: " ) ;
for ( auto & it : borders )
__spf_print ( PRINT_SPLITTED_FRAGMENTS , " %d - %d, " , it . first - > lineNumber ( ) , it . second - > lineNumber ( ) ) ;
__spf_print ( PRINT_SPLITTED_FRAGMENTS , " \n " ) ;
# endif
moveStatements ( createNewLoop ( loopGraph ) , borders , deep ) ;
globalSince = lowestParentGraph - > loop - > GetOriginal ( ) - > lexNext ( ) ;
setup = setupSplitBorders ( loopGraph , lowestParentGraph , globalSince , globalTill , borders , privates , depInfoForLoopGraph ) ;
}
//move comment to uppest loop
if ( hasSplited )
{
if ( loopGraph - > loop - > comments ( ) )
{
prev - > lexNext ( ) - > addComment ( loopGraph - > loop - > comments ( ) ) ;
loopGraph - > loop - > delComments ( ) ;
}
}
return hasSplited ? 0 : 1 ;
}
int splitLoops ( SgFile * file , vector < LoopGraph * > & loopGraphs , vector < Messages > & messages ,
const map < LoopGraph * , depGraph * > & depInfoForLoopGraph ,
const map < string , CommonBlock * > & commonBlocks ,
const map < string , vector < FuncInfo * > > & allFuncInfo , int & countOfTransform )
{
cacheDeps . clear ( ) ;
map < int , LoopGraph * > mapLoopGraph ;
createMapLoopGraph ( loopGraphs , mapLoopGraph ) ;
int totalErr = 0 ;
for ( auto & loopPair : mapLoopGraph )
{
2025-06-22 09:19:37 +03:00
if ( ! loopPair . second - > isFor ( ) )
2023-09-14 19:43:13 +03:00
continue ;
LoopGraph * loop = loopPair . second ;
auto attrsTr = getAttributes < SgStatement * , SgStatement * > ( loop - > loop - > GetOriginal ( ) , set < int > { SPF_TRANSFORM_DIR } ) ;
for ( auto attr : attrsTr )
{
SgExpression * list = attr - > expr ( 0 ) ;
if ( list - > lhs ( ) - > variant ( ) = = SPF_FISSION_OP )
{
checkNull ( list - > lhs ( ) - > lhs ( ) , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SgExprListExp * listExp = isSgExprListExp ( list - > lhs ( ) - > lhs ( ) ) ;
checkNull ( listExp , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
int deep = listExp - > length ( ) ;
currIR = buildCFGforCurrentFunc ( loop - > loop , SAPFOR : : CFG_Settings ( true , true ) , commonBlocks , allFuncInfo ) ;
totalErr = splitLoop ( loop , messages , deep , depInfoForLoopGraph ) ;
if ( totalErr > 0 )
{
messages . push_back ( Messages ( ERROR , loop - > lineNum , R196 , L " The loop transformation cannot be performed due to dependencies between operators " , 2022 ) ) ;
__spf_print ( 1 , " %d The loop transformation cannot be performed due to dependencies between operators \n " , loop - > lineNum ) ;
}
else if ( totalErr = = 0 )
{
filterSpfAttributes ( loop - > loop - > GetOriginal ( ) ) ;
countOfTransform + + ;
}
deleteCFG ( currIR ) ;
}
}
}
cacheDeps . clear ( ) ;
return totalErr ;
}