#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 &symbols) { SgExpression *tmp = exp; int idx = 0; if (alignOnLoop.size() == 0) alignOnLoop = vector(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* 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(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* Array::getAcrDims() { return &acrossDims; } vector* Array::getAlignOnLoop() { return &alignOnLoop; } void Array::addTfmDim(int _dim) { transformDims.push_back(_dim); } vector* Array::getTfmDims() { return &transformDims; } void Array::addAccess(Access* _newAccess) { accesses.push_back(_newAccess); } vector* 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* Array::getIfCals() { return &ifCalls; } vector* Array::getElseCals() { return &elseCalls; } vector* Array::getZeroSt() { return &zeroSt; } vector* 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* tArrAcrDims = arrays[i]->getAcrDims(); std::vector* 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* Loop::getArrays() { return &arrays; } vector* Loop::getSymbols() { return &symbols; } int Loop::getLoopDim() { return loopDim; }