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