10b57cec5SDimitry Andric //===- BranchFolding.h - Fold machine code branch instructions --*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_BRANCHFOLDING_H 100b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_BRANCHFOLDING_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 130b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 140b57cec5SDimitry Andric #include "llvm/CodeGen/LivePhysRegs.h" 150b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 160b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 170b57cec5SDimitry Andric #include <vector> 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric namespace llvm { 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric class BasicBlock; 220b57cec5SDimitry Andric class MachineBranchProbabilityInfo; 230b57cec5SDimitry Andric class MachineFunction; 240b57cec5SDimitry Andric class MachineLoopInfo; 250b57cec5SDimitry Andric class MachineRegisterInfo; 265ffd83dbSDimitry Andric class MBFIWrapper; 27480093f4SDimitry Andric class ProfileSummaryInfo; 280b57cec5SDimitry Andric class TargetInstrInfo; 290b57cec5SDimitry Andric class TargetRegisterInfo; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY BranchFolder { 320b57cec5SDimitry Andric public: 33e8d8bef9SDimitry Andric explicit BranchFolder(bool DefaultEnableTailMerge, bool CommonHoist, 340b57cec5SDimitry Andric MBFIWrapper &FreqInfo, 350b57cec5SDimitry Andric const MachineBranchProbabilityInfo &ProbInfo, 36480093f4SDimitry Andric ProfileSummaryInfo *PSI, 370b57cec5SDimitry Andric // Min tail length to merge. Defaults to commandline 380b57cec5SDimitry Andric // flag. Ignored for optsize. 390b57cec5SDimitry Andric unsigned MinTailLength = 0); 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric /// Perhaps branch folding, tail merging and other CFG optimizations on the 420b57cec5SDimitry Andric /// given function. Block placement changes the layout and may create new 430b57cec5SDimitry Andric /// tail merging opportunities. 440b57cec5SDimitry Andric bool OptimizeFunction(MachineFunction &MF, const TargetInstrInfo *tii, 455ffd83dbSDimitry Andric const TargetRegisterInfo *tri, 460b57cec5SDimitry Andric MachineLoopInfo *mli = nullptr, 470b57cec5SDimitry Andric bool AfterPlacement = false); 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric private: 500b57cec5SDimitry Andric class MergePotentialsElt { 510b57cec5SDimitry Andric unsigned Hash; 520b57cec5SDimitry Andric MachineBasicBlock *Block; 53*0fca6ea1SDimitry Andric DebugLoc BranchDebugLoc; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric public: MergePotentialsElt(unsigned h,MachineBasicBlock * b,DebugLoc bdl)56*0fca6ea1SDimitry Andric MergePotentialsElt(unsigned h, MachineBasicBlock *b, DebugLoc bdl) 57*0fca6ea1SDimitry Andric : Hash(h), Block(b), BranchDebugLoc(std::move(bdl)) {} 580b57cec5SDimitry Andric getHash()590b57cec5SDimitry Andric unsigned getHash() const { return Hash; } getBlock()600b57cec5SDimitry Andric MachineBasicBlock *getBlock() const { return Block; } 610b57cec5SDimitry Andric setBlock(MachineBasicBlock * MBB)620b57cec5SDimitry Andric void setBlock(MachineBasicBlock *MBB) { 630b57cec5SDimitry Andric Block = MBB; 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric getBranchDebugLoc()66*0fca6ea1SDimitry Andric const DebugLoc &getBranchDebugLoc() { return BranchDebugLoc; } 67*0fca6ea1SDimitry Andric 680b57cec5SDimitry Andric bool operator<(const MergePotentialsElt &) const; 690b57cec5SDimitry Andric }; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric using MPIterator = std::vector<MergePotentialsElt>::iterator; 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric std::vector<MergePotentialsElt> MergePotentials; 740b57cec5SDimitry Andric SmallPtrSet<const MachineBasicBlock*, 2> TriedMerging; 750b57cec5SDimitry Andric DenseMap<const MachineBasicBlock *, int> EHScopeMembership; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric class SameTailElt { 780b57cec5SDimitry Andric MPIterator MPIter; 790b57cec5SDimitry Andric MachineBasicBlock::iterator TailStartPos; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric public: SameTailElt(MPIterator mp,MachineBasicBlock::iterator tsp)820b57cec5SDimitry Andric SameTailElt(MPIterator mp, MachineBasicBlock::iterator tsp) 830b57cec5SDimitry Andric : MPIter(mp), TailStartPos(tsp) {} 840b57cec5SDimitry Andric getMPIter()850b57cec5SDimitry Andric MPIterator getMPIter() const { 860b57cec5SDimitry Andric return MPIter; 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric getMergePotentialsElt()890b57cec5SDimitry Andric MergePotentialsElt &getMergePotentialsElt() const { 900b57cec5SDimitry Andric return *getMPIter(); 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric getTailStartPos()930b57cec5SDimitry Andric MachineBasicBlock::iterator getTailStartPos() const { 940b57cec5SDimitry Andric return TailStartPos; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric getHash()970b57cec5SDimitry Andric unsigned getHash() const { 980b57cec5SDimitry Andric return getMergePotentialsElt().getHash(); 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric getBlock()1010b57cec5SDimitry Andric MachineBasicBlock *getBlock() const { 1020b57cec5SDimitry Andric return getMergePotentialsElt().getBlock(); 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric tailIsWholeBlock()1050b57cec5SDimitry Andric bool tailIsWholeBlock() const { 1060b57cec5SDimitry Andric return TailStartPos == getBlock()->begin(); 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric setBlock(MachineBasicBlock * MBB)1090b57cec5SDimitry Andric void setBlock(MachineBasicBlock *MBB) { 1100b57cec5SDimitry Andric getMergePotentialsElt().setBlock(MBB); 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric setTailStartPos(MachineBasicBlock::iterator Pos)1130b57cec5SDimitry Andric void setTailStartPos(MachineBasicBlock::iterator Pos) { 1140b57cec5SDimitry Andric TailStartPos = Pos; 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric }; 1170b57cec5SDimitry Andric std::vector<SameTailElt> SameTails; 1180b57cec5SDimitry Andric 11906c3fb27SDimitry Andric bool AfterBlockPlacement = false; 12006c3fb27SDimitry Andric bool EnableTailMerge = false; 12106c3fb27SDimitry Andric bool EnableHoistCommonCode = false; 12206c3fb27SDimitry Andric bool UpdateLiveIns = false; 1230b57cec5SDimitry Andric unsigned MinCommonTailLength; 12406c3fb27SDimitry Andric const TargetInstrInfo *TII = nullptr; 12506c3fb27SDimitry Andric const MachineRegisterInfo *MRI = nullptr; 12606c3fb27SDimitry Andric const TargetRegisterInfo *TRI = nullptr; 12706c3fb27SDimitry Andric MachineLoopInfo *MLI = nullptr; 1280b57cec5SDimitry Andric LivePhysRegs LiveRegs; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric private: 1310b57cec5SDimitry Andric MBFIWrapper &MBBFreqInfo; 1320b57cec5SDimitry Andric const MachineBranchProbabilityInfo &MBPI; 133480093f4SDimitry Andric ProfileSummaryInfo *PSI; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric bool TailMergeBlocks(MachineFunction &MF); 1360b57cec5SDimitry Andric bool TryTailMergeBlocks(MachineBasicBlock* SuccBB, 1370b57cec5SDimitry Andric MachineBasicBlock* PredBB, 1380b57cec5SDimitry Andric unsigned MinCommonTailLength); 1390b57cec5SDimitry Andric void setCommonTailEdgeWeights(MachineBasicBlock &TailMBB); 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric /// Delete the instruction OldInst and everything after it, replacing it 1420b57cec5SDimitry Andric /// with an unconditional branch to NewDest. 1430b57cec5SDimitry Andric void replaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, 1440b57cec5SDimitry Andric MachineBasicBlock &NewDest); 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric /// Given a machine basic block and an iterator into it, split the MBB so 1470b57cec5SDimitry Andric /// that the part before the iterator falls into the part starting at the 1480b57cec5SDimitry Andric /// iterator. This returns the new MBB. 1490b57cec5SDimitry Andric MachineBasicBlock *SplitMBBAt(MachineBasicBlock &CurMBB, 1500b57cec5SDimitry Andric MachineBasicBlock::iterator BBI1, 1510b57cec5SDimitry Andric const BasicBlock *BB); 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric /// Look through all the blocks in MergePotentials that have hash CurHash 1540b57cec5SDimitry Andric /// (guaranteed to match the last element). Build the vector SameTails of 1550b57cec5SDimitry Andric /// all those that have the (same) largest number of instructions in common 1560b57cec5SDimitry Andric /// of any pair of these blocks. SameTails entries contain an iterator into 1570b57cec5SDimitry Andric /// MergePotentials (from which the MachineBasicBlock can be found) and a 1580b57cec5SDimitry Andric /// MachineBasicBlock::iterator into that MBB indicating the instruction 1590b57cec5SDimitry Andric /// where the matching code sequence begins. Order of elements in SameTails 1600b57cec5SDimitry Andric /// is the reverse of the order in which those blocks appear in 1610b57cec5SDimitry Andric /// MergePotentials (where they are not necessarily consecutive). 1620b57cec5SDimitry Andric unsigned ComputeSameTails(unsigned CurHash, unsigned minCommonTailLength, 1630b57cec5SDimitry Andric MachineBasicBlock *SuccBB, 1640b57cec5SDimitry Andric MachineBasicBlock *PredBB); 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric /// Remove all blocks with hash CurHash from MergePotentials, restoring 1670b57cec5SDimitry Andric /// branches at ends of blocks as appropriate. 1680b57cec5SDimitry Andric void RemoveBlocksWithHash(unsigned CurHash, MachineBasicBlock *SuccBB, 169*0fca6ea1SDimitry Andric MachineBasicBlock *PredBB, 170*0fca6ea1SDimitry Andric const DebugLoc &BranchDL); 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric /// None of the blocks to be tail-merged consist only of the common tail. 1730b57cec5SDimitry Andric /// Create a block that does by splitting one. 1740b57cec5SDimitry Andric bool CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB, 1750b57cec5SDimitry Andric MachineBasicBlock *SuccBB, 1760b57cec5SDimitry Andric unsigned maxCommonTailLength, 1770b57cec5SDimitry Andric unsigned &commonTailIndex); 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric /// Create merged DebugLocs of identical instructions across SameTails and 1800b57cec5SDimitry Andric /// assign it to the instruction in common tail; merge MMOs and undef flags. 1810b57cec5SDimitry Andric void mergeCommonTails(unsigned commonTailIndex); 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric bool OptimizeBranches(MachineFunction &MF); 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric /// Analyze and optimize control flow related to the specified block. This 1860b57cec5SDimitry Andric /// is never called on the entry block. 1870b57cec5SDimitry Andric bool OptimizeBlock(MachineBasicBlock *MBB); 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric /// Remove the specified dead machine basic block from the function, 1900b57cec5SDimitry Andric /// updating the CFG. 1910b57cec5SDimitry Andric void RemoveDeadBlock(MachineBasicBlock *MBB); 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric /// Hoist common instruction sequences at the start of basic blocks to their 1940b57cec5SDimitry Andric /// common predecessor. 1950b57cec5SDimitry Andric bool HoistCommonCode(MachineFunction &MF); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric /// If the successors of MBB has common instruction sequence at the start of 1980b57cec5SDimitry Andric /// the function, move the instructions before MBB terminator if it's legal. 1990b57cec5SDimitry Andric bool HoistCommonCodeInSuccs(MachineBasicBlock *MBB); 2000b57cec5SDimitry Andric }; 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric } // end namespace llvm 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_BRANCHFOLDING_H 205