109467b48Spatrick //===- BranchFolding.h - Fold machine code branch instructions --*- C++ -*-===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick 909467b48Spatrick #ifndef LLVM_LIB_CODEGEN_BRANCHFOLDING_H 1009467b48Spatrick #define LLVM_LIB_CODEGEN_BRANCHFOLDING_H 1109467b48Spatrick 1209467b48Spatrick #include "llvm/ADT/DenseMap.h" 1309467b48Spatrick #include "llvm/ADT/SmallPtrSet.h" 1409467b48Spatrick #include "llvm/CodeGen/LivePhysRegs.h" 1509467b48Spatrick #include "llvm/CodeGen/MachineBasicBlock.h" 1609467b48Spatrick #include "llvm/Support/Compiler.h" 1709467b48Spatrick #include <vector> 1809467b48Spatrick 1909467b48Spatrick namespace llvm { 2009467b48Spatrick 2109467b48Spatrick class BasicBlock; 2209467b48Spatrick class MachineBranchProbabilityInfo; 2309467b48Spatrick class MachineFunction; 2409467b48Spatrick class MachineLoopInfo; 2509467b48Spatrick class MachineRegisterInfo; 26097a140dSpatrick class MBFIWrapper; 2709467b48Spatrick class ProfileSummaryInfo; 2809467b48Spatrick class TargetInstrInfo; 2909467b48Spatrick class TargetRegisterInfo; 3009467b48Spatrick 3109467b48Spatrick class LLVM_LIBRARY_VISIBILITY BranchFolder { 3209467b48Spatrick public: 33*73471bf0Spatrick explicit BranchFolder(bool DefaultEnableTailMerge, bool CommonHoist, 3409467b48Spatrick MBFIWrapper &FreqInfo, 3509467b48Spatrick const MachineBranchProbabilityInfo &ProbInfo, 3609467b48Spatrick ProfileSummaryInfo *PSI, 3709467b48Spatrick // Min tail length to merge. Defaults to commandline 3809467b48Spatrick // flag. Ignored for optsize. 3909467b48Spatrick unsigned MinTailLength = 0); 4009467b48Spatrick 4109467b48Spatrick /// Perhaps branch folding, tail merging and other CFG optimizations on the 4209467b48Spatrick /// given function. Block placement changes the layout and may create new 4309467b48Spatrick /// tail merging opportunities. 4409467b48Spatrick bool OptimizeFunction(MachineFunction &MF, const TargetInstrInfo *tii, 45097a140dSpatrick const TargetRegisterInfo *tri, 4609467b48Spatrick MachineLoopInfo *mli = nullptr, 4709467b48Spatrick bool AfterPlacement = false); 4809467b48Spatrick 4909467b48Spatrick private: 5009467b48Spatrick class MergePotentialsElt { 5109467b48Spatrick unsigned Hash; 5209467b48Spatrick MachineBasicBlock *Block; 5309467b48Spatrick 5409467b48Spatrick public: MergePotentialsElt(unsigned h,MachineBasicBlock * b)5509467b48Spatrick MergePotentialsElt(unsigned h, MachineBasicBlock *b) 5609467b48Spatrick : Hash(h), Block(b) {} 5709467b48Spatrick getHash()5809467b48Spatrick unsigned getHash() const { return Hash; } getBlock()5909467b48Spatrick MachineBasicBlock *getBlock() const { return Block; } 6009467b48Spatrick setBlock(MachineBasicBlock * MBB)6109467b48Spatrick void setBlock(MachineBasicBlock *MBB) { 6209467b48Spatrick Block = MBB; 6309467b48Spatrick } 6409467b48Spatrick 6509467b48Spatrick bool operator<(const MergePotentialsElt &) const; 6609467b48Spatrick }; 6709467b48Spatrick 6809467b48Spatrick using MPIterator = std::vector<MergePotentialsElt>::iterator; 6909467b48Spatrick 7009467b48Spatrick std::vector<MergePotentialsElt> MergePotentials; 7109467b48Spatrick SmallPtrSet<const MachineBasicBlock*, 2> TriedMerging; 7209467b48Spatrick DenseMap<const MachineBasicBlock *, int> EHScopeMembership; 7309467b48Spatrick 7409467b48Spatrick class SameTailElt { 7509467b48Spatrick MPIterator MPIter; 7609467b48Spatrick MachineBasicBlock::iterator TailStartPos; 7709467b48Spatrick 7809467b48Spatrick public: SameTailElt(MPIterator mp,MachineBasicBlock::iterator tsp)7909467b48Spatrick SameTailElt(MPIterator mp, MachineBasicBlock::iterator tsp) 8009467b48Spatrick : MPIter(mp), TailStartPos(tsp) {} 8109467b48Spatrick getMPIter()8209467b48Spatrick MPIterator getMPIter() const { 8309467b48Spatrick return MPIter; 8409467b48Spatrick } 8509467b48Spatrick getMergePotentialsElt()8609467b48Spatrick MergePotentialsElt &getMergePotentialsElt() const { 8709467b48Spatrick return *getMPIter(); 8809467b48Spatrick } 8909467b48Spatrick getTailStartPos()9009467b48Spatrick MachineBasicBlock::iterator getTailStartPos() const { 9109467b48Spatrick return TailStartPos; 9209467b48Spatrick } 9309467b48Spatrick getHash()9409467b48Spatrick unsigned getHash() const { 9509467b48Spatrick return getMergePotentialsElt().getHash(); 9609467b48Spatrick } 9709467b48Spatrick getBlock()9809467b48Spatrick MachineBasicBlock *getBlock() const { 9909467b48Spatrick return getMergePotentialsElt().getBlock(); 10009467b48Spatrick } 10109467b48Spatrick tailIsWholeBlock()10209467b48Spatrick bool tailIsWholeBlock() const { 10309467b48Spatrick return TailStartPos == getBlock()->begin(); 10409467b48Spatrick } 10509467b48Spatrick setBlock(MachineBasicBlock * MBB)10609467b48Spatrick void setBlock(MachineBasicBlock *MBB) { 10709467b48Spatrick getMergePotentialsElt().setBlock(MBB); 10809467b48Spatrick } 10909467b48Spatrick setTailStartPos(MachineBasicBlock::iterator Pos)11009467b48Spatrick void setTailStartPos(MachineBasicBlock::iterator Pos) { 11109467b48Spatrick TailStartPos = Pos; 11209467b48Spatrick } 11309467b48Spatrick }; 11409467b48Spatrick std::vector<SameTailElt> SameTails; 11509467b48Spatrick 11609467b48Spatrick bool AfterBlockPlacement; 11709467b48Spatrick bool EnableTailMerge; 11809467b48Spatrick bool EnableHoistCommonCode; 11909467b48Spatrick bool UpdateLiveIns; 12009467b48Spatrick unsigned MinCommonTailLength; 12109467b48Spatrick const TargetInstrInfo *TII; 12209467b48Spatrick const MachineRegisterInfo *MRI; 12309467b48Spatrick const TargetRegisterInfo *TRI; 12409467b48Spatrick MachineLoopInfo *MLI; 12509467b48Spatrick LivePhysRegs LiveRegs; 12609467b48Spatrick 12709467b48Spatrick private: 12809467b48Spatrick MBFIWrapper &MBBFreqInfo; 12909467b48Spatrick const MachineBranchProbabilityInfo &MBPI; 13009467b48Spatrick ProfileSummaryInfo *PSI; 13109467b48Spatrick 13209467b48Spatrick bool TailMergeBlocks(MachineFunction &MF); 13309467b48Spatrick bool TryTailMergeBlocks(MachineBasicBlock* SuccBB, 13409467b48Spatrick MachineBasicBlock* PredBB, 13509467b48Spatrick unsigned MinCommonTailLength); 13609467b48Spatrick void setCommonTailEdgeWeights(MachineBasicBlock &TailMBB); 13709467b48Spatrick 13809467b48Spatrick /// Delete the instruction OldInst and everything after it, replacing it 13909467b48Spatrick /// with an unconditional branch to NewDest. 14009467b48Spatrick void replaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, 14109467b48Spatrick MachineBasicBlock &NewDest); 14209467b48Spatrick 14309467b48Spatrick /// Given a machine basic block and an iterator into it, split the MBB so 14409467b48Spatrick /// that the part before the iterator falls into the part starting at the 14509467b48Spatrick /// iterator. This returns the new MBB. 14609467b48Spatrick MachineBasicBlock *SplitMBBAt(MachineBasicBlock &CurMBB, 14709467b48Spatrick MachineBasicBlock::iterator BBI1, 14809467b48Spatrick const BasicBlock *BB); 14909467b48Spatrick 15009467b48Spatrick /// Look through all the blocks in MergePotentials that have hash CurHash 15109467b48Spatrick /// (guaranteed to match the last element). Build the vector SameTails of 15209467b48Spatrick /// all those that have the (same) largest number of instructions in common 15309467b48Spatrick /// of any pair of these blocks. SameTails entries contain an iterator into 15409467b48Spatrick /// MergePotentials (from which the MachineBasicBlock can be found) and a 15509467b48Spatrick /// MachineBasicBlock::iterator into that MBB indicating the instruction 15609467b48Spatrick /// where the matching code sequence begins. Order of elements in SameTails 15709467b48Spatrick /// is the reverse of the order in which those blocks appear in 15809467b48Spatrick /// MergePotentials (where they are not necessarily consecutive). 15909467b48Spatrick unsigned ComputeSameTails(unsigned CurHash, unsigned minCommonTailLength, 16009467b48Spatrick MachineBasicBlock *SuccBB, 16109467b48Spatrick MachineBasicBlock *PredBB); 16209467b48Spatrick 16309467b48Spatrick /// Remove all blocks with hash CurHash from MergePotentials, restoring 16409467b48Spatrick /// branches at ends of blocks as appropriate. 16509467b48Spatrick void RemoveBlocksWithHash(unsigned CurHash, MachineBasicBlock* SuccBB, 16609467b48Spatrick MachineBasicBlock* PredBB); 16709467b48Spatrick 16809467b48Spatrick /// None of the blocks to be tail-merged consist only of the common tail. 16909467b48Spatrick /// Create a block that does by splitting one. 17009467b48Spatrick bool CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB, 17109467b48Spatrick MachineBasicBlock *SuccBB, 17209467b48Spatrick unsigned maxCommonTailLength, 17309467b48Spatrick unsigned &commonTailIndex); 17409467b48Spatrick 17509467b48Spatrick /// Create merged DebugLocs of identical instructions across SameTails and 17609467b48Spatrick /// assign it to the instruction in common tail; merge MMOs and undef flags. 17709467b48Spatrick void mergeCommonTails(unsigned commonTailIndex); 17809467b48Spatrick 17909467b48Spatrick bool OptimizeBranches(MachineFunction &MF); 18009467b48Spatrick 18109467b48Spatrick /// Analyze and optimize control flow related to the specified block. This 18209467b48Spatrick /// is never called on the entry block. 18309467b48Spatrick bool OptimizeBlock(MachineBasicBlock *MBB); 18409467b48Spatrick 18509467b48Spatrick /// Remove the specified dead machine basic block from the function, 18609467b48Spatrick /// updating the CFG. 18709467b48Spatrick void RemoveDeadBlock(MachineBasicBlock *MBB); 18809467b48Spatrick 18909467b48Spatrick /// Hoist common instruction sequences at the start of basic blocks to their 19009467b48Spatrick /// common predecessor. 19109467b48Spatrick bool HoistCommonCode(MachineFunction &MF); 19209467b48Spatrick 19309467b48Spatrick /// If the successors of MBB has common instruction sequence at the start of 19409467b48Spatrick /// the function, move the instructions before MBB terminator if it's legal. 19509467b48Spatrick bool HoistCommonCodeInSuccs(MachineBasicBlock *MBB); 19609467b48Spatrick }; 19709467b48Spatrick 19809467b48Spatrick } // end namespace llvm 19909467b48Spatrick 20009467b48Spatrick #endif // LLVM_LIB_CODEGEN_BRANCHFOLDING_H 201