14900 lines
524 KiB
C++
14900 lines
524 KiB
C++
|
|
/*********************************************************************/
|
|
/* Fortran DVM V.5 2011 (DVM+OpenMP+ACC) */
|
|
/*********************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#define IN_DVM_
|
|
#include "dvm.h"
|
|
#undef IN_DVM_
|
|
|
|
#include "libSageOMP.h"
|
|
|
|
|
|
const char *name_loop_var[MAX_DIMS+1] = {"idvm00","idvm01","idvm02","idvm03", "idvm04","idvm05","idvm06","idvm07","idvm08","idvm09","idvm10","idvm11","idvm12","idvm13","idvm14","idvm15"};
|
|
const char *name_bufIO[Ntp] = {"i000io","r000io", "d000io","c000io","l000io","dc00io","ch00io","i100io","i200io","i800io","l100io","l200io","l800io"};
|
|
SgSymbol *rmbuf[Ntp];
|
|
const char *name_rmbuf[Ntp] = {"i000bf","r000bf", "d000bf","c000bf","l000bf","dc00bf","ch00bf","i100bf","i200bf","i800bf","l100bf","l200bf","l800bf"};
|
|
SgSymbol *dvmcommon, *dvmcommon_ch;
|
|
SgSymbol *heapcommon;
|
|
SgSymbol *redcommon;
|
|
SgSymbol *dbgcommon;
|
|
int lineno; // number of line in file
|
|
SgStatement *first_exec; // first executable statement in procedure
|
|
int nproc,ndis,nblock,ndim, nblock_all;
|
|
SgVariableSymb *mem_symb[Ntp];
|
|
int mem_use[Ntp];
|
|
|
|
int lab; // current label
|
|
//SgExpression * size_array, *array_handle, *align_template;
|
|
//SgExpression * axis_array, *coeff_array, *const_array;
|
|
//SgExpression *rml; //remote-variable list of REMOTE_ACCESS directive
|
|
|
|
int inasynchr; //set to 1 in the range of ASYNCHRONOUS
|
|
symb_list *dsym; //distributed array symbol list
|
|
group_name_list *grname; //shadow/reduction group name list
|
|
int v_print = 0; //set to 1 by -v flag
|
|
int warn_all = 0; //set to 1 by -w flag
|
|
int own_exe;
|
|
symb_list *redvar_list;
|
|
int pointer_in_tree; //set to 1 if there is a POINTER in alignment tree
|
|
//used by GenDistArray and GenAlignArray
|
|
symb_list *proc_symb;//processor array symbol list
|
|
symb_list *task_symb;//task array symbol list
|
|
symb_list * consistent_symb;// consistent array symbol list
|
|
symb_list *async_symb;// ASYNCID symbol list
|
|
symb_list *loc_templ_symb;// local TEMPLATE symbol list
|
|
symb_list *index_symb;// INDEX_DELTA variable list (code optimization)
|
|
int in_task_region;//set to 1 in the range of TASK_REGION
|
|
int task_ind; //current task index is storing in dvm000(task_ind)
|
|
int in_task; //set to 1 in the range of ON directive
|
|
SgSymbol *task_array;// current task array symbol pointer
|
|
SgLabel *task_lab;
|
|
SgStatement *task_do;
|
|
SgStatement * task_region_st;
|
|
fragment_list *cur_fragment = NULL; //current fragment number (used in debuging directives)
|
|
SgExpression *heap_ar_decl;
|
|
int is_heap_ref;
|
|
int heap_size; //calculated size of array HEAP(volume of memory for all pointer headers)
|
|
stmt_list * pref_st; //list of PREFETCH directive in procedure
|
|
int maxbuf = 5; //maximal number of remote group buffers for given array
|
|
int gen_block, mult_block;
|
|
SgExpression *async_id;
|
|
SgExpression *struct_component;
|
|
SgSymbol *file_var_s;
|
|
int nloopred; //counter of parallel loops with reduction group
|
|
int nloopcons; //counter of parallel loops with consistent group
|
|
stmt_list *wait_list; // list of REDUCTION_WAIT directives
|
|
int task_ps = 0;
|
|
int opt_base, opt_loop_range; //set on by compiler options (code optimization options)
|
|
SgExpression *sum_dvm = NULL;
|
|
int dvm_const_ref;
|
|
int unparse_functions;
|
|
int privateall = 0;
|
|
|
|
extern SgStatement *parallel_dir;
|
|
extern int iacross;
|
|
|
|
extern "C" int out_free_form;
|
|
extern "C" int out_upper_case;
|
|
extern "C" int out_line_unlimit;
|
|
extern "C" int out_line_length;
|
|
extern "C" PTR_SYMB last_file_symbol;
|
|
|
|
Options options;
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// FOR DEBUGGING
|
|
//#include "dump_info.C"
|
|
//-----------------------------------------------------------------------
|
|
|
|
#if __SPF_BUILT_IN_FDVM
|
|
int convert_file(int argc, char* argv[], const char* proj_name)
|
|
#else
|
|
int main(int argc, char *argv[])
|
|
#endif
|
|
{
|
|
FILE *fout = NULL;
|
|
FILE *fout_cuf = NULL, *fout_C_cu = NULL, *fout_info = NULL; /*ACC*/
|
|
const char *fout_name = NULL;
|
|
char *fout_name_cuf; /*ACC*/
|
|
char *fout_name_C_cu; /*ACC*/
|
|
char *fout_name_info_C; /*ACC*/
|
|
|
|
#ifndef __SPF_BUILT_IN_FDVM
|
|
const char *proj_name = "dvm.proj";
|
|
#endif
|
|
char *source_name;
|
|
int level, hpf, openmp, isz, dvm_type_size;
|
|
int a_mode = 0;
|
|
|
|
// initialisation
|
|
initialize();
|
|
|
|
openmp = hpf = 0; dvm_type_size = 0;
|
|
|
|
argv++;
|
|
while ((argc > 1) && (*argv)[0] == '-')
|
|
{
|
|
if ((*argv)[1] == 'o' && ((*argv)[2] == '\0')) {
|
|
fout_name = argv[1];
|
|
argv++;
|
|
argc--;
|
|
}
|
|
else if ((*argv)[1] == 'a' && ((*argv)[2] == '\0')) {
|
|
proj_name = argv[1];
|
|
argv++;
|
|
argc--;
|
|
a_mode = 1;
|
|
}
|
|
else if (!strcmp(argv[0], "-dc"))
|
|
check_regim = 1;
|
|
else if (!strcmp(argv[0], "-dbif1"))
|
|
dbg_if_regim = 1;
|
|
else if (!strcmp(argv[0], "-dbif2"))
|
|
dbg_if_regim = 2;
|
|
else if (!strcmp(argv[0], "-speedL0")) /* for dedugging ACROSS-scheme */
|
|
options.setOn(SPEED_TEST_L0); /*ACC*/
|
|
else if (!strcmp(argv[0], "-speedL1")) /* for dedugging ACROSS-scheme */
|
|
options.setOn(SPEED_TEST_L1); /*ACC*/
|
|
else if (!strcmp(argv[0], "-dmpi"))
|
|
deb_mpi = 1;
|
|
else if (!strcmp(argv[0], "-dnoind"))
|
|
d_no_index = 1;
|
|
else if (!strcmp(argv[0], "-dperf")) {
|
|
debug_regim = 1;
|
|
omp_debug = DPERF;
|
|
}
|
|
else if (!strcmp(argv[0], "-dvmLoopAnalysisEC")) /*ACC*/
|
|
{
|
|
options.setOn(LOOP_ANALYSIS);
|
|
options.setOn(OPT_EXP_COMP);
|
|
}
|
|
else if (!strcmp(argv[0], "-dvmIrregAnalysis")) /*ACC*/
|
|
{
|
|
options.setOn(LOOP_ANALYSIS);
|
|
options.setOn(OPT_EXP_COMP);
|
|
options.setOn(GPU_IRR_ACC);
|
|
}
|
|
else if (!strcmp(argv[0], "-dvmLoopAnalysis")) /*ACC*/
|
|
options.setOn(LOOP_ANALYSIS);
|
|
else if (!strcmp(argv[0], "-dvmPrivateAnalysis")) /*ACC*/
|
|
options.setOn(PRIVATE_ANALYSIS);
|
|
else if ((*argv)[1] == 'd') {
|
|
switch ((*argv)[2]) {
|
|
case '0': level = 0; break;
|
|
case '1': level = 1; omp_debug = D1; /*OMP*/ break;
|
|
case '2': level = 2; omp_debug = D2; /*OMP*/ break;
|
|
case '3': level = 3; omp_debug = D3; /*OMP*/ break;
|
|
case '4': level = 4; omp_debug = D4; /*OMP*/ break;
|
|
case '5': level = 5; omp_debug = D5; /*OMP*/ break;
|
|
/* case '5': level = -1; many_files=1; break;*/
|
|
default: level = -1;
|
|
}
|
|
if (level > 0)
|
|
debug_regim = 1;
|
|
if ((*argv)[3] == '\0')
|
|
AddToFragmentList(0, 0, level, -1);
|
|
else if ((*argv)[3] == ':')
|
|
FragmentList(*argv + 4, level, -1);
|
|
}
|
|
else if ((*argv)[1] == 'e') {
|
|
switch ((*argv)[2]) {
|
|
case '0': level = 0; break;
|
|
case '1': level = 1; break;
|
|
case '2': level = 2; break;
|
|
case '3': level = 3; break;
|
|
case '4': level = 4; break;
|
|
case 'm': omp_perf = 1; break;
|
|
default: level = -1;
|
|
}
|
|
if ((*argv)[3] == '\0')
|
|
AddToFragmentList(0, 0, -1, level);
|
|
else if ((*argv)[3] == ':')
|
|
FragmentList(*argv + 4, -1, level);
|
|
}
|
|
else if (!strcmp(argv[0], "-spf"))
|
|
{
|
|
(void)fprintf(stderr, "Illegal option -spf \n");
|
|
return 1;
|
|
}
|
|
else if (!strcmp(argv[0], "-p")) {
|
|
only_debug = 0; hpf = 0;
|
|
}
|
|
else if (!strcmp(argv[0], "-s")) {
|
|
only_debug = 1; hpf = 0;
|
|
}
|
|
else if (!strcmp(argv[0], "-v"))
|
|
v_print = 1;
|
|
else if (!strcmp(argv[0], "-w"))
|
|
warn_all = 1;
|
|
else if (!strcmp(argv[0], "-bind0"))
|
|
bind_ = 0;
|
|
else if (!strcmp(argv[0], "-bind1"))
|
|
bind_ = 1;
|
|
else if (!strcmp(argv[0], "-t8"))
|
|
dvm_type_size = 8;
|
|
else if (!strcmp(argv[0], "-t4"))
|
|
dvm_type_size = 4;
|
|
else if (!strcmp(argv[0], "-r8"))
|
|
default_real_size = 8;
|
|
else if (!strcmp(argv[0], "-i8"))
|
|
default_integer_size = 8;
|
|
else if (!strcmp(argv[0], "-hpf") || !strcmp(argv[0], "-hpf1") || !strcmp(argv[0], "-hpf2"))
|
|
hpf = 1;
|
|
else if (!strcmp(argv[0], "-mp")) {
|
|
OMP_program = 1; /*OMP*/
|
|
openmp = 1;
|
|
}
|
|
//else if (!strcmp(argv[0],"-ta"))
|
|
// ACC_program = 1;
|
|
else if (!strcmp(argv[0], "-noH"))
|
|
ACC_program = 0;
|
|
else if (!strcmp(argv[0], "-noCudaType")) /*ACC*/
|
|
undefined_Tcuda = 1;
|
|
else if (!strcmp(argv[0], "-noCuda"))
|
|
options.setOn(NO_CUDA); /*ACC*/
|
|
else if (!strcmp(argv[0], "-noPureFunc"))
|
|
options.setOn(NO_PURE_FUNC); /*ACC*/
|
|
else if (!strcmp(argv[0], "-C_Cuda")) /*ACC*/
|
|
options.setOn(C_CUDA);
|
|
else if (!strcmp(argv[0], "-FTN_Cuda") || !strcmp(argv[0], "-F_Cuda")) /*ACC*/
|
|
options.setOff(C_CUDA);
|
|
else if (!strcmp(argv[0], "-no_blocks_info") || !strcmp(argv[0], "-noBI"))
|
|
options.setOn(NO_BL_INFO); /*ACC*/
|
|
else if (!strcmp(argv[0], "-cacheIdx"))
|
|
options.setOff(NO_BL_INFO); /*ACC*/
|
|
else if (!strcmp(argv[0], "-Ohost")) /*ACC*/
|
|
options.setOn(O_HOST);
|
|
else if (!strcmp(argv[0], "-noOhost")) /*ACC*/
|
|
options.setOff(O_HOST);
|
|
else if (!strcmp(argv[0], "-Opl2")) /*ACC*/
|
|
{
|
|
parloop_by_handler = 2;
|
|
options.setOn(O_HOST);
|
|
options.setOn(O_PL2);
|
|
// options.setOn(NO_CUDA);
|
|
}
|
|
else if (!strcmp(argv[0], "-Opl")) /*ACC*/
|
|
{
|
|
parloop_by_handler = 1;
|
|
options.setOn(O_PL);
|
|
}
|
|
else if (!strcmp(argv[0], "-oneThread")) /*ACC*/
|
|
options.setOn(ONE_THREAD);
|
|
else if (!strcmp(argv[0], "-noTfm")) /*ACC*/
|
|
options.setOff(AUTO_TFM);
|
|
else if (!strcmp(argv[0], "-autoTfm")) /*ACC*/
|
|
options.setOn(AUTO_TFM);
|
|
else if (!strcmp(argv[0], "-gpuO0")) /*ACC*/
|
|
options.setOn(GPU_O0);
|
|
else if (!strcmp(argv[0], "-gpuO1")) /*ACC*/
|
|
options.setOn(GPU_O1);
|
|
else if (!strcmp(argv[0], "-rtc")) /*ACC*/
|
|
options.setOn(RTC); //for NVRTC compilation and execution
|
|
else if (!strcmp(argv[0], "-ffo"))
|
|
out_free_form = 1;
|
|
else if (!strcmp(argv[0], "-upcase"))
|
|
out_upper_case = 1;
|
|
else if (!strcmp(argv[0], "-noLimitLine"))
|
|
out_line_unlimit = 1;
|
|
else if (!strcmp(argv[0], "-uniForm"))
|
|
{
|
|
out_free_form = 1;
|
|
out_line_length = 72;
|
|
}
|
|
else if (!strcmp(argv[0], "-noRemote"))
|
|
options.setOn(NO_REMOTE);
|
|
else if (!strcmp(argv[0], "-lgstd"))
|
|
{
|
|
(void)fprintf(stderr, "Illegal option -lgstd \n");
|
|
return 1;
|
|
}
|
|
else if (!strcmp(argv[0], "-byFunUnparse"))
|
|
unparse_functions = 1;
|
|
else if (!strncmp(argv[0], "-bufio", 6)) {
|
|
if ((*argv)[6] != '\0' && (isz = is_integer_value(*argv + 6)))
|
|
IOBufSize = isz;
|
|
}
|
|
else if (!strncmp(argv[0], "-bufUnparser", 12)) {
|
|
if ((*argv)[12] != '\0' && (isz = is_integer_value(*argv + 12)))
|
|
UnparserBufSize = isz * 1024 * 1024;
|
|
}
|
|
else if (!strcmp(argv[0], "-ioRTS"))
|
|
options.setOn(IO_RTS);
|
|
else if (!strcmp(argv[0], "-read_all"))
|
|
options.setOn(READ_ALL);
|
|
else if (!strcmp(argv[0], "-Obase"))
|
|
opt_base = 1;
|
|
else if (!strcmp(argv[0], "-Oloop_range"))
|
|
opt_loop_range = 1;
|
|
else if ((*argv)[1] == 'H') {
|
|
if ((*argv)[2] == 's' && (*argv)[3] == 'h' && (*argv)[4] == 'w') {
|
|
if ((*argv)[5] != '\0' && (all_sh_width = is_integer_value(*argv + 5)))
|
|
;
|
|
}
|
|
else if (!strcmp(*argv + 2, "nora"))
|
|
no_rma = 1;
|
|
else if (!strcmp(*argv + 2, "oneq"))
|
|
one_inquiry = 1;
|
|
else if (!strcmp(*argv + 2, "onlyl"))
|
|
only_local = 1;
|
|
}
|
|
else if (!strncmp(argv[0], "-collapse", 9))
|
|
if ((*argv)[9] != '\0' && (collapse_loop_count = is_integer_value(*argv + 9)));
|
|
argc--;
|
|
argv++;
|
|
}
|
|
|
|
// Check options combinations
|
|
options.checkCombinations();
|
|
|
|
if (isHPFprogram(source_name = *argv)) {
|
|
HPF_program = 1;
|
|
hpf = 0;
|
|
}
|
|
if (hpf)
|
|
return 0;
|
|
|
|
// definition of DvmType size: len_DvmType
|
|
// len_DvmType==0, if DvmType-size == default_integer_size == 4
|
|
if (bind_ == 1)
|
|
len_DvmType = 8; //sizeof(long) == 8
|
|
if (dvm_type_size)
|
|
len_DvmType = dvm_type_size;
|
|
if (len_DvmType == 0 && default_integer_size == 8)
|
|
len_DvmType = 4;
|
|
|
|
if (ACC_program && debug_regim && !only_debug)
|
|
{
|
|
(void)fprintf(stderr, "Warning: -noH option is set to debug mode\n");
|
|
ACC_program = 0;
|
|
}
|
|
if (parloop_by_handler>0 && debug_regim)
|
|
{
|
|
(void)fprintf(stderr, "Warning: -Opl/Opl2 option is ignored in debug mode\n");
|
|
parloop_by_handler = 0;
|
|
options.setOff(O_PL);
|
|
options.setOff(O_PL2);
|
|
}
|
|
|
|
if (openmp && ACC_program)
|
|
{
|
|
(void)fprintf(stderr, "Warning: -noH option is set to -mp mode\n");
|
|
ACC_program = 0;
|
|
}
|
|
if (parloop_by_handler == 2 && !options.isOn(O_HOST))
|
|
{
|
|
(void)fprintf(stderr, "Warning: -Ohost option is set to -Opl2 mode\n");
|
|
options.setOn(O_HOST);
|
|
}
|
|
if(out_free_form == 1 && out_line_length == 72 && out_line_unlimit == 1)
|
|
{
|
|
(void)fprintf(stderr, "Warning: -noLimitLine and -uniForm options are incompatible; -noLimitLine option is ignored\n");
|
|
out_line_unlimit = 0;
|
|
}
|
|
if (v_print)
|
|
(void)fprintf(stderr, "<<<<< Translating >>>>>\n");
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
SgProject project(proj_name);
|
|
SgFile *file;
|
|
addNumberOfFileToAttribute(&project);
|
|
|
|
//----------------------------
|
|
ProjectStructure(project);
|
|
Private_Vars_Project_Analyzer();
|
|
//----------------------------
|
|
|
|
initVariantNames(); //for project
|
|
initIntrinsicFunctionNames(); //for project
|
|
initSupportedVars(); // for project, acc_f2c.cpp
|
|
initF2C_FunctionCalls(); // for project, acc_f2c.cpp
|
|
for(int id=project.numberOfFiles()-1; id >= 0; id--)
|
|
{
|
|
file = &(project.file(id)); //file->unparsestdout();
|
|
fin_name = new char[strlen(project.fileName(id))+2];
|
|
sprintf(fin_name, "%s%s", project.fileName(id), " ");
|
|
//fin_name = strcat(project.fileName(0)," ");
|
|
// for call of function 'tpoint'
|
|
//added one symbol to input-file name
|
|
//printf("%s",fin_name); //!!! debug
|
|
if(!fout_name)
|
|
fout_name = doOutFileName(file->filename());
|
|
else if (fout_name && source_name && !strcmp(source_name, fout_name))
|
|
{
|
|
(void)fprintf(stderr, "Output file has the same name as source file\n");
|
|
return 1;
|
|
}
|
|
|
|
//printf("%s\n", fout_name);///!!! debug
|
|
fout_name_cuf = ChangeFtoCuf(fout_name); /*ACC*/
|
|
fout_name_C_cu = ChangeFto_C_Cu(fout_name); /*ACC*/
|
|
fout_name_info_C = ChangeFto_info_C(fout_name); /*ACC*/
|
|
|
|
//set the last symbol of file
|
|
last_file_symbol = file->filept->cur_symb; //for low_level.c and not only
|
|
initLibNames(); //for every file
|
|
InitDVM(file); //for every file
|
|
current_file = file; // global variable (used in SgTypeComplex)
|
|
max_lab = getLastLabelId();
|
|
|
|
if (dbg_if_regim)
|
|
GetLabel(); //set maxlabval=90000
|
|
/*
|
|
printf("Labels:\n");
|
|
printf("first:%d max: %d \n",firstLabel(file)->thelabel->stateno, getLastLabelId());
|
|
for(int num=1; num<=getLastLabelId(); num++)
|
|
if(isLabel(num))
|
|
printf("%d is label\n",num);
|
|
else
|
|
printf("%d isn't label\n",num);
|
|
|
|
*/
|
|
|
|
if (openmp) { /*OMP*/
|
|
if (debug_regim > 0) /*OMP*/
|
|
InstrumentForOpenMPDebug(file); /*OMP*/
|
|
else /*OMP*/
|
|
TranslateFileOpenMPDVM(file); /*OMP*/
|
|
}
|
|
else
|
|
TranslateFileDVM(file);
|
|
/* DEBUG */
|
|
/* {FILE *fout; fout = fopen("out.out","w"); file->unparse(fout);} */
|
|
/* classifyStatements(file);
|
|
printf("**************************************************\n");
|
|
printf("**** Expression Table ****************************\n");
|
|
printf("**************************************************\n");
|
|
classifyExpressions(file);
|
|
printf("**************************************************\n");
|
|
printf("**** Symbol Table *******************************\n");
|
|
printf("**************************************************\n");
|
|
classifySymbols(file);
|
|
printf("**************************************************\n");
|
|
*/
|
|
/* end DEBUG */
|
|
|
|
// file->unparsestdout();
|
|
|
|
if (err_cnt) {
|
|
(void)fprintf(stderr, "%d error(s)\n", err_cnt);
|
|
//!!! exit(1);
|
|
return 1;
|
|
}
|
|
//file->saveDepFile("dvm.dep");
|
|
//DVMFileUnparse(file);
|
|
//file->saveDepFile("f.dep");
|
|
|
|
if (!fout_name) { //outfile is not specified, output result to stdout
|
|
file->unparsestdout();
|
|
return 0;
|
|
}
|
|
|
|
//writing result of converting into file
|
|
if ((fout = fopen(fout_name, "w")) == NULL) {
|
|
(void)fprintf(stderr, "Can't open file %s for write\n", fout_name);
|
|
return 1;
|
|
}
|
|
|
|
if (GeneratedForCuda()) /*ACC*/
|
|
{
|
|
if ((fout_C_cu = fopen(fout_name_C_cu, "w")) == NULL) {
|
|
(void)fprintf(stderr, "Can't open file %s for write\n", fout_name_C_cu);
|
|
return 1;
|
|
}
|
|
|
|
if (!options.isOn(C_CUDA))
|
|
{
|
|
if ((fout_cuf = fopen(fout_name_cuf, "w")) == NULL) {
|
|
(void)fprintf(stderr, "Can't open file %s for write\n", fout_name_cuf);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if ((fout_info = fopen(fout_name_info_C, "w")) == NULL) {
|
|
(void)fprintf(stderr, "Can't open file %s for write\n", fout_name_info_C);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
if (v_print)
|
|
(void)fprintf(stderr, "<<<<< Unparsing %s >>>>>\n", fout_name);
|
|
if (mod_gpu) /*ACC*/
|
|
UnparseTo_CufAndCu_Files(file, fout_cuf, fout_C_cu, fout_info);
|
|
|
|
if (unparse_functions)
|
|
UnparseFunctionsOfFile(file, fout);
|
|
else if (UnparserBufSize)
|
|
//UnparseProgram_ThroughAllocBuf(fout,file->filept,UnparserBufSize);
|
|
file->unparseS(fout, UnparserBufSize);
|
|
else
|
|
file->unparse(fout);
|
|
|
|
if ((fclose(fout)) < 0) {
|
|
(void)fprintf(stderr, "Could not close %s\n", fout_name);
|
|
return 1;
|
|
}
|
|
|
|
if (GeneratedForCuda()) /*ACC*/
|
|
{
|
|
if ((fclose(fout_C_cu)) < 0) {
|
|
(void)fprintf(stderr, "Could not close %s\n", fout_name_C_cu);
|
|
return 1;
|
|
}
|
|
|
|
if (!options.isOn(C_CUDA))
|
|
{
|
|
if ((fclose(fout_cuf)) < 0) {
|
|
(void)fprintf(stderr, "Could not close %s\n", fout_name_cuf);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if ((fclose(fout_info)) < 0) {
|
|
(void)fprintf(stderr, "Could not close %s\n", fout_name_info_C);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
fout_name = NULL;
|
|
}
|
|
|
|
if (v_print)
|
|
(void)fprintf(stderr, "\n***** Done *****\n");
|
|
return 0;
|
|
}
|
|
|
|
void initialize()
|
|
{
|
|
int i;
|
|
Dloop_No = 0;
|
|
nfrag = 0; //counter of intervals for performance analizer
|
|
St_frag = 0;
|
|
St_loop_first = 0;
|
|
St_loop_last = 0;
|
|
close_loop_interval = 0;
|
|
len_int = 0;
|
|
len_DvmType = 0;
|
|
if (sizeof(long) == 8) //default rule for bind, set by options -bind0,-bind1
|
|
bind_ = 1;
|
|
else
|
|
bind_ = 0;
|
|
perf_analysis = 0; //set to 1 by -e1
|
|
omp_perf = 0; //set to 1 by -emp
|
|
dvm_debug = 0; //set to 1 by -d1 or -d2 or -d3 or -d4 flag
|
|
only_debug = 0; //set to 1 by -s flag
|
|
level_debug = 0; //set to 1 by -d1, to 2 by -d2, ...
|
|
debug_fragment = NULL;
|
|
perf_fragment = NULL;
|
|
debug_regim = 0;
|
|
dbg_if_regim = 0;
|
|
check_regim = 0; //set by option -dc
|
|
deb_mpi = 0; //set by option -dmpi
|
|
d_no_index = 0; //set by option -dnoind
|
|
IOBufSize = SIZE_IO_BUF;
|
|
HPF_program = 0;
|
|
many_files = 1; /*29.06.01*/
|
|
iacross = 0; //for HPF_program
|
|
irg = 0; //for HPF_program
|
|
redgref = NULL; //for HPF_program
|
|
idebrg = 0; //for HPF_program
|
|
iconsg = 0;
|
|
consgref = NULL;
|
|
idebcg = 0;
|
|
all_sh_width = no_rma = one_inquiry = only_local = 0;
|
|
opt_base = 0;
|
|
opt_loop_range = 0;
|
|
in_interface = 0;
|
|
out_free_form = 0;
|
|
out_upper_case = 0;
|
|
out_line_unlimit = 0;
|
|
out_line_length = 132;
|
|
default_integer_size = 4;
|
|
default_real_size = 4;
|
|
unparse_functions = 0; //set to 1 by option -byFunUnparse
|
|
for (i = 0; i < Ndev; i++) /*ACC*/
|
|
device_flag[i] = 0; // set by option and by TARGETS clause of REGION directive
|
|
ACC_program = 1; /*ACC*/
|
|
region_debug = 0; /*ACC*/
|
|
region_compare = 0; /*ACC*/
|
|
undefined_Tcuda = 0; /*ACC*/
|
|
options.setOn(C_CUDA); /*ACC*/
|
|
options.setOn(NO_BL_INFO); /*ACC*/
|
|
options.setOn(O_HOST); /*ACC*/
|
|
parloop_by_handler = 0; /*ACC*/
|
|
collapse_loop_count = 0; /*ACC*/
|
|
cuda_functions = 0; /*ACC*/
|
|
err_cnt = 0;
|
|
}
|
|
|
|
SgSymbol *LastSymbolOfFile(SgFile *f)
|
|
{ SgSymbol *s;
|
|
s = f->firstSymbol();
|
|
while(s->next())
|
|
s = s->next();
|
|
|
|
return s;
|
|
}
|
|
|
|
char *doOutFileName(const char *fdeb_name)
|
|
{
|
|
char *name;
|
|
int i;
|
|
|
|
name = (char *)malloc((unsigned)(strlen(fdeb_name) + 5 + 2 + 1));
|
|
strcpy(name, fdeb_name);
|
|
for (i = strlen(name) - 1; i >= 0; i--)
|
|
{
|
|
if (name[i] == '.')
|
|
break;
|
|
}
|
|
strcpy(name + i, ".DVMH.f");
|
|
return(name);
|
|
}
|
|
|
|
int isHPFprogram(char *filename)
|
|
{
|
|
int i;
|
|
|
|
if (!filename)
|
|
return (0);
|
|
|
|
for (i = strlen(filename)-1 ; i >= 0 ; i --)
|
|
{
|
|
if ( filename[i] == '.' )
|
|
break;
|
|
}
|
|
|
|
//if (i>=0 && !strcmp(&(filename[i+1]),"hpf"))
|
|
if(i>=0 && (filename[i+1] == 'h' || filename[i+1] =='H') && (filename[i+2] == 'p' || filename[i+2] =='P') && (filename[i+3] == 'f' || filename[i+3] =='F'))
|
|
return(1);
|
|
else
|
|
return(0);
|
|
}
|
|
|
|
void initVariantNames(){
|
|
for(int i = 0; i < MAXTAGS; i++) tag[i] = NULL;
|
|
/*!!!*/
|
|
#include "tag.h"
|
|
}
|
|
|
|
void initLibNames(){
|
|
for(int i = 0; i < MAX_LIBFUN_NUM; i++) {
|
|
fdvm[i] = NULL;
|
|
name_dvm[i] = NULL;
|
|
}
|
|
#include "libdvm.h"
|
|
}
|
|
|
|
void initMask(){
|
|
for(int i = 0; i < MAX_LIBFUN_NUM; i++) {
|
|
fmask[i] = 0;
|
|
}
|
|
}
|
|
|
|
void InitDVM( SgFile *f) {
|
|
SgStatement *fst;
|
|
int i;
|
|
fst = f->firstStatement(); //fst -> File header
|
|
// Initialize COMMON names
|
|
dvmcommon = new SgSymbol(VARIABLE_NAME,"mem000",*fst);//DEFAULT variant is right for COMMON
|
|
//but Sage don't want to create such symbol
|
|
dvmcommon_ch = new SgSymbol(VARIABLE_NAME,"mch000",*fst);
|
|
heapcommon = new SgSymbol(VARIABLE_NAME,"heap00",*fst);
|
|
dbgcommon = new SgSymbol(VARIABLE_NAME,"dbg000",*fst);
|
|
|
|
// Initialize the functions symbols (for LibDVM functions)
|
|
for (i=0; name_dvm[i] && i<MAX_LIBFUN_NUM; i++) {
|
|
fdvm[i] = new SgFunctionSymb(FUNCTION_NAME, name_dvm[i], *SgTypeInt(), *fst);
|
|
// printf("name_dvm[%d] = %s\n", i , name_dvm[i]);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void initF90Names() {
|
|
for(int i = 0; i < NUM__F90; i++)
|
|
f90[i] = NULL;
|
|
}
|
|
|
|
SgType * SgTypeComplex(SgFile *f)
|
|
{
|
|
SgType *t;
|
|
for(t=f->firstType(); t; t=t->next())
|
|
if(t->variant()==T_COMPLEX)
|
|
return(t);
|
|
|
|
return(new SgType(T_COMPLEX));
|
|
}
|
|
|
|
SgType * SgTypeDoubleComplex(SgFile *f)
|
|
{
|
|
SgType *t;
|
|
for(t=f->firstType(); t; t=t->next())
|
|
if(t->variant()==T_DCOMPLEX)
|
|
return(t);
|
|
|
|
return(new SgType(T_DCOMPLEX));
|
|
}
|
|
|
|
int MemoryUse()
|
|
{
|
|
int i;
|
|
for(i=0; i<Ntp; i++)
|
|
if(mem_use[i] != 0 )
|
|
return(1);
|
|
return(0);
|
|
}
|
|
|
|
void TempVarDVM(SgStatement * func ) {
|
|
|
|
int i;
|
|
SgValueExp N(100),M1(1),M0(0), MB(64);
|
|
SgExpression *MS;
|
|
//SgSubscriptExp M00(M0,M0);
|
|
// SgExpression *M00(DDOT,&M0,&M0,NULL);
|
|
SgExpression *M00 = new SgExpression(DDOT,&M0.copy(),&MB.copy(),NULL);
|
|
SgExpression *le = NULL ;
|
|
SgArrayType *typearray;
|
|
|
|
typearray = new SgArrayType(*SgTypeInt());
|
|
dvmbuf = new SgVariableSymb("dvm000", *typearray, *func);
|
|
typearray = new SgArrayType(*SgTypeInt());
|
|
hpfbuf = new SgVariableSymb("hpf000", *typearray, *func);
|
|
|
|
Iconst[0] = new SgConstantSymb("dvm0c0", *func, *new SgValueExp(0));
|
|
Iconst[1] = new SgConstantSymb("dvm0c1", *func, *new SgValueExp(1));
|
|
Iconst[2] = new SgConstantSymb("dvm0c2", *func, *new SgValueExp(2));
|
|
Iconst[3] = new SgConstantSymb("dvm0c3", *func, *new SgValueExp(3));
|
|
Iconst[4] = new SgConstantSymb("dvm0c4", *func, *new SgValueExp(4));
|
|
Iconst[5] = new SgConstantSymb("dvm0c5", *func, *new SgValueExp(5));
|
|
Iconst[6] = new SgConstantSymb("dvm0c6", *func, *new SgValueExp(6));
|
|
Iconst[7] = new SgConstantSymb("dvm0c7", *func, *new SgValueExp(7));
|
|
Iconst[8] = new SgConstantSymb("dvm0c8", *func, *new SgValueExp(8));
|
|
Iconst[9] = new SgConstantSymb("dvm0c9", *func, *new SgValueExp(9));
|
|
|
|
if(debug_regim)
|
|
dbg_var = new SgVariableSymb("dbgvar00", *SgTypeInt(), *func);
|
|
|
|
if(only_debug)
|
|
return;
|
|
|
|
typearray = new SgArrayType(*SgTypeFloat());
|
|
typearray-> addRange(*M00);
|
|
Rmem = mem_symb[Real] = new SgVariableSymb("r0000m", *typearray, *func);
|
|
//Rmem-> declareTheSymbol(*func);
|
|
typearray = new SgArrayType(*SgTypeDouble());
|
|
typearray-> addRange(*M00);
|
|
Dmem = mem_symb[Double] = new SgVariableSymb("d0000m", *typearray, *func);
|
|
//Dmem-> declareTheSymbol(*func);
|
|
typearray = new SgArrayType(*SgTypeInt());
|
|
typearray-> addRange(*M00);
|
|
Imem = mem_symb[Integer] = new SgVariableSymb("i0000m", *typearray, *func);
|
|
//Imem-> declareTheSymbol(*func);
|
|
typearray = new SgArrayType(*SgTypeBool());
|
|
typearray-> addRange(*M00);
|
|
Lmem = mem_symb[Logical] = new SgVariableSymb("l0000m", *typearray, *func);
|
|
//Lmem-> declareTheSymbol(*func);
|
|
//!!!!!!!
|
|
typearray = new SgArrayType(* SgTypeComplex(current_file));
|
|
typearray-> addRange(*M00);
|
|
Cmem = mem_symb[Complex] = new SgVariableSymb("c0000m", *typearray, *func);
|
|
typearray = new SgArrayType(* SgTypeDoubleComplex(current_file));
|
|
typearray-> addRange(*M00);
|
|
DCmem = mem_symb[DComplex] = new SgVariableSymb("dc000m", *typearray, *func);
|
|
typearray = new SgArrayType(*SgTypeChar());
|
|
typearray-> addRange(*M00);
|
|
Chmem = mem_symb[Character] = new SgVariableSymb("ch000m", *typearray, *func);
|
|
//---------
|
|
le= new SgExpression(LEN_OP);
|
|
le->setLhs(new SgValueExp(1));
|
|
SgType *tint1 = new SgType(T_INT, le, NULL);
|
|
le= new SgExpression(LEN_OP);
|
|
le->setLhs(new SgValueExp(2));
|
|
SgType *tint2 = new SgType(T_INT, le, NULL);
|
|
le= new SgExpression(LEN_OP);
|
|
le->setLhs(new SgValueExp(8));
|
|
SgType *tint8 = new SgType(T_INT, le, NULL);
|
|
//----------
|
|
typearray = new SgArrayType(*tint1);
|
|
typearray-> addRange(*M00);
|
|
mem_symb[Integer_1] = new SgVariableSymb("i000m1", *typearray, *func);
|
|
typearray = new SgArrayType(*tint2);
|
|
typearray-> addRange(*M00);
|
|
mem_symb[Integer_2] = new SgVariableSymb("i000m2", *typearray, *func);
|
|
typearray = new SgArrayType(*tint8);
|
|
typearray-> addRange(*M00);
|
|
mem_symb[Integer_8] = new SgVariableSymb("i000m8", *typearray, *func);
|
|
//---------
|
|
le= new SgExpression(LEN_OP);
|
|
le->setLhs(new SgValueExp(1));
|
|
SgType *tlog1 = new SgType(T_BOOL, le, NULL);
|
|
le= new SgExpression(LEN_OP);
|
|
le->setLhs(new SgValueExp(2));
|
|
SgType *tlog2 = new SgType(T_BOOL, le, NULL);
|
|
le= new SgExpression(LEN_OP);
|
|
le->setLhs(new SgValueExp(8));
|
|
SgType *tlog8 = new SgType(T_BOOL, le, NULL);
|
|
//----------
|
|
typearray = new SgArrayType(*tlog1);
|
|
typearray-> addRange(*M00);
|
|
mem_symb[Logical_1] = new SgVariableSymb("l000m1", *typearray, *func);
|
|
typearray = new SgArrayType(*tlog2);
|
|
typearray-> addRange(*M00);
|
|
mem_symb[Logical_2] = new SgVariableSymb("l000m2", *typearray, *func);
|
|
typearray = new SgArrayType(*tlog8);
|
|
typearray-> addRange(*M00);
|
|
mem_symb[Logical_8] = new SgVariableSymb("l000m8", *typearray, *func);
|
|
|
|
for(i=0; i<8; i++)
|
|
loop_var[i] = new SgVariableSymb(name_loop_var[i], *SgTypeInt(), *func);
|
|
|
|
MS = new SgValueExp(IOBufSize);
|
|
typearray = new SgArrayType(*SgTypeInt());
|
|
typearray-> addRange(*MS);
|
|
bufIO[Integer] = new SgVariableSymb(name_bufIO[Integer], *typearray, *func);
|
|
typearray = new SgArrayType(*SgTypeFloat());
|
|
typearray-> addRange(*MS);
|
|
bufIO[Real] = new SgVariableSymb(name_bufIO[Real], *typearray, *func);
|
|
typearray = new SgArrayType(*SgTypeDouble());
|
|
typearray-> addRange(*MS);
|
|
bufIO[Double] = new SgVariableSymb(name_bufIO[Double], *typearray, *func);
|
|
typearray = new SgArrayType(* SgTypeComplex(current_file));
|
|
typearray-> addRange(*MS);
|
|
bufIO[Complex] = new SgVariableSymb(name_bufIO[Complex], *typearray, *func);
|
|
typearray = new SgArrayType(*SgTypeBool());
|
|
typearray-> addRange(*MS);
|
|
bufIO[Logical] = new SgVariableSymb(name_bufIO[Logical], *typearray, *func);
|
|
typearray = new SgArrayType(* SgTypeDoubleComplex(current_file));
|
|
typearray-> addRange(*MS);
|
|
bufIO[DComplex] = new SgVariableSymb(name_bufIO[DComplex], *typearray, *func);
|
|
typearray = new SgArrayType(* new SgType(T_STRING));
|
|
typearray-> addRange(*MS);
|
|
bufIO[Character] = new SgVariableSymb(name_bufIO[Character], *typearray, *func);
|
|
typearray = new SgArrayType(*tint1);
|
|
typearray-> addRange(*MS);
|
|
bufIO[Integer_1] = new SgVariableSymb(name_bufIO[Integer_1], *typearray, *func);
|
|
typearray = new SgArrayType(*tint2);
|
|
typearray-> addRange(*MS);
|
|
bufIO[Integer_2] = new SgVariableSymb(name_bufIO[Integer_2], *typearray, *func);
|
|
typearray = new SgArrayType(*tint8);
|
|
typearray-> addRange(*MS);
|
|
bufIO[Integer_8] = new SgVariableSymb(name_bufIO[Integer_8], *typearray, *func);
|
|
typearray = new SgArrayType(*tlog1);
|
|
typearray-> addRange(*MS);
|
|
bufIO[Logical_1] = new SgVariableSymb(name_bufIO[Logical_1], *typearray, *func);
|
|
typearray = new SgArrayType(*tlog2);
|
|
typearray-> addRange(*MS);
|
|
bufIO[Logical_2] = new SgVariableSymb(name_bufIO[Logical_2], *typearray, *func);
|
|
typearray = new SgArrayType(*tlog8);
|
|
typearray-> addRange(*MS);
|
|
bufIO[Logical_8] = new SgVariableSymb(name_bufIO[Logical_8], *typearray, *func);
|
|
|
|
typearray = new SgArrayType(*SgTypeInt());
|
|
rmbuf[Integer] = new SgVariableSymb(name_rmbuf[Integer], *typearray, *func);
|
|
typearray = new SgArrayType(*SgTypeFloat());
|
|
rmbuf[Real] = new SgVariableSymb(name_rmbuf[Real], *typearray, *func);
|
|
typearray = new SgArrayType(*SgTypeDouble());
|
|
rmbuf[Double] = new SgVariableSymb(name_rmbuf[Double], *typearray, *func);
|
|
typearray = new SgArrayType(* SgTypeComplex(current_file));
|
|
rmbuf[Complex] = new SgVariableSymb(name_rmbuf[Complex], *typearray, *func);
|
|
typearray = new SgArrayType(*SgTypeBool());
|
|
rmbuf[Logical] = new SgVariableSymb(name_rmbuf[Logical], *typearray, *func);
|
|
typearray = new SgArrayType(* SgTypeDoubleComplex(current_file));
|
|
rmbuf[DComplex] = new SgVariableSymb(name_rmbuf[DComplex], *typearray, *func);
|
|
typearray = new SgArrayType(* new SgType(T_STRING));
|
|
rmbuf[Character] = new SgVariableSymb(name_rmbuf[Character], *typearray, *func);
|
|
typearray = new SgArrayType(*tint1);
|
|
rmbuf[Integer_1] = new SgVariableSymb(name_rmbuf[Integer_1], *typearray, *func);
|
|
typearray = new SgArrayType(*tint2);
|
|
rmbuf[Integer_2] = new SgVariableSymb(name_rmbuf[Integer_2], *typearray, *func);
|
|
typearray = new SgArrayType(*tint8);
|
|
rmbuf[Integer_8] = new SgVariableSymb(name_rmbuf[Integer_8], *typearray, *func);
|
|
typearray = new SgArrayType(*tlog1);
|
|
rmbuf[Logical_1] = new SgVariableSymb(name_rmbuf[Logical_1], *typearray, *func);
|
|
typearray = new SgArrayType(*tlog2);
|
|
rmbuf[Logical_2] = new SgVariableSymb(name_rmbuf[Logical_2], *typearray, *func);
|
|
typearray = new SgArrayType(*tlog8);
|
|
rmbuf[Logical_8] = new SgVariableSymb(name_rmbuf[Logical_8], *typearray, *func);
|
|
|
|
typearray = new SgArrayType(*SgTypeInt());
|
|
heapdvm = new SgVariableSymb("heap00", *typearray, *func);
|
|
|
|
Pipe = new SgVariableSymb("pipe00", *SgTypeDouble(), *func);
|
|
|
|
return;
|
|
}
|
|
|
|
char* FileNameVar(int i)
|
|
{ char *name;
|
|
name = new char[80];
|
|
sprintf(name,"%s%d","filenm00",i);
|
|
return(name);
|
|
}
|
|
|
|
char* RedGroupVarName(SgSymbol *gr)
|
|
{ char *name;
|
|
name = new char[80];
|
|
sprintf(name,"%s%s",gr->identifier(),"00");
|
|
return(name);
|
|
}
|
|
|
|
char* ModuleProcName(SgSymbol *smod)
|
|
{ char *name;
|
|
name = new char[80];
|
|
sprintf(name,"dvm_%s",smod->identifier());
|
|
return(name);
|
|
}
|
|
|
|
SgSymbol* BaseSymbol(SgSymbol *ar)
|
|
{ char *name;
|
|
SgSymbol *sbs, *base;
|
|
SgArrayType *typearray;
|
|
SgValueExp M0(0), MB(64);
|
|
SgExpression *M00 = new SgExpression(DDOT,&M0.copy(),&MB.copy(),NULL);
|
|
name = new char[80];
|
|
base = baseMemory(ar->type()->baseType());
|
|
//strncpy(name,base->identifier(),5);
|
|
//strcat (name,ar->identifier());
|
|
sprintf(name,"%.4s_%s",base->identifier(),ar->identifier());
|
|
typearray = new SgArrayType(*ar->type()->baseType());
|
|
typearray-> addRange(*M00);
|
|
sbs = new SgVariableSymb(name, *typearray, *cur_func);
|
|
return(sbs);
|
|
}
|
|
|
|
SgSymbol* IndexSymbol(SgSymbol *si)
|
|
{ char *name;
|
|
SgSymbol *sn;
|
|
name = new char[80];
|
|
sprintf(name,"%s__d",si->identifier());
|
|
sn = new SgVariableSymb(name, *si->type(), *cur_func);
|
|
return(sn);
|
|
}
|
|
|
|
SgSymbol* InitLoopSymbol(SgSymbol *si,SgType *t)
|
|
{ char *name;
|
|
SgSymbol *sn;
|
|
name = new char[80];
|
|
sprintf(name,"%s__init",si->identifier());
|
|
sn = new SgVariableSymb(name, *t, *cur_func);
|
|
return(sn);
|
|
}
|
|
|
|
SgSymbol* DerivedTypeBaseSymbol(SgSymbol *stype,SgType *t)
|
|
{
|
|
char *name;
|
|
SgSymbol *sn;
|
|
SgArrayType *typearray;
|
|
SgValueExp M0(0), MB(64);
|
|
SgExpression *M00 = new SgExpression(DDOT,&M0.copy(),&MB.copy(),NULL);
|
|
name = new char[80];
|
|
sprintf(name,"%s0000m",stype->identifier());
|
|
typearray = new SgArrayType(*t);
|
|
typearray-> addRange(*M00);
|
|
sn = new SgVariableSymb(name, *typearray, *cur_func);
|
|
return(sn);
|
|
}
|
|
|
|
SgSymbol* CommonSymbol(SgSymbol *stype)
|
|
{ char *name;
|
|
name = new char[80];
|
|
sprintf(name,"mem000%s",stype->identifier());
|
|
return(new SgSymbol(VARIABLE_NAME,name,*cur_func->controlParent()));
|
|
}
|
|
|
|
SgSymbol *CheckSummaSymbol()
|
|
{
|
|
return(new SgVariableSymb("check_sum00",*SgTypeDouble(),*cur_func));
|
|
}
|
|
|
|
SgSymbol *DebugGoToSymbol(SgType *t)
|
|
{char *name;
|
|
SgSymbol *sn;
|
|
name = new char[80];
|
|
sprintf(name,"dbv_goto00%d",++nifvar);
|
|
sn = new SgVariableSymb(name,*t,*cur_func);
|
|
if_goto = AddToSymbList(if_goto, sn);
|
|
return(sn);
|
|
}
|
|
|
|
|
|
SgSymbol *TaskAMVSymbol(SgSymbol *s)
|
|
{ char *name;
|
|
name = (char *) malloc((unsigned)(strlen(s->identifier())+5));
|
|
sprintf(name,"%s_amv",s->identifier());
|
|
return(new SgSymbol(VARIABLE_NAME,name,*cur_func));
|
|
}
|
|
|
|
SgSymbol *TaskIndSymbol(SgSymbol *s)
|
|
{ char *name;
|
|
name = (char *) malloc((unsigned)(strlen(s->identifier())+3));
|
|
sprintf(name,"i_%s",s->identifier());
|
|
return(new SgVariableSymb(name,*SgTypeInt(),*cur_func));
|
|
}
|
|
|
|
SgSymbol *TaskRenumArraySymbol(SgSymbol *s)
|
|
{ char *name;
|
|
name = (char *) malloc((unsigned)(strlen(s->identifier())+7));
|
|
sprintf(name,"renum_%s",s->identifier());
|
|
return(new SgVariableSymb(name,*(s->type()),*cur_func));
|
|
}
|
|
|
|
SgSymbol *TaskLPsArraySymbol(SgSymbol *s)
|
|
{ char *name;
|
|
name = (char *) malloc((unsigned)(strlen(s->identifier())+5));
|
|
sprintf(name,"lps_%s",s->identifier());
|
|
return(new SgVariableSymb(name,*(s->type()),*cur_func));
|
|
}
|
|
|
|
SgSymbol *TaskHPsArraySymbol(SgSymbol *s)
|
|
{ char *name;
|
|
name = (char *) malloc((unsigned)(strlen(s->identifier())+5));
|
|
sprintf(name,"hps_%s",s->identifier());
|
|
return(new SgVariableSymb(name,*(s->type()),*cur_func));
|
|
}
|
|
|
|
SgSymbol * CreateRegistrationArraySymbol()
|
|
{
|
|
SgSymbol *sn;
|
|
SgArrayType *typearray;
|
|
char *ident = cur_func->symbol()->identifier(); //Module identifier
|
|
char *name = new char[10+strlen(ident)];
|
|
sprintf(name,"deb_%s_dvm",ident);
|
|
typearray = new SgArrayType(*SgTypeInt());
|
|
sn = new SgVariableSymb(name, *typearray, *cur_func);
|
|
return(sn);
|
|
}
|
|
|
|
void CreateCoeffs(coeffs* scoef,SgSymbol *ar)
|
|
{int i,r,i0;
|
|
char *name;
|
|
r=Rank(ar);
|
|
i0 = opt_base ? 1 : 2;
|
|
if(opt_loop_range) i0=0;
|
|
for(i=i0;i<=r+2;i++){
|
|
name = new char[strlen(ar->identifier()) + 6];
|
|
sprintf(name,"%s%s%d", ar->identifier(),"000",i);
|
|
scoef->sc[i] = new SgVariableSymb(name, *SgTypeInt(), *cur_func);
|
|
//printf("%s",(scoef->sc[i])->identifier());
|
|
}
|
|
scoef->use = 0;
|
|
if(IN_MODULE && !IS_TEMPLATE(ar))
|
|
scoef->use = 1;
|
|
}
|
|
|
|
SgSymbol *CreateConsistentHeaderSymb(SgSymbol *ar)
|
|
{
|
|
char *name;
|
|
name = new char[80];
|
|
SgArrayType *typearray;
|
|
//SgValueExp M1(1);
|
|
name = new char[80];
|
|
sprintf(name,"%s%s",ar->identifier(),"000");
|
|
typearray = new SgArrayType(*SgTypeInt());
|
|
//typearray-> addRange(M1);
|
|
return( new SgVariableSymb(name, *typearray, *cur_func));
|
|
}
|
|
|
|
SgSymbol *IOstatSymbol()
|
|
{
|
|
if(!IOstat)
|
|
IOstat = new SgSymbol(VARIABLE_NAME, "iostat_dvm", *SgTypeInt(), *cur_func);
|
|
return (IOstat);
|
|
}
|
|
|
|
SgStatement *doPublicStmtForDvmModuleProcedure(SgSymbol *smod)
|
|
{
|
|
mod_attr *attrm;
|
|
SgStatement *st = NULL;
|
|
|
|
if((attrm=DVM_PROC_IN_MODULE(smod)) && attrm->symb){
|
|
st = new SgStatement(PUBLIC_STMT);
|
|
st->setExpression(0, *new SgExprListExp(*new SgVarRefExp(*attrm->symb)));
|
|
}
|
|
return (st);
|
|
}
|
|
|
|
void DeclareVariableWithInitialization (SgSymbol *sym, SgType *type, SgStatement *lstat)
|
|
{
|
|
if(!sym) return;
|
|
SgStatement *decl_st = sym->makeVarDeclStmt();
|
|
SgExpression *eeq = DVMVarInitialization(decl_st->expr(0)->lhs());
|
|
decl_st->expr(0)->setLhs(eeq);
|
|
if (type)
|
|
decl_st->expr(1)->setType(type);
|
|
decl_st->setVariant(VAR_DECL_90);
|
|
lstat -> insertStmtAfter(*decl_st);
|
|
}
|
|
|
|
void DeclareVarDVM(SgStatement *lstat, SgStatement *lstat2)
|
|
{
|
|
//lstat is not equal lstat2 only for MODULE:
|
|
//lstat2 is header of generated module procedure dvm_<module_name>
|
|
//some generated specification statements are inserted in specification part
|
|
//of module and other are inserted in module procedure
|
|
|
|
SgArrayType *typearray;
|
|
SgStatement *equiv, *st,*st1,*com, *st_next;
|
|
SgExpression *em[Ntp], *eeq, *ed;
|
|
SgValueExp c1(1),c0(0);
|
|
SgExprListExp *el, *eel;
|
|
int i=0;
|
|
int j;
|
|
SgType *tlen = NULL;
|
|
if(len_DvmType) {
|
|
SgExpression *le;
|
|
le = new SgExpression(LEN_OP);
|
|
le->setLhs(new SgValueExp(len_DvmType));
|
|
tlen = new SgType(T_INT, le, SgTypeInt());
|
|
}
|
|
|
|
st_next = lstat->lexNext();
|
|
|
|
if(in_interface) goto HEADERS_; //only array header declaration is created in interface body of interface block
|
|
|
|
// create DATA statement for SAVE groups: DATA gref(1)/0/ gred/0/...
|
|
if(grname && !IN_MODULE) { //group name list is not empty
|
|
group_name_list *sl;
|
|
char *data_str= new char[4000];
|
|
int i =0;
|
|
sprintf(data_str,"data ");
|
|
for(sl=grname; sl; sl=sl->next)
|
|
if(IS_SAVE(sl->symb)) {
|
|
i++;
|
|
if (sl->symb->variant() == REF_GROUP_NAME){
|
|
strcat(data_str,sl->symb->identifier());
|
|
strcat(data_str,"(1)/0/ ");
|
|
} else {
|
|
strcat(data_str,sl->symb->identifier());
|
|
strcat(data_str,"/0/ ");
|
|
}
|
|
}
|
|
if(i) {
|
|
st = new SgStatement(DATA_DECL);// creates DATA statement
|
|
SgExpression *es = new SgExpression(STMT_STR);
|
|
NODE_STR(es->thellnd) = data_str; //e->thellnd->entry.string_val = data_str;
|
|
st -> setExpression(0,*es);
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
}
|
|
|
|
|
|
// inserting in main program SAVE statement (without list): for OpenMP translation
|
|
if(IN_MAIN_PROGRAM && !saveall)
|
|
lstat -> insertStmtAfter(*new SgStatement(SAVE_DECL));
|
|
|
|
if (!only_debug) {
|
|
// declare array bases for DVM-arrays
|
|
if(opt_base && !HPF_program && dsym) {
|
|
symb_list *sl;
|
|
coeffs *c;
|
|
for(sl=dsym; sl; sl=sl->next) {
|
|
if(IS_TEMPLATE(sl->symb))
|
|
continue;
|
|
c = ((coeffs *) sl->symb-> attributeValue(0,ARRAY_COEF));
|
|
if(!c->use)
|
|
continue;
|
|
st = (*ARRAY_BASE_SYMBOL(sl->symb))->makeVarDeclStmt();
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
}
|
|
|
|
// create DATA statement for SAVE array headers: DATA a(1)/0/ b(1)/0/...
|
|
if(dsym && !IN_MODULE) { //distributed objects list is not empty
|
|
symb_list *sl;
|
|
char *data_str= new char[4000];
|
|
int i =0;
|
|
sprintf(data_str,"data ");
|
|
for(sl=dsym; sl; sl=sl->next) {
|
|
if(IS_SAVE(sl->symb)) {
|
|
i++;
|
|
/* if (i==5) {
|
|
strcat(data_str, "\n + ");
|
|
i=1;
|
|
}
|
|
*/
|
|
strcat(data_str,sl->symb->identifier());
|
|
strcat(data_str,"(1)/0/ ");
|
|
// sprintf(data_str, "%s%s(1)/0/",data_str,sl->symb->identifier());
|
|
}
|
|
}
|
|
// strcat(data_str,"\n");
|
|
if(i) {
|
|
st = new SgStatement(DATA_DECL);// creates DATA statement
|
|
SgExpression *es = new SgExpression(STMT_STR);
|
|
// e = new SgValueExp(data_str);
|
|
// NODE_STR(es->thellnd) = NODE_STR(e->thellnd);
|
|
NODE_STR(es->thellnd) = data_str; //e->thellnd->entry.string_val = data_str;
|
|
st -> setExpression(0,*es);
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
}
|
|
|
|
// declaring DVM do-variables
|
|
for(j=0; j<nio; j++) {
|
|
// loop_var[j] -> declareTheSymbol(*func);
|
|
st = loop_var[j] ->makeVarDeclStmt();
|
|
|
|
lstat2 -> insertStmtAfter(*st);
|
|
}
|
|
|
|
// declaring DVM memory variables
|
|
st1 = lstat2->lexNext();
|
|
|
|
if(MemoryUse())
|
|
//if (mem_use[Integer] || mem_use[Real] || mem_use[Double] || mem_use[Complex] || mem_use[Logical] || mem_use[DComplex] || mem_use[Character])
|
|
mem_use[Integer] = mem_use[Double] = 1; //DVM-COMMON-blocks must have the same length
|
|
else
|
|
if(IN_MAIN_PROGRAM)
|
|
mem_use[Integer] = mem_use[Double] = 1; //in MAIN-program DVM-COMMON must be always
|
|
|
|
for(j=0,i=0; j<Ntp; j++)
|
|
if(mem_use[j] != 0)
|
|
{
|
|
st = mem_symb[j]->makeVarDeclStmt();
|
|
lstat2 -> insertStmtAfter(*st);
|
|
em[j] = new SgArrayRefExp(*mem_symb[j]);
|
|
i++;
|
|
}
|
|
|
|
if(i>1) {
|
|
// generating EQUIVALENCE statement
|
|
// EQUIVALENCE (Imem(0), Rmem(0),...,Lmem(0))
|
|
|
|
j=0;
|
|
while (!mem_use[j])
|
|
j++;
|
|
el = new SgExprListExp(*em[j]);
|
|
for(j=j+1; j<Ntp; j++){
|
|
if(mem_use[j]) {
|
|
//el->append(*em[j]);
|
|
eel = new SgExprListExp(*em[j]);
|
|
eel->setRhs(*el);
|
|
el = eel;
|
|
}
|
|
}
|
|
eeq = new SgExpression (EQUI_LIST);
|
|
eeq -> setLhs(*el);
|
|
equiv = new SgStatement(EQUI_STAT);
|
|
equiv->setExpression(0,*eeq);
|
|
st1->insertStmtBefore(*equiv);
|
|
}
|
|
|
|
// declaring DVM memory variable of type CHARACTER in MAIN-program
|
|
// in MAIN-program DVM-COMMON must be always declared character array ch000m(0:1)
|
|
if(IN_MAIN_PROGRAM && !mem_use[Character]) {
|
|
st = Chmem ->makeVarDeclStmt();
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
|
|
|
|
// declaring COMMON block for DVM memory variables
|
|
if(i) {
|
|
el = new SgExprListExp(* new SgArrayRefExp(*Imem));
|
|
eeq = new SgExpression (COMM_LIST);
|
|
eeq -> setSymbol(*dvmcommon);
|
|
eeq -> setLhs(*el);
|
|
com = new SgStatement(COMM_STAT);
|
|
com->setExpression(0,*eeq);
|
|
st1->insertStmtBefore(*com);
|
|
}
|
|
/* if(mem_use[Character]) {
|
|
el = new SgExprListExp(* new SgArrayRefExp(*Chmem));
|
|
eeq = new SgExpression (COMM_LIST);
|
|
eeq -> setSymbol(*dvmcommon_ch);
|
|
eeq -> setLhs(*el);
|
|
com = new SgStatement(COMM_STAT);
|
|
com->setExpression(0,*eeq);
|
|
st1->insertStmtBefore(*com);
|
|
}
|
|
*/
|
|
// declaring DVM memory variable of derived type
|
|
if(mem_use_structure){
|
|
base_list *el;
|
|
SgExpression *e;
|
|
for(el=mem_use_structure;el;el=el->next) {
|
|
st = el->base_symbol ->makeVarDeclStmt();
|
|
lstat2 -> insertStmtAfter(*st);
|
|
|
|
// declaring COMMON block for DVM memory variables of derived type
|
|
|
|
e = new SgExprListExp(* new SgArrayRefExp(*el->base_symbol));
|
|
eeq = new SgExpression (COMM_LIST);
|
|
eeq -> setSymbol(*CommonSymbol(el->type_symbol));
|
|
eeq -> setLhs(*e);
|
|
com = new SgStatement(COMM_STAT);
|
|
com->setExpression(0,*eeq);
|
|
st1->insertStmtBefore(*com);
|
|
}
|
|
}
|
|
|
|
|
|
// declaring buffer variables for remote access
|
|
for(i=0; i<Ntp; i++)
|
|
if(rmbuf_size[i]) {
|
|
typearray = isSgArrayType(rmbuf[i]->type());
|
|
typearray-> addRange(* new SgValueExp(rmbuf_size[i]));
|
|
//rmbuf[i]-> declareTheSymbol(*func);
|
|
st = rmbuf[i] ->makeVarDeclStmt();
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
|
|
// declaring DVM buffer variables for Input/Output
|
|
st1 = lstat->lexNext();
|
|
i=0;
|
|
for (j=0; j<Ntp; j++)
|
|
if(buf_use[j]){
|
|
//bufIO[j]-> declareTheSymbol(*func);
|
|
st = bufIO[j] ->makeVarDeclStmt();
|
|
lstat -> insertStmtAfter(*st);
|
|
em[j] = new SgArrayRefExp(*bufIO[j]);
|
|
i++;
|
|
}
|
|
|
|
if(i && !buf_use[0]) { //declare integer I/O buffer always
|
|
buf_use[0] = 1;
|
|
st = bufIO[0] ->makeVarDeclStmt();
|
|
lstat -> insertStmtAfter(*st);
|
|
em[0] = new SgArrayRefExp(*bufIO[0]);
|
|
i++;
|
|
}
|
|
|
|
if(i>1) {
|
|
// generating EQUIVALENCE statement
|
|
// EQUIVALENCE (i000io(1), r000io(1),...,l000io(1))
|
|
// bufIO[0] bufIO[1] bufIO[4]
|
|
j=0;
|
|
while (!buf_use[j])
|
|
j++;
|
|
el = new SgExprListExp(*em[j]);
|
|
for(j=j+1; j<Ntp; j++){
|
|
if(buf_use[j]) {
|
|
eel = new SgExprListExp(*em[j]);
|
|
eel->setRhs(*el);
|
|
el = eel;
|
|
// el->append(*em[j]);
|
|
}
|
|
}
|
|
eeq = new SgExpression (EQUI_LIST);
|
|
eeq -> setLhs(*el);
|
|
equiv = new SgStatement(EQUI_STAT);
|
|
equiv->setExpression(0,*eeq);
|
|
st1->insertStmtBefore(*equiv);
|
|
}
|
|
|
|
// declaring buffer HEAP for headers of dynamic arrays
|
|
if(heap_ar_decl && heap_size){
|
|
typearray = isSgArrayType(heapdvm->type());
|
|
typearray-> addRange(* new SgValueExp(heap_size));
|
|
st = heapdvm ->makeVarDeclStmt();
|
|
//st =fdvm[0]->makeVarDeclStmt();// creates INTEGER name, then name is removed
|
|
//heap_ar_decl->setLhs(new SgExprListExp(new SgValueExp(heap_size)));
|
|
//(heap_ar_decl->lhs())->setRhs(NULL);
|
|
//st -> setExpression(0,*new SgExprListExp(*heap_ar_decl));
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
lstat -> insertStmtAfter(*st);
|
|
// declaring COMMON block for headers of dynamic arrays
|
|
el = new SgExprListExp(* new SgArrayRefExp(*heapdvm));
|
|
eeq = new SgExpression (COMM_LIST);
|
|
eeq -> setSymbol(*heapcommon);
|
|
eeq -> setLhs(*el);
|
|
com = new SgStatement(COMM_STAT);
|
|
com->setExpression(0,*eeq);
|
|
lstat->insertStmtAfter(*com);
|
|
}
|
|
// declaring SAVE variables for SAVE-arrays used in REGION
|
|
DeclareDataRegionSaveVariables(lstat, tlen); /*ACC*/
|
|
|
|
} //endif !only_debug
|
|
|
|
// declaring dvm-procedure for module as public
|
|
if(IN_MODULE && privateall && (st=doPublicStmtForDvmModuleProcedure(cur_func->symbol())))
|
|
lstat->insertStmtAfter(*st);
|
|
|
|
// declaring variable for new IOSTAT specifier of Input/Output statement (if END=,ERR=,EOR= are replaced with IOSTAT=)
|
|
if(IOstat)
|
|
{
|
|
st = IOstat ->makeVarDeclStmt();
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
|
|
// declare mask for registration (only in module)
|
|
if(debug_regim && count_reg ) {
|
|
typearray = isSgArrayType(registration_array->type());
|
|
typearray-> addRange(* new SgValueExp(count_reg));
|
|
st = registration_array ->makeVarDeclStmt();
|
|
eeq = DVMVarInitialization(st->expr(0)->lhs());
|
|
st->expr(0)->setLhs(eeq);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
st->setVariant(VAR_DECL_90);
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
|
|
// generate PARAMETER statement
|
|
|
|
if(dvm_const_ref == 1) {
|
|
st= new SgStatement(PARAM_DECL);
|
|
el = NULL;
|
|
for(j=0; j<10; j++) {
|
|
eel = new SgExprListExp(* new SgRefExp(CONST_REF, *Iconst[j]));
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
}
|
|
st->setExpression(0,*el);
|
|
lstat2 -> insertStmtAfter(*st);
|
|
|
|
// declare constants as INTEGER
|
|
st = fdvm[0]->makeVarDeclStmt();// creates INTEGER name, then name is removed
|
|
el = NULL;
|
|
|
|
for(j=0; j<10; j++) {
|
|
eel = new SgExprListExp(* new SgVarRefExp(Iconst[j]));
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
}
|
|
st -> setExpression(0,*el);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
lstat2 -> insertStmtAfter(*st);
|
|
}
|
|
|
|
// declare group names as INTEGER
|
|
if(grname) {
|
|
group_name_list *sl;
|
|
st =fdvm[0]->makeVarDeclStmt();// creates INTEGER name, then name is removed
|
|
el = NULL;
|
|
for(sl=grname; sl; sl=sl->next) {
|
|
if (sl->symb->variant() == REF_GROUP_NAME)
|
|
eeq = new SgArrayRefExp(*(sl->symb),*new SgValueExp(3));
|
|
else
|
|
eeq = new SgVarRefExp(*(sl->symb));
|
|
if(IN_MODULE)
|
|
eeq = DVMVarInitialization(eeq);
|
|
eel = new SgExprListExp(* eeq);
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
}
|
|
st -> setExpression(0,*el);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
if(IN_MODULE)
|
|
st->setVariant(VAR_DECL_90);
|
|
lstat -> insertStmtAfter(*st);
|
|
|
|
|
|
// declare common blocks for remote references groups
|
|
for(sl=grname; sl; sl=sl->next)
|
|
if (sl->symb->variant() == REF_GROUP_NAME) {
|
|
el = new SgExprListExp(* new SgArrayRefExp(*(sl->symb)));
|
|
eeq = new SgExpression (COMM_LIST);
|
|
eeq -> setSymbol(*(sl->symb));
|
|
eeq -> setLhs(*el);
|
|
com = new SgStatement(COMM_STAT);
|
|
com->setExpression(0,*eeq);
|
|
st->insertStmtAfter(*com);
|
|
}
|
|
|
|
// declare variables for reduction groups and consistent groups
|
|
st =fdvm[0]->makeVarDeclStmt();// creates INTEGER name, then name is removed
|
|
el = NULL;
|
|
for(sl=grname; sl; sl=sl->next) {
|
|
if (sl->symb->variant() == REDUCTION_GROUP_NAME || sl->symb->variant() == CONSISTENT_GROUP_NAME) {
|
|
SgSymbol *rgv;
|
|
int nl;
|
|
nl = sl->symb->variant() == REDUCTION_GROUP_NAME ? nloopred : nloopcons;
|
|
rgv = * ((SgSymbol **) (sl->symb)-> attributeValue(0,RED_GROUP_VAR));
|
|
ed = new SgExpression(DDOT,new SgValueExp(0),new SgValueExp(nl),NULL);
|
|
eeq = new SgArrayRefExp(*rgv,*ed);
|
|
if(IN_MODULE)
|
|
eeq = DVMVarInitialization(eeq);
|
|
//eeq = new SgArrayRefExp(*rgv,*new SgValueExp(nloopred));
|
|
eel = new SgExprListExp(* eeq);
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
}
|
|
}
|
|
if(el) {
|
|
st -> setExpression(0,*el);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
if(IN_MODULE)
|
|
st->setVariant(VAR_DECL_90);
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
}
|
|
// declare common block for reduction variables
|
|
if(redvar_list && !only_debug) {
|
|
symb_list *sl;
|
|
char * ncom = new char[100];
|
|
char * f_name;
|
|
el = NULL;
|
|
redvar_list = SortingBySize(redvar_list);
|
|
for(sl=redvar_list; sl; sl=sl->next)
|
|
if (CURRENT_SCOPE(sl->symb) && !IS_ARRAY(sl->symb) && !IN_COMMON(sl->symb) && !IN_DATA(sl->symb) && !IS_DUMMY(sl->symb) && !IS_SAVE(sl->symb) && !IN_EQUIVALENCE(sl->symb) && strcmp(sl->symb->identifier(),cur_func->symbol()->identifier()) && (cur_func->expr(0) ? sl->symb != cur_func->expr(0)->symbol() : 1)) {
|
|
eel = new SgExprListExp(* new SgVarRefExp(*(sl->symb)));
|
|
el = (SgExprListExp*) AddListToList(el,eel);
|
|
}
|
|
if (el){
|
|
f_name = cur_func->symbol()->identifier();
|
|
if(f_name[0]=='_') //main program unit without name: sage-name == _MAIN
|
|
f_name=f_name+1;
|
|
sprintf(ncom,"%s%s", f_name,"dvm");
|
|
st = cur_func->symbol()->scope();
|
|
redcommon = new SgSymbol(VARIABLE_NAME,ncom,*st);
|
|
eeq = new SgExpression (COMM_LIST);
|
|
eeq -> setSymbol(*redcommon);
|
|
eeq -> setLhs(*el);
|
|
com = new SgStatement(COMM_STAT);
|
|
com->setExpression(0,*eeq);
|
|
lstat->insertStmtAfter(*com);
|
|
}
|
|
}
|
|
|
|
// declare processor array names as INTEGER
|
|
if(proc_symb) {
|
|
symb_list *sl;
|
|
st =fdvm[0]->makeVarDeclStmt();// creates INTEGER name, then name is removed
|
|
el = NULL;
|
|
for(sl=proc_symb; sl; sl=sl->next) {
|
|
eel = new SgExprListExp(* new SgVarRefExp(*(sl->symb)));
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
}
|
|
st -> setExpression(0,*el);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
|
|
// declare index variables (optimization code)
|
|
if(index_symb) {
|
|
symb_list *sl;
|
|
for(sl=index_symb; sl; sl=sl->next) {
|
|
st = sl->symb->makeVarDeclStmt();
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
}
|
|
|
|
// declare task arrays as INTEGER
|
|
if(task_symb){
|
|
symb_list *sl;
|
|
SgArrayType *artype;
|
|
st =fdvm[0]->makeVarDeclStmt();// creates INTEGER name, then name is removed
|
|
el = NULL;
|
|
for(sl=task_symb; sl; sl=sl->next) {
|
|
artype = isSgArrayType(sl->symb->type());
|
|
eel = new SgExprListExp(* new SgArrayRefExp(*(sl->symb),*new SgValueExp(2),*artype->sizeInDim(0)));
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
eel = new SgExprListExp(*new SgVarRefExp(TASK_SYMBOL(sl->symb))); // symbol for TASK AMview
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
}
|
|
st -> setExpression(0,*el);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
lstat -> insertStmtAfter(*st);
|
|
//SgSymbol *s= TASK_IND_VAR(task_symb->symb);
|
|
st = fdvm[0]->makeVarDeclStmt();
|
|
el = NULL;
|
|
for(sl=task_symb; sl; sl=sl->next) {
|
|
artype = isSgArrayType(sl->symb->type());
|
|
eel = new SgExprListExp(* new SgArrayRefExp(*TASK_RENUM_ARRAY(sl->symb),*artype->sizeInDim(0)));
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
if(TASK_AUTO(sl->symb))
|
|
{
|
|
eel = new SgExprListExp(* new SgArrayRefExp(*TASK_HPS_ARRAY(sl->symb),*artype->sizeInDim(0)));
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
eel = new SgExprListExp(* new SgArrayRefExp(*TASK_LPS_ARRAY(sl->symb),*artype->sizeInDim(0)));
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
}
|
|
//eel = new SgExprListExp(*new SgVarRefExp(TASK_IND_VAR(sl->symb))); // symbol for TASK index variable
|
|
//eel->setRhs(el);
|
|
//el = eel;
|
|
}
|
|
st -> setExpression(0,*el);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
lstat -> insertStmtAfter(*st);
|
|
|
|
}
|
|
|
|
// declare ASYNCID as INTEGER
|
|
if(async_symb){
|
|
symb_list *sl;
|
|
SgArrayType *artype;
|
|
//SgArrayRefExp *ae;
|
|
st =fdvm[0]->makeVarDeclStmt();// creates INTEGER name, then name is removed
|
|
el = NULL;
|
|
for(sl=async_symb; sl; sl=sl->next) {
|
|
//eel = new SgExprListExp(* new SgArrayRefExp(*(sl->symb),*new SgValueExp(ASYNCID_NUMB)));
|
|
//eeq = new SgArrayRefExp(*(sl->symb),*new SgValueExp(ASYNCID_NUMB));
|
|
eeq = new SgArrayRefExp(*(sl->symb));
|
|
artype = isSgArrayType(sl->symb->type());
|
|
if(artype)
|
|
eeq->setLhs(artype->getDimList()); //add dimensions of array
|
|
else
|
|
eeq->setLhs(new SgValueExp(ASYNCID_NUMB));
|
|
if(IN_MODULE)
|
|
eeq = DVMVarInitialization(eeq);
|
|
eel = new SgExprListExp(*eeq);
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
}
|
|
st -> setExpression(0,*el);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
if(IN_MODULE)
|
|
st->setVariant(VAR_DECL_90);
|
|
lstat -> insertStmtAfter(*st);
|
|
|
|
|
|
// declare common blocks for ASYNCID variables
|
|
for(sl=async_symb; sl; sl=sl->next) {
|
|
if(IN_COMMON(sl->symb)) {
|
|
el = new SgExprListExp(* new SgArrayRefExp(*(sl->symb)));
|
|
eeq = new SgExpression (COMM_LIST);
|
|
eeq -> setSymbol(*(sl->symb));
|
|
eeq -> setLhs(*el);
|
|
com = new SgStatement(COMM_STAT);
|
|
com->setExpression(0,*eeq);
|
|
st->insertStmtAfter(*com);
|
|
}
|
|
}
|
|
}
|
|
|
|
// declare scalar variables for copying array header elements used for referencing array
|
|
if(!HPF_program && dsym ) {
|
|
symb_list *sl;
|
|
coeffs * c;
|
|
int i,rank,i0;
|
|
SgExpression *eepub, *lpub=NULL;
|
|
st =fdvm[0]->makeVarDeclStmt();// creates INTEGER name, then name is removed
|
|
el = NULL;
|
|
for(sl=dsym; sl; sl=sl->next) {
|
|
c = ((coeffs *) sl->symb-> attributeValue(0,ARRAY_COEF));
|
|
if(IS_TEMPLATE(sl->symb) || !c->use)
|
|
continue;
|
|
int flag_public = IN_MODULE && privateall && sl->symb->attributes() & PUBLIC_BIT ? 1 : 0;
|
|
rank=Rank(sl->symb);
|
|
i0 = opt_base ? 1 : 2;
|
|
if(opt_loop_range) i0=0;
|
|
for(i=i0;i<=rank;i++){
|
|
eel = new SgExprListExp(* new SgVarRefExp(*(c->sc[i])));
|
|
eepub = flag_public ? &eel->copy() : NULL;
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
if(flag_public)
|
|
{
|
|
eepub->setRhs(lpub);
|
|
lpub = eepub;
|
|
}
|
|
}
|
|
eel = new SgExprListExp(* new SgVarRefExp(*(c->sc[rank+2])));
|
|
eepub = flag_public ? &eel->copy() : NULL;
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
if(flag_public)
|
|
{
|
|
eepub->setRhs(lpub);
|
|
lpub = eepub;
|
|
}
|
|
|
|
}
|
|
if(el){
|
|
st -> setExpression(0,*el);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
if(lpub){
|
|
st = new SgStatement(PUBLIC_STMT);
|
|
st->setExpression(0,*lpub);
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
}
|
|
|
|
|
|
// declare Pipeline variable for ACROSS implementation
|
|
if(pipeline){
|
|
st = Pipe->makeVarDeclStmt();
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
|
|
// declare Debug variable for -dbif regim
|
|
if(dbg_if_regim && dbg_var && !IN_MODULE) {
|
|
st = dbg_var->makeVarDeclStmt();
|
|
lstat -> insertStmtAfter(*st);
|
|
|
|
// declaring COMMON block for Debug variable
|
|
|
|
el = new SgExprListExp(* new SgVarRefExp(*dbg_var));
|
|
eeq = new SgExpression (COMM_LIST);
|
|
eeq -> setSymbol(*dbgcommon);
|
|
eeq -> setLhs(*el);
|
|
com = new SgStatement(COMM_STAT);
|
|
com->setExpression(0,*eeq);
|
|
lstat->insertStmtAfter(*com);
|
|
}
|
|
|
|
|
|
// declare CheckSumma variable for -dc regim
|
|
if(check_sum){
|
|
st = check_sum->makeVarDeclStmt();
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
|
|
// declare FileNameVariables
|
|
if(fnlist){
|
|
filename_list *sl;
|
|
for(sl=fnlist; sl; sl=sl->next) {
|
|
st =sl->fns->makeVarDeclStmt();//character variables
|
|
|
|
st->expr(0)->setLhs(FileNameInitialization(st->expr(0)->lhs(),sl->name));
|
|
st->setVariant(VAR_DECL_90);
|
|
|
|
lstat2 -> insertStmtAfter(*st);
|
|
}
|
|
}
|
|
|
|
// declare CONSISTENT array headers as INTEGER
|
|
if(consistent_symb) {
|
|
symb_list *sl;
|
|
SgExpression *ea;
|
|
st =fdvm[0]->makeVarDeclStmt();// creates INTEGER name, then name is removed
|
|
|
|
el = NULL;
|
|
for(sl=consistent_symb; sl; sl=sl->next) {
|
|
|
|
/* if(IN_COMMON(sl->symb) && cur_func->variant() != PROG_HEDR)
|
|
continue;*/ /*25.03.03*/
|
|
ea = new SgArrayRefExp(*(CONSISTENT_HEADER(sl->symb)),*new SgValueExp(HSIZE(Rank(sl->symb))));
|
|
ea->setType(*SgTypeInt());
|
|
eel = new SgExprListExp(*ea);
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
}
|
|
if(el) {
|
|
st -> setExpression(0,*el);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
}
|
|
|
|
// declare variables for saving conditional expression for Arithmetic IF and Computed GO TO
|
|
// for regim of debugging and performance analysing
|
|
if(if_goto) {
|
|
symb_list *sl;
|
|
for(sl=if_goto; sl; sl=sl->next)
|
|
{st = (sl->symb)->makeVarDeclStmt();
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
}
|
|
|
|
HEADERS_: //begin generating for interface block
|
|
|
|
// declare array headers as INTEGER
|
|
if(dsym) {
|
|
symb_list *sl;
|
|
SgExpression *ea,*ehs;
|
|
st =fdvm[0]->makeVarDeclStmt();// creates INTEGER name, then name is removed
|
|
el = NULL;
|
|
for(sl=dsym; sl; sl=sl->next) {
|
|
if(IS_BY_USE(sl->symb)) continue;
|
|
//if(!isSgArrayType(sl->symb->type())) //for POINTER
|
|
// sl->symb ->setType(* new SgArrayType(*SgTypeInt()));
|
|
///if(IS_TEMPLATE(sl->symb) && !RTS2_OBJECT(sl->symb)) {
|
|
/// ea = new SgVarRefExp(*(sl->symb));
|
|
|
|
///} else {
|
|
ehs = IS_POINTER_F90(sl->symb) ? new SgExpression(DDOT) : new SgValueExp(HEADER_SIZE(sl->symb));
|
|
ea = new SgArrayRefExp(*(sl->symb),*ehs);
|
|
if(IS_POINTER(sl->symb) && (sl->symb->attributes() & DIMENSION_BIT)) { //array of POINTER
|
|
SgArrayType *artype;
|
|
artype = isSgArrayType(sl->symb->type());
|
|
if(artype)
|
|
(ea->lhs())->setRhs(artype->getDimList()); //add dimensions of array
|
|
}
|
|
///}
|
|
//TYPE_BASE(sl->symb->type()->thetype) = SgTypeInt()->thetype;
|
|
ea->setType(*SgTypeInt());
|
|
if(IN_MODULE && !IS_POINTER_F90(sl->symb))
|
|
ea = DVMVarInitialization(ea);
|
|
eel = new SgExprListExp(*ea);
|
|
eel->setRhs(el);
|
|
el = eel;
|
|
}
|
|
if(el) {
|
|
st -> setExpression(0,*el);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
if(IN_MODULE)
|
|
st->setVariant(VAR_DECL_90);
|
|
lstat -> insertStmtAfter(*st);
|
|
}
|
|
|
|
}
|
|
|
|
//declare Common-blocks for TEMPLATE with attribute COMMON
|
|
{
|
|
symb_list *sl;
|
|
for(sl=dsym; sl; sl=sl->next) {
|
|
if(IS_TEMPLATE(sl->symb) && IN_COMMON(sl->symb)) {
|
|
el = new SgExprListExp(* new SgVarRefExp(*(sl->symb)));
|
|
eeq = new SgExpression (COMM_LIST);
|
|
eeq -> setSymbol(*(sl->symb));
|
|
eeq -> setLhs(*el);
|
|
com = new SgStatement(COMM_STAT);
|
|
com->setExpression(0,*eeq);
|
|
st->insertStmtAfter(*com);
|
|
}
|
|
}
|
|
}
|
|
// end of declaration generating for interface block
|
|
if(in_interface) return;
|
|
|
|
// declare array hpf000(N), N = maxhpf
|
|
if(HPF_program && maxhpf != 0) {
|
|
typearray = isSgArrayType(hpfbuf->type());
|
|
typearray-> addRange(* new SgValueExp(maxhpf));
|
|
st = hpfbuf ->makeVarDeclStmt();
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
lstat2 -> insertStmtAfter(*st);
|
|
}
|
|
|
|
// declare array dvm000(N), N = maxdvm
|
|
if(cur_func->variant() == PROG_HEDR || !(maxdvm <= 3 && fmask[RTLINI] == 0 && fmask[BEGBL] == 0 && fmask[FNAME] == 0 && fmask[GETVM] == 0 && fmask[GETAM] == 0 && fmask[DVMLF] == 0)) {
|
|
typearray = isSgArrayType(dvmbuf->type());
|
|
typearray-> addRange(* new SgValueExp(maxdvm));
|
|
//dvmbuf-> declareTheSymbol(*func);
|
|
st = dvmbuf ->makeVarDeclStmt();
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
lstat2 -> insertStmtAfter(*st);
|
|
}
|
|
|
|
// declare LibDVM functions as INTEGER
|
|
i=0;
|
|
while ( (i<MAX_LIBFUN_NUM) && (fmask[i] != 1) ) //looking for first element of fmask[] equal to 1
|
|
i++;
|
|
if(i == MAX_LIBFUN_NUM) goto EXTERN_;
|
|
st = fdvm[i]->makeVarDeclStmt();
|
|
el = isSgExprListExp(st->expr(0));
|
|
// el = new SgExprListExp(* new SgVarRefExp(fdvm[0]));
|
|
for(j=i+1; fdvm[j] && j<MAX_LIBFUN_NUM ; j++) {
|
|
if(fmask[j] == 1) {
|
|
eel = new SgExprListExp(* new SgVarRefExp(fdvm[j]));
|
|
eel->setRhs(*el);
|
|
el = eel;
|
|
//el->append (* em[0]);
|
|
}
|
|
}
|
|
st -> setExpression(0,*el);
|
|
if(len_DvmType)
|
|
st->expr(1)->setType(tlen);
|
|
|
|
lstat2 -> insertStmtAfter(*st);
|
|
|
|
// declare LibDVM subroutines as EXTERNAL
|
|
EXTERN_:
|
|
i=0;
|
|
while ( (i<MAX_LIBFUN_NUM) && (fmask[i] != 2) ) //looking for first element of fmask[] equal to 2
|
|
i++;
|
|
if(i == MAX_LIBFUN_NUM) goto GPU_;
|
|
st = new SgStatement(EXTERN_STAT);
|
|
el = new SgExprListExp(* new SgVarRefExp(fdvm[i]));
|
|
for(j=i+1; fdvm[j] && j<MAX_LIBFUN_NUM ; j++) {
|
|
if(fmask[j] == 2) {
|
|
eel = new SgExprListExp(* new SgVarRefExp(fdvm[j]));
|
|
eel->setRhs(*el);
|
|
el = eel;
|
|
}
|
|
}
|
|
st -> setExpression(0,*el);
|
|
|
|
lstat2 -> insertStmtAfter(*st);
|
|
|
|
GPU_:
|
|
// declare GPU objects
|
|
if(!IN_MODULE)
|
|
DeclareVarGPU(lstat,tlen); /*ACC*/
|
|
// add comment
|
|
if(lstat->lexNext() != st_next)
|
|
(lstat->lexNext())->setComments("! DVMH declarations \n");
|
|
}
|
|
|
|
void TranslateFileDVM(SgFile *f)
|
|
{
|
|
SgStatement *func,*stat,*end_of_source_file;
|
|
SgStatement *end_of_unit; // last node (END or CONTAINS statement) of program unit
|
|
|
|
|
|
InitializeACC();
|
|
|
|
// grab the first statement in the file.
|
|
stat = f->firstStatement(); // file header
|
|
//last statement of file
|
|
end_of_source_file = FILE_LAST_STATEMENT(stat) ? *FILE_LAST_STATEMENT(stat) : lastStmtOfFile(f);
|
|
// add empty-statement to insert generated procedures at the end of file (after that)
|
|
end_of_source_file->insertStmtAfter( *new SgStatement(COMMENT_STAT),*stat);
|
|
end_of_source_file = end_of_source_file->lexNext();
|
|
if(ACC_program || parloop_by_handler)
|
|
end_of_source_file->addComment("!-----------------------------------------------------------------------\n");
|
|
|
|
//numfun = f->numberOfFunctions(); // number of functions
|
|
// function is program unit accept BLOCKDATA and MODULE (F90),i.e.
|
|
// PROGRAM, SUBROUTINE, FUNCTION
|
|
if(debug_fragment || perf_fragment) // is debugging or performance analizing regime specified ?
|
|
BeginDebugFragment(0,NULL);// begin the fragment with number 0 (involving whole file(program)
|
|
//for(i = 0; i < numfun; i++) {
|
|
// func = f -> functions(i);
|
|
|
|
for(stat=stat->lexNext(); stat!=end_of_source_file; stat=end_of_unit->lexNext())
|
|
{
|
|
if(stat->variant() == CONTROL_END) { //end of procedure or module with CONTAINS statement
|
|
end_of_unit = stat;
|
|
continue;
|
|
}
|
|
|
|
if( stat->variant() == BLOCK_DATA){//BLOCK_DATA header
|
|
TransBlockData(stat, end_of_unit); //replacing variant VAR_DECL with VAR_DECL_90 for declaration statement with initialisation
|
|
continue;
|
|
}
|
|
// PROGRAM, SUBROUTINE, FUNCTION header
|
|
func = stat;
|
|
cur_func = stat;
|
|
|
|
//scanning the Symbols Table of the function
|
|
// ScanSymbTable(func->symbol(), (f->functions(i+1))->symbol());
|
|
|
|
|
|
// translating the program unit (procedure, module)
|
|
if(only_debug)
|
|
InsertDebugStat(func, end_of_unit);
|
|
else
|
|
TransFunc(func, end_of_unit);
|
|
|
|
}
|
|
|
|
if(ACC_program)
|
|
{ InsertCalledProcedureCopies();
|
|
AddExternStmtToBlock_C();
|
|
GenerateEndIfDir();
|
|
GenerateDeclarationDir();
|
|
GenerateStmtsForInfoFile();
|
|
}
|
|
}
|
|
|
|
|
|
void TransFunc(SgStatement *func,SgStatement* &end_of_unit) {
|
|
SgStatement *stmt,*last,*rmout, *data_stf, *first, *first_dvm_exec, *last_spec, *stam, *last_dvm_entry, *lentry = NULL;
|
|
SgStatement *st_newv = NULL;// for NEW_VALUE directives
|
|
SgExpression *e;
|
|
SgStatement *task_region_parent = NULL, *on_stmt = NULL, *mod_proc, *begbl = NULL, *dvmh_init_st=NULL;
|
|
SgStatement *copy_proc = NULL;
|
|
SgStatement *has_contains = NULL;
|
|
SgLabel *lab_exec;
|
|
|
|
int i;
|
|
int begin_block;
|
|
distribute_list *distr = NULL;
|
|
distribute_list *dsl,*distr_last = NULL;
|
|
align *pal = NULL;
|
|
align *node, *root = NULL;
|
|
stmt_list *pstmt = NULL;
|
|
int inherit_is = 0;
|
|
int contains[2];
|
|
int in_on = 0;
|
|
char io_modes_str[4] = "\0";
|
|
|
|
//initialization
|
|
dsym = NULL;
|
|
grname = NULL;
|
|
saveall = 0;
|
|
maxdvm = 0;
|
|
maxhpf = 0;
|
|
count_reg = 0;
|
|
initMask();
|
|
data_stf = NULL;
|
|
loc_distr = 0;
|
|
begin_block = 0;
|
|
goto_list = NULL;
|
|
proc_symb = NULL;
|
|
task_symb = NULL;
|
|
consistent_symb = NULL;
|
|
async_symb = NULL;
|
|
check_sum = NULL;
|
|
loc_templ_symb=NULL;
|
|
index_symb = NULL;
|
|
nio = 0;
|
|
task_do = NULL;
|
|
for (i=0; i<Ntp; i++)
|
|
{ mem_use[i] = 0;
|
|
mem_symb[i] = NULL;
|
|
}
|
|
mem_use_structure = NULL;
|
|
heap_ar_decl = NULL;
|
|
is_heap_ref = 0;
|
|
//heap_size = 1;
|
|
heap_size = 0;
|
|
pref_st = NULL;
|
|
pipeline = 0;
|
|
registration = NULL;
|
|
filename_num = 0;
|
|
fnlist = NULL;
|
|
nloopred = 0;
|
|
nloopcons = 0;
|
|
wait_list = NULL;
|
|
SIZE_function = NULL;
|
|
dvm_const_ref = 0;
|
|
in_interface = 0;
|
|
mod_proc = NULL;
|
|
if_goto = NULL;
|
|
nifvar = 0;
|
|
entry_list = NULL;
|
|
dbif_cond = 0;
|
|
dbif_not_cond = 0;
|
|
last_dvm_entry = NULL;
|
|
allocated_list = NULL;
|
|
privateall = 0;
|
|
//if(ACC_program)
|
|
InitializeInFuncACC();
|
|
all_replicated = isInternalOrModuleProcedure(func) ? 0 : 1;
|
|
//Private_Vars_Function_Analyzer(func);
|
|
TempVarDVM(func);
|
|
initF90Names();
|
|
first = func->lexNext();
|
|
//!!!debug
|
|
//if(fsymb)
|
|
//printf("\n%s %s \n", header(func->variant()),fsymb->identifier());
|
|
//else {
|
|
//printf("Function name error \n");
|
|
//return;
|
|
//}
|
|
//get the last node of the program unit(function)
|
|
last = func->lastNodeOfStmt();
|
|
end_of_unit = last;
|
|
if(!(last->variant() == CONTROL_END))
|
|
printf(" END Statement is absent\n");
|
|
/*
|
|
fsymb = func->symbol();
|
|
if((func->variant() == PROG_HEDR) && !strcmp(fsymb->identifier(),"_MAIN")){
|
|
progsymb = new SgFunctionSymb(PROGRAM_NAME, "MAIN", *SgTypeInt(), *current_file->firstStatement() );
|
|
func->setSymbol(*progsymb);
|
|
}
|
|
*/
|
|
|
|
//**********************************************************************
|
|
// Specification Directives Processing
|
|
//**********************************************************************
|
|
// follow the statements of the function in lexical order
|
|
// until first executable statement
|
|
for (stmt = first; stmt && (stmt != last); stmt = stmt->lexNext()) {
|
|
//printf("statement %d %s\n",stmt->lineNumber(),stmt->fileName());
|
|
|
|
if (!isSgExecutableStatement(stmt)) //is Fortran specification statement
|
|
// isSgExecutableStatement:
|
|
// FALSE - for specification statement of Fortan 90
|
|
// TRUE - for executable statement of Fortan 90 and
|
|
// all directives of F-DVM
|
|
{
|
|
//!!!debug
|
|
// printVariantName(stmt->variant()); //for debug
|
|
// printf("\n");
|
|
|
|
//discovering distributed arrays in COMMON-blocks
|
|
if(stmt->variant()==COMM_STAT) {
|
|
DeleteShapeSpecDAr(stmt);
|
|
|
|
if( !DeleteHeapFromList(stmt) ) { //common list is empty
|
|
stmt=stmt->lexPrev();
|
|
stmt->lexNext()->extractStmt(); //deleting the statement
|
|
}
|
|
continue;
|
|
}
|
|
// analizing SAVE statement
|
|
if(stmt->variant()==SAVE_DECL) {
|
|
if (!stmt->expr(0)) //SAVE without name-list
|
|
saveall = 1;
|
|
else if(IN_MAIN_PROGRAM)
|
|
pstmt = addToStmtList(pstmt, stmt); //for extracting and replacing by SAVE without list
|
|
continue;
|
|
}
|
|
// deleting SAVE-attribute from Type Declaration Statement (for replacing by SAVE without list)
|
|
if(IN_MAIN_PROGRAM && isSgVarDeclStmt(stmt))
|
|
DeleteSaveAttribute(stmt);
|
|
|
|
if(IN_MODULE && stmt->variant() == PRIVATE_STMT && !stmt->expr(0))
|
|
privateall = 1;
|
|
|
|
// deleting distributed arrays from variable list of declaration
|
|
// statement and testing are there any group names
|
|
if( isSgVarDeclStmt(stmt) || isSgVarListDeclStmt(stmt)) {
|
|
|
|
if( !DeleteDArFromList(stmt) ) { //variable list is empty
|
|
stmt=stmt->lexPrev();
|
|
stmt->lexNext()->extractStmt(); //deleting the statement
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if((stmt->variant() == DATA_DECL) || (stmt->variant() == STMTFN_STAT)) {
|
|
if(stmt->variant() == STMTFN_STAT && stmt->expr(0) && stmt->expr(0)->symbol() && ((!strcmp(stmt->expr(0)->symbol()->identifier(),"number_of_processors")) || (!strcmp(stmt->expr(0)->symbol()->identifier(),"processors_rank")) || (!strcmp(stmt->expr(0)->symbol()->identifier(),"processors_size")))){
|
|
stmt=stmt->lexPrev();
|
|
stmt->lexNext()->extractStmt();
|
|
//deleting the statement-function declaration named
|
|
// NUMBER_OF_PROCESSORS or PROCESSORS_RANK or PROCESSORS_SIZE
|
|
continue;
|
|
}
|
|
if(stmt->variant()==STMTFN_STAT)
|
|
DECL(stmt->expr(0)->symbol()) = 2; //flag of statement function name
|
|
|
|
if(!data_stf)
|
|
data_stf = stmt; //first statement in data-or-function statement part
|
|
continue;
|
|
}
|
|
if (stmt->variant() == ENTRY_STAT) {
|
|
//err("ENTRY statement is not permitted in FDVM", stmt);
|
|
warn("ENTRY among specification statements", 81,stmt);
|
|
continue;
|
|
}
|
|
if(stmt->variant() == INTERFACE_STMT || stmt->variant() == INTERFACE_ASSIGNMENT || stmt->variant() == INTERFACE_OPERATOR){
|
|
stmt = InterfaceBlock(stmt); //stmt->lastNodeOfStmt();
|
|
continue;
|
|
}
|
|
|
|
if( stmt->variant() == USE_STMT) {
|
|
all_replicated=0;
|
|
if(stmt->lexPrev() != func && stmt->lexPrev()->variant()!=USE_STMT)
|
|
err("Misplaced USE statement", 639, stmt);
|
|
UpdateUseListWithDvmArrays(stmt);
|
|
continue;
|
|
}
|
|
|
|
if(stmt->variant() == STRUCT_DECL){
|
|
StructureProcessing(stmt);
|
|
stmt=stmt->lastNodeOfStmt();
|
|
continue;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
if ((stmt->variant() == FORMAT_STAT)) // || (stmt->variant() == DATA_DECL))
|
|
{// printf(" ");
|
|
// printVariantName(stmt->variant()); //for debug
|
|
//printf("\n");
|
|
continue;
|
|
}
|
|
|
|
|
|
// processing the DVM Specification Directives
|
|
|
|
//including the DVM specification directive to list of these directives
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
|
|
switch(stmt->variant()) {
|
|
case(ACC_ROUTINE_DIR):
|
|
ACC_ROUTINE_Directive(stmt);
|
|
continue;
|
|
case(HPF_TEMPLATE_STAT):
|
|
if(IN_MODULE && stmt->expr(1))
|
|
err("Illegal directive in module",632,stmt);
|
|
TemplateDeclarationTest(stmt);
|
|
continue;
|
|
case(HPF_PROCESSORS_STAT):
|
|
//!!!for debug
|
|
// printf("CDVM$ ");
|
|
// printVariantName(stmt->variant());
|
|
// printf("\n");
|
|
//
|
|
continue;
|
|
case(DVM_DYNAMIC_DIR):
|
|
{SgExpression *el;
|
|
SgSymbol *ar;
|
|
for(el = stmt->expr(0); el; el=el->rhs()){ // array name list
|
|
ar = el->lhs()->symbol(); //array name
|
|
//if(!(ar->attributes() & ALIGN_BIT) && !(ar->attributes() & DISTRIBUTE_BIT) && !(ar->attributes() & INHERIT_BIT))
|
|
// SYMB_ATTR(ar->thesymb)= SYMB_ATTR(ar->thesymb) | POSTPONE_BIT;
|
|
}
|
|
all_replicated = 0;
|
|
}
|
|
continue;
|
|
case(DVM_SHADOW_DIR):
|
|
{SgExpression *el;
|
|
SgExpression **she = new (SgExpression *);
|
|
SgSymbol *ar;
|
|
int nw=0;
|
|
// calculate lengh of shadow_list
|
|
for(el = stmt->expr(1); el; el=el->rhs())
|
|
nw++;
|
|
*she = stmt->expr(1);
|
|
for(el = stmt->expr(0); el; el=el->rhs()){ // array name list
|
|
ar = el->lhs()->symbol(); //array name
|
|
ar->addAttribute(SHADOW_WIDTH, (void *) she, sizeof(SgExpression *));
|
|
/* if(nw<Rank(ar))
|
|
Warning("Length of shadow-spec-list is smaller than the rank of array '%s'", ar->identifier(), stmt);
|
|
*/
|
|
if (nw!=Rank(ar)) // wrong shadow width list
|
|
Error("Length of shadow-edge-list is not equal to the rank of array '%s'", ar->identifier(), 88, stmt);
|
|
}
|
|
}
|
|
//!!!for debug
|
|
//printf("CDVM$ ");
|
|
//printVariantName(stmt->variant());
|
|
// printf("\n");
|
|
//
|
|
continue;
|
|
|
|
case(DVM_TASK_DIR):
|
|
{SgExpression * sl;
|
|
for(sl=stmt->expr(0); sl; sl = sl->rhs())
|
|
task_symb=AddToSymbList(task_symb, sl->lhs()->symbol());
|
|
}
|
|
continue;
|
|
|
|
case(DVM_CONSISTENT_DIR):
|
|
{SgExpression * sl;
|
|
for(sl=stmt->expr(0); sl; sl = sl->rhs()) {
|
|
SgSymbol **header = new (SgSymbol *);
|
|
consistent_symb=AddToSymbList(consistent_symb, sl->lhs()->symbol());
|
|
*header= CreateConsistentHeaderSymb(sl->lhs()->symbol());
|
|
// adding the attribute (CONSISTENT_ARRAY_HEADER) to distributed array symbol
|
|
sl->lhs()->symbol()->addAttribute(CONSISTENT_ARRAY_HEADER, (void*) header, sizeof(SgSymbol *));
|
|
}
|
|
}
|
|
continue;
|
|
|
|
case(DVM_INDIRECT_GROUP_DIR):
|
|
case(DVM_REMOTE_GROUP_DIR):
|
|
{SgExpression * sl;
|
|
if(options.isOn(NO_REMOTE))
|
|
continue;
|
|
if(INTERFACE_RTS2)
|
|
err("Illegal directive in -Opl2 mode. Asynchronous operations are not supported in this mode", 649, stmt);
|
|
for(sl=stmt->expr(0); sl; sl = sl->rhs()){
|
|
SgArrayType *artype;
|
|
artype = new SgArrayType(*SgTypeInt());
|
|
artype->addRange(*new SgValueExp(3));
|
|
sl->lhs()->symbol()->setType(artype);
|
|
AddToGroupNameList(sl->lhs()->symbol());
|
|
}
|
|
}
|
|
continue;
|
|
|
|
case DVM_CONSISTENT_GROUP_DIR:
|
|
case DVM_REDUCTION_GROUP_DIR:
|
|
if(INTERFACE_RTS2)
|
|
err("Illegal directive in -Opl2 mode. Asynchronous operations are not supported in this mode", 649, stmt);
|
|
{SgExpression * sl;
|
|
for(sl=stmt->expr(0); sl; sl = sl->rhs())
|
|
AddToGroupNameList(sl->lhs()->symbol());
|
|
}
|
|
continue;
|
|
|
|
case(DVM_INHERIT_DIR):
|
|
{SgExpression * sl;
|
|
inherit_is = 1; all_replicated = 0;
|
|
for(sl=stmt->expr(0); sl; sl = sl->rhs()){
|
|
if(IS_DUMMY(sl->lhs()->symbol()))
|
|
ArrayHeader(sl->lhs()->symbol(),1);
|
|
else
|
|
Error("Inconsistent declaration of identifier '%s'",sl->lhs()->symbol()->identifier(),16,stmt);
|
|
}
|
|
}
|
|
continue;
|
|
|
|
ALIGN:
|
|
case(DVM_ALIGN_DIR): // adding the alignees and the align_base to
|
|
// the Align_Tree_List
|
|
{ SgSymbol *base, *alignee;
|
|
SgExpression *eal;
|
|
algn_attr *attr_base, *attr_alignee;
|
|
//dvm = 1;
|
|
attr_base = attr_alignee = NULL;
|
|
if(stmt->expr(2)){
|
|
base = (stmt->expr(2)->variant()==ARRAY_OP) ? (stmt->expr(2))->rhs()->symbol() : (stmt->expr(2))->symbol();
|
|
// align_base symbol
|
|
attr_base = (algn_attr *) base->attributeValue(0,ALIGN_TREE);
|
|
}
|
|
else
|
|
base = NULL;
|
|
for(eal=stmt->expr(0); eal; eal=eal->rhs()) {
|
|
//scanning the alignees list
|
|
// (eal - SgExprListExp)
|
|
alignee = (eal->lhs())->symbol();
|
|
if(alignee->attributes() & EQUIVALENCE_BIT)
|
|
Error("DVM-array cannot be specified in EQUIVALENCE statement: %s", alignee->identifier(),341,stmt);
|
|
if(alignee == base)
|
|
{ Error("'%s' is aligned with itself", alignee->identifier(), 266,stmt);
|
|
continue;
|
|
}
|
|
if(stmt->expr(1) && IN_MODULE && IS_ALLOCATABLE_POINTER(alignee))
|
|
Error("Inconsistent declaration of identifier '%s'", alignee->identifier(), 16,stmt);
|
|
attr_alignee=(algn_attr *) alignee->attributeValue(0,ALIGN_TREE);
|
|
if(stmt->expr(2) && (stmt->expr(2)->variant()==ARRAY_OP) && !IS_DUMMY(alignee))
|
|
Error("Inconsistent declaration of identifier '%s'", alignee->identifier(), 16,stmt);
|
|
if(!stmt->expr(1) && ! stmt->expr(2)) {
|
|
SYMB_ATTR(alignee->thesymb)= SYMB_ATTR(alignee->thesymb) | POSTPONE_BIT;
|
|
if(!attr_alignee){
|
|
// creating new node for the alignee
|
|
node = new align;
|
|
node->symb = alignee;
|
|
node->next = pal;
|
|
node->alignees = NULL;
|
|
node->align_stmt = stmt;
|
|
pal = node;
|
|
// adding the attribute (ALIGN_TREE) to the alignee symbol
|
|
attr_alignee = new algn_attr;
|
|
attr_alignee->type = NODE;
|
|
attr_alignee->ref = node;
|
|
alignee->addAttribute(ALIGN_TREE, (void *) attr_alignee, sizeof(algn_attr));
|
|
} else
|
|
if(attr_alignee->type == NODE) {
|
|
Err_g("Duplicate aligning of the array '%s'",alignee->identifier(),82);
|
|
continue;
|
|
}
|
|
node= attr_alignee->ref;
|
|
node->align_stmt = stmt;
|
|
continue;
|
|
|
|
}
|
|
if (!pal || (!attr_base && !attr_alignee)) {
|
|
// creating new tree with root for align_base
|
|
node = new align; // creating new node for the alignee
|
|
node->symb = alignee;
|
|
node->next = NULL;
|
|
node->alignees = NULL;
|
|
node->align_stmt = stmt;
|
|
root = new align; // creating new node for the base (root)
|
|
root->symb = base;
|
|
root->next = pal;
|
|
root->alignees = node;
|
|
root->align_stmt = NULL;
|
|
pal = root; // pal points to this tree
|
|
|
|
// adding the attribute (ALIGN_TREE) to the base symbol
|
|
attr_base = new algn_attr;
|
|
attr_base->type = ROOT;
|
|
attr_base->ref = root;
|
|
base->addAttribute(ALIGN_TREE, (void *) attr_base, sizeof(algn_attr));
|
|
//for debug
|
|
//printf("Attribute ALIGN_TREE of %s : type = %d\n", base->identifier(), ((algn_attr*) base->attributeValue(0,ALIGN_TREE))->type);
|
|
// adding the attribute (ALIGN_TREE) to the alignee symbol
|
|
attr_alignee = new algn_attr;
|
|
attr_alignee->type = NODE;
|
|
attr_alignee->ref = node;
|
|
alignee->addAttribute(ALIGN_TREE, (void *) attr_alignee, sizeof(algn_attr));
|
|
//for debug
|
|
//printf("Attribute ALIGN_TREE of %s : type = %d\n", alignee->identifier(), ((algn_attr*) alignee->attributeValue(0,ALIGN_TREE))->type);
|
|
}
|
|
else if (!attr_alignee && attr_base) {
|
|
// creating new node for the alignee and
|
|
// adding it to alignees_list of the node for align_base
|
|
root = ((algn_attr*) base->attributeValue(0,ALIGN_TREE))->ref;
|
|
node = new align; // creating new node for the alignee
|
|
node->symb = alignee;
|
|
node->next = root->alignees;
|
|
node->alignees = NULL;
|
|
node->align_stmt = stmt;
|
|
root->alignees = node; // adding it to alignees_list of
|
|
// the node for align_base
|
|
// adding the attribute (ALIGN_TREE) to the alignee symbol
|
|
attr_alignee = new algn_attr;
|
|
attr_alignee->type = NODE;
|
|
attr_alignee->ref = node;
|
|
alignee->addAttribute(ALIGN_TREE, (void *) attr_alignee, sizeof(algn_attr));
|
|
//for debug
|
|
//printf("Attribute ALIGN_TREE of %s : type = %d\n", alignee->identifier(), ((algn_attr*) alignee->attributeValue(0,ALIGN_TREE))->type);
|
|
}
|
|
else if (attr_alignee && !attr_base) {
|
|
|
|
if(attr_alignee->type == NODE) {
|
|
Err_g("Duplicate aligning of the array '%s'", alignee->identifier(),82);
|
|
continue;
|
|
}
|
|
// creating new node for align_base,
|
|
// adding a tree for the alignee to alignees_list of it
|
|
|
|
node=((algn_attr*) alignee->attributeValue(0,ALIGN_TREE))->ref;
|
|
// deleting tree for the alignee from Align_Tree_List
|
|
if (pal == node)
|
|
pal = node->next;
|
|
else
|
|
for(root=pal ; root->next != node; root=root->next)
|
|
;
|
|
root->next = node->next;
|
|
|
|
root = new align; // creating new node for the base (root)
|
|
root->symb = base;
|
|
root->next = pal;
|
|
root->alignees = node;
|
|
root->align_stmt = NULL;
|
|
node->align_stmt = stmt; // setting the field 'align_stmt'
|
|
// of the node for alignee
|
|
node->next = NULL; // setting off 'next' field of the node
|
|
//for alignee
|
|
pal = root; // pal points to new tree
|
|
// adding the attribute (ALIGN_TREE) to the base symbol
|
|
attr_base = new algn_attr;
|
|
attr_base->type = ROOT;
|
|
attr_base->ref = root;
|
|
base->addAttribute(ALIGN_TREE, (void *) attr_base, sizeof(algn_attr));
|
|
//for debug
|
|
//printf("Attribute ALIGN_TREE of %s : type = %d\n", base->identifier(), ((algn_attr*) base->attributeValue(0,ALIGN_TREE))->type);
|
|
// changing field 'type'of the attribute (ALIGN_TREE)
|
|
// of the alignee symbol
|
|
attr_alignee->type = NODE;
|
|
//for debug
|
|
//printf("Attribute ALIGN_TREE of %s : type = %d\n", alignee->identifier(), ((algn_attr*) alignee->attributeValue(0,ALIGN_TREE))->type);
|
|
|
|
}
|
|
else if (attr_alignee && attr_base) {
|
|
|
|
if(attr_alignee->type == NODE) {
|
|
Err_g("Duplicate aligning of the array '%s'", alignee->identifier(),82);
|
|
continue;
|
|
}
|
|
//testing: is a node for align_base the node of alignee tree
|
|
// ...
|
|
// adding a tree for the alignee to alignees_list
|
|
// of the node for align_base
|
|
node=((algn_attr*) alignee->attributeValue(0,ALIGN_TREE))->ref;
|
|
// deleting tree for the alignee from Align_Tree_List
|
|
if (pal == node)
|
|
pal = node->next;
|
|
else
|
|
for(root=pal ; root->next != node; root=root->next)
|
|
;
|
|
root->next = node->next;
|
|
|
|
root = ((algn_attr*) base->attributeValue(0,ALIGN_TREE))->ref;
|
|
node->align_stmt = stmt;
|
|
node->next = root->alignees;
|
|
root->alignees = node;
|
|
|
|
// changing field 'type'of the attribute (ALIGN_TREE)
|
|
// of the alignee symbol
|
|
attr_alignee->type = NODE;
|
|
//for debug
|
|
//printf("Attribute ALIGN_TREE of %s : type = %d\n", alignee->identifier(), ((algn_attr*) alignee->attributeValue(0,ALIGN_TREE))->type);
|
|
}
|
|
|
|
}
|
|
}
|
|
//!!!for debug
|
|
//printf("CDVM$ ");
|
|
//printVariantName(stmt->variant());
|
|
//printf("\n");
|
|
//
|
|
continue;
|
|
|
|
DISTR:
|
|
case(DVM_DISTRIBUTE_DIR): // adding the statement to the Distribute
|
|
// directive list
|
|
//dvm = 1;
|
|
if (!distr) {
|
|
distr = new distribute_list;
|
|
distr->stdis = stmt;
|
|
distr->next = NULL;
|
|
distr_last = distr;
|
|
} else {
|
|
dsl = new distribute_list;
|
|
dsl->stdis = stmt;
|
|
dsl->next = NULL;
|
|
distr_last->next = dsl;
|
|
distr_last = dsl;
|
|
}
|
|
//!!!for debug
|
|
//printf("CDVM$ ");
|
|
//printVariantName(stmt->variant());
|
|
//printf("\n");
|
|
//
|
|
DistributeArrayList(stmt); //adding the attribute DISTRIBUTE_ to distribute-array symbol
|
|
continue;
|
|
case(DVM_POINTER_DIR):
|
|
{SgExpression *el;
|
|
SgStatement **pst = new (SgStatement *);
|
|
|
|
SgSymbol *sym;
|
|
int *index;
|
|
*pst = stmt;
|
|
for(el = stmt->expr(0); el; el=el->rhs()){ // name list
|
|
sym = el->lhs()->symbol(); // name
|
|
sym->addAttribute(POINTER_, (void *) pst, sizeof(SgStatement *));
|
|
if((sym->type()->variant() != T_INT) && (sym->type()->variant() != T_ARRAY))
|
|
Error("POINTER '%s' is not integer variable",sym->identifier(),83,stmt);
|
|
if( (sym->type()->variant() == T_ARRAY) && (sym->type()->baseType()->variant() != T_INT))
|
|
Error("POINTER '%s' is not integer variable",sym->identifier(),83,stmt);
|
|
//if(IS_DUMMY(sym) || IN_COMMON(sym))
|
|
if(IS_DUMMY(sym))
|
|
Error("Inconsistent declaration of identifier '%s' ",sym->identifier(),16,stmt);
|
|
if(IS_SAVE(sym))
|
|
Error("POINTER may not have SAVE attribute: %s",sym->identifier(),84,stmt);
|
|
/*
|
|
if(!IS_DVM_ARRAY(sym))
|
|
Error("POINTER '%s' is not distributed object",sym->identifier(), 85,stmt);
|
|
*/
|
|
if(!IS_DVM_ARRAY(sym))
|
|
// AddDistSymbList(sym);
|
|
ArrayHeader(sym,0);
|
|
index = new int;
|
|
*index = heap_size+1;
|
|
// adding the attribute (HEAP_INDEX) to POINTER symbol
|
|
sym->addAttribute(HEAP_INDEX, (void *) index, sizeof(int));
|
|
heap_size = heap_size + HEADER_SIZE(sym)*NumberOfElements(sym,stmt,1);
|
|
}
|
|
}
|
|
//!!!for debug
|
|
//printf("CDVM$ ");
|
|
//printVariantName(stmt->variant());
|
|
// printf("\n");
|
|
//
|
|
continue;
|
|
|
|
case (DVM_HEAP_DIR):
|
|
heap_ar_decl = new SgArrayRefExp(*heapdvm);
|
|
continue;
|
|
|
|
case (DVM_ASYNCID_DIR):
|
|
{SgExpression * sl;
|
|
SgArrayType *artype;
|
|
for(sl=stmt->expr(0); sl; sl = sl->rhs()) {
|
|
artype = new SgArrayType(*SgTypeInt());
|
|
artype->addRange(*new SgValueExp(ASYNCID_NUMB));
|
|
if(sl->lhs()->lhs()) //array specification
|
|
artype->addRange(*(sl->lhs()->lhs()));
|
|
sl->lhs()->symbol()->setType(artype);
|
|
async_symb=AddToSymbList(async_symb, sl->lhs()->symbol());
|
|
if(stmt->expr(1)) // ASYNCID,COMMON:: name-list
|
|
SYMB_ATTR(sl->lhs()->symbol()->thesymb)= SYMB_ATTR(sl->lhs()->symbol()->thesymb) | COMMON_BIT;
|
|
}
|
|
}
|
|
continue;
|
|
|
|
case (DVM_VAR_DECL):
|
|
{ SgExpression *el,*eol,*eda;
|
|
SgSymbol *symb;
|
|
int i, nattrs[8];
|
|
for(i=0; i<8; i++)
|
|
nattrs[i] = 0;
|
|
eda = NULL;
|
|
//testing obgect list
|
|
isListOfArrays(stmt->expr(0),stmt);
|
|
|
|
for(el = stmt->expr(2); el; el=el->rhs()) // attribute list
|
|
switch(el->lhs()->variant()) {
|
|
case (ALIGN_OP):
|
|
nattrs[0]++;
|
|
eda = el->lhs();
|
|
break;
|
|
case (DISTRIBUTE_OP):
|
|
nattrs[1]++;
|
|
eda = el->lhs();
|
|
break;
|
|
case (TEMPLATE_OP):
|
|
nattrs[2]++;
|
|
TemplateDeclarationTest(stmt);
|
|
break;
|
|
case (PROCESSORS_OP):
|
|
nattrs[3]++;
|
|
break;
|
|
case (DIMENSION_OP):
|
|
nattrs[4]++;
|
|
for(eol=stmt->expr(0); eol; eol=eol->rhs()) { //testing object list
|
|
symb=eol->lhs()->symbol();
|
|
if(!( (symb->attributes() & TEMPLATE_BIT) || (symb->attributes() & PROCESSORS_BIT)))
|
|
Error("Object '%s' has neither TEMPLATE nor PROCESSORS attribute",symb->identifier(), 86,stmt);
|
|
}
|
|
//testing shape specification (el->lhs()->lhs()) : each expression is specification expression
|
|
if((el->lhs()->lhs()) && (! TestShapeSpec(el->lhs()->lhs())))
|
|
err("Illegal shape specification in DIMENSION attribute",87,stmt);
|
|
break;
|
|
case (DYNAMIC_OP):
|
|
nattrs[5]++;
|
|
break;
|
|
case (SHADOW_OP):
|
|
{SgExpression *eln;
|
|
SgExpression **she = new (SgExpression *);
|
|
SgSymbol *ar;
|
|
int nw=0;
|
|
|
|
nattrs[6]++;
|
|
|
|
// calculate lengh of shadow_list
|
|
for(eln = el->lhs()->lhs() ; eln; eln=eln->rhs())
|
|
nw++;
|
|
*she = el->lhs()->lhs(); //shadow specification
|
|
for(eln = stmt->expr(0); eln; eln=eln->rhs()){ // array name list
|
|
ar = eln->lhs()->symbol(); //array name
|
|
ar->addAttribute(SHADOW_WIDTH, (void *) she, sizeof(SgExpression *));
|
|
/* if(nw<Rank(ar))
|
|
Warning("Length of shadow-spec-list is smaller than the rank of array '%s'", ar->identifier(), stmt);
|
|
*/
|
|
if (nw!=Rank(ar)) // wrong shadow width list
|
|
Error("Length of shadow-edge-list is not equal to the rank of array '%s'", ar->identifier(), 88,stmt);
|
|
}
|
|
break;
|
|
}
|
|
case (COMMON_OP):
|
|
nattrs[7]++;
|
|
break;
|
|
}
|
|
for(i=0; i<8; i++)
|
|
if( nattrs[i]>1)
|
|
Error("%s attribute appears more than once in the combined-directive", AttrName(i), 89, stmt);
|
|
if(eda)
|
|
if(eda->variant() == ALIGN_OP){
|
|
stmt->setVariant(DVM_ALIGN_DIR);
|
|
if(! eda->lhs())
|
|
BIF_LL2(stmt->thebif)= NULL;
|
|
else
|
|
BIF_LL2(stmt->thebif)= eda->lhs()->thellnd;
|
|
if(! eda->rhs())
|
|
BIF_LL3(stmt->thebif)= NULL;
|
|
else
|
|
BIF_LL3(stmt->thebif)= eda->rhs()->thellnd;
|
|
//stmt->setExpression(1,*eda->lhs());
|
|
//stmt->setExpression(2,*eda->rhs());
|
|
goto ALIGN;
|
|
}
|
|
else {
|
|
stmt->setVariant(DVM_DISTRIBUTE_DIR);
|
|
if(! eda->lhs())
|
|
BIF_LL2(stmt->thebif)=NULL;
|
|
else
|
|
BIF_LL2(stmt->thebif)= eda->lhs()->thellnd;
|
|
if(! eda->rhs())
|
|
BIF_LL3(stmt->thebif)= NULL;
|
|
else
|
|
BIF_LL3(stmt->thebif)= eda->rhs()->thellnd;
|
|
//stmt->setExpression(1,*eda->lhs());
|
|
//stmt->setExpression(2,*eda->rhs());
|
|
if( eda->symbol())
|
|
stmt->setSymbol(*eda->symbol());
|
|
goto DISTR;
|
|
}
|
|
}
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
// all declaration statements are processed,
|
|
// current statement is executable (F77/DVM)
|
|
|
|
break;
|
|
}
|
|
|
|
if(pstmt && (stmt != last))
|
|
pstmt = pstmt->next; //deleting first executable statement from
|
|
// DVM Specification Directive List
|
|
|
|
//**********************************************************************
|
|
// LibDVM References Generation
|
|
// for distributed and aligned arrays
|
|
//**********************************************************************
|
|
|
|
//TempVarDVM(func);
|
|
first_exec = stmt; // first executable statement
|
|
|
|
// testing procedure (-dbif2 regim)
|
|
if(debug_regim && dbg_if_regim>1 && ((func->variant() == PROC_HEDR) || (func->variant() == FUNC_HEDR)) && !pstmt && !isInternalOrModuleProcedure(func) && !lookForDVMdirectivesInBlock(first_exec,func->lastNodeOfStmt(),contains) && !contains[0] && !contains[1])
|
|
copy_proc = CreateCopyOfExecPartOfProcedure();
|
|
|
|
lab_exec = first_exec->label(); // store the label of first ececutable statement
|
|
BIF_LABEL(first_exec->thebif) = NULL;
|
|
last_spec = first_exec->lexPrev();//may be extracted after
|
|
where = first_exec; //before first executable statement will be inserted new statements
|
|
stam = NULL;
|
|
if(grname)
|
|
CreateRedGroupVars();
|
|
|
|
ndvm = 1; // ndvm is number of first free element of array "dvm000"
|
|
nhpf = 1; // nhpf is number of first free element of array "hpf000"
|
|
|
|
//generating "dummy" assign statement (always it is deleted)
|
|
// dvm000(1) = fname(file_name)
|
|
//function 'fname' tells the name of source file to DVM run-time system
|
|
InsertNewStatementBefore(D_Fname(),first_exec);
|
|
first_dvm_exec = last_spec->lexNext(); //first DVM function call
|
|
|
|
if(IN_MODULE){
|
|
if(TestDVMDirectivesInModule(pstmt) || TestUseStmts() || debug_regim) {
|
|
mod_proc = CreateModuleProcedure(cur_func,first_exec,has_contains);
|
|
where = mod_proc->lexNext();
|
|
end_of_unit = where;
|
|
} else {
|
|
first_dvm_exec = last_spec->lexNext();
|
|
goto EXEC_PART_;
|
|
}
|
|
}
|
|
|
|
if(HPF_program)
|
|
first_hpf_exec = first_dvm_exec;
|
|
|
|
if(func->variant() == PROG_HEDR) { // MAIN-program
|
|
//generating a call statement:
|
|
// call dvmlf(line_number_of_first_executable_statement,source-file-name)
|
|
LINE_NUMBER_BEFORE(first_exec,first_exec);
|
|
//generating function call ftcntr(...)
|
|
//function 'ftcntr' checks Fortran and C data type compatibility
|
|
TypeControl_New();
|
|
//generating the function call which initializes the control structures of DVM run-time system,
|
|
// it's inserted in MAIN program)
|
|
// dvm000(1) = <flag>
|
|
// call dvmh_init(dvm000(1))
|
|
dvmh_init_st = RTL_GPU_Init();
|
|
if(!task_symb) // !!! added the condition temporarily
|
|
{
|
|
BeginBlock_H();
|
|
begin_block = 1;
|
|
begbl = cur_st;
|
|
}
|
|
if(dbg_if_regim)
|
|
InitDebugVar();
|
|
}
|
|
|
|
else if(func->variant() == MODULE_STMT) // Module
|
|
ndvm++;
|
|
else
|
|
// generating assign statement
|
|
// dvm000(1) = BegBl()
|
|
// ( function BegBl defines the begin of object localisation block)
|
|
if(distr || task_symb || TestDVMDirectivesInProcedure(pstmt)) {
|
|
BeginBlock_H();
|
|
begin_block = 1;
|
|
begbl = cur_st;
|
|
}
|
|
else
|
|
ndvm++;
|
|
|
|
//generating assign statement
|
|
// dvm000(2) = GetAM()
|
|
//(function GetAM creates initial abstract machine)
|
|
//and assign statement
|
|
// dvm000(3) = GetPS(AMRef)
|
|
//(function GetPS returns virtual machine reference, on what abstract
|
|
// machine is mapped)
|
|
stam = NULL;
|
|
|
|
ndvm = 4; // 3 first elements are reserved
|
|
|
|
//generating call (module procedure) and/or assign statements for USE statements
|
|
GenForUseStmts(func,where);
|
|
|
|
//Creating (reconfiguring) processor systems
|
|
ReconfPS(pstmt);
|
|
|
|
//Creating task arrays
|
|
if(task_symb){
|
|
symb_list *tl;
|
|
for(tl=task_symb; tl; tl=tl->next) ///looking through the task symbol list
|
|
CreateTaskArray(tl->symb);
|
|
}
|
|
//Initializing groups
|
|
if(grname && !IN_MODULE)
|
|
InitGroups();
|
|
|
|
//Initializing HEAP counter
|
|
if(heap_size != 0 ) //there are declared POINTER variables
|
|
if( !heap_ar_decl )
|
|
Err_g("Missing %s declaration", "HEAP", 91);
|
|
// else
|
|
//generating assign statement: HEAP(1) = 2
|
|
// InitHeap(heap_ar_decl->symbol());
|
|
//Initializing ASYNCID counter
|
|
if(!IN_MODULE)
|
|
//if(IN_MAIN_PROGRAM) // (27.01.05)
|
|
InitAsyncid();
|
|
//Creating CONSISTENT arrays
|
|
/* if(consistent_symb){
|
|
symb_list *cl;
|
|
for(cl=consistent_symb; cl; cl=cl->next) ///looking through the consistent array symbol list
|
|
CreateConsistentArray(cl->symb);
|
|
}*/
|
|
//Looking through the Distibute Directive List
|
|
for(dsl=distr; dsl; dsl=dsl->next) {
|
|
SgExpression *target,*ps = NULL;
|
|
int idis; // DisRuleArray index
|
|
SgSymbol *das;
|
|
int no_rules;
|
|
no_rules = 1;
|
|
for(e=dsl->stdis->expr(0); e; e=e->rhs()){//are there in dist-name-list array-name
|
|
//that is not a dummy, a pointer, and
|
|
//a COMMON-block element in procedure
|
|
das = (e->lhs())->symbol();
|
|
if( !IS_DUMMY(das) && !IS_POINTER(das) && !(IN_COMMON(das) && (das->scope()->variant() != PROG_HEDR)) && !IS_ALLOCATABLE_POINTER(das)){
|
|
no_rules = 0; ps = NULL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
SgExpression *distr_rule_list = doDisRules(dsl->stdis,no_rules,idis);
|
|
nproc = 0;
|
|
target = hasOntoClause(dsl->stdis);
|
|
if( target ) { //is there ONTO_clause
|
|
nproc = RankOfSection(target);
|
|
if(dsl->stdis->expr(1) && nblock && nproc && (nblock > nproc))
|
|
Error("The number of BLOCK/GENBLOCK elements of dist-format-list is greater than the rank of PROCESSORS '%s' ", target->symbol()->identifier(),90,dsl->stdis);
|
|
}
|
|
/* if(dsl->stdis->expr(1) && nblock && (nblock != nblock_all))
|
|
err("The number of BLOCK elements of dist-format-list must be the same in all DISTRIBUTE and REDISTRIBUTE directives", dsl->stdis);*/
|
|
|
|
if(!no_rules)
|
|
ps = PSReference(dsl->stdis);
|
|
|
|
//looking through the dist_name_list
|
|
for(e=dsl->stdis->expr(0); e; e=e->rhs()) {
|
|
das = (e->lhs())->symbol(); // distribute array symbol
|
|
/* if(dsl->stdis->expr(2) && !IS_DUMMY(das))
|
|
Error("'%s' is not a dummy argument", das->identifier(),dsl->stdis);
|
|
*/
|
|
int is_global_template_in_procedure = IS_TEMPLATE(das) && IN_COMMON(das) && !IN_MAIN_PROGRAM;
|
|
if(!dsl->stdis->expr(1) && !is_global_template_in_procedure)
|
|
SYMB_ATTR(das->thesymb)= SYMB_ATTR(das->thesymb) | POSTPONE_BIT;
|
|
/*if(IS_POINTER(das) && (das->attributes() & DIMENSION_BIT))
|
|
Error("Distributee '%s' with POINTER attribute is not a scalar variable", das->identifier(),dsl->stdis);
|
|
*/
|
|
|
|
// creating LibDVM function calls for distributed array and its Align Tree
|
|
|
|
//GenDistArray(das,idis,dis_rules,ps,dsl->stdis);
|
|
GenDistArray(das,idis,distr_rule_list,ps,dsl->stdis);
|
|
}
|
|
|
|
}
|
|
|
|
//Looking through the Align Tree List
|
|
for(root=pal; root; root=root->next) {
|
|
if(!( root->symb->attributes() & DISTRIBUTE_BIT) && !( root->symb->attributes() & ALIGN_BIT) && !( root->symb->attributes() & INHERIT_BIT) && !( root->symb->attributes() & POSTPONE_BIT))
|
|
Err_g("Alignment tree root '%s' is not distributed", root->symb->identifier(),92);
|
|
if(( root->symb->attributes() & POSTPONE_BIT) && !( root->symb->attributes() & DISTRIBUTE_BIT) && CURRENT_SCOPE(root->symb) ) {
|
|
GenAlignArray(root,NULL,0,NULL,0);
|
|
AlignTree(root);
|
|
}
|
|
if( (root->symb->attributes() & INHERIT_BIT) || !CURRENT_SCOPE(root->symb) )
|
|
AlignTree(root);
|
|
|
|
}
|
|
|
|
if(debug_regim && registration) { // registrating arrays for debugger
|
|
LINE_NUMBER_BEFORE(func,where); //(first_exec,where);
|
|
ArrayRegistration();
|
|
}
|
|
// testing procedure
|
|
// if(dvm_debug && dbg_if_regim>1 && ((func->variant() == PROC_HEDR) || (func->variant() == FUNC_HEDR)) && !pstmt)// && !hasParallelDir(first_exec,func))
|
|
// copy_proc=1;
|
|
for(;pstmt; pstmt= pstmt->next)
|
|
Extract_Stmt(pstmt->st);// extracting DVM Specification Directives
|
|
|
|
if(!loc_distr && !task_symb && !proc_symb && !IN_MAIN_PROGRAM) {
|
|
//there are no local distributed arrays
|
|
//no task array , no asinc and no processor array
|
|
if(begin_block){
|
|
begbl->extractStmt(); //extract dvmh_scope_start /*begbl()*/ call
|
|
begin_block = 0;
|
|
fmask[SCOPE_START] = 0; //fmask[BEGBL] = 0;
|
|
}
|
|
if(!loc_templ_symb && stam) {
|
|
stam->lexNext()->extractStmt(); //extract getps() call
|
|
stam->extractStmt(); //extract getam() call
|
|
fmask[GETAM] = 0; fmask[GETVM] = 0;
|
|
}
|
|
}
|
|
|
|
if(begin_block && !IN_MAIN_PROGRAM) {
|
|
LINE_NUMBER_BEFORE(first_exec,begbl);
|
|
}
|
|
|
|
if(lab_exec)
|
|
first_exec-> setLabel(*lab_exec); //restore label of first executable statement
|
|
|
|
last_dvm_entry = first_exec->lexPrev();
|
|
|
|
if(copy_proc)
|
|
InsertCopyOfExecPartOfProcedure(copy_proc);
|
|
|
|
//**********************************************************************
|
|
// Executable Directives Processing
|
|
//**********************************************************************
|
|
|
|
EXEC_PART_:
|
|
for (i=0; i<Ntp; i++)
|
|
buf_use[i] = rmbuf_size[i]= 0;
|
|
IOstat = NULL;
|
|
inparloop = 0;
|
|
inasynchr = 0;
|
|
own_exe = 0;
|
|
redvar_list = NULL;
|
|
rma =NULL;
|
|
in_task_region = 0;
|
|
task_ind = 0;
|
|
in_task=0;
|
|
task_lab = NULL;
|
|
dvm_ar= NULL;
|
|
|
|
if(IN_MODULE) {
|
|
if(!mod_proc && first_exec->variant() == CONTAINS_STMT)
|
|
end_of_unit = has_contains = first_exec;
|
|
//else if(mod_proc)
|
|
// mod_proc = MayBeDeleteModuleProc(mod_proc,end_of_unit);
|
|
goto END_;
|
|
}
|
|
|
|
//follow the executable statements in lexical order until last statement
|
|
// of the function
|
|
for(stmt=first_exec; stmt ; stmt=stmt->lexNext()) {
|
|
cur_st = stmt; //printf("executable statement %d %s\n",stmt->lineNumber(),stmt->fileName());
|
|
|
|
while(rma && rma->rmout == stmt)//current statement is out of scope REMOTE_ACCESS directive
|
|
RemoteAccessEnd();
|
|
|
|
if(isACCdirective(stmt)) /*ACC*/
|
|
{ pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = ACC_Directive(stmt);
|
|
continue;
|
|
}
|
|
|
|
if(IN_COMPUTE_REGION && IN_STATEMENT_GROUP(stmt)) /*ACC*/
|
|
{
|
|
stmt = ACC_CreateStatementGroup(stmt);
|
|
continue;
|
|
}
|
|
switch(stmt->variant()) {
|
|
case CONTROL_END:
|
|
if(stmt == last) {
|
|
EndOfProgramUnit(stmt, func, begin_block);
|
|
goto END_;
|
|
}
|
|
break;
|
|
|
|
case CONTAINS_STMT:
|
|
has_contains = end_of_unit = stmt;
|
|
EndOfProgramUnit(stmt, func, begin_block);
|
|
goto END_;
|
|
break;
|
|
case RETURN_STAT:
|
|
EndOfProgramUnit(stmt, func, begin_block);
|
|
if(dvm_debug || perf_analysis )
|
|
{ // RETURN statement is added to list for debugging (exit the loop)
|
|
goto_list = addToStmtList(goto_list, stmt);
|
|
if(begin_block)
|
|
AddDebugGotoAttribute(stmt,stmt->lexPrev()->lexPrev()); //to insert statements for debugging before call endbl() inserted before RETURN
|
|
}
|
|
if(stmt->lexNext() == last)
|
|
goto END_;
|
|
if(stmt->lexNext()->variant() == CONTAINS_STMT){
|
|
has_contains = end_of_unit = stmt->lexNext();
|
|
goto END_;
|
|
}
|
|
break;
|
|
case STOP_STAT:
|
|
if(begin_block && func->variant() != PROG_HEDR)
|
|
EndBlock_H(stmt);
|
|
if(stmt->expr(0)){
|
|
SgStatement *print_st;
|
|
InsertNewStatementBefore(print_st=PrintStat(stmt->expr(0)),stmt);
|
|
ReplaceByIfStmt(print_st);
|
|
}
|
|
RTLExit(stmt);
|
|
if(stmt->lexNext() == last)
|
|
goto END_;
|
|
break;
|
|
case PAUSE_NODE:
|
|
err("PAUSE statement is not permitted in FDVM", 93,stmt);
|
|
break;
|
|
case EXIT_STMT:
|
|
//if(dvm_debug || perf_analysis )
|
|
// EXIT statement is added to list for debugging (exit the loop)
|
|
//goto_list = addToStmtList(goto_list, stmt);
|
|
break;
|
|
case ENTRY_STAT:
|
|
if(distr) {
|
|
warn("ENTRY of program unit distributed arrays are in",169,stmt);
|
|
// err("ENTRY statement is not permitted in FDVM", stmt);
|
|
}
|
|
GoRoundEntry(stmt);
|
|
//BeginBlockForEntry(stmt);
|
|
entry_list=addToStmtList(entry_list,stmt);
|
|
|
|
break;
|
|
|
|
case SWITCH_NODE: // SELECT CASE ...
|
|
case ARITHIF_NODE: // Arithmetical IF
|
|
case IF_NODE: // IF... THEN
|
|
case WHILE_NODE: // DO WHILE (...)
|
|
if(HPF_program && !inparloop){
|
|
first_time = 1;
|
|
SearchDistArrayRef(stmt->expr(0),stmt);
|
|
cur_st = stmt;
|
|
}
|
|
if(dvm_debug)
|
|
DebugExpression(stmt->expr(0),stmt);
|
|
else
|
|
ChangeDistArrayRef(stmt->expr(0));
|
|
|
|
if((dvm_debug || perf_analysis) && stmt->variant()==ARITHIF_NODE )
|
|
goto_list = addToStmtList(goto_list, stmt);
|
|
|
|
break;
|
|
|
|
case CASE_NODE: // CASE ...
|
|
case ELSEIF_NODE: // ELSE IF...
|
|
if(HPF_program && !inparloop){
|
|
first_time = 1;
|
|
SearchDistArrayRef(stmt->expr(0),stmt);
|
|
cur_st = stmt;
|
|
}
|
|
ChangeDistArrayRef(stmt->expr(0));
|
|
break;
|
|
|
|
case LOGIF_NODE: // Logical IF
|
|
if( !stmt->lineNumber()) {//inserted statement
|
|
stmt = stmt->lexNext();
|
|
break;
|
|
}
|
|
if(HPF_program) {
|
|
if(!inparloop){ //outside the range of parallel loop
|
|
ReplaceContext(stmt);
|
|
first_time = 1;
|
|
SearchDistArrayRef(stmt->expr(0),stmt); //look for distributed array elements
|
|
cur_st = stmt;
|
|
} else //inside the range of parallel loop
|
|
IsLIFReductionOp(stmt, indep_st->expr(0) ? indep_st->expr(0)->lhs() : indep_st->expr(0)); //look for reduction operator
|
|
}
|
|
if(dvm_debug) {
|
|
ReplaceContext(stmt);
|
|
DebugExpression(stmt->expr(0),stmt);
|
|
} else {
|
|
ChangeDistArrayRef(stmt->expr(0));
|
|
if(perf_analysis && IsGoToStatement(stmt->lexNext()))
|
|
ReplaceContext(stmt);
|
|
}
|
|
continue; // to next statement
|
|
|
|
|
|
case FORALL_STAT: // FORALL statement
|
|
{SgSymbol *do_var;
|
|
SgExpression *el,*ei,*etriplet,*ec;
|
|
el=stmt->expr(0); //list of loop indexes
|
|
for(el= stmt->expr(0); el; el=el->rhs()){
|
|
ei=el->lhs(); //expression: i=l:u:s
|
|
etriplet= ei->lhs();//l:u:s
|
|
do_var=ei->symbol();//do-variable
|
|
//printf("%s=",do_var->identifier());
|
|
|
|
//etriplet->unparsestdout();
|
|
//printf(" ");
|
|
}
|
|
ec=stmt->expr(1); // conditional expression
|
|
//ec->unparsestdout();
|
|
|
|
}
|
|
stmt=stmt->lexNext();// statement that is a part of FORALL statement
|
|
break;
|
|
// continue;
|
|
case GOTO_NODE: // GO TO
|
|
if((dvm_debug || perf_analysis) && stmt->lineNumber() )
|
|
goto_list = addToStmtList(goto_list, stmt);
|
|
break;
|
|
|
|
case COMGOTO_NODE: // Computed GO TO
|
|
if(HPF_program && !inparloop){
|
|
ReplaceContext(stmt);
|
|
first_time = 1;
|
|
SearchDistArrayRef(stmt->expr(1),stmt);
|
|
cur_st = stmt;
|
|
}
|
|
if(dvm_debug) {
|
|
ReplaceContext(stmt);
|
|
DebugExpression(stmt->expr(1),stmt);
|
|
} else
|
|
{ ChangeDistArrayRef(stmt->expr(1));
|
|
if (perf_analysis )
|
|
ReplaceContext(stmt);
|
|
}
|
|
if(dvm_debug || perf_analysis )
|
|
goto_list = addToStmtList(goto_list, stmt);
|
|
break;
|
|
|
|
case ASSIGN_STAT: // Assign statement
|
|
{ SgSymbol *s;
|
|
if(inasynchr && !INTERFACE_RTS2) { //inside the range of ASYNCHRONOUS construct
|
|
if(ArrayAssignment(stmt)) { //Fortran 90
|
|
AsynchronousCopy(stmt);
|
|
}
|
|
pstmt = addToStmtList(pstmt, stmt); // add to list of extracted statements
|
|
stmt=cur_st;
|
|
break;
|
|
}
|
|
if( !stmt->lineNumber()) //inserted debug statement
|
|
break;
|
|
|
|
if((s=stmt->expr(0)->symbol()) && IS_POINTER(s)){ // left part variable is POINTER
|
|
if(isSgFunctionCallExp(stmt->expr(1)) && !strcmp(stmt->expr(1)->symbol()->identifier(),"allocate")){
|
|
if(inparloop)
|
|
err("Illegal statement in the range of parallel loop", 94, stmt);
|
|
AllocateArray(stmt,distr);
|
|
if(stmt != cur_st){//stmt == cur_st in error situation
|
|
Extract_Stmt(stmt);
|
|
stmt=cur_st;
|
|
}
|
|
|
|
} else if( (isSgVarRefExp(stmt->expr(1)) || isSgArrayRefExp(stmt->expr(1))) && stmt->expr(1)->symbol() && IS_POINTER(stmt->expr(1)->symbol())) {
|
|
AssignPointer(stmt);
|
|
if(stmt != cur_st){
|
|
Extract_Stmt(stmt);
|
|
stmt=cur_st;
|
|
}
|
|
|
|
} else
|
|
err("Only a value of ALLOCATE function or other POINTER may be assigned to a POINTER",95,stmt);
|
|
|
|
break;
|
|
}
|
|
if(HPF_program){
|
|
if(!inparloop){ //outside the range of parallel loop
|
|
ReplaceContext(stmt);
|
|
first_time = 1;
|
|
SearchDistArrayRef(stmt->expr(1),stmt); //look for distributed array elements
|
|
cur_st = stmt;
|
|
} else //inside the range of parallel loop
|
|
IsReductionOp(stmt,indep_st->expr(0) ? indep_st->expr(0)->lhs() : indep_st->expr(0)); //look for reduction operator
|
|
}
|
|
/* if(own_exe) { // "owner executes" rule
|
|
ReplaceContext(stmt);
|
|
ReplaceAssignByIf(stmt);
|
|
} else */
|
|
if(!inparloop && isDistObject(stmt->expr(0))){
|
|
if( !isSgArrayType(stmt->expr(0)->type())){ //array element
|
|
if(all_replicated == 0){ // not all arrays in procedure are replicated
|
|
ReplaceContext(stmt);
|
|
|
|
|
|
if(!in_on) {
|
|
LINE_NUMBER_BEFORE(stmt,stmt);
|
|
ReplaceAssignByIf(stmt);
|
|
}
|
|
//own_exe = 1;
|
|
if(warn_all)
|
|
warn("Owner-computes rule", 139, stmt);
|
|
//warn("Assignment of distributed array element outside the range of parallel loop: owner executes", stmt);
|
|
}
|
|
own_exe = 1;
|
|
}
|
|
else { //array section
|
|
if(DistrArrayAssign(stmt)) {
|
|
pstmt = addToStmtList(pstmt, stmt); // add to list of extracted statements
|
|
stmt=cur_st;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!inparloop && AssignDistrArray(stmt)) {
|
|
pstmt = addToStmtList(pstmt, stmt); // add to list of extracted statements
|
|
stmt=cur_st;
|
|
break;
|
|
}
|
|
|
|
// if(inparloop && !TestLeftPart(new_red_var_list, stmt->expr(0)))
|
|
// Error("Illegal assignment in the range of parallel loop",stmt);
|
|
|
|
|
|
if(dvm_debug) {
|
|
SgStatement *where_st, *stmt1, *stparent;
|
|
where_st=stmt->lexNext();
|
|
ReplaceContext(stmt);
|
|
DebugAssignStatement(stmt);
|
|
|
|
if(own_exe && !in_on) { //declaring omitted block
|
|
where_st = where_st->lexPrev();
|
|
stmt1 = dbg_if_regim ? CreateIfThenConstr(DebugIfCondition(),D_Skpbl()) : D_Skpbl();
|
|
stparent = (all_replicated == 0) ? stmt->controlParent()->controlParent() : stmt->controlParent();
|
|
InsertNewStatementAfter(stmt1,where_st,stparent);
|
|
}
|
|
stmt = cur_st;
|
|
} else {
|
|
ChangeDistArrayRef_Left(stmt->expr(0)); // left part
|
|
ChangeDistArrayRef(stmt->expr(1)); // right part
|
|
}
|
|
own_exe =0;
|
|
}
|
|
break;
|
|
|
|
case PROC_STAT: // CALL
|
|
if( !stmt->lineNumber()) //inserted debug statement
|
|
break;
|
|
if(HPF_program && !inparloop){
|
|
ReplaceContext(stmt);
|
|
first_time = 1;
|
|
SearchDistArrayRef(stmt->expr(0),stmt);
|
|
cur_st = stmt;
|
|
}
|
|
if(dvm_debug){
|
|
ReplaceContext(stmt);
|
|
DebugExpression(NULL,stmt);
|
|
} else {
|
|
// looking through the arguments list
|
|
SgExpression * el;
|
|
for(el=stmt->expr(0); el; el=el->rhs())
|
|
ChangeArg_DistArrayRef(el); // argument
|
|
}
|
|
break;
|
|
case ALLOCATE_STMT:
|
|
ALLOCATEf90_arrays(stmt,distr);
|
|
if(!stmt->expr(0)){
|
|
cur_st=stmt->lexPrev();
|
|
Extract_Stmt(stmt);
|
|
stmt=cur_st;
|
|
} else
|
|
{ cur_st = stmt;
|
|
if(debug_regim)
|
|
AllocatableArrayRegistration(stmt);
|
|
EnterDataRegionForAllocated(stmt); /*ACC*/
|
|
stmt=cur_st;
|
|
}
|
|
break;
|
|
case DEALLOCATE_STMT:
|
|
DEALLOCATEf90_arrays(stmt);
|
|
if(!stmt->expr(0)){
|
|
Extract_Stmt(stmt);
|
|
stmt=cur_st;
|
|
}
|
|
break;
|
|
case DVM_PARALLEL_ON_DIR:
|
|
if(!TestParallelWithoutOn(stmt,1))
|
|
{
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
}
|
|
|
|
if(inparloop){
|
|
err("Nested PARALLEL directives are not permitted", 96, stmt);
|
|
break;
|
|
}
|
|
//!!!acc printf("parallel on %d region %d\n",stmt->lineNumber(), cur_region);
|
|
|
|
par_do = stmt->lexNext();// first DO statement of parallel loop
|
|
|
|
while(isOmpDir (par_do)) // || isACCdirective(par_do)
|
|
{ cur_st = par_do;
|
|
par_do=par_do->lexNext();
|
|
}
|
|
if(!isSgForStmt(par_do)) {
|
|
err("PARALLEL directive must be followed by DO statement",97,stmt); //directive is ignored
|
|
break;
|
|
}
|
|
inparloop = 1;
|
|
if(!ParallelLoop(stmt))// error in PARALLEL directive
|
|
inparloop = 0;
|
|
|
|
pstmt = addToStmtList(pstmt, stmt); // add to list of extracted statements
|
|
//Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;
|
|
// setting stmt on last DO statement of parallel loop nest
|
|
break;
|
|
|
|
case HPF_INDEPENDENT_DIR:
|
|
if(inparloop){
|
|
//illegal nested INDEPENDENT directive is ignored
|
|
pstmt = addToStmtList(pstmt, stmt); //including the HPF directive to list
|
|
break;
|
|
}
|
|
indep_st = stmt; // INDEPENDENT directive
|
|
par_do = stmt->lexNext();// first DO statement of parallel loop
|
|
if(!isSgForStmt(par_do)) {
|
|
err("INDEPENDENT directive must be followed by DO statement",97,stmt);
|
|
//directive is ignored
|
|
break;
|
|
}
|
|
inparloop = 1;
|
|
IEXLoopAnalyse(func);
|
|
if(!IndependentLoop(stmt))// error in INDEPENDENT directive
|
|
inparloop = 0;
|
|
|
|
|
|
//including the HPF directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st; // setting stmt on last DO statement of parallel loop nest
|
|
break;
|
|
|
|
case DVM_SHADOW_GROUP_DIR:
|
|
{
|
|
SgSymbol *s;
|
|
SgExpression *gref;
|
|
if(INTERFACE_RTS2)
|
|
err("Illegal directive in -Opl2 mode. Asynchronous operations are not supported in this mode", 649, stmt);
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98, stmt);
|
|
LINE_NUMBER_AFTER(stmt,stmt); //for tracing set on global variable of LibDVM
|
|
s = stmt->symbol();
|
|
AddToGroupNameList (s);
|
|
gref = new SgVarRefExp(s);
|
|
CreateBoundGroup(gref);
|
|
//s -> addAttribute(SHADOW_GROUP_IND, (void *) index, sizeof(int));
|
|
ShadowList(stmt->expr(0), stmt, gref);
|
|
}
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;//setting stmt on last inserted statement
|
|
break;
|
|
|
|
case DVM_SHADOW_START_DIR:
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
LINE_NUMBER_AFTER(stmt,stmt); //for tracing set on global variable of LibDVM
|
|
if(ACC_program) /*ACC*/
|
|
// generating call statement ( in and out compute region):
|
|
// call dvmh_shadow_renew( BoundGroupRef)
|
|
doCallAfter(ShadowRenew_H(new SgVarRefExp(stmt->symbol()) ));
|
|
|
|
doCallAfter(StartBound(new SgVarRefExp(stmt->symbol())));
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;//setting stmt on inserted statement
|
|
break;
|
|
|
|
case DVM_SHADOW_WAIT_DIR:
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
LINE_NUMBER_AFTER(stmt,stmt); //for tracing set on global variable of LibDVM
|
|
doCallAfter(WaitBound(new SgVarRefExp(stmt->symbol())));
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;//setting stmt on inserted statement
|
|
break;
|
|
|
|
case DVM_REDUCTION_START_DIR:
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
LINE_NUMBER_AFTER(stmt,stmt); //for tracing set on global variable of LibDVM
|
|
doCallAfter(StartRed(new SgVarRefExp(stmt->symbol())));
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;//setting stmt on inserted statement
|
|
break;
|
|
|
|
case DVM_REDUCTION_WAIT_DIR:
|
|
{SgExpression *rg = new SgVarRefExp(stmt->symbol());
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
LINE_NUMBER_AFTER(stmt,stmt); //for tracing set on global variable of LibDVM
|
|
doCallAfter(WaitRed(rg));
|
|
if(dvm_debug)
|
|
doCallAfter( D_CalcRG(DebReductionGroup( rg->symbol())));
|
|
|
|
doCallAfter(DeleteObject_H(rg));
|
|
doAssignTo_After(rg, new SgValueExp(0));
|
|
if(debug_regim)
|
|
doCallAfter( D_DelRG(DebReductionGroup( rg->symbol())));
|
|
}
|
|
//Extract_Stmt(stmt); // extracting DVM-directive
|
|
wait_list = addToStmtList(wait_list, stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;//setting stmt on last inserted statement
|
|
break;
|
|
|
|
|
|
case DVM_CONSISTENT_START_DIR:
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
LINE_NUMBER_AFTER(stmt,stmt); //for tracing set on global variable of LibDVM
|
|
doAssignStmtAfter(StartConsGroup(new SgVarRefExp(stmt->symbol())));
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;//setting stmt on inserted statement
|
|
break;
|
|
|
|
case DVM_CONSISTENT_WAIT_DIR:
|
|
{SgExpression *rg = new SgVarRefExp(stmt->symbol());
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
LINE_NUMBER_AFTER(stmt,stmt); //for tracing set on global variable of LibDVM
|
|
doAssignStmtAfter(WaitConsGroup(rg));
|
|
//if(dvm_debug)
|
|
//doAssignStmtAfter( D_CalcRG(DebReductionGroup( rg->symbol())));
|
|
if(cur_st->controlParent()->variant() != PROG_HEDR){
|
|
doCallAfter(DeleteObject_H(rg));
|
|
doAssignTo_After(rg, new SgValueExp(0));
|
|
}
|
|
//if(debug_regim)
|
|
//doAssignStmtAfter( D_DelRG(DebReductionGroup( rg->symbol())));
|
|
}
|
|
wait_list = addToStmtList(wait_list, stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;//setting stmt on last inserted statement
|
|
break;
|
|
|
|
case DVM_REMOTE_ACCESS_DIR:
|
|
if(inparloop) {
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
break;
|
|
}
|
|
ReplaceContext(stmt->lexNext());
|
|
switch(stmt->lexNext()->variant()) {
|
|
case LOGIF_NODE:
|
|
rmout = stmt->lexNext()->lexNext()->lexNext();
|
|
break;
|
|
case SWITCH_NODE:
|
|
rmout = stmt->lexNext()->lastNodeOfStmt()->lexNext();
|
|
break;
|
|
case IF_NODE:
|
|
rmout = lastStmtOfIf(stmt->lexNext())->lexNext();
|
|
break;
|
|
case CASE_NODE:
|
|
case ELSEIF_NODE:
|
|
err("Misplaced REMOTE_ACCESS directive", 99,stmt);
|
|
rmout = stmt->lexNext()->lexNext();
|
|
break;
|
|
case FOR_NODE:
|
|
rmout = lastStmtOfDo(stmt->lexNext())->lexNext();
|
|
break;
|
|
case WHILE_NODE:
|
|
rmout = lastStmtOfDo(stmt->lexNext())->lexNext();
|
|
break;
|
|
case DVM_PARALLEL_ON_DIR:
|
|
rmout = lastStmtOfDo(stmt->lexNext()->lexNext())->lexNext();
|
|
break;
|
|
default:
|
|
rmout = stmt->lexNext()->lexNext();
|
|
break;
|
|
}
|
|
//adding new element to remote_access directive/clause list
|
|
AddRemoteAccess(stmt->expr(0),rmout);
|
|
LINE_NUMBER_STL_BEFORE(cur_st,stmt,stmt->lexNext()); // moving the label of next statement
|
|
// looking through the remote variable list
|
|
RemoteVariableList(stmt->symbol(),stmt->expr(0),stmt);
|
|
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_NEW_VALUE_DIR:
|
|
if((stmt->lexNext()->variant()==DVM_REDISTRIBUTE_DIR) || (stmt->lexNext()->variant()==DVM_REALIGN_DIR))
|
|
st_newv = stmt;
|
|
else
|
|
err("NEW_VALUE directive must be followed by REDISTRIBUTE or REALIGN directive", 146,stmt);
|
|
break;
|
|
|
|
case DVM_REALIGN_DIR:
|
|
if(inparloop){
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
st_newv = 0;
|
|
break;
|
|
} else {
|
|
int iaxis; // AxisArray index
|
|
int nr,new_sign,ia;
|
|
SgSymbol *als,*tgs;
|
|
|
|
where = stmt; //for inserting before current directive
|
|
iaxis = ndvm;
|
|
ia = 0;
|
|
//sta = NULL;
|
|
// new_val = isSgExprListExp(stmt->expr(2)) ? (stmt->expr(2)->rhs()->lhs()) : (SgExpression *) NULL;
|
|
|
|
tgs = isSgExprListExp(stmt->expr(2)) ? (stmt->expr(2))->lhs()->symbol() : (stmt->expr(2))->symbol();
|
|
if(!HEADER(tgs))
|
|
Error("'%s' isn't distributed array", tgs->identifier(), 72,stmt);
|
|
|
|
new_sign = 0;
|
|
if(st_newv)
|
|
new_sign = 1; // NEW_VALUE without variable list
|
|
//looking through the alignee_list
|
|
for(e=stmt->expr(0); e; e=e->rhs()) {
|
|
als = (e->lhs())->symbol(); // realigned array symbol
|
|
//nr = doAlignRule(als, stmt, ia);
|
|
SgExpression *align_rule_list = doAlignRules(als, stmt, ia, nr);
|
|
/*
|
|
*if(sta) // is not first list element
|
|
* for(i=0;i<2*nr;i++)
|
|
* Extract_Stmt(sta->lexNext());//extracting axis and coeff
|
|
* //assignment statements
|
|
*/
|
|
|
|
/*
|
|
* if(new_val)
|
|
* if(!new_val->lhs()) // NEW_VALUE without variable list
|
|
* new_sign = 1;
|
|
* else
|
|
* for(env=new_val->lhs(); env; env=env->rhs()) {
|
|
* symb=env->lhs()->symbol();
|
|
* if(symb==als) {
|
|
* new_sign = 1;
|
|
* break;
|
|
* }
|
|
* }
|
|
*/
|
|
LINE_NUMBER_AFTER(stmt,cur_st);// doAssignStmt in doAlignRule resets cur_st
|
|
//all inserted statements for REALIGN directive appear before it
|
|
RealignArray(als,tgs,iaxis,nr,align_rule_list,new_sign,stmt);
|
|
// doAssignStmt(RealignArr(DistObjectRef(als),DistObjectRef(stmt->expr(2)->symbol()),iaxis,iaxis+nr,iaxis+2*nr,new_sign));
|
|
|
|
ia = iaxis;
|
|
|
|
}
|
|
SET_DVM(iaxis);
|
|
|
|
}
|
|
|
|
Extract_Stmt(stmt); // extracting REALIGN directive
|
|
if(st_newv)
|
|
Extract_Stmt(st_newv); //extracting preceeding NEW_VALUE directive
|
|
stmt = cur_st;//setting stmt on last inserted statement
|
|
st_newv = 0;
|
|
break;
|
|
|
|
case DVM_REDISTRIBUTE_DIR:
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
else {
|
|
int idis; // DisRuleArray index
|
|
int new_sign,isave;
|
|
SgSymbol *das;
|
|
SgExpression *target,*ps;
|
|
// new_val = hasNewValueClause(stmt);
|
|
nproc = 0;
|
|
isave = ndvm;
|
|
where = stmt; //for inserting before current directive
|
|
LINE_NUMBER_BEFORE(stmt,stmt);
|
|
SgExpression *distr_rule_list = doDisRules(stmt,0,idis);
|
|
target = hasOntoClause(stmt);
|
|
if ( target ) { //is there ONTO_clause
|
|
nproc=RankOfSection(target); // rank of Processors
|
|
if(nblock && nproc && nblock > nproc)
|
|
Error("The number of BLOCK/GENBLOCK elements of dist-format-list is greater than the rank of PROCESSORS '%s'", target->symbol()->identifier(),90,stmt);
|
|
}
|
|
ps = PSReference(stmt);
|
|
//LINE_NUMBER_AFTER(stmt,cur_st);// doAssignStmt in doDisRuleArrays resets cur_st
|
|
//all inserted statements for REDISTRIBUTE directive appear before it
|
|
new_sign = 0;
|
|
if(st_newv)
|
|
new_sign = 1; // NEW_VALUE without variable list
|
|
//looking through the dist_name_list
|
|
for(e=stmt->expr(0); e; e=e->rhs()) {
|
|
das = (e->lhs())->symbol(); // distribute array symbol
|
|
// for debug
|
|
//printf("%s\n ", das->identifier());
|
|
//
|
|
//new_sign = 0;
|
|
//if(new_val)
|
|
// if(!new_val->lhs()) // NEW_VALUE without variable list
|
|
// new_sign = 1;
|
|
// else
|
|
// for(env=new_val->lhs(); env; env=env->rhs()) {
|
|
// symb=env->lhs()->symbol();
|
|
// if(symb==das) {
|
|
// new_sign = 1;
|
|
// break;
|
|
// }
|
|
// }
|
|
// if(Rank(das)!=ndis)
|
|
// Error("Length of dist-format-list is not equal the rank of %s ", das->identifier(),stmt);
|
|
|
|
// creating LibDVM function calls for redistributing array
|
|
|
|
RedistributeArray(das,idis,distr_rule_list,ps,new_sign,e->lhs(),stmt);
|
|
|
|
}
|
|
|
|
SET_DVM(isave);
|
|
Extract_Stmt(stmt); // extracting REDISTRIBUTE directive
|
|
if(st_newv)
|
|
Extract_Stmt(st_newv); //extracting preceeding NEW_VALUE directive
|
|
stmt = cur_st;//setting stmt on last inserted statement
|
|
|
|
}
|
|
st_newv = 0;
|
|
break;
|
|
|
|
case DVM_LOCALIZE_DIR:
|
|
{
|
|
int iaxis;
|
|
int rank=Rank(stmt->expr(1)->symbol());
|
|
SgExpression *ei;
|
|
if(!INTERFACE_RTS2)
|
|
{
|
|
warn("LOCALIZE directive is ignored, -Opl2 option should be specified",621,stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
}
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
for(ei=stmt->expr(1)->lhs(),iaxis=rank; ei; ei=ei->rhs(),iaxis--)
|
|
if(ei->lhs()->variant() == DDOT)
|
|
break;
|
|
|
|
if( HEADER(stmt->expr(0)->symbol()) && HEADER(stmt->expr(1)->symbol()) )
|
|
{
|
|
doCallAfter(IndirectLocalize(HeaderRef(stmt->expr(0)->symbol()),HeaderRef(stmt->expr(1)->symbol()),iaxis));
|
|
Extract_Stmt(stmt);
|
|
}
|
|
if( !HEADER( stmt->expr(0)->symbol()) )
|
|
Error("'%s' is not distributed array", stmt->expr(0)->symbol()->identifier(),72,stmt);
|
|
if( !HEADER( stmt->expr(1)->symbol()) )
|
|
Error("'%s' is not distributed array", stmt->expr(1)->symbol()->identifier(),72,stmt);
|
|
|
|
stmt = cur_st;
|
|
break;
|
|
}
|
|
|
|
case DVM_SHADOW_ADD_DIR:
|
|
if(!INTERFACE_RTS2)
|
|
{
|
|
warn("SHADOW_ADD directive is ignored, -Opl2 option should be specified",621,stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
}
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
Shadow_Add_Directive(stmt);
|
|
Extract_Stmt(stmt);
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
//Debugging Directive
|
|
case DVM_INTERVAL_DIR:
|
|
if (perf_analysis > 1){
|
|
//generating call to 'binter' function of performance analizer
|
|
// (begin of user interval)
|
|
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
InsertNewStatementAfter(St_Binter(OpenInterval(stmt),Value_F95(stmt->expr(0))), cur_st,cur_st->controlParent());
|
|
}
|
|
pstmt = addToStmtList(pstmt, stmt); //including the DVM directive to list
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_ENDINTERVAL_DIR:
|
|
if (perf_analysis > 1){
|
|
//generating call to 'einter' function of performance analizer
|
|
// (end of user interval)
|
|
|
|
if(!St_frag){
|
|
err("Unmatched directive",182,stmt);
|
|
break;
|
|
}
|
|
if(St_frag && St_frag->begin_st && (St_frag->begin_st->controlParent() != stmt->controlParent()))
|
|
err("Misplaced directive",103,stmt); //interval must be a block
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
InsertNewStatementAfter(St_Einter(INTERVAL_NUMBER,INTERVAL_LINE), cur_st, stmt->controlParent());
|
|
CloseInterval();
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;
|
|
}
|
|
else
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
|
|
case DVM_EXIT_INTERVAL_DIR:
|
|
if (perf_analysis > 1){
|
|
//generating calls to 'einter' function of performance analizer
|
|
// (exit from user intervals)
|
|
|
|
if(!St_frag){
|
|
err("Misplaced directive",103,stmt);
|
|
break;
|
|
}
|
|
ExitInterval(stmt);
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;
|
|
}
|
|
else
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
|
|
case DVM_MAP_DIR:
|
|
{ int ind;
|
|
SgExpression *ps,*am,*index;
|
|
SgSymbol *s_tsk;
|
|
if(inparloop){
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
break;
|
|
}
|
|
LINE_NUMBER_BEFORE(stmt,stmt);
|
|
where = stmt; //for inserting before current directive
|
|
ind = ndvm;
|
|
s_tsk = stmt->expr(0)->symbol();
|
|
if(!stmt->expr(2)) // MAP ... ONTO ...
|
|
{ index = Calculate(stmt->expr(0)->lhs()->lhs());
|
|
if(!isSgValueExp(index) && !isSgVarRefExp(index))
|
|
{ doAssignStmt(index);
|
|
index = DVM000(ind);
|
|
}
|
|
PSReference(stmt);
|
|
ps = new SgArrayRefExp(*s_tsk,*new SgValueExp(1),*index);
|
|
cur_st->setExpression(0,*ps);
|
|
am = new SgArrayRefExp(*s_tsk,*new SgValueExp(2),*index);
|
|
doCallStmt(MapAM(am,ps));
|
|
SET_DVM(ind);
|
|
} else // MAP ... BY ...
|
|
{ SgExpression *section, *ev_tsk, *e_count;
|
|
SgSymbol *s_ind;
|
|
int ips,i_size, i_lps, ic;
|
|
SgStatement *dost;
|
|
s_tsk->addAttribute(TSK_AUTO, (void*) 1, 0);
|
|
section = stmt->expr(0)->lhs();
|
|
i_size = ndvm;
|
|
doAssignStmt(GetSize(ParentPS(),0));
|
|
// pr = psview(PSRef, rank, SizeArray, StaticSign)
|
|
ips = ndvm;
|
|
doAssignStmt(Reconf(DVM000(i_size), 1, 0));
|
|
s_ind = loop_var[0]; //TASK_IND_VAR(s_tsk);
|
|
ev_tsk = new SgVarRefExp(s_ind);
|
|
ic = ndvm;
|
|
e_count = CountOfTasks(stmt);
|
|
doAssignStmt(e_count);
|
|
TestParamType(stmt);
|
|
doCallStmt(MapTasks(DVM000(ic),DVM000(i_size),new SgVarRefExp(stmt->expr(2)->symbol()),new SgVarRefExp(TASK_LPS_ARRAY(s_tsk)),new SgVarRefExp(TASK_HPS_ARRAY(s_tsk)),new SgVarRefExp(TASK_RENUM_ARRAY(s_tsk))));
|
|
ps = new SgArrayRefExp(*s_tsk,*new SgValueExp(1),*ev_tsk);
|
|
am = new SgArrayRefExp(*s_tsk,*new SgValueExp(2),*ev_tsk);
|
|
dost = new SgForStmt(*s_ind,*new SgValueExp(1),*e_count,*MapAM(am,ps));
|
|
where->insertStmtBefore(*dost);
|
|
cur_st = dost;
|
|
i_lps = ndvm;
|
|
doAssignStmtAfter( &(*new SgArrayRefExp(*TASK_LPS_ARRAY(s_tsk),*ev_tsk) - *new SgValueExp(1)) );
|
|
doAssignStmtAfter( &(*new SgArrayRefExp(*TASK_HPS_ARRAY(s_tsk),*ev_tsk) - *new SgValueExp(1)) );
|
|
doAssignTo_After(ps, CrtPS(DVM000(ips), i_lps, i_lps+1, 0) );
|
|
cur_st = dost->lastNodeOfStmt();
|
|
SET_DVM(i_size);
|
|
}
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;
|
|
}
|
|
break;
|
|
|
|
case DVM_TASK_REGION_DIR:
|
|
if(in_task_region++) {
|
|
err("Nested TASK_REGION are not permitted", 100,stmt);
|
|
break;
|
|
}
|
|
if(inparloop){
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
break;
|
|
}
|
|
if((stmt->lexNext()->variant() != DVM_ON_DIR) && (stmt->lexNext()->variant() != DVM_END_TASK_REGION_DIR) && (stmt->lexNext()->variant() != DVM_PARALLEL_TASK_DIR))
|
|
err("Statement is outside of on-block",101,stmt->lexNext());
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
//if(stmt->expr(0))
|
|
Reduction_Task_Region(stmt);
|
|
//if(stmt->expr(1))
|
|
Consistent_Task_Region(stmt);
|
|
task_region_st = stmt;
|
|
task_region_parent = stmt->controlParent(); //to test nesting blocks
|
|
task_lab = (SgLabel *) NULL;
|
|
task_ind = ndvm++;
|
|
if(dvm_debug)
|
|
DebugTaskRegion(stmt);
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_END_TASK_REGION_DIR:
|
|
if(!in_task_region--) {
|
|
err("No matching TASK_REGION", 102,stmt);
|
|
break;
|
|
}
|
|
if(inparloop){
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
break;
|
|
}
|
|
if(stmt->controlParent() != task_region_parent) //test of nesting blocks
|
|
err("Misplaced directive",103,stmt);
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
if(dvm_debug)
|
|
CloseTaskRegion(task_region_st,stmt);
|
|
EndReduction_Task_Region(stmt);
|
|
EndConsistent_Task_Region(stmt);
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_ON_DIR:
|
|
if(in_task++) {
|
|
err("Nested ON-blocks are not permitted", 104,stmt);
|
|
break;
|
|
}
|
|
|
|
if(inparloop){
|
|
err("The directive is inside the range of PARALLEL loop",98, stmt);
|
|
break;
|
|
}
|
|
|
|
if(!isSgArrayRefExp(stmt->expr(0)) || !stmt->expr(0)->symbol()) {
|
|
err("Syntax error",14, stmt);
|
|
break;
|
|
}
|
|
|
|
on_stmt = stmt;
|
|
if(HEADER(stmt->expr(0)->symbol())) // ON <dvm-array-element> construct
|
|
{
|
|
LINE_NUMBER_BEFORE(stmt,stmt);
|
|
in_on++;
|
|
break;
|
|
}
|
|
// ON <task-array-element> construct
|
|
if(!in_task_region)
|
|
err("ON directive is outside of the task region", 105,stmt);
|
|
if( stmt->expr(0)->symbol()->attributes() & TASK_BIT)
|
|
{
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
task_lab = GetLabel();
|
|
StartTask(stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;
|
|
}
|
|
else
|
|
Error("'%s' is not task array", stmt->expr(0)->symbol()->identifier(),77,stmt);
|
|
break;
|
|
|
|
case DVM_END_ON_DIR:
|
|
if(!in_task) {
|
|
err("No matching ON directive", 106,stmt);
|
|
break;
|
|
} else
|
|
in_task--;
|
|
if(in_task) //nested ON constructs
|
|
break;
|
|
|
|
if(inparloop){
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
break;
|
|
}
|
|
if(on_stmt && stmt->controlParent() != on_stmt->controlParent())
|
|
err("Misplaced directive",103,stmt);
|
|
if(in_on) // end of ON <dvm-array-element> construct
|
|
{
|
|
ReplaceOnByIf(on_stmt,stmt);
|
|
Extract_Stmt(on_stmt); // extracting DVM-directive (ON)
|
|
in_on--;
|
|
|
|
if(dvm_debug)
|
|
{
|
|
SgStatement *std = dbg_if_regim ? CreateIfThenConstr(DebugIfCondition(),D_Skpbl()) : D_Skpbl();
|
|
InsertNewStatementAfter(std,stmt,stmt->controlParent());
|
|
cur_st = lastStmtOf(std);
|
|
}
|
|
Extract_Stmt(stmt); // extracting DVM-directive (END_ON)
|
|
stmt = cur_st;
|
|
break;
|
|
}
|
|
//end of ON <task-array-element> construct
|
|
if((stmt->lexNext()->variant() != DVM_ON_DIR) && (stmt->lexNext()->variant() != DVM_END_TASK_REGION_DIR))
|
|
err("Statement is outside of on-block",101,stmt->lexNext());
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
doCallAfter(StopAM());
|
|
InsertNewStatementAfter(new SgStatement(CONT_STAT),cur_st,stmt->controlParent());
|
|
if(task_lab)
|
|
cur_st->setLabel(*task_lab);
|
|
FREE_DVM(1);
|
|
Extract_Stmt(stmt);// extracting DVM-directive (END_ON)
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_RESET_DIR:
|
|
if(inparloop){
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
break;
|
|
}
|
|
if(options.isOn(NO_REMOTE)) {
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
}
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
doCallAfter(DeleteObject_H(GROUP_REF(stmt->symbol(),1)));
|
|
doAssignTo_After(GROUP_REF(stmt->symbol(),1),new SgValueExp(0));
|
|
Extract_Stmt(stmt);// extracting DVM-directive
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_PREFETCH_DIR:
|
|
if(inparloop){
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
break;
|
|
}
|
|
if(options.isOn(NO_REMOTE)) {
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
}
|
|
if(INTERFACE_RTS2)
|
|
err("Illegal directive in -Opl2 mode. Asynchronous operations are not supported in this mode", 649, stmt);
|
|
|
|
{SgStatement *if_st,*endif_st;
|
|
pref_st = addToStmtList(pref_st, stmt);//add to list of PREFETCH directive
|
|
if_st = doIfThenConstrForPrefetch(stmt);
|
|
cur_st = if_st->lexNext()->lexNext();//ELSE IF
|
|
endif_st = cur_st->lexNext()->lexNext(); //END IF
|
|
doAssignStmtAfter((stmt->symbol()->attributes() & INDIRECT_BIT) ? LoadIG(stmt->symbol()) : LoadBG(GROUP_REF(stmt->symbol(),1)));
|
|
doAssignTo_After(GROUP_REF(stmt->symbol(),3),new SgValueExp(1));
|
|
cur_st = if_st;//IF THEN
|
|
doAssignTo_After(GROUP_REF(stmt->symbol(),1),(stmt->symbol()->attributes() & INDIRECT_BIT) ? CreateIG(0,1) : CreateBG(0,1));
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
Extract_Stmt(stmt);// extracting DVM-directive
|
|
stmt = endif_st;
|
|
}
|
|
break;
|
|
|
|
/* case DVM_INDIRECT_ACCESS_DIR:*/
|
|
/*
|
|
case DVM_OWN_DIR:
|
|
if(inparloop){
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
break;
|
|
}
|
|
if(stmt->lexNext()->variant() == ASSIGN_STAT)
|
|
own_exe = 1;
|
|
else
|
|
err("OWN directive must precede an assignment statement",stmt);
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
|
|
break;
|
|
*/
|
|
case DVM_PARALLEL_TASK_DIR:
|
|
{ //SgForStmt *stdo;
|
|
SgExpression *el;
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
if(!in_task_region)
|
|
err("Parallel-task-loop directive is outside of the task region", 107,stmt);
|
|
if(in_task++) {
|
|
err("Nested ON-blocks are not permitted", 104,stmt);
|
|
break;
|
|
}
|
|
//stdo = isSgForStmt(stmt->lexNext());
|
|
if(! isSgForStmt(stmt->lexNext())){
|
|
err(" PARALLEL directive must be followed by DO statement",97,stmt);
|
|
//directive is ignored
|
|
break;
|
|
}
|
|
for(el=stmt->expr(1); el; el=el->rhs()) {
|
|
if(el->lhs()->variant() != ACC_PRIVATE_OP)
|
|
err("Illegal clause",150,stmt);
|
|
break;
|
|
}
|
|
task_do = stmt->lexNext();
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
cur_st = task_do;
|
|
task_lab = GetLabel();//stdo->endOfLoop()
|
|
// task_do_ind = <renum_array>(loop_var_ind)
|
|
doAssignTo_After(new SgVarRefExp(task_do->symbol()),new SgArrayRefExp(*TASK_RENUM_ARRAY(stmt->expr(0)->symbol()),*new SgVarRefExp(loop_var[0])));
|
|
task_do->setSymbol(*loop_var[0]);
|
|
StartTask(stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
//Extract_Stmt(stmt);// extracting DVM-directive
|
|
//stmt = cur_st;
|
|
}
|
|
break;
|
|
|
|
case DVM_ASYNCWAIT_DIR:
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98, stmt);
|
|
if(INTERFACE_RTS2)
|
|
warn("Illegal directive/statement in -Opl2 mode. Asynchronous execution is replaced by a synchronous.", 649, stmt);
|
|
else
|
|
{
|
|
LINE_NUMBER_AFTER(stmt,stmt); //for tracing set on global variable of LibDVM
|
|
AsyncCopyWait(stmt->expr(0));
|
|
}
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;//setting stmt on last inserted statement
|
|
break;
|
|
|
|
case DVM_ASYNCHRONOUS_DIR:
|
|
AnalyzeAsynchronousBlock(stmt); //analysis of ASYNCHRONOUS_ENDASYNCHRONOUS block
|
|
inasynchr++;
|
|
async_id = stmt->expr(0);
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop",98, stmt);
|
|
if(INTERFACE_RTS2)
|
|
warn("Illegal directive/statement in -Opl2 mode. Asynchronous execution is replaced by a synchronous.", 649, stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
|
|
case DVM_ENDASYNCHRONOUS_DIR:
|
|
inasynchr--;
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop",98, stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
|
|
case DVM_F90_DIR:
|
|
if(inparloop) {
|
|
err("The directive is inside the range of PARALLEL loop",98, stmt);
|
|
break;
|
|
}
|
|
if(!inasynchr)
|
|
err("Misplaced directive",103,stmt);
|
|
AsynchronousCopy(stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt=cur_st;
|
|
break;
|
|
|
|
case DVM_TEMPLATE_CREATE_DIR:
|
|
LINE_NUMBER_BEFORE(stmt,stmt);
|
|
Template_Create(stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_TEMPLATE_DELETE_DIR:
|
|
LINE_NUMBER_BEFORE(stmt,stmt);
|
|
Template_Delete(stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_TRACEON_DIR:
|
|
InsertNewStatementAfter(new SgCallStmt(*fdvm[TRON]),stmt,stmt->controlParent());
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
Extract_Stmt(stmt);// extracting DVM-directive
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_TRACEOFF_DIR:
|
|
InsertNewStatementAfter(new SgCallStmt(*fdvm[TROFF]),stmt,stmt->controlParent());
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
Extract_Stmt(stmt);// extracting DVM-directive
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_BARRIER_DIR:
|
|
doAssignStmtAfter(Barrier());
|
|
FREE_DVM(1);
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
Extract_Stmt(stmt);// extracting DVM-directive
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_CHECK_DIR:
|
|
if(check_regim) {
|
|
cur_st = Check(stmt);
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;
|
|
} else
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
|
|
case DVM_DEBUG_DIR:
|
|
{ int num;
|
|
/*
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
*/
|
|
if((stmt->expr(0)->variant() != INT_VAL) || (num=stmt->expr(0)->valueInteger())<= 0)
|
|
err("Illegal fragment number",181,stmt);
|
|
else if(debug_fragment || perf_fragment)
|
|
BeginDebugFragment(num,stmt);
|
|
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
}
|
|
break;
|
|
case DVM_ENDDEBUG_DIR:
|
|
{ int num;
|
|
/*
|
|
if(inparloop)
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
*/
|
|
if((stmt->expr(0)->variant() != INT_VAL) || (num=stmt->expr(0)->valueInteger())<= 0)
|
|
err("Illegal fragment number",181,stmt);
|
|
else if((debug_fragment || perf_fragment) && ((cur_fragment && cur_fragment->No != num) || !cur_fragment))
|
|
err("Unmatched directive",182,stmt);
|
|
else {
|
|
if(cur_fragment && cur_fragment->begin_st && (stmt->controlParent() != cur_fragment->begin_st->controlParent()))
|
|
err("Misplaced directive",103,stmt); //fragment must be a block
|
|
EndDebugFragment(num);
|
|
}
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
}
|
|
break;
|
|
|
|
case DVM_IO_MODE_DIR:
|
|
IoModeDirective(stmt,io_modes_str,WITH_ERR_MSG);
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
case OPEN_STAT:
|
|
Open_Statement(stmt,io_modes_str,WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
case CLOSE_STAT:
|
|
Close_Statement(stmt,WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
case INQUIRE_STAT:
|
|
Inquiry_Statement(stmt,WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
case BACKSPACE_STAT:
|
|
case ENDFILE_STAT:
|
|
case REWIND_STAT:
|
|
FilePosition_Statement(stmt,WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
case WRITE_STAT:
|
|
case READ_STAT:
|
|
ReadWrite_Statement(stmt, WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
case PRINT_STAT:
|
|
Any_IO_Statement(stmt);
|
|
ReadWritePrint_Statement(stmt,WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_CP_CREATE_DIR: /*Check Point*/
|
|
CP_Create_Statement(stmt, WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
case DVM_CP_SAVE_DIR:
|
|
CP_Save_Statement(stmt, WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
case DVM_CP_LOAD_DIR:
|
|
CP_Load_Statement(stmt, WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
case DVM_CP_WAIT_DIR:
|
|
CP_Wait(stmt, WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break; /*Check Point*/
|
|
|
|
case FOR_NODE:
|
|
if(HPF_program)
|
|
SetDoVar(stmt->symbol());
|
|
if(perf_analysis == 4 && !IN_COMPUTE_REGION)
|
|
SeqLoopBegin(stmt);
|
|
if(dvm_debug)
|
|
DebugLoop(stmt);
|
|
else
|
|
{
|
|
ChangeDistArrayRef(stmt->expr(0));
|
|
ChangeDistArrayRef(stmt->expr(1));
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// analyzing of loop end statement
|
|
{
|
|
SgStatement *end_stmt;
|
|
end_stmt = isSgLogIfStmt(stmt->controlParent()) ? stmt->controlParent() : stmt;
|
|
if(inparloop && isParallelLoopEndStmt(end_stmt,par_do))
|
|
|
|
{ //stmt is last statement of parallel loop or is body of logical IF , which
|
|
// is last statement
|
|
EndOfParallelLoopNest(stmt,end_stmt,par_do,func);
|
|
inparloop = 0; // end of parallel loop nest
|
|
stmt = cur_st;
|
|
//SET_DVM(iplp);
|
|
continue;
|
|
} // end of processing last statement of parallel loop
|
|
//printf("!!! end parallel loop %d\n",end_stmt->lineNumber());
|
|
if(HPF_program && isDoEndStmt(end_stmt))
|
|
OffDoVarsOfNest(end_stmt);
|
|
|
|
if(task_do && isDoEndStmt(end_stmt) && end_stmt->controlParent() == task_do){
|
|
SgStatement *st;
|
|
st=ReplaceDoLabel(end_stmt,task_lab);
|
|
if(st) {
|
|
BIF_LABEL(st->thebif) = NULL;
|
|
stmt = st;
|
|
InsertNewStatementBefore (StopAM(),st);
|
|
st->setLabel(*task_lab);
|
|
|
|
} else {//ENDDO
|
|
InsertNewStatementBefore (StopAM(),stmt);
|
|
}
|
|
in_task--;
|
|
}
|
|
|
|
if(dvm_debug){
|
|
if( isDoEndStmt_f90(stmt)) {
|
|
//on debug regim logical IF may not be end of loop
|
|
CloseLoop(stmt);
|
|
stmt = cur_st;
|
|
}
|
|
}
|
|
else if(perf_analysis && close_loop_interval)
|
|
if(isDoEndStmt_f90(end_stmt)){
|
|
SeqLoopEnd(end_stmt,stmt);
|
|
stmt = cur_st;
|
|
}
|
|
|
|
} // end of processing last statement of loop nest
|
|
|
|
} // end of processing executable statement/directive
|
|
|
|
END_: // end of program unit
|
|
//checking: is in program unit any enclosed DVM-construct?
|
|
if(in_task_region)
|
|
err("Missing ENDTASK_REGION directive",108,stmt);
|
|
if(in_task)
|
|
err("Missing ENDON directive",109,stmt);
|
|
//checking: is in program unit any enclosed ACC-construct? /*ACC*/
|
|
if(cur_region) /*ACC*/
|
|
{ if( cur_region->is_data)
|
|
err("Missing END DATA REGION directive",602,stmt);
|
|
else
|
|
err("Missing END REGION directive",603,stmt);
|
|
}
|
|
|
|
// for declaring dvm000(N) is used maximal value of ndvm
|
|
SET_DVM(ndvm);
|
|
cur_st = first_dvm_exec;
|
|
if(last_dvm_entry)
|
|
lentry = last_dvm_entry->lexNext(); // lentry - statement following first_dvm_exec or last generated dvm-initialization statement(before first_exec)
|
|
// before first_exec may be new statements generated for first_exec
|
|
|
|
if(!IN_MODULE) {
|
|
if(has_contains)
|
|
MarkCoeffsAsUsed();
|
|
InitBaseCoeffs();
|
|
InitRemoteGroups();
|
|
InitShadowGroups();
|
|
InitRedGroupVariables();
|
|
WaitDirList();
|
|
if(IN_MAIN_PROGRAM)
|
|
EnterDataRegionForVariablesInMainProgram(begin_block ? begbl : dvmh_init_st); /*ACC*/
|
|
else
|
|
EnterDataRegionForLocalVariables(begin_block ? begbl : cur_st, first_exec, begin_block); /*ACC*/
|
|
DoStmtsForENTRY(first_dvm_exec,lentry); // copy the previously generated statements for each ENTRY
|
|
// except for statements generated for the first executable statement if it is DVM-directive
|
|
UnregisterVariables(begin_block); // close data region before exit from the procedure
|
|
|
|
fmask[FNAME] = 0;
|
|
stmt = data_stf ? data_stf->lexPrev() : first_dvm_exec->lexPrev();
|
|
DeclareVarDVM(stmt,stmt);
|
|
CheckInrinsicNames();
|
|
|
|
} else {
|
|
if(mod_proc){
|
|
cur_st = end_of_unit->lexPrev();
|
|
InitBaseCoeffs();
|
|
MayBeDeleteModuleProc(mod_proc,end_of_unit);
|
|
}
|
|
fmask[FNAME] = 0;
|
|
nloopred = nloopcons = MAX_RED_VAR_SIZE;
|
|
stmt= mod_proc ? has_contains->lexPrev() : first_dvm_exec->lexPrev();
|
|
DeclareVarDVM(stmt, (mod_proc ? mod_proc : stmt));
|
|
}
|
|
|
|
Extract_Stmt(first_dvm_exec); //extract fname() call
|
|
for(;pstmt; pstmt= pstmt->next)
|
|
Extract_Stmt(pstmt->st);// extracting DVM Directives and
|
|
//statements (inside the range of ASYNCHRONOUS construct)
|
|
return;
|
|
}
|
|
|
|
|
|
int DeleteDArFromList(SgStatement *stmt)
|
|
{ SgExpression *el,*preve,*pl,*opl,*dvm_list, *dvml;
|
|
SgSymbol * s;
|
|
int ia,is_assign;
|
|
|
|
if(stmt->variant() == SAVE_DECL || stmt->variant() == OPTIONAL_STMT || stmt->variant() == PRIVATE_STMT || stmt->variant() == PUBLIC_STMT) //|| stmt->variant() == INTENT_STMT deleted 28.06.21
|
|
return(1);
|
|
|
|
pl = stmt->expr(0);
|
|
preve = 0;
|
|
is_assign = 0;
|
|
dvm_list = NULL;
|
|
for(el=stmt->expr(0); el; el=el->rhs()) {
|
|
if(el->lhs()->variant() == ASSGN_OP || el->lhs()->variant() == POINTST_OP) is_assign = 1;//with initial value
|
|
s = el->lhs()->symbol();
|
|
if(s) {
|
|
if((debug_regim || IN_MAIN_PROGRAM) && !in_interface && IS_ARRAY(s) )
|
|
registration = AddNewToSymbList( registration, s);
|
|
if(!strcmp(s->identifier(),"heap") && el->lhs()->lhs())
|
|
// heap_ar_decl = el->lhs();
|
|
//heap_ar_decl->setSymbol(*heapdvm);
|
|
heap_ar_decl = new SgArrayRefExp(*heapdvm);
|
|
// heap_ar_decl = el->lhs()->lhs();
|
|
ia = s->attributes();
|
|
if(IS_GROUP_NAME(s))
|
|
Error("Inconsistent declaration of identifier: %s",s->identifier(),16,stmt);
|
|
|
|
if(((ia & DISTRIBUTE_BIT) || (ia & ALIGN_BIT) || (ia & INHERIT_BIT)) && !(ia & DVM_POINTER_BIT) || (ia & HEAP_BIT) || !strcmp(s->identifier(),"heap") ){
|
|
el->lhs()->setLhs(NULL);
|
|
if(stmt->variant() == POINTER_STMT || stmt->variant() == TARGET_STMT || stmt->variant() == STATIC_STMT)
|
|
continue;
|
|
dvml = new SgExprListExp(el->lhs()->copy());
|
|
dvml->setRhs(dvm_list);
|
|
dvm_list = dvml;
|
|
|
|
if(preve)
|
|
preve->setRhs( el->rhs());
|
|
else
|
|
pl = el->rhs();
|
|
}
|
|
else
|
|
preve = el;
|
|
}
|
|
else
|
|
preve = el;
|
|
}
|
|
if(stmt->variant() == VAR_DECL && dvm_list) {
|
|
for( opl = stmt->expr(2); opl; opl=opl->rhs()) //looking through the option list and generating new statements
|
|
NewSpecificationStatement(opl->lhs(),dvm_list,stmt);
|
|
}
|
|
if(is_assign && stmt->variant() == VAR_DECL && !stmt->expr(2))
|
|
stmt->setVariant(VAR_DECL_90);
|
|
|
|
if(pl) {
|
|
stmt->setExpression(0, *pl);
|
|
return (1);
|
|
}
|
|
else // variable list is empty
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
int DeleteHeapFromList(SgStatement *stmt)
|
|
{ SgExpression *el,*ec,*preve,*pl, *prcl, *cl;
|
|
SgSymbol * s;
|
|
int ia;
|
|
// stmt is COMMON statement
|
|
prcl = NULL;
|
|
cl = stmt->expr(0);
|
|
for(ec=stmt->expr(0); ec; ec=ec->rhs()) {// looking through COMM_LIST
|
|
pl = ec->lhs();
|
|
preve = NULL;
|
|
for(el=ec->lhs(); el; el=el->rhs()) {
|
|
s = el->lhs()->symbol();
|
|
if(s) {
|
|
ia = s->attributes();
|
|
if( (ia & HEAP_BIT) || !strcmp(s->identifier(),"heap") ){
|
|
if(preve)
|
|
preve->setRhs( el->rhs());
|
|
else
|
|
pl = el->rhs();
|
|
}
|
|
else
|
|
preve = el;
|
|
}
|
|
else
|
|
preve = el;
|
|
} //end of loop el
|
|
if(pl) {
|
|
ec->setLhs(pl);
|
|
prcl = ec;
|
|
}
|
|
else {// common variable list is empty
|
|
if(prcl)
|
|
prcl->setRhs(ec->rhs());
|
|
else
|
|
cl = ec->rhs();
|
|
}
|
|
}
|
|
if(cl) {
|
|
stmt->setExpression(0, *cl);
|
|
return(1);
|
|
}
|
|
else // COMM_LIST is empty
|
|
return(0);
|
|
}
|
|
|
|
void NewSpecificationStatement(SgExpression *op, SgExpression *dvm_list, SgStatement *stmt)
|
|
{SgStatement *st;
|
|
switch(op->variant()){
|
|
case PUBLIC_OP:
|
|
st = new SgStatement(PUBLIC_STMT);
|
|
break;
|
|
case PRIVATE_OP:
|
|
st = new SgStatement(PRIVATE_STMT);
|
|
break;
|
|
// 28.06.21
|
|
// case IN_OP:
|
|
// case OUT_OP:
|
|
// case INOUT_OP:
|
|
// st = new SgStatement(INTENT_STMT);
|
|
// st->setExpression(1, op->copy());
|
|
// break;
|
|
case SAVE_OP:
|
|
st = new SgStatement(SAVE_DECL);
|
|
break;
|
|
case OPTIONAL_OP:
|
|
st = new SgStatement(OPTIONAL_STMT);
|
|
break;
|
|
case POINTER_OP:
|
|
st = new SgStatement(POINTER_STMT);
|
|
break;
|
|
case TARGET_OP:
|
|
st = new SgStatement(TARGET_STMT);
|
|
break;
|
|
case STATIC_OP:
|
|
st = new SgStatement(STATIC_STMT);
|
|
break;
|
|
default: st = NULL;
|
|
}
|
|
if(st){
|
|
st->setExpression(0,*dvm_list);
|
|
stmt->insertStmtBefore(*st, *stmt->controlParent());
|
|
}
|
|
}
|
|
|
|
int DeferredShape(SgExpression *eShape)
|
|
{
|
|
SgExpression *el;
|
|
SgSubscriptExp *sbe;
|
|
for(el=eShape; el; el=el->rhs())
|
|
{
|
|
if ((sbe=isSgSubscriptExp(el->lhs())) != NULL && !sbe->ubound() && !sbe->lbound())
|
|
continue;
|
|
else
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void TemplateDeclarationTest(SgStatement *stmt)
|
|
{
|
|
SgExpression *eol;
|
|
SgSymbol *symb;
|
|
for(eol=stmt->expr(0); eol; eol=eol->rhs()) { //testing object list
|
|
symb=eol->lhs()->symbol();
|
|
if(IS_DUMMY(symb))
|
|
Error("Template may not be a dummy argument: %s",symb->identifier(), 80,stmt);
|
|
if(DeferredShape(eol->lhs()->lhs()))
|
|
symb->addAttribute(DEFERRED_SHAPE,(void*)1,0);
|
|
if(IN_COMMON(symb) && IN_MODULE)
|
|
{
|
|
SYMB_ATTR(symb->thesymb) = SYMB_ATTR(symb->thesymb) & (~COMMON_BIT);
|
|
Warning("COMMON attribute is ignored: %s",symb->identifier(), 641,stmt);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CreateArray_RTS2(SgSymbol *das, int indh, SgStatement *stdis)
|
|
{
|
|
int rank = Rank(das);
|
|
SgExpression *shape_list = DEFERRED_SHAPE_TEMPLATE(das) ? NULL : doDvmShapeList(das,stdis);
|
|
if(IS_TEMPLATE(das))
|
|
{
|
|
// adding to the Template_array Symbol the attribute (ARRAY_HEADER)
|
|
// with integer value "indh" //"iamv"
|
|
ArrayHeader(das,indh); // or 2
|
|
SgExpression *array_header = HeaderRef(das);
|
|
das->addAttribute(RTS2_CREATED, (void*) 1, 0);
|
|
if(!DEFERRED_SHAPE_TEMPLATE(das))
|
|
doCallStmt(DvmhTemplateCreate(das,array_header,rank,shape_list));
|
|
}
|
|
else
|
|
{
|
|
// create dvm-array
|
|
ArrayHeader(das,indh);
|
|
SgExpression *array_header = HeaderRef(das);
|
|
SgExpression *shadow_list = DeclaredShadowWidths(das);
|
|
doCallStmt(DvmhArrayCreate(das,array_header,rank,ListUnion(shape_list,shadow_list)));
|
|
if(!HAS_SAVE_ATTR(das) && !IN_MODULE)
|
|
doCallStmt(ScopeInsert(array_header));
|
|
}
|
|
}
|
|
|
|
void GenDistArray (SgSymbol *das, int idisars, SgExpression *distr_rule_list, SgExpression *ps, SgStatement *stdis) {
|
|
|
|
int iamv,rank,iaxis,ileft,iright,ifst,indh;
|
|
SgExpression *am_view = NULL, *array_header, *size_array;
|
|
|
|
int ia,sign,re_sign,postponed_root;
|
|
SgStatement *savest;
|
|
|
|
savest = where;
|
|
ifst = ndvm;
|
|
pointer_in_tree = 0;
|
|
postponed_root = 0;
|
|
indh = 1;
|
|
|
|
if(IS_POINTER(das)) { //is POINTER
|
|
ArrayHeader(das,0);
|
|
loc_distr = 1; // POINTER is local object
|
|
goto TREE_;
|
|
}
|
|
if(IS_ALLOCATABLE(das)) { // ALLOCATABLE
|
|
ArrayHeader(das,-2);
|
|
loc_distr = 1; // ALLOCATABLE is local object
|
|
goto TREE_;
|
|
}
|
|
|
|
if(IS_DUMMY(das)) { //is dummy argument
|
|
ArrayHeader(das,1);
|
|
//ReplaceArrayBounds(das);
|
|
goto TREE_;
|
|
}
|
|
if(IS_POINTER_F90(das)) { // POINTER F90
|
|
ArrayHeader(das,-2);
|
|
if(!IS_DUMMY(das))
|
|
loc_distr = 1;
|
|
goto TREE_;
|
|
}
|
|
if(IN_COMMON(das)) // COMMON-block element or TEMPLATE_COMMON
|
|
if(das->scope()->variant() != PROG_HEDR) { // is not in MAIN-program
|
|
//if(stdis->controlParent()->variant() != PROG_HEDR)
|
|
|
|
if(IS_TEMPLATE(das))
|
|
{
|
|
if(idisars == -1) { //interface of RTS2
|
|
das->addAttribute(RTS2_CREATED, (void*) 1, 0);
|
|
// ArrayHeader(das,1);
|
|
} //else
|
|
ArrayHeader(das,2);
|
|
} else
|
|
ArrayHeader(das,1);
|
|
goto TREE_;
|
|
}
|
|
//if(DEFERRED_SHAPE_TEMPLATE(das)
|
|
|
|
if((das->attributes() & SAVE_BIT) || (saveall && (!IN_COMMON(das)))
|
|
|| ORIGINAL_SYMBOL(das)->scope()->variant() == MODULE_STMT) {
|
|
SgStatement *if_st;
|
|
if_st = doIfThenConstr(das);
|
|
//first_exec = if_st->lexNext(); // reffer to ENDIF statement
|
|
where = if_st->lexNext(); // reffer to ENDIF statement
|
|
}
|
|
|
|
LINE_NUMBER_BEFORE(stdis,where); // for tracing set the global variable of LibDVM to
|
|
// line number of statement(stdis)
|
|
ia = das->attributes();
|
|
//if(ia & DYNAMIC_BIT && IS_SAVE(das))
|
|
// Error ("Saved object may not have the DYNAMIC attribute: %s", das->identifier(), 111,stdis);
|
|
|
|
rank = Rank(das);
|
|
if(ndis && rank && rank != ndis)
|
|
Error ("Rank of array %s is not equal to the length of the dist_format_list", das->identifier(), 110,stdis);
|
|
|
|
if((ia & SAVE_BIT) || saveall || IN_MODULE)
|
|
sign = 1;
|
|
else
|
|
sign = 0;
|
|
if(ia & TEMPLATE_BIT) { //!!! must be changed
|
|
if(ia & ALIGN_BASE_BIT)
|
|
sign = 1;
|
|
else { //template is not used in ALIGN or REALIGN directive
|
|
//(is used only in parallel directive)
|
|
sign = 2;
|
|
loc_templ_symb=AddToSymbList(loc_templ_symb,das);
|
|
}
|
|
}
|
|
if(ia & POSTPONE_BIT)
|
|
indh = -1;
|
|
|
|
if(idisars == -1) { //interface of RTS2
|
|
CreateArray_RTS2(das,indh,stdis);
|
|
// distribute dvm-array
|
|
if(!(ia & POSTPONE_BIT)) //distr_rule_list!=NULL
|
|
doCallStmt(DvmhDistribute(das,rank,distr_rule_list));
|
|
where = savest;
|
|
goto TREE_;
|
|
}
|
|
// interface of RTS1
|
|
if(DEFERRED_SHAPE_TEMPLATE(das))
|
|
{
|
|
iamv = ndvm; ifst = iamv+1;
|
|
ArrayHeader(das,iamv);
|
|
doAssignStmt(new SgValueExp(0));
|
|
doAssignTo(HeaderRef(das),DVM000(iamv)); // t = AMViewRef
|
|
where = savest;
|
|
goto TREE_;
|
|
}
|
|
|
|
// dvm000(i) = crtamv(AMRef, rank, SizeArray, StaticSign)
|
|
// crtamv() creates current Abstract_Machine view
|
|
size_array = doSizeArray(das,stdis);
|
|
if(!rank) //distributee is not array
|
|
size_array = new SgValueExp(0); // for continuing translation of procedure
|
|
|
|
iamv = ndvm; ifst = iamv+1;
|
|
if(ia & POSTPONE_BIT){
|
|
//indh = -1;
|
|
if(ia & TEMPLATE_BIT)
|
|
//dvm000(i) = 0; (AMViewRef = 0)
|
|
doAssignStmt(new SgValueExp(0));
|
|
else
|
|
ifst = ndvm;
|
|
} else {
|
|
am_view = LeftPart_AssignStmt(CreateAMView(size_array, rank, sign));
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(am_view, mult_block, ndis));
|
|
//dvm000(i) = genbli(PSRef, AMViewRef, AxisWeightArray, AxisCount)
|
|
// genbli sets on the weights of elements of processor system
|
|
if(gen_block == 1)
|
|
doAssignStmt(GenBlock(ps,am_view, idisars+2*nblock,nblock));
|
|
if(gen_block == 2)
|
|
doAssignStmt(WeightBlock(ps,am_view, idisars+2*nblock, idisars+3*nblock,nblock));
|
|
//dvm000(i) = DisAM(AMViewRef, PSRef, ParamCount, AxisArray,DistrParamArray)
|
|
// DisAM distributes resourses of parent (current) AM between children
|
|
doAssignStmt(DistributeAM(am_view, ps, nblock, idisars, idisars+nblock));
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(am_view, mult_block, 0));
|
|
}
|
|
|
|
//if distributed object isn't template then
|
|
// 1) create distribute array (CrtDa)
|
|
// 2) align distribute array with AM view:
|
|
// align (i1,...,ik) with AM(i1,...,ik):: dist_array
|
|
|
|
|
|
if(! (ia & TEMPLATE_BIT)) {
|
|
// dvm000(i) = CrtDA (ArrayHeader,Base,Rank,TypeSize,SizeArray,
|
|
// StaticSign,ReDistrSign, LeftBSizeArray,RightBSizeArray)
|
|
// function CrtDA creates system structures, dosn't allocate array
|
|
|
|
ArrayHeader(das,indh);
|
|
array_header = HeaderRef(das);
|
|
//creating LeftBSizeArray and RightBSizeArray
|
|
ileft = ndvm;
|
|
iright = BoundSizeArrays(das);
|
|
if(ia & DYNAMIC_BIT)
|
|
re_sign = 3;
|
|
else
|
|
re_sign = 0;
|
|
|
|
StoreLowerBoundsPlus(das,NULL);
|
|
|
|
doAssignStmt(CreateDistArray(das,array_header,size_array,rank,ileft,iright,sign,re_sign));
|
|
|
|
//ndvm--; // CrtDa result is exit code, test and free
|
|
|
|
if(!(ia & POSTPONE_BIT)) {
|
|
|
|
// dvm000(i) = AlgnDA (ArrayHandle,AMViewHandle,
|
|
// Axis Array,Coeff Array),Const Array)
|
|
//function AlgnDA alignes the array according to aligning template
|
|
//actually AlgnDA distributes aligned array elements between virtual
|
|
//processors
|
|
iaxis = ndvm;
|
|
doAlignRule_1(rank);
|
|
// doAlignRule_1(axis_array,coeff_array,const_array);
|
|
doAssignStmt(AlignArray(array_header, am_view, iaxis, iaxis+rank, iaxis+2*rank));
|
|
|
|
// AlgnDA result is exit code, isn't used */
|
|
// axis_array, coeff_array and const_array arn't used more
|
|
}
|
|
SET_DVM(ileft);
|
|
|
|
//doAssignTo(header_ref(das,rank+2),HeaderNplus1(das));
|
|
// calculating HEADER(rank+1)
|
|
}
|
|
else
|
|
|
|
// adding to the Template_array Symbol the attribute (ARRAY_HEADER)
|
|
// with integer value "iamv"
|
|
{
|
|
ArrayHeader(das,iamv);
|
|
doAssignTo(HeaderRef(das),DVM000(iamv)); // t = AMViewRef
|
|
if(IN_COMMON(das))
|
|
StoreLowerBoundsPlus(das,NULL);
|
|
}
|
|
where = savest; //first_exec;
|
|
|
|
TREE_:
|
|
// Looking through the Align Tree of distributed array
|
|
if(das->numberOfAttributes(ALIGN_TREE)) {//there are any align statements
|
|
algn_attr * attr;
|
|
align * root;
|
|
|
|
postponed_root = (das->attributes() & POSTPONE_BIT);
|
|
attr = (algn_attr *) das->attributeValue(0,ALIGN_TREE);
|
|
root = attr->ref; // reference to root of align tree
|
|
// test: attr->type == ROOT ????
|
|
// for(node=root->alignees; node; node=node->next)
|
|
AlignTree(root);
|
|
}
|
|
if(!pointer_in_tree && !postponed_root) // there are not any allocatable aligned arrays in alignment_tree
|
|
{SET_DVM(ifst);}
|
|
//end GenDistArray
|
|
}
|
|
|
|
/*
|
|
void RedistributeArray_RTS2(das,headref,*distr_rule_list,stdis)
|
|
{
|
|
if(ia & POSTPONE_BIT) {
|
|
SgStatement *if_st,*end_if;
|
|
SgExpression *size_array;
|
|
int iaxis;
|
|
int iamv = INDEX(das);
|
|
if_st = doIfThenConstrForRedis(headref,stdis,iamv);
|
|
where = end_if = if_st->lexNext()->lexNext(); // reffer to ENDIF statement
|
|
|
|
int ia = das->attributes();
|
|
int rank = Rank(das);
|
|
|
|
// distribute dvm-array
|
|
if(distr_rule_list!=NULL)
|
|
doCallStmt(DvmhDistribute(das,rank,distr_rule_list));
|
|
}
|
|
else {
|
|
|
|
|
|
}
|
|
}
|
|
*/
|
|
|
|
void RedistributeArray(SgSymbol *das, int idisars, SgExpression *distr_rule_list, SgExpression *ps, int sign, SgExpression *dasref, SgStatement *stdis)
|
|
{ int rank,ia;
|
|
SgExpression *headref, *stre;
|
|
rank = Rank(das);
|
|
headref = IS_POINTER(das) ? PointerHeaderRef(dasref,1) : HeaderRef(das);
|
|
if(isSgRecordRefExp(dasref))
|
|
{ stre = & (dasref->copy());
|
|
stre-> setLhs(headref);
|
|
headref = stre;
|
|
}
|
|
if(rank && rank != ndis)
|
|
Error ("Rank of array '%s' isn't equal to the length of the dist_format_list",das->identifier(), 110,stdis);
|
|
|
|
ia=das->attributes();
|
|
if(!(ia & DYNAMIC_BIT) && !(ia & POSTPONE_BIT))
|
|
Error (" '%s' hasn't the DYNAMIC attribute",das->identifier(), 113,stdis);
|
|
if(!(ia & DISTRIBUTE_BIT) && !(ia & INHERIT_BIT))
|
|
Error (" '%s' does not appear in DISTRIBUTE/INHERIT directive ",das->identifier(), 114,stdis);
|
|
if(ia & ALIGN_BIT)
|
|
Error ("A distributee may not have the ALIGN attribute: %s",das->identifier(), 54, stdis);
|
|
if(!HEADER(das)) {
|
|
Error("'%s' isn't distributed array", das->identifier(), 72,stdis);
|
|
return;
|
|
}
|
|
|
|
if(idisars==-1) // indirect distribution => interface of RTS2
|
|
{
|
|
//RedistributeArray_RTS2(das,headref,distr_rule_list,stdis);
|
|
doCallStmt(DvmhRedistribute(das,rank,distr_rule_list));
|
|
doAssignTo(HeaderRefInd(das,HEADER_SIZE(das)),new SgValueExp(1)); // Header(HEADER_SIZE) = 1 => the array has been distributed already
|
|
return;
|
|
}
|
|
|
|
if(ia & POSTPONE_BIT){
|
|
SgStatement *if_st,*end_if;
|
|
SgExpression * size_array, *am_view, *amvref, *headref_flag;
|
|
int i1,st_sign,iaxis,iamv;
|
|
iamv = INDEX(das);
|
|
if(ia & TEMPLATE_BIT) //TEMPLATE ( iamv>1 )
|
|
headref_flag = headref;
|
|
else
|
|
headref_flag = IS_POINTER(das) ? PointerHeaderRef(dasref,HEADER_SIZE(das)) : HeaderRefInd(das,HEADER_SIZE(das));
|
|
if_st = doIfThenConstrForRedis(headref_flag,stdis,iamv); /*08.05.17*/
|
|
where = end_if = if_st->lexNext()->lexNext(); // reffer to ENDIF statement
|
|
i1 = ndvm;
|
|
if(ACC_program || parloop_by_handler) /*ACC*/
|
|
where->insertStmtBefore(*Redistribute_H(headref,sign),*where->controlParent());
|
|
amvref = (ia & TEMPLATE_BIT) ? headref : GetAMView( headref);
|
|
//inserting after ELSE
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(amvref, mult_block, ndis));
|
|
//dvm000(i) = genbli(PSRef, AMViewRef, AxisWeightArray, AxisCount)
|
|
// genbli sets on the weights of processor system elements
|
|
if(gen_block == 1)
|
|
doAssignStmt(GenBlock(ps,amvref, idisars+2*nblock,nblock));
|
|
if(gen_block == 2)
|
|
doAssignStmt(WeightBlock(ps,amvref,idisars+2*nblock,idisars+3*nblock,nblock));
|
|
doCallStmt(RedistributeAM(headref, ps, nblock,idisars,sign));
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(amvref, mult_block, 0));
|
|
where = if_st->lexNext(); // reffer to ELSE statement
|
|
//inserting after IF (...) THEN
|
|
if (DEFERRED_SHAPE_TEMPLATE(das))
|
|
am_view = DVM000(INDEX(das));
|
|
else
|
|
{
|
|
if(ia & TEMPLATE_BIT)
|
|
size_array = doSizeArray(das,stdis);
|
|
else
|
|
size_array = doSizeArrayQuery( IS_POINTER(das) ? headref : HeaderRefInd(das,1),rank);
|
|
if(!rank) //distributee is not array
|
|
size_array = new SgValueExp(0); // for continuing translation of procedure
|
|
|
|
// dvm000(i) = crtamv(AMRef, rank, SizeArray, StaticSign)
|
|
//crtamv creates current Abstract_Machine view
|
|
|
|
if((ia & SAVE_BIT) || saveall || IN_COMMON(das) || das->scope() != cur_func || IS_BY_USE(das) )
|
|
st_sign = 1;
|
|
else
|
|
st_sign = 0;
|
|
if(iamv <= 1) // is not TEMPLATE
|
|
iamv = ndvm++;
|
|
am_view = DVM000(iamv);
|
|
doAssignTo(am_view,CreateAMView(size_array, rank, st_sign));
|
|
}
|
|
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(am_view, mult_block, ndis));
|
|
//dvm000(i) = genbli(PSRef, AMViewRef, AxisWeightArray, AxisCount)
|
|
// genbli sets on the weights of elements of processor system
|
|
if(gen_block == 1)
|
|
doAssignStmt(GenBlock(ps,am_view, idisars+2*nblock,nblock));
|
|
if(gen_block == 2)
|
|
doAssignStmt(WeightBlock(ps,am_view, idisars+2*nblock, idisars+3*nblock,nblock));
|
|
//dvm000(i) = DisAM(AMViewRef, PSRef, ParamCount, AxisArray,DistrParamArray)
|
|
// DisAM distributes resourses of parent (current) AM between children
|
|
doAssignStmt(DistributeAM(am_view,ps,nblock,idisars,idisars+nblock));
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(am_view, mult_block, 0));
|
|
if (!(ia & TEMPLATE_BIT)) {
|
|
// dvm000(i) = AlgnDA (ArrayHandle,AMViewHandle,
|
|
// Axis Array,Coeff Array,Const Array)
|
|
//function AlgnDA alignes the array according to aligning template
|
|
//actually AlgnDA distributes aligned array elements between virtual
|
|
//processors
|
|
iaxis = ndvm;
|
|
doAlignRule_1(rank);
|
|
doAssignStmt(AlignArray( headref, am_view, iaxis, iaxis+rank, iaxis+2*rank));
|
|
doAssignTo(headref_flag, new SgValueExp(1)); // Header(HEADER_SIZE) == 1 => the array has been distributed already
|
|
} else
|
|
doAssignTo(headref,am_view); // t = AMViewRef
|
|
// Looking through the Align Tree of distributed array
|
|
if(das->numberOfAttributes(ALIGN_TREE) && !IS_ALLOCATABLE_POINTER(das)) {//there are any align statements
|
|
algn_attr * attr;
|
|
align * root;
|
|
attr = (algn_attr *) das->attributeValue(0,ALIGN_TREE);
|
|
root = attr->ref; // reference to the root of align tree
|
|
AlignTreeAlloc(root,stdis);
|
|
}
|
|
SET_DVM(i1);
|
|
cur_st = end_if; // => where 10.12.12 ;
|
|
where = stdis; //10.12.12
|
|
}
|
|
else {
|
|
SgExpression *amvref;
|
|
|
|
if(ACC_program || parloop_by_handler) /*ACC*/
|
|
where->insertStmtBefore(*Redistribute_H(headref,sign),*where->controlParent());
|
|
|
|
amvref = (ia & TEMPLATE_BIT) ? headref : GetAMView( headref);
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(amvref, mult_block, ndis));
|
|
if(gen_block == 1)
|
|
// genbli sets on the weights of processor system elements
|
|
doAssignStmt(GenBlock(ps,amvref, idisars+2*nblock,nblock));
|
|
if(gen_block == 2)
|
|
doAssignStmt(WeightBlock(ps,amvref,idisars+2*nblock,idisars+3*nblock,nblock));
|
|
doCallStmt(RedistributeAM(headref,ps,nblock,idisars,sign));
|
|
//doAssignTo_After(header_ref(das,rank+2),HeaderNplus1(das));
|
|
// calculating HEADER(rank+1)
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(amvref, mult_block, 0));
|
|
}
|
|
}
|
|
|
|
void AlignTree( align *root) {
|
|
align *node;
|
|
int nr,iaxis,ia;
|
|
SgStatement *stalgn;
|
|
int pointer_is;
|
|
stalgn = NULL;
|
|
pointer_is = 0;
|
|
iaxis = 0;
|
|
for(node=root->alignees; node; node=node->next) {
|
|
if (stalgn != node->align_stmt) {
|
|
if(IN_COMMON(node->symb) && (node->symb->scope()->variant() != PROG_HEDR) || !CURRENT_SCOPE(node->symb))
|
|
{ stalgn = NULL; ia = -1;}
|
|
else {
|
|
stalgn = node->align_stmt;
|
|
iaxis = ndvm; ia = 0;
|
|
}
|
|
}
|
|
else if(!INDEX(root->symb) || pointer_is || (INDEX(root->symb)==-1))
|
|
{ iaxis = ndvm; ia = 0;}
|
|
else
|
|
ia = iaxis;
|
|
if(IS_ALLOCATABLE(node->symb) || (IS_ALLOCATABLE(root->symb) && CURRENT_SCOPE(root->symb)))
|
|
ia = -2; //doAlignRule is empty: align rules are not generated
|
|
if(IS_POINTER_F90(node->symb) || (IS_POINTER_F90(root->symb) && !IS_DUMMY(root->symb) && CURRENT_SCOPE(root->symb)))
|
|
ia = -2; //doAlignRule is empty: align rules are not generated
|
|
SgExpression *align_rule_list = doAlignRules(node->symb,node->align_stmt,ia,nr);// creating axis_array,
|
|
// coeff_array and const_array
|
|
GenAlignArray(node,root, nr, align_rule_list, iaxis);
|
|
pointer_is = IS_POINTER(node->symb) || IS_ALLOCATABLE_POINTER(node->symb);
|
|
AlignTree(node);
|
|
}
|
|
}
|
|
|
|
|
|
void GenAlignArray(align *node, align *root, int nr, SgExpression *align_rule_list, int iaxis) {
|
|
|
|
// 1) creates Distribute Array for "node"
|
|
// 2) alignes Distribute Array with Distribute Array for "root" or with Template
|
|
|
|
// To array symbol added attribute ARRAY_HEADER (by function ArrayHeader):
|
|
// 0, for DVM-pointer
|
|
// -1, for array with postponed allignment and for array allined with one or DVM-pointer
|
|
// -2, for ALLOCATABLE array
|
|
// 1, for other arrays
|
|
|
|
int rank,ileft,iright,isize;
|
|
int sign,re_sign,ia,indh;
|
|
SgSymbol *als;
|
|
SgExpression *array_header,*size_array;
|
|
SgStatement *savest;
|
|
//st = first_exec; // store first_exec
|
|
savest = where;
|
|
als = node->symb;
|
|
ia = als->attributes();
|
|
|
|
// for debug
|
|
//printf("%s\n", als->identifier());
|
|
//
|
|
|
|
if(IS_POINTER(als)) { //alignee is POINTER
|
|
|
|
int *index = new int [2];
|
|
*index = iaxis;
|
|
*(index+1) = nr;
|
|
als-> addAttribute(ALIGN_RULE, (void*) index, 2*sizeof(int));
|
|
|
|
ArrayHeader(als,0);
|
|
loc_distr = 1; //POINTER is local object
|
|
pointer_in_tree = 1;
|
|
return;
|
|
}
|
|
if(IS_ALLOCATABLE(als)) { //alignee is ALLOCATABLE array
|
|
|
|
// int *index = new int [2];
|
|
// *index = 0; //iaxis;
|
|
// *(index+1) = nr;
|
|
// als-> addAttribute(ALIGN_RULE, (void*) index, 2*sizeof(int));
|
|
|
|
ArrayHeader(als,-2);
|
|
loc_distr = 1; //ALLOCATABLE array is local object
|
|
pointer_in_tree = 1;
|
|
return;
|
|
}
|
|
if(IS_POINTER_F90(als)) { // POINTER F90
|
|
if(IS_DUMMY(als))
|
|
ArrayHeader(als,1);
|
|
else{
|
|
ArrayHeader(als,-2);
|
|
pointer_in_tree = 1;
|
|
loc_distr = 1;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if(root){
|
|
indh = INDEX(root->symb);
|
|
if(CURRENT_SCOPE(root->symb) && ((indh == 0) || (indh == -1) || ((indh > 1) && (root->symb->attributes() & POSTPONE_BIT)))) {
|
|
//align-target is allocatable array: it is aligned directly
|
|
// or indirectly with POINTER
|
|
//or
|
|
//align-target is "postponed" array:it is aligned directly
|
|
// or indirectly with array having POSTPONE_BIT attribute
|
|
// or
|
|
// align-target is TEMPLATE with POSTPONE_BIT
|
|
int *index = new int [2];
|
|
*index = iaxis;
|
|
*(index+1) = nr;
|
|
als-> addAttribute(ALIGN_RULE, (void*) index, 2*sizeof(int));
|
|
|
|
ArrayHeader(als,-1);
|
|
indh = -1;
|
|
} else
|
|
ArrayHeader(als,1);
|
|
|
|
if(root && IS_ALLOCATABLE(root->symb) && CURRENT_SCOPE(root->symb)) {
|
|
Error("Array '%s' may not be alligned with ALLOCATABLE array",als->identifier(),401,node->align_stmt);
|
|
return;
|
|
}
|
|
|
|
} else {
|
|
ArrayHeader(als,-1); // with POSTPONE_BIT
|
|
indh = 1;
|
|
}
|
|
|
|
|
|
if(IS_TEMPLATE(als)){
|
|
Error("Template '%s' appears as an alignee",als->identifier(),116,node->align_stmt);
|
|
return;
|
|
}
|
|
if(IS_DUMMY(als)) { //alignee is dummy argument
|
|
if(!root) return;
|
|
if(!IS_DUMMY(root->symb)){ // align-target is local array
|
|
if(!IN_COMMON(root->symb) && CURRENT_SCOPE(root->symb))
|
|
Error("Dummy argument '%s' is aligned with a local array", als->identifier(),117, node->align_stmt);
|
|
}
|
|
else
|
|
if(warn_all)
|
|
warn("Associated actual arguments must be aligned",177,node->align_stmt);
|
|
return;
|
|
}
|
|
|
|
if(IN_COMMON(als)){ // COMMON-block element
|
|
if(root && !IN_COMMON(root->symb) && (root->symb->scope()->variant() != PROG_HEDR)) {
|
|
//align-target is not in COMMON and its scope is not MAIN-program
|
|
Error("Aligned array '%s' is in COMMON but align-target is not", als->identifier(), 118,node->align_stmt);
|
|
return;
|
|
}
|
|
if(als->scope()->variant() != PROG_HEDR) // is not in MAIN-program
|
|
return;
|
|
}
|
|
if(indh <= 0 && root && CURRENT_SCOPE(root->symb)) //align-target is allocatable or "postponed" array /podd 31.05.08/
|
|
return;
|
|
|
|
if(IS_SAVE(als)) { // has SAVE attribute
|
|
if(root && !IS_TEMPLATE(root->symb) && !IN_COMMON(root->symb) && !HAS_SAVE_ATTR(root->symb) && CURRENT_SCOPE(root->symb) ) {
|
|
Error("Aligned array '%s' has SAVE attribute but align-target has not", als->identifier(),119,node->align_stmt);
|
|
return;
|
|
}
|
|
}
|
|
if(IS_SAVE(als) || ORIGINAL_SYMBOL(als)->scope()->variant() == MODULE_STMT) {
|
|
SgStatement *ifst;
|
|
ifst = doIfThenConstr(als);
|
|
//first_exec = ifst->lexNext(); // reffer to ENDIF statement
|
|
where = ifst->lexNext(); // reffer to ENDIF statement
|
|
}
|
|
LINE_NUMBER_BEFORE(node->align_stmt,where);
|
|
// for tracing set the global variable of LibDVM to
|
|
// line number of ALIGN directive
|
|
|
|
array_header = HeaderRef(als);
|
|
rank = Rank(als);
|
|
|
|
if(INTERFACE_RTS2) { //interface of RTS2
|
|
|
|
doCallStmt(DvmhArrayCreate(als,array_header,rank,ListUnion(doDvmShapeList(als,node->align_stmt),DeclaredShadowWidths(als))));
|
|
if(!HAS_SAVE_ATTR(als) && !IN_MODULE)
|
|
doCallStmt(ScopeInsert(array_header));
|
|
if(!(ia & POSTPONE_BIT) && align_rule_list)
|
|
doCallStmt(DvmhAlign(als,root->symb,nr,align_rule_list));
|
|
where = savest;
|
|
return;
|
|
}
|
|
// interface of RTS1
|
|
isize = ndvm;
|
|
size_array = doSizeArray(als, node->align_stmt );
|
|
ileft = ndvm;
|
|
iright= BoundSizeArrays(als);
|
|
if((ia & SAVE_BIT) || saveall || IN_MODULE)
|
|
sign = 1;
|
|
else
|
|
sign = 0;
|
|
|
|
if(ia & DYNAMIC_BIT){
|
|
/*
|
|
if( IS_SAVE(als))
|
|
Error ("Saved object may not have the DYNAMIC attribute: %s", als->identifier(), 111,node->align_stmt);
|
|
|
|
if(IN_COMMON(als))
|
|
Error ("Object in COMMON may not have the DYNAMIC attribute: %s", als->identifier(), 112,node->align_stmt);
|
|
*/
|
|
re_sign = 2;
|
|
}
|
|
else if(ia & POSTPONE_BIT)
|
|
re_sign = 2;
|
|
else
|
|
re_sign = 0;
|
|
// aligned array may not be redisributed
|
|
|
|
StoreLowerBoundsPlus(als,NULL);
|
|
// dvm000(i) = CrtDA (ArrayHeader,Base,Rank,TypeSize,SizeArray,
|
|
// StaticSign,ReDistrSign, LeftBSizeArray,RightBSizeArray)
|
|
// function CrtDA creates system structures, dosn't allocate array
|
|
doAssignStmt(CreateDistArray(als, array_header, size_array,rank,ileft,iright,sign,re_sign));
|
|
/* ndvm--; // CrtDa result is exit code, test and free */
|
|
|
|
if(!(ia & POSTPONE_BIT)) {
|
|
// dvm000(i) = AlgnDA (ArrayHeader,PatternRef,
|
|
// Axis Array,Coeff Array,Const Array)
|
|
doAssignStmt(AlignArray(array_header,HeaderRef(root->symb),
|
|
iaxis, iaxis+nr,iaxis+2*nr));
|
|
//doAssignTo(header_ref(als,rank+2),HeaderNplus1(als));//calculating HEADER(rank+1)
|
|
}
|
|
SET_DVM(isize);
|
|
//first_exec = st; //restore first_exec
|
|
where = savest; //first_exec;
|
|
}
|
|
|
|
void RealignArray(SgSymbol *als, SgSymbol *tgs, int iaxis, int nr, SgExpression *align_rule_list, int new_sign, SgStatement *stal)
|
|
{ int ia,iamv;
|
|
SgStatement *if_st;
|
|
SgExpression *header_flag = HeaderRefInd(als,HEADER_SIZE(als));
|
|
|
|
ia=als->attributes();
|
|
if(!(ia & DYNAMIC_BIT) && !(ia & POSTPONE_BIT))
|
|
Error (" '%s' hasn't the DYNAMIC attribute",als->identifier(), 113,stal);
|
|
if(!(ia & ALIGN_BIT) && !(ia & INHERIT_BIT))
|
|
Error (" '%s' does not appear in ALIGN or INHERIT directive ",als->identifier(),120, stal);
|
|
if(ia & DISTRIBUTE_BIT)
|
|
Error ("An alignee may not have the DISTRIBUTE attribute: %s",als->identifier(), 57, stal);
|
|
if(!HEADER(als)) {
|
|
Error("%s isn't distributed array", als->identifier(), 72,stal);
|
|
return;
|
|
}
|
|
if(!HEADER(tgs))
|
|
return;
|
|
if(INTERFACE_RTS2)
|
|
{
|
|
doCallAfter(DvmhRealign(HeaderRef(als),new_sign,HeaderRef(tgs),nr,align_rule_list));
|
|
return;
|
|
}
|
|
iamv = ndvm;
|
|
if(ACC_program || parloop_by_handler) /*ACC*/
|
|
{ if( !(ia & POSTPONE_BIT) )
|
|
doCallAfter(Realign_H(HeaderRef(als),new_sign));
|
|
else {
|
|
if_st = doIfThenConstrForRealign(header_flag,cur_st,0);
|
|
cur_st = if_st;
|
|
doCallAfter(Realign_H(HeaderRef(als),new_sign));
|
|
cur_st = if_st->lexNext()->lexNext(); //ENDIF statement
|
|
}
|
|
}
|
|
doCallAfter(RealignArr(HeaderRef(als),HeaderRef(tgs),iaxis,iaxis+nr,iaxis+2*nr,new_sign));
|
|
|
|
|
|
if(ia & POSTPONE_BIT) {
|
|
if_st = doIfThenConstrForRealign(header_flag,cur_st,1);
|
|
where = if_st->lexNext(); // reffer to ENDIF statement
|
|
algn_attr *attr = (algn_attr *) als->attributeValue(0,ALIGN_TREE);
|
|
align *root = attr->ref; // reference to the root of align tree
|
|
if( !(ia & ALLOCATABLE_BIT) && !(ia & POINTER_BIT) && root->alignees)
|
|
// Looking through the Align Tree of array
|
|
AlignTreeAlloc(root,stal);
|
|
doAssignTo(header_flag, new SgValueExp(1));
|
|
SET_DVM(iamv);
|
|
cur_st = where;// ENDIF statement
|
|
where = stal; //11.12.12
|
|
}
|
|
}
|
|
|
|
void ALLOCATEf90_arrays(SgStatement *stmt, distribute_list *distr)
|
|
{SgExpression *alce,*al, *new_list, *apr;
|
|
SgSymbol *ar;
|
|
int dvm_flag = 0;
|
|
where = stmt;
|
|
ReplaceContext(stmt);
|
|
//LINE_NUMBER_BEFORE(stmt,stmt); /*26.10.17*/
|
|
if(stmt->hasLabel()) /*26.10.17*/
|
|
InsertNewStatementBefore(new SgStatement(CONT_STAT),stmt); // lab CONTINUE
|
|
SgStatement *prev = stmt->lexPrev();
|
|
new_list = stmt->expr(0); apr = NULL;
|
|
for(al=stmt->expr(0); al; al=al->rhs()) {
|
|
alce = al->lhs(); //allocation
|
|
|
|
if(isSgRecordRefExp(alce))
|
|
{ struct_component = alce;
|
|
alce = RightMostField(alce);
|
|
} else
|
|
struct_component = NULL;
|
|
ar = alce->symbol();
|
|
//ar = (isSgRecordRefExp(alce)) ? RightMostField(alce)->symbol() : alce->symbol();
|
|
if(!IS_ALLOCATABLE_POINTER(ar)) {
|
|
Error("An allocate/deallocate object must have the ALLOCATABLE or POINTER attribute: %s",ar->identifier(),287,stmt);
|
|
continue;
|
|
}
|
|
if(only_debug)
|
|
return;
|
|
if(ar->attributes() & DISTRIBUTE_BIT) {
|
|
//determine corresponding DISTRIBUTE statement
|
|
SgStatement *dist_st = (DISTRIBUTE_DIRECTIVE(ar)) ? *(DISTRIBUTE_DIRECTIVE(ar)) : NULL;
|
|
if(ar->attributes() & POINTER_BIT)
|
|
AllocatePointerHeader(ar,stmt);
|
|
if(struct_component)
|
|
ALLOCATEStructureComponent(ar,struct_component,alce,stmt);
|
|
//allocate distributed array
|
|
if(dist_st)
|
|
ALLOCATEf90DistArray(ar,alce,dist_st,stmt);
|
|
//delete from list of ALLOCATE statement
|
|
if(apr)
|
|
apr->setRhs(al->rhs());
|
|
else
|
|
new_list = al->rhs();
|
|
dvm_flag = 1;
|
|
}
|
|
|
|
else if(ar->attributes() & ALIGN_BIT) {
|
|
if(ar->attributes() & POINTER_BIT)
|
|
AllocatePointerHeader(ar,stmt);
|
|
//allocate aligned array
|
|
if(struct_component)
|
|
ALLOCATEStructureComponent(ar,struct_component,alce,stmt);
|
|
else
|
|
AllocateAlignArray(ar,alce,stmt);
|
|
//delete from list of ALLOCATE statement
|
|
if(apr)
|
|
apr->setRhs(al->rhs());
|
|
else
|
|
new_list = al->rhs();
|
|
dvm_flag = 1;
|
|
}
|
|
else
|
|
apr = al;
|
|
}
|
|
//replace allocation-list of ALLOCATE statement by new_list
|
|
//stmt->setExression(0,new_list);
|
|
if(new_list)
|
|
BIF_LL1(stmt->thebif)= new_list->thellnd;
|
|
else
|
|
BIF_LL1(stmt->thebif)= NULL;
|
|
|
|
if(dvm_flag)
|
|
LINE_NUMBER_AFTER_WITH_CP(stmt,prev,stmt->controlParent()); /*26.10.17*/
|
|
return;
|
|
}
|
|
|
|
void AllocatePointerHeader(SgSymbol *ar,SgStatement *stmt)
|
|
{SgStatement *alst;
|
|
SgExpression *headerRef, *structRef;
|
|
alst = new SgStatement(ALLOCATE_STMT);
|
|
headerRef = new SgArrayRefExp(*ar,*new SgValueExp(HEADER_SIZE(ar)));
|
|
if(ar->variant() == FIELD_NAME)
|
|
{ structRef = &(struct_component->copy());
|
|
structRef->setRhs(headerRef);
|
|
headerRef = structRef;
|
|
}
|
|
alst->setExpression(0, *new SgExprListExp(*headerRef));
|
|
//alst->setExpression(0, *new SgExprListExp(*new SgArrayRefExp(*ar,*new SgValueExp(HEADER_SIZE(ar)))));
|
|
InsertNewStatementBefore(alst,stmt);
|
|
}
|
|
|
|
void DEALLOCATEf90_arrays(SgStatement *stmt)
|
|
{SgExpression *al, *new_list, *apr;
|
|
SgSymbol *ar;
|
|
SgStatement *prev;
|
|
int dvm_flag = 0;
|
|
|
|
ReplaceContext(stmt);
|
|
//LINE_NUMBER_BEFORE(stmt,stmt); /*26.10.17*/
|
|
if(stmt->hasLabel()) /*26.10.17*/
|
|
InsertNewStatementBefore(new SgStatement(CONT_STAT),stmt); // lab CONTINUE
|
|
cur_st = prev = stmt->lexPrev();
|
|
new_list = stmt->expr(0); apr = NULL;
|
|
for(al=stmt->expr(0); al; al=al->rhs()) {
|
|
ar = (isSgRecordRefExp(al->lhs())) ? RightMostField(al->lhs())->symbol() : al->lhs()->symbol();
|
|
if(!IS_ALLOCATABLE_POINTER(ar)) {
|
|
Error("An allocate/deallocate object must have the ALLOCATABLE or POINTER attribute: %s",ar->identifier(),287,stmt);
|
|
continue;
|
|
}
|
|
if(ar->variant()==FIELD_NAME && IS_DVM_ARRAY(ar))
|
|
{ SgExpression *structRef, *headerRef;
|
|
headerRef = new SgArrayRefExp(*ar,*new SgValueExp(1));
|
|
structRef = &(al->lhs()->copy());
|
|
structRef->setRhs(headerRef);
|
|
headerRef = structRef;
|
|
InsertNewStatementAfter(DeleteObject_H(headerRef),cur_st,stmt->controlParent()); /*26.10.17*/
|
|
dvm_flag = 1;
|
|
//doCallAfter(DeleteObject_H(headerRef));
|
|
//if(ACC_program) /*ACC*/
|
|
//InsertNewStatementAfter(DestroyArray(headerRef),cur_st,stmt->controlParent());
|
|
|
|
apr = al;
|
|
continue;
|
|
}
|
|
if(HEADER(ar)) {
|
|
InsertNewStatementAfter(DeleteObject_H(HeaderRefInd(ar,1)),cur_st,stmt->controlParent()); /*26.10.17*/
|
|
dvm_flag = 1;
|
|
//if(ACC_program) /*ACC*/
|
|
//InsertNewStatementAfter(DestroyArray(HeaderRefInd(ar,1)),cur_st,stmt->controlParent());
|
|
//FREE_DVM(1);
|
|
//doCallAfter(DeleteObject_H(HeaderRefInd(ar,1)));
|
|
|
|
if(IS_POINTER_F90(ar)){
|
|
apr = al;
|
|
continue;
|
|
}
|
|
if(apr)
|
|
apr->setRhs(al->rhs());
|
|
else
|
|
new_list = al->rhs();
|
|
|
|
} else
|
|
{ apr = al;
|
|
InsertNewStatementAfter(DataExit(&al->lhs()->copy(),0),cur_st,stmt->controlParent()); /*26.10.17*/
|
|
//if(ACC_program) /*ACC*/
|
|
// InsertNewStatementAfter(DestroyScalar(&al->lhs()->copy()),cur_st,stmt->controlParent());
|
|
//doCallAfter(DataExit(&al->lhs()->copy(),0)); /*ACC*/
|
|
}
|
|
}
|
|
//replace deallocation-list of DEALLOCATE statement by new_list
|
|
if(new_list)
|
|
BIF_LL1(stmt->thebif)= new_list->thellnd;
|
|
else
|
|
BIF_LL1(stmt->thebif)= NULL;
|
|
|
|
if(dvm_flag)
|
|
LINE_NUMBER_AFTER_WITH_CP(stmt,prev,stmt->controlParent()); /*26.10.17*/
|
|
return;
|
|
}
|
|
|
|
|
|
void AllocateArray(SgStatement *stmt, distribute_list *distr)
|
|
{ SgExpression *desc;
|
|
SgSymbol *p;
|
|
if(!stmt->expr(1)->lhs()) {// empty argument list of allocate function call
|
|
err("Wrong argument list of ALLOCATE function call", 262, stmt);
|
|
return;
|
|
}
|
|
desc = stmt->expr(1)->lhs()->lhs(); //descriptor array reference
|
|
if(!isSgArrayRefExp(desc) || !desc->symbol() || (desc->symbol()->type()->baseType()->variant() != T_INT) || IS_POINTER(desc->symbol()) || IS_DVM_ARRAY(desc->symbol()))
|
|
{
|
|
err("Descriptor array error", 122, stmt);
|
|
return;
|
|
}
|
|
if(desc->lhs())
|
|
ChangeDistArrayRef(desc);
|
|
|
|
where = stmt;
|
|
p = stmt->expr(0)->symbol(); // pointer in left part
|
|
/*if (p->attributes() & DIMENSION_BIT)
|
|
Error("POINTER in left part has DIMENSION attribute: %s",p->identifier(),stmt);*/
|
|
if(p->attributes() & DISTRIBUTE_BIT) {
|
|
//determine corresponding DISTRIBUTE statement
|
|
SgStatement *dist_st;
|
|
SgExpression *el;
|
|
distribute_list *dsl;
|
|
dist_st = NULL;
|
|
for(dsl=distr; dsl && !dist_st; dsl=dsl->next)
|
|
for(el=dsl->stdis->expr(0); el; el=el->rhs())
|
|
if(el->lhs()->symbol() == p) {
|
|
dist_st = dsl->stdis;
|
|
break;
|
|
}
|
|
//allocate distributed array
|
|
ReplaceContext(stmt);
|
|
AllocateDistArray(p,desc,dist_st,stmt);
|
|
return;
|
|
}
|
|
|
|
if(p->attributes() & ALIGN_BIT) {
|
|
//allocate aligned array
|
|
ReplaceContext(stmt);
|
|
AllocateAlignArray(p,desc,stmt);
|
|
return;
|
|
}
|
|
|
|
Error("POINTER '%s' is not distributed object",p->identifier(), 85,stmt);
|
|
return;
|
|
}
|
|
|
|
void AllocateDistArray(SgSymbol *p, SgExpression *desc, SgStatement *stdis, SgStatement *stmt) {
|
|
|
|
int iamv,rank,iaxis,ileft,iright,ifst;
|
|
SgExpression *array_header, *size_array, *ps, *arglist, *lbound;
|
|
//SgSymbol *sheap;
|
|
int ia,sign,re_sign;
|
|
int idisars;
|
|
|
|
ifst = ndvm;
|
|
// if(IS_DUMMY(p) || IN_COMMON(p)) { //is dummy argument or COMMON-block element
|
|
// return;
|
|
//}
|
|
LINE_NUMBER_BEFORE(stmt,stmt); // for tracing set the global variable of LibDVM to
|
|
// line number of statement(stmt)
|
|
SgExpression *distr_rule_list = doDisRules(stdis,0,idisars);
|
|
//idisars = doDisRuleArrays(stdis,0,NULL);
|
|
if(idisars == -1)
|
|
Error ("INDIRECT/DERIVED format is not permitted for pointer %s", p->identifier(), 626,stdis);
|
|
rank = PointerRank(p);
|
|
if(ndis && rank && rank != ndis)
|
|
Error ("Rank of pointer %s is not equal to the length of the dist_format_list", p->identifier(), 123,stdis);
|
|
|
|
// dvm000(i) = CrtAMV(AMRef, rank, SizeArray, StaticSign)
|
|
//CrtAMV creates current Abstract_Machine view
|
|
ia = p->attributes();
|
|
size_array = ReverseDim(desc,rank);
|
|
if((ia & SAVE_BIT) || saveall || (ia & COMMON_BIT))
|
|
sign = 1;
|
|
else
|
|
sign = 0;
|
|
iamv = ndvm; /* ifst = iamv+1; */
|
|
if(!(ia & POSTPONE_BIT)){
|
|
doAssignStmt(CreateAMView(size_array, rank, sign));
|
|
|
|
ps = PSReference(stdis);
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(DVM000(iamv), mult_block, ndis));
|
|
//dvm000(i) = genbli(PSRef, AMViewRef, AxisWeightArray, AxisCount)
|
|
// genbli sets on the weights of elements of processor system
|
|
if(gen_block == 1)
|
|
doAssignStmt(GenBlock(ps,DVM000(iamv), idisars+2*nblock,nblock));
|
|
if(gen_block == 2)
|
|
doAssignStmt(WeightBlock(ps,DVM000(iamv),idisars+2*nblock, idisars+3*nblock,nblock));
|
|
//dvm000(i) = DisAM(AMViewRef, PSRef, ParamCount, AxisArray,DistrParamArray)
|
|
// DisAM distributes resourses of parent (current) AM between children
|
|
doAssignStmt(DistributeAM(DVM000(iamv),ps,nblock,idisars,idisars+nblock));
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(DVM000(iamv), mult_block, 0));
|
|
}
|
|
|
|
// dvm000(i) = CrtDA (ArrayHeader,Base,Rank,TypeSize,SizeArray,
|
|
// StaticSign,ReDistrSign, LeftBSizeArray,RightBSizeArray)
|
|
// function CrtDA creates system structures, doesn't allocate array
|
|
|
|
//sheap = heap_ar_decl ? heap_ar_decl->symbol() : p;//heap_ar_decl == NULL is user error
|
|
//doAssignTo(stmt->expr(0), ARRAY_ELEMENT(sheap,1));
|
|
// P = HEAP(1) or P(I) = HEAP(1)
|
|
if(!stmt->expr(0)->lhs()) // case P
|
|
doAssignTo(stmt->expr(0), new SgValueExp(POINTER_INDEX(p)));
|
|
// P = <heap-index> or P(I) = <heap-index>
|
|
else { // case P(I,...)
|
|
doAssignTo(stmt->expr(0), HeapIndex(stmt));
|
|
}
|
|
array_header = PointerHeaderRef(stmt->expr(0),1);
|
|
//doAssignTo( ARRAY_ELEMENT(sheap, 1), &(* ARRAY_ELEMENT(sheap, 1) + *new SgValueExp(HEADER_SIZE(p))));
|
|
//HEAP(1) = HEAP(1) + <header_size>
|
|
//doLogIfForHeap(sheap, heap_size);
|
|
|
|
//creating LeftBSizeArray and RightBSizeArray
|
|
ileft = ndvm;
|
|
iright = BoundSizeArrays(p);
|
|
if(ia & DYNAMIC_BIT)
|
|
re_sign = 3;
|
|
else
|
|
re_sign = 0;
|
|
arglist= stmt->expr(1)->lhs();
|
|
lbound=0;
|
|
if(arglist->rhs() && arglist->rhs()->rhs() && arglist->rhs()->rhs()->rhs() ) {//there are 3-nd and 4-nd argument of ALLOCATE function call
|
|
SgExpression *heap;
|
|
lbound = arglist->rhs()->rhs()->lhs(); //lower bound array reference ??
|
|
heap = arglist->rhs()->lhs(); //heap array reference ??
|
|
if(heap && isSgArrayRefExp(heap) && !heap->lhs() && lbound && isSgArrayRefExp(lbound))
|
|
;
|
|
else
|
|
lbound = 0;
|
|
}
|
|
if(!lbound)
|
|
StoreLowerBoundsPlus(p,stmt->expr(0));
|
|
else
|
|
StoreLowerBoundsPlusFromAllocate(p,stmt->expr(0),lbound);
|
|
doAssignStmt(CreateDistArray(p,array_header,size_array,rank,ileft,iright,sign,re_sign));
|
|
if(debug_regim && TestType(PointerType(p))) {
|
|
SgExpression *heap;
|
|
if(stmt->expr(1)->lhs()->rhs()) {//there is 2-nd argument of ALLOCATE function call
|
|
heap = stmt->expr(1)->lhs()->rhs()->lhs(); //heap array reference
|
|
if(heap && isSgArrayRefExp(heap) && !heap->lhs())
|
|
InsertNewStatementBefore(D_RegistrateArray(rank, TestType(PointerType(p)), GetAddresDVM(array_header),size_array,stmt->expr(0) ) ,stmt);
|
|
}
|
|
}
|
|
if(ia & POSTPONE_BIT)
|
|
{ SET_DVM(ifst); return;}
|
|
// dvm000(i) = AlgnDA (ArrayHandle,AMViewHandle,
|
|
// Axis Array,Coeff Array),Const Array)
|
|
//function AlgnDA alignes the array according to aligning template
|
|
//actually AlgnDA distributes aligned array elements between virtual
|
|
//processors
|
|
iaxis = ndvm;
|
|
doAlignRule_1(rank);
|
|
// doAlignRule_1(axis_array,coeff_array,const_array);
|
|
doAssignStmt(AlignArray(array_header, DVM000(iamv), iaxis, iaxis+rank, iaxis+2*rank));
|
|
// axis_array, coeff_array and const_array arn't used more
|
|
SET_DVM(ileft);
|
|
|
|
// doAssignTo(header_ref(p,rank+2),HeaderNplus1(p));
|
|
// calculating HEADER(rank+1)
|
|
|
|
|
|
// Looking through the Align Tree of distributed array
|
|
//algn_attr * attr;
|
|
//align * root;
|
|
if(p->numberOfAttributes(ALIGN_TREE)) {//there are any align statements
|
|
algn_attr * attr;
|
|
align * root;
|
|
attr = (algn_attr *) p->attributeValue(0,ALIGN_TREE);
|
|
root = attr->ref; // reference to root of align tree
|
|
|
|
AlignTreeAlloc(root,stmt);
|
|
}
|
|
|
|
SET_DVM(ifst);
|
|
}
|
|
|
|
void ALLOCATEf90DistArray(SgSymbol *p, SgExpression *desc, SgStatement *stdis, SgStatement *stmt) {
|
|
|
|
int iamv,rank,iaxis,ileft,iright,ifst;
|
|
SgExpression *array_header, *size_array, *ps;
|
|
int ia,sign,re_sign;
|
|
int idisars;
|
|
SgType *type;
|
|
/*
|
|
if(p->variant() == FIELD_NAME)
|
|
{ SgExpression *structRef ;
|
|
structRef = &(struct_component->copy());
|
|
array_header = new SgArrayRefExp(*p,*new SgValueExp(HEADER_SIZE(p)));
|
|
structRef->setRhs(array_header);
|
|
array_header = structRef;
|
|
|
|
} else
|
|
*/
|
|
if(!HEADER(p)) return;
|
|
ifst = ndvm;
|
|
|
|
//idisars = doDisRuleArrays(stdis,0,NULL);
|
|
SgExpression *distr_rule_list = doDisRules(stdis,0,idisars);
|
|
rank = Rank(p);
|
|
if(ndis && rank && rank != ndis)
|
|
Error ("Rank of array %s is not equal to the length of the dist_format_list", p->identifier(), 110,stdis);
|
|
type = p->type();
|
|
size_array = doSizeAllocArray(p,desc,stmt,(idisars==-1 ? RTS2 : RTS1));
|
|
array_header = HeaderRef(p);
|
|
ia = p->attributes();
|
|
|
|
if(idisars == -1) //interface of RTS2
|
|
{
|
|
SgExpression *shadow_list = DeclaredShadowWidths(p);
|
|
doCallStmt(DvmhArrayCreate(p,array_header,rank,ListUnion(size_array,shadow_list)));
|
|
//doCallStmt(ScopeInsert(array_header));
|
|
if(!(ia & POSTPONE_BIT)) //distr_rule_list!=NULL
|
|
doCallStmt(DvmhDistribute(p,rank,distr_rule_list)); // distribute dvm-array
|
|
SET_DVM(ifst);
|
|
return;
|
|
}
|
|
|
|
// dvm000(i) = crtamv(AMRef, rank, SizeArray, StaticSign)
|
|
// crtamv function creates current Abstract_Machine view
|
|
if((ia & SAVE_BIT) || saveall || (ia & COMMON_BIT) || p->scope()!=cur_func || IS_BY_USE(p))
|
|
sign = 1;
|
|
else
|
|
sign = 0;
|
|
iamv = ndvm;
|
|
if(!(ia & POSTPONE_BIT)){
|
|
doAssignStmt(CreateAMView(size_array, rank, sign));
|
|
ps = PSReference(stdis);
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(DVM000(iamv), mult_block, ndis));
|
|
//dvm000(i) = genbli(PSRef, AMViewRef, AxisWeightArray, AxisCount)
|
|
// genbli sets on the weights of elements of processor system
|
|
if(gen_block == 1)
|
|
doAssignStmt(GenBlock(ps,DVM000(iamv), idisars+2*nblock,nblock));
|
|
if(gen_block == 2)
|
|
doAssignStmt(WeightBlock(ps,DVM000(iamv),idisars+2*nblock, idisars+3*nblock,nblock));
|
|
//dvm000(i) = DisAM(AMViewRef, PSRef, ParamCount, AxisArray,DistrParamArray)
|
|
// DisAM distributes resourses of parent (current) AM between children
|
|
doAssignStmt(DistributeAM(DVM000(iamv),ps,nblock,idisars,idisars+nblock));
|
|
if(mult_block)
|
|
doAssignStmt(MultBlock(DVM000(iamv), mult_block, 0));
|
|
}
|
|
|
|
// dvm000(i) = CrtDA (ArrayHeader,Base,Rank,TypeSize,SizeArray,
|
|
// StaticSign,ReDistrSign, LeftBSizeArray,RightBSizeArray)
|
|
// function CrtDA creates system structures, doesn't allocate array
|
|
|
|
//creating LeftBSizeArray and RightBSizeArray
|
|
ileft = ndvm;
|
|
iright = BoundSizeArrays(p);
|
|
if(ia & DYNAMIC_BIT)
|
|
re_sign = 3;
|
|
else
|
|
re_sign = 0;
|
|
|
|
StoreLowerBoundsPlusOfAllocatable(p,desc);
|
|
|
|
doAssignStmt(CreateDistArray(p,array_header,size_array,rank,ileft,iright,sign,re_sign));
|
|
if(debug_regim && TestType(type))
|
|
InsertNewStatementBefore(D_RegistrateArray(rank, TestType(type), GetAddresDVM(HeaderRefInd(p,1)),size_array,new SgVarRefExp(p)) ,stmt);
|
|
|
|
if(ia & POSTPONE_BIT)
|
|
{ SET_DVM(ifst); return;}
|
|
|
|
// dvm000(i) = AlgnDA (ArrayHandle,AMViewHandle,
|
|
// Axis Array,Coeff Array),Const Array)
|
|
//function AlgnDA alignes the array according to aligning template
|
|
//actually AlgnDA distributes aligned array elements between virtual processors
|
|
|
|
iaxis = ndvm;
|
|
doAlignRule_1(rank);
|
|
doAssignStmt(AlignArray(array_header, DVM000(iamv), iaxis, iaxis+rank, iaxis+2*rank));
|
|
|
|
SET_DVM(ifst);
|
|
}
|
|
|
|
void ALLOCATEStructureComponent(SgSymbol *p, SgExpression *struct_e, SgExpression *desc, SgStatement *stmt) {
|
|
|
|
int rank,ileft,iright,ifst;
|
|
SgExpression *array_header, *size_array;
|
|
int ia,sign,re_sign;
|
|
SgType *type;
|
|
SgExpression *structRef, *struct_ , *struct_comp;
|
|
// p->variant() == FIELD_NAME
|
|
|
|
structRef = &(struct_e->copy());
|
|
array_header = new SgArrayRefExp(*p, *new SgValueExp(1)); //*new SgValueExp(HEADER_SIZE(p)));
|
|
structRef->setRhs(array_header);
|
|
array_header = structRef;
|
|
ifst = ndvm;
|
|
rank = Rank(p);
|
|
type = p->type();
|
|
size_array = doSizeAllocArray(p,desc,stmt,(INTERFACE_RTS2 ? RTS2:RTS1));
|
|
if( INTERFACE_RTS2 ) // interface of RTS2
|
|
{
|
|
doCallStmt(DvmhArrayCreate(p,array_header,rank,ListUnion(size_array,DeclaredShadowWidths(p))));
|
|
//doCallStmt(ScopeInsert(array_header));
|
|
return;
|
|
}
|
|
//interface of RTS1
|
|
SgSymbol *s_struct = LeftMostField(struct_e)->symbol();
|
|
ia = s_struct->attributes();
|
|
if((ia & SAVE_BIT) || saveall || (ia & COMMON_BIT) || s_struct->scope()!=cur_func || IS_BY_USE(s_struct))
|
|
sign = 1;
|
|
else
|
|
sign = 0;
|
|
|
|
// dvm000(i) = CrtDA (ArrayHeader,Base,Rank,TypeSize,SizeArray,
|
|
// StaticSign,ReDistrSign, LeftBSizeArray,RightBSizeArray)
|
|
// function CrtDA creates system structures, doesn't allocate array
|
|
|
|
//creating LeftBSizeArray and RightBSizeArray
|
|
ileft = ndvm;
|
|
iright = BoundSizeArrays(p);
|
|
if(p->attributes() & DYNAMIC_BIT)
|
|
re_sign = 3;
|
|
else
|
|
re_sign = 0;
|
|
|
|
struct_ = &(struct_e->copy());
|
|
struct_ ->setRhs(NULL);
|
|
StoreLowerBoundsPlusOfAllocatableComponent(p,desc,struct_);
|
|
|
|
doAssignStmt(CreateDistArray(p,array_header,size_array,rank,ileft,iright,sign,re_sign));
|
|
struct_comp = &(struct_->copy());
|
|
struct_comp->setRhs(new SgArrayRefExp(*p));
|
|
if(debug_regim && TestType(type))
|
|
InsertNewStatementBefore(D_RegistrateArray(rank, TestType(type), GetAddresDVM(header_ref_in_structure(p,1,struct_)),size_array,struct_comp) ,stmt);
|
|
|
|
SET_DVM(ifst);
|
|
return;
|
|
}
|
|
|
|
|
|
void AlignTreeAlloc( align *root,SgStatement *stmt) {
|
|
align *node;
|
|
int nr,iaxis=-1,ia,*ix;
|
|
SgStatement *stalgn;
|
|
SgExpression *align_rule_list=NULL;
|
|
stalgn = NULL;
|
|
|
|
for(node=root->alignees; node; node=node->next) {
|
|
if(IS_POINTER(node->symb)) //node is pointer must not be allocated
|
|
continue;
|
|
ix = ALIGN_RULE_INDEX(node->symb);
|
|
if(ix)
|
|
{iaxis = *ix; nr = *(++ix);}
|
|
else {
|
|
if (stalgn != node->align_stmt) {
|
|
stalgn = node->align_stmt;
|
|
iaxis = ndvm; ia = 0;
|
|
}
|
|
else
|
|
ia = iaxis;
|
|
align_rule_list = doAlignRules(node->symb,node->align_stmt,ia,nr);// creating axis_array,
|
|
} // coeff_array and const_array
|
|
|
|
AlignAllocArray(node,root, nr, iaxis, NULL, stmt);
|
|
AlignTreeAlloc(node,stmt);
|
|
}
|
|
}
|
|
align *CopyAlignTreeNode(SgSymbol *ar)
|
|
{
|
|
algn_attr * attr;
|
|
align *node, *node_copy;
|
|
SgStatement *algn_st;
|
|
|
|
attr = (algn_attr *) ORIGINAL_SYMBOL(ar)->attributeValue(0,ALIGN_TREE);
|
|
node = attr->ref; // reference to root of align tree
|
|
node_copy = new align;
|
|
node_copy->symb = ar;
|
|
node_copy->align_stmt = node->align_stmt;
|
|
//algn_st = node->align_stmt;
|
|
return(node_copy);
|
|
}
|
|
|
|
void AllocateAlignArray(SgSymbol *p, SgExpression *desc, SgStatement *stmt) {
|
|
int nr=0,iaxis=0,*ix=NULL,ifst=0;
|
|
SgStatement *algn_st;
|
|
SgSymbol *base, *pb;
|
|
SgExpression *align_rule_list;
|
|
align *node,*root=NULL, *node_copy;
|
|
ifst = ndvm;
|
|
pb = ORIGINAL_SYMBOL(p);
|
|
if(!pb->attributeValue(0,ALIGN_TREE))
|
|
return;
|
|
node = ((algn_attr *) pb->attributeValue(0,ALIGN_TREE))->ref;
|
|
algn_st = node->align_stmt;
|
|
node_copy = IS_BY_USE(p) ? CopyAlignTreeNode(p) : node;
|
|
if(algn_st->expr(2)){
|
|
base = (algn_st->expr(2)->variant()==ARRAY_OP) ? (algn_st->expr(2))->rhs()->symbol() : (algn_st->expr(2))->symbol();// align_base symbol
|
|
root = ((algn_attr *) base->attributeValue(0,ALIGN_TREE))->ref;
|
|
}
|
|
if(IS_ALLOCATABLE_POINTER(p)){
|
|
AlignAllocArray(node_copy,root,0,0,desc,stmt);
|
|
return;
|
|
}
|
|
/*
|
|
if(!algn_st->expr(2)){ //postponed aligning
|
|
root = NULL;
|
|
if(IS_ALLOCATABLE_POINTER(p)){
|
|
AlignAllocArray(node,root,0,0,desc,stmt);
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
base = (algn_st->expr(2)->variant()==ARRAY_OP) ? (algn_st->expr(2))->rhs()->symbol() : (algn_st->expr(2))->symbol();// align_base symbol
|
|
root = ((algn_attr *) base->attributeValue(0,ALIGN_TREE))->ref;
|
|
|
|
if(IS_ALLOCATABLE_POINTER(p)){
|
|
AlignAllocArray(node,root,0,0,desc,stmt);
|
|
return;
|
|
}
|
|
*/
|
|
if(root) {
|
|
LINE_NUMBER_BEFORE(stmt,stmt); // for tracing set the global variable of LibDVM to
|
|
// line number of statement(stmt)
|
|
ix = ALIGN_RULE_INDEX(p);
|
|
if(ix)
|
|
{iaxis = *ix; nr = *(++ix);}
|
|
else {
|
|
iaxis = ndvm;
|
|
align_rule_list = doAlignRules(p,algn_st,0,nr);
|
|
}
|
|
}
|
|
//sheap = heap_ar_decl ? heap_ar_decl->symbol() : p;//heap_ar_decl == NULL is user error
|
|
//doAssignTo(stmt->expr(0), ARRAY_ELEMENT(sheap,1));
|
|
// P = HEAP(1) or P(I) = HEAP(1)
|
|
if(!stmt->expr(0)->lhs()) // case P
|
|
doAssignTo(stmt->expr(0), new SgValueExp(POINTER_INDEX(p)));
|
|
// P = <heap-index> or P(I) = <heap-index>
|
|
else { // case P(I,...)
|
|
doAssignTo(stmt->expr(0), HeapIndex(stmt));
|
|
}
|
|
//doAssignTo( ARRAY_ELEMENT(sheap, 1), &(* ARRAY_ELEMENT(sheap, 1) + *new SgValueExp(HEADER_SIZE(p))));
|
|
//HEAP(1) = HEAP(1) + <header_size>
|
|
//doLogIfForHeap(sheap, heap_size); //IF(HEAP(1) > heap_size) STOP 'HEAP limit is exceeded'
|
|
|
|
AlignAllocArray(node,root,nr,iaxis,desc,stmt);
|
|
AlignTreeAlloc(node,stmt);
|
|
SET_DVM(ifst);
|
|
}
|
|
|
|
void AlignAllocArray(align *node, align *root, int nr, int iaxis,SgExpression *desc, SgStatement *stmt) {
|
|
|
|
// 1) creates Distributed Array for "node"
|
|
// 2) alignes Distributed Array with Distributed Array for "root" or with
|
|
// Template
|
|
|
|
int rank,ileft,iright,isize;
|
|
int sign,re_sign,ia;
|
|
SgSymbol *als;
|
|
SgExpression *array_header,*size_array,*pref, *arglist, *lbound;
|
|
SgExpression *align_rule_list;
|
|
SgType *type;
|
|
|
|
als = node->symb;
|
|
ia = als->attributes();
|
|
|
|
if(!HEADER(ORIGINAL_SYMBOL(als))){
|
|
Error("Array '%s' may not be allocated", als->identifier(),124,node->align_stmt);
|
|
return;
|
|
}
|
|
if(IS_TEMPLATE(als) || IS_DUMMY(als) || (IN_COMMON(als) && !IS_POINTER(als) && !IS_ALLOCATABLE_POINTER(als)))
|
|
return;
|
|
|
|
if(IS_SAVE(als)) { // has SAVE attribute
|
|
if(root && !IS_TEMPLATE(root->symb) && !IN_COMMON(root->symb) && !HAS_SAVE_ATTR(root->symb) && CURRENT_SCOPE(root->symb) ) {
|
|
Error("Aligned array '%s' has SAVE attribute but align-target has not", als->identifier(),119,node->align_stmt);
|
|
return;
|
|
}
|
|
SgStatement *ifst;
|
|
ifst = doIfThenConstr(als);
|
|
where = ifst->lexNext(); // reffer to ENDIF statement
|
|
}
|
|
LINE_NUMBER_BEFORE(stmt,where);
|
|
rank = Rank(als);
|
|
|
|
if(INTERFACE_RTS2) { //interface of RTS2
|
|
size_array = NULL;
|
|
array_header = HeaderRef(als);
|
|
if(IS_ALLOCATABLE_POINTER(als))
|
|
size_array = doSizeAllocArray(als, desc, stmt, RTS2);
|
|
else if(!IS_POINTER(als))
|
|
size_array = doDvmShapeList(als,node->align_stmt);
|
|
doCallStmt(DvmhArrayCreate(als,array_header,rank,ListUnion(size_array,DeclaredShadowWidths(als))));
|
|
//doCallStmt(ScopeInsert(array_header));
|
|
align_rule_list = root ? doAlignRules(node->symb,node->align_stmt,0,nr) : NULL;
|
|
if( root && align_rule_list) //!(ia & POSTPONE_BIT)
|
|
doCallStmt(DvmhAlign(als,root->symb,nr,align_rule_list));
|
|
if(IS_SAVE(als))
|
|
where = where->lexNext();
|
|
return;
|
|
}
|
|
//interface of RTS1
|
|
isize = ndvm;
|
|
if(IS_POINTER(als)){
|
|
size_array = ReverseDim(desc,rank);
|
|
pref = where->expr(0);
|
|
array_header = PointerHeaderRef(pref,1);
|
|
type = PointerType(als);
|
|
} else if(IS_ALLOCATABLE_POINTER(als)) {
|
|
size_array = doSizeAllocArray(als, desc, stmt, RTS1);
|
|
pref = NULL;
|
|
array_header = HeaderRef(als);
|
|
type = als->type();
|
|
} else {
|
|
size_array = doSizeArray(als, node->align_stmt );
|
|
pref = NULL;
|
|
array_header = HeaderRef(als);
|
|
type = als->type();
|
|
}
|
|
|
|
ileft = ndvm;
|
|
iright= BoundSizeArrays(als);
|
|
if((ia & SAVE_BIT) || saveall || (ia & COMMON_BIT) || als->scope()!=cur_func || IS_BY_USE(als))
|
|
sign = 1;
|
|
else
|
|
sign = 0;
|
|
|
|
if(ia & DYNAMIC_BIT)
|
|
re_sign = 2;
|
|
else
|
|
re_sign = 0;
|
|
//re_sign = 0; aligned array may not be redisributed
|
|
if(IS_ALLOCATABLE_POINTER(als)) {
|
|
StoreLowerBoundsPlusOfAllocatable(als,desc);
|
|
iaxis = ndvm;
|
|
if(root) //!(ia & POSTPONE_BIT)
|
|
align_rule_list = doAlignRules(node->symb,node->align_stmt,0,nr); //nr = doAlignRule(als,node->align_stmt,0);
|
|
}
|
|
else {
|
|
arglist= stmt->expr(1)->lhs();
|
|
lbound=0;
|
|
if(arglist->rhs() && arglist->rhs()->rhs() && arglist->rhs()->rhs()->rhs() ) {//there are 3-nd and 4-nd argument of ALLOCATE function call
|
|
SgExpression *heap;
|
|
lbound = arglist->rhs()->rhs()->lhs(); //lower bound array reference ??
|
|
heap = arglist->rhs()->lhs(); //heap array reference ??
|
|
if(heap && isSgArrayRefExp(heap) && !heap->lhs() && lbound && isSgArrayRefExp(lbound))
|
|
;
|
|
else
|
|
lbound = 0;
|
|
}
|
|
if(!lbound)
|
|
StoreLowerBoundsPlus(als,pref);
|
|
else
|
|
StoreLowerBoundsPlusFromAllocate(als,pref,lbound);
|
|
}
|
|
|
|
// dvm000(i) = CrtDA (ArrayHeader,Base,Rank,TypeSize,SizeArray,
|
|
// StaticSign,ReDistrSign, LeftBSizeArray,RightBSizeArray)
|
|
// function CrtDA creates system structures, dosn't allocate array
|
|
doAssignStmt(CreateDistArray(als, array_header, size_array,rank,ileft,iright,sign,re_sign));
|
|
if( debug_regim && TestType(type)) {
|
|
if(IS_POINTER(als) ){
|
|
SgExpression *heap;
|
|
if(stmt->expr(1)->lhs()->rhs()) {//there is 2-nd argument of ALLOCATE function call
|
|
heap = stmt->expr(1)->lhs()->rhs()->lhs(); //heap array reference
|
|
if(heap && isSgArrayRefExp(heap) && !heap->lhs())
|
|
InsertNewStatementBefore(D_RegistrateArray(rank, TestType(PointerType(als)), GetAddresDVM(array_header),size_array,stmt->expr(0) ) ,stmt);
|
|
}
|
|
} else if(IS_ALLOCATABLE_POINTER(als))
|
|
InsertNewStatementBefore(D_RegistrateArray(rank, TestType(type), GetAddresDVM(HeaderRefInd(als,1)),size_array,new SgVarRefExp(als)),stmt);
|
|
else
|
|
InsertNewStatementBefore(D_RegistrateArray(rank, TestType(type), GetAddresDVM(HeaderRefInd(als,1)),size_array,new SgVarRefExp(als)),where);
|
|
}
|
|
if(root) // non postponed aligning ((ia & POSTPONE_BIT)==0)
|
|
|
|
// dvm000(i) = AlgnDA (ArrayHeader,PatternRef,
|
|
// Axis Array,Coeff Array,Const Array)
|
|
doAssignStmt(AlignArray(array_header,HeaderRef(root->symb),
|
|
iaxis, iaxis+nr,iaxis+2*nr));
|
|
|
|
//doAssignTo(header_ref(als,rank+2),HeaderNplus1(als));//calculating HEADER(rank+1)
|
|
SET_DVM(isize);
|
|
if(IS_SAVE(als))
|
|
where = where->lexNext();
|
|
}
|
|
|
|
void PostponedAlignArray(align *node, align *root, int nr, int iaxis) {
|
|
|
|
// 1) creates Distributed Array for "node"
|
|
// 2) alignes Distributed Array with Distributed Array for "root"
|
|
|
|
int rank,ileft,iright,isize;
|
|
int sign,re_sign,ia;
|
|
SgSymbol *als;
|
|
SgExpression *array_header,*size_array;
|
|
|
|
als = node->symb;
|
|
ia = als->attributes();
|
|
|
|
if(!HEADER(als)){
|
|
Error("Array '%s' may not be aligned", als->identifier(),125,node->align_stmt);
|
|
return;
|
|
}
|
|
if(IS_TEMPLATE(als) || IS_DUMMY(als) || IN_COMMON(als))
|
|
return;
|
|
|
|
if(IS_SAVE(als)) { // has SAVE attribute
|
|
if(root && !IS_TEMPLATE(root->symb) && !IN_COMMON(root->symb) && !HAS_SAVE_ATTR(root->symb) && CURRENT_SCOPE(root->symb) ) {
|
|
Error("Aligned array '%s' has SAVE attribute but align-target has not", als->identifier(),119,node->align_stmt);
|
|
return;
|
|
}
|
|
SgStatement *ifst;
|
|
ifst = doIfThenConstr(als);
|
|
where = ifst->lexNext(); // reffer to ENDIF statement
|
|
}
|
|
LINE_NUMBER_BEFORE(node->align_stmt,where);
|
|
// for tracing set the global variable of LibDVM to
|
|
// line number of ALIGN directive
|
|
array_header = HeaderRef(als);
|
|
isize = ndvm;
|
|
size_array = doSizeArray(als, node->align_stmt );
|
|
rank = Rank(als);
|
|
ileft = ndvm;
|
|
iright= BoundSizeArrays(als);
|
|
if((ia & SAVE_BIT) || saveall)
|
|
sign = 1;
|
|
else
|
|
sign = 0;
|
|
|
|
if(ia & DYNAMIC_BIT)
|
|
re_sign = 2;
|
|
else
|
|
re_sign = 0;
|
|
|
|
StoreLowerBoundsPlus(als,NULL);
|
|
|
|
// dvm000(i) = CrtDA (ArrayHeader,Base,Rank,TypeSize,SizeArray,
|
|
// StaticSign,ReDistrSign, LeftBSizeArray,RightBSizeArray)
|
|
// function CrtDA creates system structures, dosn't allocate array
|
|
doAssignStmt(CreateDistArray(als, array_header, size_array,rank,ileft,iright,sign,re_sign));
|
|
|
|
// dvm000(i) = AlgnDA (ArrayHeader,PatternRef,
|
|
// Axis Array,Coeff Array,Const Array)
|
|
doAssignStmt(AlignArray(array_header,HeaderRef(root->symb),
|
|
iaxis, iaxis+nr,iaxis+2*nr));
|
|
SET_DVM(isize);
|
|
if(IS_SAVE(als))
|
|
where = where->lexNext();
|
|
}
|
|
|
|
void Template_Create(SgStatement *stmt)
|
|
{
|
|
SgExpression *el;
|
|
int isave = ndvm;
|
|
for(el = stmt->expr(0); el; el=el->rhs())
|
|
{
|
|
if(isSgArrayRefExp(el->lhs()))
|
|
{
|
|
SgSymbol *s = el->lhs()->symbol();
|
|
int rank = Rank(s);
|
|
if(!HEADER(s))
|
|
{
|
|
Error("'%s' has not DISTRIBUTE attribute ", s->identifier(), 637,stmt);
|
|
continue;
|
|
}
|
|
if(!(s->attributes() & POSTPONE_BIT))
|
|
{
|
|
Error("Template '%s' has no postponed distribution", s->identifier(), 638,stmt);
|
|
continue;
|
|
}
|
|
if(!DEFERRED_SHAPE_TEMPLATE(s))
|
|
{
|
|
Error("Template '%s' has no deferred shape", s->identifier(), 640,stmt);
|
|
continue;
|
|
}
|
|
where = stmt;
|
|
SgExpression *size_array = doSizeAllocArray(s, el->lhs(), stmt, (INTERFACE_RTS2 ? RTS2 : RTS1));
|
|
cur_st = stmt;
|
|
if(INTERFACE_RTS2)
|
|
{
|
|
doCallAfter(DvmhTemplateCreate(s,HeaderRef(s),rank,size_array));
|
|
//doCallAfter(ScopeInsert(HeaderRef(s)));
|
|
}
|
|
else
|
|
{
|
|
doAssignTo_After(DVM000(INDEX(s)),CreateAMView(size_array, rank, 1));
|
|
where = cur_st;
|
|
StoreLowerBoundsPlusOfAllocatable(s,el->lhs());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err("Illegal element of list",636,stmt);
|
|
continue;
|
|
}
|
|
}
|
|
SET_DVM(isave);
|
|
}
|
|
|
|
void Template_Delete(SgStatement *stmt)
|
|
{
|
|
SgExpression *el;
|
|
for(el = stmt->expr(0); el; el=el->rhs())
|
|
{
|
|
if(isSgArrayRefExp(el->lhs()))
|
|
{
|
|
SgSymbol *s = el->lhs()->symbol();
|
|
if(!HEADER(s))
|
|
{
|
|
Error("'%s' has not DISTRIBUTE attribute ", s->identifier(), 637,stmt);
|
|
continue;
|
|
}
|
|
if(!DEFERRED_SHAPE_TEMPLATE(s))
|
|
{
|
|
Error("Template '%s' has no deferred shape", s->identifier(), 640,stmt);
|
|
continue;
|
|
}
|
|
|
|
doCallAfter(DeleteObject_H(HeaderRef(s)));
|
|
}
|
|
else
|
|
{
|
|
err("Illegal element of list",636,stmt);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
SgExpression * dvm_array_ref () {
|
|
// creates array reference: dvm000(i) , i - index of first free element
|
|
SgValueExp * index = new SgValueExp(ndvm);
|
|
return( new SgArrayRefExp(*dvmbuf, *index));
|
|
}
|
|
|
|
SgExpression * dvm_ref (int n) {
|
|
// creates array reference: dvm000(n)
|
|
SgValueExp * index = new SgValueExp(n);
|
|
return( new SgArrayRefExp(*dvmbuf, *index));
|
|
}
|
|
|
|
|
|
void Align_Tree(align *root) {
|
|
align *p;
|
|
if (!root)
|
|
return;
|
|
|
|
// looking through alignees of the root
|
|
for(p=root->alignees; p; p=p->next)
|
|
{
|
|
//printf(" %s is aligned with %s (statement at line %d)\n", p->symb->identifier(), root->symb->identifier(), p->align_stmt->lineNumber());
|
|
Align_Tree(p);
|
|
}
|
|
return;
|
|
}
|
|
|
|
stmt_list *addToStmtList(stmt_list *pstmt, SgStatement *stat)
|
|
{
|
|
// adding the statement to the beginning of statement list
|
|
// pstmt-> stat -> stmt-> ... -> stmt
|
|
stmt_list * stl;
|
|
if (!pstmt) {
|
|
pstmt = new stmt_list;
|
|
pstmt->st = stat;
|
|
pstmt->next = NULL;
|
|
} else {
|
|
stl = new stmt_list;
|
|
stl->st = stat;
|
|
stl->next = pstmt;
|
|
pstmt = stl;
|
|
}
|
|
return (pstmt);
|
|
}
|
|
|
|
stmt_list *delFromStmtList(stmt_list *pstmt)
|
|
{
|
|
// deletinging last statement from the statement list
|
|
// pstmt-> stat -> stmt-> ... -> stmt
|
|
pstmt = pstmt->next;
|
|
return (pstmt);
|
|
}
|
|
|
|
void RenamingDvmArraysByUse(SgStatement *stmt)
|
|
{
|
|
SgSymbol *ar;
|
|
SgExpression *e = stmt->expr(0), *el;
|
|
|
|
if(e && e->variant()==ONLY_NODE)
|
|
e = e->lhs();
|
|
for(el=e; el; el=el->rhs())
|
|
{
|
|
ar = el->lhs()->lhs()->symbol();
|
|
if(!IS_DVM_ARRAY(ar)) continue;
|
|
// if(el->lhs()->rhs())
|
|
if(strcmp(ar->identifier(),ORIGINAL_SYMBOL(ar)->identifier())) //case of renaming in a use statement
|
|
{ //printf("%s %s SCOPE: %s\n", ar->identifier(),ORIGINAL_SYMBOL(ar)->identifier(),ar->scope()->symbol()->identifier());
|
|
//adding the distributed array symbol 'ar' to symb_list 'dsym'
|
|
if(!(ar->attributes() & DVM_POINTER_BIT))
|
|
AddDistSymbList(ar);
|
|
// creating variables used for optimisation array references in parallel loop
|
|
coeffs *scoef = new coeffs;
|
|
CreateCoeffs(scoef,ar);
|
|
// adding the attribute (ARRAY_COEF) to distributed array symbol
|
|
ar->addAttribute(ARRAY_COEF, (void*) scoef, sizeof(coeffs));
|
|
}
|
|
}
|
|
}
|
|
|
|
void ArrayHeader (SgSymbol *ar,int ind)
|
|
{
|
|
// creating header of distributed array: HEADER(0:N+1),
|
|
// N - rank of array
|
|
// Rank+1 elements for DVM system
|
|
// and 1 element for F_DVM
|
|
|
|
int *index = new int;
|
|
int * count = new int;
|
|
coeffs *scoef = new coeffs;
|
|
SgSymbol **base = new (SgSymbol *);
|
|
SgType *btype;
|
|
|
|
if(IS_BY_USE(ar))
|
|
return;
|
|
|
|
if(HEADER(ar)) {
|
|
Err_g("Illegal aligning of '%s'", ar->identifier(),126);
|
|
return;
|
|
}
|
|
btype = Base_Type(ar->type());
|
|
|
|
/*
|
|
if(btype->variant() == T_STRING)
|
|
Err_g("Illegal type of '%s'", ar->identifier(),141);
|
|
*/ /* podd 13.01.12 */
|
|
|
|
if( ar->attributes() & DATA_BIT )
|
|
Err_g("Distributed object may not be initialized (in DATA statement): %s", ar->identifier(), 265);
|
|
if(!(ar->attributes() & DIMENSION_BIT) && !(ar->attributes() & DVM_POINTER_BIT))
|
|
Err_g("Distributed object '%s' is not array", ar->identifier(),127);
|
|
if(ar->attributes() & DVM_POINTER_BIT)
|
|
//TypeMemory(PointerType(ar)); // marking type memory use
|
|
TypeMemory(SgTypeInt()); // marking type memory use
|
|
else if(!(ar->attributes() & TEMPLATE_BIT) ) //ind == 1
|
|
{
|
|
TypeMemory(btype); // marking type memory use
|
|
if(TypeIndex(btype) == -1 && btype->variant()!=T_DERIVED_TYPE)
|
|
//if(TypeSize(btype) != TypeSize(baseMemory(btype)->type()->baseType()))
|
|
Err_g("Illegal type of '%s'", ar->identifier(),141);
|
|
}
|
|
//adding the distributed array symbol 'ar' to symb_list 'dsym'
|
|
if(!(ar->attributes() & DVM_POINTER_BIT))
|
|
AddDistSymbList(ar);
|
|
|
|
|
|
*index = ind;
|
|
// adding the attribute (ARRAY_HEADER) to distributed array symbol
|
|
ar->addAttribute(ARRAY_HEADER, (void*) index, sizeof(int));
|
|
*count = 0;
|
|
// adding the attribute (BUFFER_COUNT) to distributed array symbol
|
|
// counter of remote group buffers
|
|
ar->addAttribute(BUFFER_COUNT, (void*) count, sizeof(int));
|
|
// creating variables used for optimisation array references in parallel loop
|
|
CreateCoeffs(scoef,ar);
|
|
// adding the attribute (ARRAY_COEF) to distributed array symbol
|
|
ar->addAttribute(ARRAY_COEF, (void*) scoef, sizeof(coeffs));
|
|
//creating base variable
|
|
if(opt_base) {
|
|
*base= BaseSymbol(ar);
|
|
// adding the attribute (ARRAY_BASE) to distributed array symbol
|
|
ar->addAttribute(ARRAY_BASE, (void*) base, sizeof(SgSymbol *));
|
|
}
|
|
}
|
|
|
|
int Rank (SgSymbol *s)
|
|
{
|
|
SgArrayType *artype;
|
|
if(IS_POINTER(s))
|
|
return(PointerRank(s));
|
|
artype=isSgArrayType(s->type());
|
|
if(artype)
|
|
return (artype->dimension());
|
|
else
|
|
return (0);
|
|
}
|
|
|
|
SgExpression *doSizeArrayQuery(SgExpression *headref,int rank)
|
|
{int ind,i;
|
|
ind = ndvm;
|
|
for(i=1; i<=rank ; i++)
|
|
doAssignStmt(GetSize(headref,i));
|
|
return(DVM000(ind));
|
|
}
|
|
|
|
SgExpression *doDvmShapeList(SgSymbol *ar, SgStatement *st) /* RTS2 */
|
|
{
|
|
SgExpression *l_bound, *u_bound, *pe, *result=NULL;
|
|
SgSubscriptExp *sbe;
|
|
SgValueExp c1(1);
|
|
SgArrayType *artype;
|
|
int i;
|
|
artype = isSgArrayType(ar->type());
|
|
if((! artype) || (!(ar->attributes() & DIMENSION_BIT))) {//isn't array
|
|
ndim = 0;
|
|
return (NULL);
|
|
}
|
|
ndim = artype->dimension();
|
|
for(i=0; i<ndim ; i++) {
|
|
pe = artype->sizeInDim(i);
|
|
if ((sbe=isSgSubscriptExp(pe)) != NULL) {
|
|
|
|
if(!sbe->ubound()) {
|
|
Error("Illegal array shape: %s",ar->identifier(), 162,st);
|
|
u_bound = &(c1.copy());
|
|
}
|
|
else if(sbe->ubound()->variant() == STAR_RANGE) {// ubound = *
|
|
Error("Assumed-size array: %s",ar->identifier(), 162,st);
|
|
u_bound = &(c1.copy());
|
|
}
|
|
else
|
|
u_bound = &((sbe->ubound())->copy());
|
|
if(sbe->lbound())
|
|
l_bound = &((sbe->lbound())->copy());
|
|
else if(sbe->ubound())
|
|
l_bound = &(c1.copy());
|
|
else {
|
|
Error("Illegal array shape: %s",ar->identifier(), 162,st);
|
|
l_bound = &(c1.copy());
|
|
}
|
|
}
|
|
else {
|
|
if(pe->variant() == STAR_RANGE) // dim=ubound = *
|
|
Error("Assumed-size array: %s",ar->identifier(),162,st);
|
|
u_bound = &(pe->copy());
|
|
l_bound = &(c1.copy());
|
|
}
|
|
//reversing dimensions for LibDVM
|
|
result = AddElementToList(result, DvmType_Ref(Calculate(u_bound)));
|
|
result = AddElementToList(result, DvmType_Ref(Calculate(l_bound)));
|
|
}
|
|
return(result);
|
|
}
|
|
|
|
SgExpression *doShapeList(SgSymbol *ar, SgStatement *st) /* RTS2 */
|
|
{
|
|
SgExpression *l_bound, *u_bound, *pe, *result=NULL;
|
|
SgSubscriptExp *sbe;
|
|
SgValueExp c1(1);
|
|
SgArrayType *artype;
|
|
int i;
|
|
artype = isSgArrayType(ar->type());
|
|
if((! artype) || (!(ar->attributes() & DIMENSION_BIT))) {//isn't array
|
|
ndim = 0;
|
|
return (NULL);
|
|
}
|
|
ndim = artype->dimension();
|
|
for(i=0; i<ndim ; i++) {
|
|
|
|
pe = artype->sizeInDim(i);
|
|
if(IS_BY_USE(ar)) {
|
|
u_bound = UBOUNDFunction(ar,i+1);
|
|
l_bound = LBOUNDFunction(ar,i+1);
|
|
}
|
|
else if ((sbe=isSgSubscriptExp(pe)) != NULL) {
|
|
if(sbe->ubound() && (sbe->ubound()->variant() == INT_VAL || sbe->ubound()->variant() == CONST_REF) && (!sbe->lbound() || sbe->lbound() && (sbe->lbound()->variant() == INT_VAL || sbe->lbound()->variant() == CONST_REF))) {
|
|
u_bound = &((sbe->ubound())->copy());
|
|
if(sbe->lbound())
|
|
l_bound = &((sbe->lbound())->copy());
|
|
else
|
|
l_bound = &(c1.copy());
|
|
}
|
|
else {
|
|
if(sbe->ubound() && sbe->ubound()->variant() == STAR_RANGE) {
|
|
if(st->variant()==DVM_PARALLEL_ON_DIR )
|
|
Error("Assumed-size array in parallel loop: %s",ar->identifier(), 162,st);
|
|
else if( st->variant()==ACC_REGION_DIR)
|
|
Error("Assumed-size array in region: %s",ar->identifier(), 162,st);
|
|
else
|
|
Error("Assumed-size array: %s",ar->identifier(), 162,st);
|
|
}
|
|
u_bound = UBOUNDFunction(ar,i+1);
|
|
l_bound = LBOUNDFunction(ar,i+1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(pe->variant() == INT_VAL || pe->variant() == CONST_REF) {
|
|
u_bound = &(pe->copy());
|
|
l_bound = &(c1.copy());
|
|
}
|
|
else {
|
|
if(pe->variant() == STAR_RANGE) {
|
|
if(st->variant()==DVM_PARALLEL_ON_DIR )
|
|
Error("Assumed-size array in parallel loop: %s",ar->identifier(), 162,st);
|
|
else if( st->variant()==ACC_REGION_DIR)
|
|
Error("Assumed-size array in region: %s",ar->identifier(), 162,st);
|
|
else
|
|
Error("Assumed-size array: %s",ar->identifier(), 162,st);
|
|
}
|
|
u_bound = UBOUNDFunction(ar,i+1);
|
|
l_bound = LBOUNDFunction(ar,i+1);
|
|
}
|
|
}
|
|
//reversing dimensions for LibDVM
|
|
result = AddElementToList(result, DvmType_Ref(u_bound));
|
|
result = AddElementToList(result, DvmType_Ref(l_bound));
|
|
|
|
}
|
|
return(result);
|
|
}
|
|
|
|
|
|
SgExpression * doSizeFunctionArray(SgSymbol *ar, SgStatement *st)
|
|
{
|
|
SgExpression *esize, *pe, *result;
|
|
SgSubscriptExp *sbe;
|
|
SgValueExp c1(1);
|
|
SgArrayType *artype;
|
|
int i,n;
|
|
|
|
//allocating SizeArray and setting on it
|
|
result = dvm_array_ref(); // SizeArray reference
|
|
artype = isSgArrayType(ar->type());
|
|
if((! artype) || (!(ar->attributes() & DIMENSION_BIT))) {//isn't array
|
|
ndim = 0;
|
|
return (result);
|
|
}
|
|
ndim = n = artype->dimension();
|
|
for(i=n-1; i>=0 ; i--) { //reversing dimensions for LibDVM
|
|
pe = artype->sizeInDim(i);
|
|
if ((sbe=isSgSubscriptExp(pe)) != NULL) {
|
|
if(!sbe->ubound())
|
|
esize = SizeFunction(ar,i+1);
|
|
else if(sbe->ubound()->variant() == STAR_RANGE) {// ubound = *
|
|
Error("Assumed-size array: %s",ar->identifier(), 162,st);
|
|
esize = SizeFunction(ar,i+1);
|
|
}
|
|
else
|
|
if(sbe->lbound())
|
|
esize = &(((sbe->ubound())->copy()) - ((sbe->lbound())->copy()) + c1);
|
|
else
|
|
esize = &((sbe->ubound())->copy());
|
|
}
|
|
else
|
|
{
|
|
if(pe->variant() == STAR_RANGE) // dim=ubound = *
|
|
Error("Assumed-size array: %s",ar->identifier(),162,st);
|
|
esize = &(pe->copy());
|
|
}
|
|
|
|
// dvm000(N+j) = size_in_dimension_(n-j)
|
|
esize = Calculate( esize);
|
|
if(esize->variant()!=INT_VAL)
|
|
esize = SizeFunction(ar,i+1);
|
|
doAssignStmt(esize);
|
|
}
|
|
return (result);
|
|
}
|
|
|
|
|
|
SgExpression * doSizeArray(SgSymbol *ar, SgStatement *st)
|
|
{
|
|
SgExpression *esize, *pe, *result;
|
|
SgSubscriptExp *sbe;
|
|
SgValueExp c1(1);
|
|
SgArrayType *artype;
|
|
int i,n;
|
|
|
|
//allocating SizeArray and setting on it
|
|
result = dvm_array_ref(); // SizeArray reference
|
|
artype = isSgArrayType(ar->type());
|
|
if((! artype) || (!(ar->attributes() & DIMENSION_BIT))) {//isn't array
|
|
ndim = 0;
|
|
//Error (" Distributed object %s isn't declared as array\n", ar->identifier(),st);
|
|
return (result);
|
|
}
|
|
ndim = n = artype->dimension();
|
|
for(i=n-1; i>=0 ; i--) { //reversing dimensions for LibDVM
|
|
pe = artype->sizeInDim(i);
|
|
if ((sbe=isSgSubscriptExp(pe)) != NULL) {
|
|
|
|
if(!sbe->ubound()) {
|
|
Error("Illegal array shape: %s",ar->identifier(), 162,st);
|
|
esize = &(c1.copy()); //SizeFunction(ar,i+1);
|
|
}
|
|
else if(sbe->ubound()->variant() == STAR_RANGE) {// ubound = *
|
|
Error("Assumed-size array: %s",ar->identifier(), 162,st);
|
|
esize = &(sbe->ubound()->copy());
|
|
}
|
|
else
|
|
if(sbe->lbound())
|
|
esize = &(((sbe->ubound())->copy()) - ((sbe->lbound())->copy()) + c1);
|
|
else
|
|
esize = &((sbe->ubound())->copy());
|
|
}
|
|
else {
|
|
if(pe->variant() == STAR_RANGE) // dim=ubound = *
|
|
Error("Assumed-size array: %s",ar->identifier(),162,st);
|
|
esize = &(pe->copy());
|
|
}
|
|
|
|
// dvm000(N+j) = size_in_dimension_(n-j)
|
|
doAssignStmt(Calculate( esize));
|
|
}
|
|
return (result);
|
|
}
|
|
|
|
SgExpression * doSizeArrayD(SgSymbol *ar, SgStatement *st)
|
|
{
|
|
SgExpression *esize, *pe, *result;
|
|
SgSubscriptExp *sbe;
|
|
SgValueExp c1(1);
|
|
SgArrayType *artype;
|
|
int i,n;
|
|
if(st)
|
|
;
|
|
//allocating SizeArray and setting on it
|
|
result = dvm_array_ref(); // SizeArray reference
|
|
artype = isSgArrayType(ar->type());
|
|
if((! artype) || (!(ar->attributes() & DIMENSION_BIT))) {//isn't array
|
|
ndim = 0;
|
|
//Error (" Distributed object %s isn't declared as array\n", ar->identifier(),st);
|
|
return (result);
|
|
}
|
|
ndim = n = artype->dimension();
|
|
for(i=0; i<n; i++) { //direct order of dimensions
|
|
pe = artype->sizeInDim(i);
|
|
if ((sbe=isSgSubscriptExp(pe)) != NULL)
|
|
esize = &(((sbe->ubound())->copy()) - ((sbe->lbound())->copy()) + c1);
|
|
else
|
|
// !!! test : ubound = *
|
|
esize = &(pe->copy());
|
|
// dvm000(N+j) = size_in_dimension(j)
|
|
doAssignStmt(Calculate( esize));
|
|
}
|
|
return (result);
|
|
}
|
|
|
|
SgExpression * doSizeAllocArray(SgSymbol *ar, SgExpression *desc, SgStatement *st, int RTS_flag)
|
|
{
|
|
SgExpression *pe, *result, *size[MAX_DIMS], *el;
|
|
SgSubscriptExp *sbe;
|
|
SgValueExp c1(1);
|
|
SgArrayType *artype;
|
|
int i,n;
|
|
|
|
//allocating SizeArray and setting on it
|
|
result = RTS_flag == 1 ? dvm_array_ref() : NULL; // SizeArray reference/Shape list
|
|
artype = isSgArrayType(ar->type());
|
|
if((! artype) || (!(ar->attributes() & DIMENSION_BIT))) {//isn't array
|
|
ndim = 0;
|
|
return (result);
|
|
}
|
|
ndim = artype->dimension();
|
|
if(!desc->lhs())
|
|
Error("No allocaton specifications for %s",ar->identifier(),293,st);
|
|
if(!TestMaxDims(desc->lhs(), ar, st))
|
|
return(result);
|
|
for(el=desc->lhs(),n=0; el; el=el->rhs(),n++){
|
|
pe = el->lhs();
|
|
if((sbe=isSgSubscriptExp(pe)) != NULL)
|
|
{
|
|
if(RTS_flag == RTS1)
|
|
size[n] = &(((sbe->ubound())->copy()) - ((sbe->lbound())->copy()) + c1);
|
|
else //RTS2
|
|
{
|
|
result = AddElementToList(result, DvmType_Ref(Calculate(sbe->ubound())));
|
|
result = AddElementToList(result, DvmType_Ref(Calculate(sbe->lbound())));
|
|
}
|
|
}
|
|
else
|
|
if(RTS_flag == RTS1)
|
|
size[n] = &(pe->copy());
|
|
else //RTS2
|
|
{
|
|
result = AddElementToList(result, DvmType_Ref(Calculate(pe)));
|
|
result = AddElementToList(result, DvmType_Ref(Calculate(&c1)));
|
|
}
|
|
|
|
}
|
|
if(ndim != n)
|
|
Error("Rank of array '%s' is not equal the length of allocation-specification-list",ar->identifier(),292,st);
|
|
if(RTS_flag == RTS1)
|
|
{
|
|
for(i=n-1; i>=0 ; i--) //reversing dimensions for LibDVM
|
|
doAssignStmt(Calculate( size[i]));
|
|
}
|
|
return (result);
|
|
}
|
|
|
|
|
|
SgExpression * ArrayDimSize(SgSymbol *ar, int i)
|
|
{
|
|
// i= 1,...,Rank
|
|
SgExpression *esize,*pe;
|
|
SgSubscriptExp *sbe;
|
|
SgValueExp c1(1);
|
|
SgArrayType *artype;
|
|
|
|
if(IS_POINTER(ar))
|
|
return(UpperBound(ar,i-1)); // lower bound = 1
|
|
|
|
if(!(ar->attributes() & DIMENSION_BIT)){// Error isn't array
|
|
ndim = 0;
|
|
return (NULL);
|
|
}
|
|
artype = isSgArrayType(ar->type());
|
|
/*
|
|
if(! artype) { // Error: isn't array
|
|
ndim = 0;
|
|
return (NULL);
|
|
}
|
|
*/
|
|
pe = artype->sizeInDim(i-1);
|
|
if ((sbe=isSgSubscriptExp(pe)) != NULL){
|
|
if(!sbe->ubound())
|
|
esize = SizeFunction(ar,i);
|
|
else if(sbe->ubound()->variant() == STAR_RANGE) {// ubound = *
|
|
//Error("Assumed-size array: %s",ar->identifier(),cur_st);
|
|
esize = &(sbe->ubound()->copy());
|
|
}
|
|
else
|
|
if(sbe->lbound())
|
|
esize = &(((sbe->ubound())->copy()) - ((sbe->lbound())->copy()) + c1);
|
|
else
|
|
esize = &((sbe->ubound())->copy());
|
|
}
|
|
else
|
|
//if(pe->variant() == STAR_RANGE) // dim=ubound = *
|
|
// Error("Assumed-size array: %s",ar->identifier(),cur_st);
|
|
esize = &(pe->copy());
|
|
|
|
return (esize);
|
|
}
|
|
|
|
|
|
SgSymbol * baseMemory(SgType *t)
|
|
{
|
|
TypeMemory(t); //14.03.03
|
|
if(t->variant() == T_DERIVED_TYPE)
|
|
return baseMemoryOfDerivedType(t) ;
|
|
int Tind = TypeIndex(t); //21.04.15
|
|
if(Tind != -1)
|
|
return mem_symb[Tind] ;
|
|
else
|
|
{ //Err_g ("There is not dvm-base for array %s", " ", 616);
|
|
return mem_symb[Integer] ;
|
|
}
|
|
|
|
}
|
|
|
|
SgSymbol *baseMemoryOfDerivedType(SgType *t)
|
|
{SgSymbol *stype;
|
|
base_list *el;
|
|
stype = t->symbol();
|
|
for(el=mem_use_structure; el; el = el->next)
|
|
if(el->type_symbol == stype) return(el->base_symbol);
|
|
Error("Can not define base memory symbol for %s",stype->identifier(),333,cur_st);
|
|
return(Imem);//error
|
|
}
|
|
|
|
void TypeMemory(SgType *t)
|
|
{
|
|
if(t->variant() == T_DERIVED_TYPE)
|
|
DerivedTypeMemory(t);
|
|
int tInd = TypeIndex(t);
|
|
|
|
if(tInd != -1)
|
|
mem_use[tInd] = 1;
|
|
|
|
}
|
|
|
|
void DerivedTypeMemory(SgType *t)
|
|
{SgSymbol *stype;
|
|
base_list *el;
|
|
|
|
stype = t->symbol();
|
|
for(el=mem_use_structure; el; el = el->next)
|
|
{ if(el->type_symbol == stype)
|
|
{ if(!el->base_symbol)
|
|
el->base_symbol = DerivedTypeBaseSymbol(stype,t);
|
|
return;
|
|
}
|
|
}
|
|
el = new base_list;
|
|
el->type_symbol = stype;
|
|
el->base_symbol = DerivedTypeBaseSymbol(stype,t);
|
|
el->gpu_symbol = NULL;
|
|
el->next=mem_use_structure;
|
|
mem_use_structure = el;
|
|
}
|
|
|
|
int IntrinsicTypeSize(SgType *t)
|
|
{
|
|
switch(t->variant()) {
|
|
case T_INT:
|
|
case T_BOOL: return (len_int ? len_int : default_integer_size);
|
|
case T_FLOAT: return (len_int ? len_int : default_real_size);
|
|
case T_COMPLEX: return (len_int ? 2*len_int : 2*default_real_size);
|
|
case T_DOUBLE: return (len_int ? 2*len_int : 8);
|
|
|
|
case T_DCOMPLEX: return(16);
|
|
|
|
case T_STRING:
|
|
case T_CHAR:
|
|
return(1);
|
|
default:
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
//SAPFOR has the same function without modification, 28.09.2021
|
|
SgExpression * TypeLengthExpr(SgType *t)
|
|
{
|
|
SgExpression *len;
|
|
SgExpression *selector;
|
|
if(t->variant() == T_DERIVED_TYPE) return(new SgValueExp(StructureSize(t->symbol())));
|
|
len = TYPE_RANGES(t->thetype) ? t->length() : NULL;
|
|
selector = TYPE_KIND_LEN(t->thetype) ? t->selector() : NULL;
|
|
// printf("\nTypeSize");
|
|
// printf("\nranges:"); if(len) len->unparsestdout();
|
|
// printf("\nkind_len:"); if(selector) selector->unparsestdout();
|
|
if(!len && !selector) //the number of bytes is not specified in type declaration statement
|
|
return (new SgValueExp(IntrinsicTypeSize(t)));
|
|
else if(len && !selector) //INTEGER*2,REAL*8,CHARACTER*(N+1)
|
|
return(Calculate(len));
|
|
else
|
|
return(Calculate(LengthOfKindExpr(t, selector, len))); //specified kind or/and len
|
|
}
|
|
|
|
//SAPFOR has the same function without modification, 28.09.2021
|
|
SgExpression *LengthOfKindExpr(SgType *t, SgExpression *se, SgExpression *le)
|
|
{
|
|
switch(t->variant()) {
|
|
case T_INT:
|
|
case T_FLOAT:
|
|
case T_BOOL:
|
|
case T_DOUBLE:
|
|
return(se->lhs());
|
|
case T_COMPLEX:
|
|
case T_DCOMPLEX:
|
|
return(&(*new SgValueExp(2) * (*(se->lhs()))));
|
|
case T_CHAR:
|
|
case T_STRING:
|
|
{ SgExpression *length, *kind;
|
|
if(se->rhs() && se->rhs()->variant() == LENGTH_OP ) {
|
|
length = se->rhs()->lhs();
|
|
kind = se->lhs()->lhs();
|
|
}
|
|
else if(se->rhs() && se->rhs()->variant() != LENGTH_OP){
|
|
length = se->lhs()->lhs();
|
|
kind = se->rhs()->lhs();
|
|
}
|
|
else {
|
|
length = se->lhs();
|
|
kind = NULL;
|
|
}
|
|
length = le ? le : length;
|
|
if(kind)
|
|
return(&(*length * (*kind)));
|
|
//return(Calculate(length)->valueInteger() * Calculate(kind)->valueInteger());
|
|
else
|
|
return(length);
|
|
//return(Calculate(length)->valueInteger());
|
|
|
|
/*length = se->rhs() ? (se->rhs()->variant() == LENGTH_OP ? se->rhs()->lhs() : se->lhs()->lhs()) : se->lhs();
|
|
length = le ? le : length;
|
|
if(se->rhs()) // specified KIND and LEN
|
|
return((se->lhs()->lhs()->valueInteger()) * (se->rhs()->lhs()->valueInteger()) ); //kind*len
|
|
else
|
|
return(se->lhs()->valueInteger()); */
|
|
}
|
|
|
|
default:
|
|
return(NULL);
|
|
}
|
|
}
|
|
|
|
int TypeSize(SgType *t)
|
|
{
|
|
SgExpression *le;
|
|
int len;
|
|
if(IS_INTRINSIC_TYPE(t)) return (IntrinsicTypeSize(t));
|
|
if(t->variant() == T_DERIVED_TYPE) return (StructureSize(t->symbol()));
|
|
if((len = NumericTypeLength(t))) return(len);
|
|
le = TypeLengthExpr(t);
|
|
if(le->isInteger()){
|
|
len = le->valueInteger();
|
|
len = len < 0 ? 0 : len; //according to standard F90
|
|
} else
|
|
len = -1; //may be error situation
|
|
return(len);
|
|
}
|
|
|
|
SgExpression *StringLengthExpr(SgType *t, SgSymbol *s)
|
|
{ SgExpression *le;
|
|
le = TypeLengthExpr(t);
|
|
if (isSgKeywordValExp(le))
|
|
le = LENFunction(s);
|
|
if (le->lhs() && isSgKeywordValExp(le->lhs()))
|
|
le->setLhs(LENFunction(s));
|
|
return(le);
|
|
}
|
|
|
|
int NumericTypeLength(SgType *t)
|
|
{ SgExpression *le;
|
|
SgValueExp *ve;
|
|
if(t->variant() == T_STRING) return (0);
|
|
if(TYPE_RANGES(t->thetype)){
|
|
le = t->length();
|
|
if((ve =isSgValueExp(le)))
|
|
return (ve->intValue());
|
|
else
|
|
return (0);
|
|
}
|
|
if(TYPE_KIND_LEN(t->thetype) ) {
|
|
le = t->selector()->lhs();
|
|
if((ve=isSgValueExp(le)))
|
|
if(t->variant() == T_COMPLEX || t->variant() == T_DCOMPLEX)
|
|
return (2*ve->intValue());
|
|
else
|
|
return (ve->intValue());
|
|
else
|
|
return (0);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
int StructureSize(SgSymbol *s)
|
|
{ //SgClassSymb *sc;
|
|
//SgFieldSymb *sf;
|
|
SgSymbol *sf;
|
|
//SgType *type;
|
|
// SgExpression *le;
|
|
int n;
|
|
int size;
|
|
size = 0;
|
|
//n = ((SgClassSymb *) s)->numberOfFields();
|
|
//for(i=0;i<n;i++) {
|
|
//for(sf=((SgClassType *)(s->type()))->fieldSymb(1);sf;sf=((SgFieldSymb *)sf)->nextField()){
|
|
for(sf=FirstTypeField(s->type());sf;sf=((SgFieldSymb *)sf)->nextField()){
|
|
|
|
//sf = sc->field(i);
|
|
if(IS_POINTER_F90(sf))
|
|
{ size = size + DVMTypeLength();
|
|
continue;
|
|
}
|
|
if(isSgArrayType(sf->type())) {
|
|
//le= ArrayLength(sf,cur_st,1);
|
|
//if (le->isInteger())
|
|
// size = size + le->valueInteger();
|
|
n= NumberOfElements(sf,cur_st,2);//ArrayLength(sf,cur_st,1);
|
|
if (n != 0)
|
|
size = size + n*TypeSize(sf->type()->baseType());
|
|
else
|
|
Error("Can't calulate structure size: %s", s->identifier(),294,cur_st);
|
|
}
|
|
else
|
|
size = size + TypeSize(sf->type());
|
|
}
|
|
|
|
return(size);
|
|
}
|
|
|
|
SgSymbol *FirstTypeField(SgType *t)
|
|
{return(SymbMapping(TYPE_COLL_FIRST_FIELD(t->thetype)));}
|
|
|
|
|
|
|
|
int DVMTypeLength()
|
|
{return( len_DvmType ? len_DvmType : TypeSize(SgTypeInt()));}
|
|
|
|
|
|
int CharLength(SgType *t)
|
|
{
|
|
if(!TYPE_RANGES(t->thetype))
|
|
return(1); // CHARACTER (without len, default len=1)
|
|
|
|
return(ReplaceParameter( &(t->length()->copy()) )->valueInteger() );
|
|
//return(ReplaceParameter( (new SgExpression(TYPE_RANGES(t->thetype)))->lhs() )->valueInteger() );
|
|
}
|
|
|
|
|
|
int TypeIndex(SgType *t)
|
|
{
|
|
if(!t) return -1;
|
|
int Tsize = TypeSize(t);
|
|
switch(t->variant()) {
|
|
case T_INT: if(Tsize==4)
|
|
return (Integer);
|
|
else if (Tsize==1)
|
|
return (Integer_1);
|
|
else if (Tsize==2)
|
|
return (Integer_2);
|
|
else if (Tsize==8)
|
|
return (Integer_8);
|
|
else
|
|
break;
|
|
case T_FLOAT: if(Tsize == 4)
|
|
return (Real);
|
|
else if(Tsize == 8)
|
|
return (Double);
|
|
else
|
|
break;
|
|
case T_DOUBLE: return (Double);
|
|
case T_COMPLEX: if(Tsize == 8)
|
|
return (Complex);
|
|
else if(Tsize == 16)
|
|
return (DComplex);
|
|
else
|
|
break;
|
|
case T_DCOMPLEX: return (DComplex);
|
|
case T_BOOL: if(Tsize==4)
|
|
return (Logical);
|
|
else if(Tsize==1)
|
|
return (Logical_1);
|
|
else if (Tsize==2)
|
|
return (Logical_2);
|
|
else if (Tsize==8)
|
|
return (Logical_8);
|
|
else
|
|
break;
|
|
case T_STRING: if(Tsize==1)
|
|
return (Character); /*13.01.12*/
|
|
else
|
|
break;
|
|
default: break;
|
|
}
|
|
|
|
return (-1);
|
|
}
|
|
|
|
int CompareTypes(SgType *t1,SgType *t2)
|
|
|
|
{
|
|
if(!t1 || !t2) return(1);
|
|
if(TypeIndex(t1) >= 0 )
|
|
if( TypeIndex(t1)==TypeIndex(t2) )
|
|
return(1);
|
|
else
|
|
return(0);
|
|
if(t1->variant() == T_DERIVED_TYPE )
|
|
if(t2->variant() == T_DERIVED_TYPE && !strcmp(t1->symbol()->identifier(), t2->symbol()->identifier()))
|
|
return(1);
|
|
else
|
|
return(0);
|
|
if(TypeIndex(t1)==-1 && TypeIndex(t2)==-1)
|
|
return(1);
|
|
else
|
|
return(0);
|
|
return(0);
|
|
}
|
|
|
|
int BoundSizeArrays (SgSymbol *das)
|
|
// returns dvm-index of RightBSizeArray
|
|
{
|
|
int iright;
|
|
int i,nw,rank,width;
|
|
SgExpression *wl,*ew, *lbound[MAX_DIMS], *ubound[MAX_DIMS], *she;
|
|
|
|
rank = Rank(das);
|
|
if(SHADOW_(das)) { // there is SHADOW directive, i.e. shadow widths are
|
|
// specified
|
|
iright = 0;
|
|
she = *SHADOW_(das);
|
|
if(!TestMaxDims(she,das,0)) return(0);
|
|
for(wl = she,i=0; wl; wl = wl->rhs(),i++) {
|
|
ew = wl->lhs();
|
|
if(ew->variant() == DDOT){
|
|
lbound[i] = &(ew->lhs())->copy();//left bound
|
|
ubound[i] = &(ew->rhs())->copy();//right bound
|
|
} else {
|
|
lbound[i] = &(ew->copy());//left bound == right bound
|
|
ubound[i] = &(ew->copy());
|
|
}
|
|
}
|
|
nw = i;
|
|
|
|
if(nw<rank)
|
|
for(; i<rank; i++) {
|
|
lbound[i] = new SgValueExp(1); // by default, bound width = 1
|
|
ubound[i] = new SgValueExp(1);
|
|
}
|
|
|
|
if (nw != rank) // wrong shadow width list
|
|
return(0);
|
|
|
|
} else {// shadow widths are not specified in program
|
|
if(HPF_program && all_sh_width) // shadow width is specified by option -Hshw
|
|
width = all_sh_width; // for all arrays of HPF program
|
|
else
|
|
width = 1; //by default shadow width = 1
|
|
for(i=0; i<rank; i++) {
|
|
lbound[i] = new SgValueExp(width);
|
|
}
|
|
iright=ndvm;
|
|
}
|
|
for(i=rank-1;i>=0; i--)
|
|
doAssignStmt(lbound[i]);
|
|
if(!iright) { // shadow widths are specified in program
|
|
iright = ndvm;
|
|
for(i=rank-1;i>=0; i--)
|
|
doAssignStmt(ubound[i]);
|
|
}
|
|
return(iright);
|
|
}
|
|
|
|
void TestWeightArray(SgExpression *efm, SgStatement *st)
|
|
{
|
|
SgArrayType *artype;
|
|
if(VarType_RTS(efm->symbol())!=4) //DOUBLE PRECISION
|
|
Error("Illegal type of '%s'",efm->symbol()->identifier(),141,st);
|
|
|
|
artype = isSgArrayType(efm->symbol()->type());
|
|
if(! artype || !artype->getDimList()) //isn't array
|
|
{
|
|
Error ("'%s' isn't array", efm->symbol()->identifier(),66,st);
|
|
return;
|
|
}
|
|
|
|
if(artype->dimension() != 1)
|
|
{
|
|
Error ("Illegal rank of '%s'", efm->symbol()->identifier(),76,st);
|
|
return;
|
|
}
|
|
SgExpression *arsize = Calculate(artype->sizeInDim(0));
|
|
if(arsize->variant() == INT_VAL)
|
|
{
|
|
SgExpression *nblock = Calculate(efm->lhs());
|
|
if(nblock->variant() == INT_VAL)
|
|
{
|
|
if(((SgValueExp *)arsize)->intValue() < ((SgValueExp *)nblock)->intValue())
|
|
{
|
|
Error("Illegal array size of '%s'",efm->symbol()->identifier(),340,st);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SgExpression *AddElementToList(SgExpression *list, SgExpression *e)
|
|
{
|
|
SgExpression *el = new SgExprListExp(*e);
|
|
el->setRhs(list);
|
|
return (el);
|
|
}
|
|
|
|
SgExpression *ListUnion(SgExpression *list1, SgExpression *list2)
|
|
{
|
|
SgExpression *el1=list1, *el2=list2,*result=list1;
|
|
for( ; el1 && el2; el1=list1,el2=list2)
|
|
{
|
|
list1=list1->rhs()->rhs();
|
|
list2=list2->rhs()->rhs();
|
|
el2->rhs()->setRhs(list1);
|
|
el1->rhs()->setRhs(el2);
|
|
}
|
|
return (result);
|
|
}
|
|
|
|
int isInterfaceRTS2(SgStatement *stdis)
|
|
{
|
|
SgExpression *e, *efm;
|
|
for(e=stdis->expr(1); e; e = e->rhs()) {
|
|
efm = e->lhs(); //dist_format expression
|
|
|
|
if(efm->variant() == INDIRECT_OP)
|
|
{
|
|
if(stdis->expr(2))
|
|
{
|
|
err("ONTO/NEW_VALUE clause is not supported",625,stdis);
|
|
return(0);
|
|
}
|
|
if(parloop_by_handler == 2)
|
|
return(1);
|
|
else
|
|
{
|
|
err("Indirect/Derived distribution, -Opl2 option should be specified",624,stdis);
|
|
return(0);
|
|
}
|
|
}
|
|
}
|
|
return(parloop_by_handler==2 ? 1 : 0);
|
|
}
|
|
|
|
SgExpression *doDisRules(SgStatement *stdis, int aster, int &idis) {
|
|
|
|
SgExpression **dis_rules,*distr_list[1]; // DisRule's list
|
|
|
|
dis_rules = isInterfaceRTS2(stdis) ? distr_list : NULL;
|
|
idis = doDisRuleArrays(stdis, aster, dis_rules);
|
|
return (idis==-1 ? *dis_rules : NULL);
|
|
}
|
|
|
|
int doDisRuleArrays (SgStatement *stdis, int aster, SgExpression **distr_list ) {
|
|
|
|
SgExpression *e, *efm, *ed, *nblk[MAX_DIMS], *dist_format, *multiple[MAX_DIMS], *numb[MAX_DIMS];
|
|
SgSymbol *genbl[MAX_DIMS];
|
|
int iaxis, i, axis[MAX_DIMS], param[MAX_DIMS], tp, mps_axis;
|
|
SgValueExp M1(1);
|
|
//looking through the dist_format_list and
|
|
// creating AxisArray and DistrParamArray
|
|
ndis = 0;
|
|
nblock = 0;
|
|
gen_block = 0;
|
|
mult_block = 0;
|
|
mps_axis = 0;
|
|
iaxis = ndvm;
|
|
if(distr_list)
|
|
*distr_list = NULL;
|
|
dist_format = stdis->expr(1);
|
|
if(!dist_format){ //dist_format list is absent
|
|
all_replicated=0;
|
|
return(distr_list ? -1 : iaxis);
|
|
}
|
|
for(i=0; i<MAX_DIMS; i++)
|
|
numb[i] = NULL;
|
|
for(e=dist_format; e; e = e->rhs()) {
|
|
efm = e->lhs(); //dist_format expression
|
|
if(ndis==MAX_DIMS)
|
|
{
|
|
err("Too many dimensions",43,stdis);
|
|
break;
|
|
}
|
|
ndis++;
|
|
if(efm->variant() == BLOCK_OP) {
|
|
nblock++;
|
|
mps_axis++;
|
|
if(!( efm->symbol() ) ) // case: BLOCK or MULT_BLOCK
|
|
{
|
|
if( !efm->rhs() ) // case: BLOCK
|
|
{
|
|
if(distr_list)
|
|
*distr_list = AddElementToList(*distr_list,DvmhBlock(mps_axis));
|
|
|
|
multiple[ndis-1] = &M1;
|
|
}
|
|
else { // case: MULT_BLOCK (k)
|
|
if(distr_list)
|
|
*distr_list = AddElementToList(*distr_list,DvmhMultBlock(mps_axis, DVM000(iaxis+ndis-1)));
|
|
multiple[ndis-1] = numb[ndis-1] = efm->rhs();
|
|
mult_block = 1;
|
|
}
|
|
axis[ndis-1] = ndis;
|
|
param[ndis-1] = 0;
|
|
genbl[ndis-1] = NULL;
|
|
}
|
|
else if (!efm->lhs()) // case: GEN_BLOCK
|
|
{ if( gen_block == 2 ) // there is WGT_BLOCK in format-list
|
|
err("GEN_BLOCK and WGT_BLOCK in format-list",129,stdis);
|
|
else
|
|
gen_block = 1;
|
|
if(distr_list)
|
|
*distr_list = AddElementToList(*distr_list,DvmhGenBlock(mps_axis, efm->symbol()));
|
|
multiple[ndis-1] = &M1;
|
|
axis[ndis-1] = ndis;
|
|
param[ndis-1] = 0;
|
|
genbl[ndis-1] = efm->symbol();
|
|
tp = VarType_RTS(efm->symbol());
|
|
if((bind_ == 0 && tp != 2 && tp != 1) || (bind_ == 1 && tp != 1)) //INTEGER
|
|
Error("Illegal type of '%s'",efm->symbol()->identifier(),141,stdis);
|
|
SgArrayType *artype=isSgArrayType(efm->symbol()->type());
|
|
if( !artype || !artype->getDimList() )
|
|
Error("'%s' isn't array",efm->symbol()->identifier(),66,stdis);
|
|
}
|
|
else // case: WGT_BLOCK
|
|
{ if( gen_block == 1 ) // there is GEN_BLOCK in format-list
|
|
err("GEN_BLOCK and WGT_BLOCK in format-list",129,stdis);
|
|
else
|
|
gen_block = 2;
|
|
if(distr_list)
|
|
*distr_list = AddElementToList(*distr_list,DvmhWgtBlock(mps_axis, efm->symbol(),DVM000(iaxis+ndis-1)));
|
|
multiple[ndis-1] = &M1;
|
|
axis[ndis-1] = ndis;
|
|
param[ndis-1] = 0;
|
|
genbl[ndis-1] = efm->symbol();
|
|
nblk[ndis-1] = numb[ndis-1] = efm->lhs();
|
|
|
|
TestWeightArray(efm,stdis);
|
|
}
|
|
/* else if ((efm->lhs())->variant() == SPEC_PAIR)
|
|
* //there is one operand (variant==SPEC_PAIR)
|
|
* // case: BLOCK(SHADOW=...)
|
|
*{
|
|
* efm = (efm->lhs())->rhs();
|
|
*
|
|
*} else //there is one operand (variant==CONS)
|
|
* // case: BLOCK(LOW_SHADOW=...,HIGH_SHADOW=...)
|
|
* { }
|
|
*/
|
|
} else if(efm->variant() == INDIRECT_OP)
|
|
{
|
|
mps_axis++;
|
|
if(distr_list)
|
|
{
|
|
if(efm->symbol()) // case INDIRECT(map)
|
|
*distr_list = AddElementToList(*distr_list,DvmhIndirect(mps_axis, efm->symbol()));
|
|
else // case DERIVED(...)
|
|
{
|
|
SgExpression *eFunc[2];
|
|
SgExpression *edrv = efm->lhs(); // efm->lhs()->variant() == DERIVED_OP
|
|
DerivedSpecification(edrv, stdis, eFunc);
|
|
*distr_list = AddElementToList(*distr_list,DvmhDerived(mps_axis, DvmhDerivedRhs(edrv->rhs()),eFunc[0],eFunc[1]));
|
|
}
|
|
}
|
|
} else // variant ==KEYWORD_VAL ("*")
|
|
{ axis[ndis-1] = 0;
|
|
multiple[ndis-1] = &M1;
|
|
if(distr_list)
|
|
*distr_list = AddElementToList(*distr_list,DvmhReplicated());
|
|
}
|
|
}
|
|
|
|
if( gen_block == 1 && mult_block) // there are GEN_BLOCK and MULT_BLOCK in format-list
|
|
err("GEN_BLOCK and MULT_BLOCK in format-list",129,stdis);
|
|
|
|
if(!nblock_all && dist_format)
|
|
nblock_all = nblock;
|
|
|
|
if(nblock)
|
|
all_replicated=0;
|
|
|
|
if(aster) // dummy arguments inherit distribution
|
|
return(distr_list ? -1 : iaxis);
|
|
|
|
if(distr_list)
|
|
{
|
|
for(i=0; i<ndis; i++) {
|
|
if(numb[i])
|
|
doAssignTo(DVM000(iaxis+i),numb[i]);
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
for(i=0; i<ndis; i++) {
|
|
if(axis[i]) // axis[i] != 0
|
|
doAssignStmt(new SgValueExp(ndis - axis[i] + 1));
|
|
}
|
|
for(i=0; i<ndis; i++) {
|
|
if(axis[i]) // axis[i] != 0
|
|
doAssignStmt(new SgValueExp(param[i]));
|
|
}
|
|
if(gen_block == 1 || gen_block == 2)
|
|
for(i=0; i<ndis; i++) {
|
|
if(axis[i]) // axis[i] != 0
|
|
doAssignStmt(genbl[i] ? GetAddresMem(new SgArrayRefExp(*genbl[i], *Exprn(LowerBound(genbl[i],0)))) : ConstRef(0));
|
|
}
|
|
if(gen_block == 2)
|
|
for(i=0; i<ndis; i++) {
|
|
if(axis[i]) // axis[i] != 0
|
|
doAssignStmt(genbl[i] ? nblk[i] : ConstRef(0));
|
|
}
|
|
if(mult_block)
|
|
{ mult_block = ndvm;
|
|
for(i=ndis-1; i>=0; i--)
|
|
doAssignStmt(&(multiple[i]->copy()));
|
|
}
|
|
|
|
if(!nblock) //replication ("*") in all dimensions
|
|
doAssignStmt(new SgValueExp(0));
|
|
|
|
return (iaxis);
|
|
}
|
|
|
|
void doAlignRule_1 (int rank)
|
|
// (SgExpression **p_axis,
|
|
// SgExpression **p_coeff, SgExpression **p_const)
|
|
{ int i;
|
|
SgValueExp *num;
|
|
SgValueExp c1(1),c0(0);
|
|
// creating axis_array
|
|
// axis_array = dvm_array_ref(); // dvm000(ndvm)
|
|
for(i=1; i<=rank; i++) {
|
|
num = new SgValueExp (i);
|
|
doAssignStmt(num); // AxisArray(i)=i
|
|
}
|
|
// creating coeff_array
|
|
// coeff_array = dvm_array_ref(); // dvm000(ndvm)
|
|
for(i=1; i<=rank; i++)
|
|
doAssignStmt(&c1.copy()); // CoeffArray(i)=1
|
|
// creating const_array
|
|
//const_array = dvm_array_ref(); // dvm000(ndvm)
|
|
for(i=1; i<=rank; i++)
|
|
doAssignStmt(&c0.copy()); // ConstArray(i)=0
|
|
}
|
|
|
|
int doAlignRule (SgSymbol *alignee, SgStatement *algn_st, int iaxis)
|
|
// creating axis_array, coeff_array and const_array
|
|
// returns length of align_source_list (dimension_identifier_list)
|
|
// (SgExpression **p_axis,
|
|
// SgExpression **p_coeff, SgExpression **p_const)
|
|
{ int i,j,rank,ni,nt,ia,num, use[MAX_DIMS];
|
|
//algn_attr *attr;
|
|
//SgStatement *algn_st;
|
|
SgExpression * el,*e,*ei,*elbi,*elbb;
|
|
SgSymbol *dim_ident[MAX_DIMS],*align_base;
|
|
SgExpression *axis[MAX_DIMS], *coef[MAX_DIMS], *cons[MAX_DIMS], *et;
|
|
SgValueExp c1(1),c0(0),cM1(-1);
|
|
int num_dim[MAX_DIMS], ncolon, ntriplet;
|
|
for(i=0;i<MAX_DIMS;i++)
|
|
num_dim[i]=0;
|
|
|
|
rank = Rank(alignee); // rank of aligned array
|
|
//algn_st = node->align_stmt; // align statement
|
|
|
|
if(iaxis == -2) return(rank);//for ALLOCATABLE array in specification part
|
|
//can't generate align rules because there is not declared array shape
|
|
|
|
ni = 0; //counter of elements in align_source_list(dimension_identifier_list)
|
|
ncolon = 0; //counter of elements ':'in align_source_list
|
|
if(!algn_st->expr(1)) //align_source_list is absent
|
|
for(;ni<rank;ni++,ncolon++) {
|
|
num_dim[ncolon] = ni;
|
|
dim_ident[ni] = NULL;
|
|
use[ni] = 0;
|
|
}
|
|
//looking through the align_source_list (dimension_identifier_list)
|
|
for(el=algn_st->expr(1); el; el=el->rhs()) {
|
|
if(ni==MAX_DIMS) {
|
|
err("Illegal align-source-list",633,algn_st);
|
|
break;
|
|
}
|
|
if(isSgVarRefExp(el->lhs())) { // dimension identifier
|
|
if(el->lhs()->symbol()->attributes() & PARAMETER_BIT)
|
|
Error("The align-dummy %s isn't a scalar integer variable",el->lhs()->symbol()->identifier(), 62,algn_st);
|
|
dim_ident[ni] = (el->lhs())->symbol();
|
|
}
|
|
else if (el->lhs()->variant() == DDOT) { // ':'
|
|
num_dim[ncolon++] = ni;
|
|
dim_ident[ni] = NULL;
|
|
}
|
|
else // "*"
|
|
dim_ident[ni] = NULL;
|
|
use[ni] = 0;
|
|
|
|
ni++;
|
|
}
|
|
if(rank && rank != ni)
|
|
Error ("Rank of aligned array %s isn't equal to the length of align-source-list", alignee->identifier(),128,algn_st);
|
|
|
|
ia = alignee->attributes();
|
|
if(ia & DISTRIBUTE_BIT)
|
|
Error ("An alignee may not have the DISTRIBUTE attribute: %s", alignee->identifier(),57,algn_st);
|
|
|
|
et =(algn_st->expr(2)->variant()==ARRAY_OP) ? (algn_st->expr(2))->rhs() : algn_st->expr(2);
|
|
align_base = et->symbol();
|
|
|
|
nt = 0;//counter of elements in align_subscript_list
|
|
ntriplet = 0; //counter of triplets in align_subscript_list
|
|
if(! et->lhs()) //align_subscript_list is absent
|
|
for( ; nt<Rank(align_base); nt++,ntriplet++) {
|
|
axis[nt] = new SgValueExp(ni-num_dim[ntriplet]);
|
|
coef[nt] = new SgValueExp(1);
|
|
cons[nt] = &(*Exprn(LowerBound(align_base,nt)) -
|
|
(*Exprn( LowerBound(alignee,num_dim[ntriplet]))));
|
|
}
|
|
//looking through the align_subscript_list
|
|
for(el=et->lhs(); el; el=el->rhs()) {
|
|
if(nt==MAX_DIMS) {
|
|
err("Illegal align-subscript-list",634,algn_st);
|
|
break;
|
|
}
|
|
e = el->lhs(); //subscript expression
|
|
if(e->variant()==KEYWORD_VAL) { // "*"
|
|
axis[nt] = & cM1.copy();
|
|
coef[nt] = & c0.copy();
|
|
cons[nt] = & c0.copy();
|
|
}
|
|
else if (e->variant()==DDOT) { // triplet
|
|
axis[nt] = new SgValueExp(ni-num_dim[ntriplet]);
|
|
coef[nt] = (e->lhs() && e->lhs()->variant()==DDOT) ? & e->rhs()->copy() :
|
|
new SgValueExp(1);
|
|
//elbi = Exprn( LowerBound(alignee,num_dim[ntriplet]));
|
|
//if (e->lhs() && e->lhs()->variant()==DDOT)
|
|
// elbi = &(coef[nt]->copy()* (*elbi));
|
|
//else
|
|
// elbi = NULL;
|
|
elbb = Exprn(LowerBound(align_base,nt));
|
|
if (e->lhs())
|
|
if(e->lhs()->variant()!=DDOT)
|
|
cons[nt] = &(e->lhs()->copy() - (*elbb));
|
|
else if (e->lhs()->lhs())
|
|
cons[nt] = &(e->lhs()->lhs()->copy() - (*elbb));
|
|
else
|
|
cons[nt] = & c0.copy();
|
|
else
|
|
cons[nt] = & c0.copy();
|
|
//cons[nt] = &(*elbb - *elbi);
|
|
|
|
ntriplet++;
|
|
}
|
|
else { // expression
|
|
num = AxisNumOfDummyInExpr(e, dim_ident, ni, &ei, use, algn_st);
|
|
//ei->unparsestdout();
|
|
//printf("\nnum = %d\n", num);
|
|
if (num<=0) {
|
|
axis[nt] = & c0.copy();
|
|
coef[nt] = & c0.copy();
|
|
elbb = LowerBound(align_base,nt);
|
|
if(elbb)
|
|
cons[nt] = & (e->copy() - (elbb->copy()));
|
|
// correcting const with lower bound of align-base array
|
|
else // error situation : rank of align-base less than list length
|
|
cons[nt] = & (e->copy());
|
|
}
|
|
else {
|
|
axis[nt] = new SgValueExp(ni-num+1); // reversing numbering
|
|
CoeffConst(e, ei,&coef[nt], &cons[nt]);
|
|
if(!iaxis) TestReverse(coef[nt],algn_st);
|
|
if(!coef[nt]) {
|
|
if(!iaxis) err("Wrong align-subscript expression", 130,algn_st);
|
|
coef[nt] = & c0.copy();
|
|
cons[nt] = & c0.copy();
|
|
}
|
|
else {
|
|
// correcting const with lower bound of alignee and align-base arrays
|
|
elbb = LowerBound(align_base,nt);
|
|
elbi = LowerBound(alignee,num-1);
|
|
if(elbb && elbi)
|
|
cons[nt] = &(*cons[nt] + (*coef[nt] * (elbi->copy())) - (elbb->copy()));
|
|
}
|
|
}
|
|
}
|
|
|
|
nt++;
|
|
}
|
|
ia = align_base->attributes();
|
|
if(!iaxis) {
|
|
if(!(ia & DIMENSION_BIT) && !IS_POINTER(align_base))
|
|
Error ("Align-target %s isn't declared as array",align_base->identifier(),61,algn_st);
|
|
else
|
|
if(Rank(align_base) != nt)
|
|
Error ("Rank of align-target %s isn't equal to the length of align_subscript-list", align_base->identifier(),132,algn_st);
|
|
if(ntriplet != ncolon)
|
|
err ("The number of colons in align-source-list isn't equal to the number of subscript-triplets",131,algn_st);
|
|
// setting on arrays with reversing
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignStmt(axis[i]);
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignStmt(ReplaceFuncCall(coef[i]));
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignStmt(Calculate(cons[i]));
|
|
}
|
|
else if(iaxis == -1)
|
|
return(nt);
|
|
else {
|
|
j = iaxis + 2*nt;
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignTo(DVM000(j++),Calculate(cons[i]));
|
|
}
|
|
|
|
return(nt);
|
|
}
|
|
|
|
|
|
int doAlignRuleArrays (SgSymbol *alignee, SgStatement *algn_st, int iaxis, SgExpression *axis[], SgExpression *coef[],SgExpression *cons[], int interface )
|
|
// creating axis_array, coeff_array and const_array
|
|
// returns length of align_source_list (dimension_identifier_list)
|
|
// (SgExpression **p_axis,
|
|
// SgExpression **p_coeff, SgExpression **p_const)
|
|
{ int i,j,rank,ni,nt,ia,num, use[MAX_DIMS];
|
|
//algn_attr *attr;
|
|
//SgStatement *algn_st;
|
|
SgExpression * el,*e,*ei,*elbi,*elbb;
|
|
SgSymbol *dim_ident[MAX_DIMS],*align_base;
|
|
SgExpression *et;
|
|
SgValueExp c1(1),c0(0),cM1(-1);
|
|
int num_dim[MAX_DIMS], ncolon, ntriplet;
|
|
for(i=0;i<MAX_DIMS;i++)
|
|
num_dim[i]=0;
|
|
|
|
rank = Rank(alignee); // rank of aligned array
|
|
|
|
if(iaxis == -2) return(rank);//for ALLOCATABLE array in specification part
|
|
//can't generate align rules because there is not declared array shape
|
|
|
|
ni = 0; //counter of elements in align_source_list(dimension_identifier_list)
|
|
ncolon = 0; //counter of elements ':'in align_source_list
|
|
if(!algn_st->expr(1)) //align_source_list is absent
|
|
for(;ni<rank;ni++,ncolon++) {
|
|
num_dim[ncolon] = ni;
|
|
dim_ident[ni] = NULL;
|
|
use[ni] = 0;
|
|
}
|
|
//looking through the align_source_list (dimension_identifier_list)
|
|
for(el=algn_st->expr(1); el; el=el->rhs()) {
|
|
if(ni==MAX_DIMS) {
|
|
err("Illegal align-source-list",633,algn_st);
|
|
break;
|
|
}
|
|
if(isSgVarRefExp(el->lhs())) { // dimension identifier
|
|
if(el->lhs()->symbol()->attributes() & PARAMETER_BIT)
|
|
Error("The align-dummy %s isn't a scalar integer variable",el->lhs()->symbol()->identifier(), 62,algn_st);
|
|
dim_ident[ni] = (el->lhs())->symbol();
|
|
}
|
|
else if (el->lhs()->variant() == DDOT) { // ':'
|
|
num_dim[ncolon++] = ni;
|
|
dim_ident[ni] = NULL;
|
|
}
|
|
else // "*"
|
|
dim_ident[ni] = NULL;
|
|
use[ni] = 0;
|
|
|
|
ni++;
|
|
}
|
|
if(rank && rank != ni)
|
|
Error ("Rank of aligned array %s isn't equal to the length of align-source-list", alignee->identifier(),128,algn_st);
|
|
|
|
ia = alignee->attributes();
|
|
if(ia & DISTRIBUTE_BIT)
|
|
Error ("An alignee may not have the DISTRIBUTE attribute: %s", alignee->identifier(),57,algn_st);
|
|
|
|
et =(algn_st->expr(2)->variant()==ARRAY_OP) ? (algn_st->expr(2))->rhs() : algn_st->expr(2);
|
|
align_base = et->symbol();
|
|
|
|
nt = 0;//counter of elements in align_subscript_list
|
|
ntriplet = 0; //counter of triplets in align_subscript_list
|
|
if(! et->lhs()) //align_source_list is absent
|
|
for( ; nt<Rank(align_base); nt++,ntriplet++) {
|
|
axis[nt] = new SgValueExp(ni-num_dim[ntriplet]);
|
|
coef[nt] = new SgValueExp(1);
|
|
cons[nt] = interface == RTS2 ? new SgValueExp(0) : &(*Exprn(LowerBound(align_base,nt)) -
|
|
(*Exprn( LowerBound(alignee,num_dim[ntriplet]))));
|
|
}
|
|
//looking through the align_subscript_list
|
|
for(el=et->lhs(); el; el=el->rhs()) {
|
|
if(nt==MAX_DIMS) {
|
|
err("Illegal align-subscript-list",634,algn_st);
|
|
break;
|
|
}
|
|
e = el->lhs(); //subscript expression
|
|
if(e->variant()==KEYWORD_VAL) { // "*"
|
|
axis[nt] = & cM1.copy();
|
|
coef[nt] = & c0.copy();
|
|
cons[nt] = & c0.copy();
|
|
}
|
|
else if (e->variant()==DDOT) { // triplet
|
|
axis[nt] = new SgValueExp(ni-num_dim[ntriplet]);
|
|
coef[nt] = (e->lhs() && e->lhs()->variant()==DDOT) ? & e->rhs()->copy() :
|
|
new SgValueExp(1);
|
|
elbb = Exprn(LowerBound(align_base,nt));
|
|
if (e->lhs())
|
|
if(e->lhs()->variant()!=DDOT)
|
|
cons[nt] = interface == RTS2 ? &(e->lhs()->copy()) : &(e->lhs()->copy() - (*elbb));
|
|
else if (e->lhs()->lhs())
|
|
cons[nt] = interface == RTS2 ? &(e->lhs()->lhs()->copy()) : &(e->lhs()->lhs()->copy() - (*elbb));
|
|
else
|
|
cons[nt] = & c0.copy();
|
|
else
|
|
cons[nt] = & c0.copy();
|
|
|
|
ntriplet++;
|
|
}
|
|
else { // expression
|
|
num = AxisNumOfDummyInExpr(e, dim_ident, ni, &ei, use, algn_st);
|
|
//ei->unparsestdout();
|
|
//printf("\nnum = %d\n", num);
|
|
if (num<=0) {
|
|
axis[nt] = & c0.copy();
|
|
coef[nt] = & c0.copy();
|
|
cons[nt] = & (e->copy());
|
|
if(interface != RTS2 && (elbb = LowerBound(align_base,nt)) )
|
|
cons[nt] = & (*cons[nt] - (elbb->copy()));
|
|
// correcting const with lower bound of align-base array
|
|
// elbb==NULL is error situation : rank of align-base less than list length
|
|
|
|
}
|
|
else {
|
|
axis[nt] = new SgValueExp(ni-num+1); // reversing numbering
|
|
CoeffConst(e, ei,&coef[nt], &cons[nt]);
|
|
if(!iaxis) TestReverse(coef[nt],algn_st);
|
|
if(!coef[nt]) {
|
|
if(!iaxis) err("Wrong align-subscript expression", 130,algn_st);
|
|
coef[nt] = & c0.copy();
|
|
cons[nt] = & c0.copy();
|
|
}
|
|
else {
|
|
// correcting const with lower bound of alignee and align-base arrays
|
|
elbb = LowerBound(align_base,nt);
|
|
elbi = LowerBound(alignee,num-1);
|
|
if(interface != RTS2 && elbb && elbi)
|
|
cons[nt] = &(*cons[nt] + (*coef[nt] * (elbi->copy())) - (elbb->copy()));
|
|
}
|
|
}
|
|
}
|
|
|
|
nt++;
|
|
}
|
|
ia = align_base->attributes();
|
|
if(!iaxis) {
|
|
if(!(ia & DIMENSION_BIT) && !IS_POINTER(align_base))
|
|
Error ("Align-target %s isn't declared as array",align_base->identifier(),61,algn_st);
|
|
else
|
|
if(Rank(align_base) != nt)
|
|
Error ("Rank of align-target %s isn't equal to the length of align_subscript-list", align_base->identifier(),132,algn_st);
|
|
if(ntriplet != ncolon)
|
|
err ("The number of colons in align-source-list isn't equal to the number of subscript-triplets",131,algn_st);
|
|
}
|
|
return (nt);
|
|
}
|
|
|
|
int TestExprArray(SgExpression *e[], int n)
|
|
{
|
|
int i;
|
|
for(i=0; i<n; i++)
|
|
if(isSgValueExp(e[i]) || isSgVarRefExp(e[i]) || e[i]->variant()==CONST_REF)
|
|
continue;
|
|
else
|
|
return (0);
|
|
return (1);
|
|
}
|
|
|
|
SgExpression *doAlignRules (SgSymbol *alignee, SgStatement *algn_st, int iaxis, int &nt)
|
|
{
|
|
SgExpression *axis[MAX_DIMS],
|
|
*coef[MAX_DIMS],
|
|
*cons[MAX_DIMS];
|
|
SgExpression *el, *e, *alignment_list = NULL;
|
|
int i,j;
|
|
nt = doAlignRuleArrays (alignee, algn_st, iaxis, axis, coef, cons, INTERFACE_RTS2 ? RTS2 : RTS1);
|
|
if(iaxis == -1 || iaxis == -2)
|
|
return(NULL);
|
|
if(INTERFACE_RTS2) {
|
|
int flag_coef = TestExprArray(coef,nt);
|
|
int flag_cons = TestExprArray(cons,nt);
|
|
int j1 = ndvm, j2;
|
|
if(!iaxis) {
|
|
if(!flag_coef)
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignStmt(ReplaceFuncCall(coef[i]));
|
|
j2 = ndvm;
|
|
if(!flag_cons)
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignStmt(Calculate(cons[i]));
|
|
} else {
|
|
j1=iaxis;
|
|
j2=flag_coef ? iaxis : iaxis+nt;
|
|
}
|
|
for(int i=0; i<nt; i++)
|
|
{
|
|
e = AlignmentLinear(axis[i],flag_coef ? coef[i] : DVM000(j1++),flag_cons ? cons[i] : DVM000(j2++));
|
|
//e = AlignmentLinear(axis[i],ReplaceFuncCall(coef[i]),cons[i]); //Calculate(cons[i])
|
|
(el = new SgExprListExp(*e))->setRhs(alignment_list);
|
|
alignment_list = el;
|
|
}
|
|
return (alignment_list);
|
|
}
|
|
if(!iaxis) {
|
|
// setting on arrays with reversing
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignStmt(axis[i]);
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignStmt(ReplaceFuncCall(coef[i]));
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignStmt(Calculate(cons[i]));
|
|
}
|
|
else {
|
|
j = iaxis + 2*nt;
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignTo(DVM000(j++),Calculate(cons[i]));
|
|
}
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
SgExpression * Exprn(SgExpression *e)
|
|
{return((!e) ? new SgValueExp(0) : & e->copy());}
|
|
|
|
int AxisNumOfDummyInExpr (SgExpression *e, SgSymbol *dim_ident[], int ni, SgExpression **eref, int use[], SgStatement *st)
|
|
{
|
|
SgSymbol *symb;
|
|
SgExpression * e1;
|
|
int i,i1,i2;
|
|
*eref = NULL;
|
|
if (!e)
|
|
return(0);
|
|
if(isSgVarRefExp(e)) {
|
|
symb = e->symbol();
|
|
for(i=0; i<ni; i++) {
|
|
if(dim_ident[i]==NULL)
|
|
continue;
|
|
if(dim_ident[i]==symb) {
|
|
*eref = e;
|
|
if (use[i] == 1)
|
|
if(st && st->variant() == DVM_PARALLEL_ON_DIR)
|
|
Error("More one occurance of do-variable '%s' in iteration-align-subscript-list", symb->identifier(),133, st);
|
|
else if(st)
|
|
Error("More one occurance of align_dummy '%s' in align-subscript-list", symb->identifier(), 134,st);
|
|
use[i]++;
|
|
return(i+1);
|
|
}
|
|
}
|
|
return (0);
|
|
}
|
|
i1 = AxisNumOfDummyInExpr(e->lhs(), dim_ident, ni, eref, use, st);
|
|
e1 = *eref;
|
|
i2 = AxisNumOfDummyInExpr(e->rhs(), dim_ident, ni, eref, use, st);
|
|
if((i1==-1)||(i2==-1)) return(-1);
|
|
if(i1 && i2) {
|
|
if(st && st->variant() == DVM_PARALLEL_ON_DIR)
|
|
err("More one occurance of a do-variable in do-variable-use expression", 135,st);
|
|
else if (st)
|
|
err("More one occurance of an align_dummy in align-subscript expression", 136,st);
|
|
return(-1);
|
|
}
|
|
if(i1) *eref = e1;
|
|
return(i1 ? i1 : i2);
|
|
}
|
|
|
|
void CoeffConst(SgExpression *e, SgExpression *ei, SgExpression **pcoef, SgExpression **pcons)
|
|
// ei == I; e == a * I + b
|
|
// result: *pcoef = a, *pcons = b
|
|
{
|
|
SgValueExp c1(1), c0(0), cM1(-1);
|
|
switch(e->variant()) {
|
|
case VAR_REF: // I
|
|
*pcoef = & c1.copy();
|
|
*pcons = & c0.copy();
|
|
break;
|
|
case UNARY_ADD_OP: // +I
|
|
if(e->lhs()==ei) {
|
|
*pcoef = & c1.copy();
|
|
*pcons = & c0.copy();
|
|
}
|
|
else
|
|
*pcoef = NULL;
|
|
break;
|
|
case MINUS_OP: // -I
|
|
if(e->lhs()==ei) {
|
|
*pcoef = & cM1.copy();
|
|
*pcons = & c0.copy();
|
|
}
|
|
else
|
|
*pcoef = NULL;
|
|
break;
|
|
|
|
case MULT_OP: // a * I
|
|
if (e->lhs()==ei)
|
|
*pcoef = &(e->rhs())->copy();
|
|
else if (e->rhs()==ei)
|
|
*pcoef = &(e->lhs())->copy() ;
|
|
else
|
|
*pcoef = NULL;
|
|
*pcons = & c0.copy();
|
|
break;
|
|
case DIV_OP : // I / a
|
|
if(e->rhs()==ei)
|
|
*pcoef = NULL; // Error
|
|
else {
|
|
*pcoef = & (c1.copy() / (e->rhs())->copy());
|
|
*pcons = & c0.copy();
|
|
}
|
|
break;
|
|
case ADD_OP :
|
|
if(e->lhs()==ei) { // I + b
|
|
*pcoef = & c1.copy();
|
|
*pcons = & (e->rhs())->copy();
|
|
|
|
} else if(e->rhs()==ei) { // b + I
|
|
*pcoef = & c1.copy();
|
|
*pcons = & (e->lhs())->copy();
|
|
} else if (((e->lhs())->lhs()==ei)){ // I * a + b
|
|
if(e->lhs()->variant() == MULT_OP){
|
|
*pcons = & (e->rhs())->copy();
|
|
*pcoef = & ((e->lhs())->rhs())->copy();
|
|
}
|
|
else if(e->lhs()->variant() == MINUS_OP){
|
|
*pcons = & (e->rhs())->copy();
|
|
*pcoef = & cM1.copy();
|
|
}
|
|
else
|
|
*pcoef = NULL;
|
|
|
|
} else if (((e->lhs())->rhs()==ei)){ // a * I + b
|
|
if(e->lhs()->variant() == MULT_OP){
|
|
*pcons = & (e->rhs())->copy();
|
|
*pcoef = & ((e->lhs())->lhs())->copy();
|
|
}
|
|
else
|
|
*pcoef = NULL;
|
|
|
|
} else if (((e->rhs())->lhs()==ei)){ // b + I * a
|
|
if(e->rhs()->variant() == MULT_OP){
|
|
*pcons = & (e->lhs())->copy();
|
|
*pcoef = & ((e->rhs())->rhs())->copy();
|
|
}
|
|
else if(e->rhs()->variant() == MINUS_OP){
|
|
*pcons = & (e->lhs())->copy();
|
|
*pcoef = & cM1.copy();
|
|
}
|
|
else
|
|
*pcoef = NULL;
|
|
|
|
} else if (((e->rhs())->rhs()==ei)){ // b + a * I
|
|
if(e->rhs()->variant() == MULT_OP){
|
|
*pcons = & (e->lhs())->copy();
|
|
*pcoef = & ((e->rhs())->lhs())->copy();
|
|
}
|
|
}
|
|
else
|
|
*pcoef = NULL;
|
|
break;
|
|
case SUBT_OP :
|
|
if(e->lhs()==ei) { // I - b
|
|
*pcoef = & c1.copy();
|
|
*pcons = & SgUMinusOp((e->rhs())->copy());
|
|
|
|
} else if(e->rhs()==ei) { // b - I
|
|
*pcoef = & cM1.copy();
|
|
*pcons = & (e->lhs())->copy();
|
|
} else if (((e->lhs())->lhs()==ei)){ // I * a - b
|
|
if(e->lhs()->variant() == MULT_OP){
|
|
*pcons = & SgUMinusOp((e->rhs())->copy());
|
|
*pcoef = & ((e->lhs())->rhs())->copy();
|
|
}
|
|
else if(e->lhs()->variant() == MINUS_OP){
|
|
*pcons = & SgUMinusOp((e->rhs())->copy());
|
|
*pcoef = & cM1.copy();
|
|
}
|
|
else
|
|
*pcoef = NULL;
|
|
|
|
} else if (((e->lhs())->rhs()==ei)){ // a * I - b
|
|
if(e->lhs()->variant() == MULT_OP){
|
|
*pcons = & SgUMinusOp((e->rhs())->copy());
|
|
*pcoef = & ((e->lhs())->lhs())->copy();
|
|
}
|
|
else
|
|
*pcoef = NULL;
|
|
|
|
} else if (((e->rhs())->lhs()==ei)){ // b - I * a
|
|
if(e->rhs()->variant() == MULT_OP){
|
|
*pcons = & (e->lhs())->copy();
|
|
*pcoef = & SgUMinusOp(((e->rhs())->rhs())->copy());
|
|
}
|
|
else
|
|
*pcoef = NULL;
|
|
|
|
} else if (((e->rhs())->rhs()==ei)){ // b - a * I
|
|
if(e->rhs()->variant() == MULT_OP){
|
|
*pcons = & (e->lhs())->copy();
|
|
*pcoef = & SgUMinusOp(((e->rhs())->lhs())->copy());
|
|
}
|
|
}
|
|
else
|
|
*pcoef = NULL;
|
|
break;
|
|
default:
|
|
*pcoef = NULL;
|
|
break;
|
|
|
|
}
|
|
}
|
|
//-----------------------------------------------------------------------
|
|
SgExpression *SearchDistArrayField(SgExpression *e)
|
|
{
|
|
SgExpression *el = e;
|
|
while( isSgRecordRefExp(el))
|
|
{
|
|
if(isSgArrayRefExp(el->rhs()))
|
|
ChangeDistArrayRef(el->rhs()->lhs()); // subscript list
|
|
if(el->rhs()->symbol() && (el->rhs()->symbol()->attributes() & DISTRIBUTE_BIT || el->rhs()->symbol()->attributes() & ALIGN_BIT))
|
|
return el;
|
|
else
|
|
el = el->lhs();
|
|
}
|
|
if(el->symbol() && (el->symbol()->attributes() & DISTRIBUTE_BIT || el->symbol()->attributes() & ALIGN_BIT))
|
|
return el;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
void ChangeDistArrayRef(SgExpression *e)
|
|
{
|
|
SgExpression *el;
|
|
|
|
if(!e)
|
|
return;
|
|
if( e->variant() != BOOL_VAL && e->variant() != INT_VAL && e->symbol() && IS_GROUP_NAME(e->symbol()))
|
|
Error("Illegal group name use: '%s'",e->symbol()->identifier(),137,cur_st);
|
|
|
|
if(opt_loop_range && inparloop && isSgVarRefExp(e) && INDEX_SYMBOL(e->symbol())) {
|
|
ChangeIndexRefBySum(e);
|
|
return;
|
|
}
|
|
if(isSgArrayRefExp(e)) {
|
|
if(opt_loop_range && inparloop && (sum_dvm=TestDVMArrayRef(e)))
|
|
;
|
|
else
|
|
for(el=e->lhs(); el; el=el->rhs())
|
|
ChangeDistArrayRef(el->lhs());
|
|
/*
|
|
if(HEADER( e -> symbol()) && !isPrivateInRegion(e -> symbol()) //is distributed array reference not private in loop of region
|
|
|| IN_COMPUTE_REGION && HEADER_OF_REPLICATED(e -> symbol()) ) //or is array reference in compute region
|
|
DistArrayRef(e,0,cur_st); //replace distributed array reference
|
|
*/
|
|
/*
|
|
if ( IN_COMPUTE_REGION && is_acc_array(e->symbol())
|
|
|| !IN_COMPUTE_REGION && HEADER(e->symbol()) )
|
|
DistArrayRef(e,0,cur_st); //replace dvm-array reference
|
|
*/
|
|
|
|
if ( HEADER( e -> symbol())
|
|
|| (IN_COMPUTE_REGION || inparloop && parloop_by_handler) && DUMMY_FOR_ARRAY(e -> symbol()) && isIn_acc_array_list(*DUMMY_FOR_ARRAY(e -> symbol())) )
|
|
DistArrayRef(e,0,cur_st); //replace dvm-array reference if required
|
|
return;
|
|
}
|
|
if(isSgFunctionCallExp(e)) {
|
|
ReplaceFuncCall(e);
|
|
for(el=e->lhs(); el; el=el->rhs())
|
|
ChangeArg_DistArrayRef(el);
|
|
return;
|
|
}
|
|
|
|
if(isSgRecordRefExp(e)) {
|
|
SgExpression *eleft = SearchDistArrayField(e); //from right to left
|
|
if(eleft)
|
|
DistArrayRef(eleft,0,cur_st);
|
|
return;
|
|
}
|
|
|
|
ChangeDistArrayRef(e->lhs());
|
|
ChangeDistArrayRef(e->rhs());
|
|
return;
|
|
}
|
|
|
|
void ChangeDistArrayRef_Left(SgExpression *e)
|
|
{
|
|
SgExpression *el;
|
|
|
|
if(!e)
|
|
return;
|
|
|
|
if( e->symbol() && IS_GROUP_NAME(e->symbol()))
|
|
Error("Illegal group name use: '%s'",e->symbol()->identifier(),137,cur_st);
|
|
|
|
if(isSgArrayRefExp(e)) {
|
|
if(opt_loop_range && inparloop && (sum_dvm=TestDVMArrayRef(e)))
|
|
;
|
|
else
|
|
for(el=e->lhs(); el; el=el->rhs())
|
|
ChangeDistArrayRef(el->lhs());
|
|
/*
|
|
if(HEADER( e -> symbol()) && !isPrivateInRegion(e -> symbol()) //is distributed array reference not private in loop of region
|
|
|| IN_COMPUTE_REGION && HEADER_OF_REPLICATED(e -> symbol())) //or is array reference in compute region
|
|
|
|
DistArrayRef(e,1,cur_st);//replace distributed array reference (1 -modified variable)
|
|
*/
|
|
/*
|
|
if ( IN_COMPUTE_REGION && is_acc_array(e->symbol())
|
|
|| !IN_COMPUTE_REGION && HEADER(e->symbol()) )
|
|
DistArrayRef(e,0,cur_st); //replace dvm-array reference
|
|
*/
|
|
if ( HEADER( e -> symbol())
|
|
|| (IN_COMPUTE_REGION || inparloop && parloop_by_handler) && DUMMY_FOR_ARRAY(e -> symbol()) && isIn_acc_array_list(*DUMMY_FOR_ARRAY(e -> symbol())) )
|
|
DistArrayRef(e,1,cur_st); //replace dvm-array reference if required
|
|
|
|
return;
|
|
}
|
|
|
|
if(isSgRecordRefExp(e)) {
|
|
SgExpression *eleft = SearchDistArrayField(e); //from right to left
|
|
if(eleft)
|
|
DistArrayRef(eleft,0,cur_st);
|
|
return;
|
|
}
|
|
|
|
// e->variant()==ARRAY_OP //substring
|
|
ChangeDistArrayRef_Left(e->lhs());
|
|
ChangeDistArrayRef(e->rhs());
|
|
|
|
return;
|
|
}
|
|
|
|
void ChangeArg_DistArrayRef(SgExpression *ele)
|
|
{//ele is SgExprListExp
|
|
SgExpression *el, *e;
|
|
e = ele->lhs();
|
|
if(!e)
|
|
return;
|
|
if(isSgKeywordArgExp(e))
|
|
e = e->rhs();
|
|
|
|
if(isSgArrayRefExp(e)) {
|
|
|
|
if(!e->lhs()){ //argument is whole array (array name)
|
|
// no changes are required because array header name is
|
|
// the same as array name
|
|
if(IS_POINTER(e->symbol()))
|
|
Error("Illegal POINTER reference: '%s'",e->symbol()->identifier(),138,cur_st);
|
|
if((inparloop && parloop_by_handler || IN_COMPUTE_REGION) )
|
|
if(DUMMY_FOR_ARRAY(e->symbol()) && isIn_acc_array_list(*DUMMY_FOR_ARRAY(e ->symbol())) )
|
|
{ e->setLhs(FirstArrayElementSubscriptsForHandler(e->symbol()));
|
|
//changed by first array element reference
|
|
if(!for_host)
|
|
DistArrayRef(e,0,cur_st);
|
|
}
|
|
if(HEADER(e->symbol()) && for_host)
|
|
e->setSymbol(*HeaderSymbolForHandler(e->symbol()));
|
|
return;
|
|
}
|
|
el=e->lhs()->lhs(); //first subscript of argument
|
|
//testing: is first subscript of ArrayRef a POINTER
|
|
if((isSgVarRefExp(el) || isSgArrayRefExp(el)) && IS_POINTER(el->symbol())) {
|
|
ChangeDistArrayRef(el->lhs());
|
|
// ele->setLhs(PointerHeaderRef(el,1));
|
|
//replace ArrayRef by PointerRef: A(P)=>P(1) or A(P(I)) => P(1,I)
|
|
if(!strcmp(e->symbol()->identifier(),"heap") || (e->symbol()->attributes() & HEAP_BIT))
|
|
is_heap_ref = 1;
|
|
else
|
|
Error("Illegal POINTER reference: '%s'", el->symbol()->identifier(),138,cur_st);
|
|
if(e->lhs()->rhs()) //there are other subscripts
|
|
Error("Illegal POINTER reference: '%s'", el->symbol()->identifier(),138,cur_st);
|
|
if(HEADER(e->symbol()))
|
|
Error("Illegal POINTER reference: '%s'", el->symbol()->identifier(),138,cur_st);
|
|
|
|
e->setSymbol(*heapdvm); //replace ArrayRef: A(P)=>HEAP00(P) or A(P(I))=>HEAP00(P(I))
|
|
return;
|
|
}
|
|
}
|
|
if(isSgRecordRefExp(e) && isSgArrayRefExp(e->rhs()) && (e->rhs()->symbol()->attributes() & DISTRIBUTE_BIT || e->rhs()->symbol()->attributes() & ALIGN_BIT)
|
|
&& !e->rhs()->lhs()) {
|
|
ChangeDistArrayRef(e->lhs());
|
|
return;
|
|
}
|
|
|
|
ChangeDistArrayRef(e);
|
|
|
|
return;
|
|
}
|
|
|
|
SgExpression *ToInt(SgExpression *e)
|
|
{ if(!e) return(e);
|
|
return( e->type() && e->type()->variant()==T_INT) ? e : TypeFunction(SgTypeInt(),e,NULL);
|
|
}
|
|
|
|
SgExpression *LinearForm (SgSymbol *ar, SgExpression *el, SgExpression *erec)
|
|
{
|
|
int j,n;
|
|
SgExpression *elin,*e;
|
|
// el - subscript list (I1,I2,...In), n - rank of array (ar)
|
|
// ind - index of array header in dvm000
|
|
// generating
|
|
// [Header(n) +]
|
|
// n
|
|
// Header(n+1) + I1 + SUMMA(Header(n-k+1) * Ik)
|
|
// k=2
|
|
//or for Cuda kernel
|
|
// n
|
|
// SUMMA(Header(n-k+1) * Ik)
|
|
// k=1
|
|
|
|
// Header(0:n+1) - distributed array descriptor
|
|
|
|
n = Rank(ar);
|
|
if(!el) // there aren't any subscripts
|
|
return( coef_ref(ar,n+1,erec) ); //Header(n)
|
|
|
|
if(for_kernel) /*ACC*/
|
|
elin = NULL;
|
|
else if(opt_loop_range && inparloop && sum_dvm)
|
|
// elin = sum_dvm;
|
|
elin = coef_ref(ar,0,erec);
|
|
else
|
|
elin = coef_ref(ar,n+2,erec); // Header(n+1)
|
|
e = ToInt(el->lhs());
|
|
if (for_kernel && options.isOn(AUTO_TFM)) /*ACC*/
|
|
e = &(*coef_ref(ar,n+1,erec) * (*e)); // + Header(n)*I1 for loop Cuda-kernel
|
|
// or
|
|
elin = elin ? &(*elin + *e) : e; // + I1
|
|
j = n ;
|
|
for(e=el->rhs(); e && j; e=e->rhs(),j--) {
|
|
if(j>=2) //there is coef_ref(ar,j)
|
|
elin = &(*elin + (*coef_ref(ar,j,erec) * (*ToInt(e->lhs())))); // + Header(n-k+1)*Ik
|
|
}
|
|
|
|
if(ACROSS_MOD_IN_KERNEL && (e=analyzeArrayIndxs(ar,el))) /*ACC*/
|
|
elin = &(*elin + *e);
|
|
|
|
if(n && j != 1)
|
|
Error("Wrong number of subscripts specified for '%s'", ar->identifier(),175,cur_st);
|
|
return(elin);
|
|
}
|
|
|
|
SgExpression *LinearFormB (SgSymbol *ar, int ihead, int n, SgExpression *el)
|
|
{
|
|
int j;
|
|
SgExpression *elin,*e;
|
|
// el - subscript list (I1,I2,...In), n - rank of array (ar)
|
|
// generating
|
|
// [Header(n) +]
|
|
// n
|
|
// Header(n+1) + I1 + SUMMA(Header(n-k+1) * Ik)
|
|
// k=2
|
|
// Header(0:n+1) - distributed array descriptor
|
|
if(n == 0)
|
|
return( header_rf(ar,ihead,2) ); //Header(1)
|
|
if(!el) // there aren't any subscripts
|
|
return( header_rf(ar,ihead,n+1) ); //Header(n)
|
|
|
|
elin = header_rf(ar,ihead,n+2); // Header(n+1)
|
|
e = ToInt(el->lhs());
|
|
elin = &(*elin + *e); // + I1
|
|
j = n ;
|
|
for(e=el->rhs(); e && j; e=e->rhs(),j--)
|
|
elin = &(*elin + (*header_rf(ar,ihead,j) * (*ToInt(e->lhs()))));//+ Header(n-k+1)*Ik
|
|
|
|
return(elin);
|
|
}
|
|
/*
|
|
SgExpression *LinearFormB (SgSymbol *ar, int ihead, int n, SgExpression *el)
|
|
{
|
|
int j;
|
|
SgExpression *elin,*e;
|
|
// el - subscript list (I1,I2,...In), n - rank of array (ar)
|
|
// generating
|
|
// [Header(n) +]
|
|
// n
|
|
// Header(n+1) + I1 + SUMMA(Header(n-k+1) * Ik)
|
|
// k=2
|
|
// Header(0:n+1) - distributed array descriptor
|
|
|
|
if(n == 0)
|
|
return( header_rf(ar,ihead,2) ); //Header(1)
|
|
if(!el) // there aren't any subscripts
|
|
return( header_rf(ar,ihead,n+1) ); //Header(n)
|
|
if(IN_COMPUTE_REGION) //ACC
|
|
elin = for_kernel ? NULL : coef_ref(ar,n+2); //ACC
|
|
else // Header(n+1)
|
|
elin = header_rf(ar,ihead,n+2);
|
|
e = el->lhs();
|
|
elin = elin ? &(*elin + *e) : e; // + I1
|
|
j = n ;
|
|
for(e=el->rhs(); e && j; e=e->rhs(),j--)
|
|
if(IN_COMPUTE_REGION) //ACC
|
|
elin = &(*elin + (*coef_ref(ar,j) * (*e->lhs())));
|
|
else //+ Header(n-k+1)*Ik
|
|
elin = &(*elin + (*header_rf(ar,ihead,j) * (*e->lhs())));
|
|
|
|
return(elin);
|
|
}
|
|
*/
|
|
|
|
SgExpression *LinearFormB_for_ComputeRegion (SgSymbol *ar, int n, SgExpression *el)
|
|
{ /*ACC*/
|
|
int j;
|
|
SgExpression *elin,*e;
|
|
|
|
// el - subscript list (I1,I2,...In), n - rank of remote access buffer (ar)
|
|
// generating
|
|
// [Header(n) +]
|
|
// n
|
|
// Header(n+1) + I1 + SUMMA(Header(n-k+1) * Ik)
|
|
// k=2
|
|
// Header(0:n+1) - distributed array descriptor
|
|
//
|
|
// for CUDA-kernel
|
|
// n
|
|
// SUMMA(Header(n-k+1) * Ik)
|
|
// k=1
|
|
|
|
if(n == 0)
|
|
{ if(for_kernel ) /*ACC*/
|
|
return( new SgValueExp(0) ); // 0
|
|
else
|
|
return( coef_ref(ar,2) ); // Header(1) - offset
|
|
}
|
|
|
|
if(!el) // there aren't any subscripts
|
|
return( coef_ref(ar,n+1) ); //Header(n)
|
|
|
|
elin = for_kernel ? NULL : coef_ref(ar,n+2); // Header(n+1)
|
|
e = ToInt(el->lhs());
|
|
if (for_kernel && options.isOn(AUTO_TFM)) /*ACC*/
|
|
e = &(*coef_ref(ar,n+1) * (*e)); // Header(n)*I1 for loop Cuda-kernel
|
|
// or
|
|
elin = elin ? &(*elin + *e) : e; // [+] I1
|
|
j = n ;
|
|
for(e=el->rhs(); e && j; e=e->rhs(),j--)
|
|
elin = &(*elin + (*coef_ref(ar,j) * (*ToInt(e->lhs())))); // + Header(n-k+1)*Ik
|
|
|
|
if(ACROSS_MOD_IN_KERNEL && (e=analyzeArrayIndxs(ar,el))) /*ACC*/
|
|
elin = &(*elin + *e);
|
|
|
|
return(elin);
|
|
}
|
|
|
|
|
|
SgExpression * head_ref (SgSymbol *ar, int n) {
|
|
// creates array header reference
|
|
SgValueExp *index = new SgValueExp(n);
|
|
if(ar->thesymb->entry.var_decl.local == IO) // is dummy argument
|
|
return( new SgArrayRefExp(*ar, *new SgValueExp(1)));
|
|
else
|
|
return( new SgArrayRefExp(*dvmbuf, *index));
|
|
}
|
|
|
|
SgExpression * header_section (SgSymbol *ar, int n1, int n2) {
|
|
return(new SgArrayRefExp(*ar, *new SgExpression(DDOT, new SgValueExp(n1), new SgValueExp(n2))));
|
|
}
|
|
|
|
SgExpression * header_ref (SgSymbol *ar, int n) {
|
|
// creates array header reference: Header(n-1)
|
|
// Header(0:n+1) - distributed array descriptor
|
|
// int ind;
|
|
return( new SgArrayRefExp(*ar, *new SgValueExp(n)));
|
|
/*
|
|
if(!HEADER(ar))
|
|
return(NULL);
|
|
ind = INDEX(ar);
|
|
if(ind==1) //is not template
|
|
return( new SgArrayRefExp(*ar, *new SgValueExp(n)));
|
|
else
|
|
return( new SgArrayRefExp(*dvmbuf, *new SgValueExp(ind+n-1)));
|
|
|
|
*/
|
|
}
|
|
|
|
SgExpression * header_section_in_structure (SgSymbol *ar, int n1, int n2, SgExpression *struct_) {
|
|
// creates reference of header section
|
|
|
|
SgExpression *estr;
|
|
estr = &(struct_->copy());
|
|
estr->setRhs(new SgArrayRefExp(*ar, *new SgExpression(DDOT, new SgValueExp(n1), new SgValueExp(n2))));
|
|
return(estr);
|
|
}
|
|
|
|
SgExpression * header_ref_in_structure (SgSymbol *ar, int n, SgExpression *struct_) {
|
|
// creates array header reference: Header(n-1)
|
|
// Header(0:n+1) - distributed array descriptor
|
|
SgExpression *estr;
|
|
estr = &(struct_->copy());
|
|
estr->setRhs(new SgArrayRefExp(*ar, *new SgValueExp(n)));
|
|
return(estr);
|
|
//return( new SgArrayRefExp(*ar, *new SgValueExp(n)));
|
|
}
|
|
|
|
coeffs *DvmArrayCoefficients(SgSymbol *ar)
|
|
{
|
|
if(!ar->attributeValue(0,ARRAY_COEF)) //BY USE
|
|
{
|
|
coeffs *c_new = new coeffs;
|
|
CreateCoeffs(c_new,ar);
|
|
ar->addAttribute(ARRAY_COEF, (void*) c_new, sizeof(coeffs));
|
|
}
|
|
return (coeffs *) ar->attributeValue(0,ARRAY_COEF);
|
|
}
|
|
|
|
SgExpression * coef_ref (SgSymbol *ar, int n) {
|
|
// creates cofficient for dvm-array addressing
|
|
//array header reference Header(n) or its copy reference
|
|
// Header(0:n+1) - distributed array descriptor
|
|
if(inparloop && !HPF_program || for_kernel) { /*ACC*/
|
|
coeffs * scoef;
|
|
scoef = AR_COEFFICIENTS(ar); //(coeffs *) ar->attributeValue(0,ARRAY_COEF);
|
|
dvm_ar= AddNewToSymbList(dvm_ar,ar);
|
|
scoef->use = 1;
|
|
return (new SgVarRefExp(*(scoef->sc[n]))); //!!!must be 2<= n <=Rank(ar)+2
|
|
|
|
} else
|
|
return( new SgArrayRefExp(*ar, *new SgValueExp(n)));
|
|
}
|
|
|
|
SgExpression * coef_ref (SgSymbol *ar, int n, SgExpression *erec) {
|
|
// creates cofficient for dvm-array addressing
|
|
//array header reference Header(n) or its copy reference
|
|
// Header(0:n+1) - distributed array descriptor
|
|
if(erec) {
|
|
SgExpression *e = new SgExpression(RECORD_REF);
|
|
e->setLhs(erec);
|
|
e->setRhs( new SgArrayRefExp(*ar, *new SgValueExp(n)));
|
|
return( e );
|
|
}
|
|
if(inparloop && !HPF_program || for_kernel) { /*ACC*/
|
|
coeffs * scoef;
|
|
scoef = AR_COEFFICIENTS(ar); //(coeffs *) ar->attributeValue(0,ARRAY_COEF);
|
|
dvm_ar= AddNewToSymbList(dvm_ar,ar);
|
|
scoef->use = 1;
|
|
return (new SgVarRefExp(*(scoef->sc[n]))); //!!!must be 2<= n <=Rank(ar)+2
|
|
|
|
} else
|
|
return( new SgArrayRefExp(*ar, *new SgValueExp(n)));
|
|
}
|
|
|
|
SgExpression * header_rf (SgSymbol *ar, int ihead, int n) {
|
|
// creates array header reference: Header(n-1)
|
|
// Header(0:r+1) - distributed array descriptor
|
|
//int ind;
|
|
if(!ar)
|
|
return( new SgArrayRefExp(*dvmbuf, *new SgValueExp(ihead+n-1)));
|
|
else //(may be hpfbuf in HPF_program)
|
|
return( new SgArrayRefExp(*ar, *new SgValueExp(ihead+n-1)));
|
|
|
|
//if(!HEADER(ar))
|
|
// return(NULL);
|
|
//ind = INDEX(ar);
|
|
//if(ind==1) //is not template
|
|
// return( new SgArrayRefExp(*ar, *new SgValueExp(n)));
|
|
//else
|
|
// return( new SgArrayRefExp(*dvmbuf, *new SgValueExp(ind+n-1)));
|
|
}
|
|
|
|
SgExpression * acc_header_rf (SgSymbol *ar, int ihead, int n) {
|
|
// creates array header reference: Header(n-1)
|
|
// Header(0:r+1) - distributed array descriptor
|
|
|
|
if(!ar)
|
|
return( new SgArrayRefExp(*dvmbuf, *new SgValueExp(ihead+n-1)));
|
|
else //(may be hpfbuf in HPF_program)
|
|
return( new SgArrayRefExp(*ar, *new SgValueExp(ihead+n-1)));
|
|
|
|
}
|
|
|
|
|
|
SgExpression * HeaderRef (SgSymbol *ar) {
|
|
// creates array header reference
|
|
int ind;
|
|
if(!HEADER(ar))
|
|
return(NULL);
|
|
ind = INDEX(ar);
|
|
if (ind == 0) // is pointer
|
|
return(PointerHeaderRef(new SgVarRefExp(ar),1));
|
|
else ///if(ind<=1 || INTERFACE_RTS2) //is not template or interface of RTS2
|
|
return( new SgArrayRefExp(*ar, *new SgValueExp(1)) ); /*10.03.03*/
|
|
/*return( new SgArrayRefExp(*ar)); */
|
|
///else //is template in RTS1
|
|
/// return( new SgVarRefExp(*ar) );
|
|
//return( new SgArrayRefExp(*dvmbuf, *new SgValueExp(ind)));
|
|
}
|
|
|
|
SgExpression *HeaderRefInd(SgSymbol *ar, int n) {
|
|
int ind;
|
|
if(!HEADER(ar))
|
|
return (NULL);
|
|
ind = INDEX(ar);
|
|
if (ind == 0) // is pointer
|
|
return(PointerHeaderRef(new SgVarRefExp(ar),n));
|
|
else if(ind<=1) //is not template
|
|
return(new SgArrayRefExp(*ar, *new SgValueExp(n)));
|
|
else //is template
|
|
return(new SgArrayRefExp(*dvmbuf, *new SgValueExp(ind+n-1)));
|
|
}
|
|
|
|
/*
|
|
SgExpression * DistObjectRef (SgSymbol *ar) {
|
|
//!!! temporary
|
|
// creates distributed object reference
|
|
int ind;
|
|
ind = INDEX(ar);
|
|
return(head_ref(ar,ind));
|
|
}
|
|
*/
|
|
|
|
SgExpression *HeaderNplus1(SgSymbol * ar)
|
|
{
|
|
// n
|
|
// Header(n+1) = Header(n) - L1 - SUMMA(Header(n-i+1) * Li)
|
|
// i=2
|
|
SgArrayType *artype;
|
|
SgExpression *ehead,*e;
|
|
SgSubscriptExp *sbe;
|
|
int i,n,ind;
|
|
|
|
if(IS_POINTER(ar)){
|
|
// Li=1, i=1,n
|
|
ind = n = PointerRank(ar);
|
|
ehead = &(*header_ref(ar,ind+1) - (*new SgValueExp(1)));
|
|
for(; ind>=2; ind--)
|
|
ehead = & (*ehead - (*header_ref(ar,ind)));
|
|
return(ehead);
|
|
}
|
|
|
|
artype = isSgArrayType(ar->type());
|
|
if(!artype) // error
|
|
return(new SgValueExp(0)); // for continuing translation of procedure
|
|
n=artype->dimension();
|
|
if(!n) // error
|
|
return(new SgValueExp(0)); // for continuing translation of procedure
|
|
ind = n;
|
|
ehead = &(*header_ref(ar,ind+1) - LowerBound(ar,0)->copy());
|
|
for(i=2; i<=n; i++,ind--) {
|
|
e = artype->sizeInDim(i-1);
|
|
if((sbe=isSgSubscriptExp(e)) != NULL)
|
|
ehead = & (*ehead - (*header_ref(ar,ind) *
|
|
(sbe->lbound()->copy())));
|
|
else
|
|
ehead = & (*ehead - (*header_ref(ar,ind))); // by default Li=1
|
|
}
|
|
//ehead = & SgUMinusOp(*ehead);
|
|
return(ehead);
|
|
}
|
|
/*
|
|
SgExpression *BufferHeaderNplus1(SgExpression * rme, int n, int ihead)
|
|
{
|
|
// n
|
|
// Header(n+1) = Header(n) - L1 - SUMMA(Header(n-i+1) * Li)
|
|
// i=2
|
|
SgArrayType *artype;
|
|
SgExpression *ehead,*e,*el;
|
|
// SgSubscriptExp *sbe;
|
|
SgSymbol *ar;
|
|
int i,ind;
|
|
ar = rme->symbol();
|
|
if(!(ar->attributes() & DIMENSION_BIT)){// for continuing translation
|
|
return (new SgValueExp(0));
|
|
}
|
|
artype = isSgArrayType(ar->type());
|
|
if(!artype) // error
|
|
return(new SgValueExp(0)); // for continuing translation of procedure
|
|
|
|
ind = n;
|
|
i=0;
|
|
for (el=rme->lhs(); el; el=el->rhs()) //looking through the index list until first ':'element
|
|
if(el->lhs()->variant() == DDOT)
|
|
break;
|
|
else
|
|
i++;
|
|
if(!(e=LowerBound(ar,i)))
|
|
return(new SgValueExp(0)); // for continuing translation of procedure
|
|
else
|
|
ehead = &(* DVM000(ihead+ind) - e->copy());
|
|
|
|
for (el=el->rhs(),i++; el; el=el->rhs(),i++) //continue looking through the index list
|
|
if(el->lhs()->variant() == DDOT) {
|
|
ind--;
|
|
e = artype->sizeInDim(i);
|
|
if(e && e->variant() == DDOT && e->lhs())
|
|
ehead = & (*ehead - (*DVM000(ihead+ind) *
|
|
(e->lhs()->copy())));
|
|
else
|
|
ehead = & (*ehead - (*DVM000(ihead+ind))); // by default Li=1
|
|
}
|
|
|
|
return(ehead);
|
|
}
|
|
*/
|
|
|
|
SgExpression *BufferHeaderNplus1(SgExpression * rme, int n, int ihead,SgSymbol *ar)
|
|
{
|
|
// n
|
|
// Header(n+1) = Header(n) - L1*S1 - SUMMA(Header(n-i+1) * Li * Si)
|
|
// i=2
|
|
// Si = 1, if i-th remote subscript is ':', else Si = 0
|
|
// Li = lower bound of i-th array dimension if ':', Li = Header(2*n-i+3) - minimum of
|
|
// of lower bound and upper bound of corresponding do-variable,if a*i+b
|
|
SgArrayType *artype;
|
|
SgExpression *ehead,*e,*el;
|
|
|
|
SgSymbol *array;
|
|
int i,ind,j;
|
|
array = rme->symbol();
|
|
if(!(array->attributes() & DIMENSION_BIT)){// for continuing translation
|
|
return (new SgValueExp(0));
|
|
}
|
|
artype = isSgArrayType(array->type());
|
|
if(!artype) // error
|
|
return(new SgValueExp(0)); // for continuing translation of procedure
|
|
|
|
ind = n+1;
|
|
ehead = header_rf(ar,ihead,ind);
|
|
|
|
if(!rme->lhs()) { // buffer is equal to whole array
|
|
ehead = &(*ehead - *Exprn(LowerBound(array,0)));
|
|
for(i=1,ind=n;ind>1;ind--,i++){
|
|
e = artype->sizeInDim(i);
|
|
if(e && e->variant() == DDOT && e->lhs())
|
|
ehead = & (*ehead - (*header_rf(ar,ihead,ind) *
|
|
(LowerBound(array,i)->copy())));
|
|
else
|
|
ehead = & (*ehead - (*header_rf(ar,ihead,ind))); // by default Li=1
|
|
}
|
|
return(ehead);
|
|
}
|
|
|
|
i=0; j=0;
|
|
for (el=rme->lhs(); el; el=el->rhs()) //looking through the index list until first ':' or do-variable-use element
|
|
if((el->lhs()->variant() == DDOT) || IS_DO_VARIABLE_USE(el->lhs()))
|
|
{j = 1; break;}
|
|
else
|
|
i++;
|
|
if(j == 0) //buffer is of one element
|
|
return(ehead);
|
|
if( el->lhs()->variant() == DDOT)// :
|
|
if(!(e=LowerBound(array,i)))
|
|
return(new SgValueExp(0)); // for continuing translation of procedure
|
|
else
|
|
ehead = &(*ehead - e->copy());
|
|
else //a*i+b
|
|
ehead = &(*ehead - (*header_rf(ar,ihead,ind+n+1)));
|
|
for (el=el->rhs(),i++; el; el=el->rhs(),i++) //continue looking through the index list
|
|
if(el->lhs()->variant() == DDOT) {
|
|
ind--;
|
|
e = artype->sizeInDim(i);
|
|
if(e && e->variant() == DDOT && e->lhs())
|
|
ehead = & (*ehead - (*header_rf(ar,ihead,ind) *
|
|
(LowerBound(array,i)->copy())));
|
|
else
|
|
ehead = & (*ehead - (*header_rf(ar,ihead,ind))); // by default Li=1
|
|
}
|
|
else if( IS_DO_VARIABLE_USE(el->lhs())){
|
|
ind--;
|
|
ehead = & (*ehead - (*header_rf(ar,ihead,ind) * (*header_rf(ar,ihead,ind+n+1))));
|
|
}
|
|
return(ehead);
|
|
}
|
|
|
|
|
|
|
|
SgExpression *BufferHeader4(SgExpression * rme, int ihead)
|
|
{//temporary
|
|
if(rme)
|
|
return(DVM000(ihead+2));
|
|
else
|
|
return(NULL);
|
|
}
|
|
|
|
SgExpression *LowerBound(SgSymbol *ar, int i)
|
|
// lower bound of i-nd dimension of array ar (i= 0,...,Rank(ar)-1)
|
|
{
|
|
SgArrayType *artype;
|
|
SgExpression *e;
|
|
SgSubscriptExp *sbe;
|
|
if(IS_POINTER(ar))
|
|
return(new SgValueExp(1));
|
|
artype = isSgArrayType(ar->type());
|
|
if(!artype)
|
|
return(NULL);
|
|
e = artype->sizeInDim(i);
|
|
if(!e)
|
|
return(NULL);
|
|
if((sbe=isSgSubscriptExp(e)) != NULL) {
|
|
if(sbe->lbound())
|
|
return(IS_BY_USE(ar) ? Calculate(sbe->lbound()) : sbe->lbound());
|
|
else if(IS_ALLOCATABLE_POINTER(ar) || IS_TEMPLATE(ar)) {
|
|
if(HEADER(ar))
|
|
return(header_ref(ar,Rank(ar)+3+i));
|
|
else
|
|
return(LBOUNDFunction(ar,i+1));
|
|
}
|
|
else
|
|
return(new SgValueExp(1));
|
|
}
|
|
else
|
|
return(new SgValueExp(1)); // by default lower bound = 1
|
|
}
|
|
|
|
SgExpression *UpperBound(SgSymbol *ar, int i)
|
|
// upper bound of i-nd dimension of array ar (i= 0,...,Rank(ar)-1)
|
|
{
|
|
SgArrayType *artype;
|
|
SgExpression *e;
|
|
SgSubscriptExp *sbe;
|
|
int ri; //06.11.09
|
|
ri = Rank(ar) - i;
|
|
if(IS_POINTER(ar))
|
|
return(GetSize(HeaderRefInd(ar,1), ri)); //i+1)); 6.11.09
|
|
artype = isSgArrayType(ar->type());
|
|
if(!artype)
|
|
return(NULL);
|
|
e = artype->sizeInDim(i);
|
|
if(!e)
|
|
return(NULL);
|
|
if((sbe=isSgSubscriptExp(e)) != NULL){
|
|
if(sbe->ubound())
|
|
return(IS_BY_USE(ar) ? Calculate(sbe->ubound()) : sbe->ubound());
|
|
else if(HEADER(ar))
|
|
//return(&(*GetSize(HeaderRefInd(ar,1),i+1)-*HeaderRefInd(ar,Rank(ar)+3+i)+*new SgValueExp(1))); 06.11.09
|
|
return(&(*GetSize(HeaderRefInd(ar,1),ri)+*HeaderRefInd(ar,Rank(ar)+3+i)-*new SgValueExp(1)));
|
|
else
|
|
return(UBOUNDFunction(ar,i+1));
|
|
}
|
|
else
|
|
return(e);
|
|
// !!!! test case "*"
|
|
}
|
|
|
|
void ShadowList (SgExpression *el, SgStatement *st, SgExpression *gref)
|
|
{
|
|
int corner;
|
|
int ileft,iright;
|
|
//int ibsize = 0;
|
|
SgExpression *es, *ear, *head, *shlist[1];
|
|
SgSymbol *ar;
|
|
// looking through the array_with_shadow_list
|
|
for(es = el; es; es = es->rhs()) {
|
|
ear = es->lhs(); // array_with_shadow (variant:ARRAY_REF or ARRAY_OP)
|
|
if(ear->variant() == ARRAY_OP) {
|
|
corner = 1;
|
|
ear = ear->lhs();
|
|
}
|
|
else
|
|
corner = 0;
|
|
ar = ear->symbol();
|
|
if(HEADER(ar))
|
|
head = HeaderRef(ar);
|
|
else {
|
|
Error("'%s' isn't distributed array", ar->identifier(),72, st);
|
|
return;
|
|
}
|
|
if(gref) //interface of RTS1
|
|
{
|
|
if(ear->lhs()){
|
|
ileft = ndvm;
|
|
iright = doShadSizeArrays(ear->lhs(), ear->symbol(), st, NULL);
|
|
} else
|
|
ileft=iright= doShadSizeArrayM1(ar,NULL);
|
|
|
|
doCallAfter(InsertArrayBound(gref, head, ileft, iright, corner));
|
|
|
|
} else //interface of RTS2
|
|
{
|
|
if(ear->lhs())
|
|
{
|
|
doShadSizeArrays(ear->lhs(), ear->symbol(), st, shlist);
|
|
if(*shlist)
|
|
doCallAfter(ShadowRenew_H2(head,corner,Rank(ar),*shlist));
|
|
//doCallAfter(ShadowRenew_H2(Register_Array_H2(head),corner,Rank(ar),*shlist));
|
|
}
|
|
else
|
|
doCallAfter(ShadowRenew_H2(head,corner,0,NULL));
|
|
//doCallAfter(ShadowRenew_H2(Register_Array_H2(head),corner,0,NULL));
|
|
}
|
|
}
|
|
}
|
|
|
|
int doShadSizeArrayM1(SgSymbol *ar, SgExpression **shlist)
|
|
{
|
|
int n,i;
|
|
int ileft;
|
|
n = Rank(ar);
|
|
if(!shlist)
|
|
{
|
|
ileft = ndvm;
|
|
for(i=0; i<n; i++)
|
|
doAssignStmtAfter(new SgValueExp(-1));
|
|
return(ileft);
|
|
}
|
|
*shlist = NULL;
|
|
for(i=0; i<2*n; i++)
|
|
*shlist = AddListToList(*shlist,new SgExprListExp(*ConstRef_F95(-1)));
|
|
// *shlist = AddListToList(*shlist,&(*shlist)->copy());
|
|
return (0);
|
|
}
|
|
|
|
int doShadSizeArrays(SgExpression *shl, SgSymbol *ar, SgStatement *st, SgExpression **shlist)
|
|
{
|
|
int rank,nw;
|
|
int i=0,iright=0,j=0;
|
|
SgExpression *wl,*ew,*lbound[MAX_DIMS], *ubound[MAX_DIMS];
|
|
rank = Rank(ar);
|
|
if(!TestMaxDims(shl,ar,st))
|
|
return (0);
|
|
for(wl = shl; wl; wl = wl->rhs(),i++) {
|
|
ew = wl->lhs();
|
|
if(ew->variant() == SHADOW_NAMES_OP) {
|
|
lbound[i] = new SgValueExp(0);
|
|
ubound[i] = new SgValueExp(0);
|
|
j++;
|
|
if(!shlist) //interface of RTS1
|
|
Error("Illegal shadow width specification of array '%s'", ar->identifier(), 56, st);
|
|
else //interface of RTS2
|
|
ShadowNames(ar,rank-i,ew->lhs());
|
|
}
|
|
else if(ew->variant() == DDOT) {
|
|
lbound[i] = &(ew->lhs())->copy();//left bound
|
|
ubound[i] = &(ew->rhs())->copy();//right bound
|
|
} else {
|
|
lbound[i] = &(ew->copy());//left bound == right bound
|
|
ubound[i] = &(ew->copy());
|
|
}
|
|
}
|
|
nw = i;
|
|
TestShadowWidths(ar, lbound, ubound, nw, st);
|
|
if (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(shlist && j==i) //interface of RTS2
|
|
{
|
|
*shlist = NULL;
|
|
return(0);
|
|
}
|
|
if(!shlist) //interface of RTS1
|
|
{
|
|
for(i=rank-1;i>=0; i--)
|
|
doAssignStmtAfter(lbound[i]);
|
|
iright = ndvm;
|
|
for(i=rank-1;i>=0; i--)
|
|
doAssignStmtAfter(ubound[i]);
|
|
} else //interface of RTS2
|
|
{
|
|
*shlist = NULL;
|
|
for(i=rank-1;i>=0; i--)
|
|
{
|
|
*shlist = AddListToList(*shlist,new SgExprListExp(*DvmType_Ref(lbound[i])) );
|
|
*shlist = AddListToList(*shlist,new SgExprListExp(*DvmType_Ref(ubound[i])) );
|
|
}
|
|
}
|
|
return(iright);
|
|
}
|
|
|
|
void ShadowNames(SgSymbol *ar, int axis, SgExpression *shadow_name_list)
|
|
{
|
|
SgExpression *nml;
|
|
SgExpression *head=HeaderRef(ar);
|
|
if(!head) return;
|
|
for(nml = shadow_name_list; nml; nml = nml->rhs())
|
|
doCallAfter(IndirectShadowRenew(head,axis,nml->lhs()));
|
|
}
|
|
|
|
void TestShadowWidths(SgSymbol *ar, SgExpression * lbound[], SgExpression * ubound[], int nw, SgStatement *st)
|
|
//compare shadow widths with that specified for array 'ar' in SHADOW directive
|
|
// or SHADOW attribute of combined directive
|
|
{SgExpression *lw[MAX_DIMS], *uw[MAX_DIMS],**pe,*wl,*ew;
|
|
int i,n;
|
|
pe=SHADOW_(ar);
|
|
if(pe){ //distributed array has SHADOW attribute
|
|
//looking through the shadow width list of SHADOW directive/attribute
|
|
if(!TestMaxDims(*pe,ar,0)) return;
|
|
for(wl = *pe, i=0; wl; wl = wl->rhs(),i++) {
|
|
ew = wl->lhs();
|
|
if(ew->variant() == DDOT){
|
|
lw[i] = ew->lhs();//left bound
|
|
uw[i] = ew->rhs();//right bound
|
|
}
|
|
else {
|
|
lw[i] = ew;//left bound == right bound
|
|
uw[i] = ew;
|
|
}
|
|
}
|
|
n = i;
|
|
for(i=0; i<nw && i<n; i++){
|
|
if(lbound[i]->isInteger() && lw[i]->isInteger() && lbound[i]->valueInteger() > lw[i]->valueInteger() )
|
|
Error("Low shadow width of '%s' is greater than the corresponding one specified in SHADOW directive", ar->identifier(), 142,st);
|
|
if(ubound[i]->isInteger() && uw[i]->isInteger() && ubound[i]->valueInteger() > uw[i]->valueInteger() )
|
|
Error("High shadow width of '%s' is greater than the corresponding one specified in SHADOW directive", ar->identifier(), 143,st);
|
|
}
|
|
}
|
|
else {//by default shadow width = 1
|
|
if(!IS_DUMMY(ar) && HEADER(ar))
|
|
for(i=0; i<nw; i++){
|
|
if(lbound[i]->isInteger() && lbound[i]->valueInteger() > 1 )
|
|
Error("Low shadow width of '%s' is greater than 1", ar->identifier(), 144,st);
|
|
if(ubound[i]->isInteger() && ubound[i]->valueInteger() > 1 )
|
|
Error("High shadow width of '%s' is greater than 1", ar->identifier(), 145,st);
|
|
}
|
|
}
|
|
}
|
|
|
|
SgExpression *DeclaredShadowWidths(SgSymbol *ar)
|
|
{
|
|
SgExpression **pe,*wl,*ew, *shlist=NULL;
|
|
int i;
|
|
pe=SHADOW_(ar);
|
|
if(pe) //distributed array has SHADOW attribute
|
|
{
|
|
//looking through the shadow width list of SHADOW directive/attribute
|
|
for(wl = *pe, i=0; wl; wl = wl->rhs(),i++) {
|
|
ew = wl->lhs();
|
|
if(ew->variant() == DDOT){
|
|
shlist = AddElementToList(shlist, DvmType_Ref(ew->rhs()));
|
|
shlist = AddElementToList(shlist, DvmType_Ref(ew->lhs()));
|
|
}
|
|
else {
|
|
shlist = AddElementToList(shlist, DvmType_Ref(ew));
|
|
shlist = AddElementToList(shlist, DvmType_Ref(ew));
|
|
}
|
|
}
|
|
}
|
|
else //by default shadow width = 1
|
|
{
|
|
int rank = Rank(ar);
|
|
for (i=0; i<rank; i++) {
|
|
shlist = AddElementToList(shlist, ConstRef_F95(1));
|
|
shlist = AddElementToList(shlist, ConstRef_F95(1));
|
|
}
|
|
}
|
|
return(shlist);
|
|
}
|
|
|
|
|
|
void ShadowComp (SgExpression *ear, SgStatement *st, int ilh)
|
|
{
|
|
int ileft,iright;
|
|
SgExpression *head,*shlist[1];
|
|
SgSymbol *ar;
|
|
|
|
// array_with_shadow (variant:ARRAY_REF)
|
|
ar = ear->symbol();
|
|
if(HEADER(ar))
|
|
head = HeaderRef(ar);
|
|
else {
|
|
Error("'%s' isn't distributed array", ar->identifier(),72, st);
|
|
return;
|
|
}
|
|
if(st->expr(0)->symbol() != ar){
|
|
Error("Illegal array in SHADOW_COMPUTE clause: %s", ar->identifier(),264, st);
|
|
}
|
|
if(!ilh) //interface of RTS1
|
|
{
|
|
if(ear->lhs()){
|
|
ileft = ndvm;
|
|
iright = doShadSizeArrays(ear->lhs(), ar, st, NULL);
|
|
} else
|
|
ileft=iright= doShadSizeArrayM1(ar, NULL);
|
|
doCallAfter(AddBoundShadow(head, ileft, iright));
|
|
|
|
} else //interface of RTS2
|
|
if(ear->lhs()){
|
|
doShadSizeArrays(ear->lhs(), ar, st, shlist);
|
|
doCallAfter(ShadowCompute(ilh,head,Rank(ar),*shlist));
|
|
//doCallAfter(ShadowCompute(ilh,Register_Array_H2(head),Rank(ar),*shlist));
|
|
} else
|
|
doCallAfter(ShadowCompute(ilh,head,0,NULL));
|
|
//doCallAfter(ShadowCompute(ilh,Register_Array_H2(head),0,NULL));
|
|
}
|
|
|
|
symb_list *DerivedRhsAnalysis(SgExpression *derived_op,SgStatement *stmt, int &nd)
|
|
{
|
|
SgExpression *el;
|
|
symb_list *dummy_list = NULL;
|
|
SgSymbol *s_dummy = NULL;
|
|
nd = 0;
|
|
// looking through the rhs of derived_op ( WITH target_spec )
|
|
for(el=derived_op->rhs()->lhs();el;el=el->rhs())
|
|
{
|
|
if(el->lhs()->variant() == DUMMY_REF) // @align-dummy[ + shadow-name ]...
|
|
{
|
|
s_dummy = el->lhs()->symbol();
|
|
dummy_list = AddNewToSymbList(dummy_list,s_dummy);
|
|
nd++;
|
|
}
|
|
}
|
|
/*
|
|
if(!s_dummy) //???
|
|
err("Illegal DERIVED/SHADOW_ADD specification", 629, stmt);
|
|
*/
|
|
//reversing dummy_list
|
|
symb_list *sl = NULL;
|
|
for( ; dummy_list; dummy_list=dummy_list->next)
|
|
sl= AddNewToSymbList(sl,dummy_list->symb);
|
|
return (sl); //(dummy_list);
|
|
}
|
|
|
|
int is_derived_dummy(SgSymbol *s, symb_list *dummy_list)
|
|
{
|
|
symb_list *sl;
|
|
for(sl=dummy_list; sl; sl=sl->next)
|
|
if(s == sl->symb) return 1;
|
|
return 0;
|
|
}
|
|
|
|
symb_list *DerivedElementAnalysis(SgExpression *e, symb_list *dummy_list, symb_list *arg_list, SgStatement *stmt)
|
|
{
|
|
if(!e)
|
|
return (arg_list);
|
|
if(isSgValueExp(e))
|
|
return (arg_list);
|
|
|
|
if(isSgVarRefExp(e) && !is_derived_dummy(e->symbol(),dummy_list) || e->variant() == CONST_REF)
|
|
{
|
|
arg_list = AddNewToSymbList(arg_list,e->symbol());
|
|
return (arg_list);
|
|
}
|
|
|
|
if(isSgArrayRefExp(e) ) //!!! look trough the tree
|
|
{
|
|
if(HEADER(e->symbol()))
|
|
arg_list = AddNewToSymbList(arg_list,e->symbol());
|
|
else
|
|
Error("Illegal use of array '%s' in DERIVED/SHADOW_ADD, not implemented yet",e->symbol()->identifier(), 629, stmt);
|
|
arg_list = DerivedElementAnalysis(e->lhs(), dummy_list, arg_list, stmt);
|
|
return (arg_list);
|
|
}
|
|
|
|
arg_list = DerivedElementAnalysis(e->lhs(), dummy_list, arg_list, stmt);
|
|
arg_list = DerivedElementAnalysis(e->rhs(), dummy_list, arg_list, stmt);
|
|
return (arg_list);
|
|
}
|
|
|
|
symb_list *DerivedLhsAnalysis(SgExpression *derived_op, symb_list *dummy_list, SgStatement *stmt)
|
|
{
|
|
SgExpression *el,*e;
|
|
symb_list *arg_list = NULL, *sl;
|
|
SgExpression *elhs = derived_op->lhs(); //derived_elem_list
|
|
// looking through the lhs of derived_op (derived_elem_list)
|
|
|
|
for(el=elhs; el; el=el->rhs())
|
|
{
|
|
e = el->lhs(); // derived_elem
|
|
arg_list = DerivedElementAnalysis(e, dummy_list, arg_list, stmt);
|
|
}
|
|
return (arg_list);
|
|
}
|
|
|
|
SgExpression *FillerActualArgumentList(symb_list *paramList, int &nArg)
|
|
{
|
|
SgExpression *arg_expr_list = NULL;
|
|
symb_list *sl;
|
|
nArg = 0;
|
|
for (sl = paramList; sl; sl=sl->next)
|
|
{
|
|
if(isSgArrayType(sl->symb->type()))
|
|
{
|
|
if(!HEADER(sl->symb))
|
|
continue;
|
|
arg_expr_list = AddListToList(arg_expr_list,new SgExprListExp(*new SgArrayRefExp(*sl->symb)));
|
|
arg_expr_list = AddListToList(arg_expr_list,ElementOfAddrArgumentList(sl->symb));
|
|
nArg+=2;
|
|
}
|
|
else
|
|
{
|
|
arg_expr_list = AddListToList(arg_expr_list,new SgExprListExp(*new SgVarRefExp(*sl->symb)));
|
|
nArg++;
|
|
}
|
|
}
|
|
return arg_expr_list;
|
|
}
|
|
|
|
void DerivedSpecification(SgExpression *edrv, SgStatement *stmt, SgExpression *eFunc[])
|
|
{
|
|
int narg = 0, nd = 0;
|
|
symb_list *dummy_list = DerivedRhsAnalysis(edrv,stmt,nd);
|
|
symb_list *paramList = DerivedLhsAnalysis(edrv,dummy_list,stmt);
|
|
SgSymbol *sf_counter = IndirectFunctionSymbol(stmt,"counter");
|
|
SgSymbol *sf_filler = IndirectFunctionSymbol(stmt,"filler");
|
|
SgStatement *st_counter = CreateIndirectDistributionProcedure(sf_counter, paramList, dummy_list, edrv->lhs(), 0);
|
|
SgStatement *st_filler = CreateIndirectDistributionProcedure(sf_filler, paramList, dummy_list, edrv->lhs(), 1);
|
|
st_counter->addComment(Indirect_ProcedureComment(stmt->lineNumber()));
|
|
SgExpression *argument_list = FillerActualArgumentList(paramList,narg);
|
|
eFunc[0] = HandlerFunc (sf_counter, narg, argument_list); // counter function
|
|
eFunc[1] = HandlerFunc (sf_filler, narg, argument_list ? &argument_list->copy() : NULL); // filler function
|
|
return;
|
|
}
|
|
|
|
void Shadow_Add_Directive(SgStatement *stmt)
|
|
{
|
|
int n,iaxis;
|
|
SgExpression *el,*edrv;
|
|
for (el=stmt->expr(2),n=0; el; el=el->rhs(),n++)
|
|
; //el->setLhs(HeaderRef(el->lhs()->symbol()));HederRef() for each element of el->lhs()
|
|
int rank = Rank(stmt->expr(0)->symbol());
|
|
for (el=stmt->expr(0)->lhs(),iaxis=rank; el; el=el->rhs(),iaxis--)
|
|
if(el->lhs()->variant()==DERIVED_OP)
|
|
{
|
|
edrv = el->lhs();
|
|
break;
|
|
}
|
|
SgExpression *eFunc[2];
|
|
DerivedSpecification(edrv, stmt, eFunc);
|
|
doCallAfter(ShadowAdd(HeaderRef(stmt->expr(0)->symbol()),iaxis,DvmhDerivedRhs(edrv->rhs()),eFunc[0],eFunc[1],stmt->expr(1),n,stmt->expr(2)));
|
|
return;
|
|
}
|
|
|
|
int doAlignIteration(SgStatement *stat, SgExpression *aref)
|
|
{
|
|
SgExpression *axis[MAX_LOOP_LEVEL],
|
|
*coef[MAX_LOOP_LEVEL],
|
|
*cons[MAX_LOOP_LEVEL];
|
|
int i;
|
|
int nt = Alignment(stat,aref,axis,coef,cons,0);
|
|
// setting on arrays
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignStmtAfter(axis[i]);
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignStmtAfter(ReplaceFuncCall(coef[i]));
|
|
for(i=nt-1; i>=0; i--)
|
|
doAssignStmtAfter(Calculate(cons[i]));
|
|
return(nt);
|
|
}
|
|
|
|
int Alignment(SgStatement *stat, SgExpression *aref, SgExpression *axis[], SgExpression *coef[], SgExpression *cons[],int interface)
|
|
// creating axis_array, coeff_array and const_array
|
|
// returns the number of elements in align_iteration_list
|
|
|
|
{ int i,ni,nt,num, use[MAX_LOOP_LEVEL];
|
|
SgExpression * el,*e,*ei,*elbb, *es;
|
|
SgSymbol *l_var[MAX_LOOP_LEVEL], *ar;
|
|
SgValueExp c1(1),c0(0),cM1(-1);
|
|
|
|
|
|
ni = 0; //counter of elements in loop_control_variable_list
|
|
//looking through the loop_control_variable_list
|
|
for(el=stat->expr(2); el; el=el->rhs()) {
|
|
l_var[ni] = (el->lhs())->symbol();
|
|
use[ni] = 0;
|
|
ni++;
|
|
}
|
|
es = aref ? aref : stat->expr(0);
|
|
ar = es->symbol(); // array
|
|
|
|
//looking through the align_iteration_list
|
|
nt = 0; //counter of elements in align_iteration_list
|
|
for(el=es->lhs(); el; el=el->rhs()) {
|
|
e = el->lhs(); //subscript expression
|
|
if(e->variant()==KEYWORD_VAL || e->variant()==DDOT) { // "*" or ":"
|
|
axis[nt] = & cM1.copy();
|
|
coef[nt] = & c0.copy();
|
|
cons[nt] = & c0.copy();
|
|
}
|
|
|
|
else { // expression
|
|
num = AxisNumOfDummyInExpr(e, l_var, ni, &ei, use, stat);
|
|
//printf("\nnum = %d\n", num);
|
|
if (num<=0) {
|
|
axis[nt] = & c0.copy();
|
|
coef[nt] = & c0.copy();
|
|
cons[nt] = & (e->copy());
|
|
if((elbb = LowerBound(ar,nt)) != NULL && interface != 2)
|
|
cons[nt] = & (*cons[nt] - (elbb->copy()));
|
|
// correcting const with lower bound of array, if interface != 2
|
|
}
|
|
else {
|
|
axis[nt] = new SgValueExp(num);
|
|
CoeffConst(e, ei, &coef[nt], &cons[nt]);
|
|
if(interface != 2)
|
|
TestReverse(coef[nt],stat);
|
|
if(!coef[nt]){
|
|
err("Wrong iteration-align-subscript in PARALLEL", 160,stat);
|
|
coef[nt] = & c0.copy();
|
|
cons[nt] = & c0.copy();
|
|
}
|
|
else
|
|
// correcting const with lower bound of array, if interface != 2
|
|
if((elbb = LowerBound(ar,nt)) != NULL && interface != 2 )
|
|
cons[nt] = &(*cons[nt] - (elbb->copy()));
|
|
}
|
|
}
|
|
|
|
nt++;
|
|
}
|
|
|
|
if(Rank(ar) && Rank(ar) != nt)
|
|
Error("Rank of array '%s' isn't equal to the length of iteration-align-subscript-list", ar->identifier(), 161,stat);
|
|
|
|
return(nt);
|
|
}
|
|
|
|
int DefineLoopNumberForDimension(SgStatement * stat, SgExpression *ear, int loop_num[])
|
|
{ int ni,nt,num,i, use[MAX_LOOP_LEVEL];
|
|
SgExpression * el,*e,*ei;
|
|
SgSymbol *l_var[MAX_LOOP_LEVEL], *ar;
|
|
if(!ear) return 0;
|
|
for(i=MAX_DIMS-1; i; i--)
|
|
loop_num[i] = 0;
|
|
ni = 0; //counter of elements in loop_control_variable_list
|
|
//looking through the loop_control_variable_list
|
|
for(el=stat->expr(2); el; el=el->rhs()) {
|
|
l_var[ni] = (el->lhs())->symbol();
|
|
use[ni] = 0;
|
|
ni++;
|
|
}
|
|
//ar = stat->expr(0)->symbol(); // array
|
|
ar = ear->symbol(); // array
|
|
//looking through the align_iteration_list
|
|
nt = 0; //counter of elements in align_iteration_list
|
|
for(el=ear->lhs(); el; el=el->rhs()) {
|
|
e = el->lhs(); //subscript expression
|
|
if(e->variant()==KEYWORD_VAL) { // "*"
|
|
loop_num[nt] = 0; // -1;
|
|
|
|
}
|
|
|
|
else { // expression
|
|
num = AxisNumOfDummyInExpr(e, l_var, ni, &ei, use, stat);
|
|
//printf("\nnum = %d\n", num);
|
|
if (num<=0)
|
|
loop_num[nt] = 0;
|
|
else
|
|
loop_num[nt] = num;
|
|
}
|
|
|
|
nt++;
|
|
}
|
|
|
|
|
|
return(nt);
|
|
}
|
|
|
|
int RedFuncNumber(SgExpression *kwe)
|
|
{
|
|
char *red_name;
|
|
//PTR_LLND thellnd;
|
|
red_name = ((SgKeywordValExp *) kwe)->value();
|
|
// red_name = NODE_STRING_POINTER(kwe->thellnd);
|
|
if(!strcmp(red_name, "sum"))
|
|
return(1);
|
|
if(!strcmp(red_name, "product"))
|
|
return(2);
|
|
if(!strcmp(red_name, "max"))
|
|
return(3);
|
|
if(!strcmp(red_name, "min"))
|
|
return(4);
|
|
if(!strcmp(red_name, "and"))
|
|
return(5);
|
|
if(!strcmp(red_name, "or"))
|
|
return(6);
|
|
if(!strcmp(red_name, "neqv"))
|
|
return(7);
|
|
if(!strcmp(red_name, "eqv"))
|
|
return(8);
|
|
if(!strcmp(red_name, "maxloc"))
|
|
return(9);
|
|
if(!strcmp(red_name, "minloc"))
|
|
return(10);
|
|
|
|
return(0);
|
|
}
|
|
|
|
int RedFuncNumber_2(int num)
|
|
{ //MAXLOC: 9=>11, MINLOC: 10=>12
|
|
return(num>8 ? num+2 : num);
|
|
}
|
|
|
|
int VarType_RTS(SgSymbol *var)
|
|
{int t;
|
|
t=TestType(var->type());
|
|
if(t==7) //LOGICAL
|
|
t=(bind_==0) ? 2 : 1; //there is not LOGICAL type in RTS
|
|
return(t);
|
|
}
|
|
|
|
int VarType(SgSymbol *var)
|
|
{ if(IS_POINTER_F90(var) )
|
|
return(0);
|
|
else
|
|
return (TestType(var->type()));
|
|
}
|
|
|
|
int TestType_DVMH(SgType *type)
|
|
{
|
|
if(!type)
|
|
return(-1);
|
|
|
|
SgArrayType *artype = isSgArrayType(type);
|
|
if(artype)
|
|
type = artype->baseType();
|
|
switch(type->variant())
|
|
{
|
|
case T_BOOL:
|
|
case T_INT: return(1);
|
|
|
|
|
|
case T_FLOAT:
|
|
case T_DOUBLE: return(3);
|
|
|
|
|
|
case T_COMPLEX:
|
|
case T_DCOMPLEX: return(5);
|
|
|
|
|
|
default: return(-1);
|
|
}
|
|
|
|
}
|
|
|
|
int TestType_RTS(SgType *type)
|
|
{ int t;
|
|
t=TestType(type);
|
|
if(t==7) //LOGICAL
|
|
t=(bind_==0) ? 2 : 1; //there is not LOGICAL type in RTS
|
|
return (t);
|
|
}
|
|
|
|
int TestType(SgType *type)
|
|
{ int len;
|
|
SgArrayType *artype;
|
|
|
|
if(!type)
|
|
return(0);
|
|
|
|
artype=isSgArrayType(type);
|
|
if(artype)
|
|
type = artype->baseType();
|
|
len = TypeSize(type); /*16.04.04*/
|
|
//len = IS_INTRINSIC_TYPE(type) ? 0 : TypeSize(type);
|
|
//len = (TYPE_RANGES(type->thetype)) ? type->length()->valueInteger() : 0; 14.03.03
|
|
if(bind_ == 0)
|
|
switch(type->variant()) {
|
|
case T_BOOL: if (len == 4) return(7); /*14.11.06 type LOGICAL was introduced in debuger*/
|
|
else return(0);
|
|
|
|
case T_INT: if (len == 4) return(1); /*3.11.06 2 => 1 */
|
|
else return(0);
|
|
|
|
case T_FLOAT: if (len == 8) return(4);
|
|
else if(len == 4) return(3);
|
|
else return(0);
|
|
|
|
case T_DOUBLE: if (len == 8) return(4);
|
|
else return(0);
|
|
|
|
case T_COMPLEX: if (len ==16) return(6);
|
|
else if(len == 8) return(5);
|
|
else return(0);
|
|
|
|
case T_DCOMPLEX:if (len ==16) return(6);
|
|
else return(0);
|
|
|
|
default: return(0);
|
|
}
|
|
if(bind_ == 1)
|
|
switch(type->variant()) {
|
|
case T_BOOL: if (len == 8) return(2);
|
|
else if(len == 4) return(7); /*14.11.06 type LOGICAL was introduced in debuger*/
|
|
else return(0);
|
|
case T_INT: if (len == 8) return(2);
|
|
else if(len == 4) return(1);
|
|
else return(0);
|
|
case T_FLOAT: if (len == 8) return(4);
|
|
else if(len == 4) return(3);
|
|
else return(0);
|
|
case T_DOUBLE: if (len == 8) return(4);
|
|
else return(0);
|
|
|
|
case T_COMPLEX: if (len ==16) return(6);
|
|
else if(len == 8) return(5);
|
|
else return(0);
|
|
case T_DCOMPLEX:if (len ==16) return(6);
|
|
else return(0);
|
|
default: return(0);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
/*RTS2*/
|
|
#define rt_UNKNOWN (-1)
|
|
#define rt_CHAR 0
|
|
#define rt_INT 1
|
|
#define rt_LONG 2
|
|
#define rt_FLOAT 3
|
|
#define rt_DOUBLE 4
|
|
#define rt_FLOAT_COMPLEX 5
|
|
#define rt_DOUBLE_COMPLEX 6
|
|
#define rt_LOGICAL 7
|
|
#define rt_LLONG 8
|
|
#define rt_UCHAR 9
|
|
#define rt_UINT 10
|
|
#define rt_ULONG 11
|
|
#define rt_ULLONG 12
|
|
#define rt_SHORT 13
|
|
#define rt_USHORT 14
|
|
|
|
int TestType_RTS2(SgType *type)
|
|
{ int len;
|
|
SgArrayType *artype;
|
|
|
|
if(!type)
|
|
return(rt_UNKNOWN);
|
|
|
|
artype=isSgArrayType(type);
|
|
if(artype)
|
|
type = artype->baseType();
|
|
len = TypeSize(type);
|
|
if(bind_ == 0)
|
|
switch(type->variant()) {
|
|
case T_BOOL: if (len == 4) return(rt_LOGICAL);
|
|
else if(len == 2) return(rt_USHORT);
|
|
else return(rt_UNKNOWN);
|
|
|
|
case T_INT: if (len == 4) return(rt_INT);
|
|
else if(len == 2) return(rt_SHORT);
|
|
else return(rt_UNKNOWN);
|
|
|
|
case T_FLOAT: if (len == 8) return(rt_DOUBLE);
|
|
else if(len == 4) return(rt_FLOAT);
|
|
else return(rt_UNKNOWN);
|
|
|
|
case T_DOUBLE: if (len == 8) return(rt_DOUBLE);
|
|
else return(rt_UNKNOWN);
|
|
|
|
case T_COMPLEX: if (len ==16) return(rt_DOUBLE_COMPLEX);
|
|
else if(len == 8) return(rt_FLOAT_COMPLEX);
|
|
else return(rt_UNKNOWN);
|
|
|
|
case T_DCOMPLEX:if (len ==16) return(rt_DOUBLE_COMPLEX);
|
|
else return(rt_UNKNOWN);
|
|
case T_STRING:
|
|
case T_CHAR: if (len == 1) return(rt_CHAR);
|
|
else return(rt_UNKNOWN);
|
|
|
|
default: return(rt_UNKNOWN);
|
|
}
|
|
if(bind_ == 1)
|
|
switch(type->variant()) {
|
|
|
|
case T_BOOL: if (len == 8) return(rt_ULONG);
|
|
else if(len == 4) return(rt_LOGICAL);
|
|
else if(len == 2) return(rt_USHORT);
|
|
else return(rt_UNKNOWN);
|
|
case T_INT: if (len == 8) return(rt_LONG);
|
|
else if(len == 4) return(rt_INT);
|
|
else if(len == 2) return(rt_SHORT);
|
|
else return(rt_UNKNOWN);
|
|
case T_FLOAT: if (len == 8) return(rt_DOUBLE);
|
|
else if(len == 4) return(rt_FLOAT);
|
|
else return(rt_UNKNOWN);
|
|
case T_DOUBLE: if (len == 8) return(rt_DOUBLE);
|
|
else return(rt_UNKNOWN);
|
|
|
|
case T_COMPLEX: if (len ==16) return(rt_DOUBLE_COMPLEX);
|
|
else if(len == 8) return(rt_FLOAT_COMPLEX);
|
|
else return(rt_UNKNOWN);
|
|
case T_DCOMPLEX:if (len ==16) return(rt_DOUBLE_COMPLEX);
|
|
else return(rt_UNKNOWN);
|
|
case T_STRING:
|
|
case T_CHAR: if (len == 1) return(rt_CHAR);
|
|
else return(rt_UNKNOWN);
|
|
|
|
default: return(rt_UNKNOWN);
|
|
}
|
|
return(rt_UNKNOWN);
|
|
}
|
|
|
|
SgExpression *TypeSize_RTS2(SgType *type)
|
|
{
|
|
SgArrayType *artype=isSgArrayType(type);
|
|
if(artype)
|
|
type = artype->baseType();
|
|
int it = TestType_RTS2(type);
|
|
SgExpression *ts = it >= 0 ? &SgUMinusOp(*ConstRef(it)) : ConstRef_F95(TypeSize(type));
|
|
return(ts);
|
|
}
|
|
|
|
int DVMType()
|
|
{return(2);}
|
|
|
|
int NameIndex(SgType *type)
|
|
{int len;
|
|
len = TypeSize(type); //IS_INTRINSIC_TYPE(type) ? 0 : TypeSize(type);
|
|
switch ( type->variant()) {
|
|
case T_INT: return (GETAI);
|
|
case T_FLOAT: return((len == 8) ? GETAD : GETAF);
|
|
case T_BOOL: return (GETAL);
|
|
case T_DOUBLE: return (GETAD);
|
|
case T_COMPLEX: return (GETAC);
|
|
case T_DCOMPLEX: return (GETAC);
|
|
case T_STRING: return (GETACH);
|
|
case T_CHAR: return (GETACH);
|
|
default: return (GETAI);
|
|
}
|
|
}
|
|
|
|
SgType *Base_Type(SgType *type)
|
|
{ return ( isSgArrayType(type) ? type->baseType() : type);}
|
|
|
|
void doLoopStmt(SgStatement *st)
|
|
{
|
|
SgStatement *dost, *contst;
|
|
SgValueExp c1(1);
|
|
SgLabel *loop_lab;
|
|
SgSymbol *sio;
|
|
int i;
|
|
//!!!
|
|
nio = 3;
|
|
//!!!
|
|
sio = st->expr(0)->lhs()->symbol();
|
|
buf_use[TypeIndex(sio->type()->baseType())] = 1;
|
|
// SgSymbol * dovar = new SgVariableSymb("IDVM01",*SgTypeInt(), *func);
|
|
loop_lab = GetLabel();
|
|
contst = new SgStatement(CONT_STAT);
|
|
dost= new SgForStmt(*loop_var[0], c1.copy(), c1.copy(), c1.copy(), *contst);
|
|
BIF_LABEL_USE(dost->thebif) = loop_lab->thelabel;
|
|
(dost->lexNext())->setLabel(*loop_lab);
|
|
for(i=1; i<3; i++){
|
|
dost= new SgForStmt(*loop_var[i], c1.copy(), c1.copy(), c1.copy(),
|
|
*dost);
|
|
BIF_LABEL_USE(dost->thebif) = loop_lab->thelabel;
|
|
}
|
|
|
|
st->insertStmtAfter(*dost);
|
|
for(i=0; i<3; i++)
|
|
contst->lexNext()->extractStmt();
|
|
//dost->lexNext()->lexNext()->lexNext()->extractStmt();
|
|
//dost->lexNext()->lexNext()->lexNext()->extractStmt();
|
|
|
|
// generating the construction IF () THEN < > ELSE < > ENDIF
|
|
// and then insert it before CONTINUE statement
|
|
/* SgStatement *if_stmt =new SgIfStmt(*(current->controlParent())->expr(0) , *current);
|
|
contst -> insertStmtBefore(*if_stmt);
|
|
*/
|
|
cur_st = contst;
|
|
}
|
|
|
|
SgExpression *ReplaceParameter(SgExpression *e)
|
|
{
|
|
if(!e)
|
|
return(e);
|
|
if(e->variant() == CONST_REF) {
|
|
SgConstantSymb * sc = isSgConstantSymb(e->symbol());
|
|
if(!sc->constantValue())
|
|
{ Err_g("An initialization expression is missing: %s",sc->identifier(),267);
|
|
return(e);
|
|
}
|
|
return(ReplaceParameter(&(sc->constantValue()->copy())));
|
|
}
|
|
e->setLhs(ReplaceParameter(e->lhs()));
|
|
e->setRhs(ReplaceParameter(e->rhs()));
|
|
return(e);
|
|
}
|
|
|
|
SgExpression *ReplaceFuncCall(SgExpression *e)
|
|
{
|
|
if(!e)
|
|
return(e);
|
|
if(isSgFunctionCallExp(e) && e->symbol()) {//function call
|
|
if( !e->lhs() && (!strcmp(e->symbol()->identifier(),"number_of_processors") || !strcmp(e->symbol()->identifier(),"actual_num_procs") || !strcmp(e->symbol()->identifier(),"number_of_nodes"))) { //NUMBER_OF_PROCESSORS() or // ACTUAL_NUM_PROCS() or NUMBER_OF_NODES()
|
|
SgExprListExp *el1,*el2;
|
|
if(!strcmp(e->symbol()->identifier(),"number_of_processors"))
|
|
el1 = new SgExprListExp(*ParentPS());
|
|
else
|
|
el1 = new SgExprListExp(*CurrentPS());
|
|
el2 = new SgExprListExp(*ConstRef(0));
|
|
e->setSymbol(fdvm[GETSIZ]);
|
|
fmask[GETSIZ] = 1;
|
|
el1->setRhs(el2);
|
|
e->setLhs(el1);
|
|
return(e);
|
|
}
|
|
|
|
if( !e->lhs() && (!strcmp(e->symbol()->identifier(),"processors_rank"))) {
|
|
//PROCESSORS_RANK()
|
|
SgExprListExp *el1;
|
|
el1 = new SgExprListExp(*ParentPS());
|
|
e->setSymbol(fdvm[GETRNK]);
|
|
fmask[GETRNK] = 1;
|
|
e->setLhs(el1);
|
|
return(e);
|
|
}
|
|
|
|
if(!strcmp(e->symbol()->identifier(),"processors_size")) {
|
|
//PROCESSORS_SIZE()
|
|
SgExprListExp *el1;
|
|
el1 = new SgExprListExp(*ParentPS());
|
|
e->setSymbol(fdvm[GETSIZ]);
|
|
fmask[GETSIZ] = 1;
|
|
el1->setRhs(*(e->lhs())+(*ConstRef(0))); //el1->setRhs(e->lhs());
|
|
e->setLhs(el1);
|
|
return(e);
|
|
}
|
|
}
|
|
e->setLhs(ReplaceFuncCall(e->lhs()));
|
|
e->setRhs(ReplaceFuncCall(e->rhs()));
|
|
return(e);
|
|
}
|
|
|
|
SgExpression *Calculate(SgExpression *e)
|
|
{ SgExpression *er;
|
|
er = ReplaceParameter( &(e->copy()));
|
|
if(er->isInteger())
|
|
return( new SgValueExp(er->valueInteger()));
|
|
else
|
|
return(ReplaceFuncCall(e));
|
|
}
|
|
|
|
int ExpCompare(SgExpression *e1, SgExpression *e2)
|
|
{//compares two expressions
|
|
// returns 1 if they are textually identical
|
|
if(!e1 && !e2) // both expressions are null
|
|
return(1);
|
|
if(!e1 || !e2) // one of them is null
|
|
return(0);
|
|
if(e1->variant() != e2->variant()) // variants are not equal
|
|
return(0);
|
|
switch (e1->variant()) {
|
|
case INT_VAL:
|
|
return(NODE_IV(e1->thellnd) == NODE_IV(e2->thellnd));
|
|
case BOOL_VAL:
|
|
return(NODE_BOOL_CST(e1->thellnd) == NODE_BOOL_CST(e2->thellnd));
|
|
case FLOAT_VAL:
|
|
case DOUBLE_VAL:
|
|
case CHAR_VAL:
|
|
case STRING_VAL:
|
|
return(!strcmp(NODE_STR(e1->thellnd),NODE_STR(e2->thellnd)));
|
|
case COMPLEX_VAL:
|
|
return(ExpCompare(e1->lhs(),e2->lhs()) && ExpCompare (e1->rhs(),e2->rhs()));
|
|
case CONST_REF:
|
|
case VAR_REF:
|
|
return(e1->symbol() == e2->symbol());
|
|
case ARRAY_REF:
|
|
case FUNC_CALL:
|
|
if(e1->symbol() == e2->symbol())
|
|
return(ExpCompare(e1->lhs(),e2->lhs())); // compares subscript/argument lists
|
|
else
|
|
return(0);
|
|
case EXPR_LIST:
|
|
{SgExpression *el1,*el2;
|
|
for(el1=e1,el2=e2; el1&&el2; el1=el1->rhs(),el2=el2->rhs())
|
|
if(!ExpCompare(el1->lhs(),el2->lhs())) // the corresponding elements of lists are not identical
|
|
return(0);
|
|
if(el1 || el2) //one list is shorter than other
|
|
return(0);
|
|
else
|
|
return(1);
|
|
}
|
|
case MINUS_OP: //unary operations
|
|
case NOT_OP:
|
|
return(ExpCompare(e1->lhs(),e2->lhs())); // compares operands
|
|
default:
|
|
return(ExpCompare(e1->lhs(),e2->lhs()) && ExpCompare (e1->rhs(),e2->rhs()));
|
|
}
|
|
}
|
|
|
|
int RemAccessRefCompare(SgExpression *e1, SgExpression *e2)
|
|
{ // returns 1 if e2 ArrayRef in current statement is identical the e1 ArrayREf in precedent REMOTE_ACCESS statement
|
|
SgExpression *el1, *el2;
|
|
if(!e1) // for error situation in REMOTE_ACCESS
|
|
return(0);
|
|
|
|
if(e1->variant() != e2->variant()) // variants are not equal ( for error situation in REMOTE_ACCESS)
|
|
return(0);
|
|
|
|
if(e1->symbol() != e2->symbol()) //different array references
|
|
return(0);
|
|
|
|
if(!e1->lhs()) // whole array in REMOTE_ACCESS
|
|
return(1);
|
|
|
|
for(el1=e1->lhs(),el2=e2->lhs(); el1&&el2; el1=el1->rhs(),el2=el2->rhs()) //compares subscript lists
|
|
if(el1->lhs()->variant() == DDOT) // is ':' element
|
|
;
|
|
else
|
|
if(!ExpCompare(el1->lhs(),el2->lhs())) // corresponding subscript expressions are not identical
|
|
return(0);
|
|
if(el1 || el2) //one list is shorter than other
|
|
return(0);
|
|
else
|
|
return(1);
|
|
}
|
|
|
|
SgExpression * isRemAccessRef(SgExpression *e)
|
|
//returns remote-variable with which array reference 'e' consides or NULL
|
|
{SgExpression *el;
|
|
rem_acc *r;
|
|
if(HPF_program && !inparloop){
|
|
//rem_var *rv = (rem_var *) e->attributeValue(0,REMOTE_VARIABLE) ;
|
|
if( e->attributeValue(0,REMOTE_VARIABLE))
|
|
return(e);
|
|
else
|
|
return(NULL);
|
|
}
|
|
//looking through the remote-access directive/clause list
|
|
for(r=rma; r; r=r->next)
|
|
//looking through the remote-variable list
|
|
for(el=r->rml; el; el=el->rhs())
|
|
if(el->lhs()->attributeValue(0,REMOTE_VARIABLE) && RemAccessRefCompare(el->lhs(), e))
|
|
return(el->lhs());
|
|
return(NULL);
|
|
}
|
|
|
|
void ChangeRemAccRef(SgExpression *e, SgExpression *rve)
|
|
//changes remote-access reference by special buffer reference (multiplicated array i.e.DISTRIBUTE(*,*,...,*))
|
|
// remote-variable attribute saves information about this buffer array
|
|
{rem_var *rv = (rem_var *) rve->attributeValue(0,REMOTE_VARIABLE) ;
|
|
SgExpression *p = NULL;
|
|
SgExpression *el1, *el2,**dov;
|
|
SgSymbol *ar;
|
|
|
|
ar = e->symbol();
|
|
if(rv->ncolon) { //there are ':'elements in index list of remote variable
|
|
//looking through the subscript and index lists
|
|
for(el1=rve->lhs(),el2=e->lhs(); el1 && el2; el1=el1->rhs(),el2=el2->rhs())
|
|
if(el1->lhs()->variant() == DDOT) // ':'
|
|
p=el2;
|
|
else if((dov=IS_DO_VARIABLE_USE(el1->lhs()))){ //do-variable-use
|
|
el2->setLhs(*dov);
|
|
p=el2;
|
|
}
|
|
else
|
|
//delete corresponding subscript in remote_access reference
|
|
if(!p)
|
|
e->setLhs(el2->rhs());
|
|
else
|
|
p->setRhs(el2->rhs());
|
|
|
|
if(for_kernel || for_host)
|
|
{
|
|
if(rv->buffer)
|
|
e->setSymbol(rv->buffer); /*ACC*/
|
|
}
|
|
else
|
|
e->setSymbol(baseMemory(ar->type()->baseType()));
|
|
if(for_host) /*ACC*/
|
|
return; // is not linearized
|
|
|
|
if(IN_COMPUTE_REGION || inparloop && parloop_by_handler)
|
|
{
|
|
if(rv->buffer)
|
|
(e->lhs())->setLhs(*LinearFormB_for_ComputeRegion (rv->buffer, rv->ncolon, e->lhs())); /*ACC*/
|
|
}
|
|
else
|
|
(e->lhs())->setLhs(*LinearFormB(((rv->amv == 1) ? ar : (SgSymbol *) NULL), rv->index, rv->ncolon, e->lhs()));
|
|
(e->lhs())->setRhs(NULL);
|
|
}
|
|
else {
|
|
if(rv->amv == -1)
|
|
{
|
|
int tInt = TypeIndex(e->symbol()->type()->baseType());
|
|
if(tInt != -1)
|
|
e->setSymbol(rmbuf[tInt]);
|
|
e->setLhs(new SgExprListExp(*new SgValueExp(rv->index)));
|
|
}
|
|
else {
|
|
if(for_kernel || for_host)
|
|
{
|
|
if(rv->buffer)
|
|
e->setSymbol(rv->buffer); /*ACC*/
|
|
}
|
|
else
|
|
e->setSymbol(baseMemory(ar->type()->baseType()));
|
|
if(for_host)
|
|
{ /*ACC*/
|
|
e->setLhs (*new SgExprListExp(*new SgValueExp(0)));
|
|
return;
|
|
}
|
|
if(IN_COMPUTE_REGION || inparloop && parloop_by_handler)
|
|
{
|
|
if(rv->buffer)
|
|
(e->lhs())->setLhs(*LinearFormB_for_ComputeRegion (rv->buffer, rv->ncolon, NULL)); /*ACC*/
|
|
}
|
|
else
|
|
(e->lhs())->setLhs(*LinearFormB(((rv->amv == 1) ? ar : (SgSymbol *) NULL), rv->index, rv->ncolon, NULL));
|
|
(e->lhs())->setRhs(NULL);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
int CreateBufferArray (int rank, SgExpression *rme, int *amview, SgStatement *stmt)
|
|
{int ihead,isize,i,j,iamv,ileft,idis;
|
|
SgExpression *es,*esz[MAX_DIMS], *elb[MAX_DIMS];
|
|
ihead = ndvm; // allocating array header for buffer array
|
|
ndvm+=2*rank+2;
|
|
iamv = *amview = ndvm++;
|
|
for(es=rme->lhs(),i=0,j=0; es; es=es->rhs(),i++) //looking through the index list
|
|
if(es->lhs()->variant() == DDOT) {
|
|
//determination of dimension size
|
|
esz[j] = ArrayDimSize(rme->symbol(),i+1);
|
|
if(esz[j] && esz[j]->variant()==STAR_RANGE)
|
|
Error("Assumed-size array: %s",rme->symbol()->identifier(),162,stmt);
|
|
if(!esz[j]) //esz[j] == NULL (error situation)
|
|
esz[j] = new SgValueExp(1); //for continuing traslation
|
|
else
|
|
esz[j] = Calculate(esz[j]);
|
|
elb[j] = header_ref(rme->symbol(),Rank(rme->symbol())+i+3);
|
|
// Exprn(LowerBound(rme->symbol(),i));
|
|
j++;
|
|
}
|
|
isize = ndvm;
|
|
for(j=rank; j; j--) //creating Size Array
|
|
doAssignStmtAfter(esz[j-1]);
|
|
|
|
/*generating function call:CrtAMV(AMRef,Rank,SizeArray,StaticSign)*/
|
|
doAssignTo_After(DVM000(iamv),CreateAMView(DVM000(isize),rank,0)); //creating the representation of abstact machine
|
|
|
|
idis = ndvm;
|
|
for(j=rank; j; j--) //creating DisRule Array for DISTRIBUTE(*,*,...,*)
|
|
doAssignStmtAfter(new SgValueExp(0));
|
|
/*generating function call:DisAM(AMViewRef,PSRef,ParamCount, AxisArray, DistrParamArray)*/
|
|
doAssignStmtAfter(DistributeAM(DVM000(iamv),CurrentPS(),rank,idis,idis));//distributing
|
|
|
|
|
|
ileft = ndvm;
|
|
for(j=rank; j; j--) //creating LeftShSizeArray == RightShSizeArray = {0,..,0}
|
|
doAssignStmtAfter(new SgValueExp(0));
|
|
|
|
for(j=0; j<rank; j++) //storing lower bounds
|
|
doAssignTo_After(DVM000(ihead+rank+2+j),elb[j]);
|
|
|
|
/*generating call:CrtDA(ArrayHeader,Base,Rank,TypeSize,SizeArray,StaticSign,ReDistrSign,LeftShSizeArr,RightShSizeAr)*/
|
|
doAssignStmtAfter(CreateDistArray(rme->symbol(),DVM000(ihead),DVM000(isize),rank,ileft,ileft,0,0));
|
|
//creating distributed array ("replicated")
|
|
|
|
|
|
ndvm = isize;
|
|
for(j=1; j<=rank; j++) //creating AxisArray = {1,2,..,rank}
|
|
doAssignStmtAfter(new SgValueExp(j));
|
|
|
|
ndvm = idis;
|
|
for(j=rank; j; j--) //creating CoeffArray = {1,1,...,1}
|
|
doAssignStmtAfter(new SgValueExp(1));
|
|
|
|
//ConstArray = {0,0,...,0}
|
|
|
|
/*generating call:AlnDa(ArrayHeader,AMViewRef,AxisArray,CoefArray,ConstArray)*/
|
|
doAssignStmtAfter(AlignArray(DVM000(ihead),DVM000(iamv),isize,idis,ileft));//aligning
|
|
|
|
|
|
//doAssignTo_After(DVM000(ihead+rank+1),BufferHeaderNplus1(rme,rank,ihead));
|
|
// calculating HEADER(rank+1)
|
|
SET_DVM(isize);
|
|
return(ihead);
|
|
}
|
|
|
|
void CopyToBuffer(int rank, int ibuf, SgExpression *rme)
|
|
{ int itype,iindex,i,j,from_init,to_init;
|
|
SgExpression *es,*ei[MAX_DIMS],*el[MAX_DIMS],*head;
|
|
SgValueExp MM1(-1);
|
|
|
|
if(!rank) { // copying one element of distributed array to buffer
|
|
itype = TypeIndex(rme->symbol()->type()->baseType());
|
|
if(itype == -1)
|
|
itype = 0;
|
|
SgExpression *are = new SgArrayRefExp(*rmbuf[itype],*new SgValueExp(ibuf));//buffer reference
|
|
|
|
for(es=rme->lhs(),i=0; es; es=es->rhs(),i++){ //looking through the index list
|
|
ei[i] = &( es->lhs()->copy() - *Exprn( LowerBound(rme->symbol(),i)));
|
|
}
|
|
iindex = ndvm;
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(ei[j-1]);
|
|
|
|
if((head=HeaderRef(rme->symbol())) != NULL) // NULL if array is not distributed (error)
|
|
doAssignStmtAfter(ReadWriteElement(head,are,iindex));
|
|
|
|
if(dvm_debug)
|
|
InsertNewStatementAfter(D_RmBuf(head,GetAddresMem(are),0,iindex),cur_st,cur_st->controlParent());
|
|
|
|
SET_DVM(iindex);
|
|
return;
|
|
}
|
|
//copying section of distributed array to buffer array
|
|
|
|
for(es=rme->lhs(),i=0; es; es=es->rhs(),i++) {//looking through the index list
|
|
if(es->lhs()->variant() != DDOT)
|
|
ei[i] = &( es->lhs()->copy() - * Exprn(LowerBound(rme->symbol(),i))); //init index
|
|
else
|
|
ei[i] =& MM1.copy(); // -1
|
|
el[i] = & ei[i]->copy(); //last index
|
|
}
|
|
from_init = ndvm;
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(ei[j-1]);
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(el[j-1]);
|
|
to_init = ndvm;
|
|
for(j=rank; j; j-- )
|
|
doAssignStmtAfter(& MM1.copy());
|
|
|
|
if((head=HeaderRef(rme->symbol())) != NULL) // NULL if array is not distributed (error)
|
|
doAssignStmtAfter(ArrayCopy(head, from_init, from_init+i, from_init, DVM000(ibuf), to_init, to_init, to_init, 0));
|
|
if(dvm_debug)
|
|
InsertNewStatementAfter(D_RmBuf(head,GetAddresMem(DVM000(ibuf)),i,from_init),cur_st,cur_st->controlParent());
|
|
|
|
SET_DVM(from_init);
|
|
return;
|
|
}
|
|
|
|
void RemoteAccessDirective(SgStatement *stmt)
|
|
{SgStatement *rmout;
|
|
if(inparloop) {
|
|
err("The directive is inside the range of PARALLEL loop", 98,stmt);
|
|
return;
|
|
}
|
|
ReplaceContext(stmt->lexNext());
|
|
switch(stmt->lexNext()->variant()) {
|
|
case LOGIF_NODE:
|
|
rmout = stmt->lexNext()->lexNext()->lexNext();
|
|
break;
|
|
case SWITCH_NODE:
|
|
rmout = stmt->lexNext()->lastNodeOfStmt()->lexNext();
|
|
break;
|
|
case IF_NODE:
|
|
rmout = lastStmtOfIf(stmt->lexNext())->lexNext();
|
|
break;
|
|
case CASE_NODE:
|
|
case ELSEIF_NODE:
|
|
err("Misplaced REMOTE_ACCESS directive", 99,stmt);
|
|
rmout = stmt->lexNext()->lexNext();
|
|
break;
|
|
case FOR_NODE:
|
|
case WHILE_NODE:
|
|
rmout = lastStmtOfDo(stmt->lexNext())->lexNext();
|
|
break;
|
|
case DVM_PARALLEL_ON_DIR:
|
|
rmout = lastStmtOfDo(stmt->lexNext()->lexNext())->lexNext();
|
|
break;
|
|
default:
|
|
rmout = stmt->lexNext()->lexNext();
|
|
break;
|
|
}
|
|
// adding new element to remote_access directive/clause list
|
|
AddRemoteAccess(stmt->expr(0),rmout);
|
|
|
|
LINE_NUMBER_AFTER(stmt,stmt); //for tracing
|
|
|
|
// looking through the remote variable list
|
|
|
|
RemoteVariableList(stmt->symbol(),stmt->expr(0),stmt);
|
|
}
|
|
|
|
SgExpression *AlignmentListForRemoteDir(int nt, SgExpression *axis[], SgExpression *coef[], SgExpression *cons[])
|
|
{ // case of RTS2 interface
|
|
SgExpression *arglist=NULL, *el, *e;
|
|
|
|
for(int i=0; i<nt; i++)
|
|
{
|
|
e = AlignmentLinear(axis[i],ReplaceFuncCall(coef[i]),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 RemoteVariableList1(SgSymbol *group,SgExpression *rml, SgStatement *stmt)
|
|
{ SgStatement *if_st,*end_st = NULL;
|
|
SgExpression *el, *es;
|
|
int nc; //counter of ':' elements of remote-index-list
|
|
int n; //counter of elements of remote-index-list
|
|
int rank; //rank of remote variable
|
|
int ibuf = 0;
|
|
int iamv =-1;
|
|
if(group){
|
|
if_st = doIfThenConstrForRemAcc(group,cur_st);
|
|
end_st = cur_st; //END IF
|
|
cur_st = if_st;
|
|
}
|
|
for(el=rml; el; el= el->rhs()) {
|
|
if(!HEADER(el->lhs()->symbol())) //if non-distributed array occurs
|
|
Error("'%s' is not distributed array",el->lhs()->symbol()->identifier(),72,stmt);
|
|
n = 0;
|
|
nc = 0;
|
|
// looking through the index list of remote variable
|
|
for(es=el->lhs()->lhs(); es; es= es->rhs(),n++)
|
|
if(es->lhs()->variant() == DDOT)
|
|
nc++;
|
|
if((rank=Rank(el->lhs()->symbol())) && rank != n)
|
|
Error("Length of remote-index-list is not equal to the rank of remote variable",el->lhs()->symbol()->identifier(),165,stmt);
|
|
else
|
|
if (nc) {
|
|
ibuf = CreateBufferArray(nc,el->lhs(),&iamv, stmt);//creating replicated array
|
|
//copying to Buffer Array
|
|
CopyToBuffer(nc, ibuf, el->lhs());
|
|
}
|
|
else {
|
|
ibuf = ++rma->rmbuf_use[TypeIndex(el->lhs()->symbol()->type()->baseType())];
|
|
//copying to buffer
|
|
CopyToBuffer(nc, ibuf, el->lhs());
|
|
}
|
|
//adding attribute REMOTE_VARIABLE
|
|
rem_var *remv = new rem_var;
|
|
remv->ncolon = nc;
|
|
|
|
remv->index = ibuf;
|
|
remv->amv = iamv;
|
|
(el->lhs())->addAttribute(REMOTE_VARIABLE,(void *) remv, sizeof(rem_var));
|
|
}
|
|
if(group)
|
|
// cur_st = if_st->lastNodeOfStmt();
|
|
cur_st = end_st;
|
|
}
|
|
|
|
void RemoteVariableList(SgSymbol *group, SgExpression *rml, SgStatement *stmt)
|
|
{ SgStatement *if_st,*end_st = NULL;
|
|
SgExpression *el, *es,*coef[MAX_DIMS],*cons[MAX_DIMS],*axis[MAX_DIMS], *do_var;
|
|
SgExpression *ind_deb[MAX_DIMS];
|
|
int nc; //counter of ':' or do-var-use elements of remote-index-list
|
|
int n; //counter of elements of remote-index-list
|
|
int rank; //rank of remote variable
|
|
int num,use[MAX_DIMS];
|
|
int i,j,st_sign,iaxis,ideb=-1;
|
|
SgSymbol *dim_ident[MAX_DIMS],*ar;
|
|
int ibuf = 0;
|
|
int iamv =0;
|
|
int err_subscript = 0;
|
|
SgValueExp c0(0),cm1(-1),c1(1);
|
|
st_sign = 0;
|
|
|
|
if(options.isOn(NO_REMOTE))
|
|
return;
|
|
if(IN_COMPUTE_REGION && group)
|
|
err("Asynchronous REMOTE_ACCESS clause in compute region",574,stmt);
|
|
if(group && parloop_by_handler == 2 && stmt->variant() != DVM_PARALLEL_ON_DIR ) { // case of REMOTE_ACCESS directive
|
|
err("Illegal directive in -Opl2 mode. Asynchronous operations are not supported in this mode", 649, stmt);
|
|
group = NULL;
|
|
}
|
|
if(group){
|
|
if_st = doIfThenConstrForRemAcc(group,cur_st);
|
|
end_st = cur_st; //END IF
|
|
cur_st = if_st;
|
|
st_sign = 1;
|
|
}
|
|
if(stmt->variant() == DVM_PARALLEL_ON_DIR)
|
|
for(el=stmt->expr(2),i=0; el; el= el->rhs(),i++){ //do-variable list
|
|
//use[i] = 0;
|
|
dim_ident[i] = el->lhs()->symbol();
|
|
}
|
|
else
|
|
i = 0;
|
|
|
|
for(el=rml; el; el= el->rhs()) {
|
|
if(!HEADER(el->lhs()->symbol())) { //if non-distributed array occurs
|
|
Error("'%s' isn't distributed array",el->lhs()->symbol()->identifier(),72,stmt);
|
|
doAssignStmtAfter(&c0);
|
|
continue;
|
|
}
|
|
n = 0;
|
|
nc = 0;
|
|
err_subscript = 0;
|
|
for(j=0; j<i;j++)
|
|
use[j] = 0;
|
|
if(!TestMaxDims(el->lhs()->lhs(),el->lhs()->symbol(),stmt)) continue;
|
|
// looking through the index list of remote variable
|
|
for(es=el->lhs()->lhs(); es; es= es->rhs(),n++)
|
|
if(es->lhs()->variant() == DDOT){
|
|
axis[n] = &cm1.copy();
|
|
coef[n] = &c0.copy();
|
|
cons[n] = &c0.copy();
|
|
ind_deb[n] = &cm1.copy();
|
|
//init[n] = &c0.copy();
|
|
//last[n] = &c0.copy();
|
|
//step[n] = &c0.copy();
|
|
//dim[nc] = es->lhs(); /*ACC*/
|
|
//dim_num[nc]= n; /*ACC*/
|
|
nc++;
|
|
}
|
|
else if ((stmt->variant() == DVM_PARALLEL_ON_DIR) && (do_var=isDoVarUse(es->lhs(),use,dim_ident,i,&num,stmt))) {
|
|
CoeffConst(es->lhs(), do_var, &coef[n], &cons[n]);
|
|
axis[n] = new SgValueExp(num);
|
|
TestReverse(coef[n],stmt);
|
|
//dim[nc] = es->lhs(); /*ACC*/
|
|
//dim_num[nc]= n; /*ACC*/
|
|
nc++;
|
|
if(!coef[n]) {
|
|
err("Wrong regular subscript expression", 164,stmt);
|
|
err_subscript++;
|
|
coef[n] = &c0.copy();
|
|
cons[n] = &c0.copy();
|
|
ind_deb[n] = &c0.copy();
|
|
//init[n] = &c0.copy();
|
|
//last[n] = &c0.copy();
|
|
//step[n] = &c0.copy();
|
|
} else {
|
|
// correcting const with lower bound of corresponding array dimension
|
|
cons[n] = &(*cons[n] - *Exprn( LowerBound(el->lhs()->symbol(),n)));
|
|
ind_deb[n] = &cm1.copy();
|
|
//init[n] = &(init_do[num-1]->copy());
|
|
//last[n] = &(last_do[num-1]->copy());
|
|
//step[n] = &(step_do[num-1]->copy());
|
|
//adding attribute DO_VARIABLE_USE to regular subscript expression
|
|
SgExpression **dov = new (SgExpression *);
|
|
*dov = do_var;
|
|
(es->lhs())->addAttribute(DO_VARIABLE_USE,(void *) dov, sizeof(SgExpression *));
|
|
}
|
|
|
|
} else {
|
|
axis[n] = &c0.copy();
|
|
coef[n] = &c0.copy();
|
|
cons[n] = parloop_by_handler == 2 ? &es->lhs()->copy() : &(es->lhs()->copy() - *Exprn( LowerBound(el->lhs()->symbol(),n))) ;
|
|
ind_deb[n] = &(cons[n]->copy());
|
|
//init[n] = &c0.copy();
|
|
//last[n] = &c0.copy();
|
|
//step[n] = &c0.copy();
|
|
}
|
|
rank=Rank(el->lhs()->symbol());
|
|
if(n && rank && rank != n) {
|
|
Error("Length of remote-subscript-list is not equal to the rank of remote variable",el->lhs()->symbol()->identifier(),165,stmt);
|
|
continue;
|
|
}
|
|
if(err_subscript) continue; //there is illegal subscript
|
|
if(!n) {//remote-subscript-list is absent (whole array is remote data)
|
|
for (; n<=rank-1; n++) {
|
|
axis[n] = &cm1.copy();
|
|
coef[n] = &c0.copy();
|
|
cons[n] = &c0.copy();
|
|
ind_deb[n] = &cm1.copy();
|
|
//init[n] = &c0.copy();
|
|
//last[n] = &c0.copy();
|
|
//step[n] = &c0.copy();
|
|
//dim[n] = new SgExpression(DDOT); /*ACC*/
|
|
//dim_num[n]= n; /*ACC*/
|
|
}
|
|
nc = rank;
|
|
}
|
|
// allocating array header for buffer array
|
|
if(group){
|
|
int nbuf;
|
|
nbuf = BUFFER_INDEX(el->lhs()->symbol());
|
|
if(nbuf == maxbuf)
|
|
err("Buffer limit exceeded",183,stmt);
|
|
ibuf = 2*(nbuf+1)*(rank+1) + 2;
|
|
BUFFER_COUNT_PLUS_1(el->lhs()->symbol())
|
|
// buffer_head = HeaderRefInd(el->lhs()->symbol(),ibuf);
|
|
ar = el->lhs()->symbol();
|
|
} else {
|
|
ibuf = ndvm;
|
|
if(nc)
|
|
ndvm+=2*nc+2;
|
|
else
|
|
ndvm+=4;
|
|
//buffer_head = DVM000(ibuf);
|
|
ar = NULL;
|
|
}
|
|
// adding attribute REMOTE_VARIABLE
|
|
rem_var *remv = new rem_var;
|
|
remv->ncolon = nc;
|
|
remv->index = ibuf;
|
|
remv->amv = group ? 1 : iamv;
|
|
remv->buffer = NULL; /*ACC*/
|
|
|
|
(el->lhs())->addAttribute(REMOTE_VARIABLE,(void *) remv, sizeof(rem_var));
|
|
|
|
// case of RTS2-interface
|
|
if(parloop_by_handler==2) {
|
|
if(stmt->variant() != DVM_PARALLEL_ON_DIR) {
|
|
doCallAfter(RemoteAccess_H2(header_rf(ar,ibuf,1), el->lhs()->symbol(), HeaderRef(el->lhs()->symbol()), AlignmentListForRemoteDir(n,axis,coef,cons)));
|
|
}
|
|
continue;
|
|
}
|
|
// creating buffer for remote elements of array
|
|
iaxis = ndvm;
|
|
if (stmt->variant() == DVM_PARALLEL_ON_DIR) {
|
|
for(j=n-1; j>=0; j--)
|
|
doAssignStmtAfter(axis[j]);
|
|
for(j=n-1; j>=0; j--)
|
|
doAssignStmtAfter(ReplaceFuncCall(coef[j]));
|
|
for(j=n-1; j>=0; j--)
|
|
doAssignStmtAfter(Calculate(cons[j]));
|
|
/*
|
|
for(j=n-1; j>=0; j--)
|
|
doAssignStmtAfter(ReplaceFuncCall(init[j]));
|
|
for(j=n-1; j>=0; j--)
|
|
doAssignStmtAfter(ReplaceFuncCall(last[j]));
|
|
for(j=n-1; j>=0; j--)
|
|
doAssignStmtAfter(ReplaceFuncCall(step[j]));
|
|
*/
|
|
doCallAfter(CreateRemBuf( HeaderRef(el->lhs()->symbol()), header_rf(ar,ibuf,1), st_sign,iplp,iaxis,iaxis+n,iaxis+2*n));
|
|
} else {
|
|
ideb = ndvm;
|
|
for(j=n-1; j>=0; j--)
|
|
doAssignStmtAfter(Calculate(ind_deb[j]));
|
|
doCallAfter(CreateRemBufP( HeaderRef(el->lhs()->symbol()), header_rf(ar,ibuf,1), st_sign,ConstRef(0),ideb));
|
|
}
|
|
//if(nc)
|
|
// doAssignTo_After(header_rf(ar,ibuf,nc+2),BufferHeaderNplus1(el->lhs(),nc,ibuf,ar));
|
|
// calculating HEADER(nc+1)
|
|
//if(IN_COMPUTE_REGION) /*ACC*/
|
|
// ACC_StoreLowerBoundsOfDvmBuffer(el->lhs()->symbol(), dim, dim_num, nc, ibuf, stmt);
|
|
|
|
if(ACC_program) /*ACC*/
|
|
ACC_Before_Loadrb(header_rf(ar,ibuf,1));
|
|
|
|
// loading the buffer
|
|
doCallAfter(LoadRemBuf( header_rf(ar,ibuf,1)));
|
|
// waiting completion of loading the buffer
|
|
doCallAfter(WaitRemBuf( header_rf(ar,ibuf,1)));
|
|
|
|
if(IN_COMPUTE_REGION) /*ACC*/
|
|
ACC_Region_After_Waitrb(header_rf(ar,ibuf,1));
|
|
if(group)
|
|
//inserting buffer in group
|
|
doAssignStmtAfter(InsertRemBuf(GROUP_REF(group,1), header_rf(ar,ibuf,1)));
|
|
if(dvm_debug) {
|
|
if (stmt->variant() == DVM_PARALLEL_ON_DIR) {
|
|
ideb = ndvm;
|
|
for(j=n-1; j>=0; j--)
|
|
doAssignStmtAfter(ReplaceFuncCall(ind_deb[j]));
|
|
}
|
|
InsertNewStatementAfter(D_RmBuf( HeaderRef(el->lhs()->symbol()),GetAddresDVM( header_rf(ar,ibuf,1)),n,ideb),cur_st,cur_st->controlParent());
|
|
}
|
|
SET_DVM(iaxis);
|
|
}
|
|
|
|
if(group) {
|
|
cur_st = cur_st->lexNext()->lexNext();//IF THEN after ELSE
|
|
doAssignStmtAfter(WaitBG(GROUP_REF(group,1)));
|
|
FREE_DVM(1);
|
|
//cur_st = if_st->lastNodeOfStmt();
|
|
cur_st = end_st;
|
|
}
|
|
}
|
|
|
|
void IndirectList(SgSymbol *group, SgExpression *rml, SgStatement *stmt)
|
|
{ SgStatement *if_st,*end_st = NULL;
|
|
SgExpression *el, *es,*cons[MAX_DIMS];
|
|
SgSymbol *mehead;
|
|
int nc; //counter of indirect access dimensions
|
|
int n; //counter of elements of indirect-subscript-list
|
|
int rank; //rank of remote variable
|
|
int j,st_sign,icons;
|
|
SgSymbol *dim_ident;
|
|
int ibuf = 0;
|
|
int iamv =0;
|
|
SgValueExp c0(0),cm1(-1),c1(1);
|
|
st_sign = 0;
|
|
if(group){
|
|
if_st = doIfThenConstrForRemAcc(group,cur_st);
|
|
end_st = cur_st; //END IF
|
|
cur_st = if_st;
|
|
st_sign = 1;
|
|
}
|
|
dim_ident = stmt->expr(2)->lhs()->symbol(); //do-variable
|
|
for(el=rml; el; el= el->rhs()) {
|
|
if(!HEADER(el->lhs()->symbol())) //if non-distributed array occurs
|
|
Error("'%s' isn't distributed array",el->lhs()->symbol()->identifier(),72,stmt);
|
|
n = 0;
|
|
nc = 0;
|
|
// looking through the index list of remote variable
|
|
for(es=el->lhs()->lhs(); es; es= es->rhs(),n++)
|
|
if ((mehead = isIndirectSubscript(es->lhs(),dim_ident,stmt))) {
|
|
nc++;
|
|
cons[n] = & SgUMinusOp(*Exprn( LowerBound(el->lhs()->symbol(),n)));
|
|
//adding attribute INDIRECT_SUBSCRIPT to irregular subscript expression
|
|
SgSymbol **me = new (SgSymbol *);
|
|
*me = mehead;
|
|
(es->lhs())->addAttribute(INDIRECT_SUBSCRIPT,(void *) me, sizeof(SgSymbol *));
|
|
} else
|
|
cons[n] = &(es->lhs()->copy() - *Exprn( LowerBound(el->lhs()->symbol(),n))) ;
|
|
|
|
if((rank=Rank(el->lhs()->symbol())) && rank != n) {
|
|
Error("Length of indirect-subscript-list is not equal to the rank of remote variable",el->lhs()->symbol()->identifier(),302,stmt);
|
|
continue;
|
|
}
|
|
|
|
// allocating array header for buffer array
|
|
ibuf = ndvm;
|
|
ndvm+=+4;
|
|
if(!mehead || (nc > 1)){
|
|
// err("Illegal indirect reference",stmt);
|
|
return;
|
|
}
|
|
// creating buffer for indirect access elements of array
|
|
icons = ndvm;
|
|
for(j=n-1; j>=0; j--)
|
|
doAssignStmtAfter(Calculate(cons[j]));
|
|
doAssignStmtAfter(CreateIndBuf( HeaderRef(el->lhs()->symbol()), DVM000(ibuf), st_sign,HeaderRef(mehead),icons));
|
|
doAssignTo_After(DVM000(ibuf+3),BufferHeader4(el->lhs(),ibuf));
|
|
// calculating HEADER(nc+1)
|
|
// loading the buffer
|
|
doAssignStmtAfter(LoadIndBuf(DVM000(ibuf)));
|
|
if(group)
|
|
//inserting buffer in group
|
|
doAssignStmtAfter(InsertIndBuf(group,DVM000(ibuf)));
|
|
// waiting completion of loading the buffer
|
|
doAssignStmtAfter(WaitIndBuf(DVM000(ibuf)));
|
|
if(dvm_debug)
|
|
InsertNewStatementAfter(D_RmBuf( HeaderRef(el->lhs()->symbol()),GetAddresMem(DVM000(ibuf)),n,icons),cur_st,cur_st->controlParent());
|
|
SET_DVM(icons);
|
|
//adding attribute REMOTE_VARIABLE
|
|
rem_var *remv = new rem_var;
|
|
remv->ncolon = nc;
|
|
|
|
remv->index = ibuf;
|
|
remv->amv = iamv;
|
|
(el->lhs())->addAttribute(REMOTE_VARIABLE,(void *) remv, sizeof(rem_var));
|
|
|
|
}
|
|
if(group) {
|
|
cur_st = cur_st->lexNext()->lexNext();//IF THEN after ELSE
|
|
doAssignStmtAfter(WaitIG(group));
|
|
FREE_DVM(1);
|
|
//cur_st = if_st->lastNodeOfStmt();
|
|
cur_st = end_st;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void DeleteBuffers(SgExpression *rml)
|
|
{ SgExpression *el;
|
|
rem_var *remv;
|
|
SgStatement *current = cur_st;//store value of cur_st
|
|
SgLabel *lab;
|
|
//cur_st = cur_st->lexPrev();
|
|
for(el=rml; el; el= el->rhs()) { //looking through the remote variable list
|
|
remv = (rem_var *) (el->lhs())->attributeValue(0,REMOTE_VARIABLE);
|
|
/* if(remv->ncolon) {
|
|
doAssignStmtBefore(DeleteObject(DVM000(remv->index)),current);//delete distributed array
|
|
doAssignStmtBefore(DeleteObject(DVM000(remv->amv)),current);//delete abstract machine view
|
|
FREE_DVM(2);
|
|
}
|
|
*/
|
|
if(remv && remv->amv == 0){ //buffer is not included in named group
|
|
current->insertStmtBefore(*DeleteObject_H(header_rf((SgSymbol *) NULL,remv->index,1)),*current->controlParent());
|
|
}
|
|
}
|
|
cur_st = current; //restore cur_st
|
|
}
|
|
|
|
void RemoteAccessEnd()
|
|
{int i;
|
|
for (i=0; i<Ntp; i++) // calculating number of used scalar buffers of different type
|
|
rmbuf_size[i] =(rmbuf_size[i] < rma->rmbuf_use[i]) ? rma->rmbuf_use[i] : rmbuf_size[i]; //maximum
|
|
if(rma->rmout) // REMOTE_ACCESS directive (not clause)
|
|
DeleteBuffers(rma->rml); //deleting array buffers
|
|
DelRemoteAccess(); //deletes element from remote_access directive/clause list
|
|
//and concurently frees scalar buffers
|
|
|
|
}
|
|
|
|
void AddRemoteAccess(SgExpression *rml, SgStatement *rmout)
|
|
{int i;
|
|
rem_acc *elem = new rem_acc;
|
|
elem->rml = rml;
|
|
elem->rmout = rmout;
|
|
if(!rma) {// first element
|
|
elem->next = NULL;
|
|
for(i=0; i<Ntp; i++)
|
|
elem->rmbuf_use[i] = 0;
|
|
}
|
|
else {
|
|
elem->next = rma;
|
|
for(i=0; i<Ntp; i++)
|
|
elem->rmbuf_use[i] = rma->rmbuf_use[i];
|
|
}
|
|
rma = elem;
|
|
}
|
|
|
|
void DelRemoteAccess()
|
|
{
|
|
if(rma)
|
|
rma = rma->next;
|
|
}
|
|
|
|
SgExpression *isSpecialFormExp(SgExpression *e,int i,int ind,SgExpression *vpart[],SgSymbol *do_var[])
|
|
{
|
|
if(e->variant()==ADD_OP){
|
|
if(isInvariantPart(e->lhs()) && isDependentPart(e->rhs(),do_var)) {
|
|
vpart[i] = RenewSpecExp(e->rhs(),e->lhs()->valueInteger(),ind);
|
|
return(e->lhs());
|
|
}
|
|
if(isInvariantPart(e->rhs()) && isDependentPart(e->lhs(),do_var)) {
|
|
vpart[i] = RenewSpecExp(e->lhs(),e->rhs()->valueInteger(),ind);
|
|
return(e->rhs());
|
|
}
|
|
}
|
|
if(isDependentPart(e,do_var)){
|
|
vpart[i] = RenewSpecExp(e,0,ind);
|
|
return(new SgValueExp(0));
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
int isInvariantPart(SgExpression *e)
|
|
{ return(e->isInteger());}
|
|
|
|
int isDependentPart(SgExpression *e,SgSymbol *do_var[])
|
|
{//!!! temporaly
|
|
if(do_var[0])
|
|
;
|
|
if(isSgFunctionCallExp(e)){
|
|
if(!strcmp(e->symbol()->identifier(),"mod") && (e->lhs()->lhs()->variant()==ADD_OP))
|
|
return(1);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
SgExpression *RenewSpecExp(SgExpression *e, int cnst, int ind)
|
|
{ if(cnst % 2)
|
|
( e->lhs())->setLhs(*DVM000(ind) + (*new SgValueExp(cnst % 2)) + (*e->lhs()->lhs()));
|
|
else
|
|
( e->lhs())->setLhs(*DVM000(ind) + (*e->lhs()->lhs()));
|
|
return(e);
|
|
}
|
|
|
|
int isDistObject(SgExpression *e)
|
|
{
|
|
if(!e)
|
|
return(0);
|
|
if(isSgArrayRefExp(e))
|
|
if(HEADER(e->symbol()))
|
|
return(1);
|
|
if(e->variant() == ARRAY_OP)
|
|
return(isDistObject(e->lhs()));
|
|
return(0);
|
|
}
|
|
|
|
int isListOfArrays(SgExpression *e, SgStatement *st)
|
|
{SgExpression *el;
|
|
int test = 0;
|
|
for(el=e; el; el = el->rhs()) {
|
|
if(!(el->lhs()->symbol()->attributes() & DIMENSION_BIT) && !IS_POINTER(el->lhs()->symbol())) {
|
|
Error("'%s' is not array",el->lhs()->symbol()->identifier(), 66,st);
|
|
test = 1;
|
|
}
|
|
|
|
if( el->lhs()->lhs() && !((el->lhs()->symbol()->attributes() & TEMPLATE_BIT) || (el->lhs()->symbol()->attributes() & PROCESSORS_BIT)))
|
|
Error("Shape specification is not permitted: %s", el->lhs()->symbol()->identifier(), 263, st);
|
|
}
|
|
return(test);
|
|
}
|
|
|
|
char * AttrName(int i)
|
|
{ switch (i) {
|
|
case 0: return("ALIGN");
|
|
case 1: return("DISTRIBUTE");
|
|
case 2: return("TEMPLATE");
|
|
case 3: return("PROCESSORS");
|
|
case 4: return("DIMENSION");
|
|
case 5: return("DYNAMIC");
|
|
case 6: return("SHADOW");
|
|
case 7: return("COMMON");
|
|
default: return("NONE");
|
|
}
|
|
}
|
|
|
|
int TestShapeSpec(SgExpression *e)
|
|
{//temporary
|
|
return(isSgValueExp(e)? 1 : 1);
|
|
}
|
|
|
|
void AddToGroupNameList (SgSymbol *s)
|
|
{group_name_list *gs;
|
|
//adding the symbol 's' to group_name_list
|
|
if(!grname) {
|
|
grname = new group_name_list;
|
|
grname->symb = s;
|
|
grname->next = NULL;
|
|
} else {
|
|
for(gs=grname; gs; gs=gs->next)
|
|
if(gs->symb == s)
|
|
return;
|
|
gs = new group_name_list;
|
|
gs->symb = s;
|
|
gs->next = grname;
|
|
grname = gs;
|
|
}
|
|
}
|
|
|
|
symb_list *AddToSymbList ( symb_list *ls, SgSymbol *s)
|
|
{symb_list *l;
|
|
//adding the symbol 's' to symb_list 'ls'
|
|
if(!ls) {
|
|
ls = new symb_list;
|
|
ls->symb = s;
|
|
ls->next = NULL;
|
|
} else {
|
|
/*
|
|
for(l=ls; l; l=l->next)
|
|
if(l->symb == s)
|
|
return;
|
|
*/
|
|
l = new symb_list;
|
|
l->symb = s;
|
|
l->next = ls;
|
|
ls = l;
|
|
}
|
|
return(ls);
|
|
}
|
|
|
|
symb_list *AddNewToSymbList ( symb_list *ls, SgSymbol *s)
|
|
{symb_list *l;
|
|
//adding the symbol 's' to symb_list 'ls'
|
|
if(!ls) {
|
|
ls = new symb_list;
|
|
ls->symb = s;
|
|
ls->next = NULL;
|
|
} else {
|
|
for(l=ls; l; l=l->next)
|
|
if(l->symb == s)
|
|
return(ls);
|
|
l = new symb_list;
|
|
l->symb = s;
|
|
l->next = ls;
|
|
ls = l;
|
|
}
|
|
return(ls);
|
|
}
|
|
|
|
symb_list *AddNewToSymbListEnd ( symb_list *ls, SgSymbol *s)
|
|
{symb_list *l, *lprev;
|
|
//adding the symbol 's' to symb_list 'ls'
|
|
if(!ls) {
|
|
ls = new symb_list;
|
|
ls->symb = s;
|
|
ls->next = NULL;
|
|
} else {
|
|
for(l=ls; l; lprev=l, l=l->next)
|
|
if(l->symb == s)
|
|
return(ls);
|
|
l = new symb_list;
|
|
l->symb = s;
|
|
l->next = NULL;
|
|
lprev->next = l;
|
|
}
|
|
return(ls);
|
|
}
|
|
|
|
symb_list *MergeSymbList(symb_list *ls1, symb_list *ls2)
|
|
{
|
|
symb_list *l =ls1;
|
|
if(!ls1)
|
|
return (ls2);
|
|
while(l->next)
|
|
l = l->next;
|
|
l->next = ls2;
|
|
return ls1;
|
|
}
|
|
|
|
symb_list *CopySymbList(symb_list *ls)
|
|
{
|
|
symb_list *l=NULL, *el, *cp=NULL;
|
|
while(ls)
|
|
{
|
|
el = new symb_list;
|
|
el->symb = ls->symb;
|
|
el->next = NULL;
|
|
if(l)
|
|
l->next = el;
|
|
else
|
|
cp = el;
|
|
l = el;
|
|
ls = ls->next;
|
|
}
|
|
return cp;
|
|
}
|
|
|
|
void DeleteSymbList(symb_list *ls)
|
|
{symb_list *l;
|
|
|
|
while(ls)
|
|
{ l = ls;
|
|
ls =ls->next;
|
|
delete l;
|
|
}
|
|
}
|
|
|
|
filename_list *AddToFileNameList ( char *s)
|
|
{filename_list *ls;
|
|
SgType *tch;
|
|
SgExpression *le;
|
|
int length;
|
|
//adding the name 's' to filename_list 'ls'
|
|
if(!fnlist) {
|
|
ls = new filename_list;
|
|
ls->name = s;
|
|
ls->next = NULL;
|
|
le = new SgExpression(LEN_OP);
|
|
length = strlen(s)+1;
|
|
le->setLhs(new SgValueExp(length));
|
|
tch = new SgType(T_STRING,le,SgTypeChar());
|
|
ls->fns = new SgVariableSymb(FileNameVar(++filename_num), *tch, *cur_func);
|
|
fnlist = ls;
|
|
} else {
|
|
for(ls=fnlist; ls; ls=ls->next)
|
|
if(ls->name == s)
|
|
return(ls);
|
|
ls = new filename_list;
|
|
ls->name = s;
|
|
ls->next = fnlist;
|
|
le = new SgExpression(LEN_OP);
|
|
length = strlen(s)+1;
|
|
le->setLhs(new SgValueExp(length));
|
|
tch = new SgType(T_STRING,le,SgTypeChar());
|
|
ls->fns = new SgVariableSymb(FileNameVar(++filename_num), *tch, *cur_func);
|
|
fnlist = ls;
|
|
}
|
|
return(ls);
|
|
}
|
|
|
|
filename_list *AddToFileNameList(const char *s_in)
|
|
{
|
|
char *s = new char[strlen(s_in) + 1];
|
|
strcpy(s, s_in);
|
|
|
|
filename_list *ls;
|
|
SgType *tch;
|
|
SgExpression *le;
|
|
int length;
|
|
//adding the name 's' to filename_list 'ls'
|
|
if (!fnlist) {
|
|
ls = new filename_list;
|
|
ls->name = s;
|
|
ls->next = NULL;
|
|
le = new SgExpression(LEN_OP);
|
|
length = strlen(s) + 1;
|
|
le->setLhs(new SgValueExp(length));
|
|
tch = new SgType(T_STRING, le, SgTypeChar());
|
|
ls->fns = new SgVariableSymb(FileNameVar(++filename_num), *tch, *cur_func);
|
|
fnlist = ls;
|
|
}
|
|
else {
|
|
for (ls = fnlist; ls; ls = ls->next)
|
|
if (ls->name == s)
|
|
return(ls);
|
|
ls = new filename_list;
|
|
ls->name = s;
|
|
ls->next = fnlist;
|
|
le = new SgExpression(LEN_OP);
|
|
length = strlen(s) + 1;
|
|
le->setLhs(new SgValueExp(length));
|
|
tch = new SgType(T_STRING, le, SgTypeChar());
|
|
ls->fns = new SgVariableSymb(FileNameVar(++filename_num), *tch, *cur_func);
|
|
fnlist = ls;
|
|
}
|
|
return(ls);
|
|
}
|
|
|
|
void InsertDebugStat(SgStatement *func, SgStatement* &end_of_unit)
|
|
{
|
|
SgStatement *stmt,*last, *data_stf, *first,*first_dvm_exec,*last_spec,*last_dvm_entry, *lentry = NULL;
|
|
SgStatement *mod_proc;
|
|
SgStatement *copy_proc = NULL;
|
|
SgStatement *has_contains = NULL;
|
|
SgLabel *lab_exec;
|
|
stmt_list *pstmt = NULL;
|
|
int contains[2];
|
|
int in_on=0;
|
|
|
|
//initialization
|
|
dsym = NULL;
|
|
grname = NULL;
|
|
saveall = 0;
|
|
maxdvm = 0;
|
|
maxhpf = 0;
|
|
count_reg = 0;
|
|
initMask();
|
|
data_stf = NULL;
|
|
inparloop = 0;
|
|
inasynchr = 0;
|
|
redvar_list = NULL;
|
|
goto_list = NULL;
|
|
proc_symb = NULL;
|
|
task_symb = NULL;
|
|
consistent_symb = NULL;
|
|
async_symb=NULL;
|
|
check_sum = NULL;
|
|
loc_templ_symb=NULL;
|
|
index_symb = NULL;
|
|
in_task_region = 0;
|
|
task_ind = 0;
|
|
in_task = 0;
|
|
task_lab = NULL;
|
|
pref_st = NULL;
|
|
pipeline = 0;
|
|
registration = NULL;
|
|
filename_num = 0;
|
|
fnlist = NULL;
|
|
nloopred = 0;
|
|
nloopcons = 0;
|
|
wait_list = NULL;
|
|
SIZE_function = NULL;
|
|
dvm_const_ref = 0;
|
|
in_interface = 0;
|
|
mod_proc = NULL;
|
|
if_goto = NULL;
|
|
nifvar = 0;
|
|
entry_list = NULL;
|
|
dbif_cond = 0;
|
|
dbif_not_cond = 0;
|
|
last_dvm_entry = NULL;
|
|
all_replicated = 0;
|
|
IOstat = NULL;
|
|
privateall = 0;
|
|
|
|
TempVarDVM(func);
|
|
initF90Names();
|
|
|
|
first = func->lexNext();
|
|
//get the last node of the program unit(function)
|
|
last = func->lastNodeOfStmt();
|
|
end_of_unit = last;
|
|
if(!(last->variant() == CONTROL_END))
|
|
printf(" END Statement is absent\n");
|
|
//**********************************************************************
|
|
// Specification Directives Processing
|
|
//**********************************************************************
|
|
// follow the statements of the function in lexical order
|
|
// until first executable statement
|
|
for (stmt = first; stmt && (stmt != last); stmt = stmt->lexNext()) {
|
|
if (!isSgExecutableStatement(stmt)) //is Fortran specification statement
|
|
// isSgExecutableStatement:
|
|
// FALSE - for specification statement of Fortan 90
|
|
// TRUE - for executable statement of Fortan 90
|
|
{
|
|
//!!!debug
|
|
// printVariantName(stmt->variant());
|
|
// printf("\n");
|
|
// printf("%s %d\n",stmt->lineNumber(),
|
|
// analizing SAVE statement
|
|
if(stmt->variant()==SAVE_DECL) {
|
|
if (!stmt->expr(0)) //SAVE without name-list
|
|
saveall = 1;
|
|
else if(IN_MAIN_PROGRAM)
|
|
pstmt = addToStmtList(pstmt, stmt); //for extracting and replacing by SAVE without list
|
|
continue;
|
|
}
|
|
// deleting SAVE-attribute from Type Declaration Statement (for replacing by SAVE without list)
|
|
if(IN_MAIN_PROGRAM && isSgVarDeclStmt(stmt))
|
|
DeleteSaveAttribute(stmt);
|
|
|
|
if(IN_MODULE && stmt->variant() == PRIVATE_STMT && !stmt->expr(0))
|
|
privateall = 1;
|
|
|
|
if(debug_regim) {
|
|
if(stmt->variant()==COMM_STAT) {
|
|
SgExpression *ec, *el;
|
|
SgSymbol *sc;
|
|
for(ec=stmt->expr(0); ec; ec=ec->rhs()) // looking through COMM_LIST
|
|
for(el=ec->lhs(); el; el=el->rhs()) {
|
|
sc = el->lhs()->symbol();
|
|
if(sc){
|
|
SYMB_ATTR(sc->thesymb)= SYMB_ATTR(sc->thesymb) | COMMON_BIT;
|
|
if(IS_ARRAY(sc))
|
|
registration = AddNewToSymbList( registration, sc);
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
|
|
// registrating arrays from variable list of declaration statement
|
|
if( isSgVarDeclStmt(stmt) || isSgVarListDeclStmt(stmt)) {
|
|
RegistrationList(stmt);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
if(isSgVarDeclStmt(stmt)) VarDeclaration(stmt);// for analizing object list and changing variant of declaration statement by VAR_DECL_90
|
|
if((stmt->variant() == DATA_DECL) || (stmt->variant() == STMTFN_STAT)) {
|
|
if(stmt->variant()==STMTFN_STAT)
|
|
DECL(stmt->expr(0)->symbol()) = 2; //flag of statement function name
|
|
|
|
if(!data_stf)
|
|
data_stf = stmt; //first statement in data-or-function statement part
|
|
continue;
|
|
}
|
|
|
|
if(stmt->variant() == INTERFACE_STMT || stmt->variant() == INTERFACE_ASSIGNMENT || stmt->variant() == INTERFACE_OPERATOR) {
|
|
stmt = InterfaceBlock(stmt); //stmt= stmt->lastNodeOfStmt();
|
|
continue;
|
|
}
|
|
|
|
if( stmt->variant() == USE_STMT) {
|
|
if(stmt->lexPrev() != func && stmt->lexPrev()->variant()!=USE_STMT)
|
|
err("Misplaced USE statement", 639, stmt);
|
|
continue;
|
|
}
|
|
if(stmt->variant() == STRUCT_DECL){
|
|
StructureProcessing(stmt);
|
|
stmt=stmt->lastNodeOfStmt();
|
|
continue;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
if ((stmt->variant() == FORMAT_STAT))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
|
|
// processing the DVM Specification Directives
|
|
|
|
switch(stmt->variant()) {
|
|
case DVM_REDUCTION_GROUP_DIR:
|
|
//if (dvm_debug)
|
|
if (debug_regim)
|
|
{SgExpression * sl;
|
|
for(sl=stmt->expr(0); sl; sl = sl->rhs())
|
|
AddToGroupNameList(sl->lhs()->symbol());
|
|
}
|
|
//including the DVM specification directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
continue;
|
|
|
|
case(DVM_INDIRECT_GROUP_DIR):
|
|
case(DVM_REMOTE_GROUP_DIR):
|
|
if (debug_regim && !options.isOn(NO_REMOTE))
|
|
{SgExpression * sl;
|
|
for(sl=stmt->expr(0); sl; sl = sl->rhs()){
|
|
SgArrayType *artype;
|
|
artype = new SgArrayType(*SgTypeInt());
|
|
artype->addRange(*new SgValueExp(3));
|
|
sl->lhs()->symbol()->setType(artype);
|
|
AddToGroupNameList(sl->lhs()->symbol());
|
|
}
|
|
}
|
|
//including the DVM specification directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
continue;
|
|
case(DVM_POINTER_DIR):
|
|
if(debug_regim)
|
|
{SgExpression *el;
|
|
SgStatement **pst = new (SgStatement *);
|
|
SgSymbol *sym;
|
|
*pst = stmt;
|
|
for(el = stmt->expr(0); el; el=el->rhs()){ // name list
|
|
sym = el->lhs()->symbol(); // name
|
|
sym->addAttribute(POINTER_, (void *) pst, sizeof(SgStatement *));
|
|
}
|
|
}
|
|
//including the DVM specification directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
continue;
|
|
case(ACC_ROUTINE_DIR):
|
|
case(HPF_PROCESSORS_STAT):
|
|
case(HPF_TEMPLATE_STAT):
|
|
case(DVM_DYNAMIC_DIR):
|
|
case(DVM_SHADOW_DIR):
|
|
case(DVM_ALIGN_DIR):
|
|
case(DVM_DISTRIBUTE_DIR):
|
|
case(DVM_VAR_DECL):
|
|
case(DVM_TASK_DIR):
|
|
case(DVM_INHERIT_DIR):
|
|
case(DVM_HEAP_DIR):
|
|
case(DVM_ASYNCID_DIR):
|
|
case(DVM_CONSISTENT_DIR):
|
|
case(DVM_CONSISTENT_GROUP_DIR):
|
|
//including the DVM specification directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
continue;
|
|
}
|
|
// all declaration statements are processed,
|
|
// current statement is executable (F77/DVM)
|
|
break;
|
|
}
|
|
|
|
//TempVarDVM(func);
|
|
|
|
for(;pstmt; pstmt= pstmt->next)
|
|
Extract_Stmt(pstmt->st);// extracting DVM Specification Directives
|
|
|
|
first_exec = stmt; // first executable statement
|
|
|
|
// testing procedure (-dbif2 regim)
|
|
if(debug_regim && dbg_if_regim>1 && ((func->variant() == PROC_HEDR) || (func->variant() == FUNC_HEDR)) && !pstmt && !isInternalOrModuleProcedure(func) && !lookForDVMdirectivesInBlock(first_exec,func->lastNodeOfStmt(),contains) && !contains[0] && !contains[1])
|
|
copy_proc = CreateCopyOfExecPartOfProcedure();
|
|
|
|
lab_exec = first_exec->label(); // store the label of first ececutable statement
|
|
BIF_LABEL(first_exec->thebif) = NULL;
|
|
last_spec = stmt->lexPrev();
|
|
where = first_exec;
|
|
ndvm = 1; // ndvm is number of first free element of array "dvm000"
|
|
nhpf = 1; // nhpf is number of first free element of array "hpf000"
|
|
|
|
//generating assign statement
|
|
// dvm000(1) = fname(file_name)
|
|
//function 'fname' tells the name of source file to DVM run-time system
|
|
InsertNewStatementBefore(D_Fname(),first_exec);
|
|
|
|
first_dvm_exec = last_spec->lexNext(); //first DVM function call
|
|
if(IN_MODULE){
|
|
if(debug_regim ) {
|
|
mod_proc = CreateModuleProcedure(cur_func,first_exec,has_contains);
|
|
where = mod_proc->lexNext();
|
|
end_of_unit = where;
|
|
} else {
|
|
first_dvm_exec = last_spec->lexNext();
|
|
goto EXEC_PART_;
|
|
}
|
|
}
|
|
|
|
if(func->variant() == PROG_HEDR) { // MAIN-program
|
|
//generating a call statement
|
|
// call dvmlf(line_number_of_first_executable_statement,source-file-name)
|
|
LINE_NUMBER_STL_BEFORE(cur_st,first_exec,first_exec);
|
|
//generating the function call which initializes the control structures of DVM run-time system,
|
|
// it's inserted in MAIN program)
|
|
// dvm000(1) = <flag>
|
|
// call dvmh_init(dvm000(1))
|
|
RTL_GPU_Init();
|
|
if(dbg_if_regim)
|
|
InitDebugVar();
|
|
}
|
|
|
|
ndvm = 4;
|
|
// first_dvm_exec = last_spec->lexNext(); //first DVM function call
|
|
nio = 0;
|
|
//generating call (module procedure) and/or assign statements for USE statements
|
|
GenForUseStmts(func,where);
|
|
|
|
if(debug_regim && grname) {
|
|
if(!IN_MODULE)
|
|
InitGroups();
|
|
CreateRedGroupVars();
|
|
}
|
|
if(debug_regim && registration) {
|
|
LINE_NUMBER_BEFORE(cur_func,where); //(first_exec,first_exec);
|
|
ArrayRegistration(); // before array registration number of cur_func line
|
|
// must be put to debugger
|
|
}
|
|
if(lab_exec)
|
|
first_exec-> setLabel(*lab_exec); //restore label of first executable statement
|
|
|
|
last_dvm_entry = first_exec->lexPrev();
|
|
|
|
if(copy_proc)
|
|
InsertCopyOfExecPartOfProcedure(copy_proc);
|
|
|
|
EXEC_PART_:
|
|
|
|
if(IN_MODULE) {
|
|
if(!mod_proc && first_exec->variant() == CONTAINS_STMT)
|
|
end_of_unit = has_contains = first_exec;
|
|
goto END_;
|
|
}
|
|
|
|
//follow the executable statements in lexical order until last statement
|
|
// of the function
|
|
for(stmt=first_exec; stmt ; stmt=stmt->lexNext()) {
|
|
cur_st = stmt;
|
|
if(isACCdirective(stmt))
|
|
{ pstmt = addToStmtList(pstmt, stmt);
|
|
continue;
|
|
}
|
|
switch(stmt->variant()) {
|
|
case CONTROL_END:
|
|
if(stmt == last) {
|
|
if(func->variant() == PROG_HEDR) // for MAIN program
|
|
RTLExit(stmt);
|
|
goto END_;
|
|
}
|
|
break;
|
|
case CONTAINS_STMT:
|
|
if(func->variant() == PROG_HEDR) // for MAIN program
|
|
RTLExit(stmt);
|
|
has_contains = end_of_unit = stmt;
|
|
goto END_;
|
|
break;
|
|
case RETURN_STAT:
|
|
if(dvm_debug || perf_analysis )
|
|
goto_list = addToStmtList(goto_list, stmt);
|
|
|
|
if(stmt->lexNext() == last)
|
|
goto END_;
|
|
break;
|
|
case STOP_STAT:
|
|
if(stmt->expr(0)){
|
|
SgStatement *print_st;
|
|
InsertNewStatementBefore(print_st=PrintStat(stmt->expr(0)),stmt);
|
|
ReplaceByIfStmt(print_st);
|
|
}
|
|
RTLExit(stmt);
|
|
if(stmt->lexNext() == last)
|
|
goto END_;
|
|
break;
|
|
/*
|
|
case PAUSE_NODE:
|
|
err("PAUSE statement is not permitted in FDVM", 93,stmt);
|
|
break;
|
|
case ENTRY_STAT:
|
|
if(debug)
|
|
err("ENTRY statement is not permitted in FDVM", stmt);
|
|
break;
|
|
*/
|
|
case EXIT_STMT:
|
|
//if(dvm_debug || perf_analysis )
|
|
// EXIT statement is added to list for debugging (exit the loop)
|
|
// goto_list = addToStmtList(goto_list, stmt);
|
|
break;
|
|
|
|
case ENTRY_STAT:
|
|
GoRoundEntry(stmt);
|
|
//BeginBlockForEntry(stmt);
|
|
entry_list=addToStmtList(entry_list,stmt);
|
|
break;
|
|
|
|
case SWITCH_NODE: // SELECT CASE ...
|
|
case ARITHIF_NODE: // Arithmetical IF
|
|
case IF_NODE: // IF... THEN
|
|
case WHILE_NODE: // DO WHILE (...)
|
|
/*case ELSEIF_NODE: // ELSE IF...*/
|
|
if(dvm_debug)
|
|
DebugExpression(stmt->expr(0),stmt);
|
|
if((dvm_debug || perf_analysis) && stmt->variant()==ARITHIF_NODE )
|
|
goto_list = addToStmtList(goto_list, stmt);
|
|
break;
|
|
|
|
case LOGIF_NODE: // Logical IF
|
|
if( !stmt->lineNumber()) {//inserted statement
|
|
stmt = stmt->lexNext();
|
|
break;
|
|
}
|
|
if(dvm_debug){
|
|
if(HPF_program && inparloop)
|
|
IsLIFReductionOp(stmt, indep_st->expr(0) ? indep_st->expr(0)->lhs() : indep_st->expr(0)); //look for reduction operator
|
|
ReplaceContext(stmt);
|
|
DebugExpression(stmt->expr(0),stmt);
|
|
}
|
|
else if(perf_analysis && IsGoToStatement(stmt->lexNext()))
|
|
ReplaceContext(stmt);
|
|
|
|
continue; // to next statement
|
|
case FORALL_STAT: // FORALL statement
|
|
stmt=stmt->lexNext();// statement that is a part of FORALL statement
|
|
break;
|
|
|
|
case GOTO_NODE: // GO TO
|
|
if((dvm_debug || perf_analysis) && stmt->lineNumber() )
|
|
goto_list = addToStmtList(goto_list, stmt);
|
|
break;
|
|
case COMGOTO_NODE: // Computed GO TO
|
|
if(dvm_debug){
|
|
ReplaceContext(stmt);
|
|
DebugExpression(stmt->expr(1),stmt);
|
|
} else if(perf_analysis)
|
|
ReplaceContext(stmt);
|
|
if( dvm_debug || perf_analysis )
|
|
goto_list = addToStmtList(goto_list, stmt);
|
|
break;
|
|
|
|
case ASSIGN_STAT: // Assign statement
|
|
{SgSymbol *s;
|
|
if(!stmt->lineNumber()) //inserted debug statement
|
|
break;
|
|
s=stmt->expr(0)->symbol();
|
|
if(s && IS_POINTER(s)){ // left part variable is POINTER
|
|
if(isSgFunctionCallExp(stmt->expr(1)) && !strcmp(stmt->expr(1)->symbol()->identifier(),"allocate")){
|
|
if(inparloop)
|
|
err("Illegal statement in the range of parallel loop",94,stmt);
|
|
if(debug_regim)
|
|
//alloc_st = addToStmtList(alloc_st, stmt);
|
|
AllocArrayRegistration(stmt);
|
|
|
|
} else if( (isSgVarRefExp(stmt->expr(1)) || isSgArrayRefExp(stmt->expr(1))) && stmt->expr(1)->symbol() && IS_POINTER(stmt->expr(1)->symbol())) {
|
|
;
|
|
} else
|
|
err("Only a value of ALLOCATE function or other POINTER may be assigned to a POINTER",95,stmt);
|
|
|
|
break;
|
|
}
|
|
|
|
if(s && !inparloop && IS_DVM_ARRAY(s) && DistrArrayAssign(stmt))
|
|
break;
|
|
if(s && !inparloop && AssignDistrArray(stmt))
|
|
break;
|
|
|
|
if(dvm_debug){
|
|
SgStatement *stcur, *after_st = NULL, *stmt1;
|
|
if(HPF_program && inparloop)
|
|
IsReductionOp(stmt,indep_st->expr(0) ? indep_st->expr(0)->lhs() : indep_st->expr(0)); //look for reduction operator
|
|
ReplaceContext(stmt);
|
|
DebugAssignStatement(stmt);
|
|
|
|
if(own_exe) //"owner executes" rule
|
|
InsertNewStatementAfter(D_Skpbl(),cur_st,cur_st->controlParent());
|
|
else if(!inparloop && !in_on && stmt->expr(0)->symbol() && IS_DVM_ARRAY(stmt->expr(0)->symbol()))
|
|
InsertNewStatementAfter(D_Skpbl(),cur_st,cur_st->controlParent());
|
|
own_exe = 0;
|
|
stmt = cur_st;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case PROC_STAT: // CALL
|
|
if(!stmt->lineNumber()) //inserted debug statement
|
|
break;
|
|
if(dvm_debug){
|
|
ReplaceContext(stmt);
|
|
DebugExpression(NULL,stmt);
|
|
}
|
|
break;
|
|
|
|
case ALLOCATE_STMT:
|
|
if(debug_regim) {
|
|
AllocatableArrayRegistration(stmt);
|
|
stmt=cur_st;
|
|
}
|
|
break;
|
|
|
|
case DEALLOCATE_STMT:
|
|
break;
|
|
case FOR_NODE:
|
|
if (perf_analysis == 4)
|
|
SeqLoopBegin(stmt);
|
|
if(dvm_debug)
|
|
DebugLoop(stmt);
|
|
break;
|
|
|
|
case DVM_PARALLEL_ON_DIR:
|
|
if(!TestParallelWithoutOn(stmt,0))
|
|
{
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
}
|
|
|
|
if(debug_regim && !dvm_debug)
|
|
Reduction_Debug(stmt);
|
|
par_do = stmt->lexNext(); // first DO statement of parallel loop
|
|
while( isOmpDir (par_do)) //|| isACCdirective(par_do)
|
|
{ cur_st = par_do;
|
|
par_do=par_do->lexNext();
|
|
}
|
|
|
|
if(!isSgForStmt(par_do) && (dvm_debug || perf_analysis && perf_analysis != 2)) {
|
|
//directive is ignored
|
|
err("PARALLEL directive must be followed by DO statement",97,stmt);
|
|
break;
|
|
}
|
|
|
|
if(dvm_debug){ //debugging mode
|
|
if(inparloop){
|
|
err("Nested PARALLEL directives are not permitted", 96,stmt);
|
|
break;
|
|
}
|
|
|
|
inparloop = 1;
|
|
if(!ParallelLoop_Debug(stmt)) // error in PARALLEL directive
|
|
inparloop = 0;
|
|
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;
|
|
// setting stmt on last DO statement of parallel loop nest
|
|
}
|
|
|
|
else if(perf_analysis && perf_analysis != 2) {
|
|
inparloop = 1;
|
|
|
|
//generating call to 'bploop' function of performance analizer
|
|
// (begin of parallel interval)
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
InsertNewStatementAfter(St_Bploop(OpenInterval(stmt)), cur_st,stmt->controlParent());
|
|
|
|
if(perf_analysis == 4)
|
|
SkipParLoopNest(stmt);
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;
|
|
}
|
|
else // dvm_debug == 0 && perf_analysis == 0 or 2, i.e. standard mode
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
|
|
case HPF_INDEPENDENT_DIR:
|
|
if(dvm_debug){ //debugging mode
|
|
if(inparloop){
|
|
//illegal nested INDEPENDENT directive is ignored
|
|
pstmt = addToStmtList(pstmt, stmt); //including the HPF directive to list
|
|
break;
|
|
}
|
|
par_do = stmt->lexNext();// first DO statement of parallel loop
|
|
indep_st = stmt;
|
|
if(!isSgForStmt(par_do)) {
|
|
err("INDEPENDENT directive must be followed by DO statement",97,stmt);
|
|
//directive is ignored
|
|
break;
|
|
}
|
|
inparloop = 1;
|
|
IEXLoopAnalyse(func);
|
|
if(!IndependentLoop_Debug(stmt)) // error in INDEPENDENT directive
|
|
inparloop = 0;
|
|
}
|
|
|
|
else if(perf_analysis && perf_analysis != 2) {
|
|
inparloop = 1;
|
|
par_do = stmt->lexNext();// first DO statement of parallel loop
|
|
indep_st = stmt;
|
|
//generating call to 'bploop' function of performance analizer
|
|
// (begin of parallel interval)
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
InsertNewStatementAfter(St_Bploop(OpenInterval(stmt)), cur_st,stmt->controlParent());
|
|
SkipIndepLoopNest(stmt);
|
|
}
|
|
else {// dvm_debug == 0 && perf_analysis == 0 or 2, i.e. standard mode
|
|
par_do = stmt->lexNext();// first DO statement of parallel loop
|
|
SkipIndepLoopNest(stmt); // to extract nested INDEPENDENT directives
|
|
}
|
|
//including the HPF directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st; // setting stmt on last DO statement of parallel loop nest
|
|
break;
|
|
|
|
case DVM_REDUCTION_WAIT_DIR:
|
|
if(debug_regim) {
|
|
|
|
SgExpression *rg = new SgVarRefExp(stmt->symbol());
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
doCallAfter(DeleteObject_H(rg));
|
|
doAssignTo_After(rg, new SgValueExp(0));
|
|
//Extract_Stmt(stmt); // extracting DVM-directive
|
|
doCallAfter( D_DelRG(DebReductionGroup( rg->symbol())));
|
|
}
|
|
wait_list = addToStmtList(wait_list, stmt);
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;//setting stmt on last inserted statement
|
|
break;
|
|
case DVM_ASYNCHRONOUS_DIR:
|
|
dvm_debug=0;
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
case DVM_ENDASYNCHRONOUS_DIR:
|
|
dvm_debug=(cur_fragment && cur_fragment->dlevel)? 1 : 0;
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
case DVM_REDUCTION_START_DIR:
|
|
case DVM_SHADOW_GROUP_DIR:
|
|
case DVM_SHADOW_START_DIR:
|
|
case DVM_SHADOW_WAIT_DIR:
|
|
case DVM_REMOTE_ACCESS_DIR:
|
|
case DVM_NEW_VALUE_DIR:
|
|
case DVM_REALIGN_DIR:
|
|
case DVM_REDISTRIBUTE_DIR:
|
|
case DVM_ASYNCWAIT_DIR:
|
|
case DVM_F90_DIR:
|
|
case DVM_CONSISTENT_START_DIR:
|
|
case DVM_CONSISTENT_WAIT_DIR:
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
|
|
//Debugging Directive
|
|
case DVM_INTERVAL_DIR:
|
|
if (perf_analysis > 1){
|
|
//generating call to 'binter' function of performance analizer
|
|
// (begin of user interval)
|
|
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
InsertNewStatementAfter(St_Binter(OpenInterval(stmt),Value_F95(stmt->expr(0))), cur_st,cur_st->controlParent());
|
|
}
|
|
pstmt = addToStmtList(pstmt, stmt); //including the DVM directive to list
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_ENDINTERVAL_DIR:
|
|
if (perf_analysis > 1){
|
|
//generating call to 'einter' function of performance analizer
|
|
// (end of user interval)
|
|
|
|
if(!St_frag){
|
|
err("Unmatched directive",182,stmt);
|
|
break;
|
|
}
|
|
if(St_frag && St_frag->begin_st && (St_frag->begin_st->controlParent() != stmt->controlParent()))
|
|
err("Misplaced directive",103,stmt); //interval must be a block
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
InsertNewStatementAfter(St_Einter(INTERVAL_NUMBER,INTERVAL_LINE), cur_st, stmt->controlParent());
|
|
CloseInterval();
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;
|
|
}
|
|
else
|
|
pstmt = addToStmtList(pstmt, stmt); //including the DVM directive to list
|
|
break;
|
|
|
|
case DVM_EXIT_INTERVAL_DIR:
|
|
if (perf_analysis > 1){
|
|
//generating calls to 'einter' function of performance analizer
|
|
// (exit from user intervals)
|
|
|
|
if(!St_frag){
|
|
err("Misplaced directive",103,stmt);
|
|
break;
|
|
}
|
|
ExitInterval(stmt);
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;
|
|
}
|
|
else
|
|
pstmt = addToStmtList(pstmt, stmt); //including the DVM directive to list
|
|
break;
|
|
|
|
case DVM_OWN_DIR:
|
|
if(dvm_debug && stmt->lexNext()->variant() == ASSIGN_STAT)
|
|
own_exe = 1;
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
case DVM_DEBUG_DIR:
|
|
{ int num;
|
|
if((stmt->expr(0)->variant() != INT_VAL) || (num=stmt->expr(0)->valueInteger())<= 0)
|
|
err("Illegal fragment number",181,stmt);
|
|
else if(debug_fragment || perf_fragment)
|
|
BeginDebugFragment(num,stmt);
|
|
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
}
|
|
break;
|
|
|
|
case DVM_ENDDEBUG_DIR:
|
|
{ int num;
|
|
if((stmt->expr(0)->variant() != INT_VAL) || (num=stmt->expr(0)->valueInteger())<= 0)
|
|
err("Illegal fragment number",181,stmt);
|
|
else if((cur_fragment && cur_fragment->No != num) || !cur_fragment && (debug_fragment || perf_fragment))
|
|
err("Unmatched directive",182,stmt);
|
|
else {
|
|
if(cur_fragment && cur_fragment->begin_st && (stmt->controlParent() != cur_fragment->begin_st->controlParent()))
|
|
//test of nesting blocks
|
|
err("Misplaced directive",103,stmt);
|
|
EndDebugFragment(num);
|
|
}
|
|
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
}
|
|
break;
|
|
|
|
case DVM_TRACEON_DIR:
|
|
InsertNewStatementAfter(new SgCallStmt(*fdvm[TRON]),stmt,stmt->controlParent());
|
|
Extract_Stmt(stmt);// extracting DVM-directive
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_TRACEOFF_DIR:
|
|
InsertNewStatementAfter(new SgCallStmt(*fdvm[TROFF]),stmt,stmt->controlParent());
|
|
Extract_Stmt(stmt);// extracting DVM-directive
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_BARRIER_DIR:
|
|
doAssignStmtAfter(Barrier());
|
|
FREE_DVM(1);
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
Extract_Stmt(stmt);// extracting DVM-directive
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_CHECK_DIR:
|
|
if(check_regim) {
|
|
cur_st = Check(stmt);
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
stmt = cur_st;
|
|
} else
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
|
|
case DVM_TASK_REGION_DIR:
|
|
task_region_st = stmt;
|
|
in_task_region++;
|
|
if(dvm_debug){
|
|
//task_region_st = stmt;
|
|
//task_region_parent = stmt->controlParent(); //to test nesting blocks
|
|
//task_lab = (SgLabel *) NULL;
|
|
task_ind = ndvm++;
|
|
DebugTaskRegion(stmt);
|
|
}
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;
|
|
break;
|
|
|
|
case DVM_END_TASK_REGION_DIR:
|
|
if(dvm_debug)
|
|
CloseTaskRegion(task_region_st,stmt);
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;
|
|
in_task_region--;
|
|
break;
|
|
case DVM_ON_DIR:
|
|
if(dvm_debug) {
|
|
if( stmt->expr(0)->symbol() && IS_DVM_ARRAY(stmt->expr(0)->symbol()))
|
|
in_on++;
|
|
else if(in_task_region) {
|
|
LINE_NUMBER_AFTER(stmt,stmt);
|
|
doAssignTo_After(DVM000(task_ind),ReplaceFuncCall(stmt->expr(0)->lhs()->lhs()));
|
|
InsertNewStatementAfter(D_Iter_ON(task_ind,TypeDVM()),cur_st,stmt->controlParent());
|
|
}
|
|
}
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
stmt = cur_st;
|
|
break;
|
|
case DVM_END_ON_DIR:
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
if(dvm_debug && in_on) {
|
|
SgStatement *std = dbg_if_regim ? CreateIfThenConstr(DebugIfCondition(),D_Skpbl()) : D_Skpbl();
|
|
InsertNewStatementAfter(std,stmt,stmt->controlParent());
|
|
stmt =lastStmtOf(std);
|
|
in_on--;
|
|
}
|
|
break;
|
|
|
|
/* case DVM_INDIRECT_ACCESS_DIR: */
|
|
case DVM_MAP_DIR:
|
|
case DVM_RESET_DIR:
|
|
case DVM_PREFETCH_DIR:
|
|
case DVM_PARALLEL_TASK_DIR:
|
|
case DVM_LOCALIZE_DIR:
|
|
case DVM_SHADOW_ADD_DIR:
|
|
case DVM_IO_MODE_DIR:
|
|
case DVM_TEMPLATE_CREATE_DIR:
|
|
case DVM_TEMPLATE_DELETE_DIR:
|
|
//including the DVM directive to list
|
|
pstmt = addToStmtList(pstmt, stmt);
|
|
break;
|
|
//Input/Output statements
|
|
case OPEN_STAT:
|
|
case CLOSE_STAT:
|
|
case INQUIRE_STAT:
|
|
case BACKSPACE_STAT:
|
|
case ENDFILE_STAT:
|
|
case REWIND_STAT:
|
|
case WRITE_STAT:
|
|
case READ_STAT:
|
|
case PRINT_STAT:
|
|
if(perf_analysis)
|
|
stmt = Any_IO_Statement(stmt);
|
|
break;
|
|
case DVM_CP_CREATE_DIR: /*Chek Point*/
|
|
CP_Create_Statement(stmt, WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
case DVM_CP_SAVE_DIR:
|
|
CP_Save_Statement(stmt, WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
case DVM_CP_LOAD_DIR:
|
|
CP_Load_Statement(stmt, WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break;
|
|
case DVM_CP_WAIT_DIR:
|
|
CP_Wait(stmt, WITH_ERR_MSG);
|
|
stmt = cur_st;
|
|
break; /*Chek Point*/
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
{ SgStatement *end_stmt;
|
|
end_stmt = isSgLogIfStmt(stmt->controlParent()) ? stmt->controlParent() : stmt;
|
|
|
|
if(inparloop && isParallelLoopEndStmt(end_stmt,par_do)) { // is last statement of parallel loop
|
|
SgStatement *go_stmt = NULL;
|
|
inparloop = 0; // closing parallel loop nest
|
|
//replacing the label of DO statements locating above parallel loop in nest,
|
|
// which is ended by stmt,
|
|
// by new label and inserting CONTINUE with this label
|
|
ReplaceDoNestLabel_Above(end_stmt, par_do, GetLabel());
|
|
if(debug_regim && HPF_program)
|
|
INDReductionDebug();
|
|
if(dvm_debug) {
|
|
CloseDoInParLoop(end_stmt); //on debug regim end_stmt==stmt
|
|
end_stmt = cur_st;
|
|
if(dbg_if_regim) {
|
|
// generating GO TO statement: GO TO begin_lab
|
|
// and inserting it after last statement of parallel loop nest
|
|
go_stmt = new SgGotoStmt(*begin_lab);
|
|
cur_st->insertStmtAfter(*go_stmt,*par_do->controlParent());
|
|
cur_st = go_stmt; // GO TO statement
|
|
}
|
|
// generating call statement : call dendl(...)
|
|
CloseParLoop(end_stmt->controlParent(),cur_st,end_stmt);
|
|
if(dbg_if_regim)
|
|
//setting label of ending parallel loop nest
|
|
(go_stmt->lexNext())->setLabel(*end_lab);
|
|
if(irg) {
|
|
// generating statement:
|
|
// call dvmh_delete_object(RedGroupRef) // dvm000(i) = delobj(RedGroupRef)
|
|
doCallAfter(DeleteObject_H(redgref));
|
|
if(idebrg)
|
|
doCallAfter( D_DelRG(DVM000(idebrg)));
|
|
}
|
|
} else if(perf_analysis == 4)
|
|
SeqLoopEndInParLoop(end_stmt,stmt);
|
|
|
|
if(perf_analysis && perf_analysis != 2) {
|
|
// generating call eloop(...) - end of parallel interval
|
|
//(performance analyzer function)
|
|
InsertNewStatementAfter(St_Enloop(INTERVAL_NUMBER,INTERVAL_LINE),cur_st,cur_st->controlParent());
|
|
CloseInterval();
|
|
if(perf_analysis != 4)
|
|
OverLoopAnalyse(func);
|
|
}
|
|
|
|
stmt = cur_st;
|
|
if(dvm_debug)
|
|
{SET_DVM(iplp);}
|
|
continue;
|
|
}
|
|
|
|
if(isDoEndStmt_f90(end_stmt)) {
|
|
if(dvm_debug)
|
|
CloseLoop(stmt); // on debug regim stmt=end_stmt
|
|
else if (perf_analysis && close_loop_interval)
|
|
SeqLoopEnd(end_stmt,stmt);
|
|
stmt = cur_st;
|
|
}
|
|
}
|
|
}
|
|
|
|
END_:
|
|
|
|
// for declaring dvm000(N) is used maximal value of ndvm
|
|
SET_DVM(ndvm);
|
|
cur_st = first_dvm_exec;
|
|
if(last_dvm_entry)
|
|
lentry = last_dvm_entry->lexNext();
|
|
if(!IN_MODULE) {
|
|
InitRemoteGroups();
|
|
//InitFileNameVariables();
|
|
if(debug_regim) {
|
|
InitRedGroupVariables();
|
|
WaitDirList();
|
|
}
|
|
DoStmtsForENTRY(first_dvm_exec,lentry);
|
|
fmask[FNAME] = 0;
|
|
stmt = data_stf ? data_stf->lexPrev() : first_dvm_exec->lexPrev();
|
|
DeclareVarDVM(stmt,stmt);
|
|
CheckInrinsicNames();
|
|
} else {
|
|
if(mod_proc)
|
|
MayBeDeleteModuleProc(mod_proc,end_of_unit);
|
|
fmask[FNAME] = 0;
|
|
nloopred = nloopcons = MAX_RED_VAR_SIZE;
|
|
stmt= mod_proc ? has_contains->lexPrev() : first_dvm_exec->lexPrev();
|
|
DeclareVarDVM(stmt, (mod_proc ? mod_proc : stmt));
|
|
}
|
|
first_dvm_exec->extractStmt(); //extract fname() call
|
|
for(;pstmt; pstmt= pstmt->next)
|
|
Extract_Stmt(pstmt->st);// extracting DVM+ACC Directives
|
|
|
|
return;
|
|
}
|
|
|
|
void VarDVM(SgStatement * func )
|
|
{ SgArrayType *typearray;
|
|
typearray =new SgArrayType(*SgTypeInt()); //typearray-> addRange(N);
|
|
dvmbuf = new SgVariableSymb("dvm000", *typearray, *func);
|
|
}
|
|
|
|
void RegistrateArg(SgExpression *ele)
|
|
{
|
|
SgExpression *el, *e;
|
|
e = ele->lhs(); //argument
|
|
if(!e)
|
|
return;
|
|
|
|
if(isSgArrayRefExp(e)) {
|
|
if(!(e->lhs())) // argument is whole array (array name)
|
|
return;
|
|
el=e->lhs()->lhs(); //first subscript of argument
|
|
//testing: is first subscript of ArrayRef a POINTER
|
|
if((isSgVarRefExp(el) || isSgArrayRefExp(el)) && IS_POINTER(el->symbol())){
|
|
if(!strcmp(e->symbol()->identifier(),"heap") || (e->symbol()->attributes() & HEAP_BIT))
|
|
heap_point = HeapList(heap_point,e->symbol(),el->symbol());
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
SgExpression *CalcLinearForm(SgSymbol *ar, SgExpression *el, SgExpression *erec)
|
|
{
|
|
int i;
|
|
SgExpression *ei, *index_list=NULL, *head_ref;
|
|
for(i=0; el; el=el->rhs(),i++)
|
|
{
|
|
ei = &(el->lhs()->copy());
|
|
ei = new SgExprListExp(*DvmType_Ref(ei));
|
|
ei->setRhs(index_list);
|
|
index_list = ei;
|
|
}
|
|
|
|
if(erec) {
|
|
head_ref = new SgExpression(RECORD_REF);
|
|
head_ref->setLhs(erec);
|
|
head_ref->setRhs( new SgArrayRefExp(*ar, *new SgValueExp(1)));
|
|
}
|
|
else
|
|
head_ref = HeaderRef(ar);
|
|
return (CalculateLinear(head_ref,i,index_list));
|
|
|
|
}
|
|
|
|
void DistArrayRef(SgExpression *e, int modified, SgStatement *st)
|
|
{ SgSymbol *ar;
|
|
SgExpression *rme, *erec=NULL;
|
|
int *h;
|
|
int is_record_ref = 0;
|
|
//replace distributed array reference A(I1,I2,...,In) by
|
|
// n
|
|
// <memory>( Header(n+1) + I1 + SUMMA(Header(n-k+1) * Ik))
|
|
// k=2
|
|
// <memory> is I0000M if A is of type integer
|
|
// R0000M if A is of type real
|
|
// D0000M if A is of type double precision
|
|
// C0000M if A is of type complex
|
|
// L0000M if A is of type logical
|
|
|
|
// modified == 1 for variable in left part of assign statement
|
|
|
|
hpf_ind = 0;
|
|
if (isSgRecordRefExp(e)) {
|
|
erec = e->lhs();
|
|
e->setType(e->rhs()->type());
|
|
NODE_CODE(e->thellnd) = ARRAY_REF;
|
|
ar = e->rhs()->symbol();
|
|
e->setLhs(e->rhs()->lhs());
|
|
e->setSymbol(ar);
|
|
is_record_ref = 1;
|
|
}
|
|
else
|
|
ar = e -> symbol();
|
|
if(IS_POINTER(ar)){
|
|
Error("Illegal POINTER reference: '%s'",ar->identifier(),138,st);
|
|
return;
|
|
}
|
|
h = HEADER(ar);
|
|
if(h && isSgArrayType(e->type()))
|
|
{ Error("Illegal distributed array reference: %s",ar->identifier(),335,st);
|
|
return;
|
|
}
|
|
|
|
if(h || is_record_ref) { //distributed array reference
|
|
if(!is_record_ref && *h > 1)
|
|
Error("Illegal template reference: '%s'",ar->identifier(),167,st);
|
|
if(HPF_program && inparloop && modified && !IND_target)
|
|
IND_target = IND_ModifiedDistArrayRef(e,st);
|
|
if(HPF_program && inparloop && !modified ) {
|
|
if(!IND_target_R)
|
|
IND_target_R = IND_ModifiedDistArrayRef(e,st);
|
|
IND_UsedDistArrayRef(e,st);
|
|
return;
|
|
}
|
|
if(!modified && !is_record_ref && (rma || HPF_program) && (rme=isRemAccessRef(e)))
|
|
// is remote variable reference
|
|
ChangeRemAccRef(e,rme);
|
|
|
|
else {
|
|
/* if(!inparloop && !own_exe)
|
|
Error("Distributed array element reference outside the range of parallel loop: '%s'",ar->identifier(),cur_st); */
|
|
|
|
if(isPrivateInRegion(ar)) //private array in loop of region
|
|
return; // array reference is not changed !!!
|
|
if(for_host) //if(IN_COMPUTE_REGION && inparloop && !for_kernel && options.isOn(O_HOST) )
|
|
return; // array reference is not changed !!!
|
|
if(for_kernel) /*ACC*/
|
|
;
|
|
else if(opt_base && inparloop && !HPF_program)
|
|
e->setSymbol( *ARRAY_BASE_SYMBOL(ar));
|
|
else
|
|
e->setSymbol(baseMemory(ar->type()->baseType()));
|
|
if(!e->lhs())
|
|
Error("No subscripts: %s", ar->identifier(),171,st);
|
|
else {
|
|
(e->lhs())->setLhs( (INTERFACE_RTS2 && !inparloop) ? *CalcLinearForm(ar,e->lhs(),erec) : *LinearForm(ar,e->lhs(),erec));
|
|
(e->lhs())->setRhs(NULL);
|
|
}
|
|
}
|
|
/*ACC*/
|
|
} else { // replicated array in region
|
|
if(for_host)
|
|
return; // array reference is not changed !!!
|
|
if(!for_kernel) /*ACC*/
|
|
e->setSymbol(baseMemory(ar->type()->baseType()));
|
|
if(!e->lhs())
|
|
Error("No subscripts: %s", ar->identifier(),171,st);
|
|
else
|
|
{ if(DUMMY_FOR_ARRAY(ar) && *DUMMY_FOR_ARRAY(ar)!=NULL) // for case of syntax error in PARALLEL directive
|
|
{ (e->lhs())->setLhs(*LinearForm(*DUMMY_FOR_ARRAY(ar),e->lhs(),NULL));
|
|
(e->lhs())->setRhs(NULL);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void GoRoundEntry(SgStatement *stmt)
|
|
{SgLabel *lab;
|
|
if((stmt->lexPrev()->variant() == RETURN_STAT) || (stmt->lexPrev()->variant() == STOP_STAT) ||(stmt->lexPrev()->variant() == GOTO_NODE)) // going round is
|
|
return;
|
|
|
|
if(!(lab=stmt->lexNext()->label())) {//next statement has not label
|
|
lab = GetLabel();
|
|
(stmt->lexNext())->setLabel(*lab);
|
|
}
|
|
stmt->insertStmtBefore(* new SgGotoStmt(*lab));
|
|
return;
|
|
}
|
|
void BeginBlockForEntry(SgStatement *stmt)
|
|
{if(stmt)
|
|
return;
|
|
return;
|
|
}
|
|
int TestLeftPart(symb_list *new_red_var_list, SgExpression *le)
|
|
{symb_list *ls;
|
|
if(!le)
|
|
return(0);
|
|
if(isDistObject(le))
|
|
return(1);
|
|
if(le->variant() == ARRAY_OP)
|
|
return(TestLeftPart(new_red_var_list,le->lhs()));
|
|
if(le->symbol()){
|
|
for(ls= new_red_var_list; ls; ls=ls->next)
|
|
if( le->symbol() == ls->symb)
|
|
return(1);
|
|
return(0);
|
|
}
|
|
else
|
|
return(0);
|
|
}
|
|
int isInSymbList(symb_list *ls,SgSymbol *s)
|
|
{symb_list *l;
|
|
for(l=ls; l; l=l->next)
|
|
if(s == l->symb)
|
|
return(1);
|
|
return(0);
|
|
}
|
|
|
|
void TestReverse(SgExpression *e,SgStatement *st)
|
|
{
|
|
if(e && e->isInteger() && (e->valueInteger() < 0))
|
|
err("Reverse is not supported",163,st);
|
|
return;
|
|
}
|
|
|
|
void LineNumber(SgStatement *st)
|
|
{st->insertStmtAfter(*D_Lnumb(st->lineNumber()),*st->controlParent());}
|
|
|
|
|
|
int PointerRank(SgSymbol *p)
|
|
{int rank ;
|
|
SgExpression *el;
|
|
rank = 0;
|
|
for(el= (*POINTER_DIR(p))->expr(1); el; el=el->rhs())
|
|
rank++;
|
|
return (rank);
|
|
}
|
|
|
|
SgType * PointerType(SgSymbol *p)
|
|
{return( (*POINTER_DIR(p))->expr(2)->type());}
|
|
|
|
void AssignPointer(SgStatement *ass)
|
|
{int r;
|
|
SgSymbol *pl, *pr;
|
|
//SgExpression *head_new, *head;
|
|
//ifst=ndvm;
|
|
pl = ass->expr(0)->symbol();
|
|
pr = ass->expr(1)->symbol();
|
|
/* if(IS_DVM_ARRAY(pl))
|
|
Error("POINTER '%s' in left part of assign statement has DISTRIBUTE or ALIGN attribute",pl->identifier(), 172,ass);*//*28.12.99*/
|
|
/* if(!IS_DVM_ARRAY(pr))
|
|
Error("POINTER '%s' in right part of assign statement has not DISTRIBUTE or ALIGN attribute",pr->identifier(), ass);*/
|
|
r = PointerRank(pl);
|
|
if(PointerRank(pr) != r)
|
|
err("Pointers are of different rank", 173,ass);
|
|
if(PointerType(pr) != PointerType(pl))
|
|
err("Pointers are of different type", 174,ass);
|
|
TestArrayRef(ass->expr(0),ass);
|
|
TestArrayRef(ass->expr(1),ass);
|
|
|
|
/*LINE_NUMBER_AFTER(ass,ass);*/
|
|
/*
|
|
head_new = (ass->expr(0)->lhs()) ? AddFirstSubscript(ass->expr(0),new SgValueExp(1)) : HeaderRefInd(pl,1);
|
|
head = (ass->expr(1)->lhs()) ? AddFirstSubscript(ass->expr(1),new SgValueExp(1)) : HeaderRefInd(pr,1);
|
|
doAssignStmtAfter(AddHeader(head_new,head));
|
|
*/
|
|
/*
|
|
doAssignStmtAfter(AddHeader(PointerHeaderRef(ass->expr(0),1),PointerHeaderRef(ass->expr(1),1)));
|
|
CopyHeader(ass->expr(0),ass->expr(1),r);
|
|
SET_DVM(ifst);
|
|
*/
|
|
return;
|
|
}
|
|
|
|
void AddFirstSubscript(SgExpression *ea, SgExpression *ei)
|
|
{SgExpression *el,*efirst;
|
|
if(!ei || !ea)
|
|
return;
|
|
el = ea->lhs();
|
|
efirst = new SgExprListExp(*ei);
|
|
efirst -> setRhs(el);
|
|
ea -> setLhs(efirst);
|
|
}
|
|
/*
|
|
SgExpression * PointerHeaderRef(SgExpression *pe, int ind)
|
|
// P => P(ind)
|
|
// P(i,j,...) => P(ind,i,j,...)
|
|
{SgSymbol *p;
|
|
if(!(p=pe->symbol()))
|
|
return (pe);
|
|
if(p->attributes() & DIMENSION_BIT){ // POINTER p declared as array
|
|
SgExpression *ef,*cpe;
|
|
if(!pe->lhs())
|
|
return (pe);
|
|
cpe = & (pe->copy());
|
|
ef = new SgExprListExp(* new SgValueExp(ind));
|
|
ef->setRhs(cpe->lhs());
|
|
cpe->setLhs(ef);
|
|
return(cpe);
|
|
}
|
|
else
|
|
return(HeaderRefInd(p,ind));
|
|
}
|
|
*/
|
|
|
|
SgExpression * PointerHeaderRef(SgExpression *pe, int ind)
|
|
// P => HEAP(P+ind-1)
|
|
// P(i,j,...) => HEAP(P(i,j,...)+ind-1)
|
|
{ SgExpression *ef,*cpe;
|
|
if(!(pe->symbol()))
|
|
return (pe);
|
|
if(!heap_ar_decl)
|
|
return(pe); //error: HEAP isn't declared
|
|
cpe = new SgArrayRefExp(*heap_ar_decl->symbol());
|
|
ef = (ind == 1) ? new SgExprListExp(pe->copy()) : new SgExprListExp(pe->copy()+(*new SgValueExp(ind-1)));
|
|
cpe->setLhs(ef);
|
|
return(cpe);
|
|
}
|
|
|
|
|
|
void CopyHeader(SgExpression *ple, SgExpression *pre, int rank)
|
|
{ //int i;
|
|
// for(i=0; i<rank; i++)
|
|
// doAssignTo_After(PointerHeaderRef(ple,rank+2+i), PointerHeaderRef(pre,rank+2+i));
|
|
doAssignTo_After(PointerHeaderRef(ple,rank+2), PointerHeaderRef(pre,rank+2));
|
|
//for(i=0; i<rank; i++)
|
|
// doAssignTo_After(PointerHeaderRef(ple,rank+2+i), new SgValueExp(1));
|
|
}
|
|
|
|
int TestArrayRef(SgExpression *e, SgStatement *stmt)
|
|
{SgSymbol *s;
|
|
if(!(s=e->symbol()))
|
|
return (0);
|
|
if((s->attributes() & DIMENSION_BIT) && !e->lhs()) { // s declared as array
|
|
Error("No subscripts: %s", s->identifier(),171,stmt);
|
|
return(0);
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
void AddDistSymbList(SgSymbol *s)
|
|
{ symb_list *ds;
|
|
if(!dsym) {
|
|
dsym = new symb_list;
|
|
dsym->symb = s;
|
|
dsym->next = NULL;
|
|
} else {
|
|
ds = new symb_list;
|
|
ds->symb = s;
|
|
ds->next = dsym;
|
|
dsym = ds;
|
|
}
|
|
}
|
|
|
|
void StoreLowerBoundsPlus(SgSymbol *ar,SgExpression *arref)
|
|
// generating assign statements to
|
|
//store lower bounds of array in Header(rank+3:2*rank+2)
|
|
//and to initialize counter of remote access buffers: HEADER(2*rank+3) = 2*rank+4
|
|
//and to set the flag to 0: array is not distributed yet
|
|
{int i,rank;
|
|
SgExpression *le;
|
|
rank = Rank(ar);
|
|
if(!IS_TEMPLATE(ar) && !IS_POINTER(ar))
|
|
doAssignTo(header_section(ar,2,rank+1), new SgValueExp(1)); // coefficient's initialization
|
|
|
|
for(i=0;i<rank;i++) {
|
|
le = IS_POINTER(ar) ? new SgValueExp(1) : Exprn( LowerBound(ar,i));
|
|
doAssignTo(!arref ? header_ref(ar,rank+3+i) : PointerHeaderRef(arref,rank+3+i), le) ;
|
|
}
|
|
if(!IS_TEMPLATE(ar)) {
|
|
doAssignTo(!arref ? header_ref(ar,HSIZE(rank)+1) : PointerHeaderRef(arref,HSIZE(rank)+1), new SgValueExp(HSIZE(rank)+2));
|
|
// initializing HEADER(2*rank+3) - counter of remote access buffers
|
|
if(ar->attributes() & POSTPONE_BIT)
|
|
doAssignTo(!arref ? header_ref(ar,HEADER_SIZE(ar)) : PointerHeaderRef(arref,HEADER_SIZE(ar)), new SgValueExp(0));
|
|
// HEADER(HEADER_SIZE) = 0 => the array is not distributed yet
|
|
}
|
|
}
|
|
|
|
void StoreLowerBoundsPlusFromAllocate(SgSymbol *ar,SgExpression *arref,SgExpression *lbound)
|
|
// generating assign statements to
|
|
//store lower bounds of array in Header(rank+3:2*rank+2)
|
|
//and to initialize counter of remote access buffers: HEADER(2*rank+3) = 2*rank+4
|
|
//and to set the flag to 0: array is not distributed yet
|
|
{int i,rank;
|
|
SgExpression *le;
|
|
rank = Rank(ar);
|
|
for(i=0;i<rank;i++) {
|
|
le = &(lbound->copy());
|
|
if(lbound->lhs())
|
|
le->lhs()->setLhs(Calculate(&(lbound->lhs()->lhs()->copy()+ *new SgValueExp(i))));
|
|
else
|
|
le->setLhs(new SgExprListExp(*new SgValueExp(i+1)));
|
|
|
|
doAssignTo(!arref ? header_ref(ar,rank+3+i) : PointerHeaderRef(arref,rank+3+i), le) ;
|
|
}
|
|
if(!IS_TEMPLATE(ar)) {
|
|
doAssignTo(!arref ? header_ref(ar,HSIZE(rank)+1) : PointerHeaderRef(arref,HSIZE(rank)+1), new SgValueExp(HSIZE(rank)+2));
|
|
// initializing HEADER(2*rank+3) - counter of remote access buffers
|
|
if(ar->attributes() & POSTPONE_BIT)
|
|
doAssignTo(!arref ? header_ref(ar,HEADER_SIZE(ar)) : PointerHeaderRef(arref,HEADER_SIZE(ar)), new SgValueExp(0));
|
|
// HEADER(HEADER_SIZE) = 0 => the array is not distributed yet
|
|
}
|
|
}
|
|
|
|
|
|
void StoreLowerBoundsPlusOfAllocatable(SgSymbol *ar,SgExpression *desc)
|
|
// generating assign statements to
|
|
//store lower bounds of ALLOCATABLE array in Header(rank+3:2*rank+2)
|
|
//and to initialize counter of remote access buffers: HEADER(2*rank+3) = 2*rank+4
|
|
//and to set the flag to 0: array is not distributed yet
|
|
{int i,rank;
|
|
SgExpression *le,*el;
|
|
rank = Rank(ar);
|
|
doAssignTo(header_section(ar,2,rank+1), new SgValueExp(1)); // coefficient's initialization
|
|
for(i=0,el=desc->lhs();el;i++,el=el->rhs()) {
|
|
le = (el->lhs()->variant() == DDOT) ? &el->lhs()->lhs()->copy() : new SgValueExp(1) ;
|
|
doAssignTo(header_ref(ar,rank+3+i), le) ;
|
|
}
|
|
if(!IS_TEMPLATE(ar)) {
|
|
doAssignTo(header_ref(ar,HSIZE(rank)+1), new SgValueExp(HSIZE(rank)+2));
|
|
// initializing HEADER(2*rank+3) - counter of remote access buffers
|
|
if(ar->attributes() & POSTPONE_BIT)
|
|
doAssignTo(header_ref(ar,HEADER_SIZE(ar)), new SgValueExp(0));
|
|
// HEADER(HEADER_SIZE) = 0 => the array is not distributed yet
|
|
}
|
|
}
|
|
|
|
|
|
void StoreLowerBoundsPlusOfAllocatableComponent(SgSymbol *ar,SgExpression *desc, SgExpression *struct_)
|
|
// generating assign statements to
|
|
//store lower bounds of ALLOCATABLE array in Header(rank+3:2*rank+2)
|
|
//and to initialize counter of remote access buffers: HEADER(2*rank+3) = 2*rank+4
|
|
//and to set the flag to 0: array is not distributed yet
|
|
{int i,rank;
|
|
SgExpression *le,*el;
|
|
rank = Rank(ar);
|
|
doAssignTo(header_section_in_structure(ar,2,rank+1,struct_), new SgValueExp(1)); // coefficient's initialization
|
|
|
|
for(i=0,el=desc->lhs();el;i++,el=el->rhs()) {
|
|
le = (el->lhs()->variant() == DDOT) ? &el->lhs()->lhs()->copy() : new SgValueExp(1) ;
|
|
doAssignTo(header_ref_in_structure(ar,rank+3+i,struct_), le) ;
|
|
}
|
|
doAssignTo(header_ref_in_structure(ar,HSIZE(rank)+1,struct_), new SgValueExp(HSIZE(rank)+2));
|
|
// initializing HEADER(2*rank+3) - counter of remote access buffers
|
|
if(ar->attributes() & POSTPONE_BIT)
|
|
doAssignTo(header_ref_in_structure(ar,HEADER_SIZE(ar),struct_), new SgValueExp(0));
|
|
// HEADER(HEADER_SIZE) = 0 => the array is not distributed yet
|
|
|
|
}
|
|
|
|
void ReplaceLowerBound(SgSymbol *ar, int i)
|
|
//replace i-th lower bound of array 'ar' with Header(rank+3+i) reference in Symbol Table
|
|
// Li : Ui => Header(rank+3+i) : Ui
|
|
//i=0,...,rank-1
|
|
{SgExpression *e;
|
|
SgArrayType *artype;
|
|
artype = isSgArrayType(ar->type());
|
|
if(artype) {
|
|
e = artype->sizeInDim(i);
|
|
if(e->lhs() && e->rhs()) // Li : Ui
|
|
if(!(ReplaceParameter(&e->lhs()->copy())->isInteger()))
|
|
e->setLhs(header_ref(ar,Rank(ar)+3+i));
|
|
}
|
|
}
|
|
|
|
void ReplaceArrayBounds(SgSymbol *ar)
|
|
{int i,rank;
|
|
rank = Rank(ar);
|
|
if( IS_DUMMY(ar))
|
|
for(i=0; i<rank; i++)
|
|
ReplaceLowerBound(ar,i);
|
|
}
|
|
|
|
void StoreOneBounds(SgSymbol *ar)
|
|
// generating assign statements:
|
|
// Header(2*rank+3 +i) = 1, i=0,...,rank-1
|
|
{int i,rank;
|
|
rank = Rank(ar);
|
|
for(i=0;i<rank;i++)
|
|
doAssignTo(header_ref(ar,rank+3+i), new SgValueExp(1));
|
|
}
|
|
|
|
SgExpression *ConstRef(int ic)
|
|
{
|
|
dvm_const_ref = 1;
|
|
if(ic>9){
|
|
if(ic == 16)
|
|
return(&(*new SgVarRefExp(Iconst[8])+(*new SgVarRefExp(Iconst[8]))));
|
|
else if(ic-9 < 10)
|
|
return(&(*new SgVarRefExp(Iconst[ic-9])+(*new SgVarRefExp(Iconst[9]))));
|
|
else
|
|
return(&(*new SgVarRefExp(Iconst[9])+(*new SgValueExp(ic-9))));
|
|
// err("Compiler bug. Integer constant > 9", 0,cur_st);
|
|
return(new SgValueExp(ic));
|
|
}
|
|
return(new SgVarRefExp(Iconst[ic]));
|
|
}
|
|
|
|
SgExpression *SignConstRef(int ic)
|
|
{SgExpression *res;
|
|
res = (ic < 0) ? &SgUMinusOp(*ConstRef(-ic)) : ConstRef(ic);
|
|
return(res);
|
|
}
|
|
|
|
void TestParamType(SgStatement *stmt)
|
|
{SgType *t;
|
|
t = stmt->expr(2)->symbol()->type();
|
|
if(isSgArrayType(t) && (t->baseType()->variant() == T_FLOAT && TypeSize(t->baseType())==8 || t->baseType()->variant() == T_DOUBLE) && Rank(stmt->expr(2)->symbol())==2)
|
|
return ;
|
|
Error("Illegal type of parameter array '%s'",stmt->expr(2)->symbol()->identifier(),615,stmt);
|
|
}
|
|
|
|
SgExpression *CountOfTasks(SgStatement *st)
|
|
{SgExpression *e;
|
|
e = st->expr(0)->lhs()->lhs();
|
|
if(e->variant()==DDOT && !e->lhs() && !e->rhs()) //whole task's array
|
|
return(ReplaceFuncCall(ArrayDimSize(st->expr(0)->symbol(),1)));
|
|
else //section of task's array
|
|
{ err("Section/element of task array. Not implemented yet.",614,st);
|
|
return(new SgValueExp(0));
|
|
}
|
|
}
|
|
|
|
void ReconfPS( stmt_list *pstmt)
|
|
{ int rank;
|
|
SgSymbol *pr;
|
|
SgExpression *size_array, *le;
|
|
stmt_list *lst;
|
|
//looking through the DVM specification directive (pstmt)
|
|
for(lst=pstmt; lst; lst=lst->next)
|
|
if(lst->st->variant() == HPF_PROCESSORS_STAT)
|
|
for (le=lst->st->expr(0); le; le = le->rhs()) { //looking through the processor list
|
|
pr= le->lhs()->symbol();
|
|
proc_symb = AddToSymbList(proc_symb, pr);
|
|
LINE_NUMBER_BEFORE(lst->st,where);
|
|
// for tracing set the global variable of LibDVM to
|
|
// line number of directive PROCESSORS
|
|
rank = Rank(pr);
|
|
if(!rank) { // is not array P => P(1)
|
|
size_array = dvm_array_ref();
|
|
doAssignStmt(new SgValueExp(1));
|
|
rank = 1;
|
|
} else
|
|
size_array = doSizeArrayD(pr,lst->st);
|
|
|
|
// pr = reconf(PSRef, rank, SizeArray, StaticSign)
|
|
// reconf() creates processor system
|
|
doAssignTo(new SgVarRefExp(pr),Reconf(size_array, rank, 0));
|
|
}
|
|
}
|
|
|
|
SgExpression *CurrentPS ()
|
|
{SgExpression *ps;
|
|
if(in_task_region)
|
|
ps = new SgArrayRefExp(*task_array, *new SgValueExp(1),*DVM000(task_ind));
|
|
/* else if(fmask[GETAM] == 0) // not GETVM but GETAM !!
|
|
ps = GetProcSys(ConstRef(0)); //ConstRef(0); constant = 0
|
|
else
|
|
ps = DVM000(3);
|
|
*/
|
|
else
|
|
ps = ConstRef(0);
|
|
return(ps);
|
|
|
|
}
|
|
|
|
SgExpression *CurrentAM ()
|
|
{SgExpression *am;
|
|
am = ConstRef(0); //DVM000(2); //ConstRef(0); //GetAM();
|
|
return(am);
|
|
}
|
|
|
|
SgExpression *ParentPS ()
|
|
{ return( GetProcSys(&SgUMinusOp(*ConstRef(1))));}
|
|
|
|
SgExpression *PSReference(SgStatement *st)
|
|
{SgExpression *target,*es,*le[MAX_DIMS],*re[MAX_DIMS];
|
|
SgValueExp c1(1);
|
|
int ile,ips,rank,j,i;
|
|
|
|
target = (st->variant() == DVM_MAP_DIR) ? st->expr(1) : st->expr(2);
|
|
if(!target)
|
|
return( CurrentPS());
|
|
/*
|
|
if(st->variant() == DVM_REDISTRIBUTE_DIR){
|
|
target = target->lhs();
|
|
if(target->variant() == NEW_VALUE_OP)
|
|
return( CurrentPS());
|
|
}
|
|
*/
|
|
if(target->symbol()->attributes() & PROCESSORS_BIT){
|
|
if(!target->lhs())
|
|
return(target);
|
|
// return( new SgVarRefExp(target->symbol()));
|
|
|
|
for(es=target->lhs(),j=0; es; es=es->rhs(),j++){ //looking through the subscript list
|
|
if(j==MAX_DIMS) {
|
|
Error("Too many dimensions specified for %s", target->symbol()->identifier(),43,st);
|
|
break;
|
|
}
|
|
if(es->lhs()->variant() == DDOT) {
|
|
//determination of dimension bounds
|
|
if(!es->lhs()->lhs() && !es->lhs()->rhs()){
|
|
le[j] = new SgValueExp(0);
|
|
re[j] = &(*Exprn(UpperBound(target->symbol(),j)) - *Exprn(LowerBound(target->symbol(),j)));
|
|
} else if(!es->lhs()->lhs() && es->lhs()->rhs()) {
|
|
le[j] = new SgValueExp(0);
|
|
re[j] = &(*es->lhs()->rhs() - *Exprn(LowerBound(target->symbol(),j)));
|
|
} else if(es->lhs()->lhs() && !es->lhs()->rhs()) {
|
|
le[j] = &(*es->lhs()->lhs() - *Exprn(LowerBound(target->symbol(),j)));
|
|
re[j] = &(*Exprn(UpperBound(target->symbol(),j)) - *Exprn(LowerBound(target->symbol(),j)));
|
|
} else if(es->lhs()->lhs() && es->lhs()->rhs()) {
|
|
le[j] = &(*es->lhs()->lhs() - *Exprn(LowerBound(target->symbol(),j)));
|
|
re[j] = &(*es->lhs()->rhs() - *Exprn(LowerBound(target->symbol(),j)));
|
|
}
|
|
} else {
|
|
le[j] = &(*es->lhs() - *Exprn(LowerBound(target->symbol(),j)));
|
|
re[j] = &le[j]->copy();
|
|
}
|
|
}
|
|
rank = Rank(target->symbol());
|
|
if(rank && rank != j)
|
|
Error("Wrong number of subscripts specified for %s", target->symbol()->identifier(),140,st);
|
|
|
|
ile = ndvm;
|
|
for(i=0; i<j; i++) //creating Size Array
|
|
doAssignStmt(Calculate(le[i]));
|
|
for(i=0; i<j; i++) //creating Size Array
|
|
doAssignStmt(Calculate(re[i]));
|
|
ips = ndvm;
|
|
doAssignStmt(CrtPS(new SgArrayRefExp(*target->symbol()), ile, ile+j, 0));
|
|
return (DVM000(ips));
|
|
}
|
|
|
|
if(target->symbol()->attributes() & TASK_BIT)
|
|
return(TaskPS(target,st));
|
|
return( CurrentPS());
|
|
}
|
|
|
|
SgExpression *TaskPS(SgExpression *target,SgStatement *st)
|
|
{
|
|
if(!target->lhs() || target->lhs()->rhs()) //there are no subscript or >1
|
|
Error("Wrong number of subscripts specified for %s", target->symbol()->identifier(),140,st);
|
|
return( new SgArrayRefExp(*target->symbol(), *new SgValueExp(1),*target->lhs()->lhs()));
|
|
}
|
|
|
|
SgExpression *hasNewValueClause(SgStatement *stdis)
|
|
{SgExpression *e;
|
|
e = stdis->expr(2);
|
|
if(!e) // NEW_VALUE clause is absent
|
|
return (e);
|
|
e = e->lhs();
|
|
if(e->variant() == NEW_VALUE_OP)
|
|
return(e);
|
|
else if(e->rhs())
|
|
return(e->rhs()->lhs());
|
|
return(NULL);
|
|
}
|
|
|
|
SgExpression *hasOntoClause(SgStatement *stdis)
|
|
{SgExpression *target;
|
|
SgSymbol *tsymb;
|
|
target = stdis->expr(2);
|
|
if(!target) //ONTO clause is absent
|
|
return (target);
|
|
if(isSgExprListExp(target)){
|
|
target = target->lhs();
|
|
if(target->variant() == NEW_VALUE_OP)
|
|
return(NULL);
|
|
}
|
|
tsymb = target->symbol();
|
|
if(!(tsymb->attributes() & DIMENSION_BIT))
|
|
Error("'%s' isn't array",tsymb->identifier(),66,stdis);
|
|
if(stdis->variant() == DVM_DISTRIBUTE_DIR){
|
|
if(!(tsymb->attributes() & PROCESSORS_BIT))
|
|
Error("'%s' hasn't PROCESSORS attribute",tsymb->identifier(),176,stdis);
|
|
} else // REDISTRIBUTE directive
|
|
if(!(tsymb->attributes() & PROCESSORS_BIT) && !(tsymb->attributes() & TASK_BIT))
|
|
Error("'%s' hasn't PROCESSORS/TASK attribute",tsymb->identifier(),176,stdis);
|
|
return(target);
|
|
}
|
|
|
|
int RankOfSection(SgExpression *are)
|
|
{int rank;
|
|
// SgExpression *el;
|
|
//int ndim;
|
|
if(!are)
|
|
return(0);
|
|
if(are->symbol()->attributes() & TASK_BIT)
|
|
return(0);
|
|
rank = Rank(are->symbol());
|
|
if(!are->lhs())
|
|
return(rank ? rank : 1 );
|
|
|
|
return (rank);
|
|
/*for(el=are->lhs(),ndim=0; el; el = el->rhs(), ndim++)
|
|
;
|
|
return(ndim <= rank ? ndim : rank);
|
|
*/
|
|
}
|
|
|
|
void CreateTaskArray(SgSymbol *ts)
|
|
{int isize,iamv;
|
|
SgExpression *le,*re, *e;
|
|
SgArrayType *artype;
|
|
SgSymbol **tsk_amv = new (SgSymbol *);
|
|
SgSymbol **tsk_ind = new (SgSymbol *);
|
|
SgSymbol **tsk_renum_array = new (SgSymbol *);
|
|
SgSymbol **tsk_lps = new (SgSymbol *);
|
|
SgSymbol **tsk_hps = new (SgSymbol *);
|
|
|
|
isize = ndvm++;
|
|
SgStatement *dost,*as;
|
|
nio = (nio < 1 ) ? 1: nio;
|
|
artype = isSgArrayType(ts->type());
|
|
doAssignTo(DVM000(isize),ReplaceFuncCall(&artype->sizeInDim(0)->copy()));
|
|
iamv = ndvm;
|
|
task_ps=iamv;
|
|
//doAssignStmt(CreateAMView(DVM000(isize), 1, 0));
|
|
*tsk_amv = TaskAMVSymbol(ts);
|
|
doAssignTo(new SgVarRefExp(*tsk_amv),CreateAMView(DVM000(isize), 1, 0));
|
|
//loop_lab = GetLabel();
|
|
le = new SgArrayRefExp(*ts,*new SgValueExp(2),*new SgVarRefExp(loop_var[0]));
|
|
*tsk_renum_array = TaskRenumArraySymbol(ts);
|
|
e = &(*new SgArrayRefExp(**tsk_renum_array,*new SgVarRefExp(loop_var[0])) - *new SgValueExp(1));
|
|
re = GetAMR(new SgVarRefExp(*tsk_amv),e);
|
|
as = new SgAssignStmt(*le,*re);
|
|
dost= new SgForStmt(loop_var[0], new SgValueExp(1), DVM000(isize), new SgValueExp(1), as);
|
|
//BIF_LABEL_USE(dost->thebif) = loop_lab->thelabel;
|
|
//as->setLabel(*loop_lab);
|
|
where->insertStmtBefore(*dost,*where->controlParent());
|
|
//as->lexNext()->extractStmt();
|
|
//le = DVM000(iamv+1);
|
|
//re = &(*new SgVarRefExp(loop_var[0]) - *new SgValueExp(1)); //dvm000(...)=i-1
|
|
/* initializing renumeration array */
|
|
le = new SgArrayRefExp(**tsk_renum_array,*new SgVarRefExp(loop_var[0]));
|
|
re = new SgVarRefExp(loop_var[0]);
|
|
as->insertStmtBefore(*new SgAssignStmt(*le,*re));
|
|
//SET_DVM(isize);
|
|
// index = new int;
|
|
// *index = task_ps;
|
|
// adding the attribute (TASK_INDEX) to TASK symbol
|
|
// ts->addAttribute(TASK_INDEX, (void *) index, sizeof(int));
|
|
// adding the attribute (TSK_SYMBOL) to TASK symbol
|
|
ts->addAttribute(TSK_SYMBOL, (void*) tsk_amv, sizeof(SgSymbol *));
|
|
*tsk_ind = TaskIndSymbol(ts);
|
|
// adding the attribute (TSK_IND_VAR) to TASK symbol
|
|
ts->addAttribute(TSK_IND_VAR, (void*) tsk_ind, sizeof(SgSymbol *));
|
|
|
|
// adding the attribute (TSK_RENUM_ARRAY) to TASK symbol
|
|
ts->addAttribute(TSK_RENUM_ARRAY, (void*) tsk_renum_array, sizeof(SgSymbol *));
|
|
*tsk_lps = TaskLPsArraySymbol(ts);
|
|
// adding the attribute (TSK_LPS_ARRAY) to TASK symbol
|
|
ts->addAttribute(TSK_LPS_ARRAY, (void*) tsk_lps, sizeof(SgSymbol *));
|
|
*tsk_hps = TaskHPsArraySymbol(ts);
|
|
// adding the attribute (TSK_HPS_ARRAY) to TASK symbol
|
|
ts->addAttribute(TSK_HPS_ARRAY, (void*) tsk_hps, sizeof(SgSymbol *));
|
|
return;
|
|
}
|
|
|
|
int LoopVarType(SgSymbol *var,SgStatement *st)
|
|
{ int len;
|
|
SgType *type;
|
|
|
|
type = var->type();
|
|
if(!type)
|
|
return(0);
|
|
len = TypeSize(type); /*16.04.04 */
|
|
/*len = IS_INTRINSIC_TYPE(type) ? 0 : TypeSize(type);*/
|
|
//len = (TYPE_RANGES(type->thetype)) ? type->length()->valueInteger() : 0; 14.03.03
|
|
if(bind_ == 0)
|
|
switch(type->variant()) {
|
|
case T_INT: return((len == 2) ? 2 : 0); // (long = int)
|
|
default:
|
|
{ Error("Illegal type of do-variable '%s'",var->identifier(),178,st);
|
|
return(0);
|
|
}
|
|
}
|
|
if(bind_ == 1)
|
|
switch(type->variant()) {
|
|
case T_INT: if (len == 8) return(0);
|
|
else if(len == 2) return(2);
|
|
else return(1);
|
|
|
|
default: { Error("Illegal type of do-variable '%s'",var->identifier(),178,st);
|
|
return(0);
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
int LocVarType(SgSymbol *var,SgStatement *st)
|
|
{ int len;
|
|
SgType *type;
|
|
if(!var)
|
|
return(0);
|
|
type = var->type();
|
|
if(!type)
|
|
return(0);
|
|
if (isSgArrayType(type))
|
|
type = type->baseType();
|
|
len = TypeSize(type); /*16.04.04 */
|
|
if(bind_ == 0)
|
|
switch(type->variant()) {
|
|
case T_INT: if(len == 4) return(0); // (long = int)
|
|
else if(len == 2) return(2);
|
|
else if(len == 1) return(3);
|
|
else
|
|
{ err("Wrong operand of MAXLOC/MINLOC",149,st);
|
|
return(0);
|
|
}
|
|
|
|
default:
|
|
{ err("Wrong operand of MAXLOC/MINLOC",149,st);
|
|
return(0);
|
|
}
|
|
}
|
|
if(bind_ == 1)
|
|
switch(type->variant()) {
|
|
case T_INT: if (len == 8) return(0);
|
|
else if(len == 4) return(1);
|
|
else if(len == 2) return(2);
|
|
else if(len == 1) return(3);
|
|
else
|
|
{ err("Wrong operand of MAXLOC/MINLOC",149,st);
|
|
return(0);
|
|
}
|
|
default: { err("Wrong operand of MAXLOC/MINLOC",149,st);
|
|
return(0);
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
int TypeDVM()
|
|
{return(0);}
|
|
|
|
void StartTask(SgStatement *stmt)
|
|
{SgStatement *if_stmt, *st;
|
|
SgExpression *ei;
|
|
ei = stmt->expr(0)->lhs()->lhs();
|
|
doAssignTo_After(DVM000(task_ind),ReplaceFuncCall(ei));
|
|
if(!isSgVarRefExp(ei) && !isSgValueExp(ei))
|
|
ei = DVM000(task_ind);
|
|
st = (stmt->variant()==DVM_ON_DIR) ? new SgGotoStmt(*task_lab) : new SgStatement(CYCLE_STMT);
|
|
if_stmt = new SgLogIfStmt(SgEqOp(*RunAM(new SgArrayRefExp(*(stmt->expr(0)->symbol()),
|
|
*new SgValueExp(2),*ei)),*new SgValueExp(0) ),*st);
|
|
cur_st->insertStmtAfter(*if_stmt);
|
|
cur_st = if_stmt->lexNext(); // CYCLE statement or GOTO statement
|
|
(cur_st->lexNext())-> extractStmt(); //extract ENDIF
|
|
if(dvm_debug)
|
|
if( stmt->variant()==DVM_ON_DIR)
|
|
InsertNewStatementAfter(D_Iter_ON(task_ind,TypeDVM()),cur_st,stmt->controlParent());
|
|
|
|
return;
|
|
}
|
|
|
|
void InitGroups()
|
|
{ group_name_list *sl;
|
|
for(sl=grname; sl; sl=sl->next)
|
|
if(!IS_SAVE(sl->symb))
|
|
/* if (sl->symb->variant() == REF_GROUP_NAME){
|
|
doAssignTo(new SgArrayRefExp(*sl->symb,*new SgValueExp(1)),new SgValueExp(0));
|
|
doAssignTo(new SgArrayRefExp(*sl->symb,*new SgValueExp(2)),new SgValueExp(0));
|
|
doAssignTo(new SgArrayRefExp(*sl->symb,*new SgValueExp(3)),new SgValueExp(0));
|
|
} else */
|
|
if (sl->symb->variant() == REDUCTION_GROUP_NAME || sl->symb->variant() == CONSISTENT_GROUP_NAME)
|
|
doAssignTo(new SgVarRefExp(*sl->symb),new SgValueExp(0));
|
|
|
|
}
|
|
void CreateRedGroupVars()
|
|
{ group_name_list *sl;
|
|
SgSymbol *rgs;
|
|
|
|
for(sl=grname; sl; sl=sl->next)
|
|
//if(!IS_SAVE(sl->symb)) ???
|
|
if (sl->symb->variant() == REDUCTION_GROUP_NAME || sl->symb->variant() == CONSISTENT_GROUP_NAME) {
|
|
SgSymbol **ss = new (SgSymbol *);
|
|
rgs = new SgVariableSymb(RedGroupVarName(sl->symb), *new SgArrayType(*SgTypeInt()), *cur_func);
|
|
*ss = rgs;
|
|
(sl->symb)->addAttribute( RED_GROUP_VAR, (void *) ss, sizeof(SgSymbol *));
|
|
}
|
|
}
|
|
|
|
void InitShadowGroups()
|
|
{ group_name_list *sl;
|
|
for(sl=grname; sl; sl=sl->next)
|
|
if(!IS_SAVE(sl->symb))
|
|
if (sl->symb->variant() == SHADOW_GROUP_NAME)
|
|
doAssignTo_After(new SgVarRefExp(*sl->symb),new SgValueExp(0));
|
|
}
|
|
|
|
|
|
void InitRemoteGroups()
|
|
{stmt_list *stl;
|
|
for(stl=pref_st; stl; stl=stl->next) {
|
|
doAssignTo_After(new SgArrayRefExp(*stl->st->symbol(),*new SgValueExp(1)),new SgValueExp(0));
|
|
doAssignTo_After(new SgArrayRefExp(*stl->st->symbol(),*new SgValueExp(2)),new SgValueExp(0));
|
|
doAssignTo_After(new SgArrayRefExp(*stl->st->symbol(),*new SgValueExp(3)),new SgValueExp(0));
|
|
}
|
|
}
|
|
|
|
|
|
void InitRedGroupVariables()
|
|
{group_name_list *gl;
|
|
int i,nl;
|
|
SgSymbol *rgv;
|
|
for(gl=grname; gl; gl=gl->next)
|
|
if (gl->symb->variant() == REDUCTION_GROUP_NAME || gl->symb->variant() == CONSISTENT_GROUP_NAME) {
|
|
rgv = * ((SgSymbol **) (gl->symb)-> attributeValue(0,RED_GROUP_VAR));
|
|
nl = gl->symb->variant() == REDUCTION_GROUP_NAME ? nloopred : nloopcons;
|
|
for(i=nl; i; i--)
|
|
doAssignTo_After(new SgArrayRefExp(*rgv,*new SgValueExp(i)),new SgValueExp(0));
|
|
}
|
|
}
|
|
|
|
void WaitDirList()
|
|
{stmt_list *stl;
|
|
SgStatement *stat;
|
|
SgSymbol *rgv, *rg;
|
|
int i,nl;
|
|
stat = cur_st;
|
|
for(stl=wait_list; stl; stl=stl->next) {
|
|
cur_st = stl->st;
|
|
rg = ORIGINAL_SYMBOL(stl->st->symbol());
|
|
rgv = * ((SgSymbol **) rg -> attributeValue(0,RED_GROUP_VAR));
|
|
nl =(cur_st ->variant() == DVM_CONSISTENT_WAIT_DIR) ? ((cur_st->controlParent()->variant() == PROG_HEDR) ? 0 : nloopcons) : nloopred;
|
|
for(i=nl; i; i--)
|
|
doAssignTo_After(new SgArrayRefExp(*rgv,*new SgValueExp(i)),new SgValueExp(0));
|
|
}
|
|
cur_st = stat;
|
|
}
|
|
|
|
void InitDebugVar()
|
|
{SgStatement *stcall;
|
|
int flag;
|
|
if(!dbg_var) return;
|
|
flag = (only_debug) ? 0 : 1;
|
|
doAssignTo_After(new SgVarRefExp(*dbg_var),new SgValueExp(dbg_if_regim));
|
|
cur_st->insertStmtAfter(*(stcall=D_PutDebugVarAdr(dbg_var,flag)));
|
|
cur_st = stcall;
|
|
}
|
|
|
|
void InitFileNameVariables()
|
|
{ filename_list *sl;
|
|
SgExpression *lenexp,*e;
|
|
int length;
|
|
SgFunctionSymb *fs = new SgFunctionSymb(FUNCTION_NAME, "char", *SgTypeChar(), *cur_func->controlParent());
|
|
SgFunctionCallExp *fcall = new SgFunctionCallExp(*fs);
|
|
fcall->addArg(* new SgValueExp(0));
|
|
if(filename_num>1 && cur_func->variant() != PROG_HEDR) {
|
|
file_var_s = new SgVariableSymb(FileNameVar(0), *SgTypeInt(), *cur_func);
|
|
cur_st = doIfForFileVariables(file_var_s);
|
|
}
|
|
for(sl=fnlist; sl; sl=sl->next){
|
|
length = strlen(sl->name)+1;
|
|
lenexp = new SgValueExp(length);
|
|
e = new SgExpression(ARRAY_OP);
|
|
e->setLhs(new SgVarRefExp(*sl->fns));
|
|
e->setRhs(new SgExpression(DDOT,lenexp,lenexp,(SgSymbol *)NULL));
|
|
doAssignTo_After( e, fcall);
|
|
}
|
|
if(filename_num>1 && cur_func->variant() != PROG_HEDR){
|
|
doAssignTo_After( new SgVarRefExp(*file_var_s), new SgValueExp(1));
|
|
cur_st = cur_st->lexNext();
|
|
}
|
|
}
|
|
|
|
|
|
void InitHeap(SgSymbol *heap)
|
|
//generating assign statement: HEAP(1) = 2
|
|
{ doAssignTo(ARRAY_ELEMENT(heap,1), new SgValueExp(2)); }
|
|
|
|
void InitAsyncid()
|
|
{symb_list *sl;
|
|
for(sl=async_symb; sl; sl=sl->next)
|
|
//generating assign statement: ASINCID(1) = 1
|
|
if((IN_COMMON(sl->symb) && IN_MAIN_PROGRAM) || !IN_COMMON(sl->symb))
|
|
doAssignTo(ARRAY_ELEMENT(sl->symb,1), new SgValueExp(1));
|
|
}
|
|
|
|
SgExpression * isDoVarUse (SgExpression *e, int use[], SgSymbol *ident[], int ni, int *num, SgStatement *st)
|
|
{
|
|
SgExpression *ei;
|
|
*num = AxisNumOfDummyInExpr(e, ident, ni, &ei, use, st);
|
|
if (*num<=0)
|
|
return(NULL);
|
|
return(ei);
|
|
}
|
|
|
|
SgSymbol* isIndirectSubscript (SgExpression *e, SgSymbol *ident, SgStatement *st)
|
|
{//temporary
|
|
if(e && ident && st)
|
|
return(NULL);
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
/*
|
|
void InsertRedVarsInGroup(SgExpression *redgref,int irv,int nred)
|
|
{int i;
|
|
for(i=irv+nred-1; i>=irv; i--)
|
|
doAssignStmtAfter(InsertRedVar(redgref,i,iplp));
|
|
}
|
|
*/
|
|
|
|
/*
|
|
void BeginDebugFragment(int num,SgStatement *stmt)
|
|
{fragment_list *curfr;
|
|
fragment_list_in *fr;
|
|
|
|
// searhing frament
|
|
fr=debug_fragment;
|
|
//looking through the fragment list of command line
|
|
while(fr && (fr->N1 > num || fr->N2 < num) )
|
|
fr=fr->next;
|
|
if (fr){ //fragment with number 'num' is found (N1 <= num <= N2)
|
|
if(fr->dlevel){
|
|
dvm_debug = 1;
|
|
level_debug = fr->dlevel;
|
|
}
|
|
if(fr->elevel)
|
|
perf_analysis = fr->elevel;
|
|
curfr = new fragment_list;
|
|
curfr->No = num;
|
|
if(fr->dlevel)
|
|
curfr->dlevel = fr->dlevel;
|
|
else
|
|
curfr->dlevel = cur_fragment ? cur_fragment->dlevel : 0;
|
|
if(fr->elevel)
|
|
curfr->elevel = fr->elevel;
|
|
else
|
|
curfr->elevel = cur_fragment ? cur_fragment->elevel : 0;
|
|
curfr->next = cur_fragment;
|
|
cur_fragment = curfr;
|
|
} else {//fragment with number 'num' is not found
|
|
curfr = new fragment_list;
|
|
curfr->No = num;
|
|
curfr->dlevel = cur_fragment ? cur_fragment->dlevel : 0;
|
|
curfr->elevel = cur_fragment ? cur_fragment->elevel : 0;
|
|
curfr->next = cur_fragment;
|
|
cur_fragment = curfr;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void BeginDebugFragment(int num, SgStatement *stmt)
|
|
{fragment_list *curfr;
|
|
fragment_list_in *fr;
|
|
int max_dlevel,max_elevel,is_max;
|
|
//determing maximal level
|
|
if(stmt)
|
|
is_max = MaxLevels(stmt,&max_dlevel,&max_elevel);
|
|
else
|
|
is_max =0;
|
|
|
|
// searhing fragment
|
|
fr=debug_fragment;
|
|
//looking through the fragment list of command line
|
|
while(fr && (fr->N1 > num || fr->N2 < num) )
|
|
fr=fr->next;
|
|
if (fr){ //fragment with number 'num' is found (N1 <= num <= N2)
|
|
if(fr->dlevel){
|
|
if(fr->dlevel == -1){
|
|
dvm_debug = 0;
|
|
level_debug = 0;
|
|
} else {
|
|
dvm_debug = 1;
|
|
level_debug = MinLevel(fr->dlevel,max_dlevel,is_max);
|
|
}
|
|
}
|
|
if(fr->elevel)
|
|
if(fr->elevel == -1)
|
|
perf_analysis = 0;
|
|
else
|
|
perf_analysis = MinLevel(fr->elevel,max_elevel,is_max);
|
|
curfr = new fragment_list;
|
|
curfr->No = num;
|
|
curfr->dlevel = level_debug;
|
|
curfr->elevel = perf_analysis;
|
|
curfr->next = cur_fragment;
|
|
cur_fragment = curfr;
|
|
} else {//fragment with number 'num' is not found
|
|
curfr = new fragment_list;
|
|
curfr->No = num;
|
|
curfr->dlevel = cur_fragment ? MinLevel(cur_fragment->dlevel,max_dlevel,is_max) : 0;
|
|
curfr->elevel = cur_fragment ? MinLevel(cur_fragment->elevel,max_elevel,is_max) : 0;
|
|
curfr->next = cur_fragment;
|
|
cur_fragment = curfr;
|
|
perf_analysis = curfr->elevel;
|
|
level_debug = curfr->dlevel;
|
|
dvm_debug = level_debug ? 1 : 0;
|
|
}
|
|
return;
|
|
}
|
|
*/
|
|
|
|
void BeginDebugFragment(int num, SgStatement *stmt)
|
|
{
|
|
fragment_list *curfr;
|
|
fragment_list_in *fr;
|
|
int max_dlevel, max_elevel, is_max, d_current, e_current, spec_dlevel, spec_elevel;
|
|
//determing maximal level of debugging and performance analyzing
|
|
if (stmt)
|
|
is_max = MaxLevels(stmt, &max_dlevel, &max_elevel);
|
|
else
|
|
{
|
|
is_max = 0;
|
|
max_dlevel = max_elevel = 4;
|
|
}
|
|
|
|
// level specified for surrounding fragment
|
|
d_current = cur_fragment ? cur_fragment->dlevel_spec : 0;
|
|
e_current = cur_fragment ? cur_fragment->elevel_spec : 0;
|
|
|
|
// searhing fragment in 2 lists
|
|
fr = debug_fragment;
|
|
//looking through the fragment list specified for debugging (-d) in command line
|
|
while (fr && (fr->N1 > num || fr->N2 < num))
|
|
fr = fr->next;
|
|
if (fr) //fragment with number 'num' is found (N1 <= num <= N2)
|
|
spec_dlevel = fr->level;
|
|
else
|
|
spec_dlevel = d_current;
|
|
|
|
fr = perf_fragment;
|
|
//looking through the fragment list specified for performance analyze (-e) in command line
|
|
while (fr && (fr->N1 > num || fr->N2 < num))
|
|
fr = fr->next;
|
|
if (fr) //fragment with number 'num' is found (N1 <= num <= N2)
|
|
spec_elevel = fr->level;
|
|
else
|
|
spec_elevel = e_current;
|
|
level_debug = MinLevel(spec_dlevel, max_dlevel, is_max);
|
|
dvm_debug = level_debug ? 1 : 0;
|
|
perf_analysis = MinLevel(spec_elevel, max_elevel, is_max);
|
|
curfr = new fragment_list;
|
|
curfr->No = num;
|
|
curfr->begin_st = stmt;
|
|
curfr->dlevel = level_debug;
|
|
curfr->elevel = perf_analysis;
|
|
curfr->dlevel_spec = spec_dlevel;
|
|
curfr->elevel_spec = spec_elevel;
|
|
curfr->next = cur_fragment;
|
|
cur_fragment = curfr;
|
|
}
|
|
|
|
int MinLevel(int level, int max, int is_max)
|
|
{
|
|
if (is_max)
|
|
return((level > max) ? max : level);
|
|
else
|
|
return(level);
|
|
}
|
|
|
|
int MaxLevels(SgStatement *stmt,int *max_dlevel,int *max_elevel)
|
|
{ SgExpression *el,*ee;
|
|
SgKeywordValExp *kwe;
|
|
int n,is_max;
|
|
*max_dlevel = 4;
|
|
*max_elevel = 4;
|
|
is_max =0;
|
|
for(el=stmt->expr(1); el; el = el->rhs()) {
|
|
ee = el->lhs();
|
|
kwe = isSgKeywordValExp(ee->lhs());
|
|
if (!strcmp(kwe->value(),"d")) {
|
|
if((ee->rhs()->variant() != INT_VAL) || (n=ee->rhs()->valueInteger()) < 0)
|
|
err("Illegal debug parameter",303,stmt);
|
|
else
|
|
{*max_dlevel = n; is_max = 1;}
|
|
}
|
|
else if (!strcmp(kwe->value(),"e")) {
|
|
if((ee->rhs()->variant() != INT_VAL) || (n=ee->rhs()->valueInteger()) < 0)
|
|
err("Illegal debug parameter",303,stmt);
|
|
else
|
|
{*max_elevel = n; is_max = 1;}
|
|
}
|
|
}
|
|
return(is_max);
|
|
}
|
|
|
|
void EndDebugFragment(int num)
|
|
{ if(!cur_fragment || cur_fragment->No != num) return;
|
|
cur_fragment = cur_fragment->next;
|
|
level_debug = cur_fragment->dlevel;
|
|
dvm_debug = level_debug ? 1 : 0;
|
|
perf_analysis = cur_fragment->elevel;
|
|
}
|
|
|
|
SgExpression *PointerArrElem(SgSymbol *p,SgStatement *stdis)
|
|
{
|
|
SgExpression *el;
|
|
for (el = stdis->expr(0); el; el = el->rhs())
|
|
if(el->lhs()->symbol() == p)
|
|
return(el->lhs());
|
|
return(NULL);
|
|
}
|
|
|
|
SgExpression *ReverseDim(SgExpression *desc,int rank)
|
|
{int i,ind;
|
|
SgExpression *e,*de;
|
|
ind = ndvm;
|
|
e = desc->lhs();
|
|
for(i= rank-1; i>=0; i--){
|
|
de = &(desc->copy());
|
|
if(e)
|
|
de->lhs()->setLhs(Calculate(&(e->lhs()->copy()+ *new SgValueExp(i))));
|
|
else
|
|
de->setLhs(new SgExprListExp(*new SgValueExp(i+1)));
|
|
doAssignStmt(de);
|
|
}
|
|
return(DVM000(ind));
|
|
}
|
|
/*
|
|
SgExpression *DoSubscriptList(SgExpression *are,int ind)
|
|
{return(new SgExprListExp(*new SgValueExp(ind)));}
|
|
*/
|
|
|
|
void EndReduction_Task_Region(SgStatement *stmt)
|
|
{
|
|
if(!stmt) return;
|
|
// actualizing of reduction variables
|
|
if(redgrefts)
|
|
ReductionVarsStart(task_red_list);
|
|
|
|
if(irgts) {
|
|
// generating call statement:
|
|
// call strtrd(RedGroupRef)
|
|
doCallAfter(StartRed(redgrefts));
|
|
|
|
// generating call statement:
|
|
// call waitrd(RedGroupRef)
|
|
doCallAfter(WaitRed(redgrefts));
|
|
/*ReductionVarsWait(red_list);*/
|
|
//if(idebrg){
|
|
// if(dvm_debug)
|
|
// doAssignStmtAfter( D_CalcRG(DVM000(idebrg)));
|
|
// doAssignStmtAfter( D_DelRG (DVM000(idebrg)));
|
|
// }
|
|
// generating assign statement:
|
|
// dvm000(i) = delobj(RedGroupRef)
|
|
doCallAfter(DeleteObject_H(redgrefts));
|
|
}
|
|
}
|
|
|
|
|
|
void Reduction_Task_Region(SgStatement *stmt)
|
|
{SgExpression *e;
|
|
SgStatement *st2, *st3;
|
|
|
|
irgts=0;
|
|
redgrefts=NULL;
|
|
e=stmt->expr(0);
|
|
if(!e) return;
|
|
task_red_list = e->lhs();
|
|
if( e->symbol()){
|
|
redgrefts = new SgVarRefExp(e->symbol());
|
|
doIfForReduction(redgrefts,0);
|
|
nloopred++;
|
|
//stcg = doIfForCreateReduction( e->symbol(),nloopcons,0);
|
|
st2 = doIfForCreateReduction( redgrefts->symbol(),nloopred,1);
|
|
st3 = cur_st;
|
|
cur_st = st2;
|
|
ReductionList(task_red_list,redgrefts,stmt,st2,st2,0);
|
|
cur_st = st3;
|
|
InsertNewStatementAfter( new SgAssignStmt(*DVM000(ndvm),*new SgValueExp(0)),cur_st,cur_st->controlParent());
|
|
|
|
} else {
|
|
irgts = ndvm;
|
|
redgrefts = DVM000(irgts);
|
|
doAssignStmtAfter(CreateReductionGroup());
|
|
//!!!??? if(debug_regim){
|
|
// idebcg = ndvm;
|
|
// doAssignStmtAfter( D_CreateDebRedGroup());
|
|
//}
|
|
|
|
ReductionList(task_red_list,redgrefts,stmt,cur_st,cur_st,0);
|
|
}
|
|
}
|
|
|
|
|
|
int NumberOfElements(SgSymbol *sym, SgStatement *stmt, int err)
|
|
{int i,rank,nm;
|
|
SgExpression *esize,*numb,*pe;
|
|
SgArrayType *artype;
|
|
SgValueExp c1(1);
|
|
SgSubscriptExp *sbe;
|
|
artype=isSgArrayType(sym->type());
|
|
if(artype)
|
|
rank = artype->dimension();//array
|
|
else
|
|
return(1); //scalar variable
|
|
numb = &c1;
|
|
for(i=1; i<=rank; i++) { //array
|
|
//calculating size of i-th dimension
|
|
pe = artype->sizeInDim(i-1);
|
|
if ((sbe=isSgSubscriptExp(pe)) != NULL){ // [lbound] : [ubound]
|
|
|
|
if(err && !sbe->ubound()){ // [lbound] :
|
|
Error("Assumed-shape or deffered-shape array: %s",sym->identifier(), 295, stmt);
|
|
esize = &(pe->copy());
|
|
}
|
|
else if(err && sbe->ubound()->variant() == STAR_RANGE) // ubound = *
|
|
Error("Assumed-size array: %s",sym->identifier(), 162, stmt);
|
|
|
|
esize = &(((sbe->ubound())->copy()) - (sbe->lbound() ? (sbe->lbound())->copy() : c1 ) + c1);
|
|
|
|
} else { // ubound
|
|
if(err && pe->variant() == STAR_RANGE) // dim=ubound = *
|
|
Error("Assumed-size array: %s",sym->identifier(), 162, stmt);
|
|
esize = &(pe->copy());
|
|
}
|
|
if(esize)
|
|
numb = &(*numb * (*esize));
|
|
}
|
|
numb = ReplaceParameter(numb);
|
|
if (numb->isInteger()) // calculating length if it is possible
|
|
nm = numb->valueInteger();
|
|
else
|
|
{ Error("Can't calculate array length: %s",sym->identifier(),194,stmt);
|
|
nm = 1;
|
|
if(err == 2) nm=0;
|
|
}
|
|
return(nm);
|
|
}
|
|
|
|
|
|
SgExpression * HeapIndex(SgStatement *st)
|
|
{SgSymbol *s;
|
|
SgExpression *e;
|
|
SgArrayType *artype;
|
|
int rank;
|
|
s = st->expr(0)->symbol();
|
|
artype=isSgArrayType(s->type());
|
|
if(!artype)
|
|
return(new SgValueExp(POINTER_INDEX(s)));
|
|
|
|
rank = artype->dimension();
|
|
|
|
if(rank == 1) {
|
|
e =&(*new SgValueExp(POINTER_INDEX(s)) + (*st->expr(0)->lhs()->lhs() - *LowerBoundOfDimension(artype,0))* ( *new SgValueExp(HEADER_SIZE(s))));
|
|
return(e);
|
|
}
|
|
return(new SgValueExp(POINTER_INDEX(s)));
|
|
}
|
|
|
|
SgExpression * LowerBoundOfDimension(SgArrayType *artype, int i)
|
|
{ SgExpression *e,*eb;
|
|
SgSubscriptExp *sbe;
|
|
e = artype->sizeInDim(i);
|
|
if(!e) // pointer declaration error
|
|
return(new SgValueExp(1));
|
|
if((sbe=isSgSubscriptExp(e)) != NULL)
|
|
eb = & (sbe->lbound()->copy());
|
|
else
|
|
eb = new SgValueExp(1); // by default lower bound = 1
|
|
return(eb);
|
|
}
|
|
|
|
|
|
|
|
SgExpression *AsyncArrayElement(SgExpression *asc, SgExpression *ei)
|
|
{SgArrayRefExp *e;
|
|
e = new SgArrayRefExp(*ORIGINAL_SYMBOL(asc->symbol()),*ei);
|
|
if(asc->lhs())
|
|
e->addSubscript(asc->lhs()->copy());
|
|
return(e);
|
|
}
|
|
|
|
void AsyncCopyWait(SgExpression * asc)
|
|
{SgForStmt *dost;
|
|
SgStatement *as,*st;
|
|
SgExpression *eas;
|
|
SgLabel *loop_lab;
|
|
int i;
|
|
st = cur_st;
|
|
|
|
//doAssignTo_After(ARRAY_ELEMENT(asc,1),new SgValueExp(1));
|
|
doAssignTo_After(AsyncArrayElement(asc,new SgValueExp(1)),new SgValueExp(1));
|
|
nio = (nio <1) ? 1 : nio;
|
|
//eas = new SgArrayRefExp(*asc,*new SgVarRefExp(*loop_var[0]));
|
|
eas = AsyncArrayElement(asc, new SgVarRefExp(*loop_var[0]));
|
|
i = ndvm++;
|
|
loop_lab = GetLabel();
|
|
as = new SgAssignStmt(*DVM000(i),*WaitCopy(eas));
|
|
//dost= new SgForStmt(loop_var[0], new SgValueExp(2), ARRAY_ELEMENT(asc,1), new SgValueExp(1), as);
|
|
dost= new SgForStmt(loop_var[0], new SgValueExp(2), AsyncArrayElement(asc,new SgValueExp(1)), new SgValueExp(1), as);
|
|
BIF_LABEL_USE(dost->thebif) = loop_lab->thelabel;
|
|
as->setLabel(*loop_lab);
|
|
InsertNewStatementAfter(dost, st, st->controlParent());
|
|
as->lexNext()->extractStmt();
|
|
cur_st = as;
|
|
|
|
SET_DVM(i);
|
|
}
|
|
|
|
int isWholeArray(SgExpression *ae)
|
|
{
|
|
if(!isSgArrayRefExp(ae))
|
|
return (0);
|
|
for(SgExpression *el=ae->lhs(); el; el=el->rhs())
|
|
{
|
|
if(el->lhs()->variant() != DDOT)
|
|
return (0);
|
|
if(el->lhs()->lhs() || el->lhs()->rhs())
|
|
return (0);
|
|
continue;
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
int DistrArrayAssign(SgStatement *stmt)
|
|
{SgExpression *le,*re,*headl,*headr;
|
|
int to_init,rl,from_init,rr,dvm_ind,left_whole,right_whole;
|
|
SgSymbol *ar;
|
|
SgType *typel,*typer;
|
|
|
|
re = stmt->expr(1);
|
|
le = stmt->expr(0);
|
|
if(!isSgArrayRefExp(le))
|
|
return(0);
|
|
if(!isSgArrayType(le->type()))
|
|
return(0);
|
|
if(isSgArrayType(re->type()))
|
|
if(!isSgArrayRefExp(re))
|
|
return(0);
|
|
else
|
|
// assignment statement of kind: <dvm_array_section> = <array_section>
|
|
{
|
|
if(only_debug)
|
|
return(1);
|
|
left_whole = !le->lhs();
|
|
right_whole = !re->lhs();
|
|
CANCEL_RTS2_MODE; // switch to basic RTS interface
|
|
ChangeDistArrayRef(le->lhs()); //replacing dvm-array references in subscript list
|
|
ChangeDistArrayRef(re->lhs());
|
|
LINE_NUMBER_BEFORE(stmt,stmt);
|
|
cur_st = stmt;
|
|
dvm_ind = 0;
|
|
ar = le->symbol();
|
|
rl = Rank(ar);
|
|
typel = ar->type()->baseType();
|
|
headl = HeaderRef(ar);
|
|
|
|
SgExpression *left_section_list = ArraySection(le,ar,rl,stmt,to_init);
|
|
ar = re->symbol();
|
|
typer = ar->type()->baseType();
|
|
if(!CompareTypes(typel,typer))
|
|
err("Different types of left and right side",620,stmt);
|
|
rr = Rank(ar);
|
|
headr = HeaderRef(ar);
|
|
if(!headr)
|
|
{ //Warning("'%s' isn't distributed array", ar->identifier(), 72,stmt);
|
|
/*
|
|
if(re->lhs()) // section
|
|
{ dvm_ind = HeaderForNonDvmArray(ar,stmt);
|
|
headr = DVM000(dvm_ind);
|
|
} else // whole array
|
|
headr = FirstElementOfSection(re);
|
|
*/
|
|
dvm_ind = HeaderForNonDvmArray(ar,stmt);
|
|
headr = DVM000(dvm_ind);
|
|
}
|
|
SgExpression *right_section_list = ArraySection(re,ar,rr,stmt,from_init);
|
|
if(INTERFACE_RTS2)
|
|
{
|
|
if(left_whole && right_whole) // whole-array = whole-array
|
|
doCallAfter(DvmhArrayCopyWhole(headr,headl));
|
|
else
|
|
doCallAfter(DvmhArrayCopy(headr,rr,right_section_list,headl,rl,left_section_list));
|
|
}
|
|
else
|
|
doAssignStmtAfter(ArrayCopy(headr, from_init, from_init+rr, from_init+2*rr, headl, to_init, to_init+rl, to_init+2*rl, 0));
|
|
if(dvm_ind)
|
|
doCallAfter(DeleteObject_H(DVM000(dvm_ind)));
|
|
SET_DVM(to_init);
|
|
RESUMPTION_RTS2_MODE; // return to RTS2 interface
|
|
return(1);
|
|
}
|
|
|
|
// assignment statement of kind: <dvm_array_section> = <scalar_expression>
|
|
if(only_debug)
|
|
return(1);
|
|
CANCEL_RTS2_MODE; // switch to basic RTS interface
|
|
if(INTERFACE_RTS2 && !isWholeArray(stmt->expr(0)))
|
|
err("Illegal array statement in -Opl2 mode", 642, stmt);
|
|
|
|
ChangeDistArrayRef(stmt->expr(0)->lhs()); //replacing dvm-array references in subscript list
|
|
ChangeDistArrayRef(stmt->expr(1));
|
|
|
|
LINE_NUMBER_BEFORE(stmt,stmt);
|
|
cur_st = stmt;
|
|
ar = le->symbol();
|
|
rl = Rank(ar);
|
|
headl = HeaderRef(ar);
|
|
typel = ar->type()->baseType();
|
|
headr = TypeFunction(typel,re,KINDFunction(new SgArrayRefExp(*baseMemory(ar->type()->baseType()))));
|
|
SgExpression *left_section_list = ArraySection(le,ar,rl,stmt,to_init);
|
|
if(INTERFACE_RTS2)
|
|
doCallAfter(DvmhArraySetValue(headl,headr));
|
|
else
|
|
doAssignStmtAfter(ArrayCopy(headr, to_init, to_init, to_init, headl, to_init, to_init+rl, to_init+2*rl, -1));
|
|
SET_DVM(to_init);
|
|
RESUMPTION_RTS2_MODE; // return to RTS2 interface
|
|
return(1);
|
|
}
|
|
|
|
int AssignDistrArray(SgStatement *stmt)
|
|
{SgExpression *le,*re,*headl,*headr;
|
|
int to_init,rl,from_init,rr,dvm_ind,left_whole,right_whole;
|
|
SgSymbol *ar;
|
|
SgType *typel,*typer;
|
|
re = stmt->expr(1);
|
|
le = stmt->expr(0);
|
|
if(!isSgArrayRefExp(le) || !isSgArrayType(le->type()))
|
|
return(0);
|
|
if(!isSgArrayRefExp(re) || !isSgArrayType(re->type()) || !IS_DVM_ARRAY(re->symbol()))
|
|
return(0);
|
|
|
|
// assignment statement of kind: <array_section> = <dvm_array_section>
|
|
if(only_debug)
|
|
return(1);
|
|
CANCEL_RTS2_MODE; // switch to basic RTS interface
|
|
left_whole = !le->lhs();
|
|
right_whole = !re->lhs();
|
|
|
|
ChangeDistArrayRef(stmt->expr(0)->lhs()); //replacing dvm-array references in subscript list
|
|
ChangeDistArrayRef(stmt->expr(1)->lhs());
|
|
|
|
LINE_NUMBER_BEFORE(stmt,stmt); //LINE_NUMBER_AFTER(stmt,stmt);
|
|
cur_st = stmt;
|
|
ar = le->symbol();
|
|
typel = ar->type()->baseType();
|
|
//Warning("'%s' isn't distributed array", ar->identifier(), 72,stmt);
|
|
rl = Rank(ar);
|
|
/*
|
|
if(le->lhs()) // section
|
|
{ dvm_ind = HeaderForNonDvmArray(ar,stmt);
|
|
headl = DVM000(dvm_ind);
|
|
} else // whole array
|
|
{ dvm_ind = 0;
|
|
headl = FirstElementOfSection(le);
|
|
}
|
|
*/
|
|
dvm_ind = HeaderForNonDvmArray(ar,stmt);
|
|
headl = DVM000(dvm_ind);
|
|
SgExpression *left_section_list = ArraySection(le,ar,rl,stmt,to_init);
|
|
ar = re->symbol();
|
|
typer = ar->type()->baseType();
|
|
rr = Rank(ar);
|
|
headr = HeaderRef(ar);
|
|
if(!headr) { // if there is error of dvm-array specification, header is not created
|
|
RESUMPTION_RTS2_MODE; // return to RTS2 interface
|
|
return(0);
|
|
}
|
|
if(!CompareTypes(typel,typer))
|
|
err("Different types of left and right side",620,stmt);
|
|
|
|
SgExpression *right_section_list = ArraySection(re,ar,rr,stmt,from_init);
|
|
if(INTERFACE_RTS2)
|
|
{
|
|
if(left_whole && right_whole) // whole-array = whole-array
|
|
doCallAfter(DvmhArrayCopyWhole(headr,headl));
|
|
else
|
|
doCallAfter(DvmhArrayCopy(headr,rr,right_section_list,headl,rl,left_section_list));
|
|
}
|
|
else
|
|
doAssignStmtAfter(ArrayCopy(headr, from_init, from_init+rr, from_init+2*rr, headl, to_init, to_init+rl, to_init+2*rl, 0));
|
|
|
|
if(dvm_ind)
|
|
doCallAfter(DeleteObject_H(DVM000(dvm_ind)));
|
|
|
|
SET_DVM(dvm_ind ? dvm_ind : to_init) ; //SET_DVM(to_init);
|
|
RESUMPTION_RTS2_MODE; // return to RTS2 interface
|
|
return(1);
|
|
}
|
|
|
|
SgExpression *ArraySection(SgExpression *are, SgSymbol *ar, int rank, SgStatement *stmt, int &init)
|
|
{
|
|
SgExpression *el,*einit[MAX_DIMS],*elast[MAX_DIMS],*estep[MAX_DIMS];
|
|
SgExpression *section_list = NULL;
|
|
int i,j;
|
|
init = ndvm;
|
|
if(!are->lhs()) { //MakeSection(are); // A => A(:,:, ...,:)
|
|
if(INTERFACE_RTS2)
|
|
MakeSection(are); // A => A(:,:, ...,:)
|
|
else {
|
|
for(j=rank; j; j--)
|
|
doAssignStmtAfter(Calculate(new SgValueExp(-1)));
|
|
ndvm += 2*rank;
|
|
return (section_list);//return(init);
|
|
}
|
|
}
|
|
if(!TestMaxDims(are->lhs(),ar,stmt)) return(0);
|
|
for(el=are->lhs(),i=0; el; el=el->rhs(),i++)
|
|
Triplet(el->lhs(),ar,i, einit,elast,estep);
|
|
if(i != rank){
|
|
Error("Wrong number of subscripts specified for '%s'",ar->identifier(),140 ,stmt);
|
|
//return (0);
|
|
}
|
|
if(INTERFACE_RTS2)
|
|
for(j=0; j<i; j++) //reversing dimensions for LibDVM
|
|
{
|
|
section_list = AddElementToList(section_list, DvmType_Ref(estep[j]));
|
|
section_list = AddElementToList(section_list, DvmType_Ref(elast[j]));
|
|
section_list = AddElementToList(section_list, DvmType_Ref(einit[j]));
|
|
}
|
|
else {
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(einit[j-1]));
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(elast[j-1]));
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(estep[j-1]);
|
|
}
|
|
return (section_list); //return(init);
|
|
}
|
|
|
|
void AsynchronousCopy(SgStatement *stmt)
|
|
{SgExpression *le,*re,*el,*einit[MAX_DIMS],*elast[MAX_DIMS],*estep[MAX_DIMS],*headl,*headr,*flag,*ec;
|
|
int j,i,from_init,to_init,rl,rr;
|
|
SgSymbol *ar,*ar1;
|
|
SgType *typel,*typer;
|
|
if(!async_id)
|
|
return;
|
|
LINE_NUMBER_BEFORE(stmt,stmt); //moving the label if present
|
|
ec = AsyncArrayElement(async_id, new SgValueExp(1));
|
|
flag = AsyncArrayElement(async_id, ec);
|
|
doAssignTo_After(ec, &(*ec + (*new SgValueExp(1))));
|
|
|
|
re = stmt->expr(1);
|
|
if(!isSgArrayRefExp(re)) {
|
|
err("Illegal statement in ASYNCHRONOS_ENDASYNCHRONOUS block",901,stmt);
|
|
return;
|
|
}
|
|
|
|
ar = re->symbol();
|
|
typer = ar->type()->baseType();
|
|
ar1=ar;
|
|
rr = Rank(ar);
|
|
headr = HeaderRef(ar);
|
|
if(!TestMaxDims(re->lhs(),ar,stmt)) return;
|
|
if(!re->lhs()) MakeSection(re); // A => A(:,:, ...,:)
|
|
for(el=re->lhs(),i=0; el; el=el->rhs(),i++)
|
|
Triplet(el->lhs(),ar,i, einit,elast,estep);
|
|
if(i != rr){
|
|
Error("Wrong number of subscripts specified for '%s'",ar->identifier(),140 ,stmt);
|
|
return;
|
|
}
|
|
from_init = ndvm;
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(einit[j-1]));
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(elast[j-1]));
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(estep[j-1]);
|
|
|
|
le = stmt->expr(0);
|
|
if(!isSgArrayRefExp(le)) {
|
|
err("Illegal statement in ASYNCHRONOS_ENDASYNCHRONOUS block",901,stmt);
|
|
return;
|
|
}
|
|
ar = le->symbol();
|
|
rl = Rank(ar);
|
|
typel = ar->type()->baseType();
|
|
if(!CompareTypes(typel,typer))
|
|
err("Different types of left and right side",620,stmt);
|
|
headl = HeaderRef(ar);
|
|
if(!TestMaxDims(le->lhs(),ar,stmt)) return;
|
|
if(!le->lhs()) MakeSection(le); // A => A(:,:, ...,:)
|
|
for(el=le->lhs(),i=0; el; el=el->rhs(),i++)
|
|
Triplet(el->lhs(),ar,i, einit,elast,estep);
|
|
if(i != rl){
|
|
Error("Wrong number of subscripts specified for '%s'",ar->identifier(),140 ,stmt);
|
|
return;
|
|
}
|
|
to_init = ndvm;
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(einit[j-1]));
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(elast[j-1]));
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(estep[j-1]);
|
|
|
|
if(!headr && !headl) {
|
|
err("Both arrays are not distributed", 297,stmt);
|
|
return;
|
|
} else if(!headr) {
|
|
Warning("'%s' isn't distributed array", ar1->identifier(), 72,stmt);
|
|
headr = FirstElementOfSection(re);
|
|
} else if(!headl) {
|
|
Warning("'%s' isn't distributed array", ar->identifier(), 72,stmt);
|
|
headl = FirstElementOfSection(le);
|
|
}
|
|
|
|
doAssignStmtAfter(AsyncArrayCopy(headr, from_init, from_init+rr, from_init+2*rr, headl, to_init, to_init+rl, to_init+2*rl, 0, flag));
|
|
|
|
SET_DVM(from_init);
|
|
}
|
|
|
|
void Triplet(SgExpression *e,SgSymbol *ar,int i, SgExpression *einit[],SgExpression *elast[],SgExpression *estep[])
|
|
{SgValueExp c1(1),c0(0);
|
|
|
|
if(e->variant() != DDOT) { //is not triplet
|
|
einit[i] = INTERFACE_RTS2 ? e : &(*e-*Exprn(LowerBound(ar,i)));
|
|
elast[i] = einit[i];
|
|
estep[i] = &c1.copy();
|
|
return;
|
|
}
|
|
// is triplet
|
|
|
|
if(e->lhs() && e->lhs()->variant() == DDOT) { // there is step
|
|
estep[i] = e->rhs();
|
|
e = e->lhs();
|
|
} else
|
|
estep[i] = &c1.copy();
|
|
if (!e->lhs())
|
|
einit[i] = INTERFACE_RTS2 ? ConstRef_F95(-2147483648) : &c0.copy();
|
|
else
|
|
einit[i] = INTERFACE_RTS2 ? e->lhs() : &(*(e->lhs())-*Exprn(LowerBound(ar,i)));
|
|
if (!e->rhs())
|
|
elast[i] = INTERFACE_RTS2 ? ConstRef_F95(-2147483648) : &(*Exprn(UpperBound(ar,i))-*Exprn(LowerBound(ar,i)));
|
|
else
|
|
elast[i] = INTERFACE_RTS2 ? e->rhs() : &(*(e->rhs())-*Exprn(LowerBound(ar,i)));
|
|
|
|
return;
|
|
}
|
|
|
|
void LowerBoundInTriplet(SgExpression *e,SgSymbol *ar,int i, SgExpression *einit[])
|
|
{
|
|
SgValueExp c1(1),c0(0);
|
|
if(e->variant() != DDOT) { //is not triplet
|
|
einit[i] = &(e->copy());
|
|
return;
|
|
}
|
|
// is triplet
|
|
if(e->lhs() && e->lhs()->variant() == DDOT) // there is step
|
|
e = e->lhs();
|
|
e = e->lhs();
|
|
if (!e)
|
|
einit[i] = Exprn(LowerBound(ar,i)); //new SgValueExp(1);
|
|
else
|
|
einit[i] = &(e->copy());
|
|
return;
|
|
}
|
|
|
|
|
|
void UpperBoundInTriplet(SgExpression *e,SgSymbol *ar,int i, SgExpression *einit[])
|
|
{
|
|
//SgValueExp c1(1),c0(0);
|
|
if(e->variant() != DDOT) { //is not triplet
|
|
einit[i] = &(e->copy());
|
|
return;
|
|
}
|
|
// is triplet
|
|
if(e->lhs() && e->lhs()->variant() == DDOT) // there is step
|
|
e = e->lhs();
|
|
e = e->rhs();
|
|
if (!e)
|
|
einit[i] = Exprn(UpperBound(ar,i));
|
|
else
|
|
einit[i] = &(e->copy());
|
|
return;
|
|
}
|
|
|
|
|
|
int doSectionIndex(SgExpression *esec, SgSymbol *ar, SgStatement *st, int idv[], int ileft, SgExpression *lrec[], SgExpression *rrec[])
|
|
{int i, j, rank, isec, ilow, ihi;
|
|
SgExpression *el,*einit[MAX_DIMS],*elast[MAX_DIMS],*estep[MAX_DIMS];
|
|
SgValueExp cM1(-1);
|
|
rank = Rank(ar);
|
|
isec = ndvm;
|
|
for(j=rank; j; j--)
|
|
doAssignStmtAfter(&cM1);
|
|
if(! esec->lhs()) { //no array section
|
|
idv[0] = isec;
|
|
idv[1] = idv[0];
|
|
} else {
|
|
if(!TestMaxDims(esec->lhs(),ar,st)) return (0);
|
|
for(el=esec->lhs(),i=0; el; el=el->rhs(),i++) //looking through the section index list
|
|
Triplet(el->lhs(),ar,i, einit,elast,estep);
|
|
if(i != rank){
|
|
Error("Wrong number of subscripts specified for '%s'",ar->identifier(),140 ,st);
|
|
return(0);
|
|
}
|
|
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(einit[j-1]));
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(elast[j-1]));
|
|
|
|
idv[0] = isec+rank;
|
|
idv[1] = isec+2*rank;
|
|
}
|
|
if(!esec->rhs()){
|
|
idv[2] = isec;
|
|
idv[3] = ileft;
|
|
idv[4] = isec;
|
|
idv[5] = ileft+rank;
|
|
return(1);
|
|
}
|
|
ilow=ndvm;
|
|
if(!esec->rhs()->lhs()) {//no low shadow section
|
|
idv[2] = isec;
|
|
idv[3] = ileft;
|
|
} else {
|
|
if(!TestMaxDims(esec->rhs()->lhs(),ar,st)) return (0);
|
|
for(el=esec->rhs()->lhs(),i=0; el; el=el->rhs(),i++)//looking through the section index list
|
|
ShadowSectionTriplet(el->lhs(), i, einit,elast,estep,lrec,rrec,0);
|
|
if(i != rank){
|
|
Error("Wrong number of subscripts specified for '%s'",ar->identifier(),140 ,st);
|
|
return(0);
|
|
}
|
|
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(einit[j-1]));
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(elast[j-1]));
|
|
|
|
idv[2] = ilow;
|
|
idv[3] = ilow+rank;
|
|
}
|
|
ihi=ndvm;
|
|
if(!esec->rhs()->rhs()) {//no high shadow section
|
|
idv[4] = isec;
|
|
idv[5] = ileft+rank;
|
|
} else {
|
|
if(!TestMaxDims(esec->rhs()->rhs(),ar,st)) return (0);
|
|
for(el=esec->rhs()->rhs(),i=0; el; el=el->rhs(),i++)//looking through the section index list
|
|
ShadowSectionTriplet(el->lhs(), i, einit,elast,estep,lrec,rrec,1);
|
|
if(i != rank){
|
|
Error("Wrong number of subscripts specified for '%s'",ar->identifier(),140 ,st);
|
|
return(0);
|
|
}
|
|
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(einit[j-1]));
|
|
for(j=i; j; j--)
|
|
doAssignStmtAfter(Calculate(elast[j-1]));
|
|
|
|
idv[4] = ihi;
|
|
idv[5] = ihi+rank;
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
void ShadowSectionTriplet(SgExpression *e, int i, SgExpression *einit[], SgExpression *elast[], SgExpression *estep[], SgExpression *lrec[], SgExpression *rrec[], int flag)
|
|
{SgValueExp c1(1),c0(0),cM1(-1);
|
|
|
|
if(e->variant() != DDOT) { //is not triplet
|
|
einit[i] = &(*e-c1.copy());
|
|
elast[i] = einit[i];
|
|
estep[i] = &c1.copy();
|
|
return;
|
|
}
|
|
// is triplet
|
|
|
|
if(e->lhs() && e->lhs()->variant() == DDOT) { // there is step
|
|
estep[i] = e->rhs();
|
|
e = e->lhs();
|
|
} else
|
|
estep[i] = &c1.copy();
|
|
|
|
if(!e->lhs() && !e->rhs()) {
|
|
einit[i] = &cM1.copy();
|
|
elast[i] = (flag == 0 )? lrec[i] : rrec[i];
|
|
return;
|
|
}
|
|
if(!e->lhs())
|
|
einit[i] = &c0.copy();
|
|
else
|
|
einit[i] = &(*(e->lhs())- c1.copy());
|
|
if (!e->rhs())
|
|
elast[i] = &(((flag == 0 )? *lrec[i] : *rrec[i]) - c1.copy());
|
|
else
|
|
elast[i] = &(*(e->rhs()) - c1.copy());
|
|
|
|
return;
|
|
}
|
|
|
|
void DeleteShadowGroups(SgStatement *stmt)
|
|
{ group_name_list *sl;
|
|
//int i;
|
|
//i=0;
|
|
for(sl=grname; sl; sl=sl->next)
|
|
//if(!IS_SAVE(sl->symb)) /*podd 18.09.07*/
|
|
if (sl->symb->variant() == SHADOW_GROUP_NAME){
|
|
//if(i == 0)
|
|
//{ LINE_NUMBER_BEFORE(stmt,stmt);}
|
|
//i++;
|
|
doIfForDelete(sl->symb,stmt);
|
|
}
|
|
}
|
|
|
|
void DeleteLocTemplate(SgStatement *stmt)
|
|
{symb_list *sl;
|
|
SgExpression *e;
|
|
//if(loc_templ_symb)
|
|
//{ LINE_NUMBER_BEFORE(stmt,stmt);}
|
|
for(sl=loc_templ_symb; sl; sl=sl->next){
|
|
e = HeaderRef(sl->symb);
|
|
if(e)
|
|
InsertNewStatementBefore(DeleteObject_H(e),stmt);
|
|
}
|
|
}
|
|
|
|
void RegistrationList(SgStatement *stmt)
|
|
{ SgExpression *el;
|
|
SgSymbol * s;
|
|
int is_assign;
|
|
is_assign =0;
|
|
for(el=stmt->expr(0); el; el=el->rhs()) {
|
|
if(el->lhs()->variant() == ASSGN_OP || el->lhs()->variant() == POINTST_OP) is_assign = 1;//with initial value
|
|
s = el->lhs()->symbol();
|
|
if(debug_regim && s && IS_ARRAY(s))
|
|
registration = AddNewToSymbList( registration, s);
|
|
}
|
|
if(is_assign && stmt->variant() == VAR_DECL && !stmt->expr(2))
|
|
stmt->setVariant(VAR_DECL_90);
|
|
return;
|
|
}
|
|
|
|
SgExpression *DebReductionGroup(SgSymbol *gs)
|
|
{
|
|
SgSymbol *rgv;
|
|
SgExpression *rgvref;
|
|
rgv = * ((SgSymbol **) (ORIGINAL_SYMBOL(gs)) -> attributeValue(0,RED_GROUP_VAR));
|
|
rgvref = new SgArrayRefExp(*rgv,*new SgValueExp(0));
|
|
return(rgvref);
|
|
}
|
|
|
|
void EndOfProgramUnit(SgStatement *stmt, SgStatement *func, int begin_block)
|
|
{
|
|
if(func->variant() == PROG_HEDR) { // for MAIN program
|
|
SgStatement *where_st = stmt;
|
|
if(begin_block)
|
|
where_st = EndBlock_H(stmt);
|
|
ExitDataRegionForVariablesInMainProgram(where_st); /*ACC*/
|
|
RTLExit(stmt);
|
|
}
|
|
else if (func->variant() == PROC_HEDR || func->variant() == FUNC_HEDR) {
|
|
SgStatement *stat = stmt;
|
|
if(begin_block)
|
|
stat = EndBlock_H(stmt);
|
|
else
|
|
DeleteShadowGroups(stmt);
|
|
if(loc_templ_symb)
|
|
DeleteLocTemplate(stmt);
|
|
acc_return_list = addToStmtList(acc_return_list,stat); //save the point to insert RTSH-calls:dvmh_data_exit
|
|
}
|
|
}
|
|
void InitBaseCoeffs()
|
|
{
|
|
if(opt_base && !HPF_program && dsym) {
|
|
symb_list *sl;
|
|
coeffs * c;
|
|
SgExpression *e,*el;
|
|
SgType *t;
|
|
for(sl=dsym; sl; sl=sl->next) {
|
|
c = AR_COEFFICIENTS(sl->symb); //((coeffs *) sl->symb-> attributeValue(0,ARRAY_COEF));
|
|
if(!c->use)
|
|
continue;
|
|
e = new SgVarRefExp(*(c->sc[1]));
|
|
t = sl->symb->type()->baseType();
|
|
el = &((*GetAddresMem( new SgArrayRefExp(*baseMemory(t),*new SgValueExp(0))) - *GetAddresMem( new SgArrayRefExp(**ARRAY_BASE_SYMBOL(sl->symb),*new SgValueExp(0)))) / *new SgValueExp(TypeSize(t)));
|
|
|
|
doAssignTo_After(e, el);
|
|
// rank=Rank(sl->symb);
|
|
//for(i=1;i<=rank;i++){
|
|
// eel = new SgExprListExp(* new SgVarRefExp(*(c->sc[1])));
|
|
}
|
|
}
|
|
}
|
|
|
|
void CreateIndexVariables(SgExpression *dol)
|
|
{SgExpression *dovar;
|
|
// looking through the do_variables list
|
|
for(dovar=dol; dovar; dovar=dovar->rhs())
|
|
if(!(INDEX_SYMBOL(dovar->lhs()->symbol()))){
|
|
SgSymbol **s = new (SgSymbol *);
|
|
//creating new variable
|
|
*s = IndexSymbol(dovar->lhs()->symbol());
|
|
// adding the attribute (INDEX_DELTA) to do-variable symbol
|
|
(dovar->lhs()->symbol())->addAttribute(INDEX_DELTA, (void*) s, sizeof(SgSymbol *));
|
|
index_symb = AddToSymbList(index_symb,*s);
|
|
}
|
|
}
|
|
|
|
void doAssignIndexVar(SgExpression *dol,int iout, SgExpression *init[])
|
|
{SgExpression *dovar;
|
|
int i;
|
|
// looking through the do_variables list
|
|
for(dovar=dol,i=0; dovar; dovar=dovar->rhs(),i++){
|
|
if(INDEX_SYMBOL(dovar->lhs()->symbol()))
|
|
doAssignTo_After(new SgVarRefExp(*INDEX_SYMBOL(dovar->lhs()->symbol())),&(*DVM000(iout+i) - init[i]->copy()));
|
|
}
|
|
}
|
|
|
|
SgExpression *TestDVMArrayRef(SgExpression *e)
|
|
{SgExpression *dovar, *vl, *ei, *el, *coeff, *cons, *eop;
|
|
SgSymbol *dim_ident[MAX_DIMS];
|
|
int i,j,k,n,num,use[MAX_DIMS],is;
|
|
sum_dvm = NULL;
|
|
is = isInSymbList(dvm_ar,e->symbol());
|
|
|
|
if(!HEADER(e->symbol())) return(NULL);
|
|
n = Rank(e->symbol());
|
|
sum_dvm = coef_ref(e->symbol(),n+2);
|
|
vl = parallel_dir->expr(2); // do_variables list of PARALLEL directive
|
|
for(dovar=vl,i=0; dovar; dovar=dovar->rhs(),i++){
|
|
dim_ident[i] = dovar->lhs()->symbol();
|
|
//fprintf(stderr,"%s\n",dovar->lhs()->symbol()->identifier());
|
|
use[i] = 0;
|
|
}
|
|
//fprintf(stderr,"%d\n",i);
|
|
for(el=e->lhs(),k=n+1;el;el=el->rhs(),k--){
|
|
//fprintf(stderr,"%d\n",k);
|
|
for(j=0;j<i;j++)
|
|
use[j] = 0;
|
|
num=AxisNumOfDummyInExpr(el->lhs(),dim_ident,i,&ei,use,NULL);
|
|
//fprintf(stderr,"num%d\n",num);
|
|
if(num<0){
|
|
Warning("Maybe incorrect subscript of DVM-array reference: %s",e->symbol()->identifier(),332,cur_st);
|
|
return(NULL);
|
|
}
|
|
if(num == 0) continue;
|
|
CoeffConst(el->lhs(),ei,&coeff,&cons);
|
|
if(!coeff){
|
|
Warning("Maybe incorrect subscript of DVM-array reference: %s",e->symbol()->identifier(),332,cur_st);
|
|
return(NULL);
|
|
}
|
|
eop = new SgVarRefExp(*INDEX_SYMBOL(dim_ident[num-1]));
|
|
|
|
if(k!=(n+1)){
|
|
eop = &((*coef_ref(e->symbol(),k))* (*eop));
|
|
// fprintf(stderr,"%d\n",k);
|
|
}
|
|
if(coeff->isInteger() && coeff->valueInteger() == 1)
|
|
{;}
|
|
else
|
|
eop = &((coeff->copy()) *(*eop));
|
|
sum_dvm = &(*sum_dvm + (*eop) );
|
|
|
|
}
|
|
//do_var=isDoVarUse(es->lhs(),use,dim_ident,i,&num,par_st)
|
|
//*num = AxisNumOfDummyInExpr(e, ident, ni, &ei, use, cur_st);
|
|
//if (*num<=0)
|
|
// return(NULL);
|
|
//return(ei);
|
|
//sum_dvm->unparsestdout();
|
|
//eop->unparsestdout();
|
|
//fprintf(stderr,"%s%d\n",e->symbol()->identifier(),k);
|
|
|
|
if(!is) ChangeArrayCoeff(e->symbol());
|
|
return(sum_dvm);
|
|
}
|
|
|
|
|
|
void ChangeIndexRefBySum(SgExpression *ve)
|
|
{
|
|
SgSymbol *is,*s;
|
|
is = *INDEX_SYMBOL(ve->symbol());
|
|
s = ve->symbol();
|
|
NODE_CODE(ve->thellnd) = ADD_OP;
|
|
//ve->setVariant(ADD_OP);
|
|
ve->setLhs(*new SgVarRefExp(*s));
|
|
//ve->setLhs(ve->copy());
|
|
//ve->setLhs(*new SgValueExp(1));
|
|
ve->setRhs(*new SgVarRefExp(is));
|
|
ve->setSymbol((SgSymbol*) NULL);
|
|
//NODE_SYMB(ve->thellnd) = NULL;
|
|
}
|
|
|
|
void ChangeArrayCoeff(SgSymbol *ar)
|
|
{
|
|
|
|
InsertNewStatementBefore(new SgAssignStmt(*coef_ref(ar,0),*sum_dvm),first_do_par);
|
|
|
|
}
|
|
|
|
|
|
SgSymbol *CreateInitLoopVar(SgSymbol *dovar, SgSymbol *init)
|
|
{
|
|
if(INIT_LOOP_VAR(dovar))
|
|
return( *INIT_LOOP_VAR(dovar));
|
|
else {
|
|
SgSymbol **s = new (SgSymbol *);
|
|
//creating new variable
|
|
*s = InitLoopSymbol(dovar,init->type());
|
|
// adding the attribute (INIT_LOOP) to do-variable symbol
|
|
dovar->addAttribute(INIT_LOOP, (void*) s, sizeof(SgSymbol *));
|
|
index_symb = AddToSymbList(index_symb,*s);
|
|
return(*s);
|
|
}
|
|
}
|
|
|
|
|
|
void ConsistentArrayList (SgExpression *el,SgExpression *gref, SgStatement *st, SgStatement *stmt1, SgStatement *stmt2)
|
|
{ SgStatement *last,*last1;
|
|
SgExpression *er, *ev, *header = NULL,*size_array;
|
|
int nr, ia=-1, sign, re_sign,renew_sign,iaxis,rank;
|
|
SgSymbol *var;
|
|
// SgValueExp c0(0),c1(1);
|
|
last = stmt2; last1 = stmt1;
|
|
//looking through the consistent array list
|
|
for(er = el; er; er=er->rhs()) {
|
|
ev = er->lhs(); // consistent array reference
|
|
var = ev->symbol();
|
|
|
|
/* if(st->variant() == DVM_CONSISTENT_GROUP_DIR){
|
|
red_group_var_list=AddToSymbList(red_group_var_list,var);
|
|
if(loc_var->symbol())
|
|
red_group_var_list =AddToSymbList(red_group_var_list,loc_var->symbol());
|
|
}
|
|
else{
|
|
new_red_var_list=AddToSymbList(new_red_var_list,var);
|
|
if(loc_var->symbol())
|
|
new_red_var_list =AddToSymbList(new_red_var_list,loc_var->symbol());
|
|
}
|
|
*/
|
|
|
|
if(var)
|
|
ia = var->attributes();
|
|
|
|
if( isSgArrayRefExp(ev)) {
|
|
|
|
if((ia & DISTRIBUTE_BIT) ||(ia & ALIGN_BIT)|| (ia & INHERIT_BIT)) //06.12.12
|
|
{ Error("Illegal object '%s' in CONSISTENT clause ", var->identifier(), 399,st);
|
|
// Error("'%s' is distributed array", var->identifier(), 148,st);
|
|
continue;
|
|
}
|
|
|
|
else if(!(ia & CONSISTENT_BIT) ) // 06.12.12 && !(ia & DISTRIBUTE_BIT) && !(ia & ALIGN_BIT) && !(ia & INHERIT_BIT)){
|
|
{ Error("Illegal object '%s' in CONSISTENT clause ", var->identifier(), 399,st);
|
|
continue;
|
|
}
|
|
|
|
} else {
|
|
err("Illegal object in CONSISTENT clause ", 399,st);
|
|
//err("Wrong consistent array",151,st); //??? error number
|
|
continue;
|
|
}
|
|
|
|
if(stmt1 != stmt2)
|
|
cur_st = last1;
|
|
|
|
if(!only_debug) {
|
|
header = new SgArrayRefExp(*(CONSISTENT_HEADER(var)),*new SgValueExp(1)); //HeaderRef(var);
|
|
rank = Rank(var);
|
|
if(IN_COMPUTE_REGION || inparloop && parloop_by_handler) /*ACC*/
|
|
{ int i;
|
|
for(i=0;i<rank;i++)
|
|
doAssignTo_After(header_ref(header->symbol(),rank+3+i) , Exprn( LowerBound(var,i))) ;
|
|
}
|
|
size_array = DVM000(ndvm);
|
|
|
|
sign = 1;
|
|
re_sign = 0; // aligned array may not be redisributed
|
|
|
|
// call crtraf (ArrayHeader,ExtHdrSign,Base,Rank,TypeSize,SizeArray, StaticSign, ReDistrSign, Memory)
|
|
|
|
doCallAfter(CreateDvmArrayHeader(var, header, size_array, rank, sign, re_sign));
|
|
where = cur_st;
|
|
doSizeFunctionArray(var,st);
|
|
cur_st = where;
|
|
}
|
|
|
|
//if(debug_regim) {
|
|
// debgref = idebrg ? DVM000(idebrg) : DebReductionGroup(gref->symbol());
|
|
// doAssignStmtAfter(D_InsRedVar(debgref,num_red,ev,ntype,ilen, loc_var, ilen+1,locindtype));
|
|
//}
|
|
|
|
last1 = cur_st;
|
|
|
|
if(stmt1 != stmt2)
|
|
cur_st = last;
|
|
renew_sign = 0; //????
|
|
if(!only_debug){
|
|
iaxis = ndvm;
|
|
//insert array into consistent group
|
|
if(st->variant() == DVM_TASK_REGION_DIR){
|
|
doAxisTask(st,ev);
|
|
//doAssignStmtAfter(IncludeConsistentTask(gref,header,DVM000(PS_INDEX(st->symbol())),iaxis,re_sign));
|
|
doAssignStmtAfter(IncludeConsistentTask(gref,header,new SgVarRefExp(TASK_SYMBOL(st->symbol())),iaxis,re_sign));
|
|
|
|
}
|
|
else {//DVM_PARALLEL_ON_DIR
|
|
nr = doAlignIteration(st, ev);
|
|
doAssignStmtAfter(InsertConsGroup(gref,header,iplp,iaxis, iaxis+nr, iaxis+2*nr,re_sign));
|
|
}
|
|
}
|
|
last = cur_st;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void ConsistentArraysStart (SgExpression *el)
|
|
{
|
|
SgExpression *er, *ev;
|
|
|
|
//looking through the consistent array list
|
|
for(er = el; er; er=er->rhs()) {
|
|
ev = er->lhs(); // consistent array reference
|
|
|
|
if(isSgArrayRefExp(ev) && !IS_DVM_ARRAY(ev->symbol())) {
|
|
doAssignStmtAfter(GetAddresMem(FirstArrayElement(ev->symbol()))) ;
|
|
FREE_DVM(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Consistent_Task_Region(SgStatement *stmt)
|
|
{SgExpression *e;
|
|
SgStatement *st2, *st3;
|
|
|
|
iconsgts=0;
|
|
consgrefts=NULL;
|
|
e=stmt->expr(1);
|
|
if(!e) return;
|
|
task_cons_list = e->lhs();
|
|
if( e->symbol()){
|
|
consgrefts = new SgVarRefExp(e->symbol());
|
|
doIfForConsistent(consgrefts);
|
|
nloopcons++;
|
|
//stcg = doIfForCreateReduction( e->symbol(),nloopcons,0);
|
|
st2 = doIfForCreateReduction( consgrefts->symbol(),nloopcons,1);
|
|
//stcg = st2;
|
|
st3 = cur_st;
|
|
cur_st = st2;
|
|
ConsistentArrayList(task_cons_list,consgrefts,stmt,st2,st2);
|
|
cur_st = st3;
|
|
InsertNewStatementAfter( new SgAssignStmt(*DVM000(ndvm),*new SgValueExp(0)),cur_st,cur_st->controlParent());
|
|
|
|
} else {
|
|
iconsgts = ndvm;
|
|
consgrefts = DVM000(iconsgts);
|
|
doAssignStmtAfter(CreateConsGroup(1,1));
|
|
//!!!??? if(debug_regim){
|
|
// idebcg = ndvm;
|
|
// doAssignStmtAfter( D_CreateDebRedGroup());
|
|
//}
|
|
//stcg = cur_st;//store current statement
|
|
ConsistentArrayList(task_cons_list,consgrefts,stmt,cur_st,cur_st);
|
|
}
|
|
}
|
|
|
|
void EndConsistent_Task_Region(SgStatement *stmt)
|
|
{
|
|
if(!stmt) return;
|
|
//LINE_NUMBER_AFTER(stmt,stmt);
|
|
// actualizing of consistent arrays
|
|
if(consgrefts)
|
|
ConsistentArraysStart(task_cons_list);
|
|
|
|
if(!iconsgts) return;
|
|
|
|
//there is synchronous CONSISTENT clause in TASK_REGION
|
|
// generating assign statement:
|
|
// dvm000(i) = strtcg(ConsistGroupRef)
|
|
doAssignStmtAfter(StartConsGroup(consgrefts));
|
|
|
|
// generating assign statement:
|
|
// dvm000(i) = waitcg(ConsistGroupRef)
|
|
doAssignStmtAfter(WaitConsGroup(consgrefts));
|
|
|
|
//if(idebcg){
|
|
//if(dvm_debug)
|
|
// doAssignStmtAfter( D_CalcRG(DVM000(idebrg)));
|
|
//doAssignStmtAfter( D_DelRG (DVM000(idebrg)));
|
|
//}
|
|
|
|
// generating statement:
|
|
// call dvmh_delete_object(ConsistGroupRef) //dvm000(i) = delobj(ConsistGroupRef)
|
|
doCallAfter(DeleteObject_H(consgrefts));
|
|
}
|
|
|
|
void doAxisTask(SgStatement *st, SgExpression *eref)
|
|
{int i,iaxis=-1;
|
|
SgExpression *el;
|
|
SgSymbol *ar;
|
|
ar = eref->symbol();
|
|
for(el=eref->lhs(),i=0; el; el=el->rhs(),i++)
|
|
if(el->lhs()->variant() !=DDOT)
|
|
iaxis = i;
|
|
if(i != Rank(ar))
|
|
Error("Rank of array '%s' isn't equal to the length of subscript list", ar->identifier(), 161,st);
|
|
doAssignStmtAfter(new SgValueExp(i-iaxis));
|
|
return;
|
|
}
|
|
|
|
|
|
void TransBlockData(SgStatement *hedr,SgStatement* &end_of_unit)
|
|
{SgStatement* stmt;
|
|
end_of_unit = hedr->lastNodeOfStmt();
|
|
for (stmt = hedr; stmt && (stmt != end_of_unit); stmt = stmt->lexNext())
|
|
if(isSgVarDeclStmt(stmt)) VarDeclaration(stmt);
|
|
// analizing object list and replacing variant of declaration statement with initialisation by VAR_DECL_90
|
|
}
|
|
|
|
void VarDeclaration(SgStatement *stmt)
|
|
{ SgExpression *el;
|
|
int is_assign;
|
|
is_assign =0;
|
|
for(el=stmt->expr(0); el; el=el->rhs()) {
|
|
if(el->lhs()->variant() == ASSGN_OP || el->lhs()->variant() == POINTST_OP) is_assign = 1;//with initial value
|
|
}
|
|
if(is_assign && stmt->variant() == VAR_DECL && !stmt->expr(2))
|
|
stmt->setVariant(VAR_DECL_90);
|
|
return;
|
|
}
|
|
|
|
SgExpression *LeftMostField(SgExpression *e)
|
|
{SgExpression *ef;
|
|
ef = e;
|
|
while(ef->variant() == RECORD_REF)
|
|
ef = ef->lhs();
|
|
return(ef);
|
|
}
|
|
|
|
SgExpression *RightMostField(SgExpression *e)
|
|
{return(e->rhs());}
|
|
|
|
SgStatement *InterfaceBlock(SgStatement *hedr)
|
|
{ SgStatement *stmt;
|
|
in_interface++;
|
|
for(stmt=hedr->lexNext(); stmt->variant()!=CONTROL_END; stmt=stmt->lexNext())
|
|
{
|
|
if(stmt->variant() == FUNC_HEDR || stmt->variant() == PROC_HEDR) //may be module procedure statement
|
|
stmt = InterfaceBody(stmt);
|
|
else if(stmt->variant() != MODULE_PROC_STMT)
|
|
err("Misplaced directive/statement", 103, stmt);
|
|
}
|
|
//if(stmt->controlParent() != hedr)
|
|
// Error("Illegal END statement");
|
|
|
|
in_interface--;
|
|
return(stmt);
|
|
}
|
|
|
|
SgStatement *InterfaceBody(SgStatement *hedr)
|
|
{
|
|
SgStatement *stmt, *last, *dvm_pred;
|
|
symb_list *distsym;
|
|
SgSymbol *s = hedr->symbol();
|
|
distsym = NULL;
|
|
dvm_pred = NULL;
|
|
|
|
if (hedr->expr(2))
|
|
{
|
|
if (hedr->expr(2)->variant() == PURE_OP)
|
|
SYMB_ATTR(s->thesymb) = SYMB_ATTR(s->thesymb) | PURE_BIT;
|
|
|
|
else if (hedr->expr(2)->variant() == ELEMENTAL_OP)
|
|
SYMB_ATTR(s->thesymb) = SYMB_ATTR(s->thesymb) | ELEMENTAL_BIT;
|
|
}
|
|
last = hedr->lastNodeOfStmt();
|
|
|
|
for(stmt=hedr->lexNext(); stmt; stmt=stmt->lexNext()) {
|
|
if(dvm_pred)
|
|
Extract_Stmt(dvm_pred); // deleting preceding DVM-directive
|
|
if(stmt == last) break; //end of interface body
|
|
dvm_pred = NULL;
|
|
|
|
if (!isSgExecutableStatement(stmt)) {//is Fortran specification statement
|
|
|
|
if(only_debug){
|
|
if(isSgVarDeclStmt(stmt)) VarDeclaration(stmt);// for analizing object list and replacing variant of statement
|
|
continue;
|
|
}
|
|
//discovering distributed arrays in COMMON-blocks
|
|
if(stmt->variant()==COMM_STAT) {
|
|
|
|
DeleteShapeSpecDAr(stmt);
|
|
if( !DeleteHeapFromList(stmt) ) { //common list is empty
|
|
stmt=stmt->lexPrev();
|
|
stmt->lexNext()->extractStmt(); //deleting the statement
|
|
}
|
|
continue;
|
|
}
|
|
|
|
// deleting distributed arrays from variable list of declaration
|
|
// statement and testing are there any group names
|
|
if( isSgVarDeclStmt(stmt) || isSgVarListDeclStmt(stmt)) {
|
|
|
|
if( !DeleteDArFromList(stmt) ) { //variable list is empty
|
|
stmt=stmt->lexPrev();
|
|
stmt->lexNext()->extractStmt(); //deleting the statement
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if(stmt->variant() == STMTFN_STAT) {
|
|
if(stmt->expr(0) && stmt->expr(0)->symbol() && ((!strcmp(stmt->expr(0)->symbol()->identifier(),"number_of_processors")) || (!strcmp(stmt->expr(0)->symbol()->identifier(),"processors_rank")) || (!strcmp(stmt->expr(0)->symbol()->identifier(),"processors_size")))){
|
|
stmt=stmt->lexPrev();
|
|
stmt->lexNext()->extractStmt();
|
|
//deleting the statement-function declaration named
|
|
// NUMBER_OF_PROCESSORS or PROCESSORS_RANK or PROCESSORS_SIZE
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (stmt->variant() == ENTRY_STAT) {
|
|
warn("ENTRY among specification statements", 81,stmt);
|
|
continue;
|
|
}
|
|
|
|
if(stmt->variant() == INTERFACE_STMT || stmt->variant() == INTERFACE_ASSIGNMENT || stmt->variant() == INTERFACE_OPERATOR){
|
|
stmt=InterfaceBlock(stmt);
|
|
continue;
|
|
}
|
|
|
|
if(stmt->variant() == STRUCT_DECL){
|
|
stmt=stmt->lastNodeOfStmt();
|
|
continue;
|
|
}
|
|
|
|
if( stmt->variant() == USE_STMT || stmt->variant() == DATA_DECL)
|
|
continue;
|
|
|
|
continue;
|
|
} // end of if(!isSgExecutable...
|
|
|
|
if ((stmt->variant() == FORMAT_STAT))
|
|
continue;
|
|
|
|
// processing the DVM Specification Directives
|
|
|
|
switch(stmt->variant()) {
|
|
|
|
case (DVM_VAR_DECL):
|
|
{ SgExpression *el;
|
|
int eda;
|
|
eda = 0;
|
|
for(el = stmt->expr(2); el; el=el->rhs()) // looking through the attribute list
|
|
switch(el->lhs()->variant()) {
|
|
case (ALIGN_OP):
|
|
case (DISTRIBUTE_OP):
|
|
eda = 1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if(eda == 0){
|
|
dvm_pred = stmt;
|
|
continue;
|
|
}
|
|
}
|
|
case (DVM_INHERIT_DIR):
|
|
case (DVM_ALIGN_DIR):
|
|
case (DVM_DISTRIBUTE_DIR):
|
|
{
|
|
SgExpression *sl;
|
|
for(sl=stmt->expr(0); sl; sl=sl->rhs()) //scanning the alignees list
|
|
if(!IS_POINTER(sl->lhs()->symbol()))
|
|
distsym = AddNewToSymbList(distsym,sl->lhs()->symbol());
|
|
}
|
|
dvm_pred = stmt;
|
|
continue;
|
|
case (ACC_ROUTINE_DIR):
|
|
ACC_ROUTINE_Directive(stmt);
|
|
dvm_pred = stmt;
|
|
continue;
|
|
|
|
case (HPF_TEMPLATE_STAT):
|
|
case (HPF_PROCESSORS_STAT):
|
|
case (DVM_DYNAMIC_DIR):
|
|
case (DVM_SHADOW_DIR):
|
|
case (DVM_TASK_DIR):
|
|
case (DVM_CONSISTENT_DIR):
|
|
case (DVM_INDIRECT_GROUP_DIR):
|
|
case (DVM_REMOTE_GROUP_DIR):
|
|
case (DVM_CONSISTENT_GROUP_DIR):
|
|
case (DVM_REDUCTION_GROUP_DIR):
|
|
case (DVM_POINTER_DIR):
|
|
case (DVM_HEAP_DIR):
|
|
case (DVM_ASYNCID_DIR):
|
|
dvm_pred = stmt;
|
|
default:
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
} //end of loop
|
|
|
|
if(!only_debug)
|
|
DeclareVarDVMForInterface(stmt->lexPrev(),distsym);
|
|
return(stmt);
|
|
}
|
|
|
|
void DeleteShapeSpecDAr(SgStatement *stmt)
|
|
{
|
|
SgExpression *ec, *el;
|
|
SgSymbol *sc;
|
|
for(ec=stmt->expr(0); ec; ec=ec->rhs()) // looking through COMM_LIST
|
|
for(el=ec->lhs(); el; el=el->rhs()) {
|
|
sc = el->lhs()->symbol();
|
|
if(sc && ((sc->attributes() & ALIGN_BIT) || (sc->attributes() & DISTRIBUTE_BIT)) )
|
|
el->lhs()->setLhs(NULL);
|
|
if(sc && !in_interface) {
|
|
SYMB_ATTR(sc->thesymb)= SYMB_ATTR(sc->thesymb) | COMMON_BIT;
|
|
if((debug_regim || IN_MAIN_PROGRAM) && IS_ARRAY(sc) )
|
|
registration = AddNewToSymbList( registration, sc);
|
|
|
|
if( !strcmp(sc->identifier(),"heap"))
|
|
heap_ar_decl = new SgArrayRefExp(*heapdvm);
|
|
}
|
|
if(sc && (sc->attributes() & TEMPLATE_BIT))
|
|
Error("Template '%s' is in COMMON",sc->identifier(),79,stmt);
|
|
}
|
|
}
|
|
|
|
void DeclareVarDVMForInterface(SgStatement *lstat, symb_list *distsymb)
|
|
{symb_list *save;
|
|
if(!distsymb) return;
|
|
save = dsym; //save global variable 'dsym' - list of distributed arrays for procedure
|
|
dsym = distsymb;
|
|
DeclareVarDVM(lstat,lstat);
|
|
dsym = save; //resave global variable 'dsym'
|
|
}
|
|
|
|
SgExpression *DVMVarInitialization(SgExpression *es)
|
|
{SgExpression *einit, *er;
|
|
switch(es->symbol()->variant()) { //initialization expression
|
|
case ASYNC_ID: einit = new SgValueExp(1); //new SgExpExpression(CONSTRUCTOR_REF); //SgConstExp
|
|
break;
|
|
default: einit = new SgValueExp(0);
|
|
break;
|
|
}
|
|
er = new SgExpression(ASSGN_OP,es,einit,NULL);
|
|
return(er);
|
|
}
|
|
|
|
SgExpression *FileNameInitialization(SgExpression *es,char *name)
|
|
{SgExpression *einit, *er;
|
|
einit = new SgExpression(CONCAT_OP,new SgValueExp(name),CHARFunction(0),NULL);
|
|
er = new SgExpression(ASSGN_OP,es,einit,NULL);
|
|
return(er);
|
|
}
|
|
|
|
SgStatement *CreateModuleProcedure(SgStatement *mod_hedr, SgStatement *lst, SgStatement* &has_contains)
|
|
{ mod_attr *attrmod;
|
|
SgStatement *last;
|
|
SgStatement *st_end ;
|
|
SgStatement *st;
|
|
SgSymbol *smod;
|
|
|
|
attrmod = new mod_attr;
|
|
attrmod->symb = NULL;
|
|
mod_hedr->symbol()->addAttribute(MODULE_STR, (void *) attrmod, sizeof(mod_attr));
|
|
|
|
// if(mod_hedr->lexNext()->variant() != USE_STMT && !dsym && !task_symb && !proc_symb)
|
|
// return(NULL);
|
|
|
|
smod = new SgSymbol(PROCEDURE_NAME, ModuleProcName(mod_hedr->symbol()), *mod_hedr);
|
|
attrmod->symb = smod;
|
|
st = new SgStatement(PROC_HEDR);
|
|
st->setSymbol(*smod);
|
|
st_end = new SgStatement(CONTROL_END);
|
|
|
|
if(lst->variant() != CONTAINS_STMT) {
|
|
last = new SgStatement(CONTAINS_STMT);
|
|
lst-> insertStmtBefore(*last);
|
|
} else
|
|
last = lst;
|
|
has_contains = last;
|
|
//last = (lst->variant() == CONTAINS_STMT) ? lst->lexNext() : lst;
|
|
last->insertStmtAfter(*st);
|
|
st->insertStmtAfter(*st_end);
|
|
return(st);
|
|
}
|
|
|
|
void GenForUseStmts(SgStatement *hedr,SgStatement *where_st)
|
|
{SgStatement *stmt;
|
|
for(stmt=hedr->lexNext();stmt->variant() == USE_STMT;stmt=stmt->lexNext()){
|
|
GenCallForUSE(stmt,where_st);
|
|
/*
|
|
if(!(stmt->expr(0)))
|
|
GenCallForUSE(stmt,where_st);
|
|
else if(stmt->expr(0)->variant() == ONLY_NODE)
|
|
GenForUseList(stmt->expr(0)->lhs(),stmt,where_st);
|
|
else {
|
|
GenForUseList(stmt->expr(0),stmt,where_st);
|
|
GenCallForUSE(stmt,where_st);
|
|
}
|
|
*/
|
|
}
|
|
|
|
}
|
|
|
|
void GenForUseList(SgExpression *ul,SgStatement *stmt, SgStatement *where_st)
|
|
{SgExpression *el, *e;
|
|
|
|
for(el=ul; el; el=el->rhs()){
|
|
e = el->lhs();
|
|
if(e->variant() == RENAME_NODE){
|
|
e = e->lhs(); //new symbol reference
|
|
}
|
|
if(!only_debug && IS_DVM_ARRAY(e->symbol()))
|
|
GenDVMArray(e->symbol(),stmt,where_st);
|
|
if(debug_regim && IS_ARRAY(e->symbol()))
|
|
Registrate_Ar(e->symbol());
|
|
}
|
|
}
|
|
|
|
void GenDVMArray(SgSymbol *ar, SgStatement *stmt, SgStatement *where_st)
|
|
{SgStatement *savest;
|
|
//SgExpression *dce;
|
|
// SgArrayType *artype;
|
|
savest = where;
|
|
where = where_st;
|
|
//generating
|
|
|
|
/*
|
|
dce = new SgArrayRefExp(*ar);
|
|
artype = isSgArrayType(ar->type());
|
|
dce->setLhs(artype->getDimList()->copy());
|
|
|
|
if(ar->attributes() & POINTER_BIT)
|
|
AllocatePointerHeader(ar,where_st);
|
|
*/
|
|
if( IS_POINTER(ar) || (IN_COMMON(ar) && (ar->scope()->variant() != PROG_HEDR)) || IS_ALLOCATABLE_POINTER(ar))
|
|
return;
|
|
if(ar->attributes() & DISTRIBUTE_BIT) {
|
|
//determine corresponding DISTRIBUTE statement
|
|
SgStatement *dist_st = *(DISTRIBUTE_DIRECTIVE(ar));
|
|
//create distributed array
|
|
int idis;
|
|
SgExpression *distr_rule_list = doDisRules(dist_st,0,idis);
|
|
SgExpression *ps = PSReference(dist_st);
|
|
GenDistArray(ar,idis,distr_rule_list,ps,dist_st);
|
|
}
|
|
|
|
else if(ar->attributes() & ALIGN_BIT) {
|
|
//create aligned array
|
|
int nr,iaxis;
|
|
algn_attr * attr;
|
|
align * root, *node,*node_copy, *root_copy = NULL;
|
|
SgStatement *algn_st;
|
|
SgSymbol *base;
|
|
attr = (algn_attr *) ORIGINAL_SYMBOL(ar)->attributeValue(0,ALIGN_TREE);
|
|
node = attr->ref; // reference to root of align tree
|
|
node_copy = new align;
|
|
node_copy->symb = ar;
|
|
node_copy->align_stmt = node->align_stmt;
|
|
algn_st = node->align_stmt;
|
|
if(!algn_st->expr(2)) //postponed aligning
|
|
root = NULL;
|
|
else {
|
|
base = (algn_st->expr(2)->variant()==ARRAY_OP) ? (algn_st->expr(2))->rhs()->symbol() : (algn_st->expr(2))->symbol();// align_base symbol
|
|
root = ((algn_attr *) ORIGINAL_SYMBOL(base)->attributeValue(0,ALIGN_TREE))->ref;
|
|
root_copy = new align;
|
|
root_copy->symb = Rename(base,stmt);
|
|
root_copy->align_stmt = root->align_stmt;
|
|
}
|
|
iaxis = ndvm;
|
|
SgExpression *align_rule_list = doAlignRules(ar,node->align_stmt,0,nr);// creating axis_array, coeff_array and const_array
|
|
GenAlignArray(node_copy,root_copy, nr, align_rule_list, iaxis);
|
|
/* AllocateAlignArray(ar,dce,stmt);*/
|
|
}
|
|
loc_distr = 0;
|
|
pointer_in_tree = 0;
|
|
where = savest;
|
|
}
|
|
|
|
SgSymbol *Rename(SgSymbol *ar, SgStatement *stmt)
|
|
{SgExpression *el, *e, *eold;
|
|
|
|
for(el=stmt->expr(0);el;el=el->rhs()){
|
|
e = el->lhs(); eold = NULL;
|
|
if(e->variant() == RENAME_NODE){
|
|
e = e->lhs(); //new symbol reference
|
|
eold = el->lhs()->rhs(); //old symbol reference
|
|
}
|
|
// if(eold && ORIGINAL_SYMBOL(eold->symbol()) == ORIGINAL_SYMBOL(ar))
|
|
if(eold && !strcmp(eold->symbol()->identifier(),ar->identifier()))
|
|
return(e->symbol());
|
|
}
|
|
return(ar);
|
|
}
|
|
|
|
void AddAttributeToLastElement(SgExpression *use_list)
|
|
{
|
|
SgExpression *el = use_list;
|
|
while(el && el->rhs())
|
|
el = el->rhs();
|
|
el->addAttribute(END_OF_USE_LIST, (void*) 1, 0);
|
|
}
|
|
|
|
void UpdateUseListWithDvmArrays(SgStatement *use_stmt)
|
|
{
|
|
SgExpression *el, *coeff_list=NULL;
|
|
SgExpression *use_list = use_stmt->expr(0);
|
|
SgSymbol *s,*sloc;
|
|
int i,r,i0;
|
|
i0 = opt_base ? 1 : 2;
|
|
if(opt_loop_range) i0=0;
|
|
|
|
if(use_list && use_list->variant()==ONLY_NODE)
|
|
use_list = use_list->lhs();
|
|
if(use_list)
|
|
AddAttributeToLastElement(use_list);
|
|
for(el=use_list; el; el=el->rhs())
|
|
{
|
|
// el->lhs()->variant() is RENAME_NODE
|
|
sloc = el->lhs()->lhs()->symbol(); // local symbol
|
|
if(!IS_DVM_ARRAY(sloc)) continue;
|
|
r = Rank(sloc);
|
|
if(el->lhs()->rhs()) // use symbol reference in renaming_op: local_symbol=>use_symbol
|
|
{
|
|
s = el->lhs()->rhs()->symbol(); //use symbol
|
|
if(strcmp(sloc->identifier(),s->identifier())) // different names
|
|
{
|
|
// creating variables used for optimisation array references in parallel loop (linearization coefficients)
|
|
coeffs *c_new = new coeffs;
|
|
CreateCoeffs(c_new,sloc);
|
|
// adding the attribute (ARRAY_COEF) to distributed array symbol
|
|
sloc->addAttribute(ARRAY_COEF, (void*) c_new, sizeof(coeffs));
|
|
// add renaming_op for all coefficients (2:rank+2) to use_list: coeff_of_sloc=>coeff_of_s
|
|
coeffs *c_use = AR_COEFFICIENTS(s);
|
|
for(i=i0;i<=r+2;i++)
|
|
if(i != r+1)
|
|
{
|
|
SgExpression *rename = new SgExpression(RENAME_NODE, new SgVarRefExp(c_new->sc[i]), new SgVarRefExp(c_use->sc[i]), NULL);
|
|
coeff_list = AddListToList(coeff_list,new SgExprListExp(*rename));
|
|
}
|
|
}
|
|
} else
|
|
{
|
|
// add cofficients of use_symbol to use_list
|
|
s = el->lhs()->symbol(); //use symbol
|
|
coeffs *c_use = AR_COEFFICIENTS(s);
|
|
for(i=i0;i<=r+2;i++)
|
|
if(i != r+1)
|
|
coeff_list = AddListToList(coeff_list,new SgExprListExp(*new SgVarRefExp(c_use->sc[i])));
|
|
}
|
|
}
|
|
if(coeff_list)
|
|
AddListToList(use_list,coeff_list);
|
|
}
|
|
|
|
void updateUseStatementWithOnly(SgStatement *st_use, SgSymbol *s_func)
|
|
{ // add name of s_func to only-list of USE statement
|
|
SgExpression *clause = st_use->expr(0);
|
|
if(clause && clause->variant() == ONLY_NODE)
|
|
{
|
|
SgExpression *el = new SgExprListExp(*new SgVarRefExp(s_func));
|
|
if(clause->lhs()) // only-list is not empty
|
|
AddListToList(clause->lhs(), el);
|
|
else
|
|
clause->setLhs(el);
|
|
}
|
|
}
|
|
|
|
void GenCallForUSE(SgStatement *hedr,SgStatement *where_st)
|
|
{SgSymbol *smod;
|
|
SgStatement *call;
|
|
mod_attr *attrm;
|
|
smod = hedr->symbol();
|
|
if((attrm=DVM_PROC_IN_MODULE(smod)) && attrm->symb){
|
|
call = new SgCallStmt(*attrm->symb);
|
|
where_st->insertStmtBefore(*call);
|
|
updateUseStatementWithOnly(hedr,attrm->symb); // add dvm-module-procedure name to only-list
|
|
}
|
|
}
|
|
|
|
SgStatement *MayBeDeleteModuleProc(SgStatement *mod_proc,SgStatement *end_mod)
|
|
{ mod_attr *attrm;
|
|
//mod_proc->unparsestdout();
|
|
//printf("-----%d %d\n",end_mod->lexPrev()->variant(),end_mod->variant()); end_mod->unparsestdout();
|
|
if(!isSgExecutableStatement(end_mod->lexPrev()) || mod_proc->lexNext()==end_mod ) {// there are not executable statements in module procedure
|
|
attrm=DVM_PROC_IN_MODULE(cur_func->symbol()) ;
|
|
attrm->symb=NULL; // deleting module procedure reference in attribute
|
|
//deleting module procedure
|
|
//for(stmt=mod_proc->lexNext(),prev=mod_proc; stmt!=end_mod->lexNext(); stmt=stmt->lexNext())
|
|
//{ prev->extractStmt(); prev = stmt; }
|
|
//end_mod->extractStmt();
|
|
//return(NULL);
|
|
}
|
|
return(mod_proc);
|
|
}
|
|
|
|
int TestDVMDirectivesInModule(stmt_list *pstmt)
|
|
{stmt_list *stmt;
|
|
int flag;
|
|
flag = 0;
|
|
for(stmt=pstmt; stmt; stmt=stmt->next) {
|
|
switch(stmt->st->variant()) {
|
|
//case HPF_TEMPLATE_STAT:
|
|
case DVM_ALIGN_DIR:
|
|
case DVM_DISTRIBUTE_DIR:
|
|
case HPF_PROCESSORS_STAT:
|
|
case DVM_VAR_DECL:
|
|
case DVM_TASK_DIR:
|
|
flag = 1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return(flag);
|
|
}
|
|
|
|
int TestDVMDirectivesInProcedure(stmt_list *pstmt)
|
|
{stmt_list *stmt;
|
|
for(stmt=pstmt; stmt; stmt=stmt->next) {
|
|
if(stmt->st->variant() != DVM_INHERIT_DIR)
|
|
return( 1 );
|
|
}
|
|
return ( 0 );
|
|
}
|
|
|
|
int TestUseStmts()
|
|
{SgStatement *stmt;
|
|
mod_attr *attrm;
|
|
int flag;
|
|
flag =0;
|
|
//looking through the USE statements
|
|
for(stmt=cur_func->lexNext();stmt->variant() == USE_STMT;stmt=stmt->lexNext()){
|
|
if((attrm=DVM_PROC_IN_MODULE(stmt->symbol())) && attrm->symb) //module has DVM-module-procedure
|
|
flag =1;
|
|
}
|
|
return(flag);
|
|
}
|
|
|
|
int ArrayAssignment(SgStatement *stmt)
|
|
{
|
|
if(isSgArrayRefExp(stmt->expr(0)) || isSgArrayType(stmt->expr(0)->type()))
|
|
return(1);
|
|
else
|
|
return(0);
|
|
}
|
|
|
|
int DVMArrayAssignment(SgStatement *stmt)
|
|
{
|
|
if(HEADER(stmt->expr(0)->symbol()) && isSgArrayType(stmt->expr(0)->type()))
|
|
return(1);
|
|
else
|
|
return(0);
|
|
}
|
|
|
|
void MakeSection(SgExpression *are)
|
|
{int n;
|
|
SgArrayRefExp *ae;
|
|
if(!(ae=isSgArrayRefExp(are))) return;
|
|
for(n = Rank(are->symbol()); n; n--)
|
|
ae->addSubscript(*new SgExpression(DDOT));
|
|
}
|
|
|
|
void DistributeArrayList(SgStatement *stdis)
|
|
{SgExpression *el;
|
|
SgSymbol *das;
|
|
SgStatement **dst = new (SgStatement *);
|
|
|
|
*dst = stdis;
|
|
for(el=stdis->expr(0); el; el=el->rhs()){
|
|
das = el->lhs()->symbol();
|
|
das->addAttribute(DISTRIBUTE_, (void *) dst, sizeof(SgStatement *));
|
|
if(das->attributes() & EQUIVALENCE_BIT)
|
|
Error("DVM-array cannot be specified in EQUIVALENCE statement: %s", das->identifier(),341,stdis);
|
|
}
|
|
}
|
|
|
|
SgExpression *DebugIfCondition()
|
|
{ if(!dbif_cond)
|
|
dbif_cond=&SgEqOp(*new SgVarRefExp(*dbg_var), *new SgValueExp(1));
|
|
return(dbif_cond);
|
|
}
|
|
/*
|
|
SgExpression *DebugIfCondition()
|
|
{return(&SgEqOp(*new SgVarRefExp(*dbg_var), *new SgValueExp(1)));}
|
|
*/
|
|
|
|
SgExpression *DebugIfNotCondition()
|
|
{ if(!dbif_not_cond)
|
|
dbif_not_cond=&SgEqOp(*new SgVarRefExp(*dbg_var), *new SgValueExp(0));
|
|
return(dbif_not_cond);
|
|
}
|
|
/*
|
|
SgExpression *DebugIfNotCondition()
|
|
{return(&SgEqOp(*new SgVarRefExp(*dbg_var), *new SgValueExp(0)));}
|
|
*/
|
|
|
|
SgStatement *LastStatementOfDoNest(SgStatement *first_do)
|
|
{SgStatement *last;
|
|
last=first_do->lastNodeOfStmt();
|
|
if(last->variant() == FOR_NODE || last->variant() == WHILE_NODE )
|
|
last=LastStatementOfDoNest(last);
|
|
|
|
return(last);
|
|
}
|
|
|
|
void TranslateBlock (SgStatement *stat)
|
|
{
|
|
TranslateFromTo(stat,lastStmtOf(stat),0); //0 - without error messages
|
|
}
|
|
|
|
/*
|
|
void TranslateBlock (SgStatement *stat)
|
|
SgStatement *stmt, *last, *next;
|
|
// last is the statement following last statement of block
|
|
|
|
last = lastStmtOf(stat); //podd 03.06.14 stat->lastNodeOfStmt();
|
|
//if (last->variant() == LOGIF_NODE)
|
|
// last =last->lexNext();
|
|
//last =last->lexNext();
|
|
*/
|
|
|
|
void TranslateFromTo(SgStatement *first, SgStatement *last, int error_msg)
|
|
//TranslateBlock (SgStatement *stat)
|
|
{SgStatement *stmt, *out, *next;
|
|
SgLabel *lab_on;
|
|
SgStatement *in_on = NULL;
|
|
char io_modes_str[4] = "\0";
|
|
out =last->lexNext();
|
|
if(only_debug) goto SEQ_PROG;
|
|
|
|
for(stmt=first; stmt!=out; stmt=next) {
|
|
cur_st = stmt; //printf("TranslateBlock %d %d\n",stmt->lineNumber(), stmt->variant());
|
|
next = stmt->lexNext();
|
|
switch(stmt->variant()) {
|
|
case CONTROL_END:
|
|
case CONTAINS_STMT:
|
|
case RETURN_STAT:
|
|
case STOP_STAT:
|
|
case PAUSE_NODE:
|
|
case ENTRY_STAT:
|
|
break;
|
|
|
|
case SWITCH_NODE: // SELECT CASE ...
|
|
case ARITHIF_NODE: // Arithmetical IF
|
|
case IF_NODE: // IF... THEN
|
|
case WHILE_NODE: // DO WHILE (...)
|
|
case CASE_NODE: // CASE ...
|
|
case ELSEIF_NODE: // ELSE IF...
|
|
ChangeDistArrayRef(stmt->expr(0));
|
|
break;
|
|
|
|
case LOGIF_NODE: // Logical IF
|
|
|
|
ChangeDistArrayRef(stmt->expr(0));
|
|
break; //continue; // to next statement
|
|
|
|
case FORALL_STAT: // FORALL statement
|
|
//stmt=stmt->lexNext(); // statement that is a part of FORALL statement
|
|
break;
|
|
// continue;
|
|
|
|
case GOTO_NODE: // GO TO
|
|
break;
|
|
|
|
case COMGOTO_NODE: // Computed GO TO
|
|
ChangeDistArrayRef(stmt->expr(1));
|
|
break;
|
|
|
|
case ASSIGN_STAT: // Assign statement
|
|
if(IN_COMPUTE_REGION && !inparloop && !in_on) /*ACC*/
|
|
TestDvmObjectAssign(stmt);
|
|
ChangeDistArrayRef_Left(stmt->expr(0)); // left part
|
|
ChangeDistArrayRef(stmt->expr(1)); // right part
|
|
break;
|
|
|
|
case PROC_STAT: // CALL
|
|
{SgExpression *el;
|
|
// looking through the arguments list
|
|
for(el=stmt->expr(0); el; el=el->rhs())
|
|
ChangeArg_DistArrayRef(el); // argument
|
|
}
|
|
break;
|
|
|
|
case ALLOCATE_STMT:
|
|
if(!IN_COMPUTE_REGION)
|
|
{ AllocatableArrayRegistration(stmt);
|
|
//stmt=cur_st;
|
|
}
|
|
break;
|
|
|
|
case DEALLOCATE_STMT:
|
|
break;
|
|
|
|
case DVM_IO_MODE_DIR:
|
|
IoModeDirective(stmt,io_modes_str,error_msg);
|
|
Extract_Stmt(stmt); // extracting DVM-directive
|
|
break;
|
|
|
|
case OPEN_STAT:
|
|
Open_Statement(stmt,io_modes_str,error_msg);
|
|
break;
|
|
case CLOSE_STAT:
|
|
Close_Statement(stmt,error_msg);
|
|
break; //continue;
|
|
case INQUIRE_STAT:
|
|
Inquiry_Statement(stmt,error_msg);
|
|
break;
|
|
case BACKSPACE_STAT:
|
|
case ENDFILE_STAT:
|
|
case REWIND_STAT:
|
|
FilePosition_Statement(stmt, error_msg);
|
|
break;
|
|
case WRITE_STAT:
|
|
case READ_STAT:
|
|
ReadWrite_Statement(stmt, error_msg);
|
|
break;
|
|
case PRINT_STAT:
|
|
Any_IO_Statement(stmt);
|
|
ReadWritePrint_Statement(stmt, error_msg);
|
|
break;
|
|
case DVM_CP_CREATE_DIR: /*Check Point*/
|
|
CP_Create_Statement(stmt, error_msg);
|
|
break;
|
|
case DVM_CP_SAVE_DIR:
|
|
CP_Save_Statement(stmt, error_msg);
|
|
break;
|
|
case DVM_CP_LOAD_DIR:
|
|
CP_Load_Statement(stmt, error_msg);
|
|
break;
|
|
case DVM_CP_WAIT_DIR:
|
|
CP_Wait(stmt, error_msg);
|
|
break; /*Check Point*/
|
|
case FOR_NODE:
|
|
ChangeDistArrayRef(stmt->expr(0));
|
|
ChangeDistArrayRef(stmt->expr(1));
|
|
break;
|
|
case DVM_ON_DIR:
|
|
if(stmt->expr(0)->symbol() && HEADER(stmt->expr(0)->symbol()))
|
|
in_on = stmt;
|
|
break;
|
|
case DVM_END_ON_DIR:
|
|
if(in_on)
|
|
{
|
|
ReplaceOnByIf(in_on,stmt);
|
|
Extract_Stmt(in_on); // extracting DVM-directive (ON)
|
|
in_on = NULL;
|
|
}
|
|
Extract_Stmt(stmt); // extracting DVM-directive (END_ON)
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return; /* podd 07.06.11*/
|
|
|
|
SEQ_PROG:
|
|
for(stmt=first; stmt!=out ; stmt=stmt->lexNext()) {
|
|
cur_st = stmt;
|
|
switch(stmt->variant()) {
|
|
case ALLOCATE_STMT:
|
|
AllocatableArrayRegistration(stmt);
|
|
stmt=cur_st;
|
|
break;
|
|
case WRITE_STAT:
|
|
case READ_STAT:
|
|
case PRINT_STAT:
|
|
if(perf_analysis)
|
|
stmt = Any_IO_Statement(stmt);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
SgStatement *CreateCopyOfExecPartOfProcedure()
|
|
{
|
|
if(!debug_regim || dbg_if_regim <= 1) return(NULL);
|
|
|
|
return( cur_func->copyPtr() );
|
|
}
|
|
|
|
|
|
void InsertCopyOfExecPartOfProcedure(SgStatement *stc)
|
|
{ SgStatement *stmt, *stend, *ifst, *cur;
|
|
// cur = new SgStatement(DVM_DEBUG_DIR);
|
|
ifst = new SgIfStmt(*DebugIfNotCondition(), *new SgStatement(CONT_STAT));
|
|
first_exec->insertStmtBefore(*ifst,*first_exec->controlParent());
|
|
stend=stc->lastNodeOfStmt();
|
|
stmt = stend->lexPrev();
|
|
if(stmt->variant()!=RETURN_STAT)
|
|
stmt->insertStmtAfter(*new SgStatement(RETURN_STAT),*stend->controlParent());
|
|
|
|
for(stmt=stc; !isSgExecutableStatement(stmt); stmt=stmt->lexNext())
|
|
{;}
|
|
|
|
cur = ifst->lexNext();
|
|
cur->insertStmtAfter(*stmt);
|
|
cur->extractStmt();
|
|
TranslateBlock(ifst);
|
|
|
|
// for(stmt=first_exec; stmt != stend; stmt=stmt->nextInChildList())
|
|
//stmt=BLOB_VALUE(BLOB_NEXT(BIF_BLOB1(stmt->thebif)))
|
|
// { stc = stmt->copyPtr();
|
|
}
|
|
|
|
int lookForDVMdirectivesInBlock(SgStatement *first,SgStatement *last,int contains[] )
|
|
{ SgStatement *stmt;
|
|
int dvm_dir=0;
|
|
contains[0]=0;
|
|
contains[1]=0;
|
|
for(stmt=first; stmt ; stmt=stmt->lexNext()) {
|
|
switch(stmt->variant()) {
|
|
case CONTAINS_STMT:
|
|
case ENTRY_STAT:
|
|
contains[0]=1;
|
|
goto END__;
|
|
break;
|
|
|
|
case DVM_PARALLEL_ON_DIR:
|
|
|
|
case DVM_ASYNCHRONOUS_DIR:
|
|
case DVM_ENDASYNCHRONOUS_DIR:
|
|
case DVM_REDUCTION_START_DIR:
|
|
case DVM_REDUCTION_WAIT_DIR:
|
|
case DVM_SHADOW_GROUP_DIR:
|
|
case DVM_SHADOW_START_DIR:
|
|
case DVM_SHADOW_WAIT_DIR:
|
|
case DVM_REMOTE_ACCESS_DIR:
|
|
case DVM_NEW_VALUE_DIR:
|
|
case DVM_REALIGN_DIR:
|
|
case DVM_REDISTRIBUTE_DIR:
|
|
case DVM_ASYNCWAIT_DIR:
|
|
case DVM_F90_DIR:
|
|
case DVM_CONSISTENT_START_DIR:
|
|
case DVM_CONSISTENT_WAIT_DIR:
|
|
|
|
case DVM_INTERVAL_DIR:
|
|
case DVM_ENDINTERVAL_DIR:
|
|
case DVM_OWN_DIR:
|
|
case DVM_DEBUG_DIR:
|
|
case DVM_ENDDEBUG_DIR:
|
|
case DVM_TRACEON_DIR:
|
|
case DVM_TRACEOFF_DIR:
|
|
case DVM_BARRIER_DIR:
|
|
case DVM_CHECK_DIR:
|
|
|
|
case DVM_TASK_REGION_DIR:
|
|
case DVM_END_TASK_REGION_DIR:
|
|
case DVM_ON_DIR:
|
|
case DVM_END_ON_DIR:
|
|
case DVM_MAP_DIR:
|
|
case DVM_RESET_DIR:
|
|
case DVM_PREFETCH_DIR:
|
|
case DVM_PARALLEL_TASK_DIR:
|
|
case DVM_IO_MODE_DIR:
|
|
case DVM_LOCALIZE_DIR:
|
|
case DVM_SHADOW_ADD_DIR:
|
|
case DVM_TEMPLATE_CREATE_DIR:
|
|
case DVM_TEMPLATE_DELETE_DIR:
|
|
dvm_dir = 1;
|
|
break;
|
|
|
|
case OPEN_STAT:
|
|
case CLOSE_STAT:
|
|
case INQUIRE_STAT:
|
|
case BACKSPACE_STAT:
|
|
case ENDFILE_STAT:
|
|
case REWIND_STAT:
|
|
contains[1]=1;
|
|
break;
|
|
default:
|
|
if(isACCdirective(stmt)) /*ACC*/
|
|
dvm_dir = 1;
|
|
break;
|
|
}
|
|
if(stmt == last) break;
|
|
}
|
|
END__:
|
|
return(dvm_dir);
|
|
}
|
|
|
|
int IsGoToStatement(SgStatement *stmt)
|
|
{int vrnt;
|
|
vrnt=stmt->variant();
|
|
return(vrnt==GOTO_NODE || vrnt==COMGOTO_NODE || vrnt==ARITHIF_NODE);
|
|
}
|
|
|
|
void CopyDvmBegin(SgStatement *entry, SgStatement *first_dvm_exec, SgStatement *last)
|
|
{ SgStatement *stmt, *current, *cpst;
|
|
current = entry;
|
|
for(stmt=first_dvm_exec->lexNext(); stmt && stmt != last; stmt=stmt->lexNext())
|
|
{
|
|
cpst = &(stmt->copy());
|
|
current->insertStmtAfter(*cpst);
|
|
current = cpst;
|
|
}
|
|
}
|
|
|
|
void DoStmtsForENTRY(SgStatement *first_dvm_exec, SgStatement *last_dvm_entry)
|
|
{stmt_list *stl;
|
|
for(stl=entry_list; stl; stl=stl->next)
|
|
CopyDvmBegin(stl->st,first_dvm_exec,last_dvm_entry);
|
|
}
|
|
|
|
void UnparseFunctionsOfFile(SgFile *f,FILE *fout)
|
|
{
|
|
SgStatement *stat,*stmt;
|
|
//int i,numfun;
|
|
//int i;
|
|
//i=0;
|
|
//printf("Unparse Functions\n");
|
|
// grab the first statement in the file.
|
|
stat = f->firstStatement(); // file header
|
|
//numfun = f->numberOfFunctions(); // number of functions
|
|
// function is program unit accept BLOCKDATA and MODULE (F90),i.e.
|
|
// PROGRAM, SUBROUTINE, FUNCTION
|
|
// for(i = 0; i < numfun; i++) {
|
|
// func = f -> functions(i);
|
|
for( stmt=stat->lexNext();stmt;stmt=stmt->lexNext())
|
|
{ //printf("function %d: %s \n", i++,stmt->symbol()->identifier());
|
|
fprintf(fout,"%s",UnparseBif_Char(stmt->thebif,FORTRAN_LANG)); //or C_LANG
|
|
//printf("end function %d \n", i);
|
|
//i++;
|
|
stmt=stmt->lastNodeOfStmt();
|
|
}
|
|
}
|
|
|
|
void StructureProcessing(SgStatement *stmt)
|
|
{ SgStatement *st,*vd, *next_st;
|
|
|
|
next_st=stmt->lexNext();
|
|
while(next_st)
|
|
{ st = next_st;
|
|
//printf("%d",st->lineNumber());
|
|
next_st=next_st->lexNext();
|
|
//printf(" : %d\n",next_st->lineNumber());
|
|
switch(st->variant())
|
|
{ case(VAR_DECL):
|
|
if(only_debug)
|
|
{
|
|
VarDeclaration(st);
|
|
break;
|
|
}
|
|
vd=st;
|
|
while(vd)
|
|
vd=ProcessVarDecl(vd);
|
|
break;;
|
|
case(CONTROL_END):
|
|
return;
|
|
case(DVM_SHADOW_DIR):
|
|
{SgExpression *el;
|
|
SgExpression **she = new (SgExpression *);
|
|
SgSymbol *ar;
|
|
int nw=0;
|
|
if(only_debug)
|
|
{
|
|
st->extractStmt();
|
|
break;
|
|
}
|
|
// calculate lengh of shadow_list
|
|
for(el = st->expr(1); el; el=el->rhs())
|
|
nw++;
|
|
*she = st->expr(1);
|
|
for(el = st->expr(0); el; el=el->rhs()){ // array name list
|
|
ar = el->lhs()->symbol(); //array name
|
|
ar->addAttribute(SHADOW_WIDTH, (void *) she, sizeof(SgExpression *));
|
|
if (nw!=Rank(ar)) // wrong shadow width list
|
|
Error("Length of shadow-edge-list is not equal to the rank of array '%s'", ar->identifier(), 88, st);
|
|
}
|
|
st->extractStmt();
|
|
break;
|
|
|
|
}
|
|
|
|
case(DVM_DISTRIBUTE_DIR):
|
|
if( !only_debug && (st->expr(1) || st->expr(2)))
|
|
err("Only a distribute-directive of kind DISTRIBUTE:: is permitted in a derived type definition",337,st);
|
|
st->extractStmt();
|
|
break;
|
|
|
|
case(DVM_ALIGN_DIR):
|
|
if(!only_debug && (st->expr(1) || st->expr(2)))
|
|
err("Only an align-directive of kind ALIGN:: is permitted in a derived type definition",337,st);
|
|
st->extractStmt();
|
|
break;
|
|
|
|
case(DVM_VAR_DECL):
|
|
{ SgExpression *el;
|
|
if(only_debug)
|
|
{
|
|
st->extractStmt();
|
|
break;
|
|
}
|
|
|
|
for(el = st->expr(2); el; el=el->rhs()) // attribute list
|
|
switch(el->lhs()->variant()) {
|
|
case (ALIGN_OP):
|
|
if(el->lhs()->lhs() || el->lhs()->rhs())
|
|
err("Only an align-directive of kind ALIGN:: is permitted in a derived type definition",337,st);
|
|
break;
|
|
case (DISTRIBUTE_OP):
|
|
if(el->lhs()->lhs() || el->lhs()->rhs())
|
|
err("Only a distribute-directive of kind DISTRIBUTE:: is permitted in a derived type definition",337,st);
|
|
break;
|
|
case (SHADOW_OP):
|
|
{SgExpression *eln;
|
|
SgExpression **she = new (SgExpression *);
|
|
SgSymbol *ar;
|
|
int nw=0;
|
|
// calculate lengh of shadow_list
|
|
for(eln = el->lhs()->lhs() ; eln; eln=eln->rhs())
|
|
nw++;
|
|
*she = el->lhs()->lhs(); //shadow specification
|
|
for(eln = st->expr(0); eln; eln=eln->rhs()){ // array name list
|
|
ar = eln->lhs()->symbol(); //array name
|
|
ar->addAttribute(SHADOW_WIDTH, (void *) she, sizeof(SgExpression *));
|
|
if (nw!=Rank(ar)) // wrong shadow width list
|
|
Error("Length of shadow-edge-list is not equal to the rank of array '%s'", ar->identifier(), 88,st);
|
|
}
|
|
break;
|
|
}
|
|
case (DYNAMIC_OP):
|
|
default:
|
|
break;
|
|
}
|
|
st->extractStmt();
|
|
break;
|
|
}
|
|
case(DVM_DYNAMIC_DIR):
|
|
st->extractStmt();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
SgStatement *ProcessVarDecl(SgStatement *vd)
|
|
{ SgExpression *el, *elb, *e, *e2;
|
|
SgSymbol *s;
|
|
SgType *t;
|
|
SgStatement *std;
|
|
int ia;
|
|
el=vd->expr(0);
|
|
elb=NULL;
|
|
while(el)
|
|
{
|
|
s = el->lhs()->symbol();
|
|
if(!s) s=el->lhs()->lhs()->symbol(); // there is initialisation:POINTST_OP/ASSGN_OP
|
|
if(!s) return(NULL);
|
|
ia = s->attributes();
|
|
if(!(ia & DISTRIBUTE_BIT) && !(ia & ALIGN_BIT))
|
|
{ elb=el;
|
|
el=el->rhs();
|
|
} else
|
|
break;
|
|
}
|
|
if(!el)
|
|
{
|
|
VarDeclaration(vd);
|
|
return(NULL);
|
|
}
|
|
if(elb)
|
|
{ elb->setRhs(NULL);
|
|
std = &(vd->copy());
|
|
std->setExpression(0,*vd->expr(0));
|
|
vd->insertStmtBefore(*std);
|
|
VarDeclaration(std);
|
|
}
|
|
|
|
if(!(ia & POINTER_BIT))
|
|
//Error("Inconsistent declaration of identifier '%s'",s->identifier(),16,vd);
|
|
Warning("DISTRIBUTE or ALIGN attribute dictates POINTER attribute '%s'",s->identifier(),336,vd);
|
|
//create new statement for s and insert before statement vd
|
|
// new SgVarDeclStmt(SgExpression &varRefValList, SgExpression &attributeList, SgType &type);
|
|
e = el->lhs()->symbol() ? el->lhs() : el->lhs()->lhs();
|
|
e=new SgExprListExp(e->copy());
|
|
e->lhs()->setLhs(new SgExpression(DDOT));
|
|
//e->setRhs(NULL);
|
|
e2= new SgExprListExp(*new SgExpression(POINTER_OP));
|
|
if(len_DvmType)
|
|
{ SgExpression *le;
|
|
le = new SgExpression(LEN_OP);
|
|
le->setLhs(new SgValueExp(len_DvmType));
|
|
t = new SgType(T_INT, le, SgTypeInt());
|
|
|
|
} else
|
|
t = SgTypeInt();
|
|
|
|
std = new SgVarDeclStmt(*e,*e2,*t);
|
|
vd->insertStmtBefore(*std);
|
|
if(el->rhs())
|
|
{ vd->setExpression(0,*(el->rhs()));
|
|
return(vd);
|
|
} else
|
|
{ vd->extractStmt();
|
|
return(NULL);
|
|
}
|
|
}
|
|
|
|
void MarkCoeffsAsUsed()
|
|
{ symb_list *sl;
|
|
coeffs * c;
|
|
for(sl=dsym; sl; sl=sl->next)
|
|
{ c = AR_COEFFICIENTS(sl->symb); //((coeffs *) sl->symb-> attributeValue(0,ARRAY_COEF));
|
|
c->use = 1;
|
|
}
|
|
}
|
|
|
|
int isInternalOrModuleProcedure(SgStatement *header_st)
|
|
{
|
|
if((header_st->variant()==FUNC_HEDR || header_st->variant()==PROC_HEDR) &&
|
|
(header_st->controlParent()->variant() == MODULE_STMT || header_st->controlParent()->variant() != GLOBAL) )
|
|
return 1;
|
|
else
|
|
return 0;
|
|
|
|
}
|
|
|
|
int TestMaxDims(SgExpression *list, SgSymbol *ar, SgStatement *stmt)
|
|
{
|
|
int ndim = 0;
|
|
SgExpression *el;
|
|
for( el=list; el; el=el->rhs())
|
|
ndim++;
|
|
if(ndim>MAX_DIMS)
|
|
{
|
|
if(stmt)
|
|
Error("Too many dimensions specified for '%s'",ar->identifier(),43,stmt);
|
|
return 0;
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
|
|
void AnalyzeAsynchronousBlock(SgStatement *dir)
|
|
{
|
|
SgStatement *st,*end_dir=NULL, *stmt;
|
|
int contains[2];
|
|
int f90_dir_flag = 0;
|
|
if(dir->lexNext()->variant()==DVM_F90_DIR )
|
|
f90_dir_flag = 1;
|
|
|
|
SgStatement *end_of_func = cur_func->lastNodeOfStmt();
|
|
st = dir->lexNext();
|
|
while(st != end_of_func)
|
|
{
|
|
if(st->variant() == DVM_ENDASYNCHRONOUS_DIR)
|
|
{
|
|
end_dir = st;
|
|
break;
|
|
}
|
|
else
|
|
st = st->lexNext();
|
|
}
|
|
if(!end_dir)
|
|
{
|
|
err("Missing END ASYNCHRONOUS directive", 108, st);
|
|
return;
|
|
}
|
|
|
|
st = dir->lexNext();
|
|
|
|
if(f90_dir_flag)
|
|
{
|
|
while (st->variant() == DVM_F90_DIR)
|
|
st = st->lexNext();
|
|
if(!lookForDVMdirectivesInBlock(st, end_dir, contains ) || contains[0] || contains[1])
|
|
err("ASYNCHRONOS_ENDASYNCHRONOUS block contains illegal dvm-directive/statement", 901, dir);
|
|
|
|
stmt = st;
|
|
while(stmt != end_dir)
|
|
{
|
|
st = stmt;
|
|
stmt = lastStmtOf(stmt)->lexNext();
|
|
st->extractStmt();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(; st != end_dir; st=st->lexNext() )
|
|
if(st->variant() != ASSIGN_STAT || !isSgArrayRefExp(st->expr(0)) || !isSgArrayRefExp(st->expr(1)))
|
|
err("Illegal statement/directive in ASYNCHRONOS_ENDASYNCHRONOUS block", 901, st);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void Renaming(char *name, SgSymbol *s)
|
|
{
|
|
SYMB_IDENT(s->thesymb) = name;
|
|
}
|
|
|
|
void AddRenameNodeToUseList(SgSymbol *s)
|
|
{
|
|
SgSymbol *smod = ORIGINAL_SYMBOL(s)->scope()->symbol(); //module symbol
|
|
SgStatement *st, *st_use=NULL, *st_use_only=NULL;
|
|
SgExpression *el_use_only=NULL;
|
|
for(st=cur_func->lexNext(); st->variant()==USE_STMT; st=st->lexNext())
|
|
{
|
|
if(st->symbol() != smod)
|
|
continue;
|
|
if(!st->expr(0))
|
|
{
|
|
st_use = st;
|
|
continue;
|
|
}
|
|
SgExpression *el=st->expr(0);
|
|
if(el->variant()==ONLY_NODE)
|
|
for(el = el->lhs(); el; el=el->rhs())
|
|
{
|
|
if(el->lhs()->symbol() && el->lhs()->symbol()==ORIGINAL_SYMBOL(s))
|
|
{
|
|
st_use_only = st; el_use_only=el;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
st_use = st;
|
|
}
|
|
SgExpression *er = new SgExpression(RENAME_NODE, new SgVarRefExp(s), new SgVarRefExp(ORIGINAL_SYMBOL(s)));
|
|
if(st_use_only)
|
|
el_use_only->setLhs(er);
|
|
else if(st_use)
|
|
st_use->setExpression(0, AddElementToList(st_use->expr(0),er));
|
|
}
|
|
|
|
void CheckInrinsicNames()
|
|
{
|
|
int i;
|
|
SgSymbol *s = NULL;
|
|
|
|
for(i=0; i<NUM__F90; i++)
|
|
{
|
|
if(!f90[i])
|
|
continue;
|
|
s = isNameConcurrence(f90[i]->identifier(), cur_func);
|
|
if(!s)
|
|
continue;
|
|
if(IS_BY_USE(s))
|
|
{
|
|
if(!strcmp(s->identifier(),ORIGINAL_SYMBOL(s)->identifier()))
|
|
AddRenameNodeToUseList(s);
|
|
Renaming(Check_Correct_Name(s->identifier()),s);
|
|
break;
|
|
}
|
|
switch (s->variant())
|
|
{
|
|
case DEFAULT:
|
|
case MODULE_NAME:
|
|
case REF_GROUP_NAME:
|
|
Error("Object named '%s' should be renamed", s->identifier(), 662, cur_func);
|
|
break;
|
|
case FUNCTION_NAME:
|
|
case ROUTINE_NAME:
|
|
case PROCEDURE_NAME:
|
|
case PROGRAM_NAME:
|
|
if(s->attributes() & INTRINSIC_BIT)
|
|
;
|
|
else if(DECL(s)==2) // statement function
|
|
Renaming(Check_Correct_Name(s->identifier()),s);
|
|
else
|
|
Err_g("Object named '%s' should be renamed or declared as INTRINSIC", s->identifier(), 662);
|
|
break;
|
|
|
|
case SHADOW_GROUP_NAME:
|
|
case REDUCTION_GROUP_NAME:
|
|
case ASYNC_ID:
|
|
case CONSISTENT_GROUP_NAME:
|
|
case CONSTRUCT_NAME:
|
|
case INTERFACE_NAME:
|
|
case NAMELIST_NAME:
|
|
case TYPE_NAME:
|
|
case CONST_NAME:
|
|
Renaming(Check_Correct_Name(s->identifier()),s);
|
|
break;
|
|
case VARIABLE_NAME:
|
|
case LABEL_VAR:
|
|
if(IS_DUMMY(s))
|
|
Err_g("Object named '%s' should be renamed", s->identifier(), 662);
|
|
else
|
|
Renaming(Check_Correct_Name(s->identifier()),s);
|
|
break;
|
|
case FIELD_NAME:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
int DvmArrayRefInExpr (SgExpression *e)
|
|
{
|
|
if (!e) return 0;
|
|
if (isSgArrayRefExp(e) && HEADER(e->symbol()))
|
|
return 1;
|
|
if (DvmArrayRefInExpr(e->lhs()) || DvmArrayRefInExpr(e->rhs()))
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
int DvmArrayRefInConstruct (SgStatement *stat)
|
|
{ // stat - FORALL or WHERE statement/construct
|
|
SgStatement *out_st = lastStmtOf(stat)->lexNext();
|
|
SgStatement *st;
|
|
for (st = stat; st != out_st; st = st->lexNext())
|
|
{
|
|
if (DvmArrayRefInExpr(stat->expr(0)) || DvmArrayRefInExpr(stat->expr(1)) || DvmArrayRefInExpr(stat->expr(2)))
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
symb_list *SortingBySize(symb_list *redvar_list)
|
|
{//variables of 8 bytes are placed at the beginning of the redvar_list
|
|
SgSymbol *sym;
|
|
symb_list *sl, *sl_prev;
|
|
SgType *type;
|
|
for(sl=redvar_list, sl_prev=sl; sl; sl_prev=sl, sl=sl->next)
|
|
{
|
|
type = isSgArrayType(sl->symb->type()) ? sl->symb->type()->baseType() : sl->symb->type();
|
|
if(TypeSize(type) != 8) continue;
|
|
if(sl==redvar_list) continue;
|
|
sl_prev->next=sl->next;
|
|
sl->next=redvar_list;
|
|
redvar_list=sl;
|
|
sl=sl_prev;
|
|
}
|
|
return redvar_list;
|
|
} |