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
20using namespace llvm;
21
22void LiveRegUnits::removeRegsNotPreserved(const uint32_t *RegMask) {
23 for (unsigned U : Units.set_bits()) {
24 for (MCRegUnitRootIterator RootReg(static_cast<MCRegUnit>(U), TRI);
25 RootReg.isValid(); ++RootReg) {
26 if (MachineOperand::clobbersPhysReg(RegMask, PhysReg: *RootReg)) {
27 Units.reset(Idx: U);
28 break;
29 }
30 }
31 }
32}
33
34void LiveRegUnits::addRegsInMask(const uint32_t *RegMask) {
35 for (MCRegUnit U : TRI->regunits()) {
36 for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
37 if (MachineOperand::clobbersPhysReg(RegMask, PhysReg: *RootReg)) {
38 Units.set(static_cast<unsigned>(U));
39 break;
40 }
41 }
42 }
43}
44
45void LiveRegUnits::stepBackward(const MachineInstr &MI) {
46 assert(!MI.isDebugInstr() &&
47 "Debug instructions must not affect liveness calculation");
48
49 // Remove defined registers and regmask kills from the set.
50 for (const MachineOperand &MOP : MI.operands()) {
51 if (MOP.isReg()) {
52 if (MOP.isDef() && MOP.getReg().isPhysical())
53 removeReg(Reg: MOP.getReg());
54 continue;
55 }
56
57 if (MOP.isRegMask()) {
58 removeRegsNotPreserved(RegMask: MOP.getRegMask());
59 continue;
60 }
61 }
62
63 // Add uses to the set.
64 for (const MachineOperand &MOP : MI.operands()) {
65 if (!MOP.isReg() || !MOP.readsReg())
66 continue;
67
68 if (MOP.getReg().isPhysical())
69 addReg(Reg: MOP.getReg());
70 }
71}
72
73void LiveRegUnits::accumulate(const MachineInstr &MI) {
74 // Add defs, uses and regmask clobbers to the set.
75 for (const MachineOperand &MOP : MI.operands()) {
76 if (MOP.isReg()) {
77 if (!MOP.getReg().isPhysical())
78 continue;
79 if (MOP.isDef() || MOP.readsReg())
80 addReg(Reg: MOP.getReg());
81 continue;
82 }
83
84 if (MOP.isRegMask()) {
85 addRegsInMask(RegMask: MOP.getRegMask());
86 continue;
87 }
88 }
89}
90
91/// Add live-in registers of basic block \p MBB to \p LiveUnits.
92static void addBlockLiveIns(LiveRegUnits &LiveUnits,
93 const MachineBasicBlock &MBB) {
94 for (const auto &LI : MBB.liveins())
95 LiveUnits.addRegMasked(Reg: LI.PhysReg, Mask: LI.LaneMask);
96}
97
98/// Add live-out registers of basic block \p MBB to \p LiveUnits.
99static void addBlockLiveOuts(LiveRegUnits &LiveUnits,
100 const MachineBasicBlock &MBB) {
101 for (const auto &LO : MBB.liveouts())
102 LiveUnits.addRegMasked(Reg: LO.PhysReg, Mask: LO.LaneMask);
103}
104
105/// Adds all callee saved registers to \p LiveUnits.
106static void addCalleeSavedRegs(LiveRegUnits &LiveUnits,
107 const MachineFunction &MF) {
108 const MachineRegisterInfo &MRI = MF.getRegInfo();
109 for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR; ++CSR)
110 LiveUnits.addReg(Reg: *CSR);
111}
112
113void LiveRegUnits::addPristines(const MachineFunction &MF) {
114 const MachineFrameInfo &MFI = MF.getFrameInfo();
115 if (!MFI.isCalleeSavedInfoValid())
116 return;
117 /// This function will usually be called on an empty object, handle this
118 /// as a special case.
119 if (empty()) {
120 /// Add all callee saved regs, then remove the ones that are saved and
121 /// restored.
122 addCalleeSavedRegs(LiveUnits&: *this, MF);
123 /// Remove the ones that are not saved/restored; they are pristine.
124 for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
125 removeReg(Reg: Info.getReg());
126 return;
127 }
128 /// If a callee-saved register that is not pristine is already present
129 /// in the set, we should make sure that it stays in it. Precompute the
130 /// set of pristine registers in a separate object.
131 /// Add all callee saved regs, then remove the ones that are saved+restored.
132 LiveRegUnits Pristine(*TRI);
133 addCalleeSavedRegs(LiveUnits&: Pristine, MF);
134 /// Remove the ones that are not saved/restored; they are pristine.
135 for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
136 Pristine.removeReg(Reg: Info.getReg());
137 addUnits(RegUnits: Pristine.getBitVector());
138}
139
140void LiveRegUnits::addLiveOuts(const MachineBasicBlock &MBB) {
141 const MachineFunction &MF = *MBB.getParent();
142 addPristines(MF);
143 addBlockLiveOuts(LiveUnits&: *this, MBB);
144
145 // For the return block: Add all callee saved registers.
146 if (MBB.isReturnBlock()) {
147 const MachineFrameInfo &MFI = MF.getFrameInfo();
148 if (MFI.isCalleeSavedInfoValid()) {
149 addCalleeSavedRegs(LiveUnits&: *this, MF);
150 // We assume callee-saved registers without CalleeSavedInfo are liveout.
151 for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
152 if (!Info.isRestored())
153 removeReg(Reg: Info.getReg());
154 }
155 }
156 }
157}
158
159void LiveRegUnits::addLiveIns(const MachineBasicBlock &MBB) {
160 const MachineFunction &MF = *MBB.getParent();
161 addPristines(MF);
162 addBlockLiveIns(LiveUnits&: *this, MBB);
163}
164