Skip to content
This repository was archived by the owner on Sep 2, 2018. It is now read-only.

[AVR] Don't reserve the frame pointer when spilling registers #226

Merged
merged 1 commit into from
Sep 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 1 addition & 51 deletions lib/CodeGen/RegAllocGreedy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,6 @@ class RAGreedy : public MachineFunctionPass,
std::unique_ptr<Spiller> SpillerInstance;
PQueue Queue;
unsigned NextCascade;

// AVR specific: have we already unallocated REG_Y after a spill was done?
bool IsYReserved;

// Live ranges pass through a number of stages as we try to allocate them.
// Some of the stages may also create new live ranges:
Expand Down Expand Up @@ -425,7 +422,6 @@ class RAGreedy : public MachineFunctionPass,
void collectHintInfo(unsigned, HintsInfo &);

bool isUnusedCalleeSavedReg(unsigned PhysReg) const;
void UndoRegYAllocation();
};
} // end anonymous namespace

Expand All @@ -452,7 +448,7 @@ FunctionPass* llvm::createGreedyRegisterAllocator() {
return new RAGreedy();
}

RAGreedy::RAGreedy(): MachineFunctionPass(ID), IsYReserved(false) {
RAGreedy::RAGreedy(): MachineFunctionPass(ID) {
initializeLiveDebugVariablesPass(*PassRegistry::getPassRegistry());
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
Expand Down Expand Up @@ -1642,34 +1638,6 @@ RAGreedy::tryInstructionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
return 0;
}

// AVR specific code used to handle the reservation of REG_Y if any other
// register has been spilled.
// :NOTE: KEEP THIS CONSTANT UPDATED with the backend!
// This has to be a define because of linkage problems between libraries.
#define REG_Y (51U)
namespace llvm {
bool RA_ReserveREG_Y = false;
bool RA_InSpillerCode = false;
} // end of namespace llvm

void RAGreedy::UndoRegYAllocation() {
// search through all virtual registers where REG_Y has been assigned and
// send them back to the work list for reallocation
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
unsigned VirtReg = TargetRegisterInfo::index2VirtReg(i);
if (MRI->reg_nodbg_empty(VirtReg))
continue;

for (MCRegAliasIterator AI(REG_Y, TRI, true); AI.isValid(); ++AI)
if (VRM->getPhys(VirtReg) == *AI) {
LiveInterval &LI = LIS->getInterval(VirtReg);
Matrix->unassign(LI);
enqueue(&LI);
}
}
}
#undef REG_Y


//===----------------------------------------------------------------------===//
// Local Splitting
Expand Down Expand Up @@ -2610,25 +2578,10 @@ unsigned RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
DEBUG(dbgs() << "Do as if this register is in memory\n");
NewVRegs.push_back(VirtReg.reg);
} else {
RA_InSpillerCode = true;
NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled);
LiveRangeEdit LRE(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
spiller().spill(LRE);
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Done);
RA_InSpillerCode = false;

// AVR specific: If we have reached this point and the backend has notified
// it has inserted a spill via ReserveREG_Y, then search for any allocations
// of REG_Y in the live intervals and undo them.
if (!IsYReserved && RA_ReserveREG_Y) {
// do all this work only once
IsYReserved = true;
// update the reserved register list
MRI->freezeReservedRegs(VRM->getMachineFunction());
RegClassInfo.runOnMachineFunction(VRM->getMachineFunction());
// finally perform the real work
UndoRegYAllocation();
}

if (VerifyEnabled)
MF->verify(this, "After spilling");
Expand Down Expand Up @@ -2688,8 +2641,5 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
postOptimization();

releaseMemory();

IsYReserved = false;
RA_ReserveREG_Y = false;
return true;
}
12 changes: 1 addition & 11 deletions lib/Target/AVR/AVRInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,6 @@

namespace llvm {

// External variable defined inside the register allocator to indicate if
// we should reserve REG_Y if it is going to be used as the frame pointer.
extern bool RA_ReserveREG_Y;
// External variable defined inside the register allocator to indicate if
// the register allocator is executing code inside the spiller.
extern bool RA_InSpillerCode;

AVRInstrInfo::AVRInstrInfo()
: AVRGenInstrInfo(AVR::ADJCALLSTACKDOWN, AVR::ADJCALLSTACKUP), RI() {}

Expand Down Expand Up @@ -134,10 +127,7 @@ void AVRInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
MachineFunction &MF = *MBB.getParent();
AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();

if (RA_InSpillerCode && !AFI->getHasSpills()) {
AFI->setHasSpills(true);
RA_ReserveREG_Y = true;
}
AFI->setHasSpills(true);

DebugLoc DL;
if (MI != MBB.end()) {
Expand Down