blob: a25ab0f12156b29a4a222c302d0bc645645903c7 [file] [log] [blame]
Chris Lattner206805e2004-02-11 04:53:20 +00001//===-- 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>
35using namespace llvm;
36
37namespace {
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
74bool 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
Chris Lattner206805e2004-02-11 04:53:20 +000083 PlacedBlocks.clear();
84 NumMoved += NumMovedBlocks;
85 return NumMovedBlocks != 0;
86}
87
88
89/// PlaceBlocks - Recursively place the specified blocks and any unplaced
90/// successors.
91void BlockPlacement::PlaceBlocks(BasicBlock *BB) {
92 assert(!PlacedBlocks.count(BB) && "Already placed this block!");
93 PlacedBlocks.insert(BB);
94
95 // Place the specified block.
96 if (&*InsertPos != BB) {
97 // Use splice to move the block into the right place. This avoids having to
98 // remove the block from the function then readd it, which causes a bunch of
99 // symbol table traffic that is entirely pointless.
100 Function::BasicBlockListType &Blocks = BB->getParent()->getBasicBlockList();
101 Blocks.splice(InsertPos, Blocks, BB);
102
103 ++NumMovedBlocks;
104 } else {
105 // This block is already in the right place, we don't have to do anything.
106 ++InsertPos;
107 }
108
109 // Keep placing successors until we run out of ones to place. Note that this
110 // loop is very inefficient (N^2) for blocks with many successors, like switch
111 // statements. FIXME!
112 while (1) {
113 // Okay, now place any unplaced successors.
114 succ_iterator SI = succ_begin(BB), E = succ_end(BB);
115
116 // Scan for the first unplaced successor.
117 for (; SI != E && PlacedBlocks.count(*SI); ++SI)
118 /*empty*/;
119 if (SI == E) return; // No more successors to place.
120
121 unsigned MaxExecutionCount = PI->getExecutionCount(*SI);
122 BasicBlock *MaxSuccessor = *SI;
123
124 // Scan for more frequently executed successors
125 for (; SI != E; ++SI)
126 if (!PlacedBlocks.count(*SI)) {
127 unsigned Count = PI->getExecutionCount(*SI);
128 if (Count > MaxExecutionCount ||
129 // Prefer to not disturb the code.
130 (Count == MaxExecutionCount && *SI == &*InsertPos)) {
131 MaxExecutionCount = Count;
132 MaxSuccessor = *SI;
133 }
134 }
135
136 // Now that we picked the maximally executed successor, place it.
137 PlaceBlocks(MaxSuccessor);
138 }
139}