blob: cee55026562217c3565531de03b91cf1f2784e99 [file] [log] [blame]
Chris Lattner206805e2004-02-11 04:53:20 +00001//===-- BasicBlockPlacement.cpp - Basic Block Code Layout optimization ----===//
Misha Brukmanfd939082005-04-21 23:48:37 +00002//
Chris Lattner206805e2004-02-11 04:53:20 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Misha Brukmanfd939082005-04-21 23:48:37 +00007//
Chris Lattner206805e2004-02-11 04:53:20 +00008//===----------------------------------------------------------------------===//
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
Chris Lattner0e5f4992006-12-19 21:40:18 +000029#define DEBUG_TYPE "block-placement"
Chris Lattner206805e2004-02-11 04:53:20 +000030#include "llvm/Analysis/ProfileInfo.h"
31#include "llvm/Function.h"
32#include "llvm/Pass.h"
33#include "llvm/Support/CFG.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000034#include "llvm/ADT/Statistic.h"
Jeff Cohenbf652682005-01-08 17:21:40 +000035#include "llvm/Transforms/Scalar.h"
Chris Lattner206805e2004-02-11 04:53:20 +000036#include <set>
37using namespace llvm;
38
Chris Lattner0e5f4992006-12-19 21:40:18 +000039STATISTIC(NumMoved, "Number of basic blocks moved");
Misha Brukmanfd939082005-04-21 23:48:37 +000040
Chris Lattner0e5f4992006-12-19 21:40:18 +000041namespace {
Chris Lattner3e8b6632009-09-02 06:11:42 +000042 struct BlockPlacement : public FunctionPass {
Nick Lewyckyecd94c82007-05-06 13:37:16 +000043 static char ID; // Pass identification, replacement for typeid
Owen Anderson081c34b2010-10-19 17:21:58 +000044 BlockPlacement() : FunctionPass(ID) {
45 initializeBlockPlacementPass(*PassRegistry::getPassRegistry());
46 }
Devang Patel794fd752007-05-01 21:15:47 +000047
Chris Lattner206805e2004-02-11 04:53:20 +000048 virtual bool runOnFunction(Function &F);
49
50 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
51 AU.setPreservesCFG();
52 AU.addRequired<ProfileInfo>();
53 //AU.addPreserved<ProfileInfo>(); // Does this work?
54 }
55 private:
56 /// PI - The profile information that is guiding us.
57 ///
58 ProfileInfo *PI;
59
60 /// NumMovedBlocks - Every time we move a block, increment this counter.
61 ///
62 unsigned NumMovedBlocks;
63
64 /// PlacedBlocks - Every time we place a block, remember it so we don't get
65 /// into infinite loops.
66 std::set<BasicBlock*> PlacedBlocks;
67
68 /// InsertPos - This an iterator to the next place we want to insert a
69 /// block.
70 Function::iterator InsertPos;
71
72 /// PlaceBlocks - Recursively place the specified blocks and any unplaced
73 /// successors.
74 void PlaceBlocks(BasicBlock *BB);
75 };
Chris Lattner206805e2004-02-11 04:53:20 +000076}
77
Dan Gohman844731a2008-05-13 00:00:25 +000078char BlockPlacement::ID = 0;
Owen Anderson2ab36d32010-10-12 19:48:12 +000079INITIALIZE_PASS_BEGIN(BlockPlacement, "block-placement",
80 "Profile Guided Basic Block Placement", false, false)
81INITIALIZE_AG_DEPENDENCY(ProfileInfo)
82INITIALIZE_PASS_END(BlockPlacement, "block-placement",
Owen Andersonce665bd2010-10-07 22:25:06 +000083 "Profile Guided Basic Block Placement", false, false)
Dan Gohman844731a2008-05-13 00:00:25 +000084
Jeff Cohenbf652682005-01-08 17:21:40 +000085FunctionPass *llvm::createBlockPlacementPass() { return new BlockPlacement(); }
86
Chris Lattner206805e2004-02-11 04:53:20 +000087bool BlockPlacement::runOnFunction(Function &F) {
88 PI = &getAnalysis<ProfileInfo>();
89
90 NumMovedBlocks = 0;
Misha Brukmanfd939082005-04-21 23:48:37 +000091 InsertPos = F.begin();
Chris Lattner206805e2004-02-11 04:53:20 +000092
93 // Recursively place all blocks.
94 PlaceBlocks(F.begin());
Misha Brukmanfd939082005-04-21 23:48:37 +000095
Chris Lattner206805e2004-02-11 04:53:20 +000096 PlacedBlocks.clear();
97 NumMoved += NumMovedBlocks;
98 return NumMovedBlocks != 0;
99}
100
101
102/// PlaceBlocks - Recursively place the specified blocks and any unplaced
103/// successors.
104void BlockPlacement::PlaceBlocks(BasicBlock *BB) {
105 assert(!PlacedBlocks.count(BB) && "Already placed this block!");
106 PlacedBlocks.insert(BB);
107
108 // Place the specified block.
109 if (&*InsertPos != BB) {
110 // Use splice to move the block into the right place. This avoids having to
111 // remove the block from the function then readd it, which causes a bunch of
112 // symbol table traffic that is entirely pointless.
113 Function::BasicBlockListType &Blocks = BB->getParent()->getBasicBlockList();
114 Blocks.splice(InsertPos, Blocks, BB);
115
116 ++NumMovedBlocks;
117 } else {
118 // This block is already in the right place, we don't have to do anything.
119 ++InsertPos;
120 }
121
122 // Keep placing successors until we run out of ones to place. Note that this
123 // loop is very inefficient (N^2) for blocks with many successors, like switch
124 // statements. FIXME!
125 while (1) {
126 // Okay, now place any unplaced successors.
127 succ_iterator SI = succ_begin(BB), E = succ_end(BB);
Misha Brukmanfd939082005-04-21 23:48:37 +0000128
Chris Lattner206805e2004-02-11 04:53:20 +0000129 // Scan for the first unplaced successor.
130 for (; SI != E && PlacedBlocks.count(*SI); ++SI)
131 /*empty*/;
132 if (SI == E) return; // No more successors to place.
Misha Brukmanfd939082005-04-21 23:48:37 +0000133
Daniel Dunbarcaaa4932009-08-08 17:43:09 +0000134 double MaxExecutionCount = PI->getExecutionCount(*SI);
Chris Lattner206805e2004-02-11 04:53:20 +0000135 BasicBlock *MaxSuccessor = *SI;
136
137 // Scan for more frequently executed successors
138 for (; SI != E; ++SI)
139 if (!PlacedBlocks.count(*SI)) {
Daniel Dunbarcaaa4932009-08-08 17:43:09 +0000140 double Count = PI->getExecutionCount(*SI);
Chris Lattner206805e2004-02-11 04:53:20 +0000141 if (Count > MaxExecutionCount ||
142 // Prefer to not disturb the code.
143 (Count == MaxExecutionCount && *SI == &*InsertPos)) {
144 MaxExecutionCount = Count;
145 MaxSuccessor = *SI;
146 }
147 }
148
149 // Now that we picked the maximally executed successor, place it.
150 PlaceBlocks(MaxSuccessor);
151 }
152}