10b57cec5SDimitry Andric //===- MachineLoopInfo.cpp - Natural Loop Calculator ----------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the MachineLoopInfo class that is used to identify natural
100b57cec5SDimitry Andric // loops and determine the loop depth of various nodes of the CFG. Note that
110b57cec5SDimitry Andric // the loops identified may actually be several natural loops that share the
120b57cec5SDimitry Andric // same header node... not just a single natural loop.
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric
160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
18e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
19349cc55cSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
20e8d8bef9SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
210b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
22480093f4SDimitry Andric #include "llvm/InitializePasses.h"
2381ad6265SDimitry Andric #include "llvm/Pass.h"
2481ad6265SDimitry Andric #include "llvm/PassRegistry.h"
2506c3fb27SDimitry Andric #include "llvm/Support/GenericLoopInfoImpl.h"
26e8d8bef9SDimitry Andric
270b57cec5SDimitry Andric using namespace llvm;
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric // Explicitly instantiate methods in LoopInfoImpl.h for MI-level Loops.
300b57cec5SDimitry Andric template class llvm::LoopBase<MachineBasicBlock, MachineLoop>;
310b57cec5SDimitry Andric template class llvm::LoopInfoBase<MachineBasicBlock, MachineLoop>;
320b57cec5SDimitry Andric
33*0fca6ea1SDimitry Andric AnalysisKey MachineLoopAnalysis::Key;
34*0fca6ea1SDimitry Andric
35*0fca6ea1SDimitry Andric MachineLoopAnalysis::Result
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)36*0fca6ea1SDimitry Andric MachineLoopAnalysis::run(MachineFunction &MF,
37*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager &MFAM) {
38*0fca6ea1SDimitry Andric return MachineLoopInfo(MFAM.getResult<MachineDominatorTreeAnalysis>(MF));
39480093f4SDimitry Andric }
40*0fca6ea1SDimitry Andric
41*0fca6ea1SDimitry Andric PreservedAnalyses
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)42*0fca6ea1SDimitry Andric MachineLoopPrinterPass::run(MachineFunction &MF,
43*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager &MFAM) {
44*0fca6ea1SDimitry Andric OS << "Machine loop info for machine function '" << MF.getName() << "':\n";
45*0fca6ea1SDimitry Andric MFAM.getResult<MachineLoopAnalysis>(MF).print(OS);
46*0fca6ea1SDimitry Andric return PreservedAnalyses::all();
47*0fca6ea1SDimitry Andric }
48*0fca6ea1SDimitry Andric
49*0fca6ea1SDimitry Andric char MachineLoopInfoWrapperPass::ID = 0;
MachineLoopInfoWrapperPass()50*0fca6ea1SDimitry Andric MachineLoopInfoWrapperPass::MachineLoopInfoWrapperPass()
51*0fca6ea1SDimitry Andric : MachineFunctionPass(ID) {
52*0fca6ea1SDimitry Andric initializeMachineLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
53*0fca6ea1SDimitry Andric }
54*0fca6ea1SDimitry Andric INITIALIZE_PASS_BEGIN(MachineLoopInfoWrapperPass, "machine-loops",
550b57cec5SDimitry Andric "Machine Natural Loop Construction", true, true)
56*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
57*0fca6ea1SDimitry Andric INITIALIZE_PASS_END(MachineLoopInfoWrapperPass, "machine-loops",
580b57cec5SDimitry Andric "Machine Natural Loop Construction", true, true)
590b57cec5SDimitry Andric
60*0fca6ea1SDimitry Andric char &llvm::MachineLoopInfoID = MachineLoopInfoWrapperPass::ID;
610b57cec5SDimitry Andric
runOnMachineFunction(MachineFunction &)62*0fca6ea1SDimitry Andric bool MachineLoopInfoWrapperPass::runOnMachineFunction(MachineFunction &) {
63*0fca6ea1SDimitry Andric LI.calculate(getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree());
640b57cec5SDimitry Andric return false;
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric
invalidate(MachineFunction &,const PreservedAnalyses & PA,MachineFunctionAnalysisManager::Invalidator &)67*0fca6ea1SDimitry Andric bool MachineLoopInfo::invalidate(
68*0fca6ea1SDimitry Andric MachineFunction &, const PreservedAnalyses &PA,
69*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager::Invalidator &) {
70*0fca6ea1SDimitry Andric // Check whether the analysis, all analyses on functions, or the function's
71*0fca6ea1SDimitry Andric // CFG have been preserved.
72*0fca6ea1SDimitry Andric auto PAC = PA.getChecker<MachineLoopAnalysis>();
73*0fca6ea1SDimitry Andric return !PAC.preserved() &&
74*0fca6ea1SDimitry Andric !PAC.preservedSet<AllAnalysesOn<MachineFunction>>() &&
75*0fca6ea1SDimitry Andric !PAC.preservedSet<CFGAnalyses>();
76*0fca6ea1SDimitry Andric }
77*0fca6ea1SDimitry Andric
calculate(MachineDominatorTree & MDT)78480093f4SDimitry Andric void MachineLoopInfo::calculate(MachineDominatorTree &MDT) {
79480093f4SDimitry Andric releaseMemory();
80*0fca6ea1SDimitry Andric analyze(MDT.getBase());
81480093f4SDimitry Andric }
82480093f4SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const83*0fca6ea1SDimitry Andric void MachineLoopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
840b57cec5SDimitry Andric AU.setPreservesAll();
85*0fca6ea1SDimitry Andric AU.addRequired<MachineDominatorTreeWrapperPass>();
860b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric
getTopBlock()890b57cec5SDimitry Andric MachineBasicBlock *MachineLoop::getTopBlock() {
900b57cec5SDimitry Andric MachineBasicBlock *TopMBB = getHeader();
910b57cec5SDimitry Andric MachineFunction::iterator Begin = TopMBB->getParent()->begin();
920b57cec5SDimitry Andric if (TopMBB->getIterator() != Begin) {
930b57cec5SDimitry Andric MachineBasicBlock *PriorMBB = &*std::prev(TopMBB->getIterator());
940b57cec5SDimitry Andric while (contains(PriorMBB)) {
950b57cec5SDimitry Andric TopMBB = PriorMBB;
960b57cec5SDimitry Andric if (TopMBB->getIterator() == Begin)
970b57cec5SDimitry Andric break;
980b57cec5SDimitry Andric PriorMBB = &*std::prev(TopMBB->getIterator());
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric return TopMBB;
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric
getBottomBlock()1040b57cec5SDimitry Andric MachineBasicBlock *MachineLoop::getBottomBlock() {
1050b57cec5SDimitry Andric MachineBasicBlock *BotMBB = getHeader();
1060b57cec5SDimitry Andric MachineFunction::iterator End = BotMBB->getParent()->end();
1070b57cec5SDimitry Andric if (BotMBB->getIterator() != std::prev(End)) {
1080b57cec5SDimitry Andric MachineBasicBlock *NextMBB = &*std::next(BotMBB->getIterator());
1090b57cec5SDimitry Andric while (contains(NextMBB)) {
1100b57cec5SDimitry Andric BotMBB = NextMBB;
1110b57cec5SDimitry Andric if (BotMBB == &*std::next(BotMBB->getIterator()))
1120b57cec5SDimitry Andric break;
1130b57cec5SDimitry Andric NextMBB = &*std::next(BotMBB->getIterator());
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric return BotMBB;
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric
findLoopControlBlock() const1195f757f3fSDimitry Andric MachineBasicBlock *MachineLoop::findLoopControlBlock() const {
1200b57cec5SDimitry Andric if (MachineBasicBlock *Latch = getLoopLatch()) {
1210b57cec5SDimitry Andric if (isLoopExiting(Latch))
1220b57cec5SDimitry Andric return Latch;
1230b57cec5SDimitry Andric else
1240b57cec5SDimitry Andric return getExitingBlock();
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric return nullptr;
1270b57cec5SDimitry Andric }
1280b57cec5SDimitry Andric
getStartLoc() const1290b57cec5SDimitry Andric DebugLoc MachineLoop::getStartLoc() const {
1300b57cec5SDimitry Andric // Try the pre-header first.
1310b57cec5SDimitry Andric if (MachineBasicBlock *PHeadMBB = getLoopPreheader())
1320b57cec5SDimitry Andric if (const BasicBlock *PHeadBB = PHeadMBB->getBasicBlock())
1330b57cec5SDimitry Andric if (DebugLoc DL = PHeadBB->getTerminator()->getDebugLoc())
1340b57cec5SDimitry Andric return DL;
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric // If we have no pre-header or there are no instructions with debug
1370b57cec5SDimitry Andric // info in it, try the header.
1380b57cec5SDimitry Andric if (MachineBasicBlock *HeadMBB = getHeader())
1390b57cec5SDimitry Andric if (const BasicBlock *HeadBB = HeadMBB->getBasicBlock())
1400b57cec5SDimitry Andric return HeadBB->getTerminator()->getDebugLoc();
1410b57cec5SDimitry Andric
1420b57cec5SDimitry Andric return DebugLoc();
1430b57cec5SDimitry Andric }
1440b57cec5SDimitry Andric
1450b57cec5SDimitry Andric MachineBasicBlock *
findLoopPreheader(MachineLoop * L,bool SpeculativePreheader,bool FindMultiLoopPreheader) const146fe6060f1SDimitry Andric MachineLoopInfo::findLoopPreheader(MachineLoop *L, bool SpeculativePreheader,
147fe6060f1SDimitry Andric bool FindMultiLoopPreheader) const {
1480b57cec5SDimitry Andric if (MachineBasicBlock *PB = L->getLoopPreheader())
1490b57cec5SDimitry Andric return PB;
1500b57cec5SDimitry Andric
1510b57cec5SDimitry Andric if (!SpeculativePreheader)
1520b57cec5SDimitry Andric return nullptr;
1530b57cec5SDimitry Andric
1540b57cec5SDimitry Andric MachineBasicBlock *HB = L->getHeader(), *LB = L->getLoopLatch();
1550b57cec5SDimitry Andric if (HB->pred_size() != 2 || HB->hasAddressTaken())
1560b57cec5SDimitry Andric return nullptr;
1570b57cec5SDimitry Andric // Find the predecessor of the header that is not the latch block.
1580b57cec5SDimitry Andric MachineBasicBlock *Preheader = nullptr;
1590b57cec5SDimitry Andric for (MachineBasicBlock *P : HB->predecessors()) {
1600b57cec5SDimitry Andric if (P == LB)
1610b57cec5SDimitry Andric continue;
1620b57cec5SDimitry Andric // Sanity.
1630b57cec5SDimitry Andric if (Preheader)
1640b57cec5SDimitry Andric return nullptr;
1650b57cec5SDimitry Andric Preheader = P;
1660b57cec5SDimitry Andric }
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric // Check if the preheader candidate is a successor of any other loop
1690b57cec5SDimitry Andric // headers. We want to avoid having two loop setups in the same block.
170fe6060f1SDimitry Andric if (!FindMultiLoopPreheader) {
1710b57cec5SDimitry Andric for (MachineBasicBlock *S : Preheader->successors()) {
1720b57cec5SDimitry Andric if (S == HB)
1730b57cec5SDimitry Andric continue;
1740b57cec5SDimitry Andric MachineLoop *T = getLoopFor(S);
1750b57cec5SDimitry Andric if (T && T->getHeader() == S)
1760b57cec5SDimitry Andric return nullptr;
1770b57cec5SDimitry Andric }
178fe6060f1SDimitry Andric }
1790b57cec5SDimitry Andric return Preheader;
1800b57cec5SDimitry Andric }
1810b57cec5SDimitry Andric
getLoopID() const1825f757f3fSDimitry Andric MDNode *MachineLoop::getLoopID() const {
1835f757f3fSDimitry Andric MDNode *LoopID = nullptr;
1845f757f3fSDimitry Andric if (const auto *MBB = findLoopControlBlock()) {
1855f757f3fSDimitry Andric // If there is a single latch block, then the metadata
1865f757f3fSDimitry Andric // node is attached to its terminating instruction.
1875f757f3fSDimitry Andric const auto *BB = MBB->getBasicBlock();
1885f757f3fSDimitry Andric if (!BB)
1895f757f3fSDimitry Andric return nullptr;
1905f757f3fSDimitry Andric if (const auto *TI = BB->getTerminator())
1915f757f3fSDimitry Andric LoopID = TI->getMetadata(LLVMContext::MD_loop);
1925f757f3fSDimitry Andric } else if (const auto *MBB = getHeader()) {
1935f757f3fSDimitry Andric // There seem to be multiple latch blocks, so we have to
1945f757f3fSDimitry Andric // visit all predecessors of the loop header and check
1955f757f3fSDimitry Andric // their terminating instructions for the metadata.
1965f757f3fSDimitry Andric if (const auto *Header = MBB->getBasicBlock()) {
1975f757f3fSDimitry Andric // Walk over all blocks in the loop.
1985f757f3fSDimitry Andric for (const auto *MBB : this->blocks()) {
1995f757f3fSDimitry Andric const auto *BB = MBB->getBasicBlock();
2005f757f3fSDimitry Andric if (!BB)
2015f757f3fSDimitry Andric return nullptr;
2025f757f3fSDimitry Andric const auto *TI = BB->getTerminator();
2035f757f3fSDimitry Andric if (!TI)
2045f757f3fSDimitry Andric return nullptr;
2055f757f3fSDimitry Andric MDNode *MD = nullptr;
2065f757f3fSDimitry Andric // Check if this terminating instruction jumps to the loop header.
2075f757f3fSDimitry Andric for (const auto *Succ : successors(TI)) {
2085f757f3fSDimitry Andric if (Succ == Header) {
2095f757f3fSDimitry Andric // This is a jump to the header - gather the metadata from it.
2105f757f3fSDimitry Andric MD = TI->getMetadata(LLVMContext::MD_loop);
2115f757f3fSDimitry Andric break;
2125f757f3fSDimitry Andric }
2135f757f3fSDimitry Andric }
2145f757f3fSDimitry Andric if (!MD)
2155f757f3fSDimitry Andric return nullptr;
2165f757f3fSDimitry Andric if (!LoopID)
2175f757f3fSDimitry Andric LoopID = MD;
2185f757f3fSDimitry Andric else if (MD != LoopID)
2195f757f3fSDimitry Andric return nullptr;
2205f757f3fSDimitry Andric }
2215f757f3fSDimitry Andric }
2225f757f3fSDimitry Andric }
2235f757f3fSDimitry Andric if (LoopID &&
2245f757f3fSDimitry Andric (LoopID->getNumOperands() == 0 || LoopID->getOperand(0) != LoopID))
2255f757f3fSDimitry Andric LoopID = nullptr;
2265f757f3fSDimitry Andric return LoopID;
2275f757f3fSDimitry Andric }
2285f757f3fSDimitry Andric
isLoopInvariantImplicitPhysReg(Register Reg) const229*0fca6ea1SDimitry Andric bool MachineLoop::isLoopInvariantImplicitPhysReg(Register Reg) const {
230*0fca6ea1SDimitry Andric MachineFunction *MF = getHeader()->getParent();
231*0fca6ea1SDimitry Andric MachineRegisterInfo *MRI = &MF->getRegInfo();
232*0fca6ea1SDimitry Andric
233*0fca6ea1SDimitry Andric if (MRI->isConstantPhysReg(Reg))
234*0fca6ea1SDimitry Andric return true;
235*0fca6ea1SDimitry Andric
236*0fca6ea1SDimitry Andric if (!MF->getSubtarget()
237*0fca6ea1SDimitry Andric .getRegisterInfo()
238*0fca6ea1SDimitry Andric ->shouldAnalyzePhysregInMachineLoopInfo(Reg))
239*0fca6ea1SDimitry Andric return false;
240*0fca6ea1SDimitry Andric
241*0fca6ea1SDimitry Andric return !llvm::any_of(
242*0fca6ea1SDimitry Andric MRI->def_instructions(Reg),
243*0fca6ea1SDimitry Andric [this](const MachineInstr &MI) { return this->contains(&MI); });
244*0fca6ea1SDimitry Andric }
245*0fca6ea1SDimitry Andric
isLoopInvariant(MachineInstr & I,const Register ExcludeReg) const246*0fca6ea1SDimitry Andric bool MachineLoop::isLoopInvariant(MachineInstr &I,
247*0fca6ea1SDimitry Andric const Register ExcludeReg) const {
248e8d8bef9SDimitry Andric MachineFunction *MF = I.getParent()->getParent();
249e8d8bef9SDimitry Andric MachineRegisterInfo *MRI = &MF->getRegInfo();
250349cc55cSDimitry Andric const TargetSubtargetInfo &ST = MF->getSubtarget();
251349cc55cSDimitry Andric const TargetRegisterInfo *TRI = ST.getRegisterInfo();
252349cc55cSDimitry Andric const TargetInstrInfo *TII = ST.getInstrInfo();
253e8d8bef9SDimitry Andric
254e8d8bef9SDimitry Andric // The instruction is loop invariant if all of its operands are.
255e8d8bef9SDimitry Andric for (const MachineOperand &MO : I.operands()) {
256e8d8bef9SDimitry Andric if (!MO.isReg())
257e8d8bef9SDimitry Andric continue;
258e8d8bef9SDimitry Andric
259e8d8bef9SDimitry Andric Register Reg = MO.getReg();
260e8d8bef9SDimitry Andric if (Reg == 0) continue;
261e8d8bef9SDimitry Andric
262*0fca6ea1SDimitry Andric if (ExcludeReg == Reg)
263*0fca6ea1SDimitry Andric continue;
264*0fca6ea1SDimitry Andric
265e8d8bef9SDimitry Andric // An instruction that uses or defines a physical register can't e.g. be
266e8d8bef9SDimitry Andric // hoisted, so mark this as not invariant.
267bdd1243dSDimitry Andric if (Reg.isPhysical()) {
268e8d8bef9SDimitry Andric if (MO.isUse()) {
269e8d8bef9SDimitry Andric // If the physreg has no defs anywhere, it's just an ambient register
270e8d8bef9SDimitry Andric // and we can freely move its uses. Alternatively, if it's allocatable,
271e8d8bef9SDimitry Andric // it could get allocated to something with a def during allocation.
272e8d8bef9SDimitry Andric // However, if the physreg is known to always be caller saved/restored
273e8d8bef9SDimitry Andric // then this use is safe to hoist.
274*0fca6ea1SDimitry Andric if (!isLoopInvariantImplicitPhysReg(Reg) &&
275349cc55cSDimitry Andric !(TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *I.getMF())) &&
276349cc55cSDimitry Andric !TII->isIgnorableUse(MO))
277e8d8bef9SDimitry Andric return false;
278e8d8bef9SDimitry Andric // Otherwise it's safe to move.
279e8d8bef9SDimitry Andric continue;
280e8d8bef9SDimitry Andric } else if (!MO.isDead()) {
281e8d8bef9SDimitry Andric // A def that isn't dead can't be moved.
282e8d8bef9SDimitry Andric return false;
283e8d8bef9SDimitry Andric } else if (getHeader()->isLiveIn(Reg)) {
284e8d8bef9SDimitry Andric // If the reg is live into the loop, we can't hoist an instruction
285e8d8bef9SDimitry Andric // which would clobber it.
286e8d8bef9SDimitry Andric return false;
287e8d8bef9SDimitry Andric }
288e8d8bef9SDimitry Andric }
289e8d8bef9SDimitry Andric
290e8d8bef9SDimitry Andric if (!MO.isUse())
291e8d8bef9SDimitry Andric continue;
292e8d8bef9SDimitry Andric
293e8d8bef9SDimitry Andric assert(MRI->getVRegDef(Reg) &&
294e8d8bef9SDimitry Andric "Machine instr not mapped for this vreg?!");
295e8d8bef9SDimitry Andric
296e8d8bef9SDimitry Andric // If the loop contains the definition of an operand, then the instruction
297e8d8bef9SDimitry Andric // isn't loop invariant.
298e8d8bef9SDimitry Andric if (contains(MRI->getVRegDef(Reg)))
299e8d8bef9SDimitry Andric return false;
300e8d8bef9SDimitry Andric }
301e8d8bef9SDimitry Andric
302e8d8bef9SDimitry Andric // If we got this far, the instruction is loop invariant!
303e8d8bef9SDimitry Andric return true;
304e8d8bef9SDimitry Andric }
305e8d8bef9SDimitry Andric
3060b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const3070b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineLoop::dump() const {
3080b57cec5SDimitry Andric print(dbgs());
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric #endif
311