[llvm] r276043 - RegisterScavenger: Introduce backward() mode.
Matthias Braun via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 19 15:37:02 PDT 2016
Author: matze
Date: Tue Jul 19 17:37:02 2016
New Revision: 276043
URL: http://llvm.org/viewvc/llvm-project?rev=276043&view=rev
Log:
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
Modified:
llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h
llvm/trunk/lib/CodeGen/RegisterScavenging.cpp
Modified: llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h?rev=276043&r1=276042&r2=276043&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h (original)
+++ llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h Tue Jul 19 17:37:02 2016
@@ -75,6 +75,12 @@ public:
/// Start tracking liveness from the begin of basic block \p MBB.
void enterBasicBlock(MachineBasicBlock &MBB);
+ /// Start tracking liveness from the end of basic block \p MBB.
+ /// Use backward() to move towards the beginning of the block. This is
+ /// preferred to enterBasicBlock() and forward() because it does not depend
+ /// on the presence of kill flags.
+ void enterBasicBlockEnd(MachineBasicBlock &MBB);
+
/// Move the internal MBB iterator and update register states.
void forward();
@@ -94,6 +100,17 @@ public:
while (MBBI != I) unprocess();
}
+ /// Update internal register state and move MBB iterator backwards.
+ /// Contrary to unprocess() this method gives precise results even in the
+ /// absence of kill flags.
+ void backward();
+
+ /// Call backward() as long as the internal iterator does not point to \p I.
+ void backward(MachineBasicBlock::iterator I) {
+ while (MBBI != I)
+ backward();
+ }
+
/// Move the internal MBB iterator but do not update register states.
void skipTo(MachineBasicBlock::iterator I) {
if (I == MachineBasicBlock::iterator(nullptr))
@@ -168,6 +185,9 @@ private:
/// Add all Reg Units that Reg contains to BV.
void addRegUnits(BitVector &BV, unsigned Reg);
+ /// Remove all Reg Units that \p Reg contains from \p BV.
+ void removeRegUnits(BitVector &BV, unsigned Reg);
+
/// Return the candidate register that is unused for the longest after
/// StartMI. UseMI is set to the instruction where the search stopped.
///
@@ -177,9 +197,11 @@ private:
unsigned InstrLimit,
MachineBasicBlock::iterator &UseMI);
- /// Allow resetting register state info for multiple
- /// passes over/within the same function.
- void initRegState();
+ /// Initialize RegisterScavenger.
+ void init(MachineBasicBlock &MBB);
+
+ /// Mark live-in registers of basic block as used.
+ void setLiveInsUsed(const MachineBasicBlock &MBB);
};
} // End llvm namespace
Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterScavenging.cpp?rev=276043&r1=276042&r2=276043&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegisterScavenging.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Tue Jul 19 17:37:02 2016
@@ -39,28 +39,7 @@ void RegScavenger::setRegUsed(unsigned R
}
}
-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(Machi
}
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;
More information about the llvm-commits
mailing list