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(); } }
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; }
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; }