Add an _embarassingly simple_ implementation of basic block layout. This is
[oota-llvm.git] / lib / Transforms / Scalar / BasicBlockPlacement.cpp
1 //===-- BasicBlockPlacement.cpp - Basic Block Code Layout optimization ----===//
2 // 
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 //===----------------------------------------------------------------------===//
9 //
10 // This file implements a very simple profile guided basic block placement
11 // algorithm.  The idea is to put frequently executed blocks together at the
12 // start of the function, and hopefully increase the number of fall-through
13 // conditional branches.  If there is no profile information for a particular
14 // function, this pass basically orders blocks in depth-first order
15 //
16 // The algorithm implemented here is basically "Algo1" from "Profile Guided Code
17 // Positioning" by Pettis and Hansen, except that it uses basic block counts
18 // instead of edge counts.  This should be improved in many ways, but is very
19 // simple for now.
20 //
21 // Basically we "place" the entry block, then loop over all successors in a DFO,
22 // placing the most frequently executed successor until we run out of blocks.  I
23 // told you this was _extremely_ simplistic. :) This is also much slower than it
24 // could be.  When it becomes important, this pass will be rewritten to use a
25 // better algorithm, and then we can worry about efficiency.
26 //
27 //===----------------------------------------------------------------------===//
28
29 #include "llvm/Analysis/ProfileInfo.h"
30 #include "llvm/Function.h"
31 #include "llvm/Pass.h"
32 #include "llvm/Support/CFG.h"
33 #include "Support/Statistic.h"
34 #include <set>
35 using namespace llvm;
36
37 namespace {
38   Statistic<> NumMoved("block-placement", "Number of basic blocks moved");
39   
40   struct BlockPlacement : public FunctionPass {
41     virtual bool runOnFunction(Function &F);
42
43     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
44       AU.setPreservesCFG();
45       AU.addRequired<ProfileInfo>();
46       //AU.addPreserved<ProfileInfo>();  // Does this work?
47     }
48   private:
49     /// PI - The profile information that is guiding us.
50     ///
51     ProfileInfo *PI;
52
53     /// NumMovedBlocks - Every time we move a block, increment this counter.
54     ///
55     unsigned NumMovedBlocks;
56
57     /// PlacedBlocks - Every time we place a block, remember it so we don't get
58     /// into infinite loops.
59     std::set<BasicBlock*> PlacedBlocks;
60
61     /// InsertPos - This an iterator to the next place we want to insert a
62     /// block.
63     Function::iterator InsertPos;
64
65     /// PlaceBlocks - Recursively place the specified blocks and any unplaced
66     /// successors.
67     void PlaceBlocks(BasicBlock *BB);
68   };
69
70   RegisterOpt<BlockPlacement> X("block-placement",
71                                 "Profile Guided Basic Block Placement");
72 }
73
74 bool BlockPlacement::runOnFunction(Function &F) {
75   PI = &getAnalysis<ProfileInfo>();
76
77   NumMovedBlocks = 0;
78   InsertPos = F.begin(); 
79
80   // Recursively place all blocks.
81   PlaceBlocks(F.begin());
82   
83   // If there are any unreachable blocks, move them to the end.
84
85   PlacedBlocks.clear();
86   NumMoved += NumMovedBlocks;
87   return NumMovedBlocks != 0;
88 }
89
90
91 /// PlaceBlocks - Recursively place the specified blocks and any unplaced
92 /// successors.
93 void BlockPlacement::PlaceBlocks(BasicBlock *BB) {
94   assert(!PlacedBlocks.count(BB) && "Already placed this block!");
95   PlacedBlocks.insert(BB);
96
97   // Place the specified block.
98   if (&*InsertPos != BB) {
99     // Use splice to move the block into the right place.  This avoids having to
100     // remove the block from the function then readd it, which causes a bunch of
101     // symbol table traffic that is entirely pointless.
102     Function::BasicBlockListType &Blocks = BB->getParent()->getBasicBlockList();
103     Blocks.splice(InsertPos, Blocks, BB);
104
105     ++NumMovedBlocks;
106   } else {
107     // This block is already in the right place, we don't have to do anything.
108     ++InsertPos;
109   }
110
111   // Keep placing successors until we run out of ones to place.  Note that this
112   // loop is very inefficient (N^2) for blocks with many successors, like switch
113   // statements.  FIXME!
114   while (1) {
115     // Okay, now place any unplaced successors.
116     succ_iterator SI = succ_begin(BB), E = succ_end(BB);
117     
118     // Scan for the first unplaced successor.
119     for (; SI != E && PlacedBlocks.count(*SI); ++SI)
120       /*empty*/;
121     if (SI == E) return;  // No more successors to place.
122     
123     unsigned MaxExecutionCount = PI->getExecutionCount(*SI);
124     BasicBlock *MaxSuccessor = *SI;
125
126     // Scan for more frequently executed successors
127     for (; SI != E; ++SI)
128       if (!PlacedBlocks.count(*SI)) {
129         unsigned Count = PI->getExecutionCount(*SI);
130         if (Count > MaxExecutionCount ||
131             // Prefer to not disturb the code.
132             (Count == MaxExecutionCount && *SI == &*InsertPos)) {
133           MaxExecutionCount = Count;
134           MaxSuccessor = *SI;
135         }
136       }
137
138     // Now that we picked the maximally executed successor, place it.
139     PlaceBlocks(MaxSuccessor);
140   }
141 }