#include "BranchFolding.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/MBFIWrapper.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineSizeOpts.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <cassert>
#include <cstddef>
#include <iterator>
#include <numeric>
usingnamespacellvm;
#define DEBUG_TYPE …
STATISTIC(NumDeadBlocks, "Number of dead blocks removed");
STATISTIC(NumBranchOpts, "Number of branches optimized");
STATISTIC(NumTailMerge , "Number of block tails merged");
STATISTIC(NumHoist , "Number of times common instructions are hoisted");
STATISTIC(NumTailCalls, "Number of tail calls optimized");
static cl::opt<cl::boolOrDefault> FlagEnableTailMerge("enable-tail-merge",
cl::init(cl::BOU_UNSET), cl::Hidden);
static cl::opt<unsigned>
TailMergeThreshold("tail-merge-threshold",
cl::desc("Max number of predecessors to consider tail merging"),
cl::init(150), cl::Hidden);
static cl::opt<unsigned>
TailMergeSize("tail-merge-size",
cl::desc("Min number of instructions to consider tail merging"),
cl::init(3), cl::Hidden);
namespace {
class BranchFolderPass : public MachineFunctionPass { … };
}
char BranchFolderPass::ID = …;
char &llvm::BranchFolderPassID = …;
INITIALIZE_PASS(…)
bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) { … }
BranchFolder::BranchFolder(bool DefaultEnableTailMerge, bool CommonHoist,
MBFIWrapper &FreqInfo,
const MachineBranchProbabilityInfo &ProbInfo,
ProfileSummaryInfo *PSI, unsigned MinTailLength)
: … { … }
void BranchFolder::RemoveDeadBlock(MachineBasicBlock *MBB) { … }
bool BranchFolder::OptimizeFunction(MachineFunction &MF,
const TargetInstrInfo *tii,
const TargetRegisterInfo *tri,
MachineLoopInfo *mli, bool AfterPlacement) { … }
static unsigned HashMachineInstr(const MachineInstr &MI) { … }
static unsigned HashEndOfMBB(const MachineBasicBlock &MBB) { … }
static bool countsAsInstruction(const MachineInstr &MI) { … }
static MachineBasicBlock::iterator
skipBackwardPastNonInstructions(MachineBasicBlock::iterator I,
MachineBasicBlock *MBB) { … }
static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
MachineBasicBlock *MBB2,
MachineBasicBlock::iterator &I1,
MachineBasicBlock::iterator &I2) { … }
void BranchFolder::replaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
MachineBasicBlock &NewDest) { … }
MachineBasicBlock *BranchFolder::SplitMBBAt(MachineBasicBlock &CurMBB,
MachineBasicBlock::iterator BBI1,
const BasicBlock *BB) { … }
static unsigned EstimateRuntime(MachineBasicBlock::iterator I,
MachineBasicBlock::iterator E) { … }
static void FixTail(MachineBasicBlock *CurMBB, MachineBasicBlock *SuccBB,
const TargetInstrInfo *TII, const DebugLoc &BranchDL) { … }
bool
BranchFolder::MergePotentialsElt::operator<(const MergePotentialsElt &o) const { … }
static unsigned CountTerminators(MachineBasicBlock *MBB,
MachineBasicBlock::iterator &I) { … }
static bool blockEndsInUnreachable(const MachineBasicBlock *MBB) { … }
static bool
ProfitableToMerge(MachineBasicBlock *MBB1, MachineBasicBlock *MBB2,
unsigned MinCommonTailLength, unsigned &CommonTailLen,
MachineBasicBlock::iterator &I1,
MachineBasicBlock::iterator &I2, MachineBasicBlock *SuccBB,
MachineBasicBlock *PredBB,
DenseMap<const MachineBasicBlock *, int> &EHScopeMembership,
bool AfterPlacement,
MBFIWrapper &MBBFreqInfo,
ProfileSummaryInfo *PSI) { … }
unsigned BranchFolder::ComputeSameTails(unsigned CurHash,
unsigned MinCommonTailLength,
MachineBasicBlock *SuccBB,
MachineBasicBlock *PredBB) { … }
void BranchFolder::RemoveBlocksWithHash(unsigned CurHash,
MachineBasicBlock *SuccBB,
MachineBasicBlock *PredBB,
const DebugLoc &BranchDL) { … }
bool BranchFolder::CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB,
MachineBasicBlock *SuccBB,
unsigned maxCommonTailLength,
unsigned &commonTailIndex) { … }
static void
mergeOperations(MachineBasicBlock::iterator MBBIStartPos,
MachineBasicBlock &MBBCommon) { … }
void BranchFolder::mergeCommonTails(unsigned commonTailIndex) { … }
bool BranchFolder::TryTailMergeBlocks(MachineBasicBlock *SuccBB,
MachineBasicBlock *PredBB,
unsigned MinCommonTailLength) { … }
bool BranchFolder::TailMergeBlocks(MachineFunction &MF) { … }
void BranchFolder::setCommonTailEdgeWeights(MachineBasicBlock &TailMBB) { … }
bool BranchFolder::OptimizeBranches(MachineFunction &MF) { … }
static bool IsEmptyBlock(MachineBasicBlock *MBB) { … }
static bool IsBranchOnlyBlock(MachineBasicBlock *MBB) { … }
static bool IsBetterFallthrough(MachineBasicBlock *MBB1,
MachineBasicBlock *MBB2) { … }
static DebugLoc getBranchDebugLoc(MachineBasicBlock &MBB) { … }
static void copyDebugInfoToPredecessor(const TargetInstrInfo *TII,
MachineBasicBlock &MBB,
MachineBasicBlock &PredMBB) { … }
static void copyDebugInfoToSuccessor(const TargetInstrInfo *TII,
MachineBasicBlock &MBB,
MachineBasicBlock &SuccMBB) { … }
static void salvageDebugInfoFromEmptyBlock(const TargetInstrInfo *TII,
MachineBasicBlock &MBB) { … }
bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { … }
bool BranchFolder::HoistCommonCode(MachineFunction &MF) { … }
static MachineBasicBlock *findFalseBlock(MachineBasicBlock *BB,
MachineBasicBlock *TrueBB) { … }
template <class Container>
static void addRegAndItsAliases(Register Reg, const TargetRegisterInfo *TRI,
Container &Set) { … }
static
MachineBasicBlock::iterator findHoistingInsertPosAndDeps(MachineBasicBlock *MBB,
const TargetInstrInfo *TII,
const TargetRegisterInfo *TRI,
SmallSet<Register, 4> &Uses,
SmallSet<Register, 4> &Defs) { … }
bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) { … }