summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/CMakeLists.txt1
-rw-r--r--llvm/lib/CodeGen/LiveRegUnits.cpp97
-rw-r--r--llvm/lib/CodeGen/RegisterScavenging.cpp67
3 files changed, 106 insertions, 59 deletions
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 398ea88363b..fb30218a838 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -46,6 +46,7 @@ add_llvm_library(LLVMCodeGen
LiveRangeCalc.cpp
LiveRangeEdit.cpp
LiveRegMatrix.cpp
+ LiveRegUnits.cpp
LiveStackAnalysis.cpp
LiveVariables.cpp
LLVMTargetMachine.cpp
diff --git a/llvm/lib/CodeGen/LiveRegUnits.cpp b/llvm/lib/CodeGen/LiveRegUnits.cpp
new file mode 100644
index 00000000000..14da799a63f
--- /dev/null
+++ b/llvm/lib/CodeGen/LiveRegUnits.cpp
@@ -0,0 +1,97 @@
+//===--- LiveRegUnits.cpp - Register Unit Set -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This file imlements the LiveRegUnits set.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/LiveRegUnits.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
+using namespace llvm;
+
+void LiveRegUnits::removeRegsNotPreserved(const uint32_t *RegMask) {
+ for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
+ for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
+ if (MachineOperand::clobbersPhysReg(RegMask, *RootReg))
+ Units.reset(U);
+ }
+ }
+}
+
+void LiveRegUnits::stepBackward(const MachineInstr &MI) {
+ // Remove defined registers and regmask kills from the set.
+ for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
+ if (O->isReg()) {
+ if (!O->isDef())
+ continue;
+ unsigned Reg = O->getReg();
+ if (!TargetRegisterInfo::isPhysicalRegister(Reg))
+ continue;
+ removeReg(Reg);
+ } else if (O->isRegMask())
+ removeRegsNotPreserved(O->getRegMask());
+ }
+
+ // Add uses to the set.
+ for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
+ if (!O->isReg() || !O->readsReg())
+ continue;
+ unsigned Reg = O->getReg();
+ if (!TargetRegisterInfo::isPhysicalRegister(Reg))
+ continue;
+ addReg(Reg);
+ }
+}
+
+/// Add live-in registers of basic block \p MBB to \p LiveUnits.
+static void addLiveIns(LiveRegUnits &LiveUnits, const MachineBasicBlock &MBB) {
+ for (const auto &LI : MBB.liveins())
+ LiveUnits.addRegMasked(LI.PhysReg, LI.LaneMask);
+}
+
+static void addLiveOuts(LiveRegUnits &LiveUnits, const MachineBasicBlock &MBB) {
+ // To get the live-outs we simply merge the live-ins of all successors.
+ for (const MachineBasicBlock *Succ : MBB.successors())
+ addLiveIns(LiveUnits, *Succ);
+}
+
+/// Add pristine registers to the given \p LiveUnits. This function removes
+/// actually saved callee save registers when \p InPrologueEpilogue is false.
+static void removeSavedRegs(LiveRegUnits &LiveUnits, const MachineFunction &MF,
+ const MachineFrameInfo &MFI,
+ const TargetRegisterInfo &TRI) {
+ for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
+ LiveUnits.removeReg(Info.getReg());
+}
+
+void LiveRegUnits::addLiveOuts(const MachineBasicBlock &MBB) {
+ const MachineFunction &MF = *MBB.getParent();
+ const MachineFrameInfo &MFI = MF.getFrameInfo();
+ if (MFI.isCalleeSavedInfoValid()) {
+ for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I)
+ addReg(*I);
+ if (!MBB.isReturnBlock())
+ removeSavedRegs(*this, MF, MFI, *TRI);
+ }
+ ::addLiveOuts(*this, MBB);
+}
+
+void LiveRegUnits::addLiveIns(const MachineBasicBlock &MBB) {
+ const MachineFunction &MF = *MBB.getParent();
+ const MachineFrameInfo &MFI = MF.getFrameInfo();
+ if (MFI.isCalleeSavedInfoValid()) {
+ for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I)
+ addReg(*I);
+ if (&MBB != &MF.front())
+ removeSavedRegs(*this, MF, MFI, *TRI);
+ }
+ ::addLiveIns(*this, MBB);
+}
diff --git a/llvm/lib/CodeGen/RegisterScavenging.cpp b/llvm/lib/CodeGen/RegisterScavenging.cpp
index fdf741fd58f..23e07581fc8 100644
--- a/llvm/lib/CodeGen/RegisterScavenging.cpp
+++ b/llvm/lib/CodeGen/RegisterScavenging.cpp
@@ -32,11 +32,7 @@ using namespace llvm;
#define DEBUG_TYPE "reg-scavenging"
void RegScavenger::setRegUsed(unsigned Reg, LaneBitmask LaneMask) {
- for (MCRegUnitMaskIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
- LaneBitmask UnitMask = (*RUI).second;
- if (UnitMask.none() || (LaneMask & UnitMask).any())
- RegUnitsAvailable.reset((*RUI).first);
- }
+ LiveUnits.addRegMasked(Reg, LaneMask);
}
void RegScavenger::init(MachineBasicBlock &MBB) {
@@ -44,6 +40,7 @@ void RegScavenger::init(MachineBasicBlock &MBB) {
TII = MF.getSubtarget().getInstrInfo();
TRI = MF.getSubtarget().getRegisterInfo();
MRI = &MF.getRegInfo();
+ LiveUnits.init(*TRI);
assert((NumRegUnits == 0 || NumRegUnits == TRI->getNumRegUnits()) &&
"Target changed?");
@@ -51,7 +48,6 @@ void RegScavenger::init(MachineBasicBlock &MBB) {
// Self-initialize.
if (!this->MBB) {
NumRegUnits = TRI->getNumRegUnits();
- RegUnitsAvailable.resize(NumRegUnits);
KillRegUnits.resize(NumRegUnits);
DefRegUnits.resize(NumRegUnits);
TmpRegUnits.resize(NumRegUnits);
@@ -64,32 +60,17 @@ void RegScavenger::init(MachineBasicBlock &MBB) {
I->Restore = nullptr;
}
- // All register units start out unused.
- RegUnitsAvailable.set();
-
- // Pristine CSRs are not available.
- BitVector PR = MF.getFrameInfo().getPristineRegs(MF);
- for (int I = PR.find_first(); I>0; I = PR.find_next(I))
- setRegUsed(I);
-
Tracking = false;
}
-void RegScavenger::setLiveInsUsed(const MachineBasicBlock &MBB) {
- for (const auto &LI : MBB.liveins())
- setRegUsed(LI.PhysReg, LI.LaneMask);
-}
-
void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) {
init(MBB);
- setLiveInsUsed(MBB);
+ LiveUnits.addLiveIns(MBB);
}
void RegScavenger::enterBasicBlockEnd(MachineBasicBlock &MBB) {
init(MBB);
- // Merge live-ins of successors to get live-outs.
- for (const MachineBasicBlock *Succ : MBB.successors())
- setLiveInsUsed(*Succ);
+ LiveUnits.addLiveOuts(MBB);
// Move internal iterator at the last instruction of the block.
if (MBB.begin() != MBB.end()) {
@@ -263,36 +244,7 @@ void RegScavenger::backward() {
assert(Tracking && "Must be tracking to determine kills and defs");
const MachineInstr &MI = *MBBI;
- // Defined or clobbered registers are available now.
- for (const MachineOperand &MO : MI.operands()) {
- if (MO.isRegMask()) {
- for (unsigned RU = 0, RUEnd = TRI->getNumRegUnits(); RU != RUEnd;
- ++RU) {
- for (MCRegUnitRootIterator RURI(RU, TRI); RURI.isValid(); ++RURI) {
- if (MO.clobbersPhysReg(*RURI)) {
- RegUnitsAvailable.set(RU);
- break;
- }
- }
- }
- } else if (MO.isReg() && MO.isDef()) {
- unsigned Reg = MO.getReg();
- if (!Reg || TargetRegisterInfo::isVirtualRegister(Reg) ||
- isReserved(Reg))
- continue;
- addRegUnits(RegUnitsAvailable, Reg);
- }
- }
- // Mark read registers as unavailable.
- for (const MachineOperand &MO : MI.uses()) {
- if (MO.isReg() && MO.readsReg()) {
- unsigned Reg = MO.getReg();
- if (!Reg || TargetRegisterInfo::isVirtualRegister(Reg) ||
- isReserved(Reg))
- continue;
- removeRegUnits(RegUnitsAvailable, Reg);
- }
- }
+ LiveUnits.stepBackward(MI);
if (MBBI == MBB->begin()) {
MBBI = MachineBasicBlock::iterator(nullptr);
@@ -302,12 +254,9 @@ void RegScavenger::backward() {
}
bool RegScavenger::isRegUsed(unsigned Reg, bool includeReserved) const {
- if (includeReserved && isReserved(Reg))
- return true;
- for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI)
- if (!RegUnitsAvailable.test(*RUI))
- return true;
- return false;
+ if (isReserved(Reg))
+ return includeReserved;
+ return !LiveUnits.available(Reg);
}
unsigned RegScavenger::FindUnusedReg(const TargetRegisterClass *RC) const {
OpenPOWER on IntegriCloud