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"
157a7e6055SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
167a7e6055SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
177a7e6055SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
187a7e6055SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h"
197a7e6055SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
207a7e6055SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
217a7e6055SDimitry Andric #include "llvm/Target/TargetRegisterInfo.h"
227a7e6055SDimitry Andric 
237a7e6055SDimitry Andric using namespace llvm;
247a7e6055SDimitry Andric 
257a7e6055SDimitry Andric void LiveRegUnits::removeRegsNotPreserved(const uint32_t *RegMask) {
267a7e6055SDimitry Andric   for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
277a7e6055SDimitry Andric     for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
287a7e6055SDimitry Andric       if (MachineOperand::clobbersPhysReg(RegMask, *RootReg))
297a7e6055SDimitry Andric         Units.reset(U);
307a7e6055SDimitry Andric     }
317a7e6055SDimitry Andric   }
327a7e6055SDimitry Andric }
337a7e6055SDimitry Andric 
347a7e6055SDimitry Andric void LiveRegUnits::addRegsInMask(const uint32_t *RegMask) {
357a7e6055SDimitry Andric   for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
367a7e6055SDimitry Andric     for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
377a7e6055SDimitry Andric       if (MachineOperand::clobbersPhysReg(RegMask, *RootReg))
387a7e6055SDimitry Andric         Units.set(U);
397a7e6055SDimitry Andric     }
407a7e6055SDimitry Andric   }
417a7e6055SDimitry Andric }
427a7e6055SDimitry Andric 
437a7e6055SDimitry Andric void LiveRegUnits::stepBackward(const MachineInstr &MI) {
447a7e6055SDimitry Andric   // Remove defined registers and regmask kills from the set.
457a7e6055SDimitry Andric   for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
467a7e6055SDimitry Andric     if (O->isReg()) {
477a7e6055SDimitry Andric       if (!O->isDef())
487a7e6055SDimitry Andric         continue;
497a7e6055SDimitry Andric       unsigned Reg = O->getReg();
507a7e6055SDimitry Andric       if (!TargetRegisterInfo::isPhysicalRegister(Reg))
517a7e6055SDimitry Andric         continue;
527a7e6055SDimitry Andric       removeReg(Reg);
537a7e6055SDimitry Andric     } else if (O->isRegMask())
547a7e6055SDimitry Andric       removeRegsNotPreserved(O->getRegMask());
557a7e6055SDimitry Andric   }
567a7e6055SDimitry Andric 
577a7e6055SDimitry Andric   // Add uses to the set.
587a7e6055SDimitry Andric   for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
597a7e6055SDimitry Andric     if (!O->isReg() || !O->readsReg())
607a7e6055SDimitry Andric       continue;
617a7e6055SDimitry Andric     unsigned Reg = O->getReg();
627a7e6055SDimitry Andric     if (!TargetRegisterInfo::isPhysicalRegister(Reg))
637a7e6055SDimitry Andric       continue;
647a7e6055SDimitry Andric     addReg(Reg);
657a7e6055SDimitry Andric   }
667a7e6055SDimitry Andric }
677a7e6055SDimitry Andric 
687a7e6055SDimitry Andric void LiveRegUnits::accumulateBackward(const MachineInstr &MI) {
697a7e6055SDimitry Andric   // Add defs, uses and regmask clobbers to the set.
707a7e6055SDimitry Andric   for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
717a7e6055SDimitry Andric     if (O->isReg()) {
727a7e6055SDimitry Andric       unsigned Reg = O->getReg();
737a7e6055SDimitry Andric       if (!TargetRegisterInfo::isPhysicalRegister(Reg))
747a7e6055SDimitry Andric         continue;
757a7e6055SDimitry Andric       if (!O->isDef() && !O->readsReg())
767a7e6055SDimitry Andric         continue;
777a7e6055SDimitry Andric       addReg(Reg);
787a7e6055SDimitry Andric     } else if (O->isRegMask())
797a7e6055SDimitry Andric       addRegsInMask(O->getRegMask());
807a7e6055SDimitry Andric   }
817a7e6055SDimitry Andric }
827a7e6055SDimitry Andric 
837a7e6055SDimitry Andric /// Add live-in registers of basic block \p MBB to \p LiveUnits.
847a7e6055SDimitry Andric static void addLiveIns(LiveRegUnits &LiveUnits, const MachineBasicBlock &MBB) {
857a7e6055SDimitry Andric   for (const auto &LI : MBB.liveins())
867a7e6055SDimitry Andric     LiveUnits.addRegMasked(LI.PhysReg, LI.LaneMask);
877a7e6055SDimitry Andric }
887a7e6055SDimitry Andric 
897a7e6055SDimitry Andric static void addLiveOuts(LiveRegUnits &LiveUnits, const MachineBasicBlock &MBB) {
907a7e6055SDimitry Andric   // To get the live-outs we simply merge the live-ins of all successors.
917a7e6055SDimitry Andric   for (const MachineBasicBlock *Succ : MBB.successors())
927a7e6055SDimitry Andric     addLiveIns(LiveUnits, *Succ);
937a7e6055SDimitry Andric }
947a7e6055SDimitry Andric 
957a7e6055SDimitry Andric /// Add pristine registers to the given \p LiveUnits. This function removes
967a7e6055SDimitry Andric /// actually saved callee save registers when \p InPrologueEpilogue is false.
977a7e6055SDimitry Andric static void removeSavedRegs(LiveRegUnits &LiveUnits, const MachineFunction &MF,
987a7e6055SDimitry Andric                             const MachineFrameInfo &MFI,
997a7e6055SDimitry Andric                             const TargetRegisterInfo &TRI) {
1007a7e6055SDimitry Andric   for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
1017a7e6055SDimitry Andric     LiveUnits.removeReg(Info.getReg());
1027a7e6055SDimitry Andric }
1037a7e6055SDimitry Andric 
1047a7e6055SDimitry Andric void LiveRegUnits::addLiveOuts(const MachineBasicBlock &MBB) {
1057a7e6055SDimitry Andric   const MachineFunction &MF = *MBB.getParent();
1067a7e6055SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
1077a7e6055SDimitry Andric   if (MFI.isCalleeSavedInfoValid()) {
1087a7e6055SDimitry Andric     for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I)
1097a7e6055SDimitry Andric       addReg(*I);
1107a7e6055SDimitry Andric     if (!MBB.isReturnBlock())
1117a7e6055SDimitry Andric       removeSavedRegs(*this, MF, MFI, *TRI);
1127a7e6055SDimitry Andric   }
1137a7e6055SDimitry Andric   ::addLiveOuts(*this, MBB);
1147a7e6055SDimitry Andric }
1157a7e6055SDimitry Andric 
1167a7e6055SDimitry Andric void LiveRegUnits::addLiveIns(const MachineBasicBlock &MBB) {
1177a7e6055SDimitry Andric   const MachineFunction &MF = *MBB.getParent();
1187a7e6055SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
1197a7e6055SDimitry Andric   if (MFI.isCalleeSavedInfoValid()) {
1207a7e6055SDimitry Andric     for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I)
1217a7e6055SDimitry Andric       addReg(*I);
1227a7e6055SDimitry Andric     if (&MBB != &MF.front())
1237a7e6055SDimitry Andric       removeSavedRegs(*this, MF, MFI, *TRI);
1247a7e6055SDimitry Andric   }
1257a7e6055SDimitry Andric   ::addLiveIns(*this, MBB);
1267a7e6055SDimitry Andric }
127