/*************************************************************** * Function: processEndExpr(StmtSequence*) * Purpose : Pre-process range end expressions in sequences * Initial : Maxime Chevalier-Boisvert on March 1, 2009 **************************************************************** Revisions and bug fixes: */ StmtSequence* processEndExpr(StmtSequence* pSeq, ProgFunction* pFunction) { // Get a reference to the statement vector const StmtSequence::StmtVector& seqStmts = pSeq->getStatements(); // Create a statement vector to store the transformed output StmtSequence::StmtVector output; // For each statement in the sequence for (StmtSequence::StmtVector::const_iterator stmtItr = seqStmts.begin(); stmtItr != seqStmts.end(); ++stmtItr) { // Get a pointer to the statement Statement* pStmt = *stmtItr; // Switch on the statement type switch (pStmt->getStmtType()) { // Expression statement case Statement::EXPR: { // Get a typed pointer to the statement ExprStmt* pExprStmt = (ExprStmt*)pStmt; // Transform the expression output.push_back( new ExprStmt( processEndExpr(pExprStmt->getExpression(), pFunction), pExprStmt->getSuppressFlag() ) ); } break; // Assignment statement case Statement::ASSIGN: { // Get a typed pointer to the statement AssignStmt* pAssignStmt = (AssignStmt*)pStmt; // Get a reference to the left expressions const AssignStmt::ExprVector& leftExprs = pAssignStmt->getLeftExprs(); // Create a vector for the transformed left-expressions AssignStmt::ExprVector newLExprs; // Transform the left-side expressions for (AssignStmt::ExprVector::const_iterator itr = leftExprs.begin(); itr != leftExprs.end(); ++itr) newLExprs.push_back(processEndExpr(*itr, pFunction)); // Transform the right-side expression Expression* pRightExpr = processEndExpr(pAssignStmt->getRightExpr(), pFunction); // Create and return the transformed assignment statement object output.push_back(new AssignStmt(newLExprs, pRightExpr, pAssignStmt->getSuppressFlag())); } break; // If-else statement case Statement::IF_ELSE: { // Get a typed pointer to the statement IfElseStmt* pIfStmt = (IfElseStmt*)pStmt; // Transform the statement output.push_back( new IfElseStmt( processEndExpr(pIfStmt->getCondition(), pFunction), processEndExpr(pIfStmt->getIfBlock(), pFunction), processEndExpr(pIfStmt->getElseBlock(), pFunction) ) ); } break; // Loop statement case Statement::LOOP: { // Get a typed pointer to the statement LoopStmt* pLoopStmt = (LoopStmt*)pStmt; // Transform the expression output.push_back( new LoopStmt( pLoopStmt->getIndexVar()? pLoopStmt->getIndexVar()->copy():NULL, pLoopStmt->getTestVar()? pLoopStmt->getTestVar()->copy():NULL, processEndExpr(pLoopStmt->getInitSeq(), pFunction), processEndExpr(pLoopStmt->getTestSeq(), pFunction), processEndExpr(pLoopStmt->getBodySeq(), pFunction), processEndExpr(pLoopStmt->getIncrSeq(), pFunction), pLoopStmt->getAnnotations() ) ); } break; // For all other statement types default: { // Copy the statement and add it to the output output.push_back(pStmt->copy()); } } } // Return the transformed output return new StmtSequence(output); }
/*************************************************************** * Function: transformLoops() * Purpose : Expand logical operators in a statement sequence * Initial : Maxime Chevalier-Boisvert on January 14, 2009 **************************************************************** Revisions and bug fixes: */ StmtSequence* transformLogic(StmtSequence* pSeq, ProgFunction* pFunction) { // Get a reference to the statement vector const StmtSequence::StmtVector& seqStmts = pSeq->getStatements(); // Create a statement vector to store the transformed output StmtSequence::StmtVector output; // For each statement in the sequence for (StmtSequence::StmtVector::const_iterator stmtItr = seqStmts.begin(); stmtItr != seqStmts.end(); ++stmtItr) { // Get a pointer to the statement Statement* pStmt = *stmtItr; // Switch on the statement type switch (pStmt->getStmtType()) { // Expression statement case Statement::EXPR: { // Get a typed pointer to the statement ExprStmt* pExprStmt = (ExprStmt*)pStmt; // Transform the expression Expression* pNewExpr = transformLogicExpr(pExprStmt->getExpression(), output, pFunction); // Create a new expression statement output.push_back(new ExprStmt(pNewExpr, pExprStmt->getSuppressFlag())); } break; // Assignment statement case Statement::ASSIGN: { // Get a typed pointer to the statement AssignStmt* pAssignStmt = (AssignStmt*)pStmt; // Get the left expressions for this assignment const AssignStmt::ExprVector& leftExprs = pAssignStmt->getLeftExprs(); // Create a vector to store the transformed left expressions AssignStmt::ExprVector newLeftExprs; // For each left expression for (AssignStmt::ExprVector::const_iterator itr = leftExprs.begin(); itr != leftExprs.end(); ++itr) newLeftExprs.push_back(transformLogicExpr(*itr, output, pFunction)); // Transform the right expression Expression* pNewRExpr = transformLogicExpr(pAssignStmt->getRightExpr(), output, pFunction); // Create a new assignment statement output.push_back(new AssignStmt(newLeftExprs, pNewRExpr, pAssignStmt->getSuppressFlag())); } break; // If-else statement case Statement::IF_ELSE: { // Get a typed pointer to the statement IfElseStmt* pIfStmt = (IfElseStmt*)pStmt; // Transform the test expression Expression* pNewTest = transformLogicExpr(pIfStmt->getCondition(), output, pFunction); // Convert the if and else blocks to split form StmtSequence* pNewIfBlock = transformLogic(pIfStmt->getIfBlock(), pFunction); StmtSequence* pNewElseBlock = transformLogic(pIfStmt->getElseBlock(), pFunction); // Create a new if-else statement and add it to the vector output.push_back(new IfElseStmt(pNewTest, pNewIfBlock, pNewElseBlock)); } break; // Loop statement case Statement::LOOP: { // Get a typed pointer to the statement LoopStmt* pLoopStmt = (LoopStmt*)pStmt; // Transform the statement sequences of the loop StmtSequence* pNewInitSeq = transformLogic(pLoopStmt->getInitSeq(), pFunction); StmtSequence* pNewTestSeq = transformLogic(pLoopStmt->getTestSeq(), pFunction); StmtSequence* pNewBodySeq = transformLogic(pLoopStmt->getBodySeq(), pFunction); StmtSequence* pNewIncrSeq = transformLogic(pLoopStmt->getIncrSeq(), pFunction); // Create a new loop statement output.push_back( new LoopStmt( pLoopStmt->getIndexVar(), pLoopStmt->getTestVar(), pNewInitSeq, pNewTestSeq, pNewBodySeq, pNewIncrSeq, pLoopStmt->getAnnotations() ) ); } break; // Other statement types default: { // Copy the statement and add it to the output output.push_back(pStmt->copy()); } } } // Return the transformed output return new StmtSequence(output); }
/*************************************************************** * Function: splitStatement() * Purpose : Convert a statement to split form * Initial : Maxime Chevalier-Boisvert on January 7, 2009 **************************************************************** Revisions and bug fixes: */ StmtSequence::StmtVector splitStatement(Statement* pStmt, ProgFunction* pFunction) { // Create a statement vector to store the converted statements StmtSequence::StmtVector stmtVector; // Switch on the statement type switch (pStmt->getStmtType()) { // Expression statement case Statement::EXPR: { // Get a typed pointer to the statement ExprStmt* pExprStmt = (ExprStmt*)pStmt; // Declare a variable to store the top-level expression created Expression* pTopExpr = NULL; // Split the expression contained in the statement splitExpression(pExprStmt->getExpression(), stmtVector, pTopExpr, pFunction); // Add a statement for the last expression stmtVector.push_back(new ExprStmt(pTopExpr, pExprStmt->getSuppressFlag())); } break; // Assignment statement case Statement::ASSIGN: { // Get a typed pointer to the statement AssignStmt* pAssignStmt = (AssignStmt*)pStmt; // Get the left expressions for this assignment const AssignStmt::ExprVector& leftExprs = pAssignStmt->getLeftExprs(); // Create a vector to store the transformed left expressions AssignStmt::ExprVector newLeftExprs; // For each left expression for (AssignStmt::ExprVector::const_iterator itr = leftExprs.begin(); itr != leftExprs.end(); ++itr) { // Declare a variable to store the last right expression Expression* pLExpr = NULL; // Split the left expression splitExpression(*itr, stmtVector, pLExpr, pFunction); // Add the expression to the list newLeftExprs.push_back(pLExpr); } // Declare a variable to store the last right expression Expression* pRExpr = NULL; // Split the right expression splitExpression(pAssignStmt->getRightExpr(), stmtVector, pRExpr, pFunction); // Create a new assignment statement for the top-level expressions stmtVector.push_back(new AssignStmt(newLeftExprs, pRExpr, pAssignStmt->getSuppressFlag())); } break; // If-else statement case Statement::IF_ELSE: { // Get a typed pointer to the statement IfElseStmt* pIfStmt = (IfElseStmt*)pStmt; // Declare a variable to store the tSequenceStmt::StmtVectorop-level test expression Expression* pTopTest = NULL; // Split the test expression bool exprSplit = splitExpression(pIfStmt->getCondition(), stmtVector, pTopTest, pFunction); // If the test expression was split if (exprSplit) { // Create a new symbol object for the test variable SymbolExpr* pTestVar = pFunction->createTemp(); // Assign the test sub-expression to the temp variable stmtVector.push_back(new AssignStmt(pTestVar, pTopTest)); // Replace the top test by the test variable pTopTest = pTestVar; } // Convert the if and else blocks to split form StmtSequence* pNewIfBlock = splitSequence(pIfStmt->getIfBlock(), pFunction); StmtSequence* pNewElseBlock = splitSequence(pIfStmt->getElseBlock(), pFunction); // Create a new if-else statement and add it to the vector stmtVector.push_back(new IfElseStmt(pTopTest, pNewIfBlock, pNewElseBlock)); } break; // Loop statement case Statement::LOOP: { // Split the loop statement and add it to the vector stmtVector.push_back(splitLoopStmt((LoopStmt*)pStmt, pFunction)); } break; // Default case, all other statement types default: { // Simply copy the statement without altering it stmtVector.push_back(pStmt->copy()); } break; } // Return the statement vector return stmtVector; }
/******************************************************************* * 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: { } } } }