56 #define DEBUG_TYPE "machine-sink" 60 cl::desc(
"Split critical edges during machine sinking"),
65 cl::desc(
"Use block frequency info to find successors to sink"),
69 "machine-sink-split-probability-threshold",
71 "Percentage threshold for splitting single-instruction critical edge. " 72 "If the branch threshold is higher than this threshold, we allow " 73 "speculative execution of up to 1 instruction to avoid branching to " 74 "splitted critical edge"),
77 STATISTIC(NumSunk,
"Number of machine instructions sunk");
78 STATISTIC(NumSplit,
"Number of critical edges split");
79 STATISTIC(NumCoalesces,
"Number of copies coalesced");
80 STATISTIC(NumPostRACopySink,
"Number of copies sunk after RA");
105 using AllSuccsCache =
106 std::map<MachineBasicBlock *, SmallVector<MachineBasicBlock *, 4>>;
132 void releaseMemory()
override {
133 CEBCandidates.
clear();
160 AllSuccsCache &AllSuccessors);
163 bool &BreakPHIEdge,
bool &LocalUse)
const;
165 bool &BreakPHIEdge, AllSuccsCache &AllSuccessors);
169 AllSuccsCache &AllSuccessors);
176 AllSuccsCache &AllSuccessors)
const;
186 "Machine code sinking",
false,
false)
194 bool MachineSinking::PerformTrivialForwardCoalescing(
MachineInstr &
MI,
199 unsigned SrcReg = MI.getOperand(1).getReg();
200 unsigned DstReg = MI.getOperand(0).getReg();
217 MI.eraseFromParent();
236 bool &LocalUse)
const {
238 "Only makes sense for vregs");
262 unsigned OpNo = &MO - &UseInst->
getOperand(0);
264 if (!(UseBlock == MBB && UseInst->
isPHI() &&
266 BreakPHIEdge =
false;
276 unsigned OpNo = &MO - &UseInst->
getOperand(0);
278 if (UseInst->
isPHI()) {
282 }
else if (UseBlock == DefMBB) {
304 DT = &getAnalysis<MachineDominatorTree>();
305 PDT = &getAnalysis<MachinePostDominatorTree>();
306 LI = &getAnalysis<MachineLoopInfo>();
307 MBFI =
UseBlockFreqInfo ? &getAnalysis<MachineBlockFrequencyInfo>() :
nullptr;
308 MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
309 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
311 bool EverMadeChange =
false;
314 bool MadeChange =
false;
317 CEBCandidates.
clear();
323 for (
auto &Pair : ToSplit) {
324 auto NewSucc = Pair.first->SplitCriticalEdge(Pair.second, *
this);
325 if (NewSucc !=
nullptr) {
336 if (!MadeChange)
break;
337 EverMadeChange =
true;
341 for (
auto I : RegsToClearKillFlags)
343 RegsToClearKillFlags.clear();
345 return EverMadeChange;
357 bool MadeChange =
false;
360 AllSuccsCache AllSuccessors;
365 bool ProcessedBegin, SawStore =
false;
371 ProcessedBegin = I == MBB.
begin();
378 bool Joined = PerformTrivialForwardCoalescing(MI, &MBB);
390 }
while (!ProcessedBegin);
395 bool MachineSinking::isWorthBreakingCriticalEdge(
MachineInstr &
MI,
403 if (!CEBCandidates.
insert(std::make_pair(From, To)).second)
420 unsigned Reg = MO.
getReg();
446 bool MachineSinking::PostponeSplitCriticalEdge(
MachineInstr &MI,
450 if (!isWorthBreakingCriticalEdge(MI, FromBB, ToBB))
511 ToSplit.
insert(std::make_pair(FromBB, ToBB));
517 bool MachineSinking::isProfitableToSinkTo(
unsigned Reg,
MachineInstr &MI,
520 AllSuccsCache &AllSuccessors) {
521 assert (SuccToSinkTo &&
"Invalid SinkTo Candidate BB");
523 if (MBB == SuccToSinkTo)
536 bool NonPHIUse =
false;
539 if (UseBlock == SuccToSinkTo && !UseInst.isPHI())
547 bool BreakPHIEdge =
false;
550 FindSuccToSinkTo(MI, SuccToSinkTo, BreakPHIEdge, AllSuccessors))
551 return isProfitableToSinkTo(Reg, MI, SuccToSinkTo, MBB2, AllSuccessors);
562 AllSuccsCache &AllSuccessors)
const {
564 auto Succs = AllSuccessors.find(MBB);
565 if (Succs != AllSuccessors.end())
566 return Succs->second;
578 const std::vector<MachineDomTreeNode *> &Children =
580 for (
const auto &DTChild : Children)
582 if (DTChild->getIDom()->getBlock() == MI.
getParent() &&
585 AllSuccs.push_back(DTChild->getBlock());
589 AllSuccs.begin(), AllSuccs.end(),
593 bool HasBlockFreq = LHSFreq != 0 && RHSFreq != 0;
594 return HasBlockFreq ? LHSFreq < RHSFreq
598 auto it = AllSuccessors.insert(std::make_pair(MBB, AllSuccs));
600 return it.first->second;
607 AllSuccsCache &AllSuccessors) {
608 assert (MBB &&
"Invalid MachineBasicBlock!");
618 if (!MO.
isReg())
continue;
620 unsigned Reg = MO.
getReg();
621 if (Reg == 0)
continue;
630 }
else if (!MO.
isDead()) {
636 if (MO.
isUse())
continue;
647 bool LocalUse =
false;
649 BreakPHIEdge, LocalUse))
660 GetAllSortedSuccessors(MI, MBB, AllSuccessors)) {
661 bool LocalUse =
false;
663 BreakPHIEdge, LocalUse)) {
664 SuccToSinkTo = SuccBlock;
675 if (!isProfitableToSinkTo(Reg, MI, MBB, SuccToSinkTo, AllSuccessors))
682 if (MBB == SuccToSinkTo)
687 if (SuccToSinkTo && SuccToSinkTo->
isEHPad())
710 auto *PredBB = PredMBB->getBasicBlock();
724 if (!BaseOp->
isReg())
730 MachineBranchPredicate MBP;
734 return MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 &&
737 MBP.LHS.getReg() == BaseOp->
getReg();
749 DbgVals->begin(), DbgVals->end());
756 if (!SuccToSinkTo.
empty() && InsertPos != SuccToSinkTo.
end())
758 InsertPos->getDebugLoc()));
764 SuccToSinkTo.
splice(InsertPos, ParentBlock, MI,
769 DBE = DbgValuesToSink.
end();
772 SuccToSinkTo.
splice(InsertPos, ParentBlock, DbgMI,
780 AllSuccsCache &AllSuccessors) {
807 bool BreakPHIEdge =
false;
810 FindSuccToSinkTo(MI, ParentBlock, BreakPHIEdge, AllSuccessors);
821 if (!MO.
isReg())
continue;
822 unsigned Reg = MO.
getReg();
828 LLVM_DEBUG(
dbgs() <<
"Sink instr " << MI <<
"\tinto block " << *SuccToSinkTo);
835 bool TryBreak =
false;
838 LLVM_DEBUG(
dbgs() <<
" *** NOTE: Won't sink load along critical edge.\n");
844 if (!TryBreak && !DT->
dominates(ParentBlock, SuccToSinkTo)) {
863 PostponeSplitCriticalEdge(MI, ParentBlock, SuccToSinkTo, BreakPHIEdge);
866 "break critical edge\n");
876 bool Status = PostponeSplitCriticalEdge(MI, ParentBlock,
877 SuccToSinkTo, BreakPHIEdge);
880 "break critical edge\n");
887 while (InsertPos != SuccToSinkTo->
end() && InsertPos->isPHI())
898 if (MO.isReg() && MO.isUse())
899 RegsToClearKillFlags.
set(MO.getReg());
947 StringRef getPassName()
const override {
return "PostRA Machine Sink"; }
977 "PostRA Machine Sink",
false,
false)
992 for (
auto *
SI : SinkableBBs) {
993 if (aliasWithRegsInLiveIn(*
SI, Reg, TRI)) {
1007 if (!SinkableBBs.count(
SI) && aliasWithRegsInLiveIn(*
SI, Reg, TRI))
1019 for (
auto DefReg : DefedRegsInCopy) {
1022 if (!BB || (SingleBB && SingleBB != BB))
1033 for (
auto U : UsedOpsInCopy) {
1035 unsigned SrcReg = MO.
getReg();
1039 if (UI.killsRegister(SrcReg, TRI)) {
1040 UI.clearRegisterKills(SrcReg, TRI);
1054 for (
unsigned DefReg : DefedRegsInCopy)
1057 for (
auto U : UsedOpsInCopy) {
1069 bool HasRegDependency =
false;
1074 unsigned Reg = MO.
getReg();
1079 HasRegDependency =
true;
1088 }
else if (MO.
isUse()) {
1090 HasRegDependency =
true;
1096 return HasRegDependency;
1108 if (!
SI->livein_empty() &&
SI->pred_size() == 1)
1111 if (SinkableBBs.
empty())
1114 bool Changed =
false;
1118 ModifiedRegUnits.clear();
1119 UsedRegUnits.clear();
1120 SeenDbgInstrs.clear();
1139 ModifiedRegUnits, UsedRegUnits))
1143 SeenDbgInstrs[MO.getReg()].push_back(MI);
1163 ModifiedRegUnits, UsedRegUnits)) {
1169 "Unexpect SrcReg or DefReg");
1180 "Unexpected predecessor");
1185 if (!MO.isReg() || !MO.isDef())
1187 unsigned reg = MO.getReg();
1188 for (
auto *MI : SeenDbgInstrs.lookup(reg))
1196 performSink(*MI, *SuccBB, InsertPos, &DbgValsToSink);
1197 updateLiveIn(MI, SuccBB, UsedOpsInCopy, DefedRegsInCopy);
1200 ++NumPostRACopySink;
1205 bool PostRAMachineSinking::runOnMachineFunction(
MachineFunction &MF) {
1206 bool Changed =
false;
1210 ModifiedRegUnits.init(*TRI);
1211 UsedRegUnits.init(*TRI);
1213 Changed |= tryToSinkCopy(BB, MF, TRI, TII);
INITIALIZE_PASS_BEGIN(MachineSinking, DEBUG_TYPE, "Machine code sinking", false, false) INITIALIZE_PASS_END(MachineSinking
static void clearKillFlags(MachineInstr *MI, MachineBasicBlock &CurBB, SmallVectorImpl< unsigned > &UsedOpsInCopy, LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void collectDebugValues(SmallVectorImpl< MachineInstr *> &DbgValues)
Scan instructions following MI and collect any matching DBG_VALUEs.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool use_nodbg_empty(unsigned RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register...
static bool AllUsesDominatedByBlock(Instruction *Inst, BasicBlock *BB, DominatorTree &DT)
AllUsesDominatedByBlock - Return true if all uses of the specified value occur in blocks dominated by...
bool isCall(QueryType Type=AnyInBundle) const
MachineDomTreeNode * getNode(MachineBasicBlock *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
MachineBasicBlock * getMBB() const
virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const
Return true if it's safe to move a machine instruction that defines the specified register class...
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
This class represents lattice values for constants.
static const DILocation * getMergedLocation(const DILocation *LocA, const DILocation *LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
static void accumulateUsedDefed(const MachineInstr &MI, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)
For a machine instruction MI, adds all register units used in UsedRegUnits and defined or clobbered i...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
iterator_range< use_nodbg_iterator > use_nodbg_operands(unsigned Reg) const
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.
bool isPredicable(QueryType Type=AllInBundle) const
Return true if this instruction has a predicate operand that controls execution.
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
unsigned getLoopDepth(const MachineBasicBlock *BB) const
Return the loop nesting level of the specified block.
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
iterator_range< mop_iterator > operands()
bool isCopyLike() const
Return true if the instruction behaves like a copy.
void removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Remove the specified register from the live in set.
Represents a predicate at the MachineFunction level.
virtual bool getMemOperandWithOffset(MachineInstr &MI, MachineOperand *&BaseOp, int64_t &Offset, const TargetRegisterInfo *TRI) const
Get the base operand and byte offset of an instruction that reads/writes memory.
iterator_range< succ_iterator > successors()
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
unsigned getNumOperands() const
Retuns the total number of operands.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
void addLiveIns(const MachineBasicBlock &MBB)
Adds registers living into block MBB.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void clearKillFlags(unsigned Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
bool available(MCPhysReg Reg) const
Returns true if no part of physical register Reg is live.
const std::vector< DomTreeNodeBase * > & getChildren() const
COFF::MachineTypes Machine
virtual const TargetInstrInfo * getInstrInfo() const
static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
reverse_iterator rbegin()
TargetInstrInfo - Interface to description of machine instruction set.
initializer< Ty > init(const Ty &Val)
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
unsigned const MachineRegisterInfo * MRI
INITIALIZE_PASS(PostRAMachineSinking, "postra-machine-sink", "PostRA Machine Sink", false, false) static bool aliasWithRegsInLiveIn(MachineBasicBlock &MBB
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_NODISCARD bool empty() const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
char & PostRAMachineSinkingID
This pass perform post-ra machine sink for COPY instructions.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
Represent the analysis usage information of a pass.
static bool SinkInstruction(Instruction *Inst, SmallPtrSetImpl< Instruction *> &Stores, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
SinkInstruction - Determine whether it is safe to sink the specified machine instruction out of its c...
self_iterator getIterator()
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
static cl::opt< unsigned > SplitEdgeProbabilityThreshold("machine-sink-split-probability-threshold", cl::desc("Percentage threshold for splitting single-instruction critical edge. " "If the branch threshold is higher than this threshold, we allow " "speculative execution of up to 1 instruction to avoid branching to " "splitted critical edge"), cl::init(40), cl::Hidden)
virtual bool shouldSink(const MachineInstr &MI) const
Return true if the instruction should be sunk by MachineSink.
std::vector< MachineBasicBlock * >::iterator pred_iterator
succ_iterator succ_begin()
bool isConvergent(QueryType Type=AnyInBundle) const
Return true if this instruction is convergent.
static bool SinkingPreventsImplicitNullCheck(MachineInstr &MI, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
Return true if MI is likely to be usable as a memory operation by the implicit null check optimizatio...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MCSubRegIterator enumerates all sub-registers of Reg.
pred_iterator pred_begin()
bool isDebugInstr() const
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
bool isConstantPhysReg(unsigned PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
void setIsKill(bool Val=true)
virtual bool isAsCheapAsAMove(const MachineInstr &MI) const
Return true if the instruction is as cheap as a move instruction.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static cl::opt< bool > UseBlockFreqInfo("machine-sink-bfi", cl::desc("Use block frequency info to find successors to sink"), cl::init(true), cl::Hidden)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
BlockVerifier::State From
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
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...
char & MachineSinkingID
MachineSinking - This pass performs sinking on machine instructions.
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
MachineInstrBuilder MachineInstrBuilder & DefMI
void setPreservesCFG()
This function should be called by the pass, iff they do not:
unsigned pred_size() const
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.
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
void clear()
Completely clear the SetVector.
void setDebugLoc(DebugLoc dl)
Replace current source information with new such.
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
bool isRenamable() const
isRenamable - Returns true if this register may be renamed, i.e.
iterator insert(iterator I, T &&Elt)
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.
MachineFunctionProperties & set(Property P)
static MachineBasicBlock * getSingleLiveInSuccBB(MachineBasicBlock &CurBB, const SmallPtrSetImpl< MachineBasicBlock *> &SinkableBBs, unsigned Reg, const TargetRegisterInfo *TRI)
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
Representation of each machine instruction.
static void updateLiveIn(MachineInstr *MI, MachineBasicBlock *SuccBB, SmallVectorImpl< unsigned > &UsedOpsInCopy, SmallVectorImpl< unsigned > &DefedRegsInCopy)
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
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.
virtual bool analyzeBranchPredicate(MachineBasicBlock &MBB, MachineBranchPredicate &MBP, bool AllowModify=false) const
Analyze the branching code at the end of MBB and parse it into the MachineBranchPredicate structure i...
bool isEHPad() const
Returns true if the block is a landing pad.
LLVM_NODISCARD bool empty() const
void initializeMachineSinkingPass(PassRegistry &)
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
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...
A set of register units used to track register liveness.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isReachableFromEntry(const MachineBasicBlock *A)
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
static bool hasRegisterDependency(MachineInstr *MI, SmallVectorImpl< unsigned > &UsedOpsInCopy, SmallVectorImpl< unsigned > &DefedRegsInCopy, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits)
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static cl::opt< bool > SplitEdges("machine-sink-split", cl::desc("Split critical edges during machine sinking"), cl::init(true), cl::Hidden)
bool isLoopHeader(const MachineBasicBlock *BB) const
True if the block is a loop header node.
A vector that has set insertion semantics.
MachineLoop * getLoopFor(const MachineBasicBlock *BB) const
Return the innermost loop that BB lives in.
StringRef - Represent a constant reference to a string, i.e.
static void performSink(MachineInstr &MI, MachineBasicBlock &SuccToSinkTo, MachineBasicBlock::iterator InsertPos, SmallVectorImpl< MachineInstr *> *DbgVals=nullptr)
Sink an instruction and its associated debug instructions.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
const MachineOperand & getOperand(unsigned i) const
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(unsigned Reg) const
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool isSafeToMove(AliasAnalysis *AA, bool &SawStore) const
Return true if it is safe to move this instruction.
Properties which a MachineFunction may have at a given point in time.