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 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 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 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()) { 497a7e6055SDimitry Andric if (!O->isDef()) 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) { 617a7e6055SDimitry Andric if (!O->isReg() || !O->readsReg()) 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 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. 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. 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 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 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 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