| 7333 | } |
| 7334 | |
| 7335 | void BeMCContext::DoSplitLargeBlocks() |
| 7336 | { |
| 7337 | Dictionary<int, int> blockEndRemap; |
| 7338 | |
| 7339 | int splitSize = 4096; |
| 7340 | int maxBlockSize = splitSize + splitSize / 4; |
| 7341 | bool hadSplits = false; |
| 7342 | |
| 7343 | for (int blockIdx = 0; blockIdx < mBlocks.size(); blockIdx++) |
| 7344 | { |
| 7345 | int blockBreakIdx = 0; |
| 7346 | |
| 7347 | auto srcBlock = mBlocks[blockIdx]; |
| 7348 | if (srcBlock->mInstructions.size() < maxBlockSize) |
| 7349 | continue; |
| 7350 | hadSplits = true; |
| 7351 | int extensionCount = srcBlock->mInstructions.size() / splitSize; |
| 7352 | // Don't allow the last block to have too few instructions |
| 7353 | if (srcBlock->mInstructions.size() % splitSize < splitSize / 4) |
| 7354 | extensionCount--; |
| 7355 | if (extensionCount == 0) // Shouldn't happen, really |
| 7356 | continue; |
| 7357 | for (int extIdx = 0; extIdx < extensionCount; extIdx++) |
| 7358 | { |
| 7359 | BeMCBlock* extBlock = mMCBlockAlloc.Alloc(); |
| 7360 | extBlock->mName = srcBlock->mName + StrFormat("__EXT%d", extIdx); |
| 7361 | mBlocks.Insert(blockIdx + 1 + extIdx, extBlock); |
| 7362 | |
| 7363 | int startIdx = (extIdx + 1) * splitSize; |
| 7364 | int endIdx = BF_MIN((extIdx + 2) * splitSize, srcBlock->mInstructions.size()); |
| 7365 | if (extIdx == extensionCount - 1) |
| 7366 | endIdx = (int)srcBlock->mInstructions.size(); |
| 7367 | |
| 7368 | extBlock->mInstructions.Insert(0, &srcBlock->mInstructions[startIdx], endIdx - startIdx); |
| 7369 | extBlock->mPreds.Add(mBlocks[blockIdx + extIdx]); |
| 7370 | |
| 7371 | if (extIdx > 0) |
| 7372 | { |
| 7373 | auto prevBlock = mBlocks[blockIdx + extIdx]; |
| 7374 | mActiveBlock = prevBlock; |
| 7375 | AllocInst(BeMCInstKind_Br, BeMCOperand::FromBlock(extBlock)); |
| 7376 | mActiveBlock = NULL; |
| 7377 | |
| 7378 | mBlocks[blockIdx + extIdx]->mSuccs.Add(extBlock); |
| 7379 | } |
| 7380 | |
| 7381 | if (extIdx == extensionCount - 1) |
| 7382 | { |
| 7383 | blockEndRemap[blockIdx] = blockIdx + extIdx + 1; |
| 7384 | |
| 7385 | for (auto succ : srcBlock->mSuccs) |
| 7386 | { |
| 7387 | succ->mPreds.Remove(srcBlock); |
| 7388 | succ->mPreds.Add(extBlock); |
| 7389 | } |
| 7390 | extBlock->mSuccs = srcBlock->mSuccs; |
| 7391 | srcBlock->mSuccs.Clear(); |
| 7392 | srcBlock->mSuccs.Add(mBlocks[blockIdx + 1]); |
nothing calls this directly
no test coverage detected