48 #define DEBUG_TYPE "tailduplication" 50 STATISTIC(NumTails,
"Number of tails duplicated");
51 STATISTIC(NumTailDups,
"Number of tail duplicated blocks");
53 "Number of instructions added due to tail duplication");
55 "Number of instructions removed due to tail duplication");
56 STATISTIC(NumDeadBlocks,
"Number of dead blocks removed");
57 STATISTIC(NumAddedPHIs,
"Number of phis added");
66 "tail-dup-indirect-size",
67 cl::desc(
"Maximum instructions to consider tail duplicating blocks that " 68 "end with indirect branches."),
cl::init(20),
73 cl::desc(
"Verify sanity of PHI instructions during taildup"),
81 bool LayoutModeIn,
unsigned TailDupSizeIn) {
88 TailDupSize = TailDupSizeIn;
90 assert(MBPI !=
nullptr &&
"Machine Branch Probability Info required");
92 LayoutMode = LayoutModeIn;
93 this->PreRegAlloc = PreRegAlloc;
102 while (MI != MBB->
end()) {
107 for (
unsigned i = 1, e = MI->getNumOperands(); i != e; i += 2) {
109 if (PHIBB == PredBB) {
117 dbgs() <<
" missing input from predecessor " 123 for (
unsigned i = 1, e = MI->getNumOperands(); i != e; i += 2) {
125 if (CheckExtra && !Preds.count(PHIBB)) {
128 dbgs() <<
" extra input from predecessor " 163 if (!tailDuplicate(IsSimple, MBB, ForcedLayoutPred, TDBBs, Copies))
176 updateSuccessorsPHIs(MBB, isDead, TDBBs, Succs);
180 NumTailDupRemoved += MBB->
size();
181 removeDeadBlock(MBB, RemovalCallback);
186 if (!SSAUpdateVRs.
empty()) {
187 for (
unsigned i = 0, e = SSAUpdateVRs.
size(); i != e; ++i) {
188 unsigned VReg = SSAUpdateVRs[i];
202 SSAUpdateVals.
find(VReg);
203 for (
unsigned j = 0, ee = LI->second.
size(); j != ee; ++j) {
205 unsigned SrcReg = LI->second[j].second;
229 SSAUpdateVRs.
clear();
230 SSAUpdateVals.
clear();
235 for (
unsigned i = 0, e = Copies.
size(); i != e; ++i) {
250 NumAddedPHIs += NewPHIs.
size();
253 *DuplicatedPreds = std::move(TDBBs);
262 bool MadeChange =
false;
292 if (
UseMI.isDebugValue())
294 if (
UseMI.getParent() != BB)
312 for (
const auto &
MI : BB) {
315 for (
unsigned i = 1, e =
MI.getNumOperands(); i != e; i += 2) {
316 unsigned SrcReg =
MI.getOperand(i).getReg();
317 UsedByPhi->
insert(SrcReg);
323 void TailDuplicator::addSSAUpdateEntry(
unsigned OrigReg,
unsigned NewReg,
326 SSAUpdateVals.
find(OrigReg);
327 if (LI != SSAUpdateVals.
end())
328 LI->second.push_back(std::make_pair(BB, NewReg));
331 Vals.push_back(std::make_pair(BB, NewReg));
332 SSAUpdateVals.
insert(std::make_pair(OrigReg, Vals));
339 void TailDuplicator::processPHI(
346 assert(SrcOpIdx &&
"Unable to find matching PHI source?");
357 addSSAUpdateEntry(DefReg, NewDef, PredBB);
371 void TailDuplicator::duplicateInstruction(
378 TII->
get(TargetOpcode::CFI_INSTRUCTION)).addCFIIndex(
397 addSSAUpdateEntry(Reg, NewReg, PredBB);
399 auto VI = LocalVRMap.
find(Reg);
400 if (
VI != LocalVRMap.
end()) {
407 if (
VI->second.SubReg != 0) {
435 if (NewRC ==
nullptr)
439 TII->
get(TargetOpcode::COPY), NewReg)
440 .addReg(
VI->second.Reg, 0,
VI->second.SubReg);
461 void TailDuplicator::updateSuccessorsPHIs(
473 if (MO.
getMBB() == FromBB) {
488 if (MO.
getMBB() == FromBB) {
500 SSAUpdateVals.
find(Reg);
501 if (LI != SSAUpdateVals.
end()) {
503 for (
unsigned j = 0, ee = LI->second.
size(); j != ee; ++j) {
512 unsigned SrcReg = LI->second[j].second;
518 MIB.addReg(SrcReg).addMBB(SrcBB);
523 for (
unsigned j = 0, ee = TDBBs.
size(); j != ee; ++j) {
530 MIB.addReg(Reg).addMBB(SrcBB);
558 unsigned MaxDuplicateCount;
559 if (TailDupSize == 0 &&
562 MaxDuplicateCount = 1;
563 else if (TailDupSize == 0)
566 MaxDuplicateCount = TailDupSize;
574 if (TII->
analyzeBranch(TailBB, PredTBB, PredFBB, PredCond) &&
584 bool HasIndirectbr =
false;
588 if (HasIndirectbr && PreRegAlloc)
601 (TailBB.getParent()->getTarget().getTargetTriple().isOSDarwin() ||
619 if (PreRegAlloc && MI.
isCall())
625 if (InstrCount > MaxDuplicateCount)
638 for (
auto SB : TailBB.successors()) {
639 for (
auto &
I : *SB) {
650 if (HasIndirectbr && PreRegAlloc)
659 return canCompletelyDuplicateBB(TailBB);
669 if (I == TailBB->
end())
671 return I->isUnconditionalBranch();
693 if (!PredCond.
empty())
699 bool TailDuplicator::duplicateSimpleBB(
707 bool Changed =
false;
721 LLVM_DEBUG(
dbgs() <<
"\nTail-duplicating into PredBB: " << *PredBB
722 <<
"From simple Succ: " << *TailBB);
728 if (PredCond.
empty())
738 if (PredFBB == TailBB)
740 if (PredTBB == TailBB)
744 if (PredTBB == PredFBB) {
750 if (PredFBB == NextBB)
752 if (PredTBB == NextBB && PredFBB ==
nullptr)
766 TII->
insertBranch(*PredBB, PredTBB, PredFBB, PredCond, DL);
783 if (!PredCond.
empty())
809 return duplicateSimpleBB(TailBB, TDBBs, UsedByPhi, Copies);
814 bool Changed =
false;
818 assert(TailBB != PredBB &&
819 "Single-block loop should have been rejected earlier!");
825 bool IsLayoutSuccessor =
false;
826 if (ForcedLayoutPred)
827 IsLayoutSuccessor = (ForcedLayoutPred == PredBB);
829 IsLayoutSuccessor =
true;
830 if (IsLayoutSuccessor)
833 LLVM_DEBUG(
dbgs() <<
"\nTail-duplicating into PredBB: " << *PredBB
834 <<
"From Succ: " << *TailBB);
851 processPHI(MI, TailBB, PredBB, LocalVRMap, CopyInfos, UsedByPhi,
true);
855 duplicateInstruction(MI, TailBB, PredBB, LocalVRMap, UsedByPhi);
858 appendCopies(PredBB, CopyInfos, Copies);
865 NumTailDupAdded += TailBB->
size() - 1;
870 "TailDuplicate called on block with multiple successors!");
891 !TII->
analyzeBranch(*PrevBB, PriorTBB, PriorFBB, PriorCond) &&
893 (!PriorTBB || PriorTBB == TailBB) &&
897 <<
"From MBB: " << *TailBB);
907 while (I != TailBB->
end() && I->isPHI()) {
911 processPHI(MI, TailBB, PrevBB, LocalVRMap, CopyInfos, UsedByPhi,
true);
915 while (I != TailBB->
end()) {
919 assert(!MI->
isBundle() &&
"Not expecting bundles before regalloc!");
920 duplicateInstruction(MI, TailBB, PrevBB, LocalVRMap, UsedByPhi);
923 appendCopies(PrevBB, CopyInfos, Copies);
970 while (I != TailBB->
end() && I->isPHI()) {
974 processPHI(MI, TailBB, PredBB, LocalVRMap, CopyInfos, UsedByPhi,
false);
976 appendCopies(PredBB, CopyInfos, Copies);
989 for (
auto &CI : CopyInfos) {
991 .
addReg(CI.second.Reg, 0, CI.second.SubReg);
998 void TailDuplicator::removeDeadBlock(
1004 if (RemovalCallback)
1005 (*RemovalCallback)(MBB);
bool shouldTailDuplicate(bool IsSimple, MachineBasicBlock &TailBB)
Determine if it is profitable to duplicate this block.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
bool isCall(QueryType Type=AnyInBundle) const
static cl::opt< unsigned > TailDuplicateSize("tail-dup-size", cl::desc("Maximum instructions to consider tail duplicating"), cl::init(2), cl::Hidden)
MachineBasicBlock * getMBB() const
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This class represents lattice values for constants.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool isCFIInstruction() const
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
iterator getFirstNonDebugInstr()
Returns an iterator to the first non-debug instruction in the basic block, or end().
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Describe properties that are true of each instruction in the target description file.
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
virtual MachineInstr & duplicate(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) const
Clones instruction or the whole instruction bundle Orig and insert into MBB before InsertBefore...
void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
unsigned getSubReg() const
static void VerifyPHIs(MachineFunction &MF, bool CheckExtra)
virtual unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const
Insert branch code into the end of the specified MachineBasicBlock.
An efficient, type-erasing, non-owning reference to a callable.
STATISTIC(NumFunctions, "Total number of functions")
void RewriteUse(MachineOperand &U)
RewriteUse - Rewrite a use of the symbolic value.
MachineModuleInfo & getMMI() const
static unsigned InstrCount
bool isMetaInstruction() const
Return true if this instruction doesn't produce any output in the form of executable instructions...
virtual unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const
Remove the branching code at the end of the specific MBB.
MachineSSAUpdater - This class updates SSA form for a set of virtual registers defined in multiple bl...
iterator_range< succ_iterator > successors()
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
static use_iterator use_end()
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
const TargetRegisterClass * getRegClassConstraint(unsigned OpIdx, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
Compute the static register class constraint for operand OpIdx.
unsigned getNumOperands() const
Retuns the total number of operands.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
static bool bothUsedInPHI(const MachineBasicBlock &A, const SmallPtrSet< MachineBasicBlock *, 8 > &SuccsB)
bool hasEHPadSuccessor() const
unsigned getCFIIndex() const
bool tailDuplicateBlocks()
Look for small blocks that are unconditionally branched to and do not fall through.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
bool isIndirectBranch(QueryType Type=AnyInBundle) const
Return true if this is an indirect branch, such as a branch through a register.
bool canFallThrough()
Return true if the block can implicitly transfer control to the block after it by falling off the end...
void initMF(MachineFunction &MF, bool PreRegAlloc, const MachineBranchProbabilityInfo *MBPI, bool LayoutMode, unsigned TailDupSize=0)
Prepare to run on a specific machine function.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
virtual const TargetInstrInfo * getInstrInfo() const
void Initialize(unsigned V)
Initialize - Reset this object to get ready for a new set of SSA updates.
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
iterator find(const_arg_type_t< KeyT > Val)
bool isReturn(QueryType Type=AnyInBundle) const
static bool isSimpleBB(MachineBasicBlock *TailBB)
True if this BB has only one unconditional jump.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool tailDuplicateAndUpdate(bool IsSimple, MachineBasicBlock *MBB, MachineBasicBlock *ForcedLayoutPred, SmallVectorImpl< MachineBasicBlock *> *DuplicatedPreds=nullptr, function_ref< void(MachineBasicBlock *)> *RemovalCallback=nullptr)
Tail duplicate a single basic block into its predecessors, and then clean up.
initializer< Ty > init(const Ty &Val)
bool erase(const KeyT &Val)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineInstrBuilder & UseMI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE and DBG_LABEL instructions...
unsigned composeSubRegIndices(unsigned a, unsigned b) const
Return the subregister index you get from composing two subregister indices.
std::pair< iterator, bool > insert(const ValueT &V)
bool canTailDuplicate(MachineBasicBlock *TailBB, MachineBasicBlock *PredBB)
Returns true if TailBB can successfully be duplicated into PredBB.
void setMBB(MachineBasicBlock *MBB)
bool optForSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
virtual const TargetRegisterClass * getMatchingSuperRegClass(const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned Idx) const
Return a subclass of the specified register class A so that each register in it has a sub-register of...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
self_iterator getIterator()
iterator_range< pred_iterator > predecessors()
succ_iterator succ_begin()
bool hasAddressTaken() const
Test whether this block is potentially the target of an indirect branch.
bool isConvergent(QueryType Type=AnyInBundle) const
Return true if this instruction is convergent.
virtual bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e...
pred_iterator pred_begin()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setIsKill(bool Val=true)
A SetVector that performs no allocations if smaller than a certain size.
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
static bool isDefLiveOut(unsigned Reg, MachineBasicBlock *BB, const MachineRegisterInfo *MRI)
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
A pair composed of a register and a sub-register index.
MachineInstrBuilder MachineInstrBuilder & DefMI
static unsigned getPHISrcRegOpIdx(MachineInstr *MI, MachineBasicBlock *SrcBB)
unsigned pred_size() const
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static cl::opt< unsigned > TailDupLimit("tail-dup-limit", cl::init(~0U), cl::Hidden)
void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
DebugLoc findBranchDebugLoc()
Find and return the merged DebugLoc of the branch instructions of the block.
void replaceRegWith(unsigned FromReg, unsigned ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
unsigned succ_size() const
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
use_iterator use_begin(unsigned RegNo) const
LLVM_NODISCARD bool empty() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
void setReg(unsigned Reg)
Change the register this operand corresponds to.
void setSubReg(unsigned subReg)
void AddAvailableValue(MachineBasicBlock *BB, unsigned V)
AddAvailableValue - Indicate that a rewritten value is available at the end of the specified block wi...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
iterator_range< use_instr_iterator > use_instructions(unsigned Reg) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static cl::opt< unsigned > TailDupIndirectBranchSize("tail-dup-indirect-size", cl::desc("Maximum instructions to consider tail duplicating blocks that " "end with indirect branches."), cl::init(20), cl::Hidden)
void setRegClass(unsigned Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const MachineOperand & getOperand(unsigned i) const
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
static void getRegsUsedByPHIs(const MachineBasicBlock &BB, DenseSet< unsigned > *UsedByPhi)
static cl::opt< bool > TailDupVerify("tail-dup-verify", cl::desc("Verify sanity of PHI instructions during taildup"), cl::init(false), cl::Hidden)
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool isNotDuplicable(QueryType Type=AnyInBundle) const
Return true if this instruction cannot be safely duplicated.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.