mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-07 16:54:48 +00:00
- Rewrite code that update register live interval that's split.
- Create and update spill slot live intervals. - Lots of bug fixes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58367 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
980e842153
commit
d0e32c5d5c
@ -260,7 +260,12 @@ namespace llvm {
|
|||||||
/// findLiveInMBBs - Given a live range, if the value of the range
|
/// findLiveInMBBs - Given a live range, if the value of the range
|
||||||
/// is live in any MBB returns true as well as the list of basic blocks
|
/// is live in any MBB returns true as well as the list of basic blocks
|
||||||
/// in which the value is live.
|
/// in which the value is live.
|
||||||
bool findLiveInMBBs(const LiveRange &LR,
|
bool findLiveInMBBs(unsigned Start, unsigned End,
|
||||||
|
SmallVectorImpl<MachineBasicBlock*> &MBBs) const;
|
||||||
|
|
||||||
|
/// findReachableMBBs - Return a list MBB that can be reached via any
|
||||||
|
/// branch or fallthroughs. Return true if the list is not empty.
|
||||||
|
bool findReachableMBBs(unsigned Start, unsigned End,
|
||||||
SmallVectorImpl<MachineBasicBlock*> &MBBs) const;
|
SmallVectorImpl<MachineBasicBlock*> &MBBs) const;
|
||||||
|
|
||||||
// Interval creation
|
// Interval creation
|
||||||
|
@ -52,6 +52,22 @@ namespace llvm {
|
|||||||
return I->second;
|
return I->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LiveInterval &getInterval(int Slot) {
|
||||||
|
SS2IntervalMap::iterator I = s2iMap.find(Slot);
|
||||||
|
assert(I != s2iMap.end() && "Interval does not exist for stack slot");
|
||||||
|
return I->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LiveInterval &getInterval(int Slot) const {
|
||||||
|
SS2IntervalMap::const_iterator I = s2iMap.find(Slot);
|
||||||
|
assert(I != s2iMap.end() && "Interval does not exist for stack slot");
|
||||||
|
return I->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasInterval(unsigned reg) const {
|
||||||
|
return s2iMap.count(reg);
|
||||||
|
}
|
||||||
|
|
||||||
BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; }
|
BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; }
|
||||||
|
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||||
|
@ -751,14 +751,14 @@ void LiveIntervals::computeIntervals() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LiveIntervals::findLiveInMBBs(const LiveRange &LR,
|
bool LiveIntervals::findLiveInMBBs(unsigned Start, unsigned End,
|
||||||
SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
|
SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
|
||||||
std::vector<IdxMBBPair>::const_iterator I =
|
std::vector<IdxMBBPair>::const_iterator I =
|
||||||
std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), LR.start);
|
std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), Start);
|
||||||
|
|
||||||
bool ResVal = false;
|
bool ResVal = false;
|
||||||
while (I != Idx2MBBMap.end()) {
|
while (I != Idx2MBBMap.end()) {
|
||||||
if (LR.end <= I->first)
|
if (I->first > End)
|
||||||
break;
|
break;
|
||||||
MBBs.push_back(I->second);
|
MBBs.push_back(I->second);
|
||||||
ResVal = true;
|
ResVal = true;
|
||||||
@ -767,6 +767,27 @@ bool LiveIntervals::findLiveInMBBs(const LiveRange &LR,
|
|||||||
return ResVal;
|
return ResVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LiveIntervals::findReachableMBBs(unsigned Start, unsigned End,
|
||||||
|
SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
|
||||||
|
std::vector<IdxMBBPair>::const_iterator I =
|
||||||
|
std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), Start);
|
||||||
|
|
||||||
|
bool ResVal = false;
|
||||||
|
while (I != Idx2MBBMap.end()) {
|
||||||
|
if (I->first > End)
|
||||||
|
break;
|
||||||
|
MachineBasicBlock *MBB = I->second;
|
||||||
|
if (getMBBEndIdx(MBB) > End)
|
||||||
|
break;
|
||||||
|
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
|
||||||
|
SE = MBB->succ_end(); SI != SE; ++SI)
|
||||||
|
MBBs.push_back(*SI);
|
||||||
|
ResVal = true;
|
||||||
|
++I;
|
||||||
|
}
|
||||||
|
return ResVal;
|
||||||
|
}
|
||||||
|
|
||||||
LiveInterval* LiveIntervals::createInterval(unsigned reg) {
|
LiveInterval* LiveIntervals::createInterval(unsigned reg) {
|
||||||
float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ?
|
float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ?
|
||||||
HUGE_VALF : 0.0F;
|
HUGE_VALF : 0.0F;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#define DEBUG_TYPE "pre-alloc-split"
|
#define DEBUG_TYPE "pre-alloc-split"
|
||||||
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
|
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
|
||||||
|
#include "llvm/CodeGen/LiveStackAnalysis.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
#include "llvm/CodeGen/MachineLoopInfo.h"
|
#include "llvm/CodeGen/MachineLoopInfo.h"
|
||||||
@ -28,9 +29,9 @@
|
|||||||
#include "llvm/Target/TargetRegisterInfo.h"
|
#include "llvm/Target/TargetRegisterInfo.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include <map>
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
static cl::opt<int> PreSplitLimit("pre-split-limit", cl::init(-1), cl::Hidden);
|
static cl::opt<int> PreSplitLimit("pre-split-limit", cl::init(-1), cl::Hidden);
|
||||||
@ -39,12 +40,13 @@ STATISTIC(NumSplits, "Number of intervals split");
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class VISIBILITY_HIDDEN PreAllocSplitting : public MachineFunctionPass {
|
class VISIBILITY_HIDDEN PreAllocSplitting : public MachineFunctionPass {
|
||||||
MachineFunction *CurMF;
|
MachineFunction *CurrMF;
|
||||||
const TargetMachine *TM;
|
const TargetMachine *TM;
|
||||||
const TargetInstrInfo *TII;
|
const TargetInstrInfo *TII;
|
||||||
MachineFrameInfo *MFI;
|
MachineFrameInfo *MFI;
|
||||||
MachineRegisterInfo *MRI;
|
MachineRegisterInfo *MRI;
|
||||||
LiveIntervals *LIs;
|
LiveIntervals *LIs;
|
||||||
|
LiveStacks *LSs;
|
||||||
|
|
||||||
// Barrier - Current barrier being processed.
|
// Barrier - Current barrier being processed.
|
||||||
MachineInstr *Barrier;
|
MachineInstr *Barrier;
|
||||||
@ -58,10 +60,14 @@ namespace {
|
|||||||
// CurrLI - Current live interval being split.
|
// CurrLI - Current live interval being split.
|
||||||
LiveInterval *CurrLI;
|
LiveInterval *CurrLI;
|
||||||
|
|
||||||
// LIValNoSSMap - A map from live interval and val# pairs to spill slots.
|
// CurrSLI - Current stack slot live interval.
|
||||||
// This records what live interval's val# has been split and what spill
|
LiveInterval *CurrSLI;
|
||||||
// slot was used.
|
|
||||||
std::map<std::pair<unsigned, unsigned>, int> LIValNoSSMap;
|
// CurrSValNo - Current val# for the stack slot live interval.
|
||||||
|
VNInfo *CurrSValNo;
|
||||||
|
|
||||||
|
// IntervalSSMap - A map from live interval to spill slots.
|
||||||
|
DenseMap<unsigned, int> IntervalSSMap;
|
||||||
|
|
||||||
// RestoreMIs - All the restores inserted due to live interval splitting.
|
// RestoreMIs - All the restores inserted due to live interval splitting.
|
||||||
SmallPtrSet<MachineInstr*, 8> RestoreMIs;
|
SmallPtrSet<MachineInstr*, 8> RestoreMIs;
|
||||||
@ -75,6 +81,8 @@ namespace {
|
|||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.addRequired<LiveIntervals>();
|
AU.addRequired<LiveIntervals>();
|
||||||
AU.addPreserved<LiveIntervals>();
|
AU.addPreserved<LiveIntervals>();
|
||||||
|
AU.addRequired<LiveStacks>();
|
||||||
|
AU.addPreserved<LiveStacks>();
|
||||||
AU.addPreserved<RegisterCoalescer>();
|
AU.addPreserved<RegisterCoalescer>();
|
||||||
if (StrongPHIElim)
|
if (StrongPHIElim)
|
||||||
AU.addPreservedID(StrongPHIEliminationID);
|
AU.addPreservedID(StrongPHIEliminationID);
|
||||||
@ -84,7 +92,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void releaseMemory() {
|
virtual void releaseMemory() {
|
||||||
LIValNoSSMap.clear();
|
IntervalSSMap.clear();
|
||||||
RestoreMIs.clear();
|
RestoreMIs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,13 +122,15 @@ namespace {
|
|||||||
findRestorePoint(MachineBasicBlock*, MachineInstr*, unsigned,
|
findRestorePoint(MachineBasicBlock*, MachineInstr*, unsigned,
|
||||||
SmallPtrSet<MachineInstr*, 4>&, unsigned&);
|
SmallPtrSet<MachineInstr*, 4>&, unsigned&);
|
||||||
|
|
||||||
void RecordSplit(unsigned, unsigned, unsigned, int);
|
int CreateSpillStackSlot(unsigned, const TargetRegisterClass *);
|
||||||
|
|
||||||
bool isAlreadySplit(unsigned, unsigned, int&);
|
bool IsAvailableInStack(unsigned, unsigned, int&) const;
|
||||||
|
|
||||||
void UpdateIntervalForSplit(VNInfo*, unsigned, unsigned);
|
void UpdateSpillSlotInterval(VNInfo*, unsigned, unsigned);
|
||||||
|
|
||||||
bool ShrinkWrapToLastUse(MachineBasicBlock*,
|
void UpdateRegisterInterval(VNInfo*, unsigned, unsigned);
|
||||||
|
|
||||||
|
bool ShrinkWrapToLastUse(MachineBasicBlock*, VNInfo*,
|
||||||
SmallVector<MachineOperand*, 4>&,
|
SmallVector<MachineOperand*, 4>&,
|
||||||
SmallPtrSet<MachineInstr*, 4>&);
|
SmallPtrSet<MachineInstr*, 4>&);
|
||||||
|
|
||||||
@ -252,38 +262,101 @@ PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI,
|
|||||||
return Pt;
|
return Pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// RecordSplit - Given a register live interval is split, remember the spill
|
/// CreateSpillStackSlot - Create a stack slot for the live interval being
|
||||||
/// slot where the val#s are in.
|
/// split. If the live interval was previously split, just reuse the same
|
||||||
void PreAllocSplitting::RecordSplit(unsigned Reg, unsigned SpillIndex,
|
/// slot.
|
||||||
unsigned RestoreIndex, int SS) {
|
int PreAllocSplitting::CreateSpillStackSlot(unsigned Reg,
|
||||||
const LiveRange *LR = NULL;
|
const TargetRegisterClass *RC) {
|
||||||
if (SpillIndex) {
|
int SS;
|
||||||
LR = CurrLI->getLiveRangeContaining(LIs->getUseIndex(SpillIndex));
|
DenseMap<unsigned, int>::iterator I = IntervalSSMap.find(Reg);
|
||||||
LIValNoSSMap.insert(std::make_pair(std::make_pair(CurrLI->reg,
|
if (I != IntervalSSMap.end()) {
|
||||||
LR->valno->id), SS));
|
SS = I->second;
|
||||||
|
} else {
|
||||||
|
SS = MFI->CreateStackObject(RC->getSize(), RC->getAlignment());
|
||||||
|
IntervalSSMap[Reg] = SS;
|
||||||
}
|
}
|
||||||
LR = CurrLI->getLiveRangeContaining(LIs->getDefIndex(RestoreIndex));
|
|
||||||
LIValNoSSMap.insert(std::make_pair(std::make_pair(CurrLI->reg,
|
// Create live interval for stack slot.
|
||||||
LR->valno->id), SS));
|
CurrSLI = &LSs->getOrCreateInterval(SS);
|
||||||
|
if (CurrSLI->getNumValNums())
|
||||||
|
CurrSValNo = CurrSLI->getValNumInfo(0);
|
||||||
|
else
|
||||||
|
CurrSValNo = CurrSLI->getNextValue(~0U, 0, LSs->getVNInfoAllocator());
|
||||||
|
return SS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isAlreadySplit - Return if a given val# of a register live interval is already
|
/// IsAvailableInStack - Return true if register is available in a split stack
|
||||||
/// split. Also return by reference the spill stock where the value is.
|
/// slot at the specified index.
|
||||||
bool PreAllocSplitting::isAlreadySplit(unsigned Reg, unsigned ValNoId, int &SS){
|
bool
|
||||||
std::map<std::pair<unsigned, unsigned>, int>::iterator I =
|
PreAllocSplitting::IsAvailableInStack(unsigned Reg, unsigned Index, int &SS) const {
|
||||||
LIValNoSSMap.find(std::make_pair(Reg, ValNoId));
|
DenseMap<unsigned, int>::iterator I = IntervalSSMap.find(Reg);
|
||||||
if (I == LIValNoSSMap.end())
|
if (I == IntervalSSMap.end())
|
||||||
return false;
|
return false;
|
||||||
SS = I->second;
|
if (LSs->getInterval(I->second).liveAt(Index)) {
|
||||||
return true;
|
SS = I->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// UpdateIntervalForSplit - Given the specified val# of the current live
|
/// UpdateSpillSlotInterval - Given the specified val# of the register live
|
||||||
/// interval is being split, and the split and rejoin indices, update the live
|
/// interval being split, and the spill and restore indicies, update the live
|
||||||
|
/// interval of the spill stack slot.
|
||||||
|
void
|
||||||
|
PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, unsigned SpillIndex,
|
||||||
|
unsigned RestoreIndex) {
|
||||||
|
const LiveRange *LR = CurrLI->getLiveRangeContaining(SpillIndex);
|
||||||
|
if (LR->contains(RestoreIndex)) {
|
||||||
|
LiveRange SLR(SpillIndex, RestoreIndex, CurrSValNo);
|
||||||
|
CurrSLI->addRange(SLR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallPtrSet<const LiveRange*, 4> Processed;
|
||||||
|
LiveRange SLR(SpillIndex, LR->end, CurrSValNo);
|
||||||
|
CurrSLI->addRange(SLR);
|
||||||
|
Processed.insert(LR);
|
||||||
|
|
||||||
|
// Start from the spill mbb, figure out the extend of the spill slot's
|
||||||
|
// live interval.
|
||||||
|
SmallVector<MachineBasicBlock*, 4> WorkList;
|
||||||
|
MachineBasicBlock *MBB = LIs->getMBBFromIndex(SpillIndex);
|
||||||
|
if (LR->end > LIs->getMBBEndIdx(MBB))
|
||||||
|
// If live range extend beyond end of mbb, add successors to work list.
|
||||||
|
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
|
||||||
|
SE = MBB->succ_end(); SI != SE; ++SI)
|
||||||
|
WorkList.push_back(*SI);
|
||||||
|
// Live range may cross multiple basic blocks, add all reachable mbbs to
|
||||||
|
// the work list.
|
||||||
|
LIs->findReachableMBBs(LR->start, LR->end, WorkList);
|
||||||
|
|
||||||
|
while (!WorkList.empty()) {
|
||||||
|
MachineBasicBlock *MBB = WorkList.back();
|
||||||
|
WorkList.pop_back();
|
||||||
|
unsigned Idx = LIs->getMBBStartIdx(MBB);
|
||||||
|
LR = CurrLI->getLiveRangeContaining(Idx);
|
||||||
|
if (LR && LR->valno == ValNo && !Processed.count(LR)) {
|
||||||
|
if (LR->contains(RestoreIndex)) {
|
||||||
|
// Spill slot live interval stops at the restore.
|
||||||
|
LiveRange SLR(LR->start, RestoreIndex, CurrSValNo);
|
||||||
|
CurrSLI->addRange(SLR);
|
||||||
|
LIs->findReachableMBBs(LR->start, RestoreIndex, WorkList);
|
||||||
|
} else {
|
||||||
|
LiveRange SLR(LR->start, LR->end, CurrSValNo);
|
||||||
|
CurrSLI->addRange(SLR);
|
||||||
|
LIs->findReachableMBBs(LR->start, LR->end, WorkList);
|
||||||
|
}
|
||||||
|
Processed.insert(LR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// UpdateRegisterInterval - Given the specified val# of the current live
|
||||||
|
/// interval is being split, and the spill and restore indices, update the live
|
||||||
/// interval accordingly.
|
/// interval accordingly.
|
||||||
void
|
void
|
||||||
PreAllocSplitting::UpdateIntervalForSplit(VNInfo *ValNo, unsigned SplitIndex,
|
PreAllocSplitting::UpdateRegisterInterval(VNInfo *ValNo, unsigned SpillIndex,
|
||||||
unsigned JoinIndex) {
|
unsigned RestoreIndex) {
|
||||||
SmallVector<std::pair<unsigned,unsigned>, 4> Before;
|
SmallVector<std::pair<unsigned,unsigned>, 4> Before;
|
||||||
SmallVector<std::pair<unsigned,unsigned>, 4> After;
|
SmallVector<std::pair<unsigned,unsigned>, 4> After;
|
||||||
SmallVector<unsigned, 4> BeforeKills;
|
SmallVector<unsigned, 4> BeforeKills;
|
||||||
@ -292,20 +365,22 @@ PreAllocSplitting::UpdateIntervalForSplit(VNInfo *ValNo, unsigned SplitIndex,
|
|||||||
|
|
||||||
// First, let's figure out which parts of the live interval is now defined
|
// First, let's figure out which parts of the live interval is now defined
|
||||||
// by the restore, which are defined by the original definition.
|
// by the restore, which are defined by the original definition.
|
||||||
const LiveRange *LR = CurrLI->getLiveRangeContaining(JoinIndex);
|
const LiveRange *LR = CurrLI->getLiveRangeContaining(RestoreIndex);
|
||||||
After.push_back(std::make_pair(JoinIndex, LR->end));
|
After.push_back(std::make_pair(RestoreIndex, LR->end));
|
||||||
if (CurrLI->isKill(ValNo, LR->end))
|
if (CurrLI->isKill(ValNo, LR->end))
|
||||||
AfterKills.push_back(LR->end);
|
AfterKills.push_back(LR->end);
|
||||||
|
|
||||||
assert(LR->contains(SplitIndex));
|
assert(LR->contains(SpillIndex));
|
||||||
if (SplitIndex > LR->start) {
|
if (SpillIndex > LR->start) {
|
||||||
Before.push_back(std::make_pair(LR->start, SplitIndex));
|
Before.push_back(std::make_pair(LR->start, SpillIndex));
|
||||||
BeforeKills.push_back(SplitIndex);
|
BeforeKills.push_back(SpillIndex);
|
||||||
}
|
}
|
||||||
Processed.insert(LR);
|
Processed.insert(LR);
|
||||||
|
|
||||||
|
// Start from the restore mbb, figure out what part of the live interval
|
||||||
|
// are defined by the restore.
|
||||||
SmallVector<MachineBasicBlock*, 4> WorkList;
|
SmallVector<MachineBasicBlock*, 4> WorkList;
|
||||||
MachineBasicBlock *MBB = LIs->getMBBFromIndex(LR->end-1);
|
MachineBasicBlock *MBB = LIs->getMBBFromIndex(RestoreIndex);
|
||||||
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
|
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
|
||||||
SE = MBB->succ_end(); SI != SE; ++SI)
|
SE = MBB->succ_end(); SI != SE; ++SI)
|
||||||
WorkList.push_back(*SI);
|
WorkList.push_back(*SI);
|
||||||
@ -321,15 +396,9 @@ PreAllocSplitting::UpdateIntervalForSplit(VNInfo *ValNo, unsigned SplitIndex,
|
|||||||
AfterKills.push_back(LR->end);
|
AfterKills.push_back(LR->end);
|
||||||
Idx = LIs->getMBBEndIdx(MBB);
|
Idx = LIs->getMBBEndIdx(MBB);
|
||||||
if (LR->end > Idx) {
|
if (LR->end > Idx) {
|
||||||
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
|
// Live range extend beyond at least one mbb. Let's see what other
|
||||||
SE = MBB->succ_end(); SI != SE; ++SI)
|
// mbbs it reaches.
|
||||||
WorkList.push_back(*SI);
|
LIs->findReachableMBBs(LR->start, LR->end, WorkList);
|
||||||
if (LR->end > Idx+1) {
|
|
||||||
MBB = LIs->getMBBFromIndex(LR->end-1);
|
|
||||||
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
|
|
||||||
SE = MBB->succ_end(); SI != SE; ++SI)
|
|
||||||
WorkList.push_back(*SI);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Processed.insert(LR);
|
Processed.insert(LR);
|
||||||
}
|
}
|
||||||
@ -359,7 +428,7 @@ PreAllocSplitting::UpdateIntervalForSplit(VNInfo *ValNo, unsigned SplitIndex,
|
|||||||
|
|
||||||
VNInfo *AValNo = (After.empty())
|
VNInfo *AValNo = (After.empty())
|
||||||
? NULL
|
? NULL
|
||||||
: CurrLI->getNextValue(JoinIndex,0, LIs->getVNInfoAllocator());
|
: CurrLI->getNextValue(RestoreIndex, 0, LIs->getVNInfoAllocator());
|
||||||
if (AValNo) {
|
if (AValNo) {
|
||||||
AValNo->hasPHIKill = HasPHIKill;
|
AValNo->hasPHIKill = HasPHIKill;
|
||||||
CurrLI->addKills(AValNo, AfterKills);
|
CurrLI->addKills(AValNo, AfterKills);
|
||||||
@ -382,7 +451,7 @@ PreAllocSplitting::UpdateIntervalForSplit(VNInfo *ValNo, unsigned SplitIndex,
|
|||||||
/// from last use to the end of the mbb). In case mbb is the where the barrier
|
/// from last use to the end of the mbb). In case mbb is the where the barrier
|
||||||
/// is, remove from the last use to the barrier.
|
/// is, remove from the last use to the barrier.
|
||||||
bool
|
bool
|
||||||
PreAllocSplitting::ShrinkWrapToLastUse(MachineBasicBlock *MBB,
|
PreAllocSplitting::ShrinkWrapToLastUse(MachineBasicBlock *MBB, VNInfo *ValNo,
|
||||||
SmallVector<MachineOperand*, 4> &Uses,
|
SmallVector<MachineOperand*, 4> &Uses,
|
||||||
SmallPtrSet<MachineInstr*, 4> &UseMIs) {
|
SmallPtrSet<MachineInstr*, 4> &UseMIs) {
|
||||||
MachineOperand *LastMO = 0;
|
MachineOperand *LastMO = 0;
|
||||||
@ -399,7 +468,8 @@ PreAllocSplitting::ShrinkWrapToLastUse(MachineBasicBlock *MBB,
|
|||||||
MII = Barrier;
|
MII = Barrier;
|
||||||
else
|
else
|
||||||
MII = MBB->end();
|
MII = MBB->end();
|
||||||
while (--MII != MEE) {
|
while (MII != MEE) {
|
||||||
|
--MII;
|
||||||
MachineInstr *UseMI = &*MII;
|
MachineInstr *UseMI = &*MII;
|
||||||
if (!UseMIs.count(UseMI))
|
if (!UseMIs.count(UseMI))
|
||||||
continue;
|
continue;
|
||||||
@ -429,6 +499,8 @@ PreAllocSplitting::ShrinkWrapToLastUse(MachineBasicBlock *MBB,
|
|||||||
if (MBB == BarrierMBB)
|
if (MBB == BarrierMBB)
|
||||||
RangeEnd = LIs->getUseIndex(BarrierIdx)+1;
|
RangeEnd = LIs->getUseIndex(BarrierIdx)+1;
|
||||||
CurrLI->removeRange(RangeStart, RangeEnd);
|
CurrLI->removeRange(RangeStart, RangeEnd);
|
||||||
|
if (LastMI)
|
||||||
|
CurrLI->addKill(ValNo, RangeStart);
|
||||||
|
|
||||||
// Return true if the last use becomes a new kill.
|
// Return true if the last use becomes a new kill.
|
||||||
return LastMI;
|
return LastMI;
|
||||||
@ -469,12 +541,10 @@ PreAllocSplitting::ShrinkWrapLiveInterval(VNInfo *ValNo, MachineBasicBlock *MBB,
|
|||||||
// At least one use in this mbb, lets look for the kill.
|
// At least one use in this mbb, lets look for the kill.
|
||||||
DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> >::iterator
|
DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> >::iterator
|
||||||
UMII2 = UseMIs.find(MBB);
|
UMII2 = UseMIs.find(MBB);
|
||||||
if (ShrinkWrapToLastUse(MBB, UMII->second, UMII2->second))
|
if (ShrinkWrapToLastUse(MBB, ValNo, UMII->second, UMII2->second))
|
||||||
// Found a kill, shrink wrapping of this path ends here.
|
// Found a kill, shrink wrapping of this path ends here.
|
||||||
return;
|
return;
|
||||||
} else if (MBB == DefMBB) {
|
} else if (MBB == DefMBB) {
|
||||||
assert(LIValNoSSMap.find(std::make_pair(CurrLI->reg, ValNo->id)) !=
|
|
||||||
LIValNoSSMap.end() && "Why wasn't def spilled?");
|
|
||||||
// There are no uses after the def.
|
// There are no uses after the def.
|
||||||
MachineInstr *DefMI = LIs->getInstructionFromIndex(ValNo->def);
|
MachineInstr *DefMI = LIs->getInstructionFromIndex(ValNo->def);
|
||||||
assert(RestoreMIs.count(DefMI) && "Not defined by a join?");
|
assert(RestoreMIs.count(DefMI) && "Not defined by a join?");
|
||||||
@ -560,7 +630,6 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
|
|||||||
unsigned SpillIndex = 0;
|
unsigned SpillIndex = 0;
|
||||||
MachineInstr *SpillMI = NULL;
|
MachineInstr *SpillMI = NULL;
|
||||||
int SS = -1;
|
int SS = -1;
|
||||||
bool PrevSpilled = isAlreadySplit(CurrLI->reg, ValNo->id, SS);
|
|
||||||
if (ValNo->def == ~0U) {
|
if (ValNo->def == ~0U) {
|
||||||
// If it's defined by a phi, we must split just before the barrier.
|
// If it's defined by a phi, we must split just before the barrier.
|
||||||
MachineBasicBlock::iterator SpillPt =
|
MachineBasicBlock::iterator SpillPt =
|
||||||
@ -568,18 +637,15 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
|
|||||||
if (SpillPt == BarrierMBB->begin())
|
if (SpillPt == BarrierMBB->begin())
|
||||||
return false; // No gap to insert spill.
|
return false; // No gap to insert spill.
|
||||||
// Add spill.
|
// Add spill.
|
||||||
if (!PrevSpilled)
|
SS = CreateSpillStackSlot(CurrLI->reg, RC);
|
||||||
// If previously split, reuse the spill slot.
|
|
||||||
SS = MFI->CreateStackObject(RC->getSize(), RC->getAlignment());
|
|
||||||
TII->storeRegToStackSlot(*BarrierMBB, SpillPt, CurrLI->reg, true, SS, RC);
|
TII->storeRegToStackSlot(*BarrierMBB, SpillPt, CurrLI->reg, true, SS, RC);
|
||||||
SpillMI = prior(SpillPt);
|
SpillMI = prior(SpillPt);
|
||||||
LIs->InsertMachineInstrInMaps(SpillMI, SpillIndex);
|
LIs->InsertMachineInstrInMaps(SpillMI, SpillIndex);
|
||||||
} else if (!PrevSpilled) {
|
} else if (!IsAvailableInStack(CurrLI->reg, RestoreIndex, SS)) {
|
||||||
if (!DefMI)
|
|
||||||
// Def is dead. Do nothing.
|
|
||||||
return false;
|
|
||||||
// If it's already split, just restore the value. There is no need to spill
|
// If it's already split, just restore the value. There is no need to spill
|
||||||
// the def again.
|
// the def again.
|
||||||
|
if (!DefMI)
|
||||||
|
return false; // Def is dead. Do nothing.
|
||||||
// Check if it's possible to insert a spill after the def MI.
|
// Check if it's possible to insert a spill after the def MI.
|
||||||
MachineBasicBlock::iterator SpillPt;
|
MachineBasicBlock::iterator SpillPt;
|
||||||
if (DefMBB == BarrierMBB) {
|
if (DefMBB == BarrierMBB) {
|
||||||
@ -592,10 +658,9 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
|
|||||||
if (SpillPt == DefMBB->end())
|
if (SpillPt == DefMBB->end())
|
||||||
return false; // No gap to insert spill.
|
return false; // No gap to insert spill.
|
||||||
}
|
}
|
||||||
SS = MFI->CreateStackObject(RC->getSize(), RC->getAlignment());
|
|
||||||
|
|
||||||
// Add spill. The store instruction kills the register if def is before
|
// Add spill. The store instruction kills the register if def is before
|
||||||
// the barrier in the barrier block.
|
// the barrier in the barrier block.
|
||||||
|
SS = CreateSpillStackSlot(CurrLI->reg, RC);
|
||||||
TII->storeRegToStackSlot(*DefMBB, SpillPt, CurrLI->reg,
|
TII->storeRegToStackSlot(*DefMBB, SpillPt, CurrLI->reg,
|
||||||
DefMBB == BarrierMBB, SS, RC);
|
DefMBB == BarrierMBB, SS, RC);
|
||||||
SpillMI = prior(SpillPt);
|
SpillMI = prior(SpillPt);
|
||||||
@ -603,7 +668,6 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add restore.
|
// Add restore.
|
||||||
// FIXME: Create live interval for stack slot.
|
|
||||||
TII->loadRegFromStackSlot(*BarrierMBB, RestorePt, CurrLI->reg, SS, RC);
|
TII->loadRegFromStackSlot(*BarrierMBB, RestorePt, CurrLI->reg, SS, RC);
|
||||||
MachineInstr *LoadMI = prior(RestorePt);
|
MachineInstr *LoadMI = prior(RestorePt);
|
||||||
LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex);
|
LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex);
|
||||||
@ -613,16 +677,24 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
|
|||||||
// create a hole in the interval.
|
// create a hole in the interval.
|
||||||
if (!DefMBB ||
|
if (!DefMBB ||
|
||||||
(SpillMI && SpillMI->getParent() == BarrierMBB)) {
|
(SpillMI && SpillMI->getParent() == BarrierMBB)) {
|
||||||
UpdateIntervalForSplit(ValNo, LIs->getUseIndex(SpillIndex)+1,
|
// Update spill stack slot live interval.
|
||||||
LIs->getDefIndex(RestoreIndex));
|
UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1,
|
||||||
|
LIs->getDefIndex(RestoreIndex));
|
||||||
|
|
||||||
// Record val# values are in the specific spill slot.
|
UpdateRegisterInterval(ValNo, LIs->getUseIndex(SpillIndex)+1,
|
||||||
RecordSplit(CurrLI->reg, SpillIndex, RestoreIndex, SS);
|
LIs->getDefIndex(RestoreIndex));
|
||||||
|
|
||||||
++NumSplits;
|
++NumSplits;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update spill stack slot live interval.
|
||||||
|
if (SpillIndex)
|
||||||
|
// If value is already in stack at the restore point, there is
|
||||||
|
// no need to update the live interval.
|
||||||
|
UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1,
|
||||||
|
LIs->getDefIndex(RestoreIndex));
|
||||||
|
|
||||||
// Shrink wrap the live interval by walking up the CFG and find the
|
// Shrink wrap the live interval by walking up the CFG and find the
|
||||||
// new kills.
|
// new kills.
|
||||||
// Now let's find all the uses of the val#.
|
// Now let's find all the uses of the val#.
|
||||||
@ -666,10 +738,8 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
|
|||||||
|
|
||||||
// Remove live range from barrier to the restore. FIXME: Find a better
|
// Remove live range from barrier to the restore. FIXME: Find a better
|
||||||
// point to re-start the live interval.
|
// point to re-start the live interval.
|
||||||
UpdateIntervalForSplit(ValNo, LIs->getUseIndex(BarrierIdx)+1,
|
UpdateRegisterInterval(ValNo, LIs->getUseIndex(BarrierIdx)+1,
|
||||||
LIs->getDefIndex(RestoreIndex));
|
LIs->getDefIndex(RestoreIndex));
|
||||||
// Record val# values are in the specific spill slot.
|
|
||||||
RecordSplit(CurrLI->reg, SpillIndex, RestoreIndex, SS);
|
|
||||||
|
|
||||||
++NumSplits;
|
++NumSplits;
|
||||||
return true;
|
return true;
|
||||||
@ -712,12 +782,13 @@ PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) {
|
bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) {
|
||||||
CurMF = &MF;
|
CurrMF = &MF;
|
||||||
TM = &MF.getTarget();
|
TM = &MF.getTarget();
|
||||||
TII = TM->getInstrInfo();
|
TII = TM->getInstrInfo();
|
||||||
MFI = MF.getFrameInfo();
|
MFI = MF.getFrameInfo();
|
||||||
MRI = &MF.getRegInfo();
|
MRI = &MF.getRegInfo();
|
||||||
LIs = &getAnalysis<LiveIntervals>();
|
LIs = &getAnalysis<LiveIntervals>();
|
||||||
|
LSs = &getAnalysis<LiveStacks>();
|
||||||
|
|
||||||
bool MadeChange = false;
|
bool MadeChange = false;
|
||||||
|
|
||||||
|
@ -410,7 +410,7 @@ void RALinScan::linearScan()
|
|||||||
for (LiveInterval::Ranges::const_iterator I = cur.begin(), E = cur.end();
|
for (LiveInterval::Ranges::const_iterator I = cur.begin(), E = cur.end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
const LiveRange &LR = *I;
|
const LiveRange &LR = *I;
|
||||||
if (li_->findLiveInMBBs(LR, LiveInMBBs)) {
|
if (li_->findLiveInMBBs(LR.start, LR.end, LiveInMBBs)) {
|
||||||
for (unsigned i = 0, e = LiveInMBBs.size(); i != e; ++i)
|
for (unsigned i = 0, e = LiveInMBBs.size(); i != e; ++i)
|
||||||
if (LiveInMBBs[i] != EntryMBB)
|
if (LiveInMBBs[i] != EntryMBB)
|
||||||
LiveInMBBs[i]->addLiveIn(Reg);
|
LiveInMBBs[i]->addLiveIn(Reg);
|
||||||
|
Loading…
Reference in New Issue
Block a user