1 //===- SimplifyCFG.cpp - CFG Simplification Routines -------------*- C++ -*--=// 2 // 3 // This file provides several routines that are useful for simplifying CFGs in 4 // various ways... 5 // 6 //===----------------------------------------------------------------------===// 7 8 #include "llvm/Analysis/SimplifyCFG.h" 9 #include "llvm/BasicBlock.h" 10 #include "llvm/Method.h" 11 #include "llvm/iTerminators.h" 12 #include "llvm/iOther.h" 13 #include "llvm/Type.h" 14 15 // UnifyAllExitNodes - Unify all exit nodes of the CFG by creating a new 16 // BasicBlock, and converting all returns to unconditional branches to this 17 // new basic block. The singular exit node is returned. 18 // 19 // If there are no return stmts in the Method, a null pointer is returned. 20 // 21 BasicBlock *cfg::UnifyAllExitNodes(Method *M) { 22 vector<BasicBlock*> ReturningBlocks; 23 24 // Loop over all of the blocks in a method, tracking all of the blocks that 25 // return. 26 // 27 for(Method::iterator I = M->begin(), E = M->end(); I != E; ++I) 28 if ((*I)->getTerminator()->getOpcode() == Instruction::Ret) 29 ReturningBlocks.push_back(*I); 30 31 if (ReturningBlocks.size() == 0) 32 return 0; // No blocks return 33 else if (ReturningBlocks.size() == 1) 34 return ReturningBlocks.front(); // Already has a single return block 35 36 // Otherwise, we need to insert a new basic block into the method, add a PHI 37 // node (if the function returns a value), and convert all of the return 38 // instructions into unconditional branches. 39 // 40 BasicBlock *NewRetBlock = new BasicBlock("", M); 41 42 if (M->getReturnType() != Type::VoidTy) { 43 // If the method doesn't return void... add a PHI node to the block... 44 PHINode *PN = new PHINode(M->getReturnType()); 45 NewRetBlock->getInstList().push_back(PN); 46 47 // Add an incoming element to the PHI node for every return instruction that 48 // is merging into this new block... 49 for (vector<BasicBlock*>::iterator I = ReturningBlocks.begin(), 50 E = ReturningBlocks.end(); I != E; ++I) 51 PN->addIncoming((*I)->getTerminator()->getOperand(0), *I); 52 53 // Add a return instruction to return the result of the PHI node... 54 NewRetBlock->getInstList().push_back(new ReturnInst(PN)); 55 } else { 56 // If it returns void, just add a return void instruction to the block 57 NewRetBlock->getInstList().push_back(new ReturnInst()); 58 } 59 60 // Loop over all of the blocks, replacing the return instruction with an 61 // unconditional branch. 62 // 63 for (vector<BasicBlock*>::iterator I = ReturningBlocks.begin(), 64 E = ReturningBlocks.end(); I != E; ++I) { 65 delete (*I)->getInstList().pop_back(); // Remove the return insn 66 (*I)->getInstList().push_back(new BranchInst(NewRetBlock)); 67 } 68 return NewRetBlock; 69 } 70