/*************************************************************** * Function: processEndExpr(Expression*) * Purpose : Pre-process range end sub-expressions in expressions * Initial : Maxime Chevalier-Boisvert on March 1, 2009 **************************************************************** Revisions and bug fixes: */ Expression* processEndExpr(Expression* pExpr, ProgFunction* pFunction, const EndExpr::AssocVector& assocs) { // Switch on the expression type switch (pExpr->getExprType()) { // Parameterized expression case Expression::PARAM: { // Get a typed pointer to the expression ParamExpr* pParamExpr = (ParamExpr*)pExpr; // Get the symbol expression SymbolExpr* pSymbol = pParamExpr->getSymExpr(); // Get the argument vector const ParamExpr::ExprVector& args = pParamExpr->getArguments(); // Create a vector for the transformed arguments ParamExpr::ExprVector newArgs; // For each argument for (size_t i = 0; i < args.size(); ++i) { // Create a new association vector EndExpr::AssocVector newAssocs; // Create an association for this argument and add it to the vector newAssocs.push_back( EndExpr::Assoc( pSymbol, i, i == args.size() - 1 ) ); // Add the higher-level associations to the end of the vector newAssocs.insert(newAssocs.end(), assocs.begin(), assocs.end()); // Transform this argument expression newArgs.push_back( processEndExpr( args[i], pFunction, newAssocs ) ); } // Return the transformed parameterized expression return new ParamExpr(pSymbol->copy(), newArgs); } break; // Cell indexing expression case Expression::CELL_INDEX: { // Get a typed pointer to the expression CellIndexExpr* pCellExpr = (CellIndexExpr*)pExpr; // Get the symbol expression SymbolExpr* pSymbol = pCellExpr->getSymExpr(); // Get the argument vector const CellIndexExpr::ExprVector& args = pCellExpr->getArguments(); // Create a vector for the transformed arguments CellIndexExpr::ExprVector newArgs; // For each argument for (size_t i = 0; i < args.size(); ++i) { // Create a new association vector EndExpr::AssocVector newAssocs; // Create an association for this argument and add it to the vector newAssocs.push_back( EndExpr::Assoc( pSymbol, i, i == args.size() - 1 ) ); // Add the higher-level associations to the end of the vector newAssocs.insert(newAssocs.end(), assocs.begin(), assocs.end()); // Transform this argument expression newArgs.push_back( processEndExpr( args[i], pFunction, newAssocs ) ); } // Return the transformed parameterized expression return new CellIndexExpr(pSymbol->copy(), newArgs); } break; // Range end expression case Expression::END: { // Ensure associations were found assert (assocs.empty() == false); // Create and return a new range end expression with the matrix associations return new EndExpr(assocs); } break; // All other expression types default: { // Copy the expression pExpr = pExpr->copy(); // Get the list of sub-expressions for this expression Expression::ExprVector subExprs = pExpr->getSubExprs(); // For each sub-expression for (size_t i = 0; i < subExprs.size(); ++i) { // Get a pointer to the sub-expression Expression* pSubExpr = subExprs[i]; // If this sub-expression is NULL, skip it if (pSubExpr == NULL) continue; // Transform this sub-expression Expression* pNewExpr = processEndExpr(pSubExpr, pFunction, assocs); // Replace the sub-expression by the transformed version pExpr->replaceSubExpr(i, pNewExpr); } // Return the modified expression return pExpr; } } }
/*************************************************************** * Function: splitExpression() * Purpose : Convert an expression to split form * Initial : Maxime Chevalier-Boisvert on January 7, 2009 **************************************************************** Revisions and bug fixes: */ bool splitExpression(Expression* pExpr, StmtSequence::StmtVector& stmtVector, Expression*& pTopExpr, ProgFunction* pFunction) { // // For each sub-expression: // - Split it recursively // - Assign top-level expression to a temp // - Replace sub-expr by temp var // // Take a temp from list to assign sub-expr to temp // Once temps are used, they become free again // // Make a copy of the expression to use as the top-level expression pTopExpr = pExpr->copy(); // If the expression is a lambda expression, perform no splitting and return early if (pTopExpr->getExprType() == Expression::ExprType::LAMBDA) return false; if (pTopExpr->getExprType() == Expression::ExprType::DOT) return false; // Get the list of sub-expressions for this expression Expression::ExprVector subExprs = pTopExpr->getSubExprs(); // If there are no sub-expressions, perform no splitting and return early if (subExprs.empty()) return false; // For each sub-expression for (size_t i = 0; i < subExprs.size(); ++i) { // Get a pointer to the sub-expression Expression* pSubExpr = subExprs[i]; // If the sub-expression is null, skip it if (pSubExpr == NULL) continue; // Declare a variable to store the top-level expression Expression* pTopSubExpr = NULL; // Split the sub-expression bool exprSplit = splitExpression(pSubExpr, stmtVector, pTopSubExpr, pFunction); // If the sub-expression was not split, skip it if (!exprSplit) continue; // If the current expression is a parameterized or // cell indexing expression and the sub-expression // is a range expressions if ((pTopExpr->getExprType() == Expression::ExprType::PARAM || pTopExpr->getExprType() == Expression::ExprType::CELL_INDEX) && pTopSubExpr->getExprType() == Expression::ExprType::RANGE) { // Replace the sub-expression by the top sub-expression directly pTopExpr->replaceSubExpr(i, pTopSubExpr); } // If the current expression is a parameterized // expression and the sub-expression is a cell-indexing // expression else if (pTopExpr->getExprType() == Expression::ExprType::PARAM && pTopSubExpr->getExprType() == Expression::ExprType::CELL_INDEX) { // Replace the sub-expression by the top sub-expression directly pTopExpr->replaceSubExpr(i, pTopSubExpr); } else { // Create a new symbol object for the temp variable SymbolExpr* pTempVar = pFunction->createTemp(); // Assign the sub-expression to the temp variable stmtVector.push_back(new AssignStmt(pTempVar, pTopSubExpr)); // Replace the sub-expression use by the temp variable pTopExpr->replaceSubExpr(i, pTempVar); } } // Expression split return true; }
/******************************************************************* * Function: ArrayIndexAnalysis::flowFunction * Purpose : compute out set from in set based on the type of statement * Initial : Nurudeen A. Lameed on July 21, 2009 ******************************************************************** Revisions and bug fixes: */ FlowSet ArrayIndexAnalysis::flowFunction(const Statement* stmt, const FlowSet& in) { // declare out flow set FlowSet out; // copy in flow set into out flow set out.insert(in.begin(), in.end()); switch(stmt->getStmtType()) { case Statement::ASSIGN: { const AssignStmt* aStmt = dynamic_cast<const AssignStmt*>(stmt); // get the left handsides Expression::ExprVector lhs = aStmt->getLeftExprs(); SymbolExpr* symbol = 0; if (lhs.size() == 1 && lhs[0]->getExprType() == Expression::SYMBOL) { symbol = dynamic_cast<SymbolExpr*>(lhs[0]); } else { // get all left symbols/expressions for (size_t i=0, size = lhs.size(); i < size; ++i) { // update out set, if it is a parameterized expression computeOutSet(lhs[i], out); } } // check the right hand side Expression* rhs = aStmt->getRightExpr(); // is symbol an array/matrix with known size? if ( allMatrixSymbols.find(symbol) != allMatrixSymbols.end() ) // symbol is used as an array ... { // get the type information TypeInfo typ = getTypeInfo(aStmt, symbol); if ( typ.getSizeKnown()) { const TypeInfo::DimVector& dimV = typ.getMatSize(); TypeInfo::DimVector bounds; // remove dimensions with value 1; (e.g. row or column vectors) std::remove_copy_if(dimV.begin(), dimV.end(), std::back_inserter(bounds), equalOne); // update the table arrayBoundsMap[symbol] = bounds; // update the flow set using the bounds updateFlowSet(symbol, bounds, out); } } // update outset (for parameterized expression) computeOutSet(rhs, out); // update outset (for index update if (isIndex(symbol)) { // compute flow set for index update computeOutSet(symbol, rhs, out); } } break; case Statement::EXPR: { // convert the statement to an expression const ExprStmt* aStmt = dynamic_cast<const ExprStmt*>(stmt); // compute out set for the statement computeOutSet(aStmt->getExpression(), out); } break; default: // do nothing; { } } return out; }
/*************************************************************** * Function: transformLoopsExpr() * Purpose : Expand logical operators in an expression * Initial : Maxime Chevalier-Boisvert on January 14, 2009 **************************************************************** Revisions and bug fixes: */ Expression* transformLogicExpr(Expression* pExpr, StmtSequence::StmtVector& stmtVector, ProgFunction* pFunction) { // If this is a binary expression if (pExpr->getExprType() == Expression::BINARY_OP) { // Get a typed pointer to the expression BinaryOpExpr* pBinExpr = (BinaryOpExpr*)pExpr; // If this is a logical OR expression if (pBinExpr->getOperator() == BinaryOpExpr::OR) { // Create a new temp variable to store the result SymbolExpr* pDestVar = pFunction->createTemp(); // Create a variable to store the left-expression value SymbolExpr* pLeftVar = pFunction->createTemp(); // Create a statement vector for the left and right expression statements StmtSequence::StmtVector leftStmts; StmtSequence::StmtVector rightStmts; // Transform the left and right expressions Expression* pNewLExpr = transformLogicExpr(pBinExpr->getLeftExpr() , stmtVector, pFunction); Expression* pNewRExpr = transformLogicExpr(pBinExpr->getRightExpr(), rightStmts, pFunction); // Assign the left-expression value to a variable stmtVector.push_back(new AssignStmt(pLeftVar, pNewLExpr)); // Create an assignment statement for the if block leftStmts.push_back(new AssignStmt(pDestVar, pLeftVar)); // Create an assignment statement for the else branch rightStmts.push_back(new AssignStmt(pDestVar, pNewRExpr)); // Create a new if-statement to replace the logical operator stmtVector.push_back( new IfElseStmt( pLeftVar, new StmtSequence(leftStmts), new StmtSequence(rightStmts) ) ); // Return the destination variable as the expression to use return pDestVar; } // If this is a logical AND expression else if (pBinExpr->getOperator() == BinaryOpExpr::AND) { // Create a new temp variable to store the result SymbolExpr* pDestVar = pFunction->createTemp(); // Create a variable to store the left-expression value SymbolExpr* pLeftVar = pFunction->createTemp(); // Create a statement vector for the left and right expression statements StmtSequence::StmtVector leftStmts; StmtSequence::StmtVector rightStmts; // Transform the left and right expressions Expression* pNewLExpr = transformLogicExpr(pBinExpr->getLeftExpr() , stmtVector, pFunction); Expression* pNewRExpr = transformLogicExpr(pBinExpr->getRightExpr(), rightStmts, pFunction); // Assign the left-expression value to a variable stmtVector.push_back(new AssignStmt(pLeftVar, pNewLExpr)); // Create an assignment statement for the if branch leftStmts.push_back(new AssignStmt(pDestVar, pNewRExpr)); // Create an assignment statement for the else block rightStmts.push_back(new AssignStmt(pDestVar, pLeftVar)); // Create a new if-statement to replace the logical operator stmtVector.push_back( new IfElseStmt( pLeftVar, new StmtSequence(leftStmts), new StmtSequence(rightStmts) ) ); // Return the destination variable as the expression to use return pDestVar; } } // At this point, we know the expression is not a logical expression // However, it could contain a logical sub-expression // Make a copy of the expression to use as the new expression Expression* pNewExpr = pExpr->copy(); // Get the list of sub-expressions for this expression Expression::ExprVector subExprs = pNewExpr->getSubExprs(); // For each sub-expression for (size_t i = 0; i < subExprs.size(); ++i) { // Get a pointer to the sub-expression Expression* pSubExpr = subExprs[i]; // If the sub-expression is null, skip it if (pSubExpr == NULL) continue; // Transform the sub-expression recursively Expression* pNewSubExpr = transformLogicExpr(pSubExpr, stmtVector, pFunction); // Replace the sub-expression pExpr->replaceSubExpr(i, pNewSubExpr); } // Return the new expression return pNewExpr; }
/******************************************************************* * Function: ArrayIndexAnalysis::findAllMatrixIndexSymbols * Purpose : Find all indices used in the current function * Initial : Nurudeen A. Lameed on July 21, 2009 ******************************************************************** Revisions and bug fixes: */ void ArrayIndexAnalysis::findAllMatrixIndexSymbols(const StmtSequence* pFuncBody) { // get the sequence of statements const StmtSequence::StmtVector& stmts = pFuncBody->getStatements(); // look for statements with a parameterized expression for (StmtSequence::StmtVector::const_iterator it = stmts.begin(), iEnd = stmts.end(); it != iEnd; ++it) { Statement* pStmt = *it; switch( pStmt->getStmtType() ) { case Statement::ASSIGN: { AssignStmt* aStmt = dynamic_cast<AssignStmt*>(pStmt); Expression::ExprVector lhs = aStmt->getLeftExprs(); for (size_t i=0, size = lhs.size(); i < size; ++i) { fillSets(lhs[i]); } fillSets(aStmt->getRightExpr()); } break; case Statement::EXPR: { ExprStmt* eStmt = dynamic_cast<ExprStmt*>(pStmt); fillSets(eStmt->getExpression()); } break; case Statement::IF_ELSE: { // convert into an if type IfElseStmt* ifstmt = (IfElseStmt*)pStmt; // get all symbols findAllMatrixIndexSymbols(ifstmt->getIfBlock()); findAllMatrixIndexSymbols(ifstmt->getElseBlock()); } break; case Statement::LOOP: { LoopStmt* lstmt = (LoopStmt*)pStmt; // loop initialization StmtSequence* initSeq = lstmt->getInitSeq(); findAllMatrixIndexSymbols(initSeq); // loop test StmtSequence* testSeq = lstmt->getTestSeq(); findAllMatrixIndexSymbols(testSeq); // loop body StmtSequence* sBodySeq = lstmt->getBodySeq(); findAllMatrixIndexSymbols(sBodySeq); // loop increment statement StmtSequence* incrSeq = lstmt->getIncrSeq(); findAllMatrixIndexSymbols(incrSeq); } default: { } } } }