Files
SAPFOR/dvm/fdvm/trunk/fdvm/parloop.cpp
2024-08-30 12:17:35 +03:00

2588 lines
92 KiB
C++

/*********************************************************************/
/* Fortran DVM+OpenMP+ACC */
/* */
/* Parallel Loop Processing */
/*********************************************************************/
#include "dvm.h"
SgStatement *parallel_dir;
SgExpression *spec_accr;
int iacross;
symb_list *newvar_list;
#define IN_ 0
#define OUT_ 1
extern int nloopred; //counter of parallel loops with reduction group
extern int nloopcons; //counter of parallel loops with consistent group
extern int opt_base, opt_loop_range; //set on by compiler options (code optimization options)
extern symb_list *redvar_list;
int ParallelLoop(SgStatement *stmt)
{
SgSymbol *do_var[MAX_LOOP_LEVEL];
SgExpression *step[MAX_LOOP_LEVEL],
*init[MAX_LOOP_LEVEL],
*last[MAX_LOOP_LEVEL],
*vpart[MAX_LOOP_LEVEL];
SgExpression *dovar;
SgValueExp c1(1);
int i=0, nloop=0, ndo=0, iout;
SgStatement *stl, *st, *first_do;
SgForStmt *stdo;
int ub; /*OMP*/
SgSymbol *newj = NULL; /*OMP*/
SgExpression *clause[13] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
// initialize global variables
parallel_dir = stmt;
redgref = NULL;
red_list = NULL;
irg=0; idebrg=0;
iconsg=0; idebcg=0;
consgref = NULL;
iacross = 0;
newvar_list = NULL;
ub = 0; /*OMP*/
if (!OMP_program) {/*OMP*/
first_do = stmt -> lexNext();// first DO statement of the loop nest
} else {
first_do = GetLexNextIgnoreOMP(stmt);// first DO statement of the loop nest /*OMP*/
newj = ChangeParallelDir (stmt);
}
//analysis of clauses
CheckClauses(stmt,clause);
int interface = 0; /*ACC*/
//interface selection: 0 - RTS1, 1- RTS1+RTS2(by handler), 2 - RTS2(by handler)
if(IN_COMPUTE_REGION || parloop_by_handler)
interface = 1;
if(parloop_by_handler == 2) {
interface = WhatInterface(stmt);
if(interface == 1)
err("Illegal clause",150,stmt );
}
//initialization vpart[]
for(i=0; i<MAX_LOOP_LEVEL; i++)
vpart[i] = NULL;
//looking through the do_variables list
if(opt_loop_range) CreateIndexVariables(stmt->expr(2));
for(dovar=stmt->expr(2); dovar; dovar=dovar->rhs())
nloop++;
LINE_NUMBER_AFTER(stmt,stmt); // line number of PARALLEL directive
TransferLabelFromTo(first_do, stmt->lexNext());
//generating call to 'bploop' function of performance analizer (begin of parallel interval)
if(perf_analysis && perf_analysis != 2)
InsertNewStatementAfter(St_Bploop(OpenInterval(stmt)), cur_st, stmt->controlParent()); //inserting after function call 'lnumb'
//par_st = cur_st;
//renewing loop-header's variables (used in start-expr, end-expr, step-expr)
if(IN_COMPUTE_REGION || parloop_by_handler) /*ACC*/
ACC_RenewParLoopHeaderVars(first_do,nloop);
//allocating LoopRef and OutInitIndexArray,OutLastIndexArray,OutStepArray
iplp = ndvm++;
iout = ndvm;
if(interface != 2)
ndvm += 3*nloop;
//looking through the loop nest
for(st=first_do,stl=NULL,i=0; i<nloop; st=st->lexNext(),i++) {
stdo = isSgForStmt(st);
if(!stdo)
break;
else if( stl && !TightlyNestedLoops_Test(stl,st))
err("Non-tightly-nested loops",339,st);
stl = st;
//if(opt_loop_range) {
ChangeDistArrayRef(stdo->start());
ChangeDistArrayRef(stdo->end());
ChangeDistArrayRef(stdo->step());
// }
do_var[i] = stdo->symbol();
step[i] = stdo->step();
if(!step[i])
step[i] = & c1.copy(); // by default: step = 1
init[i] = isSpecialFormExp(stdo->start(),i,iout+i,vpart,do_var);
if( init[i] )
step[i] = & c1.copy();
else
init[i] = stdo->start();
last[i] = stdo->end();
if (OMP_program) {/*OMP*/
if (newj != NULL) {/*OMP*/
if (ub == 0) {/*OMP*/
if (isOmpGetNumThreads(last[i])) ub=1;/*OMP*/
if (ub == 0) {/*OMP*/
isOmpGetNumThreads(init[i]);/*OMP*/
ub=2;/*OMP*/
}/*OMP*/
} /*OMP*/
} /*OMP*/
} /*OMP*/
// setting new loop parameters
if(!opt_loop_range) {
if(vpart[i])
stdo->setStart(*DVM000(iout+i)+ (*vpart[i]));//special form
//step is not replaced
else {
stdo->setStart(*DVM000(iout+i));
}
stdo->setEnd(*DVM000(iout+i+nloop));
}
else
stdo->setEnd(*DVM000(iout+i+nloop) - *new SgVarRefExp(*INDEX_SYMBOL(do_var[i])));
if(dvm_debug)
SetDoVar(stdo->symbol());
}
ndo = i;
// test whether the PARALLEL directive is correct
if( !TestParallelDirective(stmt, nloop, ndo, first_do) )
return(0); // directive is ignored
if(interface == 2)
Interface_2(stmt,clause,init,last,step,nloop,ndo,first_do); //,iout,stl,newj,ub);
else
Interface_1(stmt,clause,do_var,init,last,step,nloop,ndo,first_do,iplp,iout,stl,newj,ub);
cur_st = st->lexPrev(); // set cur_st on last DO satement of loop nest
// cur_st = stl->lexNext();
return(1);
}
void CopyHeaderElems(SgStatement *st_after)
{symb_list *sl;
SgStatement *stat;
SgExpression *e;
int i,rank;
coeffs *c;
stat=cur_st;
cur_st= st_after; //par_st;
for(sl=dvm_ar;sl;sl=sl->next) {
c = AR_COEFFICIENTS(sl->symb); //((coeffs *) sl->symb-> attributeValue(0,ARRAY_COEF));
rank=Rank(sl->symb);
for(i=2;i<=rank;i++)
doAssignTo_After(new SgVarRefExp(*(c->sc[i])), header_ref(sl->symb,i));
e = opt_base ? (&(*header_ref(sl->symb,rank+2) + * new SgVarRefExp(*(c->sc[1])))) : header_ref(sl->symb,rank+2);
doAssignTo_After(new SgVarRefExp(*(c->sc[rank+2])), e);
//doAssignTo_After(new SgVarRefExp(*(c->sc[rank+2])), header_ref(sl->symb,rank+2));
}
cur_st=stat;
//dvm_ar=NULL;
}
void EndOfParallelLoopNest(SgStatement *stmt, SgStatement *end_stmt, SgStatement *par_do,SgStatement *func)
{ //stmt is last statement of parallel loop or is body of logical IF , which
// is last statement
SgStatement *go_stmt;
if(HPF_program) {
//first_hpf_exec = first_dvm_exec;
INDLoopBegin();
OffDoVarsOfNest(end_stmt);
} else if(!IN_COMPUTE_REGION && !parloop_by_handler) { /*ACC*/
CopyHeaderElems(parallel_dir->lexNext());
dvm_ar=NULL;
}
// replacing the label of DO statements locating above parallel loop in nest,
// which is ended by stmt(or stmt->controlParent()),
// by new label and inserting CONTINUE with this label
ReplaceDoNestLabel_Above(end_stmt, par_do, GetLabel());
if(dvm_debug) {
CloseDoInParLoop(end_stmt); //on debug regim end_stmt==stmt
end_stmt = cur_st;
} else if(perf_analysis == 4 && !IN_COMPUTE_REGION && !parloop_by_handler) { // RTS calls can not be inserted into the handler
SeqLoopEndInParLoop(end_stmt,stmt);
end_stmt = cur_st;
}
if(!IN_COMPUTE_REGION && !parloop_by_handler) {
// generating GO TO statement: GO TO begin_lab
// and inserting it after last statement of parallel loop nest
go_stmt = new SgGotoStmt(*begin_lab);
go_stmt->addAttribute (OMP_MARK); /*OMP*/
cur_st->insertStmtAfter(*go_stmt,*par_do->controlParent());
cur_st = go_stmt; // GO TO statement
SgStatement *continue_stat = new SgStatement(CONT_STAT); /*OMP*/
continue_stat->addAttribute (OMP_MARK); /*OMP*/
InsertNewStatementAfter( continue_stat,cur_st,cur_st->controlParent()); /*OMP*/
}
if(dvm_debug) {
// generating call statement : call dendl(...)
CloseParLoop(end_stmt->controlParent(),cur_st,end_stmt);
}
if(!dvm_debug && stmt->lineNumber())
{
LINE_NUMBER_AFTER_WITH_CP(stmt,cur_st,par_do->controlParent());
}
// generating statements for special ACROSS:
if(iacross == -1){
SendArray(spec_accr);
iacross = 0;
}
if(IN_COMPUTE_REGION) /*ACC*/
// generating call statement to unregister remote_access buffers:
// call dvmh_destroy_array(...)
ACC_UnregisterDvmBuffers();
if(parloop_by_handler != 2 || (parloop_by_handler==2 && WhatInterface(parallel_dir) != 2))
// generating call statement:
// call endpl(LoopRef)
doCallAfter(EndParLoop(iplp));
// generating statements for ACROSS:
if(iacross){
doCallAfter(SendBound(DVM000(iacross)));
doCallAfter(WaitBound(DVM000(iacross)));
doCallAfter(DeleteObject_H (DVM000(iacross)));
}
// actualizing of reduction variables
if(redgref)
ReductionVarsStart(red_list);
if(irg) {//there is synchronous REDUCTION clause in PARALLEL
// generating call statement:
// call strtrd(RedGroupRef)
doCallAfter(StartRed(redgref));
// generating call statement:
// call waitrd(RedGroupRef)
doCallAfter(WaitRed(redgref));
if(IN_COMPUTE_REGION || parloop_by_handler) /*ACC*/
ACC_ReductionVarsAreActual();
if(idebrg){
if(dvm_debug)
doCallAfter( D_CalcRG(DVM000(idebrg)));
doCallAfter( D_DelRG (DVM000(idebrg)));
}
// generating statement:
// call dvmh_delete_object(RedGroupRef) //dvm000(i) = delobj(RedGroupRef)
doCallAfter(DeleteObject_H(redgref));
}
// actualizing of consistent arrays
if(consgref)
ConsistentArraysStart(cons_list);
if(iconsg) {//there is synchronous CONSISTENT clause in PARALLEL
if(IN_COMPUTE_REGION) /*ACC*/
// generating call statement:
// call dvmh_handle_consistent(ConsistGroupRef)
doCallAfter(HandleConsistent(consgref));
// generating assign statement:
// dvm000(i) = strtcg(ConsistGroupRef)
doAssignStmtAfter(StartConsGroup(consgref));
// generating statement:
// dvm000(i) = waitcg(ConsistGroupRef)
doAssignStmtAfter(WaitConsGroup(consgref));
// generating statement:
// call dvmh_delete_object(ConsistGroupRef) //dvm000(i) = delobj(ConsistGroupRef)
doCallAfter(DeleteObject_H(consgref));
}
// generating call eloop(...) - end of parallel interval
// (performance analyzer function)
if(perf_analysis && perf_analysis != 2) {
InsertNewStatementAfter(St_Enloop(INTERVAL_NUMBER,INTERVAL_LINE),cur_st,cur_st->controlParent());
CloseInterval();
if(perf_analysis != 4)
OverLoopAnalyse(func);
}
if(!IN_COMPUTE_REGION && !parloop_by_handler) {
// setting label of ending parallel loop nest
if(!go_stmt->lexNext()->label())
(go_stmt->lexNext())->setLabel(*end_lab);
else
go_stmt->insertStmtAfter(*ContinueWithLabel(end_lab), *go_stmt->controlParent());
}
// implementing parallel loop nest in compute region:
// generating host- and cuda-handlers and cuda kernel for loop body
if(IN_COMPUTE_REGION || parloop_by_handler) /*ACC*/
{ ACC_ParallelLoopEnd(par_do);
if(!IN_COMPUTE_REGION)
DeleteNonDvmArrays();
}
//completing REMOTE_ACCESS
if(rma && !rma->rmout)
RemoteAccessEnd();
SET_DVM(iplp);
}
void CheckClauses(SgStatement *stmt, SgExpression *clause[])
{
SgExpression *el,*e;
// looking through the specification list
for(el=stmt->expr(1); el; el=el->rhs()) {
e = el->lhs(); // specification
switch (e->variant()) {
case NEW_SPEC_OP:
if(!clause[NEW_]){
clause[NEW_] = e;
} else
err("Double NEW clause",153,stmt);
break;
case REDUCTION_OP:
if(!clause[REDUCTION_]){
clause[REDUCTION_] = e;
} else
err("Double REDUCTION clause",154,stmt);
break;
case SHADOW_RENEW_OP:
if(!clause[SHADOW_RENEW_] && !clause[SHADOW_START_] && !clause[SHADOW_START_]){
clause[SHADOW_RENEW_] = e;
} else
err("Double shadow-renew-clause",155,stmt);
break;
case SHADOW_START_OP:
if(!clause[SHADOW_RENEW_] && !clause[SHADOW_START_] && !clause[SHADOW_START_]){
clause[SHADOW_START_] = e;
} else
err("Double shadow-renew-clause",155,stmt);
break;
case SHADOW_WAIT_OP:
if(!clause[SHADOW_RENEW_] && !clause[SHADOW_START_] && !clause[SHADOW_START_]){
clause[SHADOW_WAIT_] = e;
} else
err("Double shadow-renew-clause",155,stmt);
break;
case SHADOW_COMP_OP:
if(!clause[SHADOW_COMPUTE_]){
clause[SHADOW_COMPUTE_] = e;
} else
err("Double SHADOW_COMPUTE clause",155,stmt);
break;
case REMOTE_ACCESS_OP:
if(!clause[REMOTE_ACCESS_]){
clause[REMOTE_ACCESS_] = e;
} else
err("Double REMOTE_ACCESS clause",156,stmt);
break;
case CONSISTENT_OP:
if(!clause[CONSISTENT_]){
clause[CONSISTENT_] = e;
} else
err("Double CONSISTENT clause",296,stmt);
break;
case STAGE_OP:
if(!clause[STAGE_]){
clause[STAGE_] = e;
} else
err("Double STAGE clause",298,stmt);
break;
case ACC_PRIVATE_OP:
if(!clause[PRIVATE_]){
clause[PRIVATE_] = e;
} else
err("Double PRIVATE clause",607,stmt);
break;
case ACC_CUDA_BLOCK_OP:
if(!clause[CUDA_BLOCK_]){
clause[CUDA_BLOCK_] = e;
} else
err("Double CUDA_BLOCK clause",608,stmt);
break;
case ACC_TIE_OP:
if(!clause[TIE_]){
clause[TIE_] = e;
} else
err("Double TIE clause",608,stmt);
break;
case ACROSS_OP:
if(!clause[ACROSS_]){
clause[ACROSS_] = e;
} else
err("Double ACROSS clause",157,stmt);
break;
}
}
if(clause[SHADOW_COMPUTE_] && clause[REDUCTION_])
err("Inconsistent clauses: SHADOW_COMPUTE and REDUCTION",443,stmt);
if(IN_COMPUTE_REGION && ( clause[SHADOW_START_] || clause[SHADOW_WAIT_] || clause[CONSISTENT_] && clause[CONSISTENT_]->symbol() || clause[REMOTE_ACCESS_] && clause[REMOTE_ACCESS_]->symbol()))
err("Illegal clause of PARALLEL directive in region (SHADOW_START,SHADOW_WAIT,asynchronous CONSISTENT or asynchronous REMOTE_ACCESS)",445,stmt);
}
int WhatInterface(SgStatement *stmt)
{
SgExpression *el,*e;
// undistributed parallel loop
if(!stmt->expr(0))
return(2);
// is mapped on template?
//if(stmt->expr(0)->symbol()->attributes() & TEMPLATE_BIT)
// return (1);
// looking through the specification list of PARALLEL directive
for(el=stmt->expr(1); el; el=el->rhs()) {
e = el->lhs(); // specification
switch (e->variant()) {
case ACC_PRIVATE_OP:
case ACC_CUDA_BLOCK_OP:
case SHADOW_RENEW_OP:
case SHADOW_COMP_OP:
case ACROSS_OP:
case ACC_TIE_OP:
case CONSISTENT_OP:
case STAGE_OP:
case REMOTE_ACCESS_OP:
if(e->symbol()) // asynchronous REMOTE_ACCESS
return(1);
else
break;
case REDUCTION_OP:
if(TestReductionClause(e))
break;
else
return(1);
default:
return (1);
}
}
return (2);
}
int areIllegalClauses(SgStatement *stmt)
{
SgExpression *el;
for(el=stmt->expr(1); el; el=el->rhs())
if(el->lhs()->variant() != REDUCTION_OP && el->lhs()->variant() != ACC_PRIVATE_OP && el->lhs()->variant() != ACC_CUDA_BLOCK_OP && el->lhs()->variant() != ACROSS_OP && el->lhs()->variant() != ACC_TIE_OP)
return 1;
return 0;
}
int TestParallelWithoutOn(SgStatement *stmt, int flag)
{
if(!stmt->expr(0) && parloop_by_handler != 2) //undistributed parallel loop
{
if(flag)
warn("PARALLEL directive is ignored, -Opl2 option should be specified",621,stmt);
return(0);
} else
return (1);
}
int TestParallelDirective(SgStatement *stmt, int nloop, int ndo, SgStatement *first_do)
{ // stmt - PARALLEL directive; nloop - number of items in the do-variable list of directive;
// ndo - number of loops (do-statements) in the nest
SgExpression *dovar;
SgStatement *st;
int flag_err=1; //flag of an error message
if(!nloop) // not determined yet (AnalyzeRegion())
{ flag_err = 0;
// first DO statement of the loop nest
first_do = OMP_program ? GetLexNextIgnoreOMP(stmt) : stmt->lexNext();
//looking through the do_variable list of directive
for(dovar=stmt->expr(2); dovar; dovar=dovar->rhs())
nloop++;
//looking through the loop nest
for(st=first_do,ndo=0; ndo<nloop; st=st->lexNext(),ndo++)
{
if(!isSgForStmt(st))
break;
}
}
if(ndo == 0) {
if(flag_err)
err("Directive PARALLEL must be followed by DO statement", 97, stmt);
return(0);
}
if(nloop > ndo) {
if(flag_err)
err("Length of do-variable list in PARALLEL directive is greater than the number of nested DO statements", 158,stmt);
return(0);
}
for(st=first_do,dovar=stmt->expr(2); dovar; st=st->lexNext(),dovar=dovar->rhs())
{
if(dovar->lhs()->symbol() != st->symbol()) {
if(flag_err)
err("Illegal do-variable list in PARALLEL directive",159,stmt);
return(0);
}
}
if(!stmt->expr(0) && areIllegalClauses(stmt)) //undistributed parallel loop
{
if(flag_err)
err("Illegal clause",150,stmt );
return(0);
}
if(!only_debug && stmt->expr(0) && !HEADER(stmt->expr(0)->symbol())) {
if(flag_err)
Error("'%s' isn't distributed array", stmt->expr(0)->symbol()->identifier(), 72,stmt);
return(0);
}
return(1);
}
int doParallelLoopByHandler(int iplp, SgStatement *first, SgExpression *clause[], SgExpression *oldGroup, SgExpression *newGroup,SgExpression *oldGroup2, SgExpression *newGroup2)
{ /*ACC*/
int ilh = ndvm;
LINE_NUMBER_AFTER(first,cur_st);
cur_st->addComment(ParallelLoopComment(first->lineNumber()));
doAssignStmtAfter(LoopCreate_H(cur_region ? cur_region->No : 0, iplp));
if (clause[REDUCTION_]) //there is REDUCTION clause in parallel loop
InsertReductions_H(clause[REDUCTION_]->lhs(), ilh);
if (clause[CUDA_BLOCK_]) //there is CUDA_BLOCK clause
{
int ib;
ib = ndvm;
CudaBlockSize(clause[CUDA_BLOCK_]->lhs());
InsertNewStatementAfter(SetCudaBlock_H(ilh, ib), cur_st, cur_st->controlParent());
}
if (clause[TIE_]) //there is TIE clause
{
SgExpression *el;
for (el=clause[TIE_]->lhs(); el; el=el->rhs())
InsertNewStatementAfter(Correspondence_H(ilh, HeaderForArrayInParallelDir(el->lhs()->symbol(),parallel_dir,1), AxisList(parallel_dir,el->lhs())), cur_st, cur_st->controlParent());
}
if (oldGroup) // loop with ACROSS clause
InsertNewStatementAfter(LoopAcross_H(ilh, oldGroup, newGroup), cur_st, cur_st->controlParent());
if (oldGroup2) // loop with ACROSS clause
InsertNewStatementAfter(LoopAcross_H(ilh, oldGroup2, newGroup2), cur_st, cur_st->controlParent());
return(ilh);
}
void Interface_1(SgStatement *stmt,SgExpression *clause[],SgSymbol *do_var[],SgExpression *init[],SgExpression *last[],SgExpression *step[],int nloop,int ndo,SgStatement *first_do,int iplp,int iout,SgStatement *stl,SgSymbol *newj,int ub)
{
SgStatement *stc,*if_stmt=NULL,*st2=NULL,*st3=NULL;
SgStatement *stdeb = NULL,*stat = NULL,*stg = NULL,*stcg = NULL;
SgValueExp c0(0),c1(1);
SgExpression *stage=NULL,*dopl=NULL,*dovar,*head;
SgExpression *oldGroup = NULL, *newGroup=NULL; /*ACC*/
SgExpression *oldGroup2 = NULL, *newGroup2=NULL; /*ACC*/
SgSymbol *spat;
int all_positive_step=-1;
int iacrg=-1,iinp;
int iaxis,i, isg = 0;
int nr; //number of aligning rules i.e. length of align-loop-index-list
int ag[3] = {0, 0, 0};
int step_mask[MAX_LOOP_LEVEL],
loop_num[MAX_DIMS];
stc = cur_st; // saving
// generating assign statement:
// dvm000(iplp) = crtpl(Rank);
//iplp = CreateParLoop( nloop);
doAssignTo_After(DVM000(iplp),CreateParLoop(nloop));
if(dvm_debug && dbg_if_regim>1) { //copy loop nest
SgStatement *last_st,*lst;
last_st= LastStatementOfDoNest(first_do);
if(last_st != (lst=first_do->lastNodeOfStmt()) || last_st->variant()==LOGIF_NODE)
{ last_st=ReplaceLabelOfDoStmt(first_do,last_st, GetLabel());
ReplaceDoNestLabel_Above(last_st,first_do,GetLabel());
}
stdeb=first_do->copyPtr();
}
//---------------------------------------------------------------------------
// processing specifications/clauses
if(clause[NEW_])
NewVarList(clause[NEW_]->lhs(),stmt);
if(clause[REDUCTION_])
{
red_list = clause[REDUCTION_]->lhs();
stat = cur_st; //store current statement
cur_st = stc; //insert statements for creating reduction group
//before CrtPL i.e. before creating parallel loop
if( clause[REDUCTION_]->symbol()) {
redgref = new SgVarRefExp(clause[REDUCTION_]->symbol());
doIfForReduction(redgref,1);
nloopred++;
stg = doIfForCreateReduction( clause[REDUCTION_]->symbol(),nloopred,0);
} else {
irg = ndvm;
redgref = DVM000(irg);
doAssignStmtAfter(CreateReductionGroup());
if(debug_regim){
idebrg = ndvm;
doAssignStmtAfter( D_CreateDebRedGroup());
}
stg = cur_st;//store current statement
}
cur_st = stat; // restore cur_st
}
if(clause[SHADOW_RENEW_])
{
isg = ndvm++;// index for BoundGroupRef
CreateBoundGroup(DVM000(isg));
//looking through the array_with_shadow_list
ShadowList(clause[SHADOW_RENEW_]->lhs(), stmt, DVM000(isg));
if(ACC_program) /*ACC*/
{// generating call statement ( in and out compute region):
// call dvmh_shadow_renew( BoundGroupRef)
doCallAfter(ShadowRenew_H(DVM000(isg))); //(GPU000(ish_gpu),StartShadow_GPU(cur_region->No,DVM000(isg)));
}
// generating assign statement:
// dvm000(i) = strtsh(BoundGroupRef)
doCallAfter(StartBound(DVM000(isg)));
}
if(clause[SHADOW_START_]) //sh_start
{
SgExpression *sh_start = new SgVarRefExp(clause[SHADOW_START_]->symbol());
if(ACC_program) /*ACC*/
{// generating call statement ( in and out compute region):
// call dvmh_shadow_renew( BoundGroupRef)
doCallAfter(ShadowRenew_H(sh_start));
}
// generating assign statement:
// dvm000(i) = exfrst(LoopRef,BounGroupRef)
doCallAfter(BoundFirst(iplp,sh_start));
}
if(clause[SHADOW_WAIT_]) //sh_wait
// generating assign statement:
// dvm000(i) = imlast(LoopRef,BounGroupRef)
doCallAfter(BoundLast(iplp,new SgVarRefExp(clause[SHADOW_WAIT_]->symbol())));
if(clause[SHADOW_COMPUTE_])
{
if( (clause[SHADOW_COMPUTE_]->lhs()))
ShadowComp(clause[SHADOW_COMPUTE_]->lhs(),stmt,0);
else
doCallAfter(AddBound());
}
if(clause[REMOTE_ACCESS_])
{
//adding new element to remote_access directive/clause list
AddRemoteAccess(clause[REMOTE_ACCESS_]->lhs(),NULL);
}
if(clause[CONSISTENT_])
{
SgExpression *e = clause[CONSISTENT_];
cons_list = e->lhs();
stat = cur_st; //store current statement
cur_st = stc; //insert statements for creating reduction group
//before CrtPL i.e. before creating parallel loop
if( e->symbol()){
consgref = new SgVarRefExp(e->symbol());
doIfForConsistent(consgref);
nloopcons++;
stcg = doIfForCreateReduction( e->symbol(),nloopcons,0);
} else {
iconsg = ndvm;
consgref = DVM000(iconsg);
doAssignStmtAfter(CreateConsGroup(1,1));
//!!!??? if(debug_regim){
// idebcg = ndvm;
// doAssignStmtAfter( D_CreateDebRedGroup());
//}
stcg = cur_st;//store current statement
}
cur_st = stat; // restore cur_st
}
if(clause[STAGE_])
{
if( clause[STAGE_]->lhs()->variant()==MINUS_OP && INTEGER_VALUE(clause[STAGE_]->lhs()->lhs(),1) ) //STAGE(-1)
stage = IN_COMPUTE_REGION ? GetStage(first_do,iplp) : &c0.copy();
else
stage = ReplaceFuncCall(clause[STAGE_]->lhs());
}
if (clause[TIE_])
for (SgExpression *el=clause[TIE_]->lhs(); el; el=el->rhs()) //list of tied arrays
AxisList(stmt, el->lhs()); //for testing
if(clause[ACROSS_])
{
int not_in=0;
SgExpression *e_spec[2];
SgExpression *e = clause[ACROSS_];
int all_steps = Analyze_DO_steps(step,step_mask,ndo);
InOutAcross(e,e_spec,stmt);
SgExpression *in_spec =e_spec[IN_];
SgExpression *out_spec=e_spec[OUT_];
if(not_in && in_spec && !out_spec) { // old implementation
stat = cur_st;//store current statement
cur_st = stc; //insert statements for creating shadow group
//before CrtPL i.e. before creating parallel loop
iacross = ndvm++;// index for ShadowGroupRef
//looking through the dependent_array_list
if(DepList(e->lhs(), stmt, DVM000(iacross),ANTIDEP)){
doCallAfter(StartBound(DVM000(iacross)));
doCallAfter(WaitBound(DVM000(iacross)));
doAssignStmtAfter(DeleteObject(DVM000(iacross)));
SET_DVM(iacross+1);
}
if(DepList(e->lhs(), stmt, DVM000(iacross),FLOWDEP)){
doCallAfter(ReceiveBound(DVM000(iacross)));
doCallAfter(WaitBound(DVM000(iacross)));
SET_DVM(iacross+1);
} else {
if (iacross == -1)
spec_accr = e->lhs();
else
iacross = 0;
}
cur_st = stat; // restore cur_st
} else {// new implementation
iacrg=ndvm; ndvm+=3;
if(IN_COMPUTE_REGION || parloop_by_handler)
ndvm+=3;
CreateShadowGroupsForAccross(in_spec,out_spec,stmt,ACC_GroupRef(iacrg),ACC_GroupRef(iacrg+1),ACC_GroupRef(iacrg+2),ag,all_steps,step_mask,(clause[TIE_] ? clause[TIE_]->lhs() : NULL) );
/*
if(all_positive_step) //(PositiveDoStep(step,ndo))
CreateShadowGroupsForAccross(in_spec,out_spec,stmt,ACC_GroupRef(iacrg),ACC_GroupRef(iacrg+1),ACC_GroupRef(iacrg+2),ag,all_positive_step,loop_num);
else {
//ag[1] = -1;
if(out_spec || in_spec->rhs() )
//if(in_spec->rhs()) in_spec->rhs()->unparsestdout();
err("Illegal ACROSS clause",444,stmt);
else if (stmt->expr(0)->symbol() != (in_spec->lhs()->variant() == ARRAY_OP ? in_spec->lhs()->lhs()->symbol() : in_spec->lhs()->symbol()))
Error("The base array '%s' should be specified in ACROSS clause", stmt->expr(0)->symbol()->identifier(), 256, stmt);
DefineLoopNumberForNegStep(step_mask,DefineLoopNumberForDimension(stmt,loop_num),loop_num);
CreateShadowGroupsForAccrossNeg(in_spec,stmt,ACC_GroupRef(iacrg),ACC_GroupRef(iacrg+2),ag,all_positive_step,loop_num);
//k=ag[2]; ag[2] = ag[0]; ag[0] = k;
} */
}
}
//------------------------------------------------------------------------------
iinp = ndvm;
if(dvm_debug)
OpenParLoop_Inter(stl,iinp,iinp+nloop,do_var,nloop);
// creating LoopVarAddrArray, LoopVarTypeArray,InpInitIndexArray, InpLastIndexArray
// and InpStepArray
for(i=0,dovar=stmt->expr(2); i<nloop; i++,dovar=dovar->rhs())
doAssignStmtAfter(GetAddres(do_var[i]));
for(i=0; i<nloop; i++)
doAssignStmtAfter( new SgValueExp(LoopVarType(do_var[i],stmt)));
for(i=0; i<nloop; i++)
doAssignStmtAfter( init[i] );
for(i=0; i<nloop; i++)
doAssignStmtAfter( last[i] );
for(i=0; i<nloop; i++)
doAssignStmtAfter( step[i] );
// creating AxisArray, CoeffArray and ConstArray
spat = (stmt->expr(0))->symbol(); // target array symbol
head = HeaderRef(spat);
iaxis = ndvm;
nr = doAlignIteration(stmt,NULL);
if(isg) {
// generating assign statement:
// dvm000(i) = waitsh(BoundGroupRef)
doCallAfter(WaitBound(DVM000(isg)));
}
// generating assign statement:
// dvm000(i) =
// mappl(LoopRef, PatternRef, AxisArray[], CoefArray[], ConstArray[],
// LoopVarAdrArray[], InpInitIndexArray[], InpLastIndexArray[],
// InpStepArray[],
// OutInitIndexArray[], OutLastIndexArray[], OutStepArray[])
doCallAfter( BeginParLoop (iplp, head, nloop, iaxis, nr, iinp, iout));
if(redgref) {
if(!irg) {
st2 = doIfForCreateReduction( redgref->symbol(),nloopred,1);
st3 = cur_st;
ReductionList(red_list,redgref,stmt,stg,st2,0);
cur_st = st3;
InsertNewStatementAfter( new SgAssignStmt(*DVM000(ndvm),*new SgValueExp(0)),cur_st,cur_st->controlParent());
} else
ReductionList(red_list,redgref,stmt,stg,cur_st,0);
}
if(consgref) {
if(!iconsg) {
st2 = doIfForCreateReduction( consgref->symbol(),nloopcons,1);
st3 = cur_st;
ConsistentArrayList(cons_list,consgref,stmt,stcg,st2);
cur_st = st3;
InsertNewStatementAfter( new SgAssignStmt(*DVM000(ndvm),*new SgValueExp(0)),cur_st,cur_st->controlParent());
} else
ConsistentArrayList(cons_list,consgref,stmt,stcg,cur_st);
}
if(clause[REMOTE_ACCESS_]) //rvle
RemoteVariableList(clause[REMOTE_ACCESS_]->symbol(), clause[REMOTE_ACCESS_]->lhs(), stmt);
if(iacross == -1)
ReceiveArray(spec_accr,stmt);
if(clause[ACROSS_] && !clause[STAGE_]) // there is ACROSS clause and is not STAGE clause
stage = &c0.copy(); //IN_COMPUTE_REGION ? GetStage(first_do,iplp) : &c0.copy();
if(all_positive_step) {
if(ag[0]) {
pipeline=1;
doAssignTo_After(new SgVarRefExp(Pipe), stage);
if(ACC_program && ag[2]) /*ACC*/
// generating call statement ( in and out compute region):
// call dvmh_shadow_renew( BoundGroupRef)
doCallAfter(ShadowRenew_H (DVM000(iacrg+2) ));
doCallAfter(InitAcross(0,(ag[2] ? DVM000(iacrg+2) : ConstRef(0)),DVM000(iacrg)));
if(IN_COMPUTE_REGION || parloop_by_handler)
{ oldGroup = ag[2] ? DVM000(iacrg+5) : ConstRef(0); /*ACC*/
newGroup = DVM000(iacrg+3); /*ACC*/
}
if(ag[1]) {
doCallAfter(InitAcross(1, ConstRef(0), DVM000(iacrg+1)));
if(IN_COMPUTE_REGION || parloop_by_handler)
{ oldGroup2 = ConstRef(0); /*ACC*/
newGroup2 = DVM000(iacrg+4); /*ACC*/
}
}
}
else {
if(ag[1]){
pipeline=1;
doAssignTo_After(new SgVarRefExp(Pipe), stage);
if(ACC_program && ag[2]) /*ACC*/
// generating call statement ( in and out compute region):
// call dvmh_shadow_renew( BoundGroupRef)
doCallAfter(ShadowRenew_H (DVM000(iacrg+2) ));
doCallAfter(InitAcross(1,(ag[2] ? DVM000(iacrg+2) : ConstRef(0)),DVM000(iacrg+1)));
if(IN_COMPUTE_REGION || parloop_by_handler)
{ oldGroup = ag[2] ? DVM000(iacrg+5) : ConstRef(0); /*ACC*/
newGroup = DVM000(iacrg+4); /*ACC*/
}
}
else if(ag[2]){
//err("SHADOW_RENEW clause is required",...,stmt);
pipeline=1;
doAssignTo_After(new SgVarRefExp(Pipe), stage);
if(ACC_program) /*ACC*/
// generating call statement ( in and out compute region):
// call dvmh_shadow_renew( BoundGroupRef)
doCallAfter(ShadowRenew_H (DVM000(iacrg+2) ));
//doCallAfter(StartBound(DVM000(iacrg+2))); /*09.12.19*/
//doCallAfter(WaitBound (DVM000(iacrg+2))); /*09.12.19*/
doCallAfter(InitAcross(1,DVM000(iacrg+2), ConstRef(0))); /*09.12.19*/
if(IN_COMPUTE_REGION || parloop_by_handler)
{ oldGroup = DVM000(iacrg+5); /*ACC*/
newGroup = ConstRef(0); /*ACC*/
}
}
}
} else{ //there is negative loop step
if(ag[0] || ag[2]) {
pipeline=1;
doAssignTo_After(new SgVarRefExp(Pipe), stage);
if(ACC_program && ag[2]) /*ACC*/
// generating call statement ( in and out compute region):
// call dvmh_shadow_renew( BoundGroupRef)
doCallAfter(ShadowRenew_H (DVM000(iacrg+2) ));
doCallAfter(InitAcross(0,(ag[2] ? DVM000(iacrg+2) : ConstRef(0)),(ag[0] ? DVM000(iacrg) : ConstRef(0))));
if(IN_COMPUTE_REGION || parloop_by_handler)
{ oldGroup = ag[2] ? DVM000(iacrg+5) : ConstRef(0); /*ACC*/
newGroup = ag[0] ? DVM000(iacrg+3) : ConstRef(0); /*ACC*/
}
}
}
if(dvm_debug) {
pardo_line = first_do->lineNumber();
DebugParLoop(cur_st,nloop,iinp+2*nloop);
}
StoreLoopPar(init,nloop,iout,NULL);
StoreLoopPar(last,nloop,iout+nloop,NULL);
if(opt_loop_range) ChangeLoopInitPar(first_do,nloop,init,stmt->lexNext());//must be after StoreLoopPar
if (OMP_program == 1) { /*OMP*/
if (clause[ACROSS_]) { /*OMP*/
ChangeAccrossOpenMPParam (first_do,newj,ub); /*OMP*/
} /*OMP*/
} /*OMP*/
if(!IN_COMPUTE_REGION && !parloop_by_handler)
{
// generating Logical IF statement:
// begin_lab IF (DoPL(LoopRef) .EQ. 0) GO TO end_lab
// and inserting it before loop nest
SgStatement *stn = cur_st;
SgStatement *continue_stat = new SgStatement(CONT_STAT); /*OMP*/
continue_stat->addAttribute (OMP_MARK);
InsertNewStatementAfter(continue_stat,cur_st,cur_st->controlParent()); /*OMP*/
LINE_NUMBER_AFTER(first_do,cur_st);
begin_lab = GetLabel();
stn->lexNext()-> setLabel(*begin_lab);
end_lab = GetLabel();
if(dvm_debug && dbg_if_regim)
{
int ino;
ino = ndvm;
doAssignStmtAfter(new SgValueExp(pardo_No));
dopl = doPLmb(iplp,ino);
} else
dopl = doLoop(iplp);
//if_stmt = new SgLogIfStmt(SgEqOp(*dopl , c0), *new SgGotoStmt(*end_lab));
//if_stmt -> setLabel(*begin_lab); /*29.06.01*/
// BIF_LABEL(stmt->thebif) = NULL;
doAssignStmtAfter(dopl); // podd 17.05.11 (doLoop(iplp));/*OMP*/
SgGotoStmt *go=new SgGotoStmt(*end_lab);/*OMP*/
go->addAttribute (OMP_MARK);/*OMP*/
if_stmt = new SgLogIfStmt(SgEqOp(*DVM000(ndvm-1), c0), *go);/*OMP*/
if_stmt->addAttribute (OMP_MARK);/*OMP*/
//if_stmt = new SgLogIfStmt(SgEqOp(*dopl , c0), *new SgGotoStmt(*end_lab));
//cur_st->insertStmtAfter(*if_stmt);
InsertNewStatementAfter (if_stmt, cur_st, cur_st->controlParent ());/*OMP*/
if(opt_loop_range)
{
cur_st=if_stmt->lexNext()->lexNext();
doAssignIndexVar(stmt->expr(2),iout,init);
}
(if_stmt->lexNext()->lexNext()) -> extractStmt(); //extract ENDIF
// (error Sage)
}
if(IN_COMPUTE_REGION || parloop_by_handler) /*ACC*/
{ int ilh = doParallelLoopByHandler(iplp, first_do, clause, oldGroup, newGroup,oldGroup2, newGroup2);
ACC_CreateParallelLoop(ilh,first_do,nloop,stmt,clause,1);
}
if(dvm_debug && dbg_if_regim>1)
{
SgStatement *ifst = new SgIfStmt(*DebugIfNotCondition(), *stdeb); //*new SgStatement(CONT_STAT));// *stdeb); //, *new SgStatement(CONT_STAT));
(if_stmt->lexNext())->insertStmtAfter(*ifst,*if_stmt->controlParent());
// generating GO TO statement: GO TO begin_lab
// and inserting it after last statement of parallel loop nest copy
// InsertNewStatementBefore(new SgGotoStmt(*begin_lab),ifst->lastNodeOfStmt());
//(ifst->lastNodeOfStmt())->insertStmtBefore(*new SgGotoStmt(*begin_lab),*ifst);
//InsertNewStatementAfter(new SgGotoStmt(*begin_lab),stdeb->lastNodeOfStmt(),ifst);
(stdeb->lastNodeOfStmt())->insertStmtAfter(*new SgGotoStmt(*begin_lab),*ifst);
TranslateBlock(stdeb);
}
}
void ChangeLoopInitPar(SgStatement*first_do,int nloop,SgExpression *do_init[],SgStatement *after)
{ SgStatement *stat, *st;
SgForStmt *stdo;
SgSymbol *s,*do_var, *s_start;
SgExpression *init;
int i;
stat=cur_st;
cur_st=after;
for(st=first_do,i=0; i<nloop; st=st->lexNext(),i++) {
stdo = isSgForStmt(st);
if(!stdo) break;
do_var = stdo->symbol();
init = stdo->start();
// for(i=0; i<n; i++)
if(isSgVarRefExp(init)) {
s = init->symbol();
if(s && isInSymbList(newvar_list,s)){
s_start = CreateInitLoopVar(do_var,s);
doAssignTo_After(new SgVarRefExp(s_start),&(init->copy()));
stdo->setStart(*new SgVarRefExp(s_start));
do_init[i] = stdo->start();
}
}
}
cur_st=stat;
}
int PositiveDoStep(SgExpression *step[], int i)
{int s;
SgExpression *es;
if(step[i]->isInteger())
s=step[i]->valueInteger();
else if((es=Calculate(step[i]))->isInteger())
s= es->valueInteger();
else
{ err("Non constant step in parallel loop nest with ACROSS clause",613,par_do);
s =0;
}
if(s >= 0)
return(1);
else
return(0);
}
int Analyze_DO_steps(SgExpression *step[], int step_mask[],int ndo)
{ int s,i;
s=1;
for(i=0; i<ndo; i++) {
step_mask[i] = PositiveDoStep(step, i);
s = s && step_mask[i];
}
if(s) return(1);
s = -1;
for(i=0; i<ndo; i++)
if(step_mask[i] > 0)
return (0);
return (-1);
}
void InOutAcross(SgExpression *e, SgExpression* e_spec[], SgStatement *stmt)
{
e_spec[IN_] = NULL;
e_spec[OUT_]= NULL;
InOutSpecification(e->lhs(), e_spec);
InOutSpecification(e->rhs(), e_spec);
if(e->lhs() && e->rhs() && (e_spec[IN_] == NULL || e_spec[OUT_] == NULL))
err("Double IN/OUT specification in ACROSS clause",257 ,stmt);
}
void InOutSpecification(SgExpression *ea,SgExpression* e_spec[])
{
SgKeywordValExp *kwe;
if(!ea) return;
if(ea->variant() != DDOT) {
e_spec[IN_] = ea;
} else {
if((kwe=isSgKeywordValExp(ea->lhs())) && (!strcmp(kwe->value(),"in")))
e_spec[IN_] = ea->rhs();
else
e_spec[OUT_] = ea->rhs();
}
}
void CreateShadowGroupsForAccross(SgExpression *in_spec,SgExpression *out_spec,SgStatement * stmt,SgExpression *gleft,SgExpression *g,SgExpression *gright,int ag[],int all_steps,int step_mask[],SgExpression *tie_list)
{
RecurList(in_spec, stmt,gleft, ag,0,all_steps,step_mask,tie_list);
RecurList(out_spec,stmt,gleft, ag,0,all_steps,step_mask,tie_list);
RecurList(in_spec, stmt,gright,ag,2,all_steps,step_mask,tie_list);
RecurList(out_spec,stmt,gright,ag,2,all_steps,step_mask,tie_list);
if(ag[1] == -1)
ag[1] = 0;
else
RecurList(out_spec,stmt,g,ag,1,all_steps,step_mask,tie_list);
}
void DefineLoopNumberForNegStep(int step_mask[], int n,int loop_num[])
{int i;
for(i=0;i<n;i++)
if(loop_num[i] > 0)
if(step_mask[loop_num[i]-1] > 0)
loop_num[i] = 0;
}
void DefineStepSignForDimension( int step_mask[], int n, int loop_num[], int sign[] )
{int i;
for(i=0; i<MAX_DIMS; i++)
sign[i] = 0;
for(i=0;i<n;i++)
if(loop_num[i] > 0)
sign[i] = step_mask[loop_num[i]-1] > 0 ? 1 : -1;
}
/*
void CreateShadowGroupsForAccrossNeg(SgExpression *in_spec, SgStatement * stmt, SgExpression *gleft,SgExpression *gright,int ag[],int all_positive_step,int loop_num[])
{
RecurList(in_spec, stmt,gleft, ag,0,all_positive_step,loop_num);
// RecurList(out_spec,stmt,gleft, ag,0);
RecurList(in_spec, stmt,gright,ag,2,all_positive_step,loop_num);
// RecurList(out_spec,stmt,gright,ag,2);
if(ag[1] == -1)
ag[1] = 0;
// else
// RecurList(out_spec,stmt,g,ag,1);
}
*/
SgExpression *FindArrayRefWithLoopIndexes(SgSymbol *ar, SgStatement *st, SgExpression *tie_list)
{
SgExpression *arr_ref = NULL;
if( ar == st->expr(0)->symbol())
arr_ref = st->expr(0);
else
arr_ref = tie_list ? isInTieList(ar, tie_list) : NULL;
if(!arr_ref)
Error("Array from ACROSS clause should be specified in TIE clause: %s", ar->identifier(), 648, st);
return arr_ref;
}
int RecurList (SgExpression *el, SgStatement *st, SgExpression *gref, int *ag, int gnum,int all_steps,int step_mask[],SgExpression *tie_list)
{ SgValueExp c1(1);
int rank,ndep;
int ileft,idv[6];
SgExpression *es, *ear, *head, *esec, *esc, *lrec[MAX_DIMS], *rrec[MAX_DIMS], *gref_acc = NULL;
SgSymbol *ar;
int loop_num[MAX_DIMS], sign[MAX_DIMS];
//int nel = 0;
// looking through the dependent_array_list
for(es = el; es; es = es->rhs()) {
if( es->lhs()->variant() == ARRAY_OP){
ear = es->lhs()->lhs();
esec= es->lhs()->rhs();
//corner = 1;
} else {
ear = es->lhs(); // dependent_array
esec = NULL;
//corner = 0;
if(!ear->lhs()){ //whole array
iacross = -1;
return(0);
}
}
ar = ear->symbol();
if(HEADER(ar))
head = HeaderRef(ar);
else
{
Error("'%s' isn't distributed array", ar->identifier(), 72,st);
return(0);
}
rank = Rank(ar);
ileft = ndvm;
if(!all_steps)
DefineStepSignForDimension(step_mask, DefineLoopNumberForDimension(st, FindArrayRefWithLoopIndexes(ar,st,tie_list), loop_num), loop_num, sign);
ndep = doRecurLengthArrays(ear->lhs(), ear->symbol(), st, gnum, all_steps, sign);
if(!ndep) continue;
if(GROUP_INDEX(gref))
gref_acc=DVM000(*GROUP_INDEX(gref));
ag[gnum]++;
if(ag[gnum] == 1)
{ CreateBoundGroup(gref);
if( (IN_COMPUTE_REGION || parloop_by_handler) && GROUP_INDEX(gref) ) /*ACC*/
CreateBoundGroup(gref_acc);
}
if(!esec)
{ doCallAfter(InsertArrayBoundDep(gref, head, ileft, ileft+rank, 1, ileft+2*rank));
if( (IN_COMPUTE_REGION || parloop_by_handler) && GROUP_INDEX(gref) ) /*ACC*/
doCallAfter(InsertArrayBoundDep(gref_acc, head, ileft, ileft+rank, 1, ileft+2*rank));
}
else {
if(!Recurrences(ear->lhs(),lrec,rrec,MAX_DIMS))
err("Recurrence list is not specified", 261, st);
for(esc=esec; esc; esc=esc->rhs()) {
doSectionIndex(esc->lhs(), ear->symbol(), st, idv, ileft, lrec, rrec);
doCallAfter(InsertArrayBoundSec(gref, head, idv[0],idv[1],idv[2], idv[3],idv[4], idv[5], 1, ileft+2*rank));
if( (IN_COMPUTE_REGION || parloop_by_handler) && GROUP_INDEX(gref) ) /*ACC*/
doCallAfter(InsertArrayBoundSec(gref_acc, head, idv[0],idv[1],idv[2], idv[3],idv[4], idv[5], 1, ileft+2*rank));
}
}
}
return(ag[gnum]);
}
int doRecurLengthArrays(SgExpression *shl, SgSymbol *ar, SgStatement *st, int rtype, int all_steps,int sign[])
{SgValueExp c0(0),c1(1),cM1(-1),c3(3), c5(5);
int rank,nw,nnl,positive=0;
int i=0;
nnl = 0;
SgExpression *wl,*ew, *bound[MAX_DIMS],*null[MAX_DIMS],*shsign[MAX_DIMS],*eneg;
rank = Rank(ar);
if(!shl) //without dependence-list ,
// by default dependence length is equal to the maximal size of shadow edge
for(i=rank-1,nnl=1; i>=0; i--) {
bound[i] = &cM1;
null[i] = &c0;
shsign[i] = &c3;
}
if(!TestMaxDims(shl,ar,st))
return(0);
for(wl = shl; wl; wl = wl->rhs(),i++) {
ew = wl->lhs();
positive = (all_steps == 1 || all_steps == 0 && sign[i] >= 0) ? 1 : 0;
if(rtype > 0) {
if(positive)
bound[i] = &(ew->rhs())->copy();//right bound
else
bound[i] = &(ew->lhs())->copy();//left bound
}
else {
if(positive)
bound[i] = &(ew->lhs())->copy();//left bound
else
bound[i] = &(ew->rhs())->copy();//right bound
}
null[i] = &c0;
if(bound[i]->variant() != INT_VAL) {
Error("Wrong dependence length of distributed array '%s'",ar->identifier(),179,st);
shsign[i] = &c1;
}
else if(bound[i]->valueInteger() != 0) {
nnl++;
if(positive)
shsign[i] = (rtype > 0) ? &c5 : &c3;
else {
shsign[i] = (rtype > 0) ? &c3 : &c5;
eneg = null[i] ;
null[i] = bound[i];
bound[i] = eneg;
}
} else
shsign[i] = &c1;
}
nw = i;
if (rank && (nw != rank) ) {// wrong dependence length list length
if(rtype == 0)
Error("Wrong dependence length list of distributed array '%s'", ar->identifier(),180,st);
return(0);
}
if(!nnl) return(0);
if(rtype > 0){
TestShadowWidths(ar, null, bound, nw, st);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(null[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(bound[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(shsign[i]);
}
else {
TestShadowWidths(ar, bound, null, nw, st);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(bound[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(null[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(shsign[i]);
}
return(nnl);
}
/* according Language Description (by dependence length)
int doRecurLengthArrays(SgExpression *shl, SgSymbol *ar, SgStatement *st, int rtype,int all_positive_step,int loop_num[])
{SgValueExp c0(0),c1(1),cM1(-1),c3(3), c5(5);
int rank,nw,nnl,flag;
int i=0;
nnl = 0;
SgExpression *wl,*ew, *bound[MAX_DIMS],*null[MAX_DIMS],*shsign[MAX_DIMS],*eneg;
rank = Rank(ar);
if(!shl) //without dependence-list ,
// by default dependence length is equal to the maximal size of shadow edge
for(i=rank-1,nnl=1; i>=0; i--){
bound[i] = &cM1;
null[i] = &c0;
shsign[i] = &c3;
}
if(!TestMaxDims(shl,ar,st))
return(0);
for(wl = shl; wl; wl = wl->rhs(),i++) {
ew = wl->lhs();
flag = all_positive_step ? 0 : loop_num[i];
if(rtype > 0) {
//if(!flag)
bound[i] = &(ew->rhs())->copy();//right bound
//else
// bound[i] = &(ew->lhs())->copy();//left bound
}
else {
//if(!flag)
bound[i] = &(ew->lhs())->copy();//left bound
//else
// bound[i] = &(ew->rhs())->copy();//right bound
}
null[i] = &c0;
if(bound[i]->variant() != INT_VAL) {
Error("Wrong dependence length of distributed array '%s'",ar->identifier(),179,st);
shsign[i] = &c1;
}
else if(bound[i]->valueInteger() != 0) {
nnl++;
if(!flag)
shsign[i] = (rtype > 0) ? &c5 : &c3;
else {
shsign[i] = (rtype > 0) ? &c3 : &c5;
eneg = null[i] ;
null[i] = bound[i];
bound[i] = eneg;
}
} else
shsign[i] = &c1;
}
nw = i;
if (rank && (nw != rank) ) {// wrong dependence length list length
if(rtype == 0)
Error("Wrong dependence length list of distributed array '%s'", ar->identifier(),180,st);
return(0);
}
if(!nnl) return(0);
if(rtype > 0){
TestShadowWidths(ar, null, bound, nw, st);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(null[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(bound[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(shsign[i]);
}
else {
TestShadowWidths(ar, bound, null, nw, st);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(bound[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(null[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(shsign[i]);
}
return(nnl);
}
*/
int Recurrences(SgExpression *shl, SgExpression *lrec[], SgExpression *rrec[],int n)
{SgValueExp c0(0),c1(1);
int i;
SgExpression *wl,*ew;
if(!shl) //without recurrence list
return(0);
for(i=n; i;i--){
rrec[i-1] = &c0.copy();
lrec[i-1] = &c0.copy();
}
for(wl = shl,i=0; wl; wl = wl->rhs(),i++) {
ew = wl->lhs();
rrec[i] = &(ew->rhs())->copy();//right bound
lrec[i] = &(ew->lhs())->copy();//left bound
}
return(i);
}
int DepList (SgExpression *el, SgStatement *st, SgExpression *gref, int dep)
{ SgValueExp c1(1);
int corner,rank,ndep;
int ileft;
SgExpression *es, *ear, *head;
SgSymbol *ar;
int nel = 0;
// looking through the dependent_array_list
for(es = el; es; es = es->rhs()) {
if( es->lhs()->variant() == ARRAY_OP){
ear = es->lhs()->lhs();
corner = 1;
} else {
ear = es->lhs(); // dependent_array
corner = 0;
if(!ear->lhs()){ //whole array
iacross = -1;
return(0);
}
}
ar = ear->symbol();
if(HEADER(ar))
head = HeaderRef(ar);
else {
Error("'%s' isn't distributed array", ar->identifier(), 72,st);
return(0);
}
rank = Rank(ar);
ileft = ndvm;
ndep = doDepLengthArrays(ear->lhs(), ear->symbol(), st,dep);
if(!ndep) continue;
nel++;
if(nel == 1)
CreateBoundGroup(gref);
if(dep == ANTIDEP)
doCallAfter(InsertArrayBound(gref, head, ileft, ileft+rank, corner));
else
doCallAfter(InsertArrayBoundDep(gref, head, ileft, ileft+rank,(corner ? rank : 1), ileft+2*rank));
}
return(nel);
}
/*
int doDepLengthArrays(SgExpression *shl, SgSymbol *ar, SgStatement *st, int dep)
{SgValueExp c0(0);
int rank,iright,nw,nnl;
int i=0;
SgExpression *wl,*ew, *lbound[7], *ubound[7];
rank = Rank(ar);
nnl = 0;
for(wl = shl; wl; wl = wl->rhs(),i++) {
ew = wl->lhs();
if(dep == ANTIDEP){
lbound[i] = &c0; //left bound
ubound[i] = &(ew->rhs())->copy();//right bound
if(ubound[i]->variant() != INT_VAL)
Error("Wrong dependence length of distributed array '%s'",ar->identifier(),179,st);
else if(ubound[i]->valueInteger() != 0)
nnl++;
} else {
lbound[i] = &(ew->lhs())->copy();//left bound
ubound[i] = &c0; //right bound
if(lbound[i]->variant() != INT_VAL)
Error("Wrong dependence length of distributed array '%s'",ar->identifier(),179,st);
else if(lbound[i]->valueInteger() != 0)
nnl++;
}
}
nw = i;
TestShadowWidths(ar, lbound, ubound, nw, st);
if (rank && (nw != rank)) {// wrong shadow width list length
Error("Length of shadow-edge-list is not equal to the rank of array '%s'",ar->identifier(),88,st);
return(0);
}
if(dep == ANTIDEP)
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(lbound[i]);
iright = 0;
if(nnl)
iright = ndvm;
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(ubound[i]);
return(iright);
}
*/
int doDepLengthArrays(SgExpression *shl, SgSymbol *ar, SgStatement *st, int dep)
{SgValueExp c0(0),c1(1),cM1(-1),c3(3);
int rank,nw,nnl;
int i=0;
nnl = 0;
SgExpression *wl,*ew, *bound[MAX_DIMS],*null[MAX_DIMS],*shsign[MAX_DIMS];
rank = Rank(ar);
if(!shl) //without dependence-list ,
// by default dependence length is equal to the maximal size of shadow edge
for(i=rank-1,nnl=1; i>=0; i--){
bound[i] = &cM1;
null[i] = &c0;
shsign[i] = &c3;
}
if(!TestMaxDims(shl,ar,st))
return(0);
for(wl = shl; wl; wl = wl->rhs(),i++) {
ew = wl->lhs();
if(dep == ANTIDEP)
bound[i] = &(ew->rhs())->copy();//right bound
else
bound[i] = &(ew->lhs())->copy();//left bound
null[i] = &c0;
if(bound[i]->variant() != INT_VAL) {
Error("Wrong dependence length of distributed array '%s'",ar->identifier(),179,st);
shsign[i] = &c1;
}
else if(bound[i]->valueInteger() != 0) {
nnl++;
shsign[i] = &c3;
} else
shsign[i] = &c1;
}
nw = i;
if (rank && (nw != rank)) {// wrong dependence length list length
if(dep == ANTIDEP)
Error("Wrong dependence length list of distributed array '%s'", ar->identifier(),180,st);
return(0);
}
if(!nnl) return(0);
if(dep == ANTIDEP){
TestShadowWidths(ar, null, bound, nw, st);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(null[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(bound[i]);
}
else {
TestShadowWidths(ar, bound, null, nw, st);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(bound[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(null[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(shsign[i]);
}
return(nnl);
}
/*
int doDepLengthArrays(SgExpression *shl, SgSymbol *ar, SgStatement *st, int dep, int *maxn)
{SgValueExp c0(0),c1(1),cM1(-1);
int rank,nw,nnl,nsh;
int i=0;
nnl = 0;
nsh = 0;
SgExpression *wl,*ew, *bound[7],*null[7],*shsign[7];
rank = Rank(ar);
if(!shl) //without dependence-list ,
// by default dependence length is equal to the maximal size of shadow edge
for(i=rank-1,nnl=1; i>=0; i--){
bound[i] = &cM1;
null[i] = &c0;
shsign[i] = new SgValueExp(7);
}
for(wl = shl; wl; wl = wl->rhs(),i++) {
ew = wl->lhs();
if(dep == ANTIDEP){
bound[i] = &(ew->rhs())->copy();//right bound
null[i] = &c0;
}
else {
bound[i] = &(ew->lhs())->copy();//left bound
null[i] = &(ew->rhs())->copy();//right bound
}
if(bound[i]->variant() != INT_VAL)
Error("Wrong dependence length of distributed array '%s'",ar->identifier(),179,st);
else if(bound[i]->valueInteger() != 0) {
nnl++; nsh++;
shsign[i] = new SgValueExp(7);
} else if(null[i]->valueInteger() != 0){
shsign[i] = new SgValueExp(5);
nsh++;
} else
shsign[i] = &c1;
null[i] = &c0;
}
nw = i;
*maxn = nsh;
if (rank && (nw != rank) && (dep == ANTIDEP)) {// wrong dependence length list length
Error("Wrong dependence length list of distributed array '%s'", ar->identifier(),180,st);
return(0);
}
if(!nnl) return(0);
if(dep == ANTIDEP){
TestShadowWidths(ar, null, bound, nw, st);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(null[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(bound[i]);
}
else {
TestShadowWidths(ar, bound, null, nw, st);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(bound[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(null[i]);
for(i=rank-1;i>=0; i--)
doAssignStmtAfter(shsign[i]);
}
return(nnl);
}
*/
SgExpression *doLowHighList(SgExpression *shl, SgSymbol *ar, SgStatement *st)
{
SgValueExp c1(1);
int nw, i;
SgExpression *wl, *ew, *lbound[MAX_DIMS], *hbound[MAX_DIMS];
int rank = Rank(ar);
if(!TestMaxDims(shl,ar,st))
return(NULL);
for(wl = shl,i=0; wl; wl = wl->rhs(),i++) {
ew = wl->lhs();
lbound[i] = &(ew->lhs())->copy();
hbound[i] = &(ew->rhs())->copy();
if(lbound[i]->variant() != INT_VAL || hbound[i]->variant() != INT_VAL) {
Error("Wrong dependence length of distributed array '%s'",ar->identifier(), 179, st);
lbound[i] = hbound[i] = &c1;
}
}
nw = i;
if (rank && (nw != rank) )
Error("Wrong dependence length list of distributed array '%s'", ar->identifier(), 180, st);
TestShadowWidths(ar, lbound, hbound, nw, st);
SgExpression *shlist = NULL;
for(i=0; i<nw; i++)
{
shlist = AddElementToList(shlist, DvmType_Ref(hbound[i]));
shlist = AddElementToList(shlist, DvmType_Ref(lbound[i]));
}
return( shlist );
}
SgExpression *isInTieList(SgSymbol *ar, SgExpression *tie_list)
{
SgExpression *el;
for(el=tie_list; el; el=el->rhs())
{
if(el->lhs()->symbol() && el->lhs()->symbol() == ar)
return (el->lhs());
else
continue;
}
return NULL;
}
void AcrossList(int ilh, int isOut, SgExpression *el, SgStatement *st, SgExpression *tie_clause)
{
SgExpression *es, *ear, *head=NULL;
// looking through the dependent_array_list
for(es = el; es; es = es->rhs()) {
if( es->lhs()->variant() == ARRAY_OP){
ear = es->lhs()->lhs();
err("SECTION specification is not permitted", 643, st);
} else {
ear = es->lhs();
if(!ear->lhs()) { //whole array
Error("Dependence list is not specified for %s", ear->symbol()->identifier(), 644, st);
continue;
}
}
SgSymbol *ar = ear->symbol();
if(!st->expr(0) && (!tie_clause || !isInTieList(ar,tie_clause->lhs())))
Error("Array from ACROSS clause should be specified in TIE clause: %s", ar->identifier(), 648, st);
SgExpression *head = HeaderForArrayInParallelDir(ar, st, 1);
doCallAfter(LoopAcross_H2(ilh, isOut, head, Rank(ar), doLowHighList(ear->lhs(), ar, st)));
}
}
void StoreLoopPar(SgExpression *par[], int n, int ind, SgStatement*stl)
{ SgStatement *stat = NULL;
SgSymbol*s;
int i;
if(!newvar_list) return;
if(stl) {
stat=cur_st;
cur_st=stl;
}
for(i=0; i<n; i++)
if(isSgVarRefExp(par[i])) {
s = par[i]->symbol();
if(s && isInSymbList(newvar_list,s))
doAssignTo_After(&(par[i]->copy()),DVM000(ind+i));
}
if(stl)
cur_st=stat;
}
void TestReductionList (SgExpression *el, SgStatement *st)
{
SgExpression *er, *ev, *ered, *loc_var;
symb_list *rv_list=NULL;
for(er = el; er; er=er->rhs()) {
ered = er->lhs(); // reduction
ev = ered->rhs(); // reduction variable reference
loc_var=NULL;
if(isSgExprListExp(ev)) { // MAXLOC,MINLOC
ev = ev->lhs();
loc_var = ered->rhs()->rhs()->lhs();
}
if(!ev->symbol()) continue;
if(isInSymbList(rv_list,ev->symbol()) )
Error("Reuse of '%s' in REDUCTION clause", ev->symbol()->identifier(), 663, st );
else
rv_list = AddToSymbList(rv_list,ev->symbol());
if(!loc_var || !loc_var->symbol()) continue;
if(isInSymbList(rv_list,loc_var->symbol()) )
Error("Reuse of '%s' in REDUCTION clause", loc_var->symbol()->identifier(), 663, st );
else
rv_list = AddToSymbList(rv_list,loc_var->symbol());
}
}
void ReductionList (SgExpression *el,SgExpression *gref, SgStatement *st, SgStatement *stmt1, SgStatement *stmt2, int ilh2)
{ SgStatement *last,*last1;
SgExpression *er, *ev, *ered, *loc_var,*len, *loclen, *debgref;
int irv, irf, num_red, ia, ntype,sign, num, locindtype;
int itsk = 0, ilen = 0;
SgSymbol *var;
SgValueExp c0(0),c1(1);
TestReductionList (el, st); // double use check
last = stmt2; last1 = stmt1;
//looking through the reduction list
for(er = el; er; er=er->rhs()) {
ered = er->lhs(); // reduction
ev = ered->rhs(); // reduction variable reference
if(!isSgVarRefExp(ev) && !isSgArrayRefExp(ev) && !isSgExprListExp(ev))
{ err("Wrong reduction variable",151,st);
continue;
}
loc_var = ConstRef(0);
loclen = &c0;
locindtype = 0;
len =&c1;
num=num_red=RedFuncNumber(ered->lhs());
if( !num_red)
err("Wrong reduction operation name", 70,st);
/*
if(num_red == 8) //EQV
err("Reduction function EQV is not supported now",st);
*/
if(num_red > 8) { // MAXLOC => 9,MINLOC =>10
num_red -= 6; // MAX => 3,MIN =>4
// change loc_array
ev = ered->rhs()->lhs(); // reduction variable reference
if( !ered->rhs()->rhs() || !ered->rhs()->rhs()->rhs() || ered->rhs()->rhs()->rhs()->rhs()){
//the number of operands is not equal to 3
err("Illegal operand list of MAXLOC/MINLOC",147,st);
continue;
}
loc_var = ered->rhs()->rhs()->lhs(); //location variable reference
loclen = ered->rhs()->rhs()->rhs()->lhs(); //the number of coordinates
if(isSgVarRefExp(loc_var))
loclen = TypeLengthExpr(loc_var->type()); //14.03.03 new SgValueExp(TypeSize(loc_var->type()));
else if( isSgArrayRefExp(loc_var)) {
ia = loc_var->symbol()->attributes();
if((ia & DISTRIBUTE_BIT) ||(ia & ALIGN_BIT) || (ia & INHERIT_BIT))
Error("'%s' is distributed array", loc_var->symbol()->identifier(), 148,st);
/*
if(!loc_var->lhs()){ //whole array
if(Rank(loc_var->symbol())>1)
Error("Wrong operand of MAXLOC/MINLOC: %s",loc_var->symbol()->identifier(), 149,st);
loclen = ArrayDimSize(loc_var->symbol(),1); // size of vector in elements
if(!loclen || loclen->variant()==STAR_RANGE){
Error("Wrong operand of MAXLOC/MINLOC: %s",loc_var->symbol()->identifier(), st);
loclen = &c0;
}
else
loclen = &((*ArrayDimSize(loc_var->symbol(),1)) * (*new SgValueExp(TypeSize(loc_var->symbol()->type()->baseType())))) ; // size of vector in bytes
}
*/
loclen = &(*loclen * (*TypeLengthExpr(loc_var->symbol()->type()->baseType()))) ; // size of vector in bytes
//loclen = &(*loclen * (*new SgValueExp(TypeSize(loc_var->symbol()->type()->baseType())))) ; 14.03.03
}
else
err("Wrong operand of MAXLOC/MINLOC",149,st);
}
var = ev->symbol();
ia = var->attributes();
if(isSgVarRefExp(ev))
redvar_list= AddNewToSymbList(redvar_list,var);
else if( isSgArrayRefExp(ev)) {
//if((ia & DISTRIBUTE_BIT) ||(ia & ALIGN_BIT)|| (ia & INHERIT_BIT))
// Error("'%s' is distributed array", var->identifier(), 148,st);
if(!ev->lhs()){ //whole array
len = ArrayLengthInElems(var,st,1); //size of array
ev = FirstArrayElement(var);
if((ia & DISTRIBUTE_BIT) ||(ia & ALIGN_BIT)|| (ia & INHERIT_BIT))
{ if(!only_debug)
ev = HeaderRefInd(var,1);
}
}
}
else
err("Wrong reduction variable",151,st);
ntype = VarType_RTS(var); //RedVarType
if(!ntype)
Error("Wrong type of reduction variable '%s'", var->identifier(), 152,st);
sign = 1;
if(stmt1 != stmt2)
cur_st = last1;
if(gref) // interface of RTS1
{ ilen = ndvm; // index for RedArrayLength
doAssignStmtAfter(len);
doAssignStmtAfter(loclen);
}
if(num > 8 && loc_var->symbol()) //MAXLOC,MINLOC
locindtype = LocVarType(loc_var->symbol(),st);
irv = ndvm; // index for RedVarRef
if(!only_debug) {
if(IN_COMPUTE_REGION || inparloop && parloop_by_handler) /*ACC*/
{
if(ilh2) // interface of RTS2
{
doCallAfter(LoopReduction(ilh2,RedFuncNumber_2(num),ev,ntype,len,loc_var,loclen));
continue;
}
int *index = new int;
*index = irv;
// adding the attribute (REDVAR_INDEX) to expression for reduction operation
ered->addAttribute(REDVAR_INDEX, (void *) index, sizeof(int));
doCallAfter (GetActualScalar(var));
if(num > 8 && loc_var->symbol())
doCallAfter (GetActualScalar(loc_var->symbol()));
}
doAssignStmtAfter(ReductionVar(num_red,ev,ntype,ilen, loc_var, ilen+1,sign));
if(num > 8 && loc_var->symbol()) {//MAXLOC,MINLOC
doAssignStmtAfter(LocIndType(irv, locindtype)); //LocVarType(loc_var->symbol(),st)));
}
}
if(debug_regim && st->variant()!=DVM_TASK_REGION_DIR) {
debgref = idebrg ? DVM000(idebrg) : DebReductionGroup(gref->symbol());
doCallAfter(D_InsRedVar(debgref,num_red,ev,ntype,ilen, loc_var, ilen+1,locindtype));
}
last1 = cur_st;
if(stmt1 != stmt2)
cur_st = last;
if(!only_debug){
if(!itsk && st->variant()==DVM_TASK_REGION_DIR){
itsk = ndvm;
doAssignStmtAfter(new SgVarRefExp(TASK_SYMBOL(st->symbol())));
}
irf = (st->variant()==DVM_TASK_REGION_DIR) ? itsk : iplp;
doCallAfter(InsertRedVar(gref,irv,irf));
}
last = cur_st;
}
/* if(! only_debug)
* doAssignStmtAfter(SaveRedVars(gref));
*/
return;
}
void ReductionVarsStart (SgExpression *el)
{
SgExpression *er, *ev, *ered;
int num_red;
//looking through the reduction list
for(er = el; er; er=er->rhs()) {
ered = er->lhs(); // reduction
num_red=RedFuncNumber(ered->lhs());
if(num_red <= 8) {
ev = ered->rhs(); // reduction variable reference
if(isSgVarRefExp(ev)){
doAssignStmtAfter(GetAddresMem(ev)) ;
FREE_DVM(1);
}
if(isSgArrayRefExp(ev) && !IS_DVM_ARRAY(ev->symbol())) {
if(!ev->lhs()) {//whole array
doAssignStmtAfter(GetAddresMem(FirstArrayElement(ev->symbol()))) ;
FREE_DVM(1);
}
else {
doAssignStmtAfter(GetAddresMem(ev)) ;
FREE_DVM(1);
}
}
} else { // MAXLOC => 9,MINLOC =>10
ev = ered->rhs()->lhs(); // reduction variable reference
if(isSgVarRefExp(ev)){
doAssignStmtAfter(GetAddresMem(ev)) ;
FREE_DVM(1);
}
if(isSgArrayRefExp(ev) && !IS_DVM_ARRAY(ev->symbol())) {
if(!ev->lhs()) {//whole array
doAssignStmtAfter(GetAddresMem(FirstArrayElement(ev->symbol()))) ;
FREE_DVM(1);
}
else {
doAssignStmtAfter(GetAddresMem(ev)) ;
FREE_DVM(1);
}
}
/*
if( ered->rhs()->rhs()->rhs()){ //there are >1 location variables
ind = *((int*)(ered)->attributeValue(0,LOC_ARR));
for ( ind_var_list = ered->rhs()->rhs(),ind_num=0; ind_var_list; ind_var_list=ind_var_list->rhs(), ind_num++)
doAssignTo_After(DVM000(ind+ind_num),ind_var_list->lhs()) ;
} else
*/
if(ered->rhs()->rhs() && isSgVarRefExp( ered->rhs()->rhs()->lhs())){
//location variable
doAssignStmtAfter(GetAddresMem( ered->rhs()->rhs()->lhs())) ;
FREE_DVM(1);
}
if(ered->rhs()->rhs() && isSgArrayRefExp( ered->rhs()->rhs()->lhs()) && !IS_DVM_ARRAY(ered->rhs()->rhs()->lhs()->symbol())){ //location array
if(!( ered->rhs()->rhs()->lhs())->lhs()) {//whole array
doAssignStmtAfter(GetAddresMem(FirstArrayElement((ered->rhs()->rhs()->lhs())->symbol()))) ;
FREE_DVM(1);
} else {
doAssignStmtAfter(GetAddresMem( ered->rhs()->rhs()->lhs())) ;
FREE_DVM(1);
}
}
}
}
if(redl) {// for HPF_program
reduction_list *erl;
for(erl = redl; erl; erl=erl->next) {
num_red=erl->red_op;
ev = erl->red_var; // reduction variable reference
if(isSgVarRefExp(ev)){
doAssignStmtAfter(GetAddresMem(ev)) ;
FREE_DVM(1);
}
}
}
}
/*
void ReductionVarsWait (SgExpression *el)
{ int ind;
SgExpression *er, *ered, *ind_var_list;
int num_red, ind_num;
//looking through the reduction list
for(er = el; er; er=er->rhs()) {
ered = er->lhs(); // reduction
num_red=RedFuncNumber(ered->lhs());
if((num_red > 8) && ( ered->rhs()->rhs()->rhs())){ // MAXLOC => 9,MINLOC =>10 and
//there are >1 location variables
ind = *((int*)(ered)->attributeValue(0,LOC_ARR));
for ( ind_var_list = ered->rhs()->rhs(),ind_num=0; ind_var_list; ind_var_list=ind_var_list->rhs(), ind_num++)
doAssignTo_After(ind_var_list->lhs(),DVM000(ind+ind_num)) ;
}
}
}
*/
int LocElemNumber(SgExpression *en)
{
SgExpression *ec;
int n;
n = 0;
ec = Calculate(en);
if (ec->isInteger())
n = ec->valueInteger();
else
err("Can not calculate number of elements in location array", 595, parallel_dir);
return(n);
}
void InsertReductions_H(SgExpression *red_op_list, int ilh)
{
SgStatement *last;
SgExpression *er, *ev, *ered, *loc_var, *en;
int irv, num_red, num;
SgType *type, *loc_type;
last = NULL;
if (!irg && IN_COMPUTE_REGION)
err("Asynchronous reduction is not implemented yet for GPU", 596, parallel_dir);
//looking through the reduction_op_list
for (er = red_op_list; er; er = er->rhs())
{
ered = er->lhs(); // reduction (variant==ARRAY_OP)
irv = IND_REDVAR(ered);
ev = ered->rhs(); // reduction variable reference for reduction operations except MINLOC,MAXLOC
num = num_red = RedFuncNumber(ered->lhs());
if (num > 8) // MAXLOC => 9,MINLOC =>10
{
num_red -= 6; // MAX => 3,MIN =>4
ev = ered->rhs()->lhs(); // reduction variable reference
loc_var = ered->rhs()->rhs()->lhs(); //location array reference
if (loc_var->lhs()) // array element reference, it must be array name
Error("Wrong operand of MAXLOC/MINLOC: %s", loc_var->symbol()->identifier(), 149, parallel_dir);
en = ered->rhs()->rhs()->rhs()->lhs(); // number of elements in location array
loc_el_num = LocElemNumber(en);
loc_type = loc_var->symbol()->type();
}
type = ev->symbol()->type();
if (isSgArrayType(type))
{
if (isSgArrayRefExp(ev) && !ev->lhs() && !HEADER(ev->symbol())) // whole one-dimensional array
;
else
Error("Reduction variable %s is array (array element), not implemented yet", ev->symbol()->identifier(), 597, parallel_dir);
type = type->baseType();
}
//if((nr =TestType(type)) == 5 || nr == 6) // COMPLEX or DCOMPLEX
// Error("Illegal type of reduction variable %s, not implemented yet for GPU",ev->symbol()->identifier(),592,parallel_dir);
InsertNewStatementAfter(LoopInsertReduction_H(ilh, irv), cur_st, cur_st->controlParent());
}
}
void NewVarList(SgExpression *nl,SgStatement *stmt)
{SgExpression *el,*e;
for(el=nl; el;el=el->rhs()){
e=el->lhs();
if(e->symbol()){
newvar_list=AddToSymbList(newvar_list,e->symbol());
//testing
if(IS_DUMMY(e->symbol()) || IS_SAVE(e->symbol()) || IN_COMMON(e->symbol()))
Error("Illegal variable in new-clause: %s",e->symbol()->identifier(),168,stmt); // variable in NEW clause may not be dummy argument, have the SAVE attribute,occur in a COMMON block
}
}
}
void ReceiveArray(SgExpression *spec_accr,SgStatement *parst)
{SgExpression *es,*el;
SgSymbol *ar;
int is,tp;
// looking through the array_list
for(es = spec_accr; es; es = es->rhs()) {
ar = es->lhs()->symbol();
switch(ar->type()->baseType()->variant()) {
case T_INT: tp = 1; break;
case T_FLOAT: tp = 3; break;
case T_DOUBLE: tp = 4; break;
case T_BOOL: tp = 1; break;
case T_COMPLEX: tp = 6; break;
case T_DCOMPLEX: tp = 8; break;
default: tp = 0; break;
}
is = ndvm;
if(tp == 6 || tp == 8){
doAssignStmtAfter(&(*ArrayLengthInElems(ar,parst,1)*(*new SgValueExp(2))));
tp = tp/2;
} else
doAssignStmtAfter(ArrayLengthInElems(ar,parst,1));
el = FirstArrayElement(ar);
if(HEADER(ar))
DistArrayRef(el,0,parst);
doAssignStmtAfter(DVM_Receive(iplp,GetAddresMem(el),tp,is));
}
}
void SendArray(SgExpression *spec_accr)
{SgExpression *es,*el;
SgSymbol *ar;
int is,tp;
// looking through the array_list
for(es = spec_accr; es; es = es->rhs()) {
ar = es->lhs()->symbol();
switch(ar->type()->baseType()->variant()) {
case T_INT: tp = 1; break;
case T_FLOAT: tp = 3; break;
case T_DOUBLE: tp = 4; break;
case T_BOOL: tp = 1; break;
case T_COMPLEX: tp = 6; break;
case T_DCOMPLEX: tp = 8; break;
default: tp = 0; break;
}
is = ndvm;
if(tp == 6 || tp == 8){
doAssignStmtAfter(&(*ArrayLengthInElems(ar,cur_st,0)*(*new SgValueExp(2))));
tp = tp/2;
} else
doAssignStmtAfter(ArrayLengthInElems(ar,cur_st,0));
el = FirstArrayElement(ar);
if(HEADER(ar))
DistArrayRef(el,0,cur_st);
doAssignStmtAfter(DVM_Send(iplp,GetAddresMem(el),tp,is));
}
}
void CudaBlockSize(SgExpression *cuda_block_list)
{
SgExpression *el;
el = cuda_block_list;
if (!el) return;
doAssignStmtAfter(el->lhs());
el = el->rhs();
if (el)
doAssignStmtAfter(el->lhs());
else
{
doAssignStmtAfter(new SgValueExp(1)); //by default sizeY = 1
doAssignStmtAfter(new SgValueExp(1)); //by default sizeZ = 1
return;
}
el = el->rhs();
if (el)
doAssignStmtAfter(el->lhs());
else
doAssignStmtAfter(new SgValueExp(1)); //by default sizeZ = 1
}
void CudaBlockSize(SgExpression *cuda_block_list,SgExpression *esize[])
{
SgExpression *el;
el = cuda_block_list;
esize[0] = el->lhs();
el = el->rhs();
if (el)
esize[1] = el->lhs();
else
{
esize[1] = new SgValueExp(1); //by default sizeY = 1
esize[2] = new SgValueExp(1); //by default sizeZ = 1
return;
}
el = el->rhs();
if (el)
esize[2] = el->lhs();
else
esize[2] = new SgValueExp(1); //by default sizeZ = 1
}
//***********************************************************************************************
// Interface of RTS2
//***********************************************************************************************
int TestReductionClause(SgExpression *e)
{
if( e->symbol()) // asynchronous reduction
return 0;
SgExpression *er, *ev;
for(er = e->lhs(); er; er=er->rhs())
{
ev = er->lhs()->rhs(); // reduction variable reference
if(isSgArrayRefExp(ev) && HEADER(ev->symbol()) )
return 0;
if(isSgExprListExp(ev) && HEADER(ev->lhs()->symbol()) ) //MAXLOC,MINLOC
return 0;
}
return 1;
}
int CreateParallelLoopByHandler_H2(SgExpression *init[], SgExpression *last[], SgExpression *step[], int nloop)
{ SgExpression *e=NULL,*el,*arglist=NULL;
// generate call dvmh_loop_create(const DvmType *pCurRegion, const DvmType *pRank, /* const DvmType *pStart, const DvmType *pEnd, const DvmType *pStep */...)
for(int i=nloop-1; i>=0; i--)
{
e = len_DvmType ? TypeFunction(SgTypeInt(),step[i],new SgValueExp(len_DvmType) ) : step[i];
(el = new SgExprListExp(*e))->setRhs(arglist);
arglist = el;
e = len_DvmType ? TypeFunction(SgTypeInt(),last[i],new SgValueExp(len_DvmType) ) : last[i];
(el = new SgExprListExp(*e))->setRhs(arglist);
arglist = el;
e = len_DvmType ? TypeFunction(SgTypeInt(),init[i],new SgValueExp(len_DvmType) ) : init[i];
(el = new SgExprListExp(*e))->setRhs(arglist);
arglist = el;
}
int ilh = ndvm;
doAssignStmtAfter(LoopCreate_H2(nloop,arglist));
return(ilh);
}
SgExpression *AxisList(SgStatement *stmt, SgExpression *tied_array_ref)
{
SgExpression *axis[MAX_LOOP_LEVEL],
*coef[MAX_LOOP_LEVEL],
*cons[MAX_LOOP_LEVEL];
SgExpression *arglist=NULL, *el, *e, *c;
int nt = Alignment(stmt,tied_array_ref,axis,coef,cons,2); // 2 - interface of RTS2
for(int i=0; i<nt; i++)
{
c = Calculate(coef[i]);
if(c && c->isInteger() && (c->valueInteger() < 0))
e = & SgUMinusOp(*DvmType_Ref(axis[i]));
else
e = DvmType_Ref(axis[i]);
(el = new SgExprListExp(*e))->setRhs(arglist);
arglist = el;
}
(el = new SgExprListExp(*ConstRef(nt)))->setRhs(arglist); // add rank to axis list
arglist = el;
return arglist;
}
SgExpression *ArrayRefAddition(SgExpression *aref)
{
if(!aref->lhs()) // without subscript list
{
// A => A(:,:,...,:)
SgExpression *arlist = NULL;
int n = Rank(aref->symbol());
while(n--)
arlist = AddListToList(arlist, new SgExprListExp(*new SgExpression(DDOT)));
aref->setLhs(arlist);
}
return aref;
}
SgExpression *MappingList(SgStatement *stmt, SgExpression *aref)
{
SgExpression *axis[MAX_LOOP_LEVEL],
*coef[MAX_LOOP_LEVEL],
*cons[MAX_LOOP_LEVEL];
SgExpression *arglist=NULL, *el, *e;
int nt = Alignment(stmt,aref,axis,coef,cons,2); // 2 - interface of RTS2
for(int i=0; i<nt; i++)
{
e = AlignmentLinear(axis[i],ReplaceFuncCall(coef[i]),cons[i]); //Calculate(cons[i])
(el = new SgExprListExp(*e))->setRhs(arglist);
arglist = el;
}
(el = new SgExprListExp(*ConstRef(nt)))->setRhs(arglist); // add rank to axis list
arglist = el;
return arglist;
}
void MappingParallelLoop(SgStatement *stmt, int ilh )
{
SgExpression *axis[MAX_LOOP_LEVEL],
*coef[MAX_LOOP_LEVEL],
*cons[MAX_LOOP_LEVEL];
SgExpression *arglist=NULL, *el, *e;
if(!stmt->expr(0)) // undistributed parallel loop
return;
int nt = Alignment(stmt,NULL,axis,coef,cons,2); // 2 - interface of RTS2
for(int i=0; i<nt; i++)
{
e = AlignmentLinear(axis[i],ReplaceFuncCall(coef[i]),cons[i]); //Calculate(cons[i])
(el = new SgExprListExp(*e))->setRhs(arglist);
arglist = el;
}
SgExpression *desc = HeaderRef(stmt->expr(0)->symbol()); //Register_Array_H2(HeaderRef(stmt->expr(0)->symbol())); //!!! temporary
doCallAfter(LoopMap(ilh,desc,nt,arglist));
}
void Interface_2(SgStatement *stmt,SgExpression *clause[],SgExpression *init[],SgExpression *last[],SgExpression *step[],int nloop,int ndo,SgStatement *first_do) //int iout,SgStatement *stl,SgSymbol *newj,int ub))
{
if (clause[SHADOW_RENEW_]) //there is SHADOW_RENEW clause
ShadowList(clause[SHADOW_RENEW_]->lhs(), stmt, NULL);
// create loop
int ilh = CreateParallelLoopByHandler_H2(init, last, step, nloop);
MappingParallelLoop(stmt, ilh);
//---------------------------------------------------------------------------
// processing specifications/clauses
//
if (clause[CUDA_BLOCK_]) //there is CUDA_BLOCK clause
{
SgExpression *eSize[3];
CudaBlockSize(clause[CUDA_BLOCK_]->lhs(), eSize);
doCallAfter(SetCudaBlock_H2(ilh, eSize[0], eSize[1], eSize[2]));
}
if (clause[TIE_]) //there is TIE clause
for (SgExpression *el=clause[TIE_]->lhs(); el; el=el->rhs()) //list of tied arrays
{
SgExpression *head = HeaderForArrayInParallelDir(el->lhs()->symbol(), stmt, 1);
doCallAfter(Correspondence_H(ilh, head, AxisList(stmt, el->lhs())));
}
if (clause[CONSISTENT_]) //there is CONSISTENT clause
for (SgExpression *el = clause[CONSISTENT_]->lhs(); el; el=el->rhs())
{
SgExpression *head = HeaderForArrayInParallelDir(el->lhs()->symbol(), stmt, 0);
InsertNewStatementAfter(Consistent_H(ilh, head, MappingList(stmt, el->lhs())), cur_st, cur_st->controlParent());
}
if (clause[REMOTE_ACCESS_]) //there is REMOTE_ACCESS clause
{ int nbuf=1;
//adding new element to remote_access directive/clause list
AddRemoteAccess(clause[REMOTE_ACCESS_]->lhs(),NULL);
RemoteVariableList(clause[REMOTE_ACCESS_]->symbol(), clause[REMOTE_ACCESS_]->lhs(), stmt);
for (SgExpression *el=clause[REMOTE_ACCESS_]->lhs(); el; el=el->rhs(),nbuf++)
{
SgExpression *head = HeaderForArrayInParallelDir(el->lhs()->symbol(), stmt, 0);
InsertNewStatementAfter(LoopRemoteAccess_H(ilh, head, el->lhs()->symbol(), MappingList(stmt, ArrayRefAddition(el->lhs()))), cur_st, cur_st->controlParent());
}
}
if (clause[SHADOW_COMPUTE_]) //there is SHADOW_COMPUTE clause
{
if ( (clause[SHADOW_COMPUTE_]->lhs()))
ShadowComp(clause[SHADOW_COMPUTE_]->lhs(),stmt,ilh);
else
doCallAfter(ShadowCompute(ilh,HeaderRef(stmt->expr(0)->symbol()),0,NULL));
//doCallAfter(ShadowCompute(ilh,Register_Array_H2(HeaderRef(stmt->expr(0)->symbol())),0,NULL));
}
if (clause[REDUCTION_]) //there is REDUCTION clause
{
red_list = clause[REDUCTION_]->lhs();
ReductionList(red_list,NULL,stmt,cur_st,cur_st,ilh);
}
if (clause[ACROSS_]) //there is ACROSS clause
{
SgExpression *e_spec[2];
InOutAcross(clause[ACROSS_],e_spec,stmt);
if (e_spec[IN_])
AcrossList(ilh,IN_, e_spec[IN_], stmt, clause[TIE_]);
if (e_spec[OUT_])
AcrossList(ilh,OUT_,e_spec[OUT_],stmt, clause[TIE_]);
}
if (clause[STAGE_] && !(clause[STAGE_]->lhs()->variant()==MINUS_OP && INTEGER_VALUE(clause[STAGE_]->lhs()->lhs(),1))) //there is STAGE clause and is not STAGE(-1)
doCallAfter(SetStage(ilh, clause[STAGE_]->lhs()));
//---------------------------------------------------------------------------
LINE_NUMBER_AFTER(first_do,cur_st);
cur_st->addComment(ParallelLoopComment(first_do->lineNumber()));
ACC_CreateParallelLoop(ilh,first_do,nloop,stmt,clause,2); //oldGroup,newGroup,oldGroup2,newGroup2
}
//************************************************************************************************
int ParallelLoop_Debug(SgStatement *stmt)
{
SgStatement *st,*stl = NULL,*stg, *st3;
SgStatement *first_do, *stdeb = NULL;
SgValueExp c0(0);
int i,nloop,ndo, iinp,iout,ind, mred;
SgForStmt *stdo;
SgValueExp c1(1);
SgExpression *step[MAX_LOOP_LEVEL],
*init[MAX_LOOP_LEVEL],
*last[MAX_LOOP_LEVEL],
*vpart[MAX_LOOP_LEVEL];
SgSymbol *do_var[MAX_LOOP_LEVEL];
SgExpression *vl, *dovar, *e, *el;
if (!OMP_program) {/*OMP*/
first_do = stmt -> lexNext();// first DO statement of the loop nest
} else {
first_do = GetLexNextIgnoreOMP(stmt);// first DO statement of the loop nest /*OMP*/
}
newvar_list = NULL;
redgref = NULL; red_list = NULL; irg = 0; idebrg = 0; mred =0;
LINE_NUMBER_AFTER(stmt,stmt);
TransferLabelFromTo(first_do, stmt->lexNext());
//generating call to 'bploop' function of performance analizer (begin of parallel interval)
if(perf_analysis && perf_analysis != 2)
InsertNewStatementAfter(St_Bploop(OpenInterval(stmt)), cur_st, stmt->controlParent()); //inserting after function call 'lnumb'
iplp = 0;
ndo = i = nloop = 0;
// looking through the do_variables list
vl = stmt->expr(2); // do_variables list
for(dovar=vl; dovar; dovar=dovar->rhs())
nloop++;
// looking through the specification list
for(el=stmt->expr(1); el; el=el->rhs()) {
e = el->lhs(); // specification
switch (e->variant()) {
case REDUCTION_OP:
if(mred !=0) break;
mred = 1;
red_list = e->lhs();
if( e->symbol()){
redgref = new SgVarRefExp(e->symbol());
doIfForReduction(redgref,1);
nloopred++;
stg = doIfForCreateReduction( e->symbol(),nloopred,1);
//cur_st->setControlParent(stmt->controlParent()); //to insert correctly next statements
st3 = cur_st;
cur_st = stg;
//looking through the reduction list
ReductionList(red_list,redgref, stmt, cur_st, cur_st, 0);
cur_st = st3;
InsertNewStatementAfter( new SgAssignStmt(*DVM000(ndvm),*new SgValueExp(0)),cur_st,cur_st->controlParent());
} else {
irg = ndvm;
redgref = DVM000(irg);
doAssignStmtAfter(CreateReductionGroup());
idebrg = ndvm;
doAssignStmtAfter( D_CreateDebRedGroup());
//looking through the reduction list
ReductionList(red_list,redgref, stmt, cur_st, cur_st, 0);
}
break;
case CONSISTENT_OP:
case NEW_SPEC_OP:
case SHADOW_RENEW_OP:
case SHADOW_COMP_OP:
case SHADOW_START_OP:
case SHADOW_WAIT_OP:
case REMOTE_ACCESS_OP:
case INDIRECT_ACCESS_OP:
case STAGE_OP:
case ACROSS_OP:
break;
}
}
iout = ndvm;
//initialization vpart[]
for(i=0; i<MAX_LOOP_LEVEL; i++)
vpart[i] = NULL;
i = 0;
// looking through the loop nest
for(st=first_do; i<nloop; st=st->lexNext(),i++) {
stdo = isSgForStmt(st);
if(!stdo)
break;
stl = st;
step[i] = stdo->step();
if(!step[i])
step[i] = & c1.copy(); // by default: step = 1
init[i]=isSpecialFormExp(&stdo->start()->copy(),i,iout+i,vpart,do_var);
if(init[i])
step[i] = & c1.copy();
else
init[i] = stdo->start();
last[i] = stdo->end();
if(dbg_if_regim) {// setting new loop parameters
if(vpart[i])
stdo->setStart(*DVM000(iout+i)+ (*vpart[i]));//special form
//step is not replaced
else
stdo->setStart(*DVM000(iout+i));
stdo->setEnd(*DVM000(iout+i+nloop));
}
do_var[i] = stdo->symbol();
SetDoVar(stdo->symbol());
}
ndo = i;
// test whether the directive is correct
if( !TestParallelDirective(stmt, nloop, ndo, first_do))
return(0); // directive is ignored
if(dbg_if_regim>1) { //copy loop nest
SgStatement *last_st,*lst;
last_st= LastStatementOfDoNest(first_do);
if(last_st != (lst=first_do->lastNodeOfStmt()) || last_st->variant()==LOGIF_NODE)
{ last_st=ReplaceLabelOfDoStmt(first_do,last_st, GetLabel());
ReplaceDoNestLabel_Above(last_st,first_do,GetLabel());
}
stdeb=first_do->copyPtr();
}
for(i=0; i<nloop; i++)
doAssignStmtAfter( init[i] );
for(i=0; i<nloop; i++)
doAssignStmtAfter( last[i] );
for(i=0; i<nloop; i++)
doAssignStmtAfter( step[i] );
iplp = iout;
iinp = ndvm;
OpenParLoop_Inter(stl,iinp,iinp+nloop,do_var,nloop);
// creating LoopVarTypeArray
ndvm += nloop;
for(i=0; i<nloop; i++)
doAssignStmtAfter( new SgValueExp(LoopVarType(do_var[i],stmt)));
pardo_line = first_do->lineNumber();
DebugParLoop(cur_st,nloop,iout); //DebugParLoop(cur_st,nloop,iinp+2*nloop);
if(dbg_if_regim){ // generating Logical IF statement:
// begin_lab IF (doplmbseq(...) .EQ. 0) GO TO end_lab
// and inserting it before loop nest
int ino;
SgExpression *dopl;
SgStatement *stn, *if_stmt;
stn = cur_st;
LINE_NUMBER_AFTER(first_do,cur_st);
begin_lab = GetLabel();
stn->lexNext()-> setLabel(*begin_lab);
end_lab = GetLabel();
ino = ndvm;
doAssignStmtAfter(new SgValueExp(pardo_No));
dopl = doPLmbSEQ(ino, nloop, iout);
if_stmt = new SgLogIfStmt(SgEqOp(*dopl , c0), *new SgGotoStmt(*end_lab));
cur_st->insertStmtAfter(*if_stmt);
(if_stmt->lexNext()->lexNext()) -> extractStmt(); //extract ENDIF
// (error Sage)
if(dbg_if_regim>1) {
SgStatement *ifst;
ifst = new SgIfStmt(*DebugIfNotCondition(), *stdeb);
(if_stmt->lexNext())->insertStmtAfter(*ifst,*if_stmt->controlParent());
// generating GO TO statement: GO TO begin_lab
// and inserting it after last statement of parallel loop nest copy
(stdeb->lastNodeOfStmt())->insertStmtAfter(*new SgGotoStmt(*begin_lab),*ifst);
TranslateBlock(stdeb);
}
}
cur_st = stl->lexNext();
//cur_st = st->lexPrev(); // set cur_st on last DO satement of loop nest
return(1);
}
int Reduction_Debug(SgStatement *stmt)
{
int mred;
SgExpression *e, *el;
SgStatement *stg,*st3;
redgref = NULL; irg = 0; idebrg = 0; mred =0;
LINE_NUMBER_BEFORE(stmt,stmt);
cur_st = stmt->lexPrev();
// looking through the specification list
for(el=stmt->expr(1); el; el=el->rhs()) {
e = el->lhs(); // specification
if (e->variant() == REDUCTION_OP) {
if(mred !=0) break;
mred = 1;
red_list = e->lhs();
if( e->symbol()){
redgref = new SgVarRefExp(e->symbol());
doIfForReduction(redgref,1);
nloopred++;
stg = doIfForCreateReduction( e->symbol(),nloopred,1);
st3 = cur_st;
cur_st = stg;
//looking through the reduction list
ReductionList(red_list,redgref, stmt, cur_st, cur_st, 0);
cur_st = st3;
} else {
irg = ndvm;
redgref = DVM000(irg);
doAssignStmtAfter(CreateReductionGroup());
idebrg = ndvm;
doAssignStmtAfter( D_CreateDebRedGroup());
//looking through the reduction list
ReductionList(red_list,redgref, stmt, cur_st, cur_st, 0);
}
}
}
return(0);
}