added project

This commit is contained in:
ALEXks
2023-09-14 19:43:13 +03:00
parent d78c55e275
commit 59c56cc5c2
638 changed files with 352236 additions and 92 deletions

View File

@@ -0,0 +1,27 @@
set(FDVM_SOURCES acc.cpp acc_across.cpp acc_across_analyzer.cpp acc_analyzer.cpp
acc_data.cpp acc_f2c.cpp acc_f2c_handlers.cpp acc_rtc.cpp acc_utilities.cpp
aks_analyzeLoops.cpp aks_structs.cpp calls.cpp checkpoint.cpp debug.cpp
dvm.cpp funcall.cpp help.cpp hpf.cpp io.cpp omp.cpp ompdebug.cpp parloop.cpp
stmt.cpp)
if(MSVC_IDE)
file(GLOB_RECURSE FDVM_HEADERS RELATIVE
${CMAKE_CURRENT_SOURCE_DIR} *.h)
foreach(DIR ${DVM_FORTRAN_INCLUDE_DIRS})
file(GLOB_RECURSE FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${DIR}/*.h")
set(FDVM_HEADERS ${FDVM_HEADERS} ${FILES})
endforeach()
endif()
add_executable(f_dvm ${FDVM_SOURCES} ${FDVM_HEADERS})
add_dependencies(f_dvm db sage sage++)
target_link_libraries(f_dvm db sage sage++)
target_compile_definitions(f_dvm PRIVATE SYS5)
target_include_directories(f_dvm PRIVATE "${DVM_FORTRAN_INCLUDE_DIRS}")
set_target_properties(f_dvm PROPERTIES
FOLDER "${DVM_TOOL_FOLDER}"
RUNTIME_OUTPUT_DIRECTORY ${DVM_BIN_DIR}
COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>
PDB_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>
)

View File

@@ -0,0 +1,158 @@
#echo#######################################################################
# Makefile for Fortran DVM back-end
#
#echo#######################################################################
SAGEROOT =../Sage
CONFIG_ARCH=iris4d
LIBDIR = ../libsage
#LIBDIR = $(SAGEROOT)/lib/$(CONFIG_ARCH)
#LIBDIR1 =/usr/people/podd/oldsrc
LIBDIR1 = $(LIBDIR)
LIBINCLUDE = $(SAGEROOT)/lib/include
HINCLUDE = $(SAGEROOT)/h
DVMINCLUDE = ../include
INSTALLDEST = ../bin
INSTALL = /bin/cp
#HP-ALLOCA#LDLIBS = -lPW#ENDIF#
#HP_CFLAGS#CEXTRA = -Aa#ENDIF#
CC = gcc
#USE_CC#CC=cc#ENDIF#
#CXX = DCC
CXX = g++
#USE_CFRONT#CXX=CC#ENDIF#
LOADER = $(CXX)
INCLUDE = -I. -I$(LIBINCLUDE) -I$(HINCLUDE) -I$(DVMINCLUDE)
#CFLAGS = $(INCLUDE) -Wall -c # $(CEXTRA)
CFLAGS = $(INCLUDE) -Wall -g -c # $(CEXTRA)
LDFLAGS =
LIBS = $(LIBDIR)/libSage++.a $(LIBDIR)/libsage.a $(LIBDIR)/libdb.a
DVM = f_dvm
OBGS = dvm.o funcall.o stmt.o io.o help.o debug.o hpf.o omp.o ompdebug.o acc.o acc_analyzer.o acc_across_analyzer.o calls.o acc_f2c.o acc_f2c_handlers.o acc_across.o aks_structs.o aks_analyzeLoops.o acc_data.o acc_rtc.o acc_utilities.o parloop.o checkpoint.o
# ***********************************************************
f: DVM
install: $(INSTALLDEST)/DVM
DVM: $(OBGS)
$(LOADER) $(LDFLAGS) $(OBGS) $(LIBS) -o $(DVM)
acc.o: acc.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) acc.cpp
acc_across.o: acc_across.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h $(DVMINCLUDE)/aks_structs.h
$(CXX) $(CFLAGS) acc_across.cpp
acc_across_analyzer.o: acc_across_analyzer.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h $(DVMINCLUDE)/acc_across_analyzer.h
$(CXX) $(CFLAGS) acc_across_analyzer.cpp
acc_analyzer.o: acc_analyzer.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h $(DVMINCLUDE)/acc_analyzer.h
$(CXX) $(CFLAGS) acc_analyzer.cpp
acc_data.o: acc_data.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) acc_data.cpp
acc_f2c.o: acc_f2c.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) acc_f2c.cpp
acc_f2c_handlers.o: acc_f2c_handlers.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) acc_f2c_handlers.cpp
acc_rtc.o: acc_rtc.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) acc_rtc.cpp
acc_utilities.o: acc_utilities.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) acc_utilities.cpp
aks_analyzeLoops.o: aks_analyzeLoops.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h $(DVMINCLUDE)/aks_structs.h
$(CXX) $(CFLAGS) aks_analyzeLoops.cpp
aks_structs.o: aks_structs.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h $(DVMINCLUDE)/aks_structs.h
$(CXX) $(CFLAGS) aks_structs.cpp
calls.o: calls.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) calls.cpp
checkpoint.o: checkpoint.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) checkpoint.cpp
debug.o: debug.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) debug.cpp
dvm.o: dvm.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) dvm.cpp
funcall.o: funcall.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) funcall.cpp
help.o: help.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) help.cpp
hpf.o: hpf.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) hpf.cpp
io.o: io.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) io.cpp
omp.o: omp.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) omp.cpp
ompdebug.o: ompdebug.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) ompdebug.cpp
parloop.o: parloop.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) parloop.cpp
stmt.o: stmt.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) stmt.cpp
$(INSTALLDEST)/DVM: DVM
@echo Installing $(DVM) in $(INSTALLDEST)
if [ -d $(INSTALLDEST) ] ; then true; \
else mkdir $(INSTALLDEST) ;fi
$(INSTALL) $(DVM) $(INSTALLDEST)
test: tdvm.o
tdvm.o: tdvm.cpp
$(CXX) -g -c tdvm.cpp
clean:
/bin/rm -f *.o *.dep $(DVM)
cleaninstall:
/bin/rm -f *.o $(DVM)

14197
dvm/fdvm/trunk/fdvm/acc.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
#include "leak_detector.h"
#include "acc_data.h"
// global data for ACC files
bool READ = false;
bool WRITE = true;
bool dontGenConvertXY = false;
bool oneCase = false;
int ACROSS_MOD_IN_KERNEL = 0;
int DVM_DEBUG_LVL = 0;
const int rtTypes[] = { rt_INT, rt_LLONG };
std::set<std::string> intrinsicF;
std::set<std::string> intrinsicDoubleT;
std::set<std::string> intrinsicFloatT;
std::set<std::string> intrinsicInt4T;
std::map<char, const char*> SpecialSymbols;
std::vector <SgFunctionCallExp* > RTC_FCall;
std::vector<SgExpression* > RTC_FArgs;
std::vector<SgFunctionCallExp* > RTC_FKernelArgs;
std::vector<SgSymbol*> newVars;
std::stack<SgStatement*> CopyOfBody;
const char *funcDvmhConvXYname = "dvmh_convert_XY";
Loop *currentLoop = NULL;
unsigned countKernels = 2;
int number_of_loop_line = 0; // for TRACE in acc_f2c.cpp
SgSymbol *s_indexType_int = NULL, *s_indexType_long = NULL, *s_indexType_llong = NULL;
SgType *indexType_int = NULL, *indexType_long = NULL, *indexType_llong = NULL;
const char *declaration_cmnt;
int loc_el_num;
SgStatement *cur_in_mod, *cur_in_kernel;
SgStatement *dvm_parallel_dir, *loop_body;
SgStatement *kernel_st;
SgExpression *private_list, *uses_list, *kernel_index_var_list, *formal_red_grid_list;
SgSymbol *kernel_symb, *s_overall_blocks;
SgType *t_dim3;
SgSymbol *s_threadidx, *s_blockidx, *s_blockdim, *s_griddim, *s_blocks_k;
//------ C ----------
SgStatement *block_C, *block_C_Cuda, *info_block;
SgSymbol *s_DvmhLoopRef, *s_cudaStream, *s_cmplx, *s_dcmplx;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,305 @@
#include "dvm.h"
void __convert_args(SgExpression *expr, SgExpression *&Arg, SgExpression *&Arg1, SgExpression *&Arg2)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
Arg = currArgs->lhs();
Arg1 = currArgs->rhs()->lhs();
Arg2 = currArgs->rhs()->rhs()->lhs();
convertExpr(Arg, Arg);
convertExpr(Arg1, Arg1);
convertExpr(Arg2, Arg2);
}
void __convert_args(SgExpression *expr, SgExpression *&Arg, SgExpression *&Arg1)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
Arg = currArgs->lhs();
Arg1 = currArgs->rhs()->lhs();
convertExpr(Arg, Arg);
convertExpr(Arg1, Arg1);
}
void __convert_args(SgExpression *expr, SgExpression *&Arg)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
Arg = currArgs->lhs();
convertExpr(Arg, Arg);
}
void __cmplx_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
int countArgs = 0;
bool kind = false;
int kind_val = -1;
int kind_pos = -1;
while (currArgs)
{
if (currArgs->lhs()->variant() == KEYWORD_ARG)
{
kind = true;
kind_val = currArgs->lhs()->rhs()->valueInteger();
kind_pos = countArgs;
}
countArgs++;
currArgs = currArgs->rhs();
}
if (kind == false)
{
if (countArgs == 1)
createNewFCall(expr, retExp, name, 1);
else if (countArgs == 2)
createNewFCall(expr, retExp, name, 2);
else if (countArgs == 3) // with KIND
{
kind_val = ((SgFunctionCallExp *)expr)->args()->rhs()->rhs()->lhs()->valueInteger();
if (kind_val == 4)
createNewFCall(expr, retExp, "cmplx2", 2);
else if (kind_val == 8)
createNewFCall(expr, retExp, "dcmplx2", 2);
else
createNewFCall(expr, retExp, name, 2);
}
}
else // with key word KIND
{
const char *name_kind;
if (kind_val == 4)
name_kind = "cmplx2";
else if (kind_val == 8)
name_kind = "dcmplx2";
else
name_kind = name;
if (countArgs == 2)
createNewFCall(expr, retExp, name_kind, 1);
else if (countArgs == 3)
{
if (kind_pos == 2)
createNewFCall(expr, retExp, name_kind, 2);
else if (kind_pos == 0)
{
SgFunctionCallExp *tmp = new SgFunctionCallExp(*createNewFunctionSymbol(NULL));
tmp->addArg(*((SgFunctionCallExp *)expr)->args()->rhs()->lhs());
tmp->addArg(*((SgFunctionCallExp *)expr)->args()->rhs()->rhs()->lhs());
createNewFCall(tmp, retExp, name_kind, 2);
}
else
createNewFCall(expr, retExp, "ERROR", 1);
}
}
}
void __minmax_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
SgFunctionCallExp *retFunc = createNewFCall(name);
//set first 2 agrs
SgExpression *Arg = currArgs->lhs();
convertExpr(Arg, Arg);
retFunc->addArg(*Arg);
currArgs = currArgs->rhs();
Arg = currArgs->lhs();
convertExpr(Arg, Arg);
retFunc->addArg(*Arg);
currArgs = currArgs->rhs();
//create nested MAX/MIN functions
while (currArgs)
{
SgFunctionCallExp *tmp = createNewFCall(name);
tmp->addArg(*retFunc);
Arg = currArgs->lhs();
convertExpr(Arg, Arg);
tmp->addArg(*Arg);
currArgs = currArgs->rhs();
retFunc = tmp;
}
retExp = retFunc;
}
static bool isArgIntType(SgExpression *Arg)
{
bool res = true;
if (Arg->variant() == VAR_REF)
{
SgType *tmp = Arg->symbol()->type();
if (tmp->equivalentToType(C_Type(SgTypeDouble())) ||
tmp->equivalentToType(C_Type(SgTypeFloat())))
res = false;
}
else
{
if (Arg->lhs())
res = res && isArgIntType(Arg->lhs());
if (Arg->rhs())
res = res && isArgIntType(Arg->rhs());
}
return res;
}
//TODO: add more complex analysis above
void __mod_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg, *Arg1;
__convert_args(expr, Arg, Arg1);
if (isArgIntType(Arg) && isArgIntType(Arg1))
retExp = &(*Arg % *Arg1);
else
{
retExp = createNewFCall("fmod");
((SgFunctionCallExp*) retExp)->addArg(*Arg);
((SgFunctionCallExp*) retExp)->addArg(*Arg1);
}
}
void __iand_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg, *Arg1;
__convert_args(expr, Arg, Arg1);
retExp = &(*Arg & *Arg1);
}
void __ior_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg, *Arg1;
__convert_args(expr, Arg, Arg1);
retExp = &(*Arg | *Arg1);
}
void __ieor_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg, *Arg1;
__convert_args(expr, Arg, Arg1);
SgExpression *xor_op = new SgExpression(XOR_OP);
xor_op->setLhs(*Arg);
xor_op->setRhs(*Arg1);
retExp = xor_op;
}
void __arc_sincostan_d_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg;
__convert_args(expr, Arg);
SgFunctionCallExp *retFunc = createNewFCall(name);
retFunc->addArg(*Arg);
retExp = &(*retFunc * *new SgValueExp(180.0) / *new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "CUDART_PI")));
}
void __atan2d_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg, *Arg1;
__convert_args(expr, Arg, Arg1);
SgFunctionCallExp *retFunc = createNewFCall(name);
retFunc->addArg(*Arg);
retFunc->addArg(*Arg1);
retExp = &(*retFunc * *new SgValueExp(180.0) / *new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "CUDART_PI")));
}
void __sindcosdtand_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg;
__convert_args(expr, Arg);
SgFunctionCallExp *retFunc = createNewFCall(name);
retFunc->addArg(*Arg * *new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "CUDART_PI")) / *new SgValueExp(180.0));
retExp = retFunc;
}
void __cotan_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg;
__convert_args(expr, Arg);
SgFunctionCallExp *retFunc = createNewFCall(name);
retFunc->addArg(*Arg);
retExp = &(*new SgValueExp(1.0) / *retFunc);
}
void __cotand_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg;
__convert_args(expr, Arg);
SgFunctionCallExp *retFunc = createNewFCall(name);
retFunc->addArg(*Arg * *new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "CUDART_PI")) / *new SgValueExp(180.0));
retExp = &(*new SgValueExp(1.0) / *retFunc);
}
void __ishftc_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
int countArgs = 0;
while (currArgs)
{
countArgs++;
currArgs = currArgs->rhs();
}
switch (countArgs)
{
case 2:
createNewFCall(expr, retExp, "ishc", 2);
break;
case 3:
createNewFCall(expr, retExp, name, 3);
break;
default:
//printf("this function takes 2 or 3 arguments");
break;
}
}
void __merge_bits_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression* Arg, * Arg1, * Arg2;
__convert_args(expr, Arg, Arg1, Arg2);
SgExpression *xor_op = new SgExpression(XOR_OP);
xor_op->setLhs(*Arg2);
xor_op->setRhs(*new SgValueExp(-1));
retExp = &((*Arg & *Arg2) | (*Arg1 & *xor_op));
}
void __not_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression* Arg;
__convert_args(expr, Arg);
SgExpression* xor_op = new SgExpression(XOR_OP);
xor_op->setLhs(*Arg);
xor_op->setRhs(*new SgValueExp(-1));
retExp = xor_op;
}
void __poppar_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression* Arg;
__convert_args(expr, Arg);
SgFunctionCallExp* func = createNewFCall(name);
func->addArg(*Arg);
retExp = &(*func & *new SgValueExp(1));
}
void __modulo_handler(SgExpression* expr, SgExpression*& retExp, const char* name, int nArgs)
{
SgExpression* Arg, * Arg1;
__convert_args(expr, Arg, Arg1);
SgFunctionCallExp* floor = createNewFCall("floor");
SgFunctionCallExp* doubleA = createNewFCall("double");
doubleA->addArg(*Arg);
SgFunctionCallExp* doubleB = createNewFCall("double");
doubleB->addArg(*Arg1);
floor->addArg(*doubleA / *doubleB);
retExp = &(*Arg - *Arg1 * *floor);
}

View File

@@ -0,0 +1,58 @@
#include "acc_data.h"
extern SgStatement *kernelScope;
static int indexGenerator = 0;
SgExpression* analyzeArrayIndxs(SgSymbol *array, SgExpression *listIdx)
{
SgSymbol *varName = NULL;
char *strNum = new char[32];
char *strArray, *newStr;
if (listIdx == NULL || !autoTransform || dontGenConvertXY || oneCase)
return NULL;
else
{
strArray = array->identifier();
newStr = new char[strlen(strArray) + 32];
Array *tArray = currentLoop->getArray(strArray);
if (tArray)
{
char *charEx = NULL;
SgSymbol *tSymb = tArray->findAccess(listIdx, charEx);
if (tSymb == NULL)
{
newStr[0] = '\0';
strcat(newStr, strArray);
strcat(newStr, "_");
sprintf(strNum, "%d", (int) indexGenerator);
indexGenerator++;
strcat(newStr, strNum);
if (C_Cuda)
varName = new SgSymbol(VARIABLE_NAME, TestAndCorrectName(newStr), *C_DvmType(), *kernelScope);
else
{
if (undefined_Tcuda)
{
SgExpression *le;
le = new SgExpression(LEN_OP);
le->setLhs(new SgValueExp(8));
varName = new SgSymbol(VARIABLE_NAME, TestAndCorrectName(newStr), *new SgType(T_INT, le, SgTypeInt()), *kernelScope);
}
else
varName = new SgSymbol(VARIABLE_NAME, TestAndCorrectName(newStr), *SgTypeInt(), *kernelScope);
}
tArray->addNewCoef(listIdx, charEx, varName);
}
else
varName = tSymb;
}
}
delete[]strNum;
return new SgVarRefExp(varName);
}

View File

@@ -0,0 +1,384 @@
#include "dvm.h"
#include "acc_data.h"
#include "calls.h"
//TMP:
extern symb_list *acc_call_list, *by_value_list;
// create comments of call procedures from each kernel in file _info.c
// if -FTN_Cuda option selected
void ACC_RTC_AddCalledProcedureComment(SgSymbol *symbK)
{
symb_list *sl;
int len = 0;
for (sl = acc_call_list; sl; sl = sl->next)
len = len + strlen(sl->symb->identifier()) + 1;
char *list_txt = new char[len + 1];
list_txt[0] = '\0';
for (sl = acc_call_list; sl; sl = sl->next)
{
strcat(list_txt, " ");
strcat(list_txt, sl->symb->identifier());
}
info_block->addComment(CalledProcedureComment(list_txt, symbK));
}
// complete rtc launch parameters from cuda-handlers
void ACC_RTC_CompleteAllParams()
{
for (unsigned fc = 0; fc < RTC_FCall.size(); ++fc)
{
SgFunctionCallExp *fCall = RTC_FKernelArgs[fc];
if (fCall->variant() == EXPR_LIST) // if Fortran CUDA
{
fCall = new SgFunctionCallExp(*createNewFunctionSymbol(""));
SgExpression *tmp = RTC_FKernelArgs[fc];
while (tmp)
{
fCall->addArg(*tmp->lhs());
tmp = tmp->rhs();
}
}
SgExpression *argList = RTC_FArgs[fc];
for (int k = 0; k < fCall->numberOfArgs(); ++k)
{
SgExpression *currArg = fCall->arg(k);
bool dontCast = false;
if (currArg->variant() == DEREF_OP)
currArg = currArg->lhs();
if (currArg->symbol() == NULL)
{
RTC_FCall[fc]->addArg(*new SgValueExp("<!!! NULL !!!>"));
argList = argList->rhs();
continue;
}
std::string tmpN = currArg->symbol()->identifier();
bool isarray = isSgArrayType(currArg->symbol()->type());
bool ispointer = isSgPointerType(currArg->symbol()->type());
bool notbyval = true;
symb_list *sl;
for (sl = by_value_list; sl; sl = sl->next)
{
if (strcmp(sl->symb->identifier(), currArg->symbol()->identifier()) == 0)
{
notbyval = false;
break;
}
}
bool isinuser = isInUsesListByChar(currArg->symbol()->identifier());
if (isarray || ispointer || notbyval && isinuser)
{
RTC_FCall[fc]->addArg(*new SgValueExp(""));
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_POINTER")));
RTC_FCall[fc]->addArg(*argList->lhs());
}
else
{
SgType *tmp = currArg->symbol()->type();
if (tmp->hasBaseType())
tmp->baseType();
unsigned UnFlag = ((SgDescriptType*)tmp)->modifierFlag() & BIT_UNSIGNED;
SgAttribute *attr = argList->lhs()->getAttribute(0);
bool toAdd = false;
if (attr != NULL)
{
if (attr->getAttributeType() == RTC_NOT_REPLACE)
RTC_FCall[fc]->addArg(*new SgValueExp(""));
else
toAdd = true;
}
else
toAdd = true;
if (toAdd)
{
if (options.isOn(C_CUDA))
RTC_FCall[fc]->addArg(*new SgValueExp(currArg->symbol()->identifier()));
else
{
// PGI adds to scalars n__V_ !!
std::string tmp = "n__V_";
tmp += aks_strlowr(currArg->symbol()->identifier());
RTC_FCall[fc]->addArg(*new SgValueExp(tmp.c_str()));
}
}
if (tmp->equivalentToType(C_Type(SgTypeChar())) || tmp->equivalentToType(SgTypeChar()))
{
if (UnFlag)
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_UCHAR")));
else
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_CHAR")));
}
else if (tmp->equivalentToType(C_Type(SgTypeInt())) || (tmp->equivalentToType(SgTypeInt())))
{
if (isSgDescriptType(tmp))
{
SgDescriptType *t = (SgDescriptType*)tmp;
int flag = t->modifierFlag();
if ((flag & BIT_LONG) != 0)
{
if (UnFlag)
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_ULONG")));
else
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_LONG")));
}
else if ((flag & BIT_SHORT) != 0)
{
if (UnFlag)
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_USHORT")));
else
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_SHORT")));
}
else
{
if (UnFlag)
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_UINT")));
else
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_INT")));
}
}
else
{
if (UnFlag)
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_UINT")));
else
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_INT")));
}
}
else if (tmp->equivalentToType(C_LongType()))
{
if (UnFlag)
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_ULONG")));
else
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_LONG")));
}
else if (tmp->equivalentToType(C_LongLongType()))
{
if (UnFlag)
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_ULLONG")));
else
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_LLONG")));
}
else if (tmp->equivalentToType(C_Type(SgTypeFloat())) || tmp->equivalentToType(SgTypeFloat()))
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_FLOAT")));
else if (tmp->equivalentToType(C_Type(SgTypeDouble())) || tmp->equivalentToType(SgTypeDouble()))
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_DOUBLE")));
else if (tmp->equivalentToType(indexTypeInKernel(rt_INT)))
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_INT")));
else if (tmp->equivalentToType(indexTypeInKernel(rt_LONG)))
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_LONG")));
else if (tmp->equivalentToType(indexTypeInKernel(rt_LLONG)))
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_LLONG")));
else if (tmp->equivalentToType(C_Derived_Type(s_cmplx)))
{
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_FLOAT_COMPLEX")));
SgSymbol *symb = createNewFunctionSymbol("real");
RTC_FCall[fc]->addArg(*new SgFunctionCallExp(*symb, *new SgExpression(EXPR_LIST, argList->lhs(), NULL, NULL)));
symb = createNewFunctionSymbol("imag");
RTC_FCall[fc]->addArg(*new SgFunctionCallExp(*symb, *new SgExpression(EXPR_LIST, argList->lhs(), NULL, NULL)));
dontCast = true;
}
else if (tmp->equivalentToType(C_Derived_Type(s_dcmplx)))
{
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_DOUBLE_COMPLEX")));
SgSymbol *symb = createNewFunctionSymbol("real");
RTC_FCall[fc]->addArg(*new SgFunctionCallExp(*symb, *new SgExpression(EXPR_LIST, argList->lhs(), NULL, NULL)));
symb = createNewFunctionSymbol("imag");
RTC_FCall[fc]->addArg(*new SgFunctionCallExp(*symb, *new SgExpression(EXPR_LIST, argList->lhs(), NULL, NULL)));
dontCast = true;
}
else
{
RTC_FCall[fc]->addArg(*new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "rt_UNKNOWN")));
fprintf(stderr, "Warning[-rtc]: unknown type with variant %d for kernel lauch\n", tmp->variant());
}
if (dontCast == false)
RTC_FCall[fc]->addArg(*new SgCastExp(*tmp, *argList->lhs()));
}
argList = argList->rhs();
}
}
RTC_FKernelArgs.clear();
RTC_FArgs.clear();
RTC_FCall.clear();
}
// convert unparse buffer for RTC call
char* _RTC_convertUnparse(const char* inBuf)
{
int count = 0;
for (unsigned i = 0; i < strlen(inBuf); ++i)
{
if (SpecialSymbols.find(inBuf[i]) != SpecialSymbols.end())
count += strlen(SpecialSymbols[inBuf[i]]);
}
std::string strBuf = "";
for (unsigned i = 0; i < strlen(inBuf); ++i)
{
if (SpecialSymbols.find(inBuf[i]) != SpecialSymbols.end())
{
const char *tmp = SpecialSymbols[inBuf[i]];
for (unsigned k1 = 0; k1 < strlen(tmp); ++k1)
strBuf.push_back(tmp[k1]);
}
else
strBuf.push_back(inBuf[i]);
}
strBuf += "#undef dcmplx2\\n\"\n\"#undef cmplx2\\n";
char *newBuf = new char[strlen(strBuf.c_str()) + 1];
strcpy(newBuf, strBuf.c_str());
return newBuf;
}
// convert cuda kernel to static const char*
void ACC_RTC_ConvertCudaKernel(SgStatement *cuda_kernel, const char *kernelName)
{
if (cuda_kernel != NULL)
{
cuda_kernel->addComment("#define dcmplx2 Complex<double>\n#define cmplx2 Complex<float>\nextern \"C\"\n");
char *buf = copyOfUnparse(UnparseBif_Char(cuda_kernel->thebif, C_LANG));
char *newBuf = _RTC_convertUnparse(buf);
SgPointerType *arrType = new SgPointerType(*C_Type(SgTypeChar()));
SgSymbol *cuda_kernel_code = new SgSymbol(VARIABLE_NAME, kernelName, arrType, mod_gpu);
SgStatement *decl = makeSymbolDeclarationWithInit(cuda_kernel_code, new SgValueExp(newBuf));
decl->addDeclSpec(BIT_CONST);
decl->addDeclSpec(BIT_STATIC);
cuda_kernel->insertStmtBefore(*decl);
if(acc_call_list)
{
symb_list **call_list = new (symb_list *);
*call_list = acc_call_list;
decl->addAttribute(RTC_CALLS, (void*)call_list, sizeof(symb_list *));
}
cuda_kernel->deleteStmt();
delete[] buf;
}
}
static symb_list *_RTC_addCalledToList(symb_list *call_list, graph_node *gnode)
{
edge *gedge;
for (gedge = gnode->to_called; gedge; gedge = gedge->next)
if(gedge->to->st_header)
{ call_list = AddNewToSymbList(call_list, gedge->to->symb);
call_list = _RTC_addCalledToList(call_list, gedge->to);
}
return call_list;
}
symb_list *ACC_RTC_ExpandCallList(symb_list *call_list)
{
symb_list *sl;
for (sl = call_list; sl; sl = sl->next)
{
if (!ATTR_NODE(sl->symb))
continue;
call_list = _RTC_addCalledToList(call_list, GRAPHNODE(sl->symb));
}
return call_list;
}
char* _RTC_PrototypesForKernel(symb_list *call_list)
{
SgStatement *st = NULL;
symb_list *sl = call_list;
st = FunctionPrototype(GRAPHNODE(sl->symb)->st_copy->symbol());
st->addDeclSpec(BIT_CUDA_DEVICE);
st->addDeclSpec(BIT_STATIC);
st->addComment("#define dcmplx2 Complex<double>\n#define cmplx2 Complex<float>\n");
char *buffer = copyOfUnparse(UnparseBif_Char(st->thebif, C_LANG));
for (sl = call_list->next; sl; sl = sl->next)
{
st = FunctionPrototype(GRAPHNODE(sl->symb)->st_copy->symbol());
st->addDeclSpec(BIT_CUDA_DEVICE);
st->addDeclSpec(BIT_STATIC);
char *unp_buf = UnparseBif_Char(st->thebif, C_LANG);
char *buf = new char[strlen(buffer) + strlen(unp_buf) + 1];
strcpy(buf, buffer);
strcat(buf, unp_buf);
delete[] buffer;
buffer = buf;
}
return (buffer);
}
void _RTC_UnparsedFunctionsToKernelConst(SgStatement *stmt)
{
if (CALLED_FUNCTIONS(stmt) == NULL)
return;
symb_list *call_list = *CALLED_FUNCTIONS(stmt);
graph_node * gnode = NULL;
char *buffer = _RTC_PrototypesForKernel(call_list);
for (; call_list; call_list = call_list->next)
{
gnode = GRAPHNODE(call_list->symb);
char *unp_buf = UnparseBif_Char(gnode->st_copy->thebif, C_LANG);
char *buf = new char[strlen(unp_buf) + strlen(buffer) + 1];
//buf[0] = '\0';
strcpy(buf, buffer);
strcat(buf, unp_buf);
delete[] buffer;
buffer = buf;
}
buffer = _RTC_convertUnparse(buffer);
char *kernel_buf = ((SgValueExp *)((SgVarDeclStmt *)stmt)->initialValue(0))->stringValue();
char *allBuf = new char[strlen(kernel_buf) + strlen(buffer) + 1];
strcpy(allBuf, buffer);
strcat(allBuf, kernel_buf);
((SgVarDeclStmt *)stmt)->setInitialValue(0, *new SgValueExp(allBuf));
delete[] kernel_buf;
delete[] buffer;
}
void ACC_RTC_AddFunctionsToKernelConsts(SgStatement *first_kernel_const)
{
SgStatement *stmt = mod_gpu, *next = NULL;
for (stmt = first_kernel_const; stmt; stmt = stmt->lexNext())
_RTC_UnparsedFunctionsToKernelConst(stmt);
stmt = mod_gpu;
next = mod_gpu->lexNext();
// extracting function copies
//while(next->variant() != VAR_DECL)
while (next != first_kernel_const)
{
stmt = next;
next = next->lastNodeOfStmt()->lexNext();
stmt->extractStmt();
}
}

View File

@@ -0,0 +1,87 @@
// all unused code
#include "dvm.h"
/* FROM acc_index_analyzer (aks_structs.cpp) */
int dimentionOfArray(SgExpression *listIdxIn)
{
int dim = 0;
SgExpression *listIdx = listIdxIn;
while (listIdx)
{
dim++;
listIdx = listIdx->rhs();
}
return dim;
}
bool ifExist(std::vector<char*> &listL, char *str)
{
bool retval = false;
for (size_t i = 0; i < listL.size(); ++i)
{
if (strcmp(str, listL[i]) == 0)
{
retval = true;
break;
}
}
return retval;
}
int GetIdxPlaceInParDir(SageSymbols *inList, SgSymbol *id)
{
int ret = -1;
int count = 0;
SageSymbols *tmp = inList;
while (tmp)
{
if (strcmp(tmp->symb->identifier(), id->identifier()) == 0)
{
ret = count;
break;
}
count++;
tmp = tmp->next;
}
return ret;
}
/* END BLOCK */
/* FORM acc.app*/
template<int numFields> SgType *Type_N(SgType *type, char *name);
template<int numFields>
SgType *Type_N(SgType *type, char *name)
{
SgSymbol *s_t = new SgSymbol(TYPE_NAME, name, *kernel_st);
SgFieldSymb *sx, *sy, *sz, *sw, *s;
if (numFields >= 1)
s = sx = new SgFieldSymb("x", *type, *s_t);
if (numFields >= 2)
{
s = sy = new SgFieldSymb("y", *type, *s_t);
SYMB_NEXT_FIELD(sx->thesymb) = sy->thesymb;
}
if (numFields >= 3)
{
s = sz = new SgFieldSymb("z", *type, *s_t);
SYMB_NEXT_FIELD(sy->thesymb) = sz->thesymb;
}
if (numFields >= 4)
{
s = sw = new SgFieldSymb("w", *type, *s_t);
SYMB_NEXT_FIELD(sz->thesymb) = sw->thesymb;
}
SYMB_NEXT_FIELD(s->thesymb) = NULL;
SgType *tstr = new SgType(T_STRUCT);
TYPE_COLL_FIRST_FIELD(tstr->thetype) = sx->thesymb;
s_t->setType(tstr);
SgType *td = new SgType(T_DERIVED_TYPE);
TYPE_SYMB_DERIVE(td->thetype) = s_t->thesymb;
TYPE_SYMB(td->thetype) = s_t->thesymb;
return(td);
}
/* END BLOCK */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,615 @@
#include "dvm.h"
#include "acc_data.h"
#include "aks_structs.h"
#include "aks_loopStructure.h"
extern SgStatement *dvm_parallel_dir;
extern SgStatement* AssignStatement(SgExpression &lhs, SgExpression &rhs);
using namespace std;
// ---------------------------------------------------------------------- // Access
Access::Access(SgExpression *_exp, Array *_parent)
{
exp = _exp;
expAcc = copyOfUnparse(exp->unparse());
operation[0] = operation[1] = 0;
parentArray = _parent;
}
// only one idx in one dimention in exp
void Access::matchLoopIdxs(vector<SgSymbol*> &symbols)
{
SgExpression *tmp = exp;
int idx = 0;
if (alignOnLoop.size() == 0)
alignOnLoop = vector<int>(parentArray->getDimNum());
while (tmp)
{
for (unsigned i = 0; i < symbols.size(); ++i)
{
alignOnLoop[idx] = -1;
if (matchRecursion(tmp->lhs(), symbols[i]))
{
alignOnLoop[idx] = i;
break;
}
}
idx++;
tmp = tmp->rhs();
}
}
bool Access::matchRecursion(SgExpression *_exp, SgSymbol *symb)
{
bool retVal = false;
SgExpression *left = _exp->lhs();
SgExpression *right = _exp->rhs();
if (_exp->variant() != VAR_REF)
{
if (left)
retVal = retVal || matchRecursion(left, symb);
if (right)
retVal = retVal || matchRecursion(right, symb);
}
else
{
SgSymbol *s = _exp->symbol();
if (strcmp(s->identifier(), symb->identifier()) == 0)
retVal = true;
}
return retVal;
}
void Access::setExp(char* _exp) { expAcc = _exp; }
void Access::setExp(SgExpression *_exp) { exp = _exp; }
char* Access::getExpChar() { return expAcc; }
SgExpression* Access::getExp() { return exp; }
void Access::incOperW() { operation[1]++; }
void Access::incOperR() { operation[0]++; }
Array* Access::getParentArray() { return parentArray; }
void Access::setParentArray(Array *_parent) { parentArray = _parent; }
std::vector<int>* Access::getAlignOnLoop() { return &alignOnLoop; }
// ---------------------------------------------------------------------- // Array
Array::Array(int _dim, char *_name, Loop *_parent)
{
dimNum = _dim;
name = _name;
parentLoop = _parent;
acrossType = 0;
}
Array::Array(char *_name, Loop *_parent)
{
name = _name;
parentLoop = _parent;
acrossType = 0;
}
Access* Array::getAccess(char* _expAcc)
{
int idx = -1;
for (unsigned i = 0; i < accesses.size(); ++i)
{
if (strcmp(_expAcc, accesses[i]->getExpChar()) == 0)
{
idx = i;
break;
}
}
if (idx == -1)
return NULL;
else
return accesses[idx];
}
void Array::analyzeAcrDims()
{
SgExpression *tmp = dvm_parallel_dir->expr(1);
bool fieled = false;
while (tmp)
{
SgExpression *t = tmp->lhs();
unsigned numberOfAcr = 0;
if (t->variant() == ACROSS_OP)
{
t = t->lhs();
while (t)
{
if (strcmp(name, t->lhs()->symbol()->identifier()) == 0)
{
fieled = true;
SgExpression *tt = t->lhs()->lhs();
while (tt)
{
bool acrossYes = false;
if (tt->lhs()->lhs()->valueInteger() != 0)
acrossYes = true;
if (tt->lhs()->rhs()->valueInteger() != 0)
acrossYes = true;
if (acrossYes)
{
acrossDims.push_back(1);
numberOfAcr++;
}
else
acrossDims.push_back(0);
tt = tt->rhs();
}
}
t = t->rhs();
}
}
if (numberOfAcr != 0)
acrossType = (1 << numberOfAcr) - 1;
tmp = tmp->rhs();
}
if (fieled == false)
{
for (int i = 0; i < dimNum; ++i)
acrossDims.push_back(-1);
}
if (abs(dimNum - parentLoop->getLoopDim()))
{
for (int i = 0; i < abs(dimNum - parentLoop->getLoopDim()); i++)
acrossDims.push_back(-1);
}
}
void Array::analyzeAlignOnLoop()
{
alignOnLoop = std::vector<int>(dimNum);
for (int i = 0; i < dimNum; ++i)
alignOnLoop[i] = -1;
if (accesses.size() > 0)
{
for (unsigned i = 0; i < accesses.size(); ++i)
{
if (accesses[i]->getAlignOnLoop()->size() == 0)
accesses[i]->matchLoopIdxs(*parentLoop->getSymbols());
}
int *tmp = new int[dimNum];
for (int i = 0; i < dimNum; ++i)
tmp[i] = (*(accesses[0]->getAlignOnLoop()))[i];
bool eq = true;
for (unsigned i = 1; i < accesses.size(); ++i)
{
bool ok = true;
for (int k = 0; k < dimNum; ++k)
{
if (tmp[k] != (*(accesses[i]->getAlignOnLoop()))[k])
{
ok = false;
break;
}
}
if (!ok)
{
eq = false;
break;
}
}
if (eq)
{
for (int i = 0; i < dimNum; ++i)
alignOnLoop[i] = tmp[i];
}
}
}
void Array::analyzeTrDims()
{
int dimParLoop = parentLoop->getLoopDim();
int idxAcrossSymb1 = -1;
int idxAcrossSymb2 = -1;
// all for's of Loop with across
if (dimParLoop > 1 && parentLoop->getAcrType() > 1)
{
if (parentLoop->getAcrType() == dimParLoop)
{
idxAcrossSymb1 = dimParLoop - 1;
idxAcrossSymb2 = dimParLoop - 2;
}
else
{
int t = 0;
for (int p = (int)(acrossDims.size() - 1); p >= 0 && t != 2; --p)
{
if (acrossDims[p] == 1)
{
idxAcrossSymb1 = p;
t++;
}
}
}
int idxInArray1 = -1;
int idxInArray2 = -1;
for (unsigned i = 0; i < alignOnLoop.size(); ++i)
{
if (alignOnLoop[i] == idxAcrossSymb1)
idxInArray1 = i;
else if (alignOnLoop[i] == idxAcrossSymb2)
idxInArray2 = i;
}
if (idxInArray1 != -1 && idxInArray2 != -1)
{
// inverse idxInArray and count from "1"
idxInArray1 = dimNum - idxInArray1;
idxInArray2 = dimNum - idxInArray2;
}
addTfmDim(idxInArray1);
addTfmDim(idxInArray2);
}
}
SgSymbol* Array::findAccess(SgExpression *_exp, char *&_charEx)
{
SgSymbol *retVal = NULL;
char *retStr = new char[1024]; // WARNING!! may be segfault
SgExpression *tmp = _exp;
retStr[0] = '\0';
int out = 0;
int idx = 0;
while (tmp && out != 2)
{
if (dimNum - idx == transformDims[0] || dimNum - idx == transformDims[1])
{
strcat(retStr, UnparseExpr(tmp->lhs()));
strcat(retStr, "_");
out++;
}
idx++;
tmp = tmp->rhs();
}
for (unsigned i = 0; i < charEx.size(); ++i)
{
if (strcmp(charEx[i], retStr) == 0)
{
retVal = coefInAccess[i];
break;
}
}
if (retVal == NULL)
{
_charEx = new char[strlen(retStr) + 1];
_charEx[0] = '\0';
strcat(_charEx, retStr);
}
delete []retStr;
return retVal;
}
void Array::addNewCoef(SgExpression *_exp, char *_charEx, SgSymbol* _symb)
{
SgExpression *tmp = _exp;
int out = 0;
int idx = 0;
while (tmp && out != 2)
{
if (dimNum - idx == transformDims[0])
firstEx.push_back(tmp->lhs());
else if (dimNum - idx == transformDims[1])
secondEx.push_back(tmp->lhs());
idx++;
tmp = tmp->rhs();
}
charEx.push_back(_charEx);
coefInAccess.push_back(_symb);
}
void Array::generateAssigns(SgVarRefExp *offsetX, SgVarRefExp *offsetY, SgVarRefExp *Rx, SgVarRefExp *Ry, SgVarRefExp *slash)
{
if (ifCalls.size() == 0 && elseCalls.size() == 0 && zeroSt.size() == 0)
{
for (unsigned i = 0; i < coefInAccess.size(); ++i)
{
zeroSt.push_back(AssignStatement(*new SgVarRefExp(coefInAccess[i]->copy()), *new SgValueExp(0)));
SgFunctionCallExp *funcCallExpIf, *funcCallExpElse;
funcCallExpIf = new SgFunctionCallExp(*(new SgSymbol(FUNCTION_NAME, funcDvmhConvXYname)));
funcCallExpElse = new SgFunctionCallExp(*(new SgSymbol(FUNCTION_NAME, funcDvmhConvXYname)));
funcCallExpIf->addArg(firstEx[i]->copy() - *offsetX);
funcCallExpIf->addArg(secondEx[i]->copy() - *offsetY);
funcCallExpIf->addArg(*Rx);
funcCallExpIf->addArg(*Ry);
funcCallExpIf->addArg(*slash);
funcCallExpIf->addArg(*new SgVarRefExp(coefInAccess[i]->copy()));
funcCallExpElse->addArg(secondEx[i]->copy() - *offsetX);
funcCallExpElse->addArg(firstEx[i]->copy() - *offsetY);
funcCallExpElse->addArg(*Rx);
funcCallExpElse->addArg(*Ry);
funcCallExpElse->addArg(*slash);
funcCallExpElse->addArg(*new SgVarRefExp(coefInAccess[i]->copy()));
ifCalls.push_back(funcCallExpIf);
elseCalls.push_back(funcCallExpElse);
}
}
}
void Array::setDimNum(int _num) { dimNum = _num; }
int Array::getDimNum() { return dimNum; }
Loop* Array::getParentLoop() { return parentLoop; }
void Array::setParentLoop(Loop *_loop) { parentLoop = _loop; }
vector<int>* Array::getAcrDims() { return &acrossDims; }
vector<int>* Array::getAlignOnLoop() { return &alignOnLoop; }
void Array::addTfmDim(int _dim) { transformDims.push_back(_dim); }
vector<int>* Array::getTfmDims() { return &transformDims; }
void Array::addAccess(Access* _newAccess) { accesses.push_back(_newAccess); }
vector<Access*>* Array::getAccesses() { return &accesses; }
void Array::setArrayName(char* _name) { name = _name; }
char* Array::getArrayName() { return name; }
int Array::getAcrType() { return acrossType; }
void Array::setAcrType(int _type) { acrossType = _type; }
vector<SgFunctionCallExp*>* Array::getIfCals() { return &ifCalls; }
vector<SgFunctionCallExp*>* Array::getElseCals() { return &elseCalls; }
vector<SgStatement*>* Array::getZeroSt() { return &zeroSt; }
vector<SgSymbol* >* Array::getCoefInAccess() { return &coefInAccess; }
// ---------------------------------------------------------------------- // Loop
Loop::Loop(int _line)
{
line = _line;
acrossType = 0;
loopDim = 0;
}
Loop::Loop(int _line, SgStatement *_body)
{
line = _line;
loopBody = _body;
acrossType = 0;
loopDim = 0;
}
Loop::Loop(int _acrType, int _line, SgStatement *_body)
{
line = _line;
loopBody = _body;
acrossType = _acrType;
loopDim = 0;
}
Loop::Loop(int _line, SgStatement *_body, bool withAnalyze)
{
line = _line;
loopBody = _body;
acrossType = 0;
loopDim = 0;
if (withAnalyze)
analyzeLoopBody();
}
void Loop::analyzeLoopBody()
{
// create info of array
SgStatement *stmt = loopBody;
while (stmt)
{
if (stmt->variant() == ASSIGN_STAT)
{
SgExpression *exL = stmt->expr(0);
SgExpression *exR = stmt->expr(1);
if (exL)
analyzeAssignOp(exL, 1);
if (exR)
analyzeAssignOp(exR, 0);
}
stmt = stmt->lexNext();
}
// create idxs info
SgExpression *par_dir = dvm_parallel_dir->expr(2);
while (par_dir)
{
symbols.push_back(par_dir->lhs()->symbol());
par_dir = par_dir->rhs();
}
loopDim = symbols.size();
// create private list
SgExpression *tmp = dvm_parallel_dir->expr(1);
while (tmp)
{
SgExpression *t = tmp->lhs();
if (t->variant() == ACC_PRIVATE_OP)
{
t = t->lhs();
while (t)
{
if (isSgArrayType(t->lhs()->symbol()->type()))
privateList.push_back(copyOfUnparse(t->lhs()->symbol()->identifier()));
t = t->rhs();
}
}
tmp = tmp->rhs();
}
// analyze acrossType and acrossDims in all arrays
for (unsigned i = 0; i < arrays.size(); ++i)
{
if ( !isArrayInPrivate(arrays[i]->getArrayName()) )
{
arrays[i]->analyzeAcrDims();
arrays[i]->analyzeAlignOnLoop();
}
}
analyzeAcrossType();
// analyze transformDims in all arrays
if (acrossType > 1)
{
for (unsigned i = 0; i < arrays.size(); ++i)
{
if (!isArrayInPrivate(arrays[i]->getArrayName()))
arrays[i]->analyzeTrDims();
}
}
}
void Loop::analyzeAssignOp(SgExpression *_exp, int oper)
{
if (_exp->variant() != ARRAY_REF)
{
if (_exp->lhs())
analyzeAssignOp(_exp->lhs(), oper);
if (_exp->rhs())
analyzeAssignOp(_exp->rhs(), oper);
}
else
{
SgSymbol *arrName = _exp->symbol();
if (isSgArrayType(arrName->type())) // if array ref
{
int idx;
Array *newArray = getArray(arrName->identifier(), &idx);
if (newArray == NULL)
{
Array *nArr = new Array(arrName->identifier(), this);
Access *nAcc = new Access(_exp->lhs(), nArr);
nArr->setDimNum(isSgArrayType(arrName->type())->dimension());
nArr->addAccess(nAcc);
addArray(nArr);
if (oper == 1)
nAcc->incOperW();
else if (oper == 0)
nAcc->incOperR();
}
else
{
char *strAcc = copyOfUnparse(_exp->lhs()->unparse());
Access *tAcc = newArray->getAccess(strAcc);
if (tAcc == NULL)
{
tAcc = new Access(_exp->lhs(), newArray);
newArray->addAccess(tAcc);
}
if (oper == 1)
tAcc->incOperW();
else if (oper == 0)
tAcc->incOperR();
}
}
}
}
Array* Loop::getArray(char *name, int *_idx)
{
int idx = -1;
for (unsigned i = 0; i < arrays.size(); ++i)
{
if (strcmp(name, arrays[i]->getArrayName()) == 0)
{
idx = i;
break;
}
}
_idx[0] = idx;
if (idx == -1)
return NULL;
else
return arrays[idx];
}
Array* Loop::getArray(char *name)
{
int idx = -1;
for (unsigned i = 0; i < arrays.size(); ++i)
{
if (strcmp(name, arrays[i]->getArrayName()) == 0)
{
idx = i;
break;
}
}
if (idx == -1)
return NULL;
else
return arrays[idx];
}
void Loop::analyzeAcrossType()
{
for (int i = 0; i < loopDim; ++i)
acrDims.push_back(-1);
for (unsigned i = 0; i < arrays.size(); ++i)
{
std::vector<int>* tArrAcrDims = arrays[i]->getAcrDims();
std::vector<int>* tArrAlign = arrays[i]->getAlignOnLoop();
for (unsigned k = 0; k < tArrAlign->size(); ++k)
{
if ((*tArrAlign)[k] != -1)
acrDims[(*tArrAlign)[k]] = MAX(acrDims[(*tArrAlign)[k]], (*tArrAcrDims)[(*tArrAlign)[k]]);
}
}
acrossType = 0;
for (int i = 0; i < loopDim; ++i)
{
if (acrDims[i] != -1)
acrossType++;
}
}
bool Loop::isArrayInPrivate(char *name)
{
bool retVal = false;
for (unsigned i = 0; i < privateList.size(); ++i)
{
if (strcmp(name, privateList[i]) == 0)
{
retVal = true;
break;
}
}
return retVal;
}
void Loop::addArray(Array *_array) { arrays.push_back(_array); }
void Loop::setLine(int _line) { line = _line; }
int Loop::getLine() { return line; }
void Loop::setAcrType(int _type) { acrossType = _type; }
int Loop::getAcrType() { return acrossType; }
vector<Array*>* Loop::getArrays() { return &arrays; }
vector<SgSymbol*>* Loop::getSymbols() { return &symbols; }
int Loop::getLoopDim() { return loopDim; }

View File

@@ -0,0 +1,222 @@
#include "dvm.h"
#include "aks_structs.h"
#define DEBUG_LV1 true
#if 1
std::ostream &out = std::cout;
#else
std::ofstream out("_log_debug_info.txt");
#endif
extern SgStatement *dvm_parallel_dir;
SgExpression* findDirect(SgExpression *inExpr, int DIR)
{
SgExpression *temp = NULL;
if (inExpr)
{
if (inExpr->variant() == DIR)
{
return inExpr;
}
else
{
if (inExpr->lhs())
temp = findDirect(inExpr->lhs(), DIR);
if(temp == NULL && inExpr->rhs())
temp = findDirect(inExpr->rhs(), DIR);
}
}
return temp;
}
static SgSymbol** fillDataOfArray(SgExpression* on, int& dimInPar)
{
dimInPar = 0;
SgExpression* temp = on;
while (temp)
{
dimInPar++;
temp = temp->rhs();
}
SgSymbol** symbInPar = new SgSymbol * [dimInPar];
temp = on;
for (int i = 0; i < dimInPar; ++i)
{
symbInPar[i] = temp->lhs()->symbol();
temp = temp->rhs();
}
return symbInPar;
}
SageArrayIdxs* GetIdxInParDir(const std::map<std::string, SgExpression*>& on, SgExpression *across, bool tie = false)
{
SageArrayIdxs *ret = new SageArrayIdxs();
SageArrayIdxs *act = ret;
int allDim = 0;
int dimInPar = 0;
SgSymbol** symbInPar = NULL;
ret->next = NULL;
ret->array_expr = NULL;
ret->read_write = -1;
ret->dim = 0;
ret->symb = NULL;
std::vector<SgExpression*> toAnalyze;
if (across->lhs()->variant() == EXPR_LIST)
toAnalyze.push_back(across->lhs());
else
{
if (across->lhs()->variant() == DDOT)
toAnalyze.push_back(across->lhs()->rhs());
if (across->rhs())
if (across->rhs()->variant() == DDOT)
toAnalyze.push_back(across->rhs()->rhs());
}
for (int i = 0; i < toAnalyze.size(); ++i)
{
across = toAnalyze[i];
while (across)
{
if (symbInPar == NULL)
{
if (on.size() == 0)
{
fprintf(stderr, "internal error in across convertion for GPU\n");
exit(-1);
}
else if (on.size() == 1)
symbInPar = fillDataOfArray(on.begin()->second, dimInPar);
}
SgExpression *t = across->lhs();
int dim = 0;
if (tie)
{
if (t->variant() == ARRAY_REF)
{
if (on.find(t->symbol()->identifier()) == on.end())
{
fprintf(stderr, "internal error in across convertion for GPU\n");
exit(-1);
}
else
symbInPar = fillDataOfArray(on.find(t->symbol()->identifier())->second, dimInPar);
}
else if (t->variant() == ARRAY_OP)
{
if (on.find(t->lhs()->symbol()->identifier()) == on.end())
{
fprintf(stderr, "internal error in across convertion for GPU\n");
exit(-1);
}
else
symbInPar = fillDataOfArray(on.find(t->lhs()->symbol()->identifier())->second, dimInPar);
}
}
if (t->variant() == ARRAY_REF)
t = t->lhs();
else if (t->variant() == ARRAY_OP)
t = t->lhs()->lhs();
else
{
if (DEBUG_LV1)
out << "!!! unknown variant in ACROSS dir: " << t->variant() << std::endl;
}
SgExpression *tmp = t;
while (tmp)
{
dim++;
tmp = tmp->rhs();
}
act->next = new SageArrayIdxs();
act = act->next;
act->next = NULL;
act->symb = new SageSymbols*[dim];
act->dim = dim;
for (int i = 0; i < dim; ++i)
{
act->symb[i] = new SageSymbols();
act->symb[i]->across_left = t->lhs()->lhs()->valueInteger();
act->symb[i]->across_right = t->lhs()->rhs()->valueInteger();
if (act->symb[i]->across_left != 0 || act->symb[i]->across_right != 0)
act->symb[i]->symb = symbInPar[i];
else if (i < dimInPar)
act->symb[i]->symb = symbInPar[i];
else
act->symb[i]->symb = NULL;
act->symb[i]->next = NULL;
t = t->rhs();
}
allDim++;
across = across->rhs();
}
}
ret->dim = allDim;
return ret;
}
SageAcrossInfo* GetLoopsWithParAndAcrDir()
{
SageAcrossInfo *q = NULL;
SgStatement *temp = dvm_parallel_dir;
if (temp->variant() == DVM_PARALLEL_ON_DIR)
{
SgExpression *t = findDirect(temp->expr(1), ACROSS_OP);
SgExpression *tie = findDirect(temp->expr(1), ACC_TIE_OP);
std::map<std::string, SgExpression*> arrays;
if (t != NULL)
{
q = new SageAcrossInfo();
if (temp->expr(0) && temp->expr(0)->lhs())
{
arrays[temp->expr(0)->symbol()->identifier()] = temp->expr(0)->lhs();
q->idx = GetIdxInParDir(arrays, t);
}
else if (tie)
{
SgExpression* list = tie->lhs();
while (list)
{
arrays[list->lhs()->symbol()->identifier()] = list->lhs()->lhs();
list = list->rhs();
}
q->idx = GetIdxInParDir(arrays, t, true);
}
else
{
fprintf(stderr, "internal error in across convertion for GPU\n");
exit(-1);
}
q->next = NULL;
}
}
return q;
}
SageSymbols *GetSymbInParalell(int *n, SgExpression *first)
{
SageSymbols *retval;
SageSymbols *p_t = new SageSymbols();
retval = p_t;
while(first)
{
SageSymbols *q = new SageSymbols();
q->len = -1;
q->next = NULL;
q->symb = first->lhs()->symbol();
p_t->next = q;
p_t = q;
n[0]++;
first = first->rhs();
}
return retval->next;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,552 @@
#include "dvm.h"
#include <stdexcept>
class Checkpoint {
char *cpName; // checkpoint name
char *serviceFilename; // service file name
std::vector<SgExpression *> filenames; // filenames used for checkpointing
SgExprListExp *variables; // variables list
char defaultIOMode[5];
static const char SERVICE_FILE_SUFFIX[10];
SgSymbol *serviceUnitSymbol;
SgSymbol *writeUnitSymbol;
SgSymbol *currentFileSymbol;
SgSymbol *lastFileSymbol;
SgLabel *emptyServiceFileLabel;
SgLabel *notExistingServiceFileLabel;
public:
Checkpoint(char *cpName, std::vector<SgExpression *> filenames, SgExprListExp *variables, SgExpression *cpMode) {
defaultIOMode[0] = 0;
this->cpName = new char[strlen(cpName) + 1];
strcpy(this->cpName, cpName);
this->serviceFilename = new char[strlen(cpName) + strlen(SERVICE_FILE_SUFFIX) + 1];
strcpy(this->serviceFilename, cpName);
strcat(this->serviceFilename, SERVICE_FILE_SUFFIX);
this->filenames = filenames;
this->variables = variables;
if (cpMode) {
if (cpMode->variant() == ACC_LOCAL_OP) strcpy(defaultIOMode, "l");
else if (cpMode->variant() == PARALLEL_OP) strcpy(defaultIOMode, "p");
else throw new std::runtime_error("Unknown type of checkpoint mode");
}
else strcpy(defaultIOMode, "p");
}
void getNewLabels(int variant) {
this->emptyServiceFileLabel = GetLabel();
if (variant == WRITE_STAT) this->notExistingServiceFileLabel = GetLabel();
}
SgSymbol *getServiceUnitSymbol() {
return this->serviceUnitSymbol;
}
SgSymbol *getWriteUnitSymbol() {
return this->writeUnitSymbol;
}
SgSymbol *getCurrentFileSymbol() {
return this->currentFileSymbol;
}
SgSymbol *getLastFileSymbol() {
return this->lastFileSymbol;
}
void defineVariables();
void createEmptyLastFilenameAssign();
void createSaveFilenamesStatement();
void createOpenServiceFileBeforeCp(int variant);
void createReadServiceFileStatement(int variant);
void createCloseServiceFileStatement(bool useLabel);
void createCloseWriteFileStatement();
void createOpenWriteFileStatement(bool isAsync);
void createWriteOrReadStatement(int variant);
void createWriteServiceFileStatement();
void createOpenReadFileStatement();
void createCheckFilenameStatement();
void createOpenServiceFileAfterCp();
void getNextFileStmt();
void createSaveAsyncUnitStatement();
void createCpWaitStatement(SgVarRefExp *statusVarRef);
};
const char Checkpoint::SERVICE_FILE_SUFFIX[10] = ".info.dat";
struct stringLessComparator {
bool operator()(const char *a, const char *b) const {
return strcmp(a, b) < 0;
}
};
std::map<char *, Checkpoint *, stringLessComparator> checkpointMap;
void insertContinueStatement() {
SgContinueStmt &continueStatement = *new SgContinueStmt();
cur_st->lastNodeOfStmt()->insertStmtAfter(continueStatement, *cur_st->controlParent());
cur_st = &continueStatement;
}
/* adds new checkpoint to checkpointMap
example: !DVM$ CP_CREATE CP1, VARLIST(IT, B), FILES('jac_%02d.cp0','jac_%02d.cp1') [PARALLEL | LOCAL]
*/
void CP_Create_Statement(SgStatement *stmt, int error_msg)
{
if (!options.isOn(IO_RTS)) {
if (error_msg) warn("Checkpoints aren't supported without iO_RTS option", 462, stmt);
}
SgVarRefExp *cpNameExpr = isSgVarRefExp(stmt->expr(0));
if (!cpNameExpr) return;
char *cpName = cpNameExpr->symbol()->identifier();
SgExprListExp *variablesExpr = isSgExprListExp(stmt->expr(1));
SgExpression *filenamesAndCpModeExpr = stmt->expr(2);
SgExprListExp *filenamesExpr = NULL;
SgExpression *cpMode = NULL;
std::vector<SgExpression *> filenames;
if (isSgExprListExp(filenamesAndCpModeExpr)) {
filenamesExpr = isSgExprListExp(filenamesAndCpModeExpr);
}
else if (filenamesAndCpModeExpr->variant() == ARRAY_OP) {
filenamesExpr = isSgExprListExp(filenamesAndCpModeExpr->lhs());
cpMode = filenamesAndCpModeExpr->rhs();
}
// else syntax error, no need to check
for (int i = 0; i < filenamesExpr->length(); ++i) {
SgValueExp *filename = isSgValueExp(filenamesExpr->elem(i));
if (!filename) {
if (error_msg) {
err("Every filename in CP_CREATE statement should be character constant value", 463, stmt);
}
return;
}
size_t currentFilenameLength = strlen(filename->stringValue());
if (currentFilenameLength >= 99) {
if (error_msg) {
err("Filename in CP_CREATE cannot be longer than 100 characters", 464, stmt);
}
return;
}
filenames.push_back(filenamesExpr->elem(i));
}
try {
Checkpoint *checkpoint = new Checkpoint(cpName, filenames, variablesExpr, cpMode);
checkpoint->defineVariables();
if (checkpointMap.find(cpName) != checkpointMap.end()) {
if (error_msg) {
Error("Checkpoint with name %s already exists", cpName, 465, stmt);
}
return;
}
checkpointMap[cpName] = checkpoint;
checkpoint->createSaveFilenamesStatement();
checkpoint->createEmptyLastFilenameAssign();
}
catch(std::runtime_error error) {
if (error_msg) {
err(error.what(), 0, stmt);
}
return;
}
}
/* fixme: delete from here! use the only enum for io.cpp and checkpoint.cpp */
enum {UNIT_IO, ACCESS_IO, ACTION_IO, ASYNC_IO, BLANK_IO, DECIMAL_IO, DELIM_IO, ENCODING_IO, ERR_IO, FILE_IO,
FORM_IO, IOSTAT_IO, IOMSG_IO, NEWUNIT_IO, PAD_IO, POSITION_IO, RECL_IO, ROUND_IO, SIGN_IO, STATUS_IO, DVM_MODE_IO, NUMB__CL };
enum { UNIT_RW, FMT_RW, NML_RW, ADVANCE_RW, ASYNC_RW, BLANK_RW, DECIMAL_RW, DELIM_RW, END_RW, EOR_RW, ERR_RW, ID_RW,
IOMSG_RW, IOSTAT_RW, PAD_RW, POS_RW, REC_RW, ROUND_RW, SIGN_RW, SIZE_RW, NUMB__RW };
void Checkpoint::defineVariables() {
const int varLength = 300; //(int) (20 + strlen(this->cpName));
char serviceUnitVarName[varLength];
strcpy(serviceUnitVarName, "dvmh_service_unit_");
strcat(serviceUnitVarName, this->cpName);
char writeUnitVarName[varLength];
strcpy(writeUnitVarName, "dvmh_write_unit_");
strcat(writeUnitVarName, this->cpName);
char currentFileVarName[varLength];
strcpy(currentFileVarName, "dvmh_current_file_");
strcat(currentFileVarName, this->cpName);
char lastFileVarName[varLength];
strcpy(lastFileVarName, "dvmh_last_file_");
strcat(lastFileVarName, this->cpName);
this->serviceUnitSymbol = new SgSymbol(VARIABLE_NAME, serviceUnitVarName);
this->serviceUnitSymbol->setType(SgTypeInt());
this->writeUnitSymbol = new SgSymbol(VARIABLE_NAME, writeUnitVarName);
this->writeUnitSymbol->setType(SgTypeInt());
SgStringLengthExp *lengthExpr = new SgStringLengthExp(*new SgValueExp(100));
SgType *stringType = new SgType(T_STRING, lengthExpr, SgTypeChar());
this->currentFileSymbol = new SgSymbol(VARIABLE_NAME, currentFileVarName);
this->currentFileSymbol->setType(stringType);
this->lastFileSymbol = new SgSymbol(VARIABLE_NAME, lastFileVarName);
this->lastFileSymbol->setType(stringType);
/* declare these variables for testing */
cur_func->insertStmtAfter(*serviceUnitSymbol->makeVarDeclStmt());
cur_func->insertStmtAfter(*writeUnitSymbol->makeVarDeclStmt());
cur_func->insertStmtAfter(*currentFileSymbol->makeVarDeclStmt());
cur_func->insertStmtAfter(*lastFileSymbol->makeVarDeclStmt());
}
void Checkpoint::createSaveFilenamesStatement() {
/* generates dvmh_cp_save_filenames call:
dvmh_cp_save_filenames(checkpoint_name, files_count, filename1, filename2, ...)
*/
SgStatement *stmt = SaveCheckpointFilenames(new SgValueExp(this->cpName), this->filenames);
SgStatement *cpCreateDir = cur_st;
cur_st->insertStmtAfter(*stmt, *cur_st->controlParent());
cur_st = stmt;
cpCreateDir->extractStmt();
}
void Checkpoint::createEmptyLastFilenameAssign() {
/*
initialization dvmh_last_file variable. generating dvmh_last_file = ''&
*/
SgVarRefExp *lastFilename = new SgVarRefExp(this->lastFileSymbol);
SgValueExp *emptyString = new SgValueExp("");
doAssignTo_After(lastFilename, emptyString);
}
void Checkpoint::createOpenServiceFileBeforeCp(int variant) {
/* statement to be generated:
open(newunit=service_unt, file=service_filename,
access='stream', status='old', err=err_label, position='rewind', action='read')
*/
SgExpression *ioc[NUMB__CL];
for (int i = 0; i < NUMB__CL; ++i) {
ioc[i] = NULL;
}
ioc[NEWUNIT_IO] = new SgVarRefExp(this->serviceUnitSymbol);
ioc[ACCESS_IO] = new SgValueExp("STREAM");
ioc[ACTION_IO] = new SgValueExp("READ");
ioc[FILE_IO] = new SgValueExp(serviceFilename);
ioc[POSITION_IO] = new SgValueExp("REWIND"); // for reading file
ioc[STATUS_IO] = new SgValueExp("OLD");
// if service file is opened for reading, error should occur.
// if it is opened for saving checkpoint, not existing file is normal
if (variant == WRITE_STAT) ioc[ERR_IO] = new SgLabelRefExp(*this->notExistingServiceFileLabel);
insertContinueStatement();
Dvmh_Open(ioc, defaultIOMode);
}
void Checkpoint::createOpenServiceFileAfterCp() {
/* statement to be generated:
open(newunit=service_unt, file=serviceFileName, access='stream', position='rewind', action='write')
*/
SgExpression *ioc[NUMB__CL];
for (int i = 0; i < NUMB__CL; ++i) {
ioc[i] = NULL;
}
ioc[NEWUNIT_IO] = new SgVarRefExp(this->serviceUnitSymbol);
ioc[ACCESS_IO] = new SgValueExp("STREAM");
ioc[ACTION_IO] = new SgValueExp("WRITE");
ioc[FILE_IO] = new SgValueExp(this->serviceFilename);
ioc[POSITION_IO] = new SgValueExp("REWIND");
ioc[STATUS_IO] = new SgValueExp("OLD");
insertContinueStatement();
Dvmh_Open(ioc, defaultIOMode);
}
void Checkpoint::createReadServiceFileStatement(int variant) {
/* statement to be generated:
read(unit = service_unt, end=200) last_filename
end argument is used only for writing checkpoint.
*/
SgExpression *ioc[NUMB__RW];
for (int i = 0; i < NUMB__RW; ++i) {
ioc[i] = NULL;
}
ioc[UNIT_RW] = new SgVarRefExp(this->serviceUnitSymbol);
SgLabelRefExp *endLabelRef = new SgLabelRefExp(*this->emptyServiceFileLabel);
ioc[END_RW] = endLabelRef;
SgVarRefExp &lastFilenameExpr = *new SgVarRefExp(this->lastFileSymbol);
SgExprListExp &itemsToRead = *new SgExprListExp(lastFilenameExpr);
SgExprListExp &specList = *new SgExprListExp();
SgSpecPairExp &specPairUnit = *new SgSpecPairExp(*new SgValueExp("unit"), *new SgVarRefExp(this->serviceUnitSymbol));
specList.append(specPairUnit);
if (variant == WRITE_STAT) {
SgSpecPairExp &specPairEnd = *new SgSpecPairExp(*new SgValueExp("end"), *endLabelRef);
specList.append(specPairEnd);
}
SgInputOutputStmt *ioStatement = new SgInputOutputStmt(READ_STAT, specList, itemsToRead);
insertContinueStatement();
Dvmh_ReadWrite(ioc, ioStatement);
}
void Checkpoint::createWriteServiceFileStatement() {
/* statement to be generated:
write(unit = service_unt) current_filename
*/
SgExpression *ioc[NUMB__RW];
for (int i = 0; i < NUMB__RW; ++i) {
ioc[i] = NULL;
}
ioc[UNIT_RW] = new SgVarRefExp(this->serviceUnitSymbol);
SgVarRefExp &currentFileExpr = *new SgVarRefExp(this->currentFileSymbol);
SgExprListExp &itemsToWrite = *new SgExprListExp(currentFileExpr);
SgSpecPairExp &specPairUnit = *new SgSpecPairExp(*new SgValueExp("unit"), *new SgVarRefExp(this->serviceUnitSymbol));
SgExprListExp &specList = *new SgExprListExp();
specList.append(specPairUnit);
SgInputOutputStmt *ioStatement = new SgInputOutputStmt(WRITE_STAT, specList, itemsToWrite);
insertContinueStatement();
Dvmh_ReadWrite(ioc, ioStatement);
}
void Checkpoint::createCloseServiceFileStatement(bool useLabel) {
/* statement to generate:
[label] close(unit = service_unit)
*/
SgExpression *ioc[NUMB__CL];
for (int i = 0; i < NUMB__CL; ++i)
ioc[i] = NULL;
ioc[UNIT_IO] = new SgVarRefExp(this->serviceUnitSymbol);
insertContinueStatement();
Dvmh_Close(ioc);
if (useLabel) cur_st->setLabel(*this->emptyServiceFileLabel);
}
void Checkpoint::getNextFileStmt() {
SgStatement *getNextFilenameStmt =
GetNextFilename(new SgValueExp(this->cpName),
new SgVarRefExp(this->lastFileSymbol),
new SgVarRefExp(this->currentFileSymbol));
doCallAfter(getNextFilenameStmt);
cur_st->setLabel(*this->notExistingServiceFileLabel);
}
void Checkpoint::createCloseWriteFileStatement() {
/* statement to generate:
close(unit = write_unit)
*/
SgExpression *ioc[NUMB__CL];
for (int i = 0; i < NUMB__CL; ++i)
ioc[i] = NULL;
ioc[UNIT_IO] = new SgVarRefExp(this->writeUnitSymbol);
insertContinueStatement();
Dvmh_Close(ioc);
}
void Checkpoint::createOpenReadFileStatement() {
/* statement to be generated:
open(newunit = write_unt, file=last_filename, access='stream', status='old')
*/
SgExpression *ioc[NUMB__CL];
for (int i = 0; i < NUMB__CL; ++i) {
ioc[i] = NULL;
}
ioc[NEWUNIT_IO] = new SgVarRefExp(this->writeUnitSymbol);
ioc[FILE_IO] = new SgVarRefExp(this->lastFileSymbol);
ioc[ACCESS_IO] = new SgValueExp("STREAM");
ioc[STATUS_IO] = new SgValueExp("OLD");
insertContinueStatement();
Dvmh_Open(ioc, defaultIOMode);
}
void Checkpoint::createOpenWriteFileStatement(bool isAsync) {
/* statement to be generated:
open(newunit = write_unt, file=current_filename, access='stream', status='replace', dvmIoMode = defaultIOMode[+s])
*/
SgExpression *ioc[NUMB__CL];
for (int i = 0; i < NUMB__CL; ++i) {
ioc[i] = NULL;
}
ioc[NEWUNIT_IO] = new SgVarRefExp(this->writeUnitSymbol);
ioc[FILE_IO] = new SgVarRefExp(this->currentFileSymbol);
ioc[ACCESS_IO] = new SgValueExp("STREAM");
ioc[STATUS_IO] = new SgValueExp("REPLACE");
ioc[ACTION_IO] = new SgValueExp("WRITE");
insertContinueStatement();
char *ioMode = new char[5];
strcpy(ioMode, defaultIOMode);
if (isAsync) strcat(ioMode, "s");
Dvmh_Open(ioc, ioMode);
}
void Checkpoint::createWriteOrReadStatement(int variant) {
SgExpression *ioc[NUMB__RW];
for (int i = 0; i < NUMB__RW; ++i) {
ioc[i] = NULL;
}
ioc[UNIT_RW] = new SgVarRefExp(this->writeUnitSymbol);
SgSpecPairExp &specPairUnit = *new SgSpecPairExp(*new SgValueExp("unit"), *new SgVarRefExp(this->writeUnitSymbol));
SgExprListExp &specList = *new SgExprListExp();
specList.append(specPairUnit);
SgInputOutputStmt *ioStatement = new SgInputOutputStmt(variant, specList, *this->variables);
insertContinueStatement();
Dvmh_ReadWrite(ioc, ioStatement);
}
void Checkpoint::createCheckFilenameStatement() {
/* checks that filename was in current checkpoint declaration.
generates dvmh_cp_check_filename(checkpoint_name, filename)
*/
SgValueExp *cpNameExpr = new SgValueExp(this->cpName);
SgVarRefExp *lastFileExpr = new SgVarRefExp(this->lastFileSymbol);
SgStatement *checkFileStatement = CheckFilename(cpNameExpr, lastFileExpr);
cur_st->insertStmtAfter(*checkFileStatement, *cur_st->controlParent());
cur_st = checkFileStatement;
}
void Checkpoint::createSaveAsyncUnitStatement() {
/* saves unit when cp_save is used in async mode
generates dvmh_cp_save_async_unit(checkpoint_name, filename, unit)
*/
SgValueExp *cpName = new SgValueExp(this->cpName);
SgVarRefExp *currentFileExpr = new SgVarRefExp(this->currentFileSymbol);
SgVarRefExp *writeUnitRef = new SgVarRefExp(this->writeUnitSymbol);
SgStatement *cpSaveAsyncUnit = CpSaveAsyncUnit(cpName, currentFileExpr, writeUnitRef);
cur_st->insertStmtAfter(*cpSaveAsyncUnit, *cur_st->controlParent());
cur_st = cpSaveAsyncUnit;
}
void Checkpoint::createCpWaitStatement(SgVarRefExp *statusVarRef) {
/* wait for all files to finish async saving and closing them
generates dvmh_cp_wait(checkpoint_name, status_var)
*/
SgStatement *initialCpWait = cur_st;
SgStatement *cpWaitStmt = CpWait(new SgValueExp(this->cpName), statusVarRef);
cur_st->insertStmtAfter(*cpWaitStmt);
cur_st = cpWaitStmt;
initialCpWait->extractStmt();
}
Checkpoint *getCheckpoint(SgStatement *stmt, int error_msg) {
SgVarRefExp *checkpointVarRef = isSgVarRefExp(stmt->expr(0));
char *checkpointName = new char[strlen(checkpointVarRef->symbol()->identifier()) + 1];
strcpy(checkpointName, checkpointVarRef->symbol()->identifier());
std::map<char *, Checkpoint *>::iterator checkpointIt = checkpointMap.find(checkpointName);
if (checkpointIt == checkpointMap.end()) {
if (error_msg) {
Error("No created checkpoint with name %s found", checkpointName, 466, stmt);
}
return NULL;
}
return checkpointIt->second;
}
void CP_Save_Statement(SgStatement *stmt, int error_msg) {
/*
stmt->variant() == DVM_CP_SAVE_DIR
stmt->expr(0) имя-контр-точки
stmt->expr(1) NULL или variant == ACC_ASYNC_OP
*/
Checkpoint *checkpoint = getCheckpoint(stmt, error_msg);
if (!checkpoint) return;
bool isAsync = (stmt->expr(1) != NULL && stmt->expr(1)->variant() == ACC_ASYNC_OP);
checkpoint->getNewLabels(WRITE_STAT);
checkpoint->createOpenServiceFileBeforeCp(WRITE_STAT);
checkpoint->createReadServiceFileStatement(WRITE_STAT);
checkpoint->createCloseServiceFileStatement(true);
checkpoint->getNextFileStmt();
checkpoint->createOpenWriteFileStatement(isAsync);
if (isAsync) checkpoint->createSaveAsyncUnitStatement();
checkpoint->createWriteOrReadStatement(WRITE_STAT);
if (!isAsync) checkpoint->createCloseWriteFileStatement();
checkpoint->createOpenServiceFileAfterCp();
checkpoint->createWriteServiceFileStatement();
checkpoint->createCloseServiceFileStatement(false);
}
void CP_Load_Statement(SgStatement *stmt, int error_msg) {
Checkpoint *checkpoint = getCheckpoint(stmt, error_msg);
if (!checkpoint) return;
checkpoint->getNewLabels(READ_STAT);
checkpoint->createOpenServiceFileBeforeCp(READ_STAT);
checkpoint->createReadServiceFileStatement(READ_STAT);
checkpoint->createCloseServiceFileStatement(true);
checkpoint->createCheckFilenameStatement();
checkpoint->createOpenReadFileStatement();
checkpoint->createWriteOrReadStatement(READ_STAT);
checkpoint->createCloseWriteFileStatement();
}
void CP_Wait(SgStatement *stmt, int error_msg) {
Checkpoint *checkpoint = getCheckpoint(stmt, error_msg);
if (!checkpoint) return;
SgVarRefExp *statusVarRef = isSgVarRefExp(stmt->expr(1));
if (!statusVarRef || !(statusVarRef->symbol()->type()->variant() == T_INT)) {
if (error_msg)
err("Wrong type of STATUS argument in CP_WAIT-statement", 467, stmt);
return;
}
checkpoint->createCpWaitStatement(statusVarRef);
}

File diff suppressed because it is too large Load Diff

14837
dvm/fdvm/trunk/fdvm/dvm.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1070
dvm/fdvm/trunk/fdvm/help.cpp Normal file

File diff suppressed because it is too large Load Diff

1698
dvm/fdvm/trunk/fdvm/hpf.cpp Normal file

File diff suppressed because it is too large Load Diff

2905
dvm/fdvm/trunk/fdvm/io.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,151 @@
#echo#######################################################################
# Makefile for Fortran DVM back-end
#
#echo#######################################################################
# dvm/fdvm/fdvm/makefile.uni
SAGEROOT = ../Sage
LIBDIR = ../lib
BINDIR = ../../bin
LIBINCLUDE = $(SAGEROOT)/lib/include
HINCLUDE = $(SAGEROOT)/h
DVMINCLUDE = ../include
EXECUTABLES = f_dvm
LOADER = $(LINKER)
INCL = -I. -I$(LIBINCLUDE) -I$(HINCLUDE) -I$(DVMINCLUDE)
CFLAGS = -c $(INCL) -Wall
LDFLAGS =
LIBS = $(LIBDIR)/libSage++.a $(LIBDIR)/libsage.a $(LIBDIR)/libdb.a
OBJS = acc.o \
acc_across.o \
acc_across_analyzer.o \
acc_analyzer.o \
acc_data.o \
acc_f2c.o \
acc_f2c_handlers.o \
acc_rtc.o \
acc_utilities.o \
aks_analyzeLoops.o \
aks_structs.o \
calls.o \
checkpoint.o \
debug.o \
dvm.o \
funcall.o \
help.o \
hpf.o \
io.o \
omp.o \
ompdebug.o \
parloop.o \
stmt.o
$(BINDIR)/$(EXECUTABLES): $(OBJS)
$(LOADER) $(LDFLAGS) -o $(BINDIR)/$(EXECUTABLES) $(OBJS) $(LIBS)
all: $(BINDIR)/$(EXECUTABLES)
@echo "****** COMPILING $(EXECUTABLES) DONE ******"
clean:
rm -f $(OBJS)
cleanall:
rm -f $(OBJS)
## TODO: create correct dependences
############################# dependences ############################
acc.o: acc.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) acc.cpp
acc_across.o: acc_across.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h $(DVMINCLUDE)/aks_structs.h
$(CXX) $(CFLAGS) acc_across.cpp
acc_across_analyzer.o: acc_across_analyzer.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h $(DVMINCLUDE)/acc_across_analyzer.h
$(CXX) $(CFLAGS) acc_across_analyzer.cpp
acc_analyzer.o: acc_analyzer.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h $(DVMINCLUDE)/acc_analyzer.h
$(CXX) $(CFLAGS) acc_analyzer.cpp
acc_data.o: acc_data.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) acc_data.cpp
acc_f2c.o: acc_f2c.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) acc_f2c.cpp
acc_f2c_handlers.o: acc_f2c_handlers.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) acc_f2c_handlers.cpp
acc_rtc.o: acc_rtc.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h $(DVMINCLUDE)/acc_data.h
$(CXX) $(CFLAGS) acc_rtc.cpp
acc_utilities.o: acc_utilities.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) acc_utilities.cpp
aks_analyzeLoops.o: aks_analyzeLoops.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h $(DVMINCLUDE)/aks_structs.h
$(CXX) $(CFLAGS) aks_analyzeLoops.cpp
aks_structs.o: aks_structs.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h $(DVMINCLUDE)/aks_structs.h
$(CXX) $(CFLAGS) aks_structs.cpp
calls.o: calls.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) calls.cpp
checkpoint.o: checkpoint.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) checkpoint.cpp
debug.o: debug.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) debug.cpp
dvm.o: dvm.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) dvm.cpp
funcall.o: funcall.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) funcall.cpp
help.o: help.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) help.cpp
hpf.o: hpf.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) hpf.cpp
io.o: io.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) io.cpp
omp.o: omp.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) omp.cpp
ompdebug.o: ompdebug.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) ompdebug.cpp
parloop.o: parloop.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) parloop.cpp
stmt.o: stmt.cpp $(DVMINCLUDE)/fdvm.h $(DVMINCLUDE)/libnum.h $(DVMINCLUDE)/libdvm.h \
$(DVMINCLUDE)/dvm.h
$(CXX) $(CFLAGS) stmt.cpp

View File

@@ -0,0 +1,148 @@
#######################################################################
## Copyright (C) 1999 ##
## Keldysh Institute of Appllied Mathematics ##
#######################################################################
# dvm/fdvm/fdvm/makefile.win
OUTDIR = ..\obj
BINDIR = ..\..\bin
LIBDIR = ..\lib
SAGEROOT =..\Sage
LIBINCLUDE = $(SAGEROOT)\lib\include
HINCLUDE = $(SAGEROOT)\h
FDVMINCL = ..\include
EXECUTABLES = f_dvm
INCL = -I. -I$(LIBINCLUDE) -I$(HINCLUDE) -I$(FDVMINCL)
# -w don't issue warning now.
#CFLAGS=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D SYS5 $(INCL) \
# /Fp"$(OUTDIR)/f_dvm.pch" /YX /Fo"$(OUTDIR)/" /Fd"$(OUTDIR)/" /c
CFLAGS=/nologo /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D SYS5 $(INCL) \
/Fp"$(OUTDIR)/f_dvm.pch" /Fo"$(OUTDIR)/" /Fd"$(OUTDIR)/" /c
.cpp{$(OUTDIR)/}.obj:
$(CXX) $(CFLAGS) $<
LINK=$(LINKER)
LINK_FLAGS=/nologo /subsystem:console /incremental:no\
/pdb:"$(OUTDIR)\$(EXECUTABLES).pdb" /out:"$(BINDIR)\$(EXECUTABLES).exe"
LINK_FLAGS=/nologo /subsystem:console /incremental:no\
/pdb:"$(OUTDIR)\$(EXECUTABLES).pdb" /out:"$(BINDIR)\$(EXECUTABLES).exe"
OBJS = $(OUTDIR)/acc.obj \
$(OUTDIR)/acc_across.obj \
$(OUTDIR)/acc_across_analyzer.obj \
$(OUTDIR)/acc_analyzer.obj \
$(OUTDIR)/acc_data.obj \
$(OUTDIR)/acc_f2c.obj \
$(OUTDIR)/acc_f2c_handlers.obj \
$(OUTDIR)/acc_rtc.obj \
$(OUTDIR)/acc_utilities.obj \
$(OUTDIR)/aks_analyzeLoops.obj \
$(OUTDIR)/aks_structs.obj \
$(OUTDIR)/calls.obj \
$(OUTDIR)/checkpoint.obj \
$(OUTDIR)/debug.obj \
$(OUTDIR)/dvm.obj \
$(OUTDIR)/funcall.obj \
$(OUTDIR)/help.obj \
$(OUTDIR)/hpf.obj \
$(OUTDIR)/io.obj \
$(OUTDIR)/omp.obj \
$(OUTDIR)/ompdebug.obj \
$(OUTDIR)/parloop.obj \
$(OUTDIR)/stmt.obj
LIBS = $(LIBDIR)/libSage++.lib $(LIBDIR)\libsage.lib $(LIBDIR)\libdb.lib
$(BINDIR)/$(EXECUTABLES).exe: $(OBJS)
$(LINK) @<<
$(LINK_FLAGS) $(OBJS) $(LIBS)
<<
all: $(BINDIR)/$(EXECUTABLES).exe
@echo "*** COMPILING EXECUTABLE $(EXECUTABLES) DONE"
clean:
cleanall:
# ***********************************************************
## TODO: create correct dependences
acc.obj: acc.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
acc_across.obj: acc_across.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
acc_across_analyzer.obj: acc_across_analyzer.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h $(FDVMINCL)/acc_across_analyzer.h
acc_analyzer.obj: acc_analyzer.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h $(FDVMINCL)/acc_analyzer.h
acc_data.obj: acc_data.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
acc_f2c.obj: acc_f2c.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
acc_f2c_handlers.obj: acc_f2c_handlers.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
acc_rtc.obj: acc_rtc.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
acc_utilities.obj: acc_utilities.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
aks_analyzeLoops.obj: aks_analyzeLoops.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h $(FDVMINCL)/aks_structs.h
aks_structs.obj: aks_structs.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h $(FDVMINCL)/aks_structs.h
calls.obj: calls.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
checkpoint.obj: checkpoint.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
debug.obj: debug.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
dvm.obj: dvm.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
funcall.obj: funcall.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
help.obj: help.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
hpf.obj: hpf.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
io.obj: io.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
omp.obj: omp.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
ompdebug.obj: ompdebug.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
parloop.obj: parloop.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h
stmt.obj: stmt.cpp $(FDVMINCL)/fdvm.h $(FDVMINCL)/libnum.h $(FDVMINCL)/libdvm.h \
$(FDVMINCL)/dvm.h

879
dvm/fdvm/trunk/fdvm/omp.cpp Normal file
View File

@@ -0,0 +1,879 @@
#include "dvm.h"
void AddSharedClauseForDVMVariables (SgStatement *first, SgStatement *last);
int IsPositiveDoStep(SgExpression *step) {
int s;
if (step == NULL) return (1);
if(step->isInteger())
s=step->valueInteger();
else
s = 0;
if(s >= 0)
return(1);
else
return(0);
}
int isOmpDir (SgStatement * st) {
if ((BIF_CODE(st->thebif)>800) && (BIF_CODE(st->thebif)<847)) {
return 1;
}
return 0;
}
inline int isDvmDir (SgStatement * st) {
switch (BIF_CODE(st->thebif)) {
case DVM_INTERVAL_DIR:
case DVM_ENDINTERVAL_DIR:
case DVM_DEBUG_DIR:
case DVM_ENDDEBUG_DIR:
case DVM_TRACEON_DIR:
case DVM_TRACEOFF_DIR:
case DVM_PARALLEL_ON_DIR:
case DVM_SHADOW_START_DIR:
case DVM_SHADOW_GROUP_DIR:
case DVM_SHADOW_WAIT_DIR:
case DVM_REDUCTION_START_DIR:
case DVM_REDUCTION_GROUP_DIR:
case DVM_REDUCTION_WAIT_DIR:
case DVM_DYNAMIC_DIR:
case DVM_ALIGN_DIR:
case DVM_REALIGN_DIR:
case DVM_REALIGN_NEW_DIR:
case DVM_REMOTE_ACCESS_DIR:
case HPF_INDEPENDENT_DIR:
case DVM_SHADOW_DIR:
case DVM_NEW_VALUE_DIR:
case DVM_VAR_DECL:
case DVM_POINTER_DIR:
case HPF_TEMPLATE_STAT:
case HPF_ALIGN_STAT:
case HPF_PROCESSORS_STAT:
case DVM_REDISTRIBUTE_DIR:
case DVM_TASK_REGION_DIR:
case DVM_END_TASK_REGION_DIR:
case DVM_ON_DIR:
case DVM_END_ON_DIR:
case DVM_TASK_DIR:
case DVM_MAP_DIR:
case DVM_PARALLEL_TASK_DIR:
case DVM_INHERIT_DIR:
case DVM_INDIRECT_GROUP_DIR:
case DVM_INDIRECT_ACCESS_DIR:
case DVM_REMOTE_GROUP_DIR:
case DVM_RESET_DIR:
case DVM_PREFETCH_DIR:
case DVM_OWN_DIR:
case DVM_HEAP_DIR:
case DVM_ASYNCID_DIR:
case DVM_ASYNCHRONOUS_DIR:
case DVM_ENDASYNCHRONOUS_DIR:
case DVM_ASYNCWAIT_DIR:
case DVM_F90_DIR:
case DVM_BARRIER_DIR:
case DVM_CONSISTENT_GROUP_DIR:
case DVM_CONSISTENT_START_DIR:
case DVM_CONSISTENT_WAIT_DIR:
case DVM_CONSISTENT_DIR:
case DVM_CHECK_DIR: return 1; break;
}
return 0;
}
int HideOmpStmt (SgStatement * st) {
int res=0;
SgStatement *prev = st->lexPrev ();
SgStatement *next =st->lexNext ();
while (prev && (isDvmDir(prev) || isOmpDir(prev))) prev = prev -> lexPrev ();
while (next && (isDvmDir(next) || isOmpDir(next))) next = next -> lexNext ();
if (prev && next) {
int length=st->numberOfAttributes();
int i=0;
SgAttribute *sa=NULL;
res=1;
switch (st->variant ()) {
case OMP_END_PARALLEL_DO_DIR:
case OMP_END_DO_DIR: {
for (i=0; i<length; i++) {
sa=st->getAttribute(i);
prev->addAttribute(sa->getAttributeType(),sa->getAttributeData(),sa->getAttributeSize());
}
for (i=length; i>0; i--) {
st->deleteAttribute(i);
}
prev->addAttribute(OMP_STMT_AFTER, (void*) st->copyPtr (), sizeof(SgStatement *));
break;
}
default: {
for (i=0; i<length; i++) {
sa=st->getAttribute(i);
next->addAttribute(sa->getAttributeType(),sa->getAttributeData(),sa->getAttributeSize());
}
for (i=length; i>0; i--) {
st->deleteAttribute(i);
}
next->addAttribute(OMP_STMT_BEFORE, (void*) st->copyPtr (), sizeof(SgStatement *));
break;
}
}
}
return res;
}
void AddAttributeOmp (SgStatement *stmt) {
SgStatement *last;
if (!stmt) return;
last = stmt->lastNodeOfStmt ()->lexNext ();
for (SgStatement *st=stmt;st && (st != last); st=st->lexNext ()) {
st->addAttribute (OMP_MARK);
}
}
void DelAttributeFromStmt (int type, SgStatement *st) {
int length=st->numberOfAttributes();
for (int i=0; i<length; i++) {
SgAttribute *sa=NULL;
sa = st->getAttribute(i);
if (sa->getAttributeType() == type) {
st->deleteAttribute(i);
break;
}
}
}
int AddOmpStmt (SgStatement * st) {
int res = 0;
int length=st->numberOfAttributes(OMP_STMT_BEFORE);
int i=0;
SgStatement *stmt = NULL;
SgStatement *last = st->lastNodeOfStmt ();
for (i=0;i<length; i++) {
SgAttribute *sa=st->getAttribute(i,OMP_STMT_BEFORE);
stmt = ((SgStatement *)sa->getAttributeData());
AddAttributeOmp (stmt);
if ((st->variant () == FOR_NODE) && (stmt->variant () == ASSIGN_STAT)) {
SgExpression *expr = stmt->expr (1);
if (expr->variant () == FUNC_CALL) {
if (!strcmp(expr->symbol()->identifier(),"min")) {
SgExprListExp *exp = isSgExprListExp(expr->lhs ());
if (exp) {
exp = isSgExprListExp(exp->rhs ());
if (exp) {
SgForStmt *forst = isSgForStmt (st);
if (forst) {
//TO DO
if ((forst->step () != NULL)&&(forst->step ()->isInteger ())) {
if (forst->step ()->valueInteger ()>0)
exp->setValue (*forst->end () - *forst->start());
else
exp->setValue (*forst->start () - *forst->end());
} else if (forst->step () == NULL) {
exp->setValue (*forst->end () - *forst->start());
} else {
SgFunctionCallExp *func = new SgFunctionCallExp(*new SgVariableSymb("abs"));
func->addArg(*forst->end () - *forst->start());
exp->setValue (*func);
}
}
}
}
}
}
}
st->insertStmtBefore (*stmt);
}
length=st->numberOfAttributes(OMP_STMT_AFTER);
for (i=length; i>0; i--) {
SgAttribute *sa=st->getAttribute(i-1,OMP_STMT_AFTER);
stmt = ((SgStatement *)sa->getAttributeData());
AddAttributeOmp (stmt);
last->insertStmtAfter (*stmt);
res++;
}
return res;
}
SgStatement * GetLexNextIgnoreOMP(SgStatement *st) {
SgStatement *ret=st->lexNext ();
if (ret && isOmpDir (ret)) {
return GetLexNextIgnoreOMP (ret);
}
return ret;
}
int isOmpGetNumThreads(SgExpression *e)
{
int replace = 0;
if (e == NULL) return 0;
if ((e->variant()==FUNC_CALL) && !strcmp(e->symbol()->identifier(),"omp_get_num_threads")) {
NODE_CODE(e->thellnd)=INT_VAL;
NODE_TYPE(e->thellnd) = GetAtomicType(T_INT);
NODE_INT_CST_LOW (e->thellnd) = 1;
replace = 1;
}
if((e->variant()==ADD_OP) || (e->variant()==SUBT_OP)){
replace = isOmpGetNumThreads (e->rhs());
if (!replace) replace = isOmpGetNumThreads (e->lhs());
}
return replace;
}
SgExpression * FindSubExpression (SgExpression *expr1,SgExpression *expr2) {
SgExpression * res= NULL;
if ((expr1 == NULL) || (expr2 == NULL)) return res;
if ((expr1->variant () == expr2->variant ()) &&
(expr1->lhs () != NULL) &&
(expr2->lhs () != NULL) &&
(expr1->rhs () != NULL) &&
(expr2->rhs () != NULL) &&
isSgVarRefExp(expr1->lhs ()) &&
isSgVarRefExp(expr1->rhs ()) &&
isSgVarRefExp(expr2->lhs ()) &&
isSgVarRefExp(expr2->rhs ())) {
SgSymbol *expr1_sym1=expr1->lhs ()->symbol ();
SgSymbol *expr1_sym2=expr1->rhs ()->symbol ();
SgSymbol *expr2_sym1=expr2->lhs ()->symbol ();
SgSymbol *expr2_sym2=expr2->rhs ()->symbol ();
if (!strcmp (expr1_sym1->identifier(),expr2_sym1->identifier()) && !strcmp (expr1_sym2->identifier(),expr2_sym2->identifier())) return expr1;
}
res = FindSubExpression(expr1->lhs (), expr2);
if (res == NULL) return FindSubExpression(expr1->rhs (), expr2);
return res;
}
SgSymbol *ChangeParallelDir (SgStatement *stmt) {
SgExprListExp *exp=isSgExprListExp (stmt->expr(1));
int i=0;
if (exp == NULL) return NULL;
for (SgExpression *expr=exp->elem(i); i<exp->length(); i++) {
if (expr->variant () == ACROSS_OP) {
SgStatement *st;
SgStatement *loop=GetLexNextIgnoreOMP (stmt);
for(st=loop; st && (st != loop->lastNodeOfStmt ()); st=st->lexNext ()) {
if (st->variant () == ASSIGN_STAT) {
if (st->lexNext ()->variant () == FOR_NODE) {
SgStatement *forst = st->lexNext ();
int length=forst->numberOfAttributes(OMP_STMT_BEFORE);
int find=0;
for (int i=0; i<length; i++) {
SgAttribute *sa=forst->getAttribute(i,OMP_STMT_BEFORE);
if (((SgStatement *)sa->getAttributeData())->variant () == OMP_DO_DIR) {
find=1; break;
}
}
if (find == 0) return NULL;
SgSymbol *j=st->expr(0)->symbol();
SgSymbol *newj=st->expr(1)->lhs()->symbol();
SgExpression *newj_iam=st->expr(1);
SgExpression *res = FindSubExpression (stmt->expr(0),newj_iam);
if (res != NULL) {
NODE_CODE(res->thellnd) = VAR_REF;
res->setSymbol (*j);
delete res->lhs();
delete res->rhs();
res->setLhs (NULL);
res->setRhs (NULL);
}
stmt->replaceSymbBySymb(*newj,*j);
loop->setSymbol (*j);
if (HideOmpStmt (st)) st->extractStmt ();
return newj;
}
}
if (isSgForStmt (st)) loop = st;
}
}
}
return NULL;
}
void ChangeAccrossOpenMPParam (SgStatement *stmt, SgSymbol *newj, int ub) {
SgStatement *st=stmt;
SgStatement *loop=NULL;
SgValueExp c1(1);
if (ub == 0) return;
int find=0;
for(; st && st->lexNext () && (st != stmt->lastNodeOfStmt ()); st=st->lexNext ()) {
if (st->variant ()== FOR_NODE) loop = st;
SgStatement * forst=st->lexNext ();
int length=forst->numberOfAttributes(OMP_STMT_BEFORE);
find=0;
for (int i=0; i<length; i++) {
SgAttribute *sa=forst->getAttribute(i,OMP_STMT_BEFORE);
if (((SgStatement *)sa->getAttributeData())->variant () == OMP_DO_DIR) {
find=1; break;
}
}
if (find == 1) break;
}
if ((find==1) && loop && (newj != NULL)) {
SgForStmt *accr_do = isSgForStmt(loop);
for (;st && (st->lexNext() != NULL) && (st != loop->lastNodeOfStmt ()); st=st->lexNext ())
if ((st->lexNext()!= NULL) && (st->lexNext()->lexNext() != NULL)) {
SgExpression *expr = new SgVarRefExp (loop->symbol ());
SgStatement *stIfStmt = st->lexNext()->lexNext();
if (IsPositiveDoStep(accr_do->step())) {
*expr = expr->copy() < accr_do->start()->copy() || expr->copy() > accr_do->end()->copy ();
} else {
*expr = expr->copy() < accr_do->end()->copy() || expr->copy() > accr_do->start()->copy ();
}
if (stIfStmt->lexNext()->variant () == CYCLE_STMT) {
SgIfStmt *ifst = isSgIfStmt (stIfStmt);
if (ifst != NULL) {
ifst->setExpression (0, *expr);
} else {
SgLogIfStmt *logifst = isSgLogIfStmt (stIfStmt);
if (logifst != NULL) {
logifst->setExpression (0, *expr);
}
}
}
}
if (ub == 1) {
SgExpression *ind = accr_do->end ();
*ind = *ind + *new SgFunctionCallExp(*new SgVariableSymb("OMP_GET_NUM_THREADS")) - c1.copy ();
accr_do->setEnd(*ind);
} else if (ub == 2) {
SgExpression *ind = accr_do->start ();
*ind = *ind + *new SgFunctionCallExp(*new SgVariableSymb("OMP_GET_NUM_THREADS")) - c1.copy ();
accr_do->setStart(*ind);
}
loop->setSymbol (*newj);
}
}
void ChangeParallelLoopHideOpenmp(SgStatement *stmt)
{
int nloop=0;
SgStatement *prev=NULL;
SgStatement *st;
stmt_list *stmt_to_delete = NULL;
for(SgExpression *dovar=stmt->expr(2); dovar; dovar=dovar->rhs()) nloop++;
SgStatement *next=stmt->lexNext ();
SgStatement *forst, *last;
prev=stmt->lexPrev ();
if ((next->variant () == OMP_PARALLEL_DO_DIR) ||
(next->variant () == OMP_DO_DIR)) {
forst = next->lexNext ();
if (forst->variant () == FOR_NODE) {
forst->addAttribute(OMP_STMT_BEFORE, (void*) next->copyPtr (), sizeof(SgStatement *));
stmt_to_delete = addToStmtList(stmt_to_delete, next);
last=forst->lastNodeOfStmt ()->lexNext ();
if ((last->variant () == OMP_END_PARALLEL_DO_DIR) ||
(last->variant () == OMP_END_DO_DIR)) {
forst->addAttribute(OMP_STMT_AFTER, (void*) last->copyPtr (), sizeof(SgStatement *));
stmt_to_delete = addToStmtList(stmt_to_delete, last);
}
}
} else {
if ((prev->variant () == OMP_PARALLEL_DO_DIR) ||
(prev->variant () == OMP_DO_DIR)) {
forst = next;
if (forst->variant () == FOR_NODE) {
forst->addAttribute(OMP_STMT_BEFORE, (void*) prev->copyPtr (), sizeof(SgStatement *));
stmt_to_delete = addToStmtList(stmt_to_delete, prev);
}
last=forst->lastNodeOfStmt ()->lexNext ();
if ((last->variant () == OMP_END_PARALLEL_DO_DIR) ||
(last->variant () == OMP_END_DO_DIR)) {
forst->addAttribute(OMP_STMT_AFTER, (void*) last->copyPtr (), sizeof(SgStatement *));
stmt_to_delete = addToStmtList(stmt_to_delete, last);
}
} else {
if (next->variant () == FOR_NODE) {
for(st=next, prev=st; st && (nloop>0); st=st->lexNext ()) {
if (st->variant () == FOR_NODE) {
if ((prev != st) && (prev->lexNext () != st)) {
for(SgStatement *s=prev->lexNext (); s && (s!= st); s=s->lexNext ()) {
st->addAttribute(OMP_STMT_BEFORE, (void*) s->copyPtr (), sizeof(SgStatement *));
stmt_to_delete = addToStmtList(stmt_to_delete, s);
s=s->lastNodeOfStmt ();
}
SgStatement *last=prev->lastNodeOfStmt();
for(SgStatement *s=st->lastNodeOfStmt()->lexNext (); s && (s!= last); s=s->lexNext ()) {
st->addAttribute(OMP_STMT_AFTER, (void*) s->copyPtr (), sizeof(SgStatement *));
stmt_to_delete = addToStmtList(stmt_to_delete, s);
s=s->lastNodeOfStmt ();
}
}
prev = st;
nloop--;
}
}
}
}
}
for(;stmt_to_delete; stmt_to_delete= stmt_to_delete->next) Extract_Stmt(stmt_to_delete->st);// extracting OpenMP Directives
}
void MarkAndReplaceOriginalStmt (SgStatement *func) {
SgStatement *stmt = NULL;
SgStatement *first = func->lexNext();
SgStatement *last = func->lastNodeOfStmt();
SgStatement *next = NULL;
int res=0;
for (stmt = first; stmt && (stmt != last);stmt=stmt->lexNext ()) {
if (stmt->hasLabel ()&& (stmt->variant() != FORMAT_STAT)&& (stmt->variant() != CONT_STAT)) {
SgStatement *tmp = new SgStatement (CONT_STAT);
tmp->setLabel (*stmt->label ());
tmp->setlineNumber (stmt->lineNumber());
tmp->addAttribute(OMP_MARK);
stmt->insertStmtBefore(*tmp, *stmt->controlParent());
BIF_LABEL(stmt->thebif)=NULL;
}
stmt->addAttribute(OMP_MARK);
if (stmt->variant () == DVM_PARALLEL_ON_DIR) ChangeParallelLoopHideOpenmp(stmt);
continue;
switch (stmt->variant ()) {
case OMP_PARALLEL_DO_DIR:
case OMP_DO_DIR:
case OMP_END_PARALLEL_DO_DIR:
case OMP_END_DO_DIR: res=HideOmpStmt (stmt); break;
case LOGIF_NODE: LogIf_to_IfThen(stmt); break;
}
if (res == 0) {
stmt = stmt->lexNext();
} else {
res = 0;
next = stmt->lexNext();
stmt->extractStmt ();
stmt = next;
}
}
}
stmt_list * PushToStmtList(stmt_list *pstmt, SgStatement *stat) {
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);
}
int ValFromStmtList(stmt_list *pstmt) {
if (pstmt) {
return pstmt->st->variant ();
}
return 0;
}
stmt_list * PopFromStmtList(stmt_list *pstmt) {
if (pstmt) {
stmt_list *tmp = pstmt;
pstmt = pstmt->next;
tmp->next = NULL;
delete tmp;
return (pstmt);
}
return NULL;
}
int isFromOneThread (int variant) {
switch (variant) {
case OMP_ONETHREAD_DIR:
case OMP_DO_DIR:
case OMP_SECTIONS_DIR:
case OMP_SINGLE_DIR:
case OMP_WORKSHARE_DIR:
case OMP_PARALLEL_DO_DIR:
case OMP_PARALLEL_SECTIONS_DIR:
case OMP_PARALLEL_WORKSHARE_DIR:
case OMP_MASTER_DIR:
case OMP_CRITICAL_DIR:
case PROG_HEDR:
case OMP_ORDERED_DIR: {
return 1; break;
}
case PROC_HEDR:
case FUNC_HEDR:
case OMP_PARALLEL_DIR: {
return 0; break;
}
default: {
return -1;
break;
}
}
return -1;
}
SgStatement * InsertBeginSynchroStat (SgStatement *current) { /*OMP*/
if (isADeclBif(current->variant ())) return NULL;
return current;
}
int InsertEndSynchroStat (SgStatement *current) { /*OMP*/
if (isADeclBif(current->variant ())) return 0;
if (current->variant () != CONTROL_END) {
current->insertStmtAfter(*new SgStatement (OMP_BARRIER_DIR),*current->controlParent()); /*OMP*/
//current->insertStmtAfter(*new SgStatement (OMP_END_MASTER_DIR),*current->controlParent()); /*OMP*/
} else {
current->lexNext ()->insertStmtBefore(*new SgStatement (OMP_BARRIER_DIR),*current->lexNext ()->controlParent()); /*OMP*/
//current->lexNext ()->insertStmtBefore(*new SgStatement (OMP_END_MASTER_DIR),*current->lexNext ()->controlParent()); /*OMP*/
}
return 1;
}
void InsertSynchroBlock (SgStatement *begin, SgStatement *end) {
SgStatement *last=end->lexPrev ();
SgStatement *barrier = new SgStatement (OMP_BARRIER_DIR);
SgStatement *master = new SgStatement (OMP_MASTER_DIR);
barrier->addAttribute (OMP_MARK);
master->addAttribute (OMP_MARK);
if (begin->lexPrev ()->variant () != OMP_BARRIER_DIR) begin->insertStmtBefore(*barrier,*begin->controlParent());
begin->insertStmtBefore(*master,*begin->controlParent());
barrier = new SgStatement (OMP_BARRIER_DIR);
master = new SgStatement (OMP_END_MASTER_DIR);
barrier->addAttribute (OMP_MARK);
master->addAttribute (OMP_MARK);
if (end->lexNext () != NULL) {
if (end->lexNext ()->variant () != OMP_BARRIER_DIR) last->insertStmtAfter(*barrier,*last->controlParent());
} else {
last->insertStmtAfter(*barrier,*last->controlParent());
}
last->insertStmtAfter(*master,*last->controlParent());
}
SgStatement * InsertCriticalBlock (SgStatement *begin, SgStatement *end) {
SgStatement *critical = new SgStatement (OMP_CRITICAL_DIR);
critical->setExpression (0,*new SgVarRefExp(new SgSymbol (VARIABLE_NAME,"dvmcritical")));
critical->addAttribute (OMP_MARK);
begin->insertStmtBefore(*critical,*begin->controlParent());
critical = new SgStatement (OMP_END_CRITICAL_DIR);
critical->setExpression (0,*new SgVarRefExp(new SgSymbol (VARIABLE_NAME,"dvmcritical")));
critical->addAttribute (OMP_MARK);
end->insertStmtBefore(*critical,*end->controlParent());
return critical;
}
void MarkParameters (SgStatement *st) {
SgExprListExp *list=isSgExprListExp(st->expr(0));
if (list!= NULL) {
for (int i=0;i<list->length (); i++) {
SgExpression *exp=list->elem (i);
if (exp->variant ()== CONST_REF) {
exp->symbol ()->addAttribute (OMP_MARK);
}
}
}
}
void AddOpenMPSynchro (SgStatement *func) {
SgStatement *stmt = NULL;
SgStatement *first = func->lexNext();
SgStatement *last = func->lastNodeOfStmt();
stmt_list *omp_list = NULL;
omp_list = PushToStmtList (omp_list, func);
int FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
SgStatement * SynchroBlockBegin = NULL;
for (stmt = first; stmt && (stmt != last); stmt = stmt->lexNext()) {
AddOmpStmt (stmt);
}
for(stmt = first; stmt && (stmt != last); stmt = stmt->lexNext()) {
if (stmt->variant () == OMP_ONETHREAD_DIR) {
FromOneThread = 1;
omp_list = PushToStmtList (omp_list, stmt);
continue;
}
if (stmt->variant () == PARAM_DECL) {
MarkParameters (stmt);
continue;
}
if (isADeclBif(stmt->variant ())) continue;
if (isOmpDir (stmt) || stmt->variant () == CONTROL_END || stmt->variant () == CONT_STAT) {
switch (stmt->variant ()) {
case OMP_END_PARALLEL_DIR: {
if (ValFromStmtList (omp_list) == OMP_PARALLEL_DIR) {
AddSharedClauseForDVMVariables (omp_list->st, stmt);
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
} else {
Error("Can`t find $OMP PARALLEL directive for this $OMP END PARALLEL directive %s", "", 701, stmt);
}
break;
}
case OMP_END_DO_DIR: {
if (ValFromStmtList (omp_list) == OMP_DO_DIR) {
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
} else {
Error("Can`t find $OMP DO directive for this $OMP END DO directive %s", "", 702, stmt);
}
break;
}
case OMP_END_SECTIONS_DIR: {
if (ValFromStmtList (omp_list) == OMP_SECTIONS_DIR) {
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
} else {
Error("Can`t find $OMP SECTIONS directive for this $OMP END SECTIONS directive %s", "", 703, stmt);
}
break;
}
case OMP_END_SINGLE_DIR: {
if (ValFromStmtList (omp_list) == OMP_SINGLE_DIR) {
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
} else {
Error("Can`t find $OMP SINGLE directive for this $OMP END SINGLE directive %s", "", 704, stmt);
}
break;
}
case OMP_END_WORKSHARE_DIR: {
if (ValFromStmtList (omp_list) == OMP_WORKSHARE_DIR) {
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
} else {
Error("Can`t find $OMP WORKSHARE directive for this $OMP END WORKSHARE directive %s", "", 705, stmt);
}
break;
}
case OMP_END_PARALLEL_DO_DIR: {
if (ValFromStmtList (omp_list) == OMP_PARALLEL_DO_DIR) {
AddSharedClauseForDVMVariables (omp_list->st, stmt);
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
} else {
Error("Can`t find $OMP PARALLEL DO directive for this $OMP END PARALLEL DO directive %s", "", 706, stmt);
}
break;
}
case OMP_END_PARALLEL_SECTIONS_DIR: {
if (ValFromStmtList (omp_list) == OMP_PARALLEL_SECTIONS_DIR) {
AddSharedClauseForDVMVariables (omp_list->st, stmt);
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
} else {
Error("Can`t find $OMP PARALLEL SECTIONS directive for this $OMP END PARALLEL SECTIONS directive %s", "", 707, stmt);
}
break;
}
case OMP_END_PARALLEL_WORKSHARE_DIR: {
if (ValFromStmtList (omp_list) == OMP_PARALLEL_WORKSHARE_DIR) {
AddSharedClauseForDVMVariables (omp_list->st, stmt);
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
} else {
Error("Can`t find $OMP PARALLEL WORKSHARE directive for this $OMP END PARALLEL WORKSHARE directive %s", "", 708, stmt);
}
break;
}
case OMP_END_MASTER_DIR: {
if (ValFromStmtList (omp_list) == OMP_MASTER_DIR) {
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
} else {
Error("Can`t find $OMP MASTER directive for this $OMP END MASTER directive %s", "", 709, stmt);
}
break;
}
case OMP_END_CRITICAL_DIR: {
if (ValFromStmtList (omp_list) == OMP_CRITICAL_DIR) {
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
} else {
Error("Can`t find $OMP CRITICAL directive for this $OMP END CRITICAL directive %s", "", 710, stmt);
}
break;
}
case OMP_END_ORDERED_DIR: {
if (ValFromStmtList (omp_list) == OMP_ORDERED_DIR) {
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
} else {
Error("Can`t find $OMP ORDERED directive for this $OMP END ORDERED directive %s", "", 711, stmt);
}
break;
}
case OMP_PARALLEL_DIR:
case OMP_DO_DIR:
case OMP_SECTIONS_DIR:
case OMP_SINGLE_DIR:
case OMP_WORKSHARE_DIR:
case OMP_PARALLEL_DO_DIR:
case OMP_PARALLEL_SECTIONS_DIR:
case OMP_PARALLEL_WORKSHARE_DIR:
case OMP_MASTER_DIR:
case OMP_CRITICAL_DIR:
case OMP_ORDERED_DIR: {
omp_list = PushToStmtList (omp_list, stmt);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
break;
}
case CONT_STAT:
case CONTROL_END: {
SgStatement *next =stmt->lexNext ();
if (next && (next->variant () == OMP_END_PARALLEL_DO_DIR || next->variant () == OMP_END_DO_DIR)) break;
SgStatement *cp =stmt->controlParent ();
if (cp && cp->variant () == FOR_NODE) {
SgStatement *prev = cp->lexPrev ();
if (prev) {
if (prev->variant () == OMP_DO_DIR) {
if (ValFromStmtList (omp_list) == OMP_DO_DIR) {
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
}
break;
}
if (prev->variant () == OMP_PARALLEL_DO_DIR) {
if (ValFromStmtList (omp_list) == OMP_PARALLEL_DO_DIR) {
AddSharedClauseForDVMVariables (omp_list->st, stmt);
omp_list = PopFromStmtList (omp_list);
FromOneThread = isFromOneThread (ValFromStmtList (omp_list));
}
break;
}
}
}
}
}
}
if (stmt->numberOfAttributes(OMP_CRITICAL) != 0) {
SgStatement *tmp=stmt;
for (; tmp; tmp = tmp->lexNext ()) {
if (tmp->numberOfAttributes(OMP_CRITICAL) == 0) break;
}
if (SynchroBlockBegin == NULL) stmt = InsertCriticalBlock (stmt, tmp);
else stmt = tmp->lexPrev ();
continue;
}
if ((stmt->numberOfAttributes(OMP_MARK) == 0) || (stmt->numberOfAttributes(OMP_CRITICAL) != 0)) {
if ((SynchroBlockBegin != NULL) || (FromOneThread == 1)) continue;
else {
SynchroBlockBegin = stmt;
}
} else {
if (SynchroBlockBegin != NULL) {
InsertSynchroBlock (SynchroBlockBegin, stmt);
SynchroBlockBegin = NULL;
}
}
}
if (SynchroBlockBegin != NULL) InsertSynchroBlock (SynchroBlockBegin, last);
}
SgExprListExp * FindDVMVariableRefsInExpr (SgExpression *expr, SgExprListExp *list)
{
if (expr==NULL)
return list;
if (expr->variant() == VAR_REF)
{
SgSymbol *sym = expr->symbol ();
if (sym->numberOfAttributes(OMP_MARK) == 0) {
if (list != NULL) {
if (!list->IsSymbolInExpression (*sym)) list->append (*expr);
} else {
list = new SgExprListExp (*expr);
}
}
}
if (expr->variant() == ARRAY_REF)
{
SgSymbol *sym = expr->symbol ();
if (sym->numberOfAttributes(OMP_MARK) == 0) {
if (list != NULL) {
if (!list->IsSymbolInExpression (*sym)) list->append (*new SgArrayRefExp(*sym));
} else {
list = new SgExprListExp (*new SgArrayRefExp(*sym));
}
}
}
list = FindDVMVariableRefsInExpr(expr->lhs (),list);
list = FindDVMVariableRefsInExpr(expr->rhs (),list);
return list;
}
SgExprListExp * FindDVMVariableRefsInStmt (SgStatement *stmt, SgExprListExp *list)
{
if (stmt==NULL)
return list;
list = FindDVMVariableRefsInExpr(stmt->expr (0),list);
list = FindDVMVariableRefsInExpr(stmt->expr (1),list);
list = FindDVMVariableRefsInExpr(stmt->expr (2),list);
return list;
}
SgExprListExp * FindDVMVariableRefsInStmts (SgStatement *first, SgStatement *last)
{
SgExprListExp *list = NULL;
for (SgStatement * stmt=first; stmt && (stmt != last); stmt=stmt->lexNext ()) {
list = FindDVMVariableRefsInStmt (stmt, list);
}
return list;
}
void AddSharedClauseForDVMVariables (SgStatement *first, SgStatement *last)
{
SgExprListExp *list = FindDVMVariableRefsInStmts (first->lexNext (), last);
if (list!=NULL) {
switch (first->variant ()) {
case OMP_PARALLEL_DIR:
case OMP_PARALLEL_DO_DIR:
case OMP_PARALLEL_SECTIONS_DIR:
case OMP_PARALLEL_WORKSHARE_DIR:
if (first->expr (0)) {
SgExprListExp *ll = isSgExprListExp (first->expr (0));
if (ll) ll->append (* new SgExpression (OMP_SHARED, list,NULL,NULL,NULL));
} else {
first->setExpression (0, *new SgExprListExp (* new SgExpression (OMP_SHARED, list,NULL,NULL,NULL)));
}
}
}
}
void TranslateFileOpenMPDVM(SgFile *f)
{
SgStatement *func,*stat;
//int i,numfun;
SgStatement *end_of_unit; // last node (END or CONTAINS statement ) of program unit
// 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
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 (SgSymbol *sym=f->firstSymbol(); sym; sym=sym->next ()) {
sym->addAttribute (OMP_MARK);
}
for(stat=stat->lexNext(); stat; 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); //changing variant VAR_DECL with VAR_DECL_90
continue;
}
// PROGRAM, SUBROUTINE, FUNCTION header
func = stat;
cur_func = func;
//scanning the Symbols Table of the function
// ScanSymbTable(func->symbol(), (f->functions(i+1))->symbol());
// translating the function
if(only_debug)
InsertDebugStat(func, end_of_unit);
else {
MarkAndReplaceOriginalStmt (func);
TransFunc (func, end_of_unit);
AddOpenMPSynchro (func);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1582
dvm/fdvm/trunk/fdvm/stmt.cpp Normal file

File diff suppressed because it is too large Load Diff