xref: /openbsd-src/gnu/llvm/llvm/lib/CodeGen/LiveRangeShrink.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===- LiveRangeShrink.cpp - Move instructions to shrink live range -------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick ///===---------------------------------------------------------------------===//
809467b48Spatrick ///
909467b48Spatrick /// \file
1009467b48Spatrick /// This pass moves instructions close to the definition of its operands to
1109467b48Spatrick /// shrink live range of the def instruction. The code motion is limited within
1209467b48Spatrick /// the basic block. The moved instruction should have 1 def, and more than one
1309467b48Spatrick /// uses, all of which are the only use of the def.
1409467b48Spatrick ///
1509467b48Spatrick ///===---------------------------------------------------------------------===//
1609467b48Spatrick 
1709467b48Spatrick #include "llvm/ADT/DenseMap.h"
1809467b48Spatrick #include "llvm/ADT/Statistic.h"
1909467b48Spatrick #include "llvm/ADT/iterator_range.h"
2009467b48Spatrick #include "llvm/CodeGen/MachineBasicBlock.h"
2109467b48Spatrick #include "llvm/CodeGen/MachineFunction.h"
2209467b48Spatrick #include "llvm/CodeGen/MachineFunctionPass.h"
2309467b48Spatrick #include "llvm/CodeGen/MachineInstr.h"
2409467b48Spatrick #include "llvm/CodeGen/MachineOperand.h"
2509467b48Spatrick #include "llvm/CodeGen/MachineRegisterInfo.h"
2609467b48Spatrick #include "llvm/InitializePasses.h"
2709467b48Spatrick #include "llvm/Pass.h"
2809467b48Spatrick #include "llvm/Support/Debug.h"
2909467b48Spatrick #include "llvm/Support/raw_ostream.h"
3009467b48Spatrick #include <iterator>
3109467b48Spatrick #include <utility>
3209467b48Spatrick 
3309467b48Spatrick using namespace llvm;
3409467b48Spatrick 
3509467b48Spatrick #define DEBUG_TYPE "lrshrink"
3609467b48Spatrick 
3709467b48Spatrick STATISTIC(NumInstrsHoistedToShrinkLiveRange,
3809467b48Spatrick           "Number of insructions hoisted to shrink live range.");
3909467b48Spatrick 
4009467b48Spatrick namespace {
4109467b48Spatrick 
4209467b48Spatrick class LiveRangeShrink : public MachineFunctionPass {
4309467b48Spatrick public:
4409467b48Spatrick   static char ID;
4509467b48Spatrick 
LiveRangeShrink()4609467b48Spatrick   LiveRangeShrink() : MachineFunctionPass(ID) {
4709467b48Spatrick     initializeLiveRangeShrinkPass(*PassRegistry::getPassRegistry());
4809467b48Spatrick   }
4909467b48Spatrick 
getAnalysisUsage(AnalysisUsage & AU) const5009467b48Spatrick   void getAnalysisUsage(AnalysisUsage &AU) const override {
5109467b48Spatrick     AU.setPreservesCFG();
5209467b48Spatrick     MachineFunctionPass::getAnalysisUsage(AU);
5309467b48Spatrick   }
5409467b48Spatrick 
getPassName() const5509467b48Spatrick   StringRef getPassName() const override { return "Live Range Shrink"; }
5609467b48Spatrick 
5709467b48Spatrick   bool runOnMachineFunction(MachineFunction &MF) override;
5809467b48Spatrick };
5909467b48Spatrick 
6009467b48Spatrick } // end anonymous namespace
6109467b48Spatrick 
6209467b48Spatrick char LiveRangeShrink::ID = 0;
6309467b48Spatrick 
6409467b48Spatrick char &llvm::LiveRangeShrinkID = LiveRangeShrink::ID;
6509467b48Spatrick 
6609467b48Spatrick INITIALIZE_PASS(LiveRangeShrink, "lrshrink", "Live Range Shrink Pass", false,
6709467b48Spatrick                 false)
6809467b48Spatrick 
6909467b48Spatrick using InstOrderMap = DenseMap<MachineInstr *, unsigned>;
7009467b48Spatrick 
7109467b48Spatrick /// Returns \p New if it's dominated by \p Old, otherwise return \p Old.
7209467b48Spatrick /// \p M maintains a map from instruction to its dominating order that satisfies
7309467b48Spatrick /// M[A] > M[B] guarantees that A is dominated by B.
7409467b48Spatrick /// If \p New is not in \p M, return \p Old. Otherwise if \p Old is null, return
7509467b48Spatrick /// \p New.
FindDominatedInstruction(MachineInstr & New,MachineInstr * Old,const InstOrderMap & M)7609467b48Spatrick static MachineInstr *FindDominatedInstruction(MachineInstr &New,
7709467b48Spatrick                                               MachineInstr *Old,
7809467b48Spatrick                                               const InstOrderMap &M) {
7909467b48Spatrick   auto NewIter = M.find(&New);
8009467b48Spatrick   if (NewIter == M.end())
8109467b48Spatrick     return Old;
8209467b48Spatrick   if (Old == nullptr)
8309467b48Spatrick     return &New;
8409467b48Spatrick   unsigned OrderOld = M.find(Old)->second;
8509467b48Spatrick   unsigned OrderNew = NewIter->second;
8609467b48Spatrick   if (OrderOld != OrderNew)
8709467b48Spatrick     return OrderOld < OrderNew ? &New : Old;
8809467b48Spatrick   // OrderOld == OrderNew, we need to iterate down from Old to see if it
8909467b48Spatrick   // can reach New, if yes, New is dominated by Old.
9009467b48Spatrick   for (MachineInstr *I = Old->getNextNode(); M.find(I)->second == OrderNew;
9109467b48Spatrick        I = I->getNextNode())
9209467b48Spatrick     if (I == &New)
9309467b48Spatrick       return &New;
9409467b48Spatrick   return Old;
9509467b48Spatrick }
9609467b48Spatrick 
9709467b48Spatrick /// Builds Instruction to its dominating order number map \p M by traversing
9809467b48Spatrick /// from instruction \p Start.
BuildInstOrderMap(MachineBasicBlock::iterator Start,InstOrderMap & M)9909467b48Spatrick static void BuildInstOrderMap(MachineBasicBlock::iterator Start,
10009467b48Spatrick                               InstOrderMap &M) {
10109467b48Spatrick   M.clear();
10209467b48Spatrick   unsigned i = 0;
10309467b48Spatrick   for (MachineInstr &I : make_range(Start, Start->getParent()->end()))
10409467b48Spatrick     M[&I] = i++;
10509467b48Spatrick }
10609467b48Spatrick 
runOnMachineFunction(MachineFunction & MF)10709467b48Spatrick bool LiveRangeShrink::runOnMachineFunction(MachineFunction &MF) {
10809467b48Spatrick   if (skipFunction(MF.getFunction()))
10909467b48Spatrick     return false;
11009467b48Spatrick 
11109467b48Spatrick   MachineRegisterInfo &MRI = MF.getRegInfo();
11209467b48Spatrick 
11309467b48Spatrick   LLVM_DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n');
11409467b48Spatrick 
11509467b48Spatrick   InstOrderMap IOM;
11609467b48Spatrick   // Map from register to instruction order (value of IOM) where the
11709467b48Spatrick   // register is used last. When moving instructions up, we need to
11809467b48Spatrick   // make sure all its defs (including dead def) will not cross its
11909467b48Spatrick   // last use when moving up.
12009467b48Spatrick   DenseMap<unsigned, std::pair<unsigned, MachineInstr *>> UseMap;
12109467b48Spatrick 
12209467b48Spatrick   for (MachineBasicBlock &MBB : MF) {
12309467b48Spatrick     if (MBB.empty())
12409467b48Spatrick       continue;
12509467b48Spatrick     bool SawStore = false;
12609467b48Spatrick     BuildInstOrderMap(MBB.begin(), IOM);
12709467b48Spatrick     UseMap.clear();
12809467b48Spatrick 
12909467b48Spatrick     for (MachineBasicBlock::iterator Next = MBB.begin(); Next != MBB.end();) {
13009467b48Spatrick       MachineInstr &MI = *Next;
13109467b48Spatrick       ++Next;
13273471bf0Spatrick       if (MI.isPHI() || MI.isDebugOrPseudoInstr())
13309467b48Spatrick         continue;
13409467b48Spatrick       if (MI.mayStore())
13509467b48Spatrick         SawStore = true;
13609467b48Spatrick 
13709467b48Spatrick       unsigned CurrentOrder = IOM[&MI];
13809467b48Spatrick       unsigned Barrier = 0;
13909467b48Spatrick       MachineInstr *BarrierMI = nullptr;
14009467b48Spatrick       for (const MachineOperand &MO : MI.operands()) {
14109467b48Spatrick         if (!MO.isReg() || MO.isDebug())
14209467b48Spatrick           continue;
14309467b48Spatrick         if (MO.isUse())
14409467b48Spatrick           UseMap[MO.getReg()] = std::make_pair(CurrentOrder, &MI);
14509467b48Spatrick         else if (MO.isDead() && UseMap.count(MO.getReg()))
14609467b48Spatrick           // Barrier is the last instruction where MO get used. MI should not
14709467b48Spatrick           // be moved above Barrier.
14809467b48Spatrick           if (Barrier < UseMap[MO.getReg()].first) {
14909467b48Spatrick             Barrier = UseMap[MO.getReg()].first;
15009467b48Spatrick             BarrierMI = UseMap[MO.getReg()].second;
15109467b48Spatrick           }
15209467b48Spatrick       }
15309467b48Spatrick 
15409467b48Spatrick       if (!MI.isSafeToMove(nullptr, SawStore)) {
15509467b48Spatrick         // If MI has side effects, it should become a barrier for code motion.
15609467b48Spatrick         // IOM is rebuild from the next instruction to prevent later
15709467b48Spatrick         // instructions from being moved before this MI.
15873471bf0Spatrick         if (MI.hasUnmodeledSideEffects() && !MI.isPseudoProbe() &&
15973471bf0Spatrick             Next != MBB.end()) {
16009467b48Spatrick           BuildInstOrderMap(Next, IOM);
16109467b48Spatrick           SawStore = false;
16209467b48Spatrick         }
16309467b48Spatrick         continue;
16409467b48Spatrick       }
16509467b48Spatrick 
16609467b48Spatrick       const MachineOperand *DefMO = nullptr;
16709467b48Spatrick       MachineInstr *Insert = nullptr;
16809467b48Spatrick 
16909467b48Spatrick       // Number of live-ranges that will be shortened. We do not count
17009467b48Spatrick       // live-ranges that are defined by a COPY as it could be coalesced later.
17109467b48Spatrick       unsigned NumEligibleUse = 0;
17209467b48Spatrick 
17309467b48Spatrick       for (const MachineOperand &MO : MI.operands()) {
17409467b48Spatrick         if (!MO.isReg() || MO.isDead() || MO.isDebug())
17509467b48Spatrick           continue;
17609467b48Spatrick         Register Reg = MO.getReg();
17709467b48Spatrick         // Do not move the instruction if it def/uses a physical register,
17809467b48Spatrick         // unless it is a constant physical register or a noreg.
179*d415bd75Srobert         if (!Reg.isVirtual()) {
18009467b48Spatrick           if (!Reg || MRI.isConstantPhysReg(Reg))
18109467b48Spatrick             continue;
18209467b48Spatrick           Insert = nullptr;
18309467b48Spatrick           break;
18409467b48Spatrick         }
18509467b48Spatrick         if (MO.isDef()) {
18609467b48Spatrick           // Do not move if there is more than one def.
18709467b48Spatrick           if (DefMO) {
18809467b48Spatrick             Insert = nullptr;
18909467b48Spatrick             break;
19009467b48Spatrick           }
19109467b48Spatrick           DefMO = &MO;
19209467b48Spatrick         } else if (MRI.hasOneNonDBGUse(Reg) && MRI.hasOneDef(Reg) && DefMO &&
19309467b48Spatrick                    MRI.getRegClass(DefMO->getReg()) ==
19409467b48Spatrick                        MRI.getRegClass(MO.getReg())) {
19509467b48Spatrick           // The heuristic does not handle different register classes yet
19609467b48Spatrick           // (registers of different sizes, looser/tighter constraints). This
19709467b48Spatrick           // is because it needs more accurate model to handle register
19809467b48Spatrick           // pressure correctly.
19909467b48Spatrick           MachineInstr &DefInstr = *MRI.def_instr_begin(Reg);
20009467b48Spatrick           if (!DefInstr.isCopy())
20109467b48Spatrick             NumEligibleUse++;
20209467b48Spatrick           Insert = FindDominatedInstruction(DefInstr, Insert, IOM);
20309467b48Spatrick         } else {
20409467b48Spatrick           Insert = nullptr;
20509467b48Spatrick           break;
20609467b48Spatrick         }
20709467b48Spatrick       }
20809467b48Spatrick 
20909467b48Spatrick       // If Barrier equals IOM[I], traverse forward to find if BarrierMI is
21009467b48Spatrick       // after Insert, if yes, then we should not hoist.
21109467b48Spatrick       for (MachineInstr *I = Insert; I && IOM[I] == Barrier;
21209467b48Spatrick            I = I->getNextNode())
21309467b48Spatrick         if (I == BarrierMI) {
21409467b48Spatrick           Insert = nullptr;
21509467b48Spatrick           break;
21609467b48Spatrick         }
21709467b48Spatrick       // Move the instruction when # of shrunk live range > 1.
21809467b48Spatrick       if (DefMO && Insert && NumEligibleUse > 1 && Barrier <= IOM[Insert]) {
21909467b48Spatrick         MachineBasicBlock::iterator I = std::next(Insert->getIterator());
22009467b48Spatrick         // Skip all the PHI and debug instructions.
22173471bf0Spatrick         while (I != MBB.end() && (I->isPHI() || I->isDebugOrPseudoInstr()))
22209467b48Spatrick           I = std::next(I);
22309467b48Spatrick         if (I == MI.getIterator())
22409467b48Spatrick           continue;
22509467b48Spatrick 
22609467b48Spatrick         // Update the dominator order to be the same as the insertion point.
22709467b48Spatrick         // We do this to maintain a non-decreasing order without need to update
22809467b48Spatrick         // all instruction orders after the insertion point.
22909467b48Spatrick         unsigned NewOrder = IOM[&*I];
23009467b48Spatrick         IOM[&MI] = NewOrder;
23109467b48Spatrick         NumInstrsHoistedToShrinkLiveRange++;
23209467b48Spatrick 
23309467b48Spatrick         // Find MI's debug value following MI.
23409467b48Spatrick         MachineBasicBlock::iterator EndIter = std::next(MI.getIterator());
23509467b48Spatrick         if (MI.getOperand(0).isReg())
23609467b48Spatrick           for (; EndIter != MBB.end() && EndIter->isDebugValue() &&
23773471bf0Spatrick                  EndIter->hasDebugOperandForReg(MI.getOperand(0).getReg());
23809467b48Spatrick                ++EndIter, ++Next)
23909467b48Spatrick             IOM[&*EndIter] = NewOrder;
24009467b48Spatrick         MBB.splice(I, &MBB, MI.getIterator(), EndIter);
24109467b48Spatrick       }
24209467b48Spatrick     }
24309467b48Spatrick   }
24409467b48Spatrick   return false;
24509467b48Spatrick }
246