17a7e6055SDimitry Andric //===- LiveRegUnits.cpp - Register Unit Set -------------------------------===//
27a7e6055SDimitry Andric //
37a7e6055SDimitry Andric //                     The LLVM Compiler Infrastructure
47a7e6055SDimitry Andric //
57a7e6055SDimitry Andric // This file is distributed under the University of Illinois Open Source
67a7e6055SDimitry Andric // License. See LICENSE.TXT for details.
77a7e6055SDimitry Andric //
87a7e6055SDimitry Andric //===----------------------------------------------------------------------===//
97a7e6055SDimitry Andric //
107a7e6055SDimitry Andric /// \file This file imlements the LiveRegUnits set.
117a7e6055SDimitry Andric //
127a7e6055SDimitry Andric //===----------------------------------------------------------------------===//
137a7e6055SDimitry Andric 
147a7e6055SDimitry Andric #include "llvm/CodeGen/LiveRegUnits.h"
156d97bb29SDimitry Andric 
167a7e6055SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
177a7e6055SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
187a7e6055SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
197a7e6055SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h"
207a7e6055SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
216d97bb29SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
222cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
237a7e6055SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
247a7e6055SDimitry Andric 
257a7e6055SDimitry Andric using namespace llvm;
267a7e6055SDimitry Andric 
removeRegsNotPreserved(const uint32_t * RegMask)277a7e6055SDimitry Andric void LiveRegUnits::removeRegsNotPreserved(const uint32_t *RegMask) {
287a7e6055SDimitry Andric   for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
297a7e6055SDimitry Andric     for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
307a7e6055SDimitry Andric       if (MachineOperand::clobbersPhysReg(RegMask, *RootReg))
317a7e6055SDimitry Andric         Units.reset(U);
327a7e6055SDimitry Andric     }
337a7e6055SDimitry Andric   }
347a7e6055SDimitry Andric }
357a7e6055SDimitry Andric 
addRegsInMask(const uint32_t * RegMask)367a7e6055SDimitry Andric void LiveRegUnits::addRegsInMask(const uint32_t *RegMask) {
377a7e6055SDimitry Andric   for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
387a7e6055SDimitry Andric     for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
397a7e6055SDimitry Andric       if (MachineOperand::clobbersPhysReg(RegMask, *RootReg))
407a7e6055SDimitry Andric         Units.set(U);
417a7e6055SDimitry Andric     }
427a7e6055SDimitry Andric   }
437a7e6055SDimitry Andric }
447a7e6055SDimitry Andric 
stepBackward(const MachineInstr & MI)457a7e6055SDimitry Andric void LiveRegUnits::stepBackward(const MachineInstr &MI) {
467a7e6055SDimitry Andric   // Remove defined registers and regmask kills from the set.
477a7e6055SDimitry Andric   for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
487a7e6055SDimitry Andric     if (O->isReg()) {
49*4ba319b5SDimitry Andric       if (!O->isDef() || O->isDebug())
507a7e6055SDimitry Andric         continue;
517a7e6055SDimitry Andric       unsigned Reg = O->getReg();
527a7e6055SDimitry Andric       if (!TargetRegisterInfo::isPhysicalRegister(Reg))
537a7e6055SDimitry Andric         continue;
547a7e6055SDimitry Andric       removeReg(Reg);
557a7e6055SDimitry Andric     } else if (O->isRegMask())
567a7e6055SDimitry Andric       removeRegsNotPreserved(O->getRegMask());
577a7e6055SDimitry Andric   }
587a7e6055SDimitry Andric 
597a7e6055SDimitry Andric   // Add uses to the set.
607a7e6055SDimitry Andric   for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
61*4ba319b5SDimitry Andric     if (!O->isReg() || !O->readsReg() || O->isDebug())
627a7e6055SDimitry Andric       continue;
637a7e6055SDimitry Andric     unsigned Reg = O->getReg();
647a7e6055SDimitry Andric     if (!TargetRegisterInfo::isPhysicalRegister(Reg))
657a7e6055SDimitry Andric       continue;
667a7e6055SDimitry Andric     addReg(Reg);
677a7e6055SDimitry Andric   }
687a7e6055SDimitry Andric }
697a7e6055SDimitry Andric 
accumulate(const MachineInstr & MI)70c4394386SDimitry Andric void LiveRegUnits::accumulate(const MachineInstr &MI) {
717a7e6055SDimitry Andric   // Add defs, uses and regmask clobbers to the set.
727a7e6055SDimitry Andric   for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
737a7e6055SDimitry Andric     if (O->isReg()) {
747a7e6055SDimitry Andric       unsigned Reg = O->getReg();
757a7e6055SDimitry Andric       if (!TargetRegisterInfo::isPhysicalRegister(Reg))
767a7e6055SDimitry Andric         continue;
777a7e6055SDimitry Andric       if (!O->isDef() && !O->readsReg())
787a7e6055SDimitry Andric         continue;
797a7e6055SDimitry Andric       addReg(Reg);
807a7e6055SDimitry Andric     } else if (O->isRegMask())
817a7e6055SDimitry Andric       addRegsInMask(O->getRegMask());
827a7e6055SDimitry Andric   }
837a7e6055SDimitry Andric }
847a7e6055SDimitry Andric 
857a7e6055SDimitry Andric /// Add live-in registers of basic block \p MBB to \p LiveUnits.
addBlockLiveIns(LiveRegUnits & LiveUnits,const MachineBasicBlock & MBB)866d97bb29SDimitry Andric static void addBlockLiveIns(LiveRegUnits &LiveUnits,
876d97bb29SDimitry Andric                             const MachineBasicBlock &MBB) {
887a7e6055SDimitry Andric   for (const auto &LI : MBB.liveins())
897a7e6055SDimitry Andric     LiveUnits.addRegMasked(LI.PhysReg, LI.LaneMask);
907a7e6055SDimitry Andric }
917a7e6055SDimitry Andric 
926d97bb29SDimitry Andric /// Adds all callee saved registers to \p LiveUnits.
addCalleeSavedRegs(LiveRegUnits & LiveUnits,const MachineFunction & MF)936d97bb29SDimitry Andric static void addCalleeSavedRegs(LiveRegUnits &LiveUnits,
946d97bb29SDimitry Andric                                const MachineFunction &MF) {
956d97bb29SDimitry Andric   const MachineRegisterInfo &MRI = MF.getRegInfo();
966d97bb29SDimitry Andric   for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR; ++CSR)
976d97bb29SDimitry Andric     LiveUnits.addReg(*CSR);
987a7e6055SDimitry Andric }
997a7e6055SDimitry Andric 
addPristines(const MachineFunction & MF)1002cab237bSDimitry Andric void LiveRegUnits::addPristines(const MachineFunction &MF) {
1016d97bb29SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
1026d97bb29SDimitry Andric   if (!MFI.isCalleeSavedInfoValid())
1036d97bb29SDimitry Andric     return;
1042cab237bSDimitry Andric   /// This function will usually be called on an empty object, handle this
1052cab237bSDimitry Andric   /// as a special case.
1062cab237bSDimitry Andric   if (empty()) {
1072cab237bSDimitry Andric     /// Add all callee saved regs, then remove the ones that are saved and
1082cab237bSDimitry Andric     /// restored.
1092cab237bSDimitry Andric     addCalleeSavedRegs(*this, MF);
1106d97bb29SDimitry Andric     /// Remove the ones that are not saved/restored; they are pristine.
1117a7e6055SDimitry Andric     for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
1122cab237bSDimitry Andric       removeReg(Info.getReg());
1132cab237bSDimitry Andric     return;
1142cab237bSDimitry Andric   }
1152cab237bSDimitry Andric   /// If a callee-saved register that is not pristine is already present
1162cab237bSDimitry Andric   /// in the set, we should make sure that it stays in it. Precompute the
1172cab237bSDimitry Andric   /// set of pristine registers in a separate object.
1182cab237bSDimitry Andric   /// Add all callee saved regs, then remove the ones that are saved+restored.
1192cab237bSDimitry Andric   LiveRegUnits Pristine(*TRI);
1202cab237bSDimitry Andric   addCalleeSavedRegs(Pristine, MF);
1212cab237bSDimitry Andric   /// Remove the ones that are not saved/restored; they are pristine.
1222cab237bSDimitry Andric   for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
1232cab237bSDimitry Andric     Pristine.removeReg(Info.getReg());
1242cab237bSDimitry Andric   addUnits(Pristine.getBitVector());
1257a7e6055SDimitry Andric }
1267a7e6055SDimitry Andric 
addLiveOuts(const MachineBasicBlock & MBB)1277a7e6055SDimitry Andric void LiveRegUnits::addLiveOuts(const MachineBasicBlock &MBB) {
1287a7e6055SDimitry Andric   const MachineFunction &MF = *MBB.getParent();
1296d97bb29SDimitry Andric   if (!MBB.succ_empty()) {
1302cab237bSDimitry Andric     addPristines(MF);
1316d97bb29SDimitry Andric     // To get the live-outs we simply merge the live-ins of all successors.
1326d97bb29SDimitry Andric     for (const MachineBasicBlock *Succ : MBB.successors())
1336d97bb29SDimitry Andric       addBlockLiveIns(*this, *Succ);
1346d97bb29SDimitry Andric   } else if (MBB.isReturnBlock()) {
1356d97bb29SDimitry Andric     // For the return block: Add all callee saved registers.
1367a7e6055SDimitry Andric     const MachineFrameInfo &MFI = MF.getFrameInfo();
1376d97bb29SDimitry Andric     if (MFI.isCalleeSavedInfoValid())
1386d97bb29SDimitry Andric       addCalleeSavedRegs(*this, MF);
1397a7e6055SDimitry Andric   }
1407a7e6055SDimitry Andric }
1417a7e6055SDimitry Andric 
addLiveIns(const MachineBasicBlock & MBB)1427a7e6055SDimitry Andric void LiveRegUnits::addLiveIns(const MachineBasicBlock &MBB) {
1437a7e6055SDimitry Andric   const MachineFunction &MF = *MBB.getParent();
1442cab237bSDimitry Andric   addPristines(MF);
1456d97bb29SDimitry Andric   addBlockLiveIns(*this, MBB);
1467a7e6055SDimitry Andric }
147