void CBasicBlocksBuilder::SortBlocks()
{
	assert( blocks.size() > 0 );
	std::vector<bool> used( blocks.size(), false );
	CBasicBlock currBlock = blocks[labelToBlock[firstLabel->label]];
	used[labelToBlock[firstLabel->label]] = true;
	sortedBlocks.push_back( currBlock );
	const IIRStm* jump = currBlock.Last();
	size_t numOfFreeBlocks = used.size() - 1;
	while( numOfFreeBlocks > 0 ) {
		if( IsInstanceOf<CIRJump>( const_cast< IIRStm* >( jump ) ) ) {
			// За ним просто должен идти блок с меткой, куда прыгаем
			const Temp::CLabel* nextLabel = getNextLabel( jump );
			if( nextLabel->Name() == "done_label" || used[labelToBlock[nextLabel]] ) {
				// Если блок конца фрейма, или же след ведет в посещенный блок
				// Значит нужно взять непосещенный и с ним строить след
				int position = 0;
				if( getNextFreeBlock( used, currBlock, position ) ) {
					sortedBlocks.push_back( currBlock );
					used[position] = true;
					--numOfFreeBlocks;
					jump = currBlock.Last();
					continue;
				} else {
					// Свободных блоков не осталось
					break;
				}
			}
			currBlock = blocks[labelToBlock[nextLabel]];
			sortedBlocks.push_back( currBlock );
			used[labelToBlock[nextLabel]] = true;
			--numOfFreeBlocks;
		} else if( IsInstanceOf<CIRCJump>( const_cast< IIRStm* >( jump ) ) ) {
			// За ним должен идти блок с меткой на false
			const Temp::CLabel* nextLabel = getNextConditionalLabel( jump );
			if( nextLabel->Name() == "done_label" || used[labelToBlock[nextLabel]] ) {
				int position = 0;
				if( getNextFreeBlock( used, currBlock, position ) ) {
					sortedBlocks.push_back( currBlock );
					used[position] = true;
					--numOfFreeBlocks;
					jump = currBlock.Last();
					continue;
				} else {
					// Свободных блоков не осталось
					break;
				}
			}
			currBlock = blocks[labelToBlock[nextLabel]];
			sortedBlocks.push_back( currBlock );
			used[labelToBlock[nextLabel]] = true;
			--numOfFreeBlocks;
		} else {
			assert( false );
		}
		jump = currBlock.Last();
	}
}
Ejemplo n.º 2
0
bool CSubSystem::IsCpuIdle() const
{
    CBasicBlock* nextBlock = m_executor.FindBlockAt(m_EE.m_State.nPC);
    if(nextBlock && nextBlock->GetSelfLoopCount() > 5000)
    {
        return true;
    }
    else if(m_os->IsIdle() || m_isIdle)
    {
        return true;
    }
    return false;
}
Ejemplo n.º 3
0
bool CSubSystem::IsCpuIdle()
{
    if(m_bios->IsIdle())
    {
        return true;
    }
    else
    {
        uint32 physicalPc = m_cpu.m_pAddrTranslator(&m_cpu, m_cpu.m_State.nPC);
        CBasicBlock* nextBlock = m_executor.FindBlockAt(physicalPc);
        if(nextBlock && nextBlock->GetSelfLoopCount() > 5000)
        {
            //Go a little bit faster if we're "stuck"
            return true;
        }
    }
    return false;
}