xref: /src/contrib/llvm-project/llvm/lib/CodeGen/MachineLoopInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1009b1c42SEd Schouten //===- MachineLoopInfo.cpp - Natural Loop Calculator ----------------------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // This file defines the MachineLoopInfo class that is used to identify natural
10009b1c42SEd Schouten // loops and determine the loop depth of various nodes of the CFG.  Note that
11009b1c42SEd Schouten // the loops identified may actually be several natural loops that share the
12009b1c42SEd Schouten // same header node... not just a single natural loop.
13009b1c42SEd Schouten //
14009b1c42SEd Schouten //===----------------------------------------------------------------------===//
15009b1c42SEd Schouten 
16009b1c42SEd Schouten #include "llvm/CodeGen/MachineLoopInfo.h"
17009b1c42SEd Schouten #include "llvm/CodeGen/MachineDominators.h"
18b60736ecSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
19c0981da4SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
20b60736ecSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
21eb11fae6SDimitry Andric #include "llvm/Config/llvm-config.h"
22706b4fc4SDimitry Andric #include "llvm/InitializePasses.h"
23145449b1SDimitry Andric #include "llvm/Pass.h"
24145449b1SDimitry Andric #include "llvm/PassRegistry.h"
257fa27ce4SDimitry Andric #include "llvm/Support/GenericLoopInfoImpl.h"
26b60736ecSDimitry Andric 
27009b1c42SEd Schouten using namespace llvm;
28009b1c42SEd Schouten 
2958b69754SDimitry Andric // Explicitly instantiate methods in LoopInfoImpl.h for MI-level Loops.
3058b69754SDimitry Andric template class llvm::LoopBase<MachineBasicBlock, MachineLoop>;
3158b69754SDimitry Andric template class llvm::LoopInfoBase<MachineBasicBlock, MachineLoop>;
32009b1c42SEd Schouten 
33ac9a064cSDimitry Andric AnalysisKey MachineLoopAnalysis::Key;
34ac9a064cSDimitry Andric 
35ac9a064cSDimitry Andric MachineLoopAnalysis::Result
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)36ac9a064cSDimitry Andric MachineLoopAnalysis::run(MachineFunction &MF,
37ac9a064cSDimitry Andric                          MachineFunctionAnalysisManager &MFAM) {
38ac9a064cSDimitry Andric   return MachineLoopInfo(MFAM.getResult<MachineDominatorTreeAnalysis>(MF));
39706b4fc4SDimitry Andric }
40ac9a064cSDimitry Andric 
41ac9a064cSDimitry Andric PreservedAnalyses
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)42ac9a064cSDimitry Andric MachineLoopPrinterPass::run(MachineFunction &MF,
43ac9a064cSDimitry Andric                             MachineFunctionAnalysisManager &MFAM) {
44ac9a064cSDimitry Andric   OS << "Machine loop info for machine function '" << MF.getName() << "':\n";
45ac9a064cSDimitry Andric   MFAM.getResult<MachineLoopAnalysis>(MF).print(OS);
46ac9a064cSDimitry Andric   return PreservedAnalyses::all();
47ac9a064cSDimitry Andric }
48ac9a064cSDimitry Andric 
49ac9a064cSDimitry Andric char MachineLoopInfoWrapperPass::ID = 0;
MachineLoopInfoWrapperPass()50ac9a064cSDimitry Andric MachineLoopInfoWrapperPass::MachineLoopInfoWrapperPass()
51ac9a064cSDimitry Andric     : MachineFunctionPass(ID) {
52ac9a064cSDimitry Andric   initializeMachineLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
53ac9a064cSDimitry Andric }
54ac9a064cSDimitry Andric INITIALIZE_PASS_BEGIN(MachineLoopInfoWrapperPass, "machine-loops",
55cf099d11SDimitry Andric                       "Machine Natural Loop Construction", true, true)
56ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
57ac9a064cSDimitry Andric INITIALIZE_PASS_END(MachineLoopInfoWrapperPass, "machine-loops",
58cf099d11SDimitry Andric                     "Machine Natural Loop Construction", true, true)
59009b1c42SEd Schouten 
60ac9a064cSDimitry Andric char &llvm::MachineLoopInfoID = MachineLoopInfoWrapperPass::ID;
61009b1c42SEd Schouten 
runOnMachineFunction(MachineFunction &)62ac9a064cSDimitry Andric bool MachineLoopInfoWrapperPass::runOnMachineFunction(MachineFunction &) {
63ac9a064cSDimitry Andric   LI.calculate(getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree());
64009b1c42SEd Schouten   return false;
65009b1c42SEd Schouten }
66009b1c42SEd Schouten 
invalidate(MachineFunction &,const PreservedAnalyses & PA,MachineFunctionAnalysisManager::Invalidator &)67ac9a064cSDimitry Andric bool MachineLoopInfo::invalidate(
68ac9a064cSDimitry Andric     MachineFunction &, const PreservedAnalyses &PA,
69ac9a064cSDimitry Andric     MachineFunctionAnalysisManager::Invalidator &) {
70ac9a064cSDimitry Andric   // Check whether the analysis, all analyses on functions, or the function's
71ac9a064cSDimitry Andric   // CFG have been preserved.
72ac9a064cSDimitry Andric   auto PAC = PA.getChecker<MachineLoopAnalysis>();
73ac9a064cSDimitry Andric   return !PAC.preserved() &&
74ac9a064cSDimitry Andric          !PAC.preservedSet<AllAnalysesOn<MachineFunction>>() &&
75ac9a064cSDimitry Andric          !PAC.preservedSet<CFGAnalyses>();
76ac9a064cSDimitry Andric }
77ac9a064cSDimitry Andric 
calculate(MachineDominatorTree & MDT)78706b4fc4SDimitry Andric void MachineLoopInfo::calculate(MachineDominatorTree &MDT) {
79706b4fc4SDimitry Andric   releaseMemory();
80ac9a064cSDimitry Andric   analyze(MDT.getBase());
81706b4fc4SDimitry Andric }
82706b4fc4SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const83ac9a064cSDimitry Andric void MachineLoopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
84009b1c42SEd Schouten   AU.setPreservesAll();
85ac9a064cSDimitry Andric   AU.addRequired<MachineDominatorTreeWrapperPass>();
8659850d08SRoman Divacky   MachineFunctionPass::getAnalysisUsage(AU);
87009b1c42SEd Schouten }
884a142eb2SRoman Divacky 
getTopBlock()894a142eb2SRoman Divacky MachineBasicBlock *MachineLoop::getTopBlock() {
904a142eb2SRoman Divacky   MachineBasicBlock *TopMBB = getHeader();
914a142eb2SRoman Divacky   MachineFunction::iterator Begin = TopMBB->getParent()->begin();
9201095a5dSDimitry Andric   if (TopMBB->getIterator() != Begin) {
93dd58ef01SDimitry Andric     MachineBasicBlock *PriorMBB = &*std::prev(TopMBB->getIterator());
944a142eb2SRoman Divacky     while (contains(PriorMBB)) {
954a142eb2SRoman Divacky       TopMBB = PriorMBB;
9601095a5dSDimitry Andric       if (TopMBB->getIterator() == Begin)
9701095a5dSDimitry Andric         break;
98dd58ef01SDimitry Andric       PriorMBB = &*std::prev(TopMBB->getIterator());
994a142eb2SRoman Divacky     }
1004a142eb2SRoman Divacky   }
1014a142eb2SRoman Divacky   return TopMBB;
1024a142eb2SRoman Divacky }
1034a142eb2SRoman Divacky 
getBottomBlock()1044a142eb2SRoman Divacky MachineBasicBlock *MachineLoop::getBottomBlock() {
1054a142eb2SRoman Divacky   MachineBasicBlock *BotMBB = getHeader();
1064a142eb2SRoman Divacky   MachineFunction::iterator End = BotMBB->getParent()->end();
10701095a5dSDimitry Andric   if (BotMBB->getIterator() != std::prev(End)) {
108dd58ef01SDimitry Andric     MachineBasicBlock *NextMBB = &*std::next(BotMBB->getIterator());
1094a142eb2SRoman Divacky     while (contains(NextMBB)) {
1104a142eb2SRoman Divacky       BotMBB = NextMBB;
111dd58ef01SDimitry Andric       if (BotMBB == &*std::next(BotMBB->getIterator()))
112dd58ef01SDimitry Andric         break;
113dd58ef01SDimitry Andric       NextMBB = &*std::next(BotMBB->getIterator());
1144a142eb2SRoman Divacky     }
1154a142eb2SRoman Divacky   }
1164a142eb2SRoman Divacky   return BotMBB;
1174a142eb2SRoman Divacky }
118829000e0SRoman Divacky 
findLoopControlBlock() const119b1c73532SDimitry Andric MachineBasicBlock *MachineLoop::findLoopControlBlock() const {
120b915e9e0SDimitry Andric   if (MachineBasicBlock *Latch = getLoopLatch()) {
121b915e9e0SDimitry Andric     if (isLoopExiting(Latch))
122b915e9e0SDimitry Andric       return Latch;
123b915e9e0SDimitry Andric     else
124b915e9e0SDimitry Andric       return getExitingBlock();
125b915e9e0SDimitry Andric   }
126b915e9e0SDimitry Andric   return nullptr;
127b915e9e0SDimitry Andric }
128b915e9e0SDimitry Andric 
getStartLoc() const12971d5a254SDimitry Andric DebugLoc MachineLoop::getStartLoc() const {
13071d5a254SDimitry Andric   // Try the pre-header first.
13171d5a254SDimitry Andric   if (MachineBasicBlock *PHeadMBB = getLoopPreheader())
13271d5a254SDimitry Andric     if (const BasicBlock *PHeadBB = PHeadMBB->getBasicBlock())
13371d5a254SDimitry Andric       if (DebugLoc DL = PHeadBB->getTerminator()->getDebugLoc())
13471d5a254SDimitry Andric         return DL;
13571d5a254SDimitry Andric 
13671d5a254SDimitry Andric   // If we have no pre-header or there are no instructions with debug
13771d5a254SDimitry Andric   // info in it, try the header.
13871d5a254SDimitry Andric   if (MachineBasicBlock *HeadMBB = getHeader())
13971d5a254SDimitry Andric     if (const BasicBlock *HeadBB = HeadMBB->getBasicBlock())
14071d5a254SDimitry Andric       return HeadBB->getTerminator()->getDebugLoc();
14171d5a254SDimitry Andric 
14271d5a254SDimitry Andric   return DebugLoc();
14371d5a254SDimitry Andric }
14471d5a254SDimitry Andric 
145b915e9e0SDimitry Andric MachineBasicBlock *
findLoopPreheader(MachineLoop * L,bool SpeculativePreheader,bool FindMultiLoopPreheader) const146344a3780SDimitry Andric MachineLoopInfo::findLoopPreheader(MachineLoop *L, bool SpeculativePreheader,
147344a3780SDimitry Andric                                    bool FindMultiLoopPreheader) const {
148b915e9e0SDimitry Andric   if (MachineBasicBlock *PB = L->getLoopPreheader())
149b915e9e0SDimitry Andric     return PB;
150b915e9e0SDimitry Andric 
151b915e9e0SDimitry Andric   if (!SpeculativePreheader)
152b915e9e0SDimitry Andric     return nullptr;
153b915e9e0SDimitry Andric 
154b915e9e0SDimitry Andric   MachineBasicBlock *HB = L->getHeader(), *LB = L->getLoopLatch();
155b915e9e0SDimitry Andric   if (HB->pred_size() != 2 || HB->hasAddressTaken())
156b915e9e0SDimitry Andric     return nullptr;
157b915e9e0SDimitry Andric   // Find the predecessor of the header that is not the latch block.
158b915e9e0SDimitry Andric   MachineBasicBlock *Preheader = nullptr;
159b915e9e0SDimitry Andric   for (MachineBasicBlock *P : HB->predecessors()) {
160b915e9e0SDimitry Andric     if (P == LB)
161b915e9e0SDimitry Andric       continue;
162b915e9e0SDimitry Andric     // Sanity.
163b915e9e0SDimitry Andric     if (Preheader)
164b915e9e0SDimitry Andric       return nullptr;
165b915e9e0SDimitry Andric     Preheader = P;
166b915e9e0SDimitry Andric   }
167b915e9e0SDimitry Andric 
168b915e9e0SDimitry Andric   // Check if the preheader candidate is a successor of any other loop
169b915e9e0SDimitry Andric   // headers. We want to avoid having two loop setups in the same block.
170344a3780SDimitry Andric   if (!FindMultiLoopPreheader) {
171b915e9e0SDimitry Andric     for (MachineBasicBlock *S : Preheader->successors()) {
172b915e9e0SDimitry Andric       if (S == HB)
173b915e9e0SDimitry Andric         continue;
174b915e9e0SDimitry Andric       MachineLoop *T = getLoopFor(S);
175b915e9e0SDimitry Andric       if (T && T->getHeader() == S)
176b915e9e0SDimitry Andric         return nullptr;
177b915e9e0SDimitry Andric     }
178344a3780SDimitry Andric   }
179b915e9e0SDimitry Andric   return Preheader;
180b915e9e0SDimitry Andric }
181b915e9e0SDimitry Andric 
getLoopID() const182b1c73532SDimitry Andric MDNode *MachineLoop::getLoopID() const {
183b1c73532SDimitry Andric   MDNode *LoopID = nullptr;
184b1c73532SDimitry Andric   if (const auto *MBB = findLoopControlBlock()) {
185b1c73532SDimitry Andric     // If there is a single latch block, then the metadata
186b1c73532SDimitry Andric     // node is attached to its terminating instruction.
187b1c73532SDimitry Andric     const auto *BB = MBB->getBasicBlock();
188b1c73532SDimitry Andric     if (!BB)
189b1c73532SDimitry Andric       return nullptr;
190b1c73532SDimitry Andric     if (const auto *TI = BB->getTerminator())
191b1c73532SDimitry Andric       LoopID = TI->getMetadata(LLVMContext::MD_loop);
192b1c73532SDimitry Andric   } else if (const auto *MBB = getHeader()) {
193b1c73532SDimitry Andric     // There seem to be multiple latch blocks, so we have to
194b1c73532SDimitry Andric     // visit all predecessors of the loop header and check
195b1c73532SDimitry Andric     // their terminating instructions for the metadata.
196b1c73532SDimitry Andric     if (const auto *Header = MBB->getBasicBlock()) {
197b1c73532SDimitry Andric       // Walk over all blocks in the loop.
198b1c73532SDimitry Andric       for (const auto *MBB : this->blocks()) {
199b1c73532SDimitry Andric         const auto *BB = MBB->getBasicBlock();
200b1c73532SDimitry Andric         if (!BB)
201b1c73532SDimitry Andric           return nullptr;
202b1c73532SDimitry Andric         const auto *TI = BB->getTerminator();
203b1c73532SDimitry Andric         if (!TI)
204b1c73532SDimitry Andric           return nullptr;
205b1c73532SDimitry Andric         MDNode *MD = nullptr;
206b1c73532SDimitry Andric         // Check if this terminating instruction jumps to the loop header.
207b1c73532SDimitry Andric         for (const auto *Succ : successors(TI)) {
208b1c73532SDimitry Andric           if (Succ == Header) {
209b1c73532SDimitry Andric             // This is a jump to the header - gather the metadata from it.
210b1c73532SDimitry Andric             MD = TI->getMetadata(LLVMContext::MD_loop);
211b1c73532SDimitry Andric             break;
212b1c73532SDimitry Andric           }
213b1c73532SDimitry Andric         }
214b1c73532SDimitry Andric         if (!MD)
215b1c73532SDimitry Andric           return nullptr;
216b1c73532SDimitry Andric         if (!LoopID)
217b1c73532SDimitry Andric           LoopID = MD;
218b1c73532SDimitry Andric         else if (MD != LoopID)
219b1c73532SDimitry Andric           return nullptr;
220b1c73532SDimitry Andric       }
221b1c73532SDimitry Andric     }
222b1c73532SDimitry Andric   }
223b1c73532SDimitry Andric   if (LoopID &&
224b1c73532SDimitry Andric       (LoopID->getNumOperands() == 0 || LoopID->getOperand(0) != LoopID))
225b1c73532SDimitry Andric     LoopID = nullptr;
226b1c73532SDimitry Andric   return LoopID;
227b1c73532SDimitry Andric }
228b1c73532SDimitry Andric 
isLoopInvariantImplicitPhysReg(Register Reg) const229ac9a064cSDimitry Andric bool MachineLoop::isLoopInvariantImplicitPhysReg(Register Reg) const {
230ac9a064cSDimitry Andric   MachineFunction *MF = getHeader()->getParent();
231ac9a064cSDimitry Andric   MachineRegisterInfo *MRI = &MF->getRegInfo();
232ac9a064cSDimitry Andric 
233ac9a064cSDimitry Andric   if (MRI->isConstantPhysReg(Reg))
234ac9a064cSDimitry Andric     return true;
235ac9a064cSDimitry Andric 
236ac9a064cSDimitry Andric   if (!MF->getSubtarget()
237ac9a064cSDimitry Andric            .getRegisterInfo()
238ac9a064cSDimitry Andric            ->shouldAnalyzePhysregInMachineLoopInfo(Reg))
239ac9a064cSDimitry Andric     return false;
240ac9a064cSDimitry Andric 
241ac9a064cSDimitry Andric   return !llvm::any_of(
242ac9a064cSDimitry Andric       MRI->def_instructions(Reg),
243ac9a064cSDimitry Andric       [this](const MachineInstr &MI) { return this->contains(&MI); });
244ac9a064cSDimitry Andric }
245ac9a064cSDimitry Andric 
isLoopInvariant(MachineInstr & I,const Register ExcludeReg) const246ac9a064cSDimitry Andric bool MachineLoop::isLoopInvariant(MachineInstr &I,
247ac9a064cSDimitry Andric                                   const Register ExcludeReg) const {
248b60736ecSDimitry Andric   MachineFunction *MF = I.getParent()->getParent();
249b60736ecSDimitry Andric   MachineRegisterInfo *MRI = &MF->getRegInfo();
250c0981da4SDimitry Andric   const TargetSubtargetInfo &ST = MF->getSubtarget();
251c0981da4SDimitry Andric   const TargetRegisterInfo *TRI = ST.getRegisterInfo();
252c0981da4SDimitry Andric   const TargetInstrInfo *TII = ST.getInstrInfo();
253b60736ecSDimitry Andric 
254b60736ecSDimitry Andric   // The instruction is loop invariant if all of its operands are.
255b60736ecSDimitry Andric   for (const MachineOperand &MO : I.operands()) {
256b60736ecSDimitry Andric     if (!MO.isReg())
257b60736ecSDimitry Andric       continue;
258b60736ecSDimitry Andric 
259b60736ecSDimitry Andric     Register Reg = MO.getReg();
260b60736ecSDimitry Andric     if (Reg == 0) continue;
261b60736ecSDimitry Andric 
262ac9a064cSDimitry Andric     if (ExcludeReg == Reg)
263ac9a064cSDimitry Andric       continue;
264ac9a064cSDimitry Andric 
265b60736ecSDimitry Andric     // An instruction that uses or defines a physical register can't e.g. be
266b60736ecSDimitry Andric     // hoisted, so mark this as not invariant.
267e3b55780SDimitry Andric     if (Reg.isPhysical()) {
268b60736ecSDimitry Andric       if (MO.isUse()) {
269b60736ecSDimitry Andric         // If the physreg has no defs anywhere, it's just an ambient register
270b60736ecSDimitry Andric         // and we can freely move its uses. Alternatively, if it's allocatable,
271b60736ecSDimitry Andric         // it could get allocated to something with a def during allocation.
272b60736ecSDimitry Andric         // However, if the physreg is known to always be caller saved/restored
273b60736ecSDimitry Andric         // then this use is safe to hoist.
274ac9a064cSDimitry Andric         if (!isLoopInvariantImplicitPhysReg(Reg) &&
275c0981da4SDimitry Andric             !(TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *I.getMF())) &&
276c0981da4SDimitry Andric             !TII->isIgnorableUse(MO))
277b60736ecSDimitry Andric           return false;
278b60736ecSDimitry Andric         // Otherwise it's safe to move.
279b60736ecSDimitry Andric         continue;
280b60736ecSDimitry Andric       } else if (!MO.isDead()) {
281b60736ecSDimitry Andric         // A def that isn't dead can't be moved.
282b60736ecSDimitry Andric         return false;
283b60736ecSDimitry Andric       } else if (getHeader()->isLiveIn(Reg)) {
284b60736ecSDimitry Andric         // If the reg is live into the loop, we can't hoist an instruction
285b60736ecSDimitry Andric         // which would clobber it.
286b60736ecSDimitry Andric         return false;
287b60736ecSDimitry Andric       }
288b60736ecSDimitry Andric     }
289b60736ecSDimitry Andric 
290b60736ecSDimitry Andric     if (!MO.isUse())
291b60736ecSDimitry Andric       continue;
292b60736ecSDimitry Andric 
293b60736ecSDimitry Andric     assert(MRI->getVRegDef(Reg) &&
294b60736ecSDimitry Andric            "Machine instr not mapped for this vreg?!");
295b60736ecSDimitry Andric 
296b60736ecSDimitry Andric     // If the loop contains the definition of an operand, then the instruction
297b60736ecSDimitry Andric     // isn't loop invariant.
298b60736ecSDimitry Andric     if (contains(MRI->getVRegDef(Reg)))
299b60736ecSDimitry Andric       return false;
300b60736ecSDimitry Andric   }
301b60736ecSDimitry Andric 
302b60736ecSDimitry Andric   // If we got this far, the instruction is loop invariant!
303b60736ecSDimitry Andric   return true;
304b60736ecSDimitry Andric }
305b60736ecSDimitry Andric 
306522600a2SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const30701095a5dSDimitry Andric LLVM_DUMP_METHOD void MachineLoop::dump() const {
308829000e0SRoman Divacky   print(dbgs());
309829000e0SRoman Divacky }
310522600a2SDimitry Andric #endif
311