aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/RegisterScavenging.cpp
diff options
context:
space:
mode:
authorJohn Mosby <ojomojo@gmail.com>2009-08-06 16:32:47 +0000
committerJohn Mosby <ojomojo@gmail.com>2009-08-06 16:32:47 +0000
commite0161ea1050fd4107f3307b1e25b3aac02c2ba16 (patch)
tree14de792c8fea8a385b0a823423bbddac7bddccee /lib/CodeGen/RegisterScavenging.cpp
parent759b88898d0c06134342f44e81a625ada10c136a (diff)
downloadexternal_llvm-e0161ea1050fd4107f3307b1e25b3aac02c2ba16.zip
external_llvm-e0161ea1050fd4107f3307b1e25b3aac02c2ba16.tar.gz
external_llvm-e0161ea1050fd4107f3307b1e25b3aac02c2ba16.tar.bz2
Reg Scavenging generalization (Thumb support):
- start support for new PEI w/reg alloc, allow running RS from emit{Pro,Epi}logue() target hooks. - fix minor issue with recursion detection. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78318 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegisterScavenging.cpp')
-rw-r--r--lib/CodeGen/RegisterScavenging.cpp79
1 files changed, 52 insertions, 27 deletions
diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp
index 97751cd..c3e03ab 100644
--- a/lib/CodeGen/RegisterScavenging.cpp
+++ b/lib/CodeGen/RegisterScavenging.cpp
@@ -16,6 +16,7 @@
#define DEBUG_TYPE "reg-scavenging"
#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -84,6 +85,28 @@ void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) {
RegsAvailable.set(SubReg);
}
+void RegScavenger::initRegState() {
+ ScavengedReg = 0;
+ ScavengedRC = NULL;
+ ScavengeRestore = NULL;
+ CurrDist = 0;
+ DistanceMap.clear();
+
+ // All registers started out unused.
+ RegsAvailable.set();
+
+ // Reserved registers are always used.
+ RegsAvailable ^= ReservedRegs;
+
+ // Live-in registers are in use.
+ if (MBB) {
+ if (!MBB->livein_empty())
+ for (MachineBasicBlock::const_livein_iterator I = MBB->livein_begin(),
+ E = MBB->livein_end(); I != E; ++I)
+ setUsed(*I);
+ }
+}
+
void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
MachineFunction &MF = *mbb->getParent();
const TargetMachine &TM = MF.getTarget();
@@ -94,6 +117,7 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
assert((NumPhysRegs == 0 || NumPhysRegs == TRI->getNumRegs()) &&
"Target changed?");
+ // Self-initialize.
if (!MBB) {
NumPhysRegs = TRI->getNumRegs();
RegsAvailable.resize(NumPhysRegs);
@@ -104,29 +128,23 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
// Create callee-saved registers bitvector.
CalleeSavedRegs.resize(NumPhysRegs);
const unsigned *CSRegs = TRI->getCalleeSavedRegs();
- if (CSRegs != NULL)
- for (unsigned i = 0; CSRegs[i]; ++i)
- CalleeSavedRegs.set(CSRegs[i]);
+ if (CSRegs != NULL) {
+ // At this point we know which CSRs are used by the current function,
+ // so allow those that are _not_ already used to be available to RS.
+ MachineFrameInfo *FFI = MF.getFrameInfo();
+ const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo();
+
+ for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+ CalleeSavedRegs.set(CSI[i].getReg());
+ }
+ }
}
- MBB = mbb;
- ScavengedReg = 0;
- ScavengedRC = NULL;
- ScavengeRestore = NULL;
- CurrDist = 0;
- DistanceMap.clear();
-
- // All registers started out unused.
- RegsAvailable.set();
-
- // Reserved registers are always used.
- RegsAvailable ^= ReservedRegs;
-
- // Live-in registers are in use.
- if (!MBB->livein_empty())
- for (MachineBasicBlock::const_livein_iterator I = MBB->livein_begin(),
- E = MBB->livein_end(); I != E; ++I)
- setUsed(*I);
+ // RS used within emit{Pro,Epi}logue()
+ if (mbb != MBB) {
+ MBB = mbb;
+ initRegState();
+ }
Tracking = false;
}
@@ -216,7 +234,7 @@ void RegScavenger::forward() {
UseMOs.push_back(std::make_pair(&MO,i));
else if (MO.isEarlyClobber())
EarlyClobberMOs.push_back(std::make_pair(&MO,i));
- else
+ else if (MO.isDef())
DefMOs.push_back(std::make_pair(&MO,i));
}
@@ -227,7 +245,9 @@ void RegScavenger::forward() {
unsigned Idx = UseMOs[i].second;
unsigned Reg = MO.getReg();
- assert(isUsed(Reg) && "Using an undefined register!");
+ // Allow free CSRs to be processed as uses.
+ assert((isUsed(Reg) || !CalleeSavedRegs[Reg]) &&
+ "Using an undefined register!");
// Two-address operands implicitly kill.
if ((MO.isKill() || MI->isRegTiedToDefOperand(Idx)) && !isReserved(Reg)) {
@@ -427,7 +447,8 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
// Mask off the registers which are not in the TargetRegisterClass.
BitVector Candidates(NumPhysRegs, false);
CreateRegClassMask(RC, Candidates);
- Candidates ^= ReservedRegs & Candidates; // Do not include reserved registers.
+ // Do not include reserved registers.
+ Candidates ^= ReservedRegs & Candidates;
// Exclude all the registers being used by the instruction.
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
@@ -463,8 +484,11 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
assert(ScavengedReg == 0 &&
"Scavenger slot is live, unable to scavenge another register!");
- // Make sure SReg is marked as used. It could be considered available if it is
- // one of the callee saved registers, but hasn't been spilled.
+ // Avoid infinite regress
+ ScavengedReg = SReg;
+
+ // Make sure SReg is marked as used. It could be considered available
+ // if it is one of the callee saved registers, but hasn't been spilled.
if (!isUsed(SReg)) {
MBB->addLiveIn(SReg);
setUsed(SReg);
@@ -480,7 +504,8 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
? MachineBasicBlock::iterator(MaxUseMI) : MBB->getFirstTerminator();
TII->loadRegFromStackSlot(*MBB, II, SReg, ScavengingFrameIndex, RC);
ScavengeRestore = prior(II);
- ScavengedReg = SReg;
+ // Doing this here leads to infinite regress
+ // ScavengedReg = SReg;
ScavengedRC = RC;
return SReg;