1*9880d681SAndroid Build Coastguard Worker //===-- BranchFolding.h - Fold machine code branch instructions -*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_CODEGEN_BRANCHFOLDING_H 11*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_CODEGEN_BRANCHFOLDING_H 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallPtrSet.h" 14*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LivePhysRegs.h" 15*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBasicBlock.h" 16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/BlockFrequency.h" 17*9880d681SAndroid Build Coastguard Worker #include <vector> 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker namespace llvm { 20*9880d681SAndroid Build Coastguard Worker class MachineBlockFrequencyInfo; 21*9880d681SAndroid Build Coastguard Worker class MachineBranchProbabilityInfo; 22*9880d681SAndroid Build Coastguard Worker class MachineFunction; 23*9880d681SAndroid Build Coastguard Worker class MachineModuleInfo; 24*9880d681SAndroid Build Coastguard Worker class MachineLoopInfo; 25*9880d681SAndroid Build Coastguard Worker class TargetInstrInfo; 26*9880d681SAndroid Build Coastguard Worker class TargetRegisterInfo; 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker class LLVM_LIBRARY_VISIBILITY BranchFolder { 29*9880d681SAndroid Build Coastguard Worker public: 30*9880d681SAndroid Build Coastguard Worker class MBFIWrapper; 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker explicit BranchFolder(bool defaultEnableTailMerge, bool CommonHoist, 33*9880d681SAndroid Build Coastguard Worker MBFIWrapper &MBFI, 34*9880d681SAndroid Build Coastguard Worker const MachineBranchProbabilityInfo &MBPI); 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker bool OptimizeFunction(MachineFunction &MF, const TargetInstrInfo *tii, 37*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *tri, MachineModuleInfo *mmi, 38*9880d681SAndroid Build Coastguard Worker MachineLoopInfo *mli = nullptr, 39*9880d681SAndroid Build Coastguard Worker bool AfterPlacement = false); 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker private: 42*9880d681SAndroid Build Coastguard Worker class MergePotentialsElt { 43*9880d681SAndroid Build Coastguard Worker unsigned Hash; 44*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Block; 45*9880d681SAndroid Build Coastguard Worker public: MergePotentialsElt(unsigned h,MachineBasicBlock * b)46*9880d681SAndroid Build Coastguard Worker MergePotentialsElt(unsigned h, MachineBasicBlock *b) 47*9880d681SAndroid Build Coastguard Worker : Hash(h), Block(b) {} 48*9880d681SAndroid Build Coastguard Worker getHash()49*9880d681SAndroid Build Coastguard Worker unsigned getHash() const { return Hash; } getBlock()50*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *getBlock() const { return Block; } 51*9880d681SAndroid Build Coastguard Worker setBlock(MachineBasicBlock * MBB)52*9880d681SAndroid Build Coastguard Worker void setBlock(MachineBasicBlock *MBB) { 53*9880d681SAndroid Build Coastguard Worker Block = MBB; 54*9880d681SAndroid Build Coastguard Worker } 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker bool operator<(const MergePotentialsElt &) const; 57*9880d681SAndroid Build Coastguard Worker }; 58*9880d681SAndroid Build Coastguard Worker typedef std::vector<MergePotentialsElt>::iterator MPIterator; 59*9880d681SAndroid Build Coastguard Worker std::vector<MergePotentialsElt> MergePotentials; 60*9880d681SAndroid Build Coastguard Worker SmallPtrSet<const MachineBasicBlock*, 2> TriedMerging; 61*9880d681SAndroid Build Coastguard Worker DenseMap<const MachineBasicBlock *, int> FuncletMembership; 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker class SameTailElt { 64*9880d681SAndroid Build Coastguard Worker MPIterator MPIter; 65*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator TailStartPos; 66*9880d681SAndroid Build Coastguard Worker public: SameTailElt(MPIterator mp,MachineBasicBlock::iterator tsp)67*9880d681SAndroid Build Coastguard Worker SameTailElt(MPIterator mp, MachineBasicBlock::iterator tsp) 68*9880d681SAndroid Build Coastguard Worker : MPIter(mp), TailStartPos(tsp) {} 69*9880d681SAndroid Build Coastguard Worker getMPIter()70*9880d681SAndroid Build Coastguard Worker MPIterator getMPIter() const { 71*9880d681SAndroid Build Coastguard Worker return MPIter; 72*9880d681SAndroid Build Coastguard Worker } getMergePotentialsElt()73*9880d681SAndroid Build Coastguard Worker MergePotentialsElt &getMergePotentialsElt() const { 74*9880d681SAndroid Build Coastguard Worker return *getMPIter(); 75*9880d681SAndroid Build Coastguard Worker } getTailStartPos()76*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator getTailStartPos() const { 77*9880d681SAndroid Build Coastguard Worker return TailStartPos; 78*9880d681SAndroid Build Coastguard Worker } getHash()79*9880d681SAndroid Build Coastguard Worker unsigned getHash() const { 80*9880d681SAndroid Build Coastguard Worker return getMergePotentialsElt().getHash(); 81*9880d681SAndroid Build Coastguard Worker } getBlock()82*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *getBlock() const { 83*9880d681SAndroid Build Coastguard Worker return getMergePotentialsElt().getBlock(); 84*9880d681SAndroid Build Coastguard Worker } tailIsWholeBlock()85*9880d681SAndroid Build Coastguard Worker bool tailIsWholeBlock() const { 86*9880d681SAndroid Build Coastguard Worker return TailStartPos == getBlock()->begin(); 87*9880d681SAndroid Build Coastguard Worker } 88*9880d681SAndroid Build Coastguard Worker setBlock(MachineBasicBlock * MBB)89*9880d681SAndroid Build Coastguard Worker void setBlock(MachineBasicBlock *MBB) { 90*9880d681SAndroid Build Coastguard Worker getMergePotentialsElt().setBlock(MBB); 91*9880d681SAndroid Build Coastguard Worker } setTailStartPos(MachineBasicBlock::iterator Pos)92*9880d681SAndroid Build Coastguard Worker void setTailStartPos(MachineBasicBlock::iterator Pos) { 93*9880d681SAndroid Build Coastguard Worker TailStartPos = Pos; 94*9880d681SAndroid Build Coastguard Worker } 95*9880d681SAndroid Build Coastguard Worker }; 96*9880d681SAndroid Build Coastguard Worker std::vector<SameTailElt> SameTails; 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker bool AfterBlockPlacement; 99*9880d681SAndroid Build Coastguard Worker bool EnableTailMerge; 100*9880d681SAndroid Build Coastguard Worker bool EnableHoistCommonCode; 101*9880d681SAndroid Build Coastguard Worker bool UpdateLiveIns; 102*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII; 103*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI; 104*9880d681SAndroid Build Coastguard Worker MachineModuleInfo *MMI; 105*9880d681SAndroid Build Coastguard Worker MachineLoopInfo *MLI; 106*9880d681SAndroid Build Coastguard Worker LivePhysRegs LiveRegs; 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Worker public: 109*9880d681SAndroid Build Coastguard Worker /// \brief This class keeps track of branch frequencies of newly created 110*9880d681SAndroid Build Coastguard Worker /// blocks and tail-merged blocks. 111*9880d681SAndroid Build Coastguard Worker class MBFIWrapper { 112*9880d681SAndroid Build Coastguard Worker public: MBFIWrapper(const MachineBlockFrequencyInfo & I)113*9880d681SAndroid Build Coastguard Worker MBFIWrapper(const MachineBlockFrequencyInfo &I) : MBFI(I) {} 114*9880d681SAndroid Build Coastguard Worker BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const; 115*9880d681SAndroid Build Coastguard Worker void setBlockFreq(const MachineBasicBlock *MBB, BlockFrequency F); 116*9880d681SAndroid Build Coastguard Worker raw_ostream &printBlockFreq(raw_ostream &OS, 117*9880d681SAndroid Build Coastguard Worker const MachineBasicBlock *MBB) const; 118*9880d681SAndroid Build Coastguard Worker raw_ostream &printBlockFreq(raw_ostream &OS, 119*9880d681SAndroid Build Coastguard Worker const BlockFrequency Freq) const; 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker private: 122*9880d681SAndroid Build Coastguard Worker const MachineBlockFrequencyInfo &MBFI; 123*9880d681SAndroid Build Coastguard Worker DenseMap<const MachineBasicBlock *, BlockFrequency> MergedBBFreq; 124*9880d681SAndroid Build Coastguard Worker }; 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker private: 127*9880d681SAndroid Build Coastguard Worker MBFIWrapper &MBBFreqInfo; 128*9880d681SAndroid Build Coastguard Worker const MachineBranchProbabilityInfo &MBPI; 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Worker bool TailMergeBlocks(MachineFunction &MF); 131*9880d681SAndroid Build Coastguard Worker bool TryTailMergeBlocks(MachineBasicBlock* SuccBB, 132*9880d681SAndroid Build Coastguard Worker MachineBasicBlock* PredBB); 133*9880d681SAndroid Build Coastguard Worker void setCommonTailEdgeWeights(MachineBasicBlock &TailMBB); 134*9880d681SAndroid Build Coastguard Worker void computeLiveIns(MachineBasicBlock &MBB); 135*9880d681SAndroid Build Coastguard Worker void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, 136*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *NewDest); 137*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SplitMBBAt(MachineBasicBlock &CurMBB, 138*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator BBI1, 139*9880d681SAndroid Build Coastguard Worker const BasicBlock *BB); 140*9880d681SAndroid Build Coastguard Worker unsigned ComputeSameTails(unsigned CurHash, unsigned minCommonTailLength, 141*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SuccBB, 142*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *PredBB); 143*9880d681SAndroid Build Coastguard Worker void RemoveBlocksWithHash(unsigned CurHash, MachineBasicBlock* SuccBB, 144*9880d681SAndroid Build Coastguard Worker MachineBasicBlock* PredBB); 145*9880d681SAndroid Build Coastguard Worker bool CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB, 146*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SuccBB, 147*9880d681SAndroid Build Coastguard Worker unsigned maxCommonTailLength, 148*9880d681SAndroid Build Coastguard Worker unsigned &commonTailIndex); 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker bool OptimizeBranches(MachineFunction &MF); 151*9880d681SAndroid Build Coastguard Worker bool OptimizeBlock(MachineBasicBlock *MBB); 152*9880d681SAndroid Build Coastguard Worker void RemoveDeadBlock(MachineBasicBlock *MBB); 153*9880d681SAndroid Build Coastguard Worker bool OptimizeImpDefsBlock(MachineBasicBlock *MBB); 154*9880d681SAndroid Build Coastguard Worker 155*9880d681SAndroid Build Coastguard Worker bool HoistCommonCode(MachineFunction &MF); 156*9880d681SAndroid Build Coastguard Worker bool HoistCommonCodeInSuccs(MachineBasicBlock *MBB); 157*9880d681SAndroid Build Coastguard Worker }; 158*9880d681SAndroid Build Coastguard Worker } 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Worker #endif /* LLVM_CODEGEN_BRANCHFOLDING_HPP */ 161