blob: 7de1b3c52e632fef3c1490137eefe6f350dddeed [file] [log] [blame]
Chris Lattner44d2c352003-10-13 03:32:08 +00001//===-- CombineBranch.cpp -------------------------------------------------===//
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 Lattner44d2c352003-10-13 03:32:08 +00009//
Brian Gaekeef327be2004-03-30 19:53:46 +000010// Combine branches
Chris Lattner44d2c352003-10-13 03:32:08 +000011//
Anand Shukla89233e12003-07-18 16:08:32 +000012//===----------------------------------------------------------------------===//
13
Anand Shukla89233e12003-07-18 16:08:32 +000014#include "llvm/Support/CFG.h"
Anand Shukla89233e12003-07-18 16:08:32 +000015#include "llvm/iTerminators.h"
16#include "llvm/iPHINode.h"
Anand Shukla89233e12003-07-18 16:08:32 +000017#include "llvm/Function.h"
18#include "llvm/Pass.h"
19
Brian Gaeke960707c2003-11-11 22:41:34 +000020namespace llvm {
21
Brian Gaeke960707c2003-11-11 22:41:34 +000022namespace {
Anand Shukla89233e12003-07-18 16:08:32 +000023 struct CombineBranches : public FunctionPass {
24 private:
Brian Gaekeef327be2004-03-30 19:53:46 +000025 /// Possible colors that a vertex can have during depth-first search for
26 /// back-edges.
27 ///
28 enum Color { WHITE, GREY, BLACK };
29
Anand Shukla89233e12003-07-18 16:08:32 +000030 void getBackEdgesVisit(BasicBlock *u,
31 std::map<BasicBlock *, Color > &color,
32 std::map<BasicBlock *, int > &d,
33 int &time,
34 std::map<BasicBlock *, BasicBlock *> &be);
35 void removeRedundant(std::map<BasicBlock *, BasicBlock *> &be);
Anand Shukla89233e12003-07-18 16:08:32 +000036 public:
37 bool runOnFunction(Function &F);
38 };
39
Brian Gaekeef327be2004-03-30 19:53:46 +000040 RegisterOpt<CombineBranches>
41 X("branch-combine", "Multiple backedges going to same target are merged");
Anand Shukla89233e12003-07-18 16:08:32 +000042}
43
Brian Gaekeef327be2004-03-30 19:53:46 +000044/// getBackEdgesVisit - Get the back-edges of the control-flow graph for this
45/// function. We proceed recursively using depth-first search. We get
46/// back-edges by associating a time and a color with each vertex. The time of a
47/// vertex is the time when it was first visited. The color of a vertex is
48/// initially WHITE, changes to GREY when it is first visited, and changes to
49/// BLACK when ALL its neighbors have been visited. So we have a back edge when
50/// we meet a successor of a node with smaller time, and GREY color.
51///
Anand Shukla89233e12003-07-18 16:08:32 +000052void CombineBranches::getBackEdgesVisit(BasicBlock *u,
53 std::map<BasicBlock *, Color > &color,
54 std::map<BasicBlock *, int > &d,
55 int &time,
56 std::map<BasicBlock *, BasicBlock *> &be) {
57
58 color[u]=GREY;
59 time++;
60 d[u]=time;
61
Chris Lattnera9400952003-09-24 22:06:25 +000062 for (succ_iterator vl = succ_begin(u), ve = succ_end(u); vl != ve; ++vl){
Anand Shukla89233e12003-07-18 16:08:32 +000063 BasicBlock *BB = *vl;
64
Brian Gaekeef327be2004-03-30 19:53:46 +000065 if(color[BB]!=GREY && color[BB]!=BLACK)
Anand Shukla89233e12003-07-18 16:08:32 +000066 getBackEdgesVisit(BB, color, d, time, be);
Anand Shukla89233e12003-07-18 16:08:32 +000067
68 //now checking for d and f vals
69 else if(color[BB]==GREY){
70 //so v is ancestor of u if time of u > time of v
Brian Gaekeef327be2004-03-30 19:53:46 +000071 if(d[u] >= d[BB]) // u->BB is a backedge
Anand Shukla89233e12003-07-18 16:08:32 +000072 be[u] = BB;
Anand Shukla89233e12003-07-18 16:08:32 +000073 }
74 }
75 color[u]=BLACK;//done with visiting the node and its neighbors
76}
77
Brian Gaekeef327be2004-03-30 19:53:46 +000078/// removeRedundant - Remove all back-edges that are dominated by other
79/// back-edges in the set.
80///
Anand Shukla89233e12003-07-18 16:08:32 +000081void CombineBranches::removeRedundant(std::map<BasicBlock *, BasicBlock *> &be){
82 std::vector<BasicBlock *> toDelete;
83 std::map<BasicBlock *, int> seenBB;
84
85 for(std::map<BasicBlock *, BasicBlock *>::iterator MI = be.begin(),
86 ME = be.end(); MI != ME; ++MI){
87
88 if(seenBB[MI->second])
89 continue;
90
91 seenBB[MI->second] = 1;
92
93 std::vector<BasicBlock *> sameTarget;
94 sameTarget.clear();
95
96 for(std::map<BasicBlock *, BasicBlock *>::iterator MMI = be.begin(),
97 MME = be.end(); MMI != MME; ++MMI){
98
99 if(MMI->first == MI->first)
100 continue;
101
102 if(MMI->second == MI->second)
103 sameTarget.push_back(MMI->first);
104
105 }
106
107 //so more than one branch to same target
108 if(sameTarget.size()){
109
110 sameTarget.push_back(MI->first);
111
112 BasicBlock *newBB = new BasicBlock("newCommon", MI->first->getParent());
Chris Lattner2af51722003-11-20 18:25:24 +0000113 BranchInst *newBranch = new BranchInst(MI->second, 0, 0, newBB);
Anand Shukla89233e12003-07-18 16:08:32 +0000114
115 std::map<PHINode *, std::vector<unsigned int> > phiMap;
116
Anand Shukla89233e12003-07-18 16:08:32 +0000117 for(std::vector<BasicBlock *>::iterator VBI = sameTarget.begin(),
118 VBE = sameTarget.end(); VBI != VBE; ++VBI){
119
Anand Shukla89233e12003-07-18 16:08:32 +0000120 BranchInst *ti = cast<BranchInst>((*VBI)->getTerminator());
121 unsigned char index = 1;
Brian Gaekeef327be2004-03-30 19:53:46 +0000122 if(ti->getSuccessor(0) == MI->second)
Anand Shukla89233e12003-07-18 16:08:32 +0000123 index = 0;
Anand Shukla89233e12003-07-18 16:08:32 +0000124
125 ti->setSuccessor(index, newBB);
126
127 for(BasicBlock::iterator BB2Inst = MI->second->begin(),
128 BBend = MI->second->end(); BB2Inst != BBend; ++BB2Inst){
129
130 if (PHINode *phiInst = dyn_cast<PHINode>(BB2Inst)){
131 int bbIndex;
132 bbIndex = phiInst->getBasicBlockIndex(*VBI);
Brian Gaekeef327be2004-03-30 19:53:46 +0000133 if(bbIndex>=0)
Anand Shukla89233e12003-07-18 16:08:32 +0000134 phiMap[phiInst].push_back(bbIndex);
Anand Shukla89233e12003-07-18 16:08:32 +0000135 }
136 }
137 }
138
139 for(std::map<PHINode *, std::vector<unsigned int> >::iterator
140 PI = phiMap.begin(), PE = phiMap.end(); PI != PE; ++PI){
141
142 PHINode *phiNode = new PHINode(PI->first->getType(), "phi", newBranch);
143 for(std::vector<unsigned int>::iterator II = PI->second.begin(),
144 IE = PI->second.end(); II != IE; ++II){
145 phiNode->addIncoming(PI->first->getIncomingValue(*II),
146 PI->first->getIncomingBlock(*II));
147 }
148
149 std::vector<BasicBlock *> tempBB;
150 for(std::vector<unsigned int>::iterator II = PI->second.begin(),
151 IE = PI->second.end(); II != IE; ++II){
152 tempBB.push_back(PI->first->getIncomingBlock(*II));
153 }
154
155 for(std::vector<BasicBlock *>::iterator II = tempBB.begin(),
156 IE = tempBB.end(); II != IE; ++II){
157 PI->first->removeIncomingValue(*II);
158 }
159
160 PI->first->addIncoming(phiNode, newBB);
161 }
Anand Shukla89233e12003-07-18 16:08:32 +0000162 }
163 }
164}
165
Brian Gaekeef327be2004-03-30 19:53:46 +0000166/// runOnFunction - Per function pass for combining branches.
167///
168bool CombineBranches::runOnFunction(Function &F){
169 if (F.isExternal ())
170 return false;
171
172 // Find and remove "redundant" back-edges.
173 std::map<BasicBlock *, Color> color;
Anand Shukla89233e12003-07-18 16:08:32 +0000174 std::map<BasicBlock *, int> d;
175 std::map<BasicBlock *, BasicBlock *> be;
Brian Gaekeef327be2004-03-30 19:53:46 +0000176 int time = 0;
177 getBackEdgesVisit (F.begin (), color, d, time, be);
178 removeRedundant (be);
Anand Shukla89233e12003-07-18 16:08:32 +0000179
Brian Gaekeef327be2004-03-30 19:53:46 +0000180 return true; // FIXME: assumes a modification was always made.
Anand Shukla89233e12003-07-18 16:08:32 +0000181}
Brian Gaeke960707c2003-11-11 22:41:34 +0000182
183} // End llvm namespace