LLVM API Documentation
00001 //===-- BasicBlockPlacement.cpp - Basic Block Code Layout optimization ----===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements a very simple profile guided basic block placement 00011 // algorithm. The idea is to put frequently executed blocks together at the 00012 // start of the function, and hopefully increase the number of fall-through 00013 // conditional branches. If there is no profile information for a particular 00014 // function, this pass basically orders blocks in depth-first order 00015 // 00016 // The algorithm implemented here is basically "Algo1" from "Profile Guided Code 00017 // Positioning" by Pettis and Hansen, except that it uses basic block counts 00018 // instead of edge counts. This should be improved in many ways, but is very 00019 // simple for now. 00020 // 00021 // Basically we "place" the entry block, then loop over all successors in a DFO, 00022 // placing the most frequently executed successor until we run out of blocks. I 00023 // told you this was _extremely_ simplistic. :) This is also much slower than it 00024 // could be. When it becomes important, this pass will be rewritten to use a 00025 // better algorithm, and then we can worry about efficiency. 00026 // 00027 //===----------------------------------------------------------------------===// 00028 00029 #define DEBUG_TYPE "block-placement" 00030 #include "llvm/Analysis/ProfileInfo.h" 00031 #include "llvm/Function.h" 00032 #include "llvm/Pass.h" 00033 #include "llvm/Support/CFG.h" 00034 #include "llvm/Support/Compiler.h" 00035 #include "llvm/ADT/Statistic.h" 00036 #include "llvm/Transforms/Scalar.h" 00037 #include <set> 00038 using namespace llvm; 00039 00040 STATISTIC(NumMoved, "Number of basic blocks moved"); 00041 00042 namespace { 00043 struct VISIBILITY_HIDDEN BlockPlacement : public FunctionPass { 00044 static char ID; // Pass identification, replacement for typeid 00045 BlockPlacement() : FunctionPass(&ID) {} 00046 00047 virtual bool runOnFunction(Function &F); 00048 00049 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00050 AU.setPreservesCFG(); 00051 AU.addRequired<ProfileInfo>(); 00052 //AU.addPreserved<ProfileInfo>(); // Does this work? 00053 } 00054 private: 00055 /// PI - The profile information that is guiding us. 00056 /// 00057 ProfileInfo *PI; 00058 00059 /// NumMovedBlocks - Every time we move a block, increment this counter. 00060 /// 00061 unsigned NumMovedBlocks; 00062 00063 /// PlacedBlocks - Every time we place a block, remember it so we don't get 00064 /// into infinite loops. 00065 std::set<BasicBlock*> PlacedBlocks; 00066 00067 /// InsertPos - This an iterator to the next place we want to insert a 00068 /// block. 00069 Function::iterator InsertPos; 00070 00071 /// PlaceBlocks - Recursively place the specified blocks and any unplaced 00072 /// successors. 00073 void PlaceBlocks(BasicBlock *BB); 00074 }; 00075 } 00076 00077 char BlockPlacement::ID = 0; 00078 static RegisterPass<BlockPlacement> 00079 X("block-placement", "Profile Guided Basic Block Placement"); 00080 00081 FunctionPass *llvm::createBlockPlacementPass() { return new BlockPlacement(); } 00082 00083 bool BlockPlacement::runOnFunction(Function &F) { 00084 PI = &getAnalysis<ProfileInfo>(); 00085 00086 NumMovedBlocks = 0; 00087 InsertPos = F.begin(); 00088 00089 // Recursively place all blocks. 00090 PlaceBlocks(F.begin()); 00091 00092 PlacedBlocks.clear(); 00093 NumMoved += NumMovedBlocks; 00094 return NumMovedBlocks != 0; 00095 } 00096 00097 00098 /// PlaceBlocks - Recursively place the specified blocks and any unplaced 00099 /// successors. 00100 void BlockPlacement::PlaceBlocks(BasicBlock *BB) { 00101 assert(!PlacedBlocks.count(BB) && "Already placed this block!"); 00102 PlacedBlocks.insert(BB); 00103 00104 // Place the specified block. 00105 if (&*InsertPos != BB) { 00106 // Use splice to move the block into the right place. This avoids having to 00107 // remove the block from the function then readd it, which causes a bunch of 00108 // symbol table traffic that is entirely pointless. 00109 Function::BasicBlockListType &Blocks = BB->getParent()->getBasicBlockList(); 00110 Blocks.splice(InsertPos, Blocks, BB); 00111 00112 ++NumMovedBlocks; 00113 } else { 00114 // This block is already in the right place, we don't have to do anything. 00115 ++InsertPos; 00116 } 00117 00118 // Keep placing successors until we run out of ones to place. Note that this 00119 // loop is very inefficient (N^2) for blocks with many successors, like switch 00120 // statements. FIXME! 00121 while (1) { 00122 // Okay, now place any unplaced successors. 00123 succ_iterator SI = succ_begin(BB), E = succ_end(BB); 00124 00125 // Scan for the first unplaced successor. 00126 for (; SI != E && PlacedBlocks.count(*SI); ++SI) 00127 /*empty*/; 00128 if (SI == E) return; // No more successors to place. 00129 00130 unsigned MaxExecutionCount = PI->getExecutionCount(*SI); 00131 BasicBlock *MaxSuccessor = *SI; 00132 00133 // Scan for more frequently executed successors 00134 for (; SI != E; ++SI) 00135 if (!PlacedBlocks.count(*SI)) { 00136 unsigned Count = PI->getExecutionCount(*SI); 00137 if (Count > MaxExecutionCount || 00138 // Prefer to not disturb the code. 00139 (Count == MaxExecutionCount && *SI == &*InsertPos)) { 00140 MaxExecutionCount = Count; 00141 MaxSuccessor = *SI; 00142 } 00143 } 00144 00145 // Now that we picked the maximally executed successor, place it. 00146 PlaceBlocks(MaxSuccessor); 00147 } 00148 }