xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/LiveRegUnits.cpp (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
1 //===- LiveRegUnits.cpp - Register Unit Set -------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file This file imlements the LiveRegUnits set.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/CodeGen/LiveRegUnits.h"
14 #include "llvm/CodeGen/MachineBasicBlock.h"
15 #include "llvm/CodeGen/MachineFrameInfo.h"
16 #include "llvm/CodeGen/MachineFunction.h"
17 #include "llvm/CodeGen/MachineOperand.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
19 
20 using namespace llvm;
21 
22 void LiveRegUnits::removeRegsNotPreserved(const uint32_t *RegMask) {
23   for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
24     for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
25       if (MachineOperand::clobbersPhysReg(RegMask, *RootReg)) {
26         Units.reset(U);
27         break;
28       }
29     }
30   }
31 }
32 
33 void LiveRegUnits::addRegsInMask(const uint32_t *RegMask) {
34   for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
35     for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
36       if (MachineOperand::clobbersPhysReg(RegMask, *RootReg)) {
37         Units.set(U);
38         break;
39       }
40     }
41   }
42 }
43 
44 void LiveRegUnits::stepBackward(const MachineInstr &MI) {
45   // Remove defined registers and regmask kills from the set.
46   for (const MachineOperand &MOP : MI.operands()) {
47     if (MOP.isReg()) {
48       if (MOP.isDef() && MOP.getReg().isPhysical())
49         removeReg(MOP.getReg());
50       continue;
51     }
52 
53     if (MOP.isRegMask()) {
54       removeRegsNotPreserved(MOP.getRegMask());
55       continue;
56     }
57   }
58 
59   // Add uses to the set.
60   for (const MachineOperand &MOP : MI.operands()) {
61     if (!MOP.isReg() || !MOP.readsReg())
62       continue;
63 
64     if (MOP.getReg().isPhysical())
65       addReg(MOP.getReg());
66   }
67 }
68 
69 void LiveRegUnits::accumulate(const MachineInstr &MI) {
70   // Add defs, uses and regmask clobbers to the set.
71   for (const MachineOperand &MOP : MI.operands()) {
72     if (MOP.isReg()) {
73       if (!MOP.getReg().isPhysical())
74         continue;
75       if (MOP.isDef() || MOP.readsReg())
76         addReg(MOP.getReg());
77       continue;
78     }
79 
80     if (MOP.isRegMask()) {
81       addRegsInMask(MOP.getRegMask());
82       continue;
83     }
84   }
85 }
86 
87 /// Add live-in registers of basic block \p MBB to \p LiveUnits.
88 static void addBlockLiveIns(LiveRegUnits &LiveUnits,
89                             const MachineBasicBlock &MBB) {
90   for (const auto &LI : MBB.liveins())
91     LiveUnits.addRegMasked(LI.PhysReg, LI.LaneMask);
92 }
93 
94 /// Adds all callee saved registers to \p LiveUnits.
95 static void addCalleeSavedRegs(LiveRegUnits &LiveUnits,
96                                const MachineFunction &MF) {
97   const MachineRegisterInfo &MRI = MF.getRegInfo();
98   const MachineFrameInfo &MFI = MF.getFrameInfo();
99   for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR; ++CSR) {
100     const unsigned N = *CSR;
101 
102     const auto &CSI = MFI.getCalleeSavedInfo();
103     auto Info =
104         llvm::find_if(CSI, [N](auto Info) { return Info.getReg() == N; });
105     // If we have no info for this callee-saved register, assume it is liveout
106     if (Info == CSI.end() || Info->isRestored())
107       LiveUnits.addReg(N);
108   }
109 }
110 
111 void LiveRegUnits::addPristines(const MachineFunction &MF) {
112   const MachineFrameInfo &MFI = MF.getFrameInfo();
113   if (!MFI.isCalleeSavedInfoValid())
114     return;
115   /// This function will usually be called on an empty object, handle this
116   /// as a special case.
117   if (empty()) {
118     /// Add all callee saved regs, then remove the ones that are saved and
119     /// restored.
120     addCalleeSavedRegs(*this, MF);
121     /// Remove the ones that are not saved/restored; they are pristine.
122     for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
123       removeReg(Info.getReg());
124     return;
125   }
126   /// If a callee-saved register that is not pristine is already present
127   /// in the set, we should make sure that it stays in it. Precompute the
128   /// set of pristine registers in a separate object.
129   /// Add all callee saved regs, then remove the ones that are saved+restored.
130   LiveRegUnits Pristine(*TRI);
131   addCalleeSavedRegs(Pristine, MF);
132   /// Remove the ones that are not saved/restored; they are pristine.
133   for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
134     Pristine.removeReg(Info.getReg());
135   addUnits(Pristine.getBitVector());
136 }
137 
138 void LiveRegUnits::addLiveOuts(const MachineBasicBlock &MBB) {
139   const MachineFunction &MF = *MBB.getParent();
140 
141   addPristines(MF);
142 
143   // To get the live-outs we simply merge the live-ins of all successors.
144   for (const MachineBasicBlock *Succ : MBB.successors())
145     addBlockLiveIns(*this, *Succ);
146 
147   // For the return block: Add all callee saved registers.
148   if (MBB.isReturnBlock()) {
149     const MachineFrameInfo &MFI = MF.getFrameInfo();
150     if (MFI.isCalleeSavedInfoValid())
151       addCalleeSavedRegs(*this, MF);
152   }
153 }
154 
155 void LiveRegUnits::addLiveIns(const MachineBasicBlock &MBB) {
156   const MachineFunction &MF = *MBB.getParent();
157   addPristines(MF);
158   addBlockLiveIns(*this, MBB);
159 }
160