Пример #1
0
/***************************************************************
* 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;
		}
	}
}
Пример #2
0
/***************************************************************
* 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;
}
Пример #3
0
/*******************************************************************
* 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;
}
Пример #4
0
/***************************************************************
* 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;
}
Пример #5
0
/*******************************************************************
* 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:
        {
        }
        }
    }
}