LLVM API Documentation
00001 //===- UnifyFunctionExitNodes.cpp - Make all functions have a single exit -===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This pass is used to ensure that functions have at most one return 00011 // instruction in them. Additionally, it keeps track of which node is the new 00012 // exit node of the CFG. If there are no exit nodes in the CFG, the getExitNode 00013 // method will return a null pointer. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" 00018 #include "llvm/ADT/StringExtras.h" 00019 #include "llvm/IR/BasicBlock.h" 00020 #include "llvm/IR/Function.h" 00021 #include "llvm/IR/Instructions.h" 00022 #include "llvm/IR/Type.h" 00023 #include "llvm/Transforms/Scalar.h" 00024 using namespace llvm; 00025 00026 char UnifyFunctionExitNodes::ID = 0; 00027 INITIALIZE_PASS(UnifyFunctionExitNodes, "mergereturn", 00028 "Unify function exit nodes", false, false) 00029 00030 Pass *llvm::createUnifyFunctionExitNodesPass() { 00031 return new UnifyFunctionExitNodes(); 00032 } 00033 00034 void UnifyFunctionExitNodes::getAnalysisUsage(AnalysisUsage &AU) const{ 00035 // We preserve the non-critical-edgeness property 00036 AU.addPreservedID(BreakCriticalEdgesID); 00037 // This is a cluster of orthogonal Transforms 00038 AU.addPreserved("mem2reg"); 00039 AU.addPreservedID(LowerSwitchID); 00040 } 00041 00042 // UnifyAllExitNodes - Unify all exit nodes of the CFG by creating a new 00043 // BasicBlock, and converting all returns to unconditional branches to this 00044 // new basic block. The singular exit node is returned. 00045 // 00046 // If there are no return stmts in the Function, a null pointer is returned. 00047 // 00048 bool UnifyFunctionExitNodes::runOnFunction(Function &F) { 00049 // Loop over all of the blocks in a function, tracking all of the blocks that 00050 // return. 00051 // 00052 std::vector<BasicBlock*> ReturningBlocks; 00053 std::vector<BasicBlock*> UnreachableBlocks; 00054 for(Function::iterator I = F.begin(), E = F.end(); I != E; ++I) 00055 if (isa<ReturnInst>(I->getTerminator())) 00056 ReturningBlocks.push_back(I); 00057 else if (isa<UnreachableInst>(I->getTerminator())) 00058 UnreachableBlocks.push_back(I); 00059 00060 // Then unreachable blocks. 00061 if (UnreachableBlocks.empty()) { 00062 UnreachableBlock = nullptr; 00063 } else if (UnreachableBlocks.size() == 1) { 00064 UnreachableBlock = UnreachableBlocks.front(); 00065 } else { 00066 UnreachableBlock = BasicBlock::Create(F.getContext(), 00067 "UnifiedUnreachableBlock", &F); 00068 new UnreachableInst(F.getContext(), UnreachableBlock); 00069 00070 for (std::vector<BasicBlock*>::iterator I = UnreachableBlocks.begin(), 00071 E = UnreachableBlocks.end(); I != E; ++I) { 00072 BasicBlock *BB = *I; 00073 BB->getInstList().pop_back(); // Remove the unreachable inst. 00074 BranchInst::Create(UnreachableBlock, BB); 00075 } 00076 } 00077 00078 // Now handle return blocks. 00079 if (ReturningBlocks.empty()) { 00080 ReturnBlock = nullptr; 00081 return false; // No blocks return 00082 } else if (ReturningBlocks.size() == 1) { 00083 ReturnBlock = ReturningBlocks.front(); // Already has a single return block 00084 return false; 00085 } 00086 00087 // Otherwise, we need to insert a new basic block into the function, add a PHI 00088 // nodes (if the function returns values), and convert all of the return 00089 // instructions into unconditional branches. 00090 // 00091 BasicBlock *NewRetBlock = BasicBlock::Create(F.getContext(), 00092 "UnifiedReturnBlock", &F); 00093 00094 PHINode *PN = nullptr; 00095 if (F.getReturnType()->isVoidTy()) { 00096 ReturnInst::Create(F.getContext(), nullptr, NewRetBlock); 00097 } else { 00098 // If the function doesn't return void... add a PHI node to the block... 00099 PN = PHINode::Create(F.getReturnType(), ReturningBlocks.size(), 00100 "UnifiedRetVal"); 00101 NewRetBlock->getInstList().push_back(PN); 00102 ReturnInst::Create(F.getContext(), PN, NewRetBlock); 00103 } 00104 00105 // Loop over all of the blocks, replacing the return instruction with an 00106 // unconditional branch. 00107 // 00108 for (std::vector<BasicBlock*>::iterator I = ReturningBlocks.begin(), 00109 E = ReturningBlocks.end(); I != E; ++I) { 00110 BasicBlock *BB = *I; 00111 00112 // Add an incoming element to the PHI node for every return instruction that 00113 // is merging into this new block... 00114 if (PN) 00115 PN->addIncoming(BB->getTerminator()->getOperand(0), BB); 00116 00117 BB->getInstList().pop_back(); // Remove the return insn 00118 BranchInst::Create(NewRetBlock, BB); 00119 } 00120 ReturnBlock = NewRetBlock; 00121 return true; 00122 }