LiveRegUnits.cpp revision 360784
1279315Strasz//===- LiveRegUnits.cpp - Register Unit Set -------------------------------===// 2332615Strasz// 3332615Strasz// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4279315Strasz// See https://llvm.org/LICENSE.txt for license information. 5279315Strasz// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6279315Strasz// 7279315Strasz//===----------------------------------------------------------------------===// 8279315Strasz// 9279315Strasz/// \file This file imlements the LiveRegUnits set. 10279315Strasz// 11279315Strasz//===----------------------------------------------------------------------===// 12279315Strasz 13279315Strasz#include "llvm/CodeGen/LiveRegUnits.h" 14279315Strasz 15279315Strasz#include "llvm/CodeGen/MachineBasicBlock.h" 16279315Strasz#include "llvm/CodeGen/MachineFrameInfo.h" 17279315Strasz#include "llvm/CodeGen/MachineFunction.h" 18279315Strasz#include "llvm/CodeGen/MachineInstrBundle.h" 19279315Strasz#include "llvm/CodeGen/MachineOperand.h" 20279315Strasz#include "llvm/CodeGen/MachineRegisterInfo.h" 21279315Strasz#include "llvm/CodeGen/TargetRegisterInfo.h" 22279315Strasz#include "llvm/MC/MCRegisterInfo.h" 23279315Strasz 24279315Straszusing namespace llvm; 25279315Strasz 26279315Straszvoid LiveRegUnits::removeRegsNotPreserved(const uint32_t *RegMask) { 27279315Strasz for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) { 28279315Strasz for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) { 29279315Strasz if (MachineOperand::clobbersPhysReg(RegMask, *RootReg)) 30279315Strasz Units.reset(U); 31279315Strasz } 32279315Strasz } 33279315Strasz} 34279315Strasz 35279315Straszvoid LiveRegUnits::addRegsInMask(const uint32_t *RegMask) { 36279315Strasz for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) { 37279315Strasz for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) { 38279315Strasz if (MachineOperand::clobbersPhysReg(RegMask, *RootReg)) 39279315Strasz Units.set(U); 40279315Strasz } 41279315Strasz } 42279315Strasz} 43279315Strasz 44279315Straszvoid LiveRegUnits::stepBackward(const MachineInstr &MI) { 45279315Strasz // Remove defined registers and regmask kills from the set. 46279315Strasz for (const MachineOperand &MOP : phys_regs_and_masks(MI)) { 47279315Strasz if (MOP.isRegMask()) { 48279315Strasz removeRegsNotPreserved(MOP.getRegMask()); 49279315Strasz continue; 50279315Strasz } 51279315Strasz 52279315Strasz if (MOP.isDef()) 53279315Strasz removeReg(MOP.getReg()); 54279315Strasz } 55279315Strasz 56279315Strasz // Add uses to the set. 57279315Strasz for (const MachineOperand &MOP : phys_regs_and_masks(MI)) { 58279315Strasz if (!MOP.isReg() || !MOP.readsReg()) 59279315Strasz continue; 60279315Strasz addReg(MOP.getReg()); 61279315Strasz } 62279315Strasz} 63279315Strasz 64279315Straszvoid LiveRegUnits::accumulate(const MachineInstr &MI) { 65279315Strasz // Add defs, uses and regmask clobbers to the set. 66279315Strasz for (const MachineOperand &MOP : phys_regs_and_masks(MI)) { 67279315Strasz if (MOP.isRegMask()) { 68279315Strasz addRegsInMask(MOP.getRegMask()); 69279315Strasz continue; 70279315Strasz } 71279315Strasz if (!MOP.isDef() && !MOP.readsReg()) 72279315Strasz continue; 73279315Strasz addReg(MOP.getReg()); 74279315Strasz } 75279315Strasz} 76279315Strasz 77279315Strasz/// Add live-in registers of basic block \p MBB to \p LiveUnits. 78279315Straszstatic void addBlockLiveIns(LiveRegUnits &LiveUnits, 79279315Strasz const MachineBasicBlock &MBB) { 80279315Strasz for (const auto &LI : MBB.liveins()) 81279315Strasz LiveUnits.addRegMasked(LI.PhysReg, LI.LaneMask); 82279315Strasz} 83279315Strasz 84279315Strasz/// Adds all callee saved registers to \p LiveUnits. 85279315Straszstatic void addCalleeSavedRegs(LiveRegUnits &LiveUnits, 86279315Strasz const MachineFunction &MF) { 87279315Strasz const MachineRegisterInfo &MRI = MF.getRegInfo(); 88279315Strasz for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR; ++CSR) 89279315Strasz LiveUnits.addReg(*CSR); 90279315Strasz} 91279315Strasz 92279315Straszvoid LiveRegUnits::addPristines(const MachineFunction &MF) { 93279315Strasz const MachineFrameInfo &MFI = MF.getFrameInfo(); 94279315Strasz if (!MFI.isCalleeSavedInfoValid()) 95279315Strasz return; 96279315Strasz /// This function will usually be called on an empty object, handle this 97279315Strasz /// as a special case. 98279315Strasz if (empty()) { 99279315Strasz /// Add all callee saved regs, then remove the ones that are saved and 100279315Strasz /// restored. 101279315Strasz addCalleeSavedRegs(*this, MF); 102279315Strasz /// Remove the ones that are not saved/restored; they are pristine. 103279315Strasz for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) 104279315Strasz removeReg(Info.getReg()); 105279315Strasz return; 106279315Strasz } 107279315Strasz /// If a callee-saved register that is not pristine is already present 108279315Strasz /// in the set, we should make sure that it stays in it. Precompute the 109279315Strasz /// set of pristine registers in a separate object. 110279315Strasz /// Add all callee saved regs, then remove the ones that are saved+restored. 111279315Strasz LiveRegUnits Pristine(*TRI); 112279315Strasz addCalleeSavedRegs(Pristine, MF); 113279315Strasz /// Remove the ones that are not saved/restored; they are pristine. 114279315Strasz for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) 115279315Strasz Pristine.removeReg(Info.getReg()); 116279315Strasz addUnits(Pristine.getBitVector()); 117279315Strasz} 118279315Strasz 119279315Straszvoid LiveRegUnits::addLiveOuts(const MachineBasicBlock &MBB) { 120279315Strasz const MachineFunction &MF = *MBB.getParent(); 121279315Strasz 122279315Strasz addPristines(MF); 123279315Strasz 124279315Strasz // To get the live-outs we simply merge the live-ins of all successors. 125279315Strasz for (const MachineBasicBlock *Succ : MBB.successors()) 126279315Strasz addBlockLiveIns(*this, *Succ); 127279315Strasz 128279315Strasz // For the return block: Add all callee saved registers. 129279315Strasz if (MBB.isReturnBlock()) { 130279315Strasz const MachineFrameInfo &MFI = MF.getFrameInfo(); 131279315Strasz if (MFI.isCalleeSavedInfoValid()) 132279315Strasz addCalleeSavedRegs(*this, MF); 133279315Strasz } 134279315Strasz} 135279315Strasz 136279315Straszvoid LiveRegUnits::addLiveIns(const MachineBasicBlock &MBB) { 137279315Strasz const MachineFunction &MF = *MBB.getParent(); 138279315Strasz addPristines(MF); 139279315Strasz addBlockLiveIns(*this, MBB); 140279315Strasz} 141279315Strasz