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.

llvm-svn: 55863
This commit is contained in:
Dan Gohman 2008-09-05 22:59:21 +00:00
parent 8de9c3affe
commit f17a2f3602
2 changed files with 113 additions and 109 deletions

View File

@ -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;
}

View File

@ -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() &&