コード例 #1
0
/***************************************************************************
 *      performPeepholeOptimizer
 ***************************************************************************/
bool CCilCodeGen::performPeepholeOptimize( ILFRAGMENTINFO* pILPool )
{
	//early termination
	if( pILPool->ILPool.size() == 0 )
		return true;

	ILFRAGMENTINFO& info = *pILPool;
	ILFRAGMENT optimizedILPool;

	ILFRAGMENT* pSrc = &pILPool->ILPool;
	ILFRAGMENT* pDest = &optimizedILPool;

	int32_t iMax;
	uint8_t cByteCode;
	hash_map< OP_CODE, PEEPHOLEOPTIMIZERCALLBACK >::iterator itCallback;

	uint32_t i;
	bool bContinue = true;

	while( bContinue )
	{
		pDest->clear();
		uint32_t iSize = uint32_t(pSrc->size());

		bContinue = false;

		for( i = 0; i < iSize; )
		{
			OPCODE_TABLEENTRY* pInfo;
			cByteCode = (*pSrc)[ i++ ];
			
			switch( cByteCode )
			{
			case 0xfe:
				cByteCode = (*pSrc)[ i++ ];

				//Invoke call back if available
				itCallback = m_mapPeepholeOptimizer.find( OP_CODE(cByteCode | 0xfe00) );
				if( itCallback != m_mapPeepholeOptimizer.end() )
				{
					if( int32_t iSkip = itCallback->second( pSrc->begin() + i - 2, *pDest ) )
					{
						i += iSkip - 2;
						bContinue = true;
						break;
					}
				}

				switch( cByteCode )
				{
				case CEE_CODE_LABEL & 0xff:
					{
						pDest->push_back( 0xfe );
						pDest->push_back( cByteCode );

						//Skip code label info
						for( int32_t ii = 0; ii < sizeof( int32_t ); ii++ )
						{
							pDest->push_back( (*pSrc)[ i++ ] );
						}
						break;
					}

				case CEE_EXT_LDARG & 0xff:
				case CEE_EXT_STARG & 0xff:
				case CEE_EXT_LDLOC & 0xff:
				case CEE_EXT_STLOC & 0xff:
					{
						pDest->push_back( 0xfe );
						pDest->push_back( cByteCode );

						for( int32_t ii = 0; ii < sizeof( int32_t ) * 3; ii++ )
						{
							pDest->push_back( (*pSrc)[ i++ ] );
						}
						break;
					}
				case CEE_LEAVE_TMP & 0xff:
					{
						pDest->push_back( 0xfe );
						pDest->push_back( cByteCode );

						for( int32_t ii = 0; ii < sizeof( int32_t ) * 2; ii++ )
						{
							pDest->push_back( (*pSrc)[ i++ ] );
						}
						break;
					}
				default:
					pDest->push_back( 0xfe );
					pDest->push_back( cByteCode );
					pInfo = m_OpcodeMapByOpcode[ (OP_CODE)(0xfe00 | cByteCode) ];
					iMax = pInfo->OperandParams & OPERAND_PARAMS_SIZEMASK;
					for( int32_t ii = 0; ii < iMax; ii++ )
					{
						pDest->push_back( (*pSrc)[ i++ ] );
					}
					break;
				}
				break;
			default:
				{
				//Invoke call back if available
				hash_map< OP_CODE, PEEPHOLEOPTIMIZERCALLBACK >::iterator itCallback;
				itCallback = m_mapPeepholeOptimizer.find( OP_CODE(cByteCode) );
				if( itCallback != m_mapPeepholeOptimizer.end() )
				{
					if( int32_t iSkip = itCallback->second( pSrc->begin() + i - 1, *pDest ) )
					{
						i += iSkip - 1;
						bContinue = true;
						break;
					}
				}

				pInfo = m_OpcodeMapByOpcode[ (OP_CODE)cByteCode ];
				pDest->push_back( cByteCode );
				iMax = pInfo->OperandParams & OPERAND_PARAMS_SIZEMASK;
				for( int32_t ii = 0; ii < iMax; ii++ )
				{
					pDest->push_back( (*pSrc)[ i++ ] );
				}
				}
				break;
			}
		}


		if( bContinue )
		{
			ILFRAGMENT* pTmp = pSrc;
			pSrc = pDest;
			pDest = pTmp;
		}
	}

	if( pDest != &info.ILPool )
	{
		info.ILPool.clear();
		info.ILPool = optimizedILPool;
	}

	return true;
}
コード例 #2
0
double Evaluate( AM_PARAM_EVAL_STACK& aExp )
{
    class OP_CODE   // A small class to store a operator and its priority
    {
    public:
        parm_item_type m_Optype;
        int m_Priority;

        OP_CODE( AM_PARAM_EVAL& aAmPrmEval )
            : m_Optype( aAmPrmEval.GetOperator() ),
              m_Priority( aAmPrmEval.GetPriority() )
        {}

        OP_CODE( parm_item_type aOptype )
            : m_Optype( aOptype ), m_Priority( 0 )
        {}
    };

    double result = 0.0;

    std::vector<double> values;     // the current list of values
    std::vector<OP_CODE> optype;    // the list of arith operators

    double curr_value = 0.0;
    int extra_priority = 0;

    for( unsigned ii = 0; ii < aExp.size(); ii++ )
    {
        AM_PARAM_EVAL& prm = aExp[ii];

        if( prm.IsOperator() )
        {
            if( prm.GetOperator() == OPEN_PAR )
            {
                extra_priority += AM_PARAM_EVAL::GetPriority( OPEN_PAR );
            }
            else if( prm.GetOperator() == CLOSE_PAR )
            {
                extra_priority -= AM_PARAM_EVAL::GetPriority( CLOSE_PAR );
            }
            else
            {
                optype.push_back( OP_CODE( prm ) );
                optype.back().m_Priority += extra_priority;
            }
        }
        else    // we have a value:
        {
            values.push_back( prm.GetValue() );

            if( optype.size() < 2 )
                continue;

            OP_CODE& previous_optype = optype[optype.size() - 2];

            if( optype.back().m_Priority > previous_optype.m_Priority )
            {
                double op1 = 0.0;

                double op2 = values.back();
                values.pop_back();

                if( values.size() )
                {
                    op1 = values.back();
                    values.pop_back();
                }

                switch( optype.back().m_Optype )
                {
                    case ADD:
                        values.push_back( op1+op2 );
                        break;

                    case SUB:
                        values.push_back( op1-op2 );
                        break;

                    case MUL:
                        values.push_back( op1*op2 );
                        break;

                    case DIV:
                        values.push_back( op1/op2 );
                        break;

                    default:
                        break;
                }

                optype.pop_back();
            }
        }
    }

    // Now all operators have the same priority, or those having the higher priority
    // are before others, calculate the final result by combining initial values and/or
    // replaced values.
    if( values.size() > optype.size() )
        // If there are n values, the number of operator is n-1 or n if the first
        // item of the expression to evaluate is + or - (like -$1/2)
        // If the number of operator is n-1 the first value is just copied to result
        optype.insert( optype.begin(), OP_CODE( POPVALUE ) );

    wxASSERT( values.size() == optype.size() );

    for( unsigned idx = 0; idx < values.size(); idx++ )
    {
        curr_value = values[idx];

        switch( optype[idx].m_Optype )
        {
            case POPVALUE:
                result = curr_value;
                break;

            case ADD:
                result += curr_value;
                break;

            case SUB:
                result -= curr_value;
                break;

            case MUL:
                result *= curr_value;
                break;

            case DIV:
                result /= curr_value;
                break;

            default:
                break;
        }
    }

    return result;
}