forked from OSchip/llvm-project
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. llvm-svn: 78318
This commit is contained in:
parent
b29996eb23
commit
beb7ea2931
|
@ -86,6 +86,10 @@ public:
|
||||||
/// basic block.
|
/// basic block.
|
||||||
void enterBasicBlock(MachineBasicBlock *mbb);
|
void enterBasicBlock(MachineBasicBlock *mbb);
|
||||||
|
|
||||||
|
/// initRegState - allow resetting register state info for multiple
|
||||||
|
/// passes over/within the same function.
|
||||||
|
void initRegState();
|
||||||
|
|
||||||
/// forward / backward - Move the internal MBB iterator and update register
|
/// forward / backward - Move the internal MBB iterator and update register
|
||||||
/// states.
|
/// states.
|
||||||
void forward();
|
void forward();
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#define DEBUG_TYPE "reg-scavenging"
|
#define DEBUG_TYPE "reg-scavenging"
|
||||||
#include "llvm/CodeGen/RegisterScavenging.h"
|
#include "llvm/CodeGen/RegisterScavenging.h"
|
||||||
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||||
#include "llvm/CodeGen/MachineInstr.h"
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
|
@ -84,32 +85,7 @@ void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) {
|
||||||
RegsAvailable.set(SubReg);
|
RegsAvailable.set(SubReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
|
void RegScavenger::initRegState() {
|
||||||
MachineFunction &MF = *mbb->getParent();
|
|
||||||
const TargetMachine &TM = MF.getTarget();
|
|
||||||
TII = TM.getInstrInfo();
|
|
||||||
TRI = TM.getRegisterInfo();
|
|
||||||
MRI = &MF.getRegInfo();
|
|
||||||
|
|
||||||
assert((NumPhysRegs == 0 || NumPhysRegs == TRI->getNumRegs()) &&
|
|
||||||
"Target changed?");
|
|
||||||
|
|
||||||
if (!MBB) {
|
|
||||||
NumPhysRegs = TRI->getNumRegs();
|
|
||||||
RegsAvailable.resize(NumPhysRegs);
|
|
||||||
|
|
||||||
// Create reserved registers bitvector.
|
|
||||||
ReservedRegs = TRI->getReservedRegs(MF);
|
|
||||||
|
|
||||||
// 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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
MBB = mbb;
|
|
||||||
ScavengedReg = 0;
|
ScavengedReg = 0;
|
||||||
ScavengedRC = NULL;
|
ScavengedRC = NULL;
|
||||||
ScavengeRestore = NULL;
|
ScavengeRestore = NULL;
|
||||||
|
@ -123,10 +99,52 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
|
||||||
RegsAvailable ^= ReservedRegs;
|
RegsAvailable ^= ReservedRegs;
|
||||||
|
|
||||||
// Live-in registers are in use.
|
// Live-in registers are in use.
|
||||||
if (!MBB->livein_empty())
|
if (MBB) {
|
||||||
for (MachineBasicBlock::const_livein_iterator I = MBB->livein_begin(),
|
if (!MBB->livein_empty())
|
||||||
E = MBB->livein_end(); I != E; ++I)
|
for (MachineBasicBlock::const_livein_iterator I = MBB->livein_begin(),
|
||||||
setUsed(*I);
|
E = MBB->livein_end(); I != E; ++I)
|
||||||
|
setUsed(*I);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
|
||||||
|
MachineFunction &MF = *mbb->getParent();
|
||||||
|
const TargetMachine &TM = MF.getTarget();
|
||||||
|
TII = TM.getInstrInfo();
|
||||||
|
TRI = TM.getRegisterInfo();
|
||||||
|
MRI = &MF.getRegInfo();
|
||||||
|
|
||||||
|
assert((NumPhysRegs == 0 || NumPhysRegs == TRI->getNumRegs()) &&
|
||||||
|
"Target changed?");
|
||||||
|
|
||||||
|
// Self-initialize.
|
||||||
|
if (!MBB) {
|
||||||
|
NumPhysRegs = TRI->getNumRegs();
|
||||||
|
RegsAvailable.resize(NumPhysRegs);
|
||||||
|
|
||||||
|
// Create reserved registers bitvector.
|
||||||
|
ReservedRegs = TRI->getReservedRegs(MF);
|
||||||
|
|
||||||
|
// Create callee-saved registers bitvector.
|
||||||
|
CalleeSavedRegs.resize(NumPhysRegs);
|
||||||
|
const unsigned *CSRegs = TRI->getCalleeSavedRegs();
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RS used within emit{Pro,Epi}logue()
|
||||||
|
if (mbb != MBB) {
|
||||||
|
MBB = mbb;
|
||||||
|
initRegState();
|
||||||
|
}
|
||||||
|
|
||||||
Tracking = false;
|
Tracking = false;
|
||||||
}
|
}
|
||||||
|
@ -216,7 +234,7 @@ void RegScavenger::forward() {
|
||||||
UseMOs.push_back(std::make_pair(&MO,i));
|
UseMOs.push_back(std::make_pair(&MO,i));
|
||||||
else if (MO.isEarlyClobber())
|
else if (MO.isEarlyClobber())
|
||||||
EarlyClobberMOs.push_back(std::make_pair(&MO,i));
|
EarlyClobberMOs.push_back(std::make_pair(&MO,i));
|
||||||
else
|
else if (MO.isDef())
|
||||||
DefMOs.push_back(std::make_pair(&MO,i));
|
DefMOs.push_back(std::make_pair(&MO,i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +245,9 @@ void RegScavenger::forward() {
|
||||||
unsigned Idx = UseMOs[i].second;
|
unsigned Idx = UseMOs[i].second;
|
||||||
unsigned Reg = MO.getReg();
|
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.
|
// Two-address operands implicitly kill.
|
||||||
if ((MO.isKill() || MI->isRegTiedToDefOperand(Idx)) && !isReserved(Reg)) {
|
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.
|
// Mask off the registers which are not in the TargetRegisterClass.
|
||||||
BitVector Candidates(NumPhysRegs, false);
|
BitVector Candidates(NumPhysRegs, false);
|
||||||
CreateRegClassMask(RC, Candidates);
|
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.
|
// Exclude all the registers being used by the instruction.
|
||||||
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
|
||||||
|
@ -463,8 +484,11 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
|
||||||
assert(ScavengedReg == 0 &&
|
assert(ScavengedReg == 0 &&
|
||||||
"Scavenger slot is live, unable to scavenge another register!");
|
"Scavenger slot is live, unable to scavenge another register!");
|
||||||
|
|
||||||
// Make sure SReg is marked as used. It could be considered available if it is
|
// Avoid infinite regress
|
||||||
// one of the callee saved registers, but hasn't been spilled.
|
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)) {
|
if (!isUsed(SReg)) {
|
||||||
MBB->addLiveIn(SReg);
|
MBB->addLiveIn(SReg);
|
||||||
setUsed(SReg);
|
setUsed(SReg);
|
||||||
|
@ -480,7 +504,8 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
|
||||||
? MachineBasicBlock::iterator(MaxUseMI) : MBB->getFirstTerminator();
|
? MachineBasicBlock::iterator(MaxUseMI) : MBB->getFirstTerminator();
|
||||||
TII->loadRegFromStackSlot(*MBB, II, SReg, ScavengingFrameIndex, RC);
|
TII->loadRegFromStackSlot(*MBB, II, SReg, ScavengingFrameIndex, RC);
|
||||||
ScavengeRestore = prior(II);
|
ScavengeRestore = prior(II);
|
||||||
ScavengedReg = SReg;
|
// Doing this here leads to infinite regress
|
||||||
|
// ScavengedReg = SReg;
|
||||||
ScavengedRC = RC;
|
ScavengedRC = RC;
|
||||||
|
|
||||||
return SReg;
|
return SReg;
|
||||||
|
|
Loading…
Reference in New Issue