mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-03 14:21:30 +00:00 
			
		
		
		
	Missing files for the BlockFrequency analysis added.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133767 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		
							
								
								
									
										53
									
								
								include/llvm/Analysis/BlockFrequency.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								include/llvm/Analysis/BlockFrequency.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					//========-------- BlockFrequency.h - Block Frequency Analysis -------========//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//                     The LLVM Compiler Infrastructure
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This file is distributed under the University of Illinois Open Source
 | 
				
			||||||
 | 
					// License. See LICENSE.TXT for details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Loops should be simplified before this analysis.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef LLVM_ANALYSIS_BLOCKFREQUENCY_H
 | 
				
			||||||
 | 
					#define LLVM_ANALYSIS_BLOCKFREQUENCY_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "llvm/Pass.h"
 | 
				
			||||||
 | 
					#include <climits>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace llvm {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BranchProbabilityInfo;
 | 
				
			||||||
 | 
					template<class BlockT, class FunctionT, class BranchProbInfoT>
 | 
				
			||||||
 | 
					class BlockFrequencyImpl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// BlockFrequency pass uses BlockFrequencyImpl implementation to estimate
 | 
				
			||||||
 | 
					/// IR basic block frequencies.
 | 
				
			||||||
 | 
					class BlockFrequency : public FunctionPass {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BlockFrequencyImpl<BasicBlock, Function, BranchProbabilityInfo> *BFI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  static char ID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BlockFrequency();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ~BlockFrequency();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void getAnalysisUsage(AnalysisUsage &AU) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool runOnFunction(Function &F);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// getblockFreq - Return block frequency. Never return 0, value must be
 | 
				
			||||||
 | 
					  /// positive. Please note that initial frequency is equal to 1024. It means
 | 
				
			||||||
 | 
					  /// that we should not rely on the value itself, but only on the comparison to
 | 
				
			||||||
 | 
					  /// the other block frequencies. We do this to avoid using of the floating
 | 
				
			||||||
 | 
					  /// points.
 | 
				
			||||||
 | 
					  uint32_t getBlockFreq(BasicBlock *BB);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										336
									
								
								include/llvm/Analysis/BlockFrequencyImpl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										336
									
								
								include/llvm/Analysis/BlockFrequencyImpl.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,336 @@
 | 
				
			|||||||
 | 
					//===---- BlockFrequencyImpl.h - Machine Block Frequency Implementation ---===//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//                     The LLVM Compiler Infrastructure
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This file is distributed under the University of Illinois Open Source
 | 
				
			||||||
 | 
					// License. See LICENSE.TXT for details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Shared implementation of BlockFrequency for IR and Machine Instructions.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
 | 
				
			||||||
 | 
					#define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "llvm/BasicBlock.h"
 | 
				
			||||||
 | 
					#include "llvm/ADT/DenseMap.h"
 | 
				
			||||||
 | 
					#include "llvm/ADT/PostOrderIterator.h"
 | 
				
			||||||
 | 
					#include "llvm/CodeGen/MachineBasicBlock.h"
 | 
				
			||||||
 | 
					#include "llvm/Support/BranchProbability.h"
 | 
				
			||||||
 | 
					#include "llvm/Support/Debug.h"
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace llvm {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BlockFrequency;
 | 
				
			||||||
 | 
					/// BlockFrequencyImpl implements block frequency algorithm for IR and
 | 
				
			||||||
 | 
					/// Machine Instructions. Algorithm starts with value 1024 (START_FREQ)
 | 
				
			||||||
 | 
					/// for the entry block and then propagates frequencies using branch weights
 | 
				
			||||||
 | 
					/// from (Machine)BranchProbabilityInfo. LoopInfo is not required because
 | 
				
			||||||
 | 
					/// algorithm can find "backedges" by itself.
 | 
				
			||||||
 | 
					template<class BlockT, class FunctionT, class BlockProbInfoT>
 | 
				
			||||||
 | 
					class BlockFrequencyImpl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DenseMap<BlockT *, uint32_t> Freqs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BlockProbInfoT *BPI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FunctionT *Fn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef GraphTraits< Inverse<BlockT *> > GT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static const uint32_t START_FREQ = 1024;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::string getBlockName(BasicBlock *BB) const {
 | 
				
			||||||
 | 
					    return BB->getNameStr();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::string getBlockName(MachineBasicBlock *MBB) const {
 | 
				
			||||||
 | 
					    std::stringstream ss;
 | 
				
			||||||
 | 
					    ss << "BB#" << MBB->getNumber();
 | 
				
			||||||
 | 
					    const BasicBlock *BB = MBB->getBasicBlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (BB)
 | 
				
			||||||
 | 
					      ss << " derived from LLVM BB " << BB->getNameStr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ss.str();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setBlockFreq(BlockT *BB, uint32_t Freq) {
 | 
				
			||||||
 | 
					    Freqs[BB] = Freq;
 | 
				
			||||||
 | 
					    DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") = " << Freq << "\n");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// getEdgeFreq - Return edge frequency based on SRC frequency and Src -> Dst
 | 
				
			||||||
 | 
					  /// edge probability.
 | 
				
			||||||
 | 
					  uint32_t getEdgeFreq(BlockT *Src, BlockT *Dst) const {
 | 
				
			||||||
 | 
					    BranchProbability Prob = BPI->getEdgeProbability(Src, Dst);
 | 
				
			||||||
 | 
					    uint64_t N = Prob.getNumerator();
 | 
				
			||||||
 | 
					    uint64_t D = Prob.getDenominator();
 | 
				
			||||||
 | 
					    uint64_t Res = (N * getBlockFreq(Src)) / D;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(Res <= UINT32_MAX);
 | 
				
			||||||
 | 
					    return (uint32_t) Res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// incBlockFreq - Increase BB block frequency by FREQ.
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  void incBlockFreq(BlockT *BB, uint32_t Freq) {
 | 
				
			||||||
 | 
					    Freqs[BB] += Freq;
 | 
				
			||||||
 | 
					    DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") += " << Freq
 | 
				
			||||||
 | 
					                 << " --> " << Freqs[BB] << "\n");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// divBlockFreq - Divide BB block frequency by PROB. If Prob = 0 do nothing.
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  void divBlockFreq(BlockT *BB, BranchProbability Prob) {
 | 
				
			||||||
 | 
					    uint64_t N = Prob.getNumerator();
 | 
				
			||||||
 | 
					    assert(N && "Illegal division by zero!");
 | 
				
			||||||
 | 
					    uint64_t D = Prob.getDenominator();
 | 
				
			||||||
 | 
					    uint64_t Freq = (Freqs[BB] * D) / N;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Should we assert it?
 | 
				
			||||||
 | 
					    if (Freq > UINT32_MAX)
 | 
				
			||||||
 | 
					      Freq = UINT32_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Freqs[BB] = (uint32_t) Freq;
 | 
				
			||||||
 | 
					    DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") /= (" << Prob
 | 
				
			||||||
 | 
					                 << ") --> " << Freqs[BB] << "\n");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // All blocks in postorder.
 | 
				
			||||||
 | 
					  std::vector<BlockT *> POT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Map Block -> Position in reverse-postorder list.
 | 
				
			||||||
 | 
					  DenseMap<BlockT *, unsigned> RPO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Cycle Probability for each bloch.
 | 
				
			||||||
 | 
					  DenseMap<BlockT *, uint32_t> CycleProb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // (reverse-)postorder traversal iterators.
 | 
				
			||||||
 | 
					  typedef typename std::vector<BlockT *>::iterator pot_iterator;
 | 
				
			||||||
 | 
					  typedef typename std::vector<BlockT *>::reverse_iterator rpot_iterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pot_iterator pot_begin() { return POT.begin(); }
 | 
				
			||||||
 | 
					  pot_iterator pot_end() { return POT.end(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rpot_iterator rpot_begin() { return POT.rbegin(); }
 | 
				
			||||||
 | 
					  rpot_iterator rpot_end() { return POT.rend(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rpot_iterator rpot_at(BlockT *BB) {
 | 
				
			||||||
 | 
					    rpot_iterator I = rpot_begin();
 | 
				
			||||||
 | 
					    unsigned idx = RPO[BB];
 | 
				
			||||||
 | 
					    assert(idx);
 | 
				
			||||||
 | 
					    std::advance(I, idx - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(*I == BB);
 | 
				
			||||||
 | 
					    return I;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// isReachable - Returns if BB block is reachable from the entry.
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  bool isReachable(BlockT *BB) {
 | 
				
			||||||
 | 
					    return RPO.count(BB);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// isBackedge - Return if edge Src -> Dst is a backedge.
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  bool isBackedge(BlockT *Src, BlockT *Dst) {
 | 
				
			||||||
 | 
					    assert(isReachable(Src));
 | 
				
			||||||
 | 
					    assert(isReachable(Dst));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned a = RPO[Src];
 | 
				
			||||||
 | 
					    unsigned b = RPO[Dst];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return a > b;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// getSingleBlockPred - return single BB block predecessor or NULL if
 | 
				
			||||||
 | 
					  /// BB has none or more predecessors.
 | 
				
			||||||
 | 
					  BlockT *getSingleBlockPred(BlockT *BB) {
 | 
				
			||||||
 | 
					    typename GT::ChildIteratorType
 | 
				
			||||||
 | 
					      PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
 | 
				
			||||||
 | 
					      PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (PI == PE)
 | 
				
			||||||
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    BlockT *Pred = *PI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ++PI;
 | 
				
			||||||
 | 
					    if (PI != PE)
 | 
				
			||||||
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return Pred;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void doBlock(BlockT *BB, BlockT *LoopHead,
 | 
				
			||||||
 | 
					               SmallPtrSet<BlockT *, 8> &BlocksInLoop) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DEBUG(dbgs() << "doBlock(" << getBlockName(BB) << ")\n");
 | 
				
			||||||
 | 
					    setBlockFreq(BB, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (BB == LoopHead) {
 | 
				
			||||||
 | 
					      setBlockFreq(BB, START_FREQ);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(BlockT *Pred = getSingleBlockPred(BB)) {
 | 
				
			||||||
 | 
					      if (BlocksInLoop.count(Pred))
 | 
				
			||||||
 | 
					        setBlockFreq(BB, getEdgeFreq(Pred, BB));
 | 
				
			||||||
 | 
					      // TODO: else? irreducible, ignore it for now.
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool isInLoop = false;
 | 
				
			||||||
 | 
					    bool isLoopHead = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (typename GT::ChildIteratorType
 | 
				
			||||||
 | 
					         PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
 | 
				
			||||||
 | 
					         PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
 | 
				
			||||||
 | 
					         PI != PE; ++PI) {
 | 
				
			||||||
 | 
					      BlockT *Pred = *PI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (isReachable(Pred) && isBackedge(Pred, BB)) {
 | 
				
			||||||
 | 
					        isLoopHead = true;
 | 
				
			||||||
 | 
					      } else if (BlocksInLoop.count(Pred)) {
 | 
				
			||||||
 | 
					        incBlockFreq(BB, getEdgeFreq(Pred, BB));
 | 
				
			||||||
 | 
					        isInLoop = true;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      // TODO: else? irreducible.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!isInLoop)
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!isLoopHead)
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(START_FREQ >= CycleProb[BB]);
 | 
				
			||||||
 | 
					    divBlockFreq(BB, BranchProbability(START_FREQ - CycleProb[BB], START_FREQ));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// doLoop - Propagate block frequency down throught the loop.
 | 
				
			||||||
 | 
					  void doLoop(BlockT *Head, BlockT *Tail) {
 | 
				
			||||||
 | 
					    DEBUG(dbgs() << "doLoop(" << getBlockName(Head) << ", "
 | 
				
			||||||
 | 
					                 << getBlockName(Tail) << ")\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SmallPtrSet<BlockT *, 8> BlocksInLoop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (rpot_iterator I = rpot_at(Head), E = rpot_end(); I != E; ++I) {
 | 
				
			||||||
 | 
					      BlockT *BB = *I;
 | 
				
			||||||
 | 
					      doBlock(BB, Head, BlocksInLoop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      BlocksInLoop.insert(BB);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Compute loop's cyclic probability using backedges probabilities.
 | 
				
			||||||
 | 
					    for (typename GT::ChildIteratorType
 | 
				
			||||||
 | 
					         PI = GraphTraits< Inverse<BlockT *> >::child_begin(Head),
 | 
				
			||||||
 | 
					         PE = GraphTraits< Inverse<BlockT *> >::child_end(Head);
 | 
				
			||||||
 | 
					         PI != PE; ++PI) {
 | 
				
			||||||
 | 
					      BlockT *Pred = *PI;
 | 
				
			||||||
 | 
					      assert(Pred);
 | 
				
			||||||
 | 
					      if (isReachable(Pred) && isBackedge(Pred, Head)) {
 | 
				
			||||||
 | 
					        BranchProbability Prob = BPI->getBackEdgeProbability(Pred, Head);
 | 
				
			||||||
 | 
					        uint64_t N = Prob.getNumerator();
 | 
				
			||||||
 | 
					        uint64_t D = Prob.getDenominator();
 | 
				
			||||||
 | 
					        uint64_t Res = (N * START_FREQ) / D;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // CycleProb[Head] += getEdgeFreq(Pred, Head);
 | 
				
			||||||
 | 
					        assert(Res <= UINT32_MAX);
 | 
				
			||||||
 | 
					        CycleProb[Head] += (uint32_t) Res;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend class BlockFrequency;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void doFunction(FunctionT *fn, BlockProbInfoT *bpi) {
 | 
				
			||||||
 | 
					    Fn = fn;
 | 
				
			||||||
 | 
					    BPI = bpi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Clear everything.
 | 
				
			||||||
 | 
					    RPO.clear();
 | 
				
			||||||
 | 
					    POT.clear();
 | 
				
			||||||
 | 
					    CycleProb.clear();
 | 
				
			||||||
 | 
					    Freqs.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    BlockT *EntryBlock = fn->begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    copy(po_begin(EntryBlock), po_end(EntryBlock), back_inserter(POT));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned RPOidx = 0;
 | 
				
			||||||
 | 
					    for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {
 | 
				
			||||||
 | 
					      BlockT *BB = *I;
 | 
				
			||||||
 | 
					      RPO[BB] = ++RPOidx;
 | 
				
			||||||
 | 
					      DEBUG(dbgs() << "RPO[" << getBlockName(BB) << "] = " << RPO[BB] << "\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Travel over all blocks in postorder.
 | 
				
			||||||
 | 
					    for (pot_iterator I = pot_begin(), E = pot_end(); I != E; ++I) {
 | 
				
			||||||
 | 
					      BlockT *BB = *I;
 | 
				
			||||||
 | 
					      BlockT *LastTail = 0;
 | 
				
			||||||
 | 
					      DEBUG(dbgs() << "POT: " << getBlockName(BB) << "\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for (typename GT::ChildIteratorType
 | 
				
			||||||
 | 
					           PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
 | 
				
			||||||
 | 
					           PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
 | 
				
			||||||
 | 
					           PI != PE; ++PI) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        BlockT *Pred = *PI;
 | 
				
			||||||
 | 
					        if (isReachable(Pred) && isBackedge(Pred, BB)
 | 
				
			||||||
 | 
					            && (!LastTail || RPO[Pred] > RPO[LastTail]))
 | 
				
			||||||
 | 
					          LastTail = Pred;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (LastTail)
 | 
				
			||||||
 | 
					        doLoop(BB, LastTail);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // At the end assume the whole function as a loop, and travel over it once
 | 
				
			||||||
 | 
					    // again.
 | 
				
			||||||
 | 
					    doLoop(*(rpot_begin()), *(pot_begin()));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  /// getBlockFreq - Return block frequency. Never return 0, value must be
 | 
				
			||||||
 | 
					  /// positive.
 | 
				
			||||||
 | 
					  uint32_t getBlockFreq(BlockT *BB) const {
 | 
				
			||||||
 | 
					    typename DenseMap<BlockT *, uint32_t>::const_iterator I = Freqs.find(BB);
 | 
				
			||||||
 | 
					    if (I != Freqs.end())
 | 
				
			||||||
 | 
					      return I->second ? I->second : 1;
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void print(raw_ostream &OS) const {
 | 
				
			||||||
 | 
					    OS << "\n\n---- Block Freqs ----\n";
 | 
				
			||||||
 | 
					    for (typename FunctionT::iterator I = Fn->begin(), E = Fn->end(); I != E;) {
 | 
				
			||||||
 | 
					      BlockT *BB = I++;
 | 
				
			||||||
 | 
					      OS << " " << getBlockName(BB) << " = " << getBlockFreq(BB) << "\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for (typename GraphTraits<BlockT *>::ChildIteratorType
 | 
				
			||||||
 | 
					           SI = GraphTraits<BlockT *>::child_begin(BB),
 | 
				
			||||||
 | 
					           SE = GraphTraits<BlockT *>::child_end(BB); SI != SE; ++SI) {
 | 
				
			||||||
 | 
					        BlockT *Succ = *SI;
 | 
				
			||||||
 | 
					        OS << "  " << getBlockName(BB) << " -> " << getBlockName(Succ)
 | 
				
			||||||
 | 
					           << " = " << getEdgeFreq(BB, Succ) << "\n";
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void dump() const {
 | 
				
			||||||
 | 
					    print(dbgs());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										59
									
								
								lib/Analysis/BlockFrequency.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								lib/Analysis/BlockFrequency.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					//=======-------- BlockFrequency.cpp - Block Frequency Analysis -------=======//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//                     The LLVM Compiler Infrastructure
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This file is distributed under the University of Illinois Open Source
 | 
				
			||||||
 | 
					// License. See LICENSE.TXT for details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Loops should be simplified before this analysis.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "llvm/InitializePasses.h"
 | 
				
			||||||
 | 
					#include "llvm/Analysis/BlockFrequencyImpl.h"
 | 
				
			||||||
 | 
					#include "llvm/Analysis/BlockFrequency.h"
 | 
				
			||||||
 | 
					#include "llvm/Analysis/LoopInfo.h"
 | 
				
			||||||
 | 
					#include "llvm/Analysis/Passes.h"
 | 
				
			||||||
 | 
					#include "llvm/Analysis/BranchProbabilityInfo.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace llvm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INITIALIZE_PASS_BEGIN(BlockFrequency, "block-freq", "Block Frequency Analysis",
 | 
				
			||||||
 | 
					                      true, true)
 | 
				
			||||||
 | 
					INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfo)
 | 
				
			||||||
 | 
					INITIALIZE_PASS_END(BlockFrequency, "block-freq", "Block Frequency Analysis",
 | 
				
			||||||
 | 
					                    true, true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char BlockFrequency::ID = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BlockFrequency::BlockFrequency() : FunctionPass(ID) {
 | 
				
			||||||
 | 
					  initializeBlockFrequencyPass(*PassRegistry::getPassRegistry());
 | 
				
			||||||
 | 
					  BFI = new BlockFrequencyImpl<BasicBlock, Function, BranchProbabilityInfo>();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BlockFrequency::~BlockFrequency() {
 | 
				
			||||||
 | 
					  delete BFI;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BlockFrequency::getAnalysisUsage(AnalysisUsage &AU) const {
 | 
				
			||||||
 | 
					  AU.addRequired<BranchProbabilityInfo>();
 | 
				
			||||||
 | 
					  AU.setPreservesAll();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BlockFrequency::runOnFunction(Function &F) {
 | 
				
			||||||
 | 
					  BranchProbabilityInfo &BPI = getAnalysis<BranchProbabilityInfo>();
 | 
				
			||||||
 | 
					  BFI->doFunction(&F, &BPI);
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// getblockFreq - Return block frequency. Never return 0, value must be
 | 
				
			||||||
 | 
					/// positive. Please note that initial frequency is equal to 1024. It means that
 | 
				
			||||||
 | 
					/// we should not rely on the value itself, but only on the comparison to the
 | 
				
			||||||
 | 
					/// other block frequencies. We do this to avoid using of floating points.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					uint32_t BlockFrequency::getBlockFreq(BasicBlock *BB) {
 | 
				
			||||||
 | 
					  return BFI->getBlockFreq(BB);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user