10b57cec5SDimitry Andric //===- LiveRegUnits.cpp - Register Unit Set -------------------------------===//
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 /// \file This file imlements the LiveRegUnits set.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm/CodeGen/LiveRegUnits.h"
140b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
150b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
190b57cec5SDimitry Andric
200b57cec5SDimitry Andric using namespace llvm;
210b57cec5SDimitry Andric
removeRegsNotPreserved(const uint32_t * RegMask)220b57cec5SDimitry Andric void LiveRegUnits::removeRegsNotPreserved(const uint32_t *RegMask) {
230b57cec5SDimitry Andric for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
240b57cec5SDimitry Andric for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
25*bdd1243dSDimitry Andric if (MachineOperand::clobbersPhysReg(RegMask, *RootReg)) {
260b57cec5SDimitry Andric Units.reset(U);
27*bdd1243dSDimitry Andric break;
28*bdd1243dSDimitry Andric }
290b57cec5SDimitry Andric }
300b57cec5SDimitry Andric }
310b57cec5SDimitry Andric }
320b57cec5SDimitry Andric
addRegsInMask(const uint32_t * RegMask)330b57cec5SDimitry Andric void LiveRegUnits::addRegsInMask(const uint32_t *RegMask) {
340b57cec5SDimitry Andric for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
350b57cec5SDimitry Andric for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
36*bdd1243dSDimitry Andric if (MachineOperand::clobbersPhysReg(RegMask, *RootReg)) {
370b57cec5SDimitry Andric Units.set(U);
38*bdd1243dSDimitry Andric break;
39*bdd1243dSDimitry Andric }
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric }
420b57cec5SDimitry Andric }
430b57cec5SDimitry Andric
stepBackward(const MachineInstr & MI)440b57cec5SDimitry Andric void LiveRegUnits::stepBackward(const MachineInstr &MI) {
450b57cec5SDimitry Andric // Remove defined registers and regmask kills from the set.
46*bdd1243dSDimitry Andric for (const MachineOperand &MOP : MI.operands()) {
47*bdd1243dSDimitry Andric if (MOP.isReg()) {
48*bdd1243dSDimitry Andric if (MOP.isDef() && MOP.getReg().isPhysical())
49*bdd1243dSDimitry Andric removeReg(MOP.getReg());
50*bdd1243dSDimitry Andric continue;
51*bdd1243dSDimitry Andric }
52*bdd1243dSDimitry Andric
53480093f4SDimitry Andric if (MOP.isRegMask()) {
54480093f4SDimitry Andric removeRegsNotPreserved(MOP.getRegMask());
550b57cec5SDimitry Andric continue;
56480093f4SDimitry Andric }
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric // Add uses to the set.
60*bdd1243dSDimitry Andric for (const MachineOperand &MOP : MI.operands()) {
61480093f4SDimitry Andric if (!MOP.isReg() || !MOP.readsReg())
620b57cec5SDimitry Andric continue;
63*bdd1243dSDimitry Andric
64*bdd1243dSDimitry Andric if (MOP.getReg().isPhysical())
65480093f4SDimitry Andric addReg(MOP.getReg());
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric
accumulate(const MachineInstr & MI)690b57cec5SDimitry Andric void LiveRegUnits::accumulate(const MachineInstr &MI) {
700b57cec5SDimitry Andric // Add defs, uses and regmask clobbers to the set.
71*bdd1243dSDimitry Andric for (const MachineOperand &MOP : MI.operands()) {
72*bdd1243dSDimitry Andric if (MOP.isReg()) {
73*bdd1243dSDimitry Andric if (!MOP.getReg().isPhysical())
74*bdd1243dSDimitry Andric continue;
75*bdd1243dSDimitry Andric if (MOP.isDef() || MOP.readsReg())
76*bdd1243dSDimitry Andric addReg(MOP.getReg());
77*bdd1243dSDimitry Andric continue;
78*bdd1243dSDimitry Andric }
79*bdd1243dSDimitry Andric
80480093f4SDimitry Andric if (MOP.isRegMask()) {
81480093f4SDimitry Andric addRegsInMask(MOP.getRegMask());
820b57cec5SDimitry Andric continue;
83480093f4SDimitry Andric }
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric /// Add live-in registers of basic block \p MBB to \p LiveUnits.
addBlockLiveIns(LiveRegUnits & LiveUnits,const MachineBasicBlock & MBB)880b57cec5SDimitry Andric static void addBlockLiveIns(LiveRegUnits &LiveUnits,
890b57cec5SDimitry Andric const MachineBasicBlock &MBB) {
900b57cec5SDimitry Andric for (const auto &LI : MBB.liveins())
910b57cec5SDimitry Andric LiveUnits.addRegMasked(LI.PhysReg, LI.LaneMask);
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric
940b57cec5SDimitry Andric /// Adds all callee saved registers to \p LiveUnits.
addCalleeSavedRegs(LiveRegUnits & LiveUnits,const MachineFunction & MF)950b57cec5SDimitry Andric static void addCalleeSavedRegs(LiveRegUnits &LiveUnits,
960b57cec5SDimitry Andric const MachineFunction &MF) {
970b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo();
98fe6060f1SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
99fe6060f1SDimitry Andric for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR; ++CSR) {
100fe6060f1SDimitry Andric const unsigned N = *CSR;
101fe6060f1SDimitry Andric
102fe6060f1SDimitry Andric const auto &CSI = MFI.getCalleeSavedInfo();
103fe6060f1SDimitry Andric auto Info =
104fe6060f1SDimitry Andric llvm::find_if(CSI, [N](auto Info) { return Info.getReg() == N; });
105fe6060f1SDimitry Andric // If we have no info for this callee-saved register, assume it is liveout
106fe6060f1SDimitry Andric if (Info == CSI.end() || Info->isRestored())
107fe6060f1SDimitry Andric LiveUnits.addReg(N);
108fe6060f1SDimitry Andric }
1090b57cec5SDimitry Andric }
1100b57cec5SDimitry Andric
addPristines(const MachineFunction & MF)1110b57cec5SDimitry Andric void LiveRegUnits::addPristines(const MachineFunction &MF) {
1120b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
1130b57cec5SDimitry Andric if (!MFI.isCalleeSavedInfoValid())
1140b57cec5SDimitry Andric return;
1150b57cec5SDimitry Andric /// This function will usually be called on an empty object, handle this
1160b57cec5SDimitry Andric /// as a special case.
1170b57cec5SDimitry Andric if (empty()) {
1180b57cec5SDimitry Andric /// Add all callee saved regs, then remove the ones that are saved and
1190b57cec5SDimitry Andric /// restored.
1200b57cec5SDimitry Andric addCalleeSavedRegs(*this, MF);
1210b57cec5SDimitry Andric /// Remove the ones that are not saved/restored; they are pristine.
1220b57cec5SDimitry Andric for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
1230b57cec5SDimitry Andric removeReg(Info.getReg());
1240b57cec5SDimitry Andric return;
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric /// If a callee-saved register that is not pristine is already present
1270b57cec5SDimitry Andric /// in the set, we should make sure that it stays in it. Precompute the
1280b57cec5SDimitry Andric /// set of pristine registers in a separate object.
1290b57cec5SDimitry Andric /// Add all callee saved regs, then remove the ones that are saved+restored.
1300b57cec5SDimitry Andric LiveRegUnits Pristine(*TRI);
1310b57cec5SDimitry Andric addCalleeSavedRegs(Pristine, MF);
1320b57cec5SDimitry Andric /// Remove the ones that are not saved/restored; they are pristine.
1330b57cec5SDimitry Andric for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
1340b57cec5SDimitry Andric Pristine.removeReg(Info.getReg());
1350b57cec5SDimitry Andric addUnits(Pristine.getBitVector());
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric
addLiveOuts(const MachineBasicBlock & MBB)1380b57cec5SDimitry Andric void LiveRegUnits::addLiveOuts(const MachineBasicBlock &MBB) {
1390b57cec5SDimitry Andric const MachineFunction &MF = *MBB.getParent();
1400b57cec5SDimitry Andric
1410b57cec5SDimitry Andric addPristines(MF);
1420b57cec5SDimitry Andric
1430b57cec5SDimitry Andric // To get the live-outs we simply merge the live-ins of all successors.
1440b57cec5SDimitry Andric for (const MachineBasicBlock *Succ : MBB.successors())
1450b57cec5SDimitry Andric addBlockLiveIns(*this, *Succ);
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andric // For the return block: Add all callee saved registers.
1480b57cec5SDimitry Andric if (MBB.isReturnBlock()) {
1490b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
1500b57cec5SDimitry Andric if (MFI.isCalleeSavedInfoValid())
1510b57cec5SDimitry Andric addCalleeSavedRegs(*this, MF);
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric }
1540b57cec5SDimitry Andric
addLiveIns(const MachineBasicBlock & MBB)1550b57cec5SDimitry Andric void LiveRegUnits::addLiveIns(const MachineBasicBlock &MBB) {
1560b57cec5SDimitry Andric const MachineFunction &MF = *MBB.getParent();
1570b57cec5SDimitry Andric addPristines(MF);
1580b57cec5SDimitry Andric addBlockLiveIns(*this, MBB);
1590b57cec5SDimitry Andric }
160