// moveExitCondition - Move exit condition EC into split condition block CondBB. void LoopIndexSplit::moveExitCondition(BasicBlock *CondBB, BasicBlock *ActiveBB, BasicBlock *ExitBB, ICmpInst *EC, ICmpInst *SC, PHINode *IV, Instruction *IVAdd, Loop *LP, unsigned ExitValueNum) { BasicBlock *ExitingBB = EC->getParent(); Instruction *CurrentBR = CondBB->getTerminator(); // Move exit condition into split condition block. EC->moveBefore(CurrentBR); EC->setOperand(ExitValueNum == 0 ? 1 : 0, IV); // Move exiting block's branch into split condition block. Update its branch // destination. BranchInst *ExitingBR = cast<BranchInst>(ExitingBB->getTerminator()); ExitingBR->moveBefore(CurrentBR); BasicBlock *OrigDestBB = NULL; if (ExitingBR->getSuccessor(0) == ExitBB) { OrigDestBB = ExitingBR->getSuccessor(1); ExitingBR->setSuccessor(1, ActiveBB); } else { OrigDestBB = ExitingBR->getSuccessor(0); ExitingBR->setSuccessor(0, ActiveBB); } // Remove split condition and current split condition branch. SC->eraseFromParent(); CurrentBR->eraseFromParent(); // Connect exiting block to original destination. BranchInst::Create(OrigDestBB, ExitingBB); // Update PHINodes updatePHINodes(ExitBB, ExitingBB, CondBB, IV, IVAdd, LP); // Fix dominator info. // ExitBB is now dominated by CondBB DT->changeImmediateDominator(ExitBB, CondBB); DF->changeImmediateDominator(ExitBB, CondBB, DT); // Blocks outside the loop may have been in the dominance frontier of blocks // inside the condition; this is now impossible because the blocks inside the // condition no loger dominate the exit. Remove the relevant blocks from // the dominance frontiers. for (Loop::block_iterator I = LP->block_begin(), E = LP->block_end(); I != E; ++I) { if (*I == CondBB || !DT->dominates(CondBB, *I)) continue; DominanceFrontier::iterator BBDF = DF->find(*I); DominanceFrontier::DomSetType::iterator DomSetI = BBDF->second.begin(); DominanceFrontier::DomSetType::iterator DomSetE = BBDF->second.end(); while (DomSetI != DomSetE) { DominanceFrontier::DomSetType::iterator CurrentItr = DomSetI; ++DomSetI; BasicBlock *DFBB = *CurrentItr; if (!LP->contains(DFBB)) BBDF->second.erase(DFBB); } } }
bool LoopBogusCF::runOnLoop(Loop *loop, LPPassManager &LPM) { if (disableLoopBcf) return false; ++NumLoops; DEBUG(errs() << "LoopBogusCF: Dumping loop info\n"); // DEBUG(loop->dump()); BasicBlock *header = loop->getHeader(); BranchInst *branch = dyn_cast<BranchInst>(header->getTerminator()); if (!branch || !branch->isConditional()) { DEBUG(errs() << "\t Not trivial loop -- skipping\n"); return false; } if (!loop->isLoopSimplifyForm()) { DEBUG(errs() << "\t Not simplified loop -- skipping\n"); return false; } BasicBlock *exitBlock = loop->getUniqueExitBlock(); if (!exitBlock) { DEBUG(errs() << "\t No unique exit block -- skipping\n"); return false; } if (branch->getSuccessor(0) != exitBlock && branch->getSuccessor(1) != exitBlock) { DEBUG(errs() << "\t Not trivial loop -- skipping\n"); return false; } ++NumLoopsObf; // DEBUG(header->getParent()->viewCFG()); DEBUG(errs() << "\tCreating dummy block\n"); LoopInfo &info = getAnalysis<LoopInfo>(); // Split header block BasicBlock *dummy = header->splitBasicBlock(header->getTerminator()); loop->addBasicBlockToLoop(dummy, info.getBase()); BasicBlock *trueBlock, *falseBlock = exitBlock; if (branch->getSuccessor(0) == exitBlock) { trueBlock = branch->getSuccessor(1); branch->setSuccessor(1, dummy); } else { trueBlock = branch->getSuccessor(0); branch->setSuccessor(0, dummy); } branch->moveBefore(header->getTerminator()); header->getTerminator()->eraseFromParent(); OpaquePredicate::createStub(dummy, trueBlock, falseBlock, OpaquePredicate::PredicateTrue, false); // DEBUG(header->getParent()->viewCFG()); return true; }