xref: /openbsd-src/gnu/llvm/llvm/lib/CodeGen/BranchFolding.h (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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