19 #define DEBUG_TYPE "machine-sink"
37 cl::desc(
"Split critical edges during machine sinking"),
40 STATISTIC(NumSunk,
"Number of machine instructions sunk");
41 STATISTIC(NumSplit,
"Number of critical edges split");
42 STATISTIC(NumCoalesces,
"Number of copies coalesced");
75 virtual void releaseMemory() {
76 CEBCandidates.clear();
91 bool &BreakPHIEdge,
bool &LocalUse)
const;
103 struct SuccessorSorter {
107 return LI->getLoopDepth(LHS) <
LI->getLoopDepth(RHS);
116 "Machine code sinking",
false,
false)
123 bool MachineSinking::PerformTrivialForwardCoalescing(
MachineInstr *
MI,
128 unsigned SrcReg = MI->getOperand(1).getReg();
129 unsigned DstReg = MI->getOperand(0).getReg();
132 !
MRI->hasOneNonDBGUse(SrcReg))
143 DEBUG(
dbgs() <<
"Coalescing: " << *DefMI);
145 MRI->replaceRegWith(DstReg, SrcReg);
146 MI->eraseFromParent();
156 MachineSinking::AllUsesDominatedByBlock(
unsigned Reg,
160 bool &LocalUse)
const {
162 "Only makes sense for vregs");
165 if (
MRI->use_nodbg_empty(Reg))
185 I =
MRI->use_nodbg_begin(Reg), E =
MRI->use_nodbg_end();
189 if (!(UseBlock == MBB && UseInst->
isPHI() &&
190 UseInst->
getOperand(
I.getOperandNo()+1).getMBB() == DefMBB)) {
191 BreakPHIEdge =
false;
199 I =
MRI->use_nodbg_begin(Reg), E =
MRI->use_nodbg_end();
204 if (UseInst->
isPHI()) {
207 UseBlock = UseInst->
getOperand(
I.getOperandNo()+1).getMBB();
208 }
else if (UseBlock == DefMBB) {
214 if (!DT->dominates(MBB, UseBlock))
222 DEBUG(
dbgs() <<
"******** Machine Sinking ********\n");
228 DT = &getAnalysis<MachineDominatorTree>();
229 LI = &getAnalysis<MachineLoopInfo>();
230 AA = &getAnalysis<AliasAnalysis>();
232 bool EverMadeChange =
false;
235 bool MadeChange =
false;
238 CEBCandidates.clear();
241 MadeChange |= ProcessBlock(*
I);
244 if (!MadeChange)
break;
245 EverMadeChange =
true;
247 return EverMadeChange;
257 if (!DT->isReachableFromEntry(&MBB))
return false;
259 bool MadeChange =
false;
264 bool ProcessedBegin,
SawStore =
false;
270 ProcessedBegin = I == MBB.
begin();
277 bool Joined = PerformTrivialForwardCoalescing(MI, &MBB);
283 if (SinkInstruction(MI, SawStore))
284 ++NumSunk, MadeChange =
true;
287 }
while (!ProcessedBegin);
292 bool MachineSinking::isWorthBreakingCriticalEdge(
MachineInstr *MI,
300 if (!CEBCandidates.insert(std::make_pair(From, To)))
313 unsigned Reg = MO.
getReg();
325 if (
MRI->hasOneNonDBGUse(Reg)) {
343 if (!isWorthBreakingCriticalEdge(MI, FromBB, ToBB))
351 if (LI->getLoopFor(FromBB) == LI->getLoopFor(ToBB) &&
352 LI->isLoopHeader(ToBB))
396 E = ToBB->
pred_end(); PI != E; ++PI) {
399 if (!DT->dominates(ToBB, *PI))
422 if (!DI->isDebugValue())
424 if (DI->getOperand(0).isReg() &&
448 bool MachineSinking::isProfitableToSinkTo(
unsigned Reg,
MachineInstr *MI,
451 assert (MI &&
"Invalid MachineInstr!");
452 assert (SuccToSinkTo &&
"Invalid SinkTo Candidate BB");
454 if (MBB == SuccToSinkTo)
462 bool NonPHIUse =
false;
464 I =
MRI->use_nodbg_begin(Reg), E =
MRI->use_nodbg_end();
468 if (UseBlock == SuccToSinkTo && !UseInst->
isPHI())
476 bool BreakPHIEdge =
false;
479 return isProfitableToSinkTo(Reg, MI, SuccToSinkTo, MBB2);
489 bool &BreakPHIEdge) {
491 assert (MI &&
"Invalid MachineInstr!");
492 assert (MBB &&
"Invalid MachineBasicBlock!");
502 if (!MO.
isReg())
continue;
504 unsigned Reg = MO.
getReg();
505 if (Reg == 0)
continue;
514 }
else if (!MO.
isDead()) {
520 if (MO.
isUse())
continue;
544 bool LocalUse =
false;
545 if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, MBB,
546 BreakPHIEdge, LocalUse))
556 std::stable_sort(Succs.begin(), Succs.end(), SuccessorSorter(LI));
558 E = Succs.end(); SI != E; ++SI) {
560 bool LocalUse =
false;
561 if (AllUsesDominatedByBlock(Reg, SuccBlock, MBB,
562 BreakPHIEdge, LocalUse)) {
563 SuccToSinkTo = SuccBlock;
572 if (SuccToSinkTo == 0)
574 else if (!isProfitableToSinkTo(Reg, MI, MBB, SuccToSinkTo))
581 if (MBB == SuccToSinkTo)
594 bool MachineSinking::SinkInstruction(
MachineInstr *MI,
bool &SawStore) {
612 bool BreakPHIEdge =
false;
614 MachineBasicBlock *SuccToSinkTo = FindSuccToSinkTo(MI, ParentBlock, BreakPHIEdge);
617 if (SuccToSinkTo == 0)
626 if (!MO.
isReg())
continue;
627 unsigned Reg = MO.
getReg();
633 DEBUG(
dbgs() <<
"Sink instr " << *MI <<
"\tinto block " << *SuccToSinkTo);
640 bool TryBreak =
false;
643 DEBUG(
dbgs() <<
" *** NOTE: Won't sink load along critical edge.\n");
649 if (!TryBreak && !DT->dominates(ParentBlock, SuccToSinkTo)) {
650 DEBUG(
dbgs() <<
" *** NOTE: Critical edge found\n");
655 if (!TryBreak && LI->isLoopHeader(SuccToSinkTo)) {
656 DEBUG(
dbgs() <<
" *** NOTE: Loop header found\n");
662 DEBUG(
dbgs() <<
"Sinking along critical edge.\n");
667 DEBUG(
dbgs() <<
" *** PUNTING: Not legal or profitable to "
668 "break critical edge\n");
671 DEBUG(
dbgs() <<
" *** Splitting critical edge:"
674 <<
" -- BB#" << SuccToSinkTo->
getNumber() <<
'\n');
675 SuccToSinkTo = NewSucc;
677 BreakPHIEdge =
false;
687 SuccToSinkTo, BreakPHIEdge);
689 DEBUG(
dbgs() <<
" *** PUNTING: Not legal or profitable to "
690 "break critical edge\n");
694 DEBUG(
dbgs() <<
" *** Splitting critical edge:"
697 <<
" -- BB#" << SuccToSinkTo->
getNumber() <<
'\n');
698 SuccToSinkTo = NewSucc;
704 while (InsertPos != SuccToSinkTo->
end() && InsertPos->isPHI())
712 SuccToSinkTo->
splice(InsertPos, ParentBlock, MI,
717 DBE = DbgValuesToSink.
end(); DBI != DBE; ++DBI) {
719 SuccToSinkTo->
splice(InsertPos, ParentBlock, DbgMI,
unsigned succ_size() const
void push_back(const T &Elt)
const MachineFunction * getParent() const
STATISTIC(NumSunk,"Number of machine instructions sunk")
AnalysisUsage & addPreserved()
static PassRegistry * getPassRegistry()
BasicBlock * SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P=0, bool MergeIdenticalEdges=false, bool DontDeleteUselessPHIs=false, bool SplitLandingPads=false)
static bool isVirtualRegister(unsigned Reg)
machine Machine code sinking
LoopInfoBase< BlockT, LoopT > * LI
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
const HexagonInstrInfo * TII
INITIALIZE_PASS(DeadMachineInstructionElim,"dead-mi-elimination","Remove dead machine instructions", false, false) bool DeadMachineInstructionElim bool SawStore
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
std::vector< MachineBasicBlock * >::iterator succ_iterator
MachineBasicBlock * SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P)
ID
LLVM Calling Convention Representation.
unsigned getNumOperands() const
std::vector< MachineBasicBlock * >::iterator pred_iterator
COFF::MachineTypes Machine
const MachineBasicBlock * getParent() const
bool isDebugValue() const
bool isInsertSubreg() const
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
static bool AvoidsSinking(MachineInstr *MI, MachineRegisterInfo *MRI)
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value. See class MCOperandInfo.
bool isAsCheapAsAMove(QueryType Type=AllInBundle) const
const MachineOperand & getOperand(unsigned i) const
static bool isPostDominatedBy(MachineBasicBlock *A, MachineBasicBlock *B)
isPostDominatedBy - Return true if A is post dominated by B.
#define INITIALIZE_AG_DEPENDENCY(depName)
succ_iterator succ_begin()
pred_iterator pred_begin()
machine Machine code false
virtual const TargetInstrInfo * getInstrInfo() const
char & MachineSinkingID
MachineSinking - This pass performs sinking on machine instructions.
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
static void collectDebugValues(MachineInstr *MI, SmallVectorImpl< MachineInstr * > &DbgValues)
bool isSubregToReg() const
bool isSafeToMove(const TargetInstrInfo *TII, AliasAnalysis *AA, bool &SawStore) const
static bool isPhysicalRegister(unsigned Reg)
bool isLandingPad() const
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
bool isLiveIn(unsigned Reg) const
MachineRegisterInfo & getRegInfo()
virtual void getAnalysisUsage(AnalysisUsage &AU) const
void initializeMachineSinkingPass(PassRegistry &)
INITIALIZE_PASS_BEGIN(MachineSinking,"machine-sink","Machine code sinking", false, false) INITIALIZE_PASS_END(MachineSinking
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
unsigned getReg() const
getReg - Returns the register number.
static cl::opt< bool > SplitEdges("machine-sink-split", cl::desc("Split critical edges during machine sinking"), cl::init(true), cl::Hidden)
BasicBlockListType::iterator iterator
const MCRegisterInfo & MRI
bool isRegSequence() const
unsigned pred_size() const