blob: 2591ffd6d72c0924777f212840e0068a9c09c5f4 [file] [log] [blame]
Chris Lattner62b7fd12002-04-07 20:49:59 +00001//===- UnifyFunctionExitNodes.cpp - Make all functions have a single exit -===//
John Criswell482202a2003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Chris Lattner29aae152001-07-06 16:58:36 +00009//
Chris Lattner64d13342002-05-07 18:51:25 +000010// This pass is used to ensure that functions have at most one return
11// instruction in them. Additionally, it keeps track of which node is the new
12// exit node of the CFG. If there are no exit nodes in the CFG, the getExitNode
13// method will return a null pointer.
Chris Lattner29aae152001-07-06 16:58:36 +000014//
15//===----------------------------------------------------------------------===//
16
Chris Lattner15435fd2002-05-07 19:18:48 +000017#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
Chris Lattner07f7e5d2003-03-31 17:30:25 +000018#include "llvm/Transforms/Scalar.h"
Chris Lattner29aae152001-07-06 16:58:36 +000019#include "llvm/BasicBlock.h"
Chris Lattner62b7fd12002-04-07 20:49:59 +000020#include "llvm/Function.h"
Chris Lattner29aae152001-07-06 16:58:36 +000021#include "llvm/iTerminators.h"
Chris Lattnerfb5ae022001-12-03 18:02:31 +000022#include "llvm/iPHINode.h"
Chris Lattner29aae152001-07-06 16:58:36 +000023#include "llvm/Type.h"
24
Brian Gaeke960707c2003-11-11 22:41:34 +000025namespace llvm {
26
Chris Lattnera2c09852002-07-26 21:12:44 +000027static RegisterOpt<UnifyFunctionExitNodes>
Chris Lattnerb28b6802002-07-23 18:06:35 +000028X("mergereturn", "Unify function exit nodes");
Chris Lattnerccf571a2002-01-31 00:42:27 +000029
Chris Lattnerf9413962003-09-10 20:34:51 +000030Pass *createUnifyFunctionExitNodesPass() {
31 return new UnifyFunctionExitNodes();
32}
33
Chris Lattner07f7e5d2003-03-31 17:30:25 +000034void UnifyFunctionExitNodes::getAnalysisUsage(AnalysisUsage &AU) const{
35 // We preserve the non-critical-edgeness property
36 AU.addPreservedID(BreakCriticalEdgesID);
37}
38
Chris Lattner29aae152001-07-06 16:58:36 +000039// UnifyAllExitNodes - Unify all exit nodes of the CFG by creating a new
40// BasicBlock, and converting all returns to unconditional branches to this
41// new basic block. The singular exit node is returned.
42//
Chris Lattner62b7fd12002-04-07 20:49:59 +000043// If there are no return stmts in the Function, a null pointer is returned.
Chris Lattner29aae152001-07-06 16:58:36 +000044//
Chris Lattnerfda72b12002-06-25 16:12:52 +000045bool UnifyFunctionExitNodes::runOnFunction(Function &F) {
Chris Lattner62b7fd12002-04-07 20:49:59 +000046 // Loop over all of the blocks in a function, tracking all of the blocks that
Chris Lattner29aae152001-07-06 16:58:36 +000047 // return.
48 //
Chris Lattner8d0a71a2003-05-22 22:00:07 +000049 std::vector<BasicBlock*> ReturningBlocks;
Chris Lattnerf9413962003-09-10 20:34:51 +000050 std::vector<BasicBlock*> UnwindingBlocks;
Chris Lattnerfda72b12002-06-25 16:12:52 +000051 for(Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
52 if (isa<ReturnInst>(I->getTerminator()))
53 ReturningBlocks.push_back(I);
Chris Lattnerf9413962003-09-10 20:34:51 +000054 else if (isa<UnwindInst>(I->getTerminator()))
55 UnwindingBlocks.push_back(I);
Chris Lattner29aae152001-07-06 16:58:36 +000056
Chris Lattnerf9413962003-09-10 20:34:51 +000057 // Handle unwinding blocks first...
58 if (UnwindingBlocks.empty()) {
59 UnwindBlock = 0;
60 } else if (UnwindingBlocks.size() == 1) {
61 UnwindBlock = UnwindingBlocks.front();
62 } else {
63 UnwindBlock = new BasicBlock("UnifiedUnwindBlock", &F);
64 UnwindBlock->getInstList().push_back(new UnwindInst());
65
66 for (std::vector<BasicBlock*>::iterator I = UnwindingBlocks.begin(),
67 E = UnwindingBlocks.end(); I != E; ++I) {
68 BasicBlock *BB = *I;
69 BB->getInstList().pop_back(); // Remove the return insn
70 BB->getInstList().push_back(new BranchInst(UnwindBlock));
71 }
72 }
73
74 // Now handle return blocks...
Chris Lattner86595ae2002-02-01 04:53:48 +000075 if (ReturningBlocks.empty()) {
Chris Lattnerf9413962003-09-10 20:34:51 +000076 ReturnBlock = 0;
Chris Lattner64d13342002-05-07 18:51:25 +000077 return false; // No blocks return
Chris Lattnerf9f28962002-01-31 01:12:06 +000078 } else if (ReturningBlocks.size() == 1) {
Chris Lattnerf9413962003-09-10 20:34:51 +000079 ReturnBlock = ReturningBlocks.front(); // Already has a single return block
Chris Lattnerf9f28962002-01-31 01:12:06 +000080 return false;
81 }
Chris Lattner29aae152001-07-06 16:58:36 +000082
Chris Lattner62b7fd12002-04-07 20:49:59 +000083 // Otherwise, we need to insert a new basic block into the function, add a PHI
Chris Lattner29aae152001-07-06 16:58:36 +000084 // node (if the function returns a value), and convert all of the return
85 // instructions into unconditional branches.
86 //
Chris Lattnerf9413962003-09-10 20:34:51 +000087 BasicBlock *NewRetBlock = new BasicBlock("UnifiedReturnBlock", &F);
Chris Lattner29aae152001-07-06 16:58:36 +000088
Chris Lattner07f7e5d2003-03-31 17:30:25 +000089 PHINode *PN = 0;
Chris Lattnerfda72b12002-06-25 16:12:52 +000090 if (F.getReturnType() != Type::VoidTy) {
Chris Lattner62b7fd12002-04-07 20:49:59 +000091 // If the function doesn't return void... add a PHI node to the block...
Chris Lattner07f7e5d2003-03-31 17:30:25 +000092 PN = new PHINode(F.getReturnType(), "UnifiedRetVal");
Chris Lattner3d7720a2002-09-10 23:31:28 +000093 NewRetBlock->getInstList().push_back(PN);
Chris Lattner3d7720a2002-09-10 23:31:28 +000094 NewRetBlock->getInstList().push_back(new ReturnInst(PN));
Chris Lattner29aae152001-07-06 16:58:36 +000095 } else {
96 // If it returns void, just add a return void instruction to the block
Chris Lattner674c9ff2002-09-12 19:00:43 +000097 NewRetBlock->getInstList().push_back(new ReturnInst());
Chris Lattner29aae152001-07-06 16:58:36 +000098 }
99
100 // Loop over all of the blocks, replacing the return instruction with an
101 // unconditional branch.
102 //
Chris Lattner8d0a71a2003-05-22 22:00:07 +0000103 for (std::vector<BasicBlock*>::iterator I = ReturningBlocks.begin(),
104 E = ReturningBlocks.end(); I != E; ++I) {
Chris Lattner07f7e5d2003-03-31 17:30:25 +0000105 BasicBlock *BB = *I;
106
107 // Add an incoming element to the PHI node for every return instruction that
108 // is merging into this new block...
109 if (PN) PN->addIncoming(BB->getTerminator()->getOperand(0), BB);
110
111 BB->getInstList().pop_back(); // Remove the return insn
112 BB->getInstList().push_back(new BranchInst(NewRetBlock));
Chris Lattner29aae152001-07-06 16:58:36 +0000113 }
Chris Lattnerf9413962003-09-10 20:34:51 +0000114 ReturnBlock = NewRetBlock;
Chris Lattnerf9f28962002-01-31 01:12:06 +0000115 return true;
Chris Lattner29aae152001-07-06 16:58:36 +0000116}
Brian Gaeke960707c2003-11-11 22:41:34 +0000117
118} // End llvm namespace