mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 22:50:47 +00:00
Move the code that inserts copies for function livein registers
out of ScheduleDAGEmit.cpp and into SelectionDAGISel.cpp. This allows it to be run exactly once per function, even if multiple SelectionDAG iterations happen in the entry block, as may happen with FastISel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55863 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bcc11d2a71
commit
8a11053f3c
@ -30,13 +30,6 @@ using namespace llvm;
|
||||
|
||||
STATISTIC(NumCommutes, "Number of instructions commuted");
|
||||
|
||||
namespace {
|
||||
static cl::opt<bool>
|
||||
SchedLiveInCopies("schedule-livein-copies",
|
||||
cl::desc("Schedule copies of livein registers"),
|
||||
cl::init(false));
|
||||
}
|
||||
|
||||
/// getInstrOperandRegClass - Return register class of the operand of an
|
||||
/// instruction of the specified TargetInstrDesc.
|
||||
static const TargetRegisterClass*
|
||||
@ -653,100 +646,8 @@ void ScheduleDAG::EmitCrossRCCopy(SUnit *SU,
|
||||
}
|
||||
}
|
||||
|
||||
/// EmitLiveInCopy - Emit a copy for a live in physical register. If the
|
||||
/// physical register has only a single copy use, then coalesced the copy
|
||||
/// if possible.
|
||||
void ScheduleDAG::EmitLiveInCopy(MachineBasicBlock *MBB,
|
||||
MachineBasicBlock::iterator &InsertPos,
|
||||
unsigned VirtReg, unsigned PhysReg,
|
||||
const TargetRegisterClass *RC,
|
||||
DenseMap<MachineInstr*, unsigned> &CopyRegMap){
|
||||
unsigned NumUses = 0;
|
||||
MachineInstr *UseMI = NULL;
|
||||
for (MachineRegisterInfo::use_iterator UI = MRI.use_begin(VirtReg),
|
||||
UE = MRI.use_end(); UI != UE; ++UI) {
|
||||
UseMI = &*UI;
|
||||
if (++NumUses > 1)
|
||||
break;
|
||||
}
|
||||
|
||||
// If the number of uses is not one, or the use is not a move instruction,
|
||||
// don't coalesce. Also, only coalesce away a virtual register to virtual
|
||||
// register copy.
|
||||
bool Coalesced = false;
|
||||
unsigned SrcReg, DstReg;
|
||||
if (NumUses == 1 &&
|
||||
TII->isMoveInstr(*UseMI, SrcReg, DstReg) &&
|
||||
TargetRegisterInfo::isVirtualRegister(DstReg)) {
|
||||
VirtReg = DstReg;
|
||||
Coalesced = true;
|
||||
}
|
||||
|
||||
// Now find an ideal location to insert the copy.
|
||||
MachineBasicBlock::iterator Pos = InsertPos;
|
||||
while (Pos != MBB->begin()) {
|
||||
MachineInstr *PrevMI = prior(Pos);
|
||||
DenseMap<MachineInstr*, unsigned>::iterator RI = CopyRegMap.find(PrevMI);
|
||||
// copyRegToReg might emit multiple instructions to do a copy.
|
||||
unsigned CopyDstReg = (RI == CopyRegMap.end()) ? 0 : RI->second;
|
||||
if (CopyDstReg && !TRI->regsOverlap(CopyDstReg, PhysReg))
|
||||
// This is what the BB looks like right now:
|
||||
// r1024 = mov r0
|
||||
// ...
|
||||
// r1 = mov r1024
|
||||
//
|
||||
// We want to insert "r1025 = mov r1". Inserting this copy below the
|
||||
// move to r1024 makes it impossible for that move to be coalesced.
|
||||
//
|
||||
// r1025 = mov r1
|
||||
// r1024 = mov r0
|
||||
// ...
|
||||
// r1 = mov 1024
|
||||
// r2 = mov 1025
|
||||
break; // Woot! Found a good location.
|
||||
--Pos;
|
||||
}
|
||||
|
||||
TII->copyRegToReg(*MBB, Pos, VirtReg, PhysReg, RC, RC);
|
||||
CopyRegMap.insert(std::make_pair(prior(Pos), VirtReg));
|
||||
if (Coalesced) {
|
||||
if (&*InsertPos == UseMI) ++InsertPos;
|
||||
MBB->erase(UseMI);
|
||||
}
|
||||
}
|
||||
|
||||
/// EmitLiveInCopies - If this is the first basic block in the function,
|
||||
/// and if it has live ins that need to be copied into vregs, emit the
|
||||
/// copies into the top of the block.
|
||||
void ScheduleDAG::EmitLiveInCopies(MachineBasicBlock *MBB) {
|
||||
DenseMap<MachineInstr*, unsigned> CopyRegMap;
|
||||
MachineBasicBlock::iterator InsertPos = MBB->begin();
|
||||
for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(),
|
||||
E = MRI.livein_end(); LI != E; ++LI)
|
||||
if (LI->second) {
|
||||
const TargetRegisterClass *RC = MRI.getRegClass(LI->second);
|
||||
EmitLiveInCopy(MBB, InsertPos, LI->second, LI->first, RC, CopyRegMap);
|
||||
}
|
||||
}
|
||||
|
||||
/// EmitSchedule - Emit the machine code in scheduled order.
|
||||
MachineBasicBlock *ScheduleDAG::EmitSchedule() {
|
||||
bool isEntryBB = &MF->front() == BB;
|
||||
|
||||
if (isEntryBB && !SchedLiveInCopies) {
|
||||
// If this is the first basic block in the function, and if it has live ins
|
||||
// that need to be copied into vregs, emit the copies into the top of the
|
||||
// block before emitting the code for the block.
|
||||
for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(),
|
||||
E = MRI.livein_end(); LI != E; ++LI)
|
||||
if (LI->second) {
|
||||
const TargetRegisterClass *RC = MRI.getRegClass(LI->second);
|
||||
TII->copyRegToReg(*MF->begin(), MF->begin()->end(), LI->second,
|
||||
LI->first, RC, RC);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, emit the code for all of the scheduled instructions.
|
||||
DenseMap<SDValue, unsigned> VRBaseMap;
|
||||
DenseMap<SUnit*, unsigned> CopyVRBaseMap;
|
||||
for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
|
||||
@ -764,8 +665,5 @@ MachineBasicBlock *ScheduleDAG::EmitSchedule() {
|
||||
EmitNode(SU->Node, SU->OrigNode != SU, VRBaseMap);
|
||||
}
|
||||
|
||||
if (isEntryBB && SchedLiveInCopies)
|
||||
EmitLiveInCopies(MF->begin());
|
||||
|
||||
return BB;
|
||||
}
|
||||
|
@ -63,6 +63,10 @@ static cl::opt<bool>
|
||||
DisableFastISelAbort("fast-isel-no-abort", cl::Hidden,
|
||||
cl::desc("Use the SelectionDAGISel when \"fast\" instruction "
|
||||
"selection fails"));
|
||||
static cl::opt<bool>
|
||||
SchedLiveInCopies("schedule-livein-copies",
|
||||
cl::desc("Schedule copies of livein registers"),
|
||||
cl::init(false));
|
||||
|
||||
#ifndef NDEBUG
|
||||
static cl::opt<bool>
|
||||
@ -153,6 +157,101 @@ MachineBasicBlock *TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// EmitLiveInCopy - Emit a copy for a live in physical register. If the
|
||||
/// physical register has only a single copy use, then coalesced the copy
|
||||
/// if possible.
|
||||
static void EmitLiveInCopy(MachineBasicBlock *MBB,
|
||||
MachineBasicBlock::iterator &InsertPos,
|
||||
unsigned VirtReg, unsigned PhysReg,
|
||||
const TargetRegisterClass *RC,
|
||||
DenseMap<MachineInstr*, unsigned> &CopyRegMap,
|
||||
const MachineRegisterInfo &MRI,
|
||||
const TargetRegisterInfo &TRI,
|
||||
const TargetInstrInfo &TII) {
|
||||
unsigned NumUses = 0;
|
||||
MachineInstr *UseMI = NULL;
|
||||
for (MachineRegisterInfo::use_iterator UI = MRI.use_begin(VirtReg),
|
||||
UE = MRI.use_end(); UI != UE; ++UI) {
|
||||
UseMI = &*UI;
|
||||
if (++NumUses > 1)
|
||||
break;
|
||||
}
|
||||
|
||||
// If the number of uses is not one, or the use is not a move instruction,
|
||||
// don't coalesce. Also, only coalesce away a virtual register to virtual
|
||||
// register copy.
|
||||
bool Coalesced = false;
|
||||
unsigned SrcReg, DstReg;
|
||||
if (NumUses == 1 &&
|
||||
TII.isMoveInstr(*UseMI, SrcReg, DstReg) &&
|
||||
TargetRegisterInfo::isVirtualRegister(DstReg)) {
|
||||
VirtReg = DstReg;
|
||||
Coalesced = true;
|
||||
}
|
||||
|
||||
// Now find an ideal location to insert the copy.
|
||||
MachineBasicBlock::iterator Pos = InsertPos;
|
||||
while (Pos != MBB->begin()) {
|
||||
MachineInstr *PrevMI = prior(Pos);
|
||||
DenseMap<MachineInstr*, unsigned>::iterator RI = CopyRegMap.find(PrevMI);
|
||||
// copyRegToReg might emit multiple instructions to do a copy.
|
||||
unsigned CopyDstReg = (RI == CopyRegMap.end()) ? 0 : RI->second;
|
||||
if (CopyDstReg && !TRI.regsOverlap(CopyDstReg, PhysReg))
|
||||
// This is what the BB looks like right now:
|
||||
// r1024 = mov r0
|
||||
// ...
|
||||
// r1 = mov r1024
|
||||
//
|
||||
// We want to insert "r1025 = mov r1". Inserting this copy below the
|
||||
// move to r1024 makes it impossible for that move to be coalesced.
|
||||
//
|
||||
// r1025 = mov r1
|
||||
// r1024 = mov r0
|
||||
// ...
|
||||
// r1 = mov 1024
|
||||
// r2 = mov 1025
|
||||
break; // Woot! Found a good location.
|
||||
--Pos;
|
||||
}
|
||||
|
||||
TII.copyRegToReg(*MBB, Pos, VirtReg, PhysReg, RC, RC);
|
||||
CopyRegMap.insert(std::make_pair(prior(Pos), VirtReg));
|
||||
if (Coalesced) {
|
||||
if (&*InsertPos == UseMI) ++InsertPos;
|
||||
MBB->erase(UseMI);
|
||||
}
|
||||
}
|
||||
|
||||
/// EmitLiveInCopies - If this is the first basic block in the function,
|
||||
/// and if it has live ins that need to be copied into vregs, emit the
|
||||
/// copies into the block.
|
||||
static void EmitLiveInCopies(MachineBasicBlock *EntryMBB,
|
||||
const MachineRegisterInfo &MRI,
|
||||
const TargetRegisterInfo &TRI,
|
||||
const TargetInstrInfo &TII) {
|
||||
if (SchedLiveInCopies) {
|
||||
// Emit the copies at a heuristically-determined location in the block.
|
||||
DenseMap<MachineInstr*, unsigned> CopyRegMap;
|
||||
MachineBasicBlock::iterator InsertPos = EntryMBB->begin();
|
||||
for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(),
|
||||
E = MRI.livein_end(); LI != E; ++LI)
|
||||
if (LI->second) {
|
||||
const TargetRegisterClass *RC = MRI.getRegClass(LI->second);
|
||||
EmitLiveInCopy(EntryMBB, InsertPos, LI->second, LI->first,
|
||||
RC, CopyRegMap, MRI, TRI, TII);
|
||||
}
|
||||
} else {
|
||||
// Emit the copies into the top of the block.
|
||||
for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(),
|
||||
E = MRI.livein_end(); LI != E; ++LI)
|
||||
if (LI->second) {
|
||||
const TargetRegisterClass *RC = MRI.getRegClass(LI->second);
|
||||
TII.copyRegToReg(*EntryMBB, EntryMBB->begin(),
|
||||
LI->second, LI->first, RC, RC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SelectionDAGISel code
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -187,7 +286,12 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
|
||||
// Get alias analysis for load/store combining.
|
||||
AA = &getAnalysis<AliasAnalysis>();
|
||||
|
||||
MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine());
|
||||
TargetMachine &TM = TLI.getTargetMachine();
|
||||
MachineFunction &MF = MachineFunction::construct(&Fn, TM);
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
const TargetInstrInfo &TII = *TM.getInstrInfo();
|
||||
const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
|
||||
|
||||
if (MF.getFunction()->hasGC())
|
||||
GFI = &getAnalysis<GCModuleInfo>().getFunctionInfo(*MF.getFunction());
|
||||
else
|
||||
@ -206,13 +310,15 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
|
||||
|
||||
SelectAllBasicBlocks(Fn, MF);
|
||||
|
||||
// If the first basic block in the function has live ins that need to be
|
||||
// copied into vregs, emit the copies into the top of the block before
|
||||
// emitting the code for the block.
|
||||
EmitLiveInCopies(MF.begin(), MRI, TRI, TII);
|
||||
|
||||
// Add function live-ins to entry block live-in set.
|
||||
BasicBlock *EntryBB = &Fn.getEntryBlock();
|
||||
BB = FuncInfo->MBBMap[EntryBB];
|
||||
if (!RegInfo->livein_empty())
|
||||
for (MachineRegisterInfo::livein_iterator I = RegInfo->livein_begin(),
|
||||
E = RegInfo->livein_end(); I != E; ++I)
|
||||
BB->addLiveIn(I->first);
|
||||
for (MachineRegisterInfo::livein_iterator I = RegInfo->livein_begin(),
|
||||
E = RegInfo->livein_end(); I != E; ++I)
|
||||
MF.begin()->addLiveIn(I->first);
|
||||
|
||||
#ifndef NDEBUG
|
||||
assert(FuncInfo->CatchInfoFound.size() == FuncInfo->CatchInfoLost.size() &&
|
||||
|
Loading…
Reference in New Issue
Block a user