summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/RegisterScavenging.cpp
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2016-07-19 22:37:02 +0000
committerMatthias Braun <matze@braunis.de>2016-07-19 22:37:02 +0000
commit4cb68e104880dbf08ef6546272f57400985de8b2 (patch)
treeee608a88e6c57105765c1148980c63e9fa035245 /llvm/lib/CodeGen/RegisterScavenging.cpp
parentd4ea94eb9422489724d70e1456d27869aced8228 (diff)
downloadbcm5719-llvm-4cb68e104880dbf08ef6546272f57400985de8b2.tar.gz
bcm5719-llvm-4cb68e104880dbf08ef6546272f57400985de8b2.zip
RegisterScavenger: Introduce backward() mode.
This adds two pieces: - RegisterScavenger:::enterBasicBlockEnd() which behaves similar to enterBasicBlock() but starts tracking at the end of the basic block. - A RegisterScavenger::backward() method. It is subtly different from the existing unprocess() method which only considers uses with the kill flag set: If a value is dead at the end of a basic block with a last use inside the basic block, unprocess() will fail to mark it as live. However we cannot change/fix this behaviour because unprocess() needs to perform the exact reverse operation of forward(). Differential Revision: http://reviews.llvm.org/D21873 llvm-svn: 276043
Diffstat (limited to 'llvm/lib/CodeGen/RegisterScavenging.cpp')
-rw-r--r--llvm/lib/CodeGen/RegisterScavenging.cpp107
1 files changed, 84 insertions, 23 deletions
diff --git a/llvm/lib/CodeGen/RegisterScavenging.cpp b/llvm/lib/CodeGen/RegisterScavenging.cpp
index 6b80179190d..79a698d494e 100644
--- a/llvm/lib/CodeGen/RegisterScavenging.cpp
+++ b/llvm/lib/CodeGen/RegisterScavenging.cpp
@@ -39,28 +39,7 @@ void RegScavenger::setRegUsed(unsigned Reg, LaneBitmask LaneMask) {
}
}
-void RegScavenger::initRegState() {
- for (SmallVectorImpl<ScavengedInfo>::iterator I = Scavenged.begin(),
- IE = Scavenged.end(); I != IE; ++I) {
- I->Reg = 0;
- I->Restore = nullptr;
- }
-
- // All register units start out unused.
- RegUnitsAvailable.set();
-
- // Live-in registers are in use.
- for (const auto &LI : MBB->liveins())
- setRegUsed(LI.PhysReg, LI.LaneMask);
-
- // Pristine CSRs are also unavailable.
- const MachineFunction &MF = *MBB->getParent();
- BitVector PR = MF.getFrameInfo()->getPristineRegs(MF);
- for (int I = PR.find_first(); I>0; I = PR.find_next(I))
- setRegUsed(I);
-}
-
-void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) {
+void RegScavenger::init(MachineBasicBlock &MBB) {
MachineFunction &MF = *MBB.getParent();
TII = MF.getSubtarget().getInstrInfo();
TRI = MF.getSubtarget().getRegisterInfo();
@@ -84,16 +63,56 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) {
}
this->MBB = &MBB;
- initRegState();
+ for (SmallVectorImpl<ScavengedInfo>::iterator I = Scavenged.begin(),
+ IE = Scavenged.end(); I != IE; ++I) {
+ I->Reg = 0;
+ 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);
+}
+
+void RegScavenger::enterBasicBlockEnd(MachineBasicBlock &MBB) {
+ init(MBB);
+ // Merge live-ins of successors to get live-outs.
+ for (const MachineBasicBlock *Succ : MBB.successors())
+ setLiveInsUsed(*Succ);
+
+ // Move internal iterator at the last instruction of the block.
+ if (MBB.begin() != MBB.end()) {
+ MBBI = std::prev(MBB.end());
+ Tracking = true;
+ }
+}
+
void RegScavenger::addRegUnits(BitVector &BV, unsigned Reg) {
for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI)
BV.set(*RUI);
}
+void RegScavenger::removeRegUnits(BitVector &BV, unsigned Reg) {
+ for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI)
+ BV.reset(*RUI);
+}
+
void RegScavenger::determineKillsAndDefs() {
assert(Tracking && "Must be tracking to determine kills and defs");
@@ -245,6 +264,48 @@ void RegScavenger::forward() {
setUsed(DefRegUnits);
}
+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);
+ }
+ }
+
+ if (MBBI == MBB->begin()) {
+ MBBI = MachineBasicBlock::iterator(nullptr);
+ Tracking = false;
+ } else
+ --MBBI;
+}
+
bool RegScavenger::isRegUsed(unsigned Reg, bool includeReserved) const {
if (includeReserved && isReserved(Reg))
return true;
OpenPOWER on IntegriCloud