From 8a11053f3ca7efb29312c4293c4fdb5d2ca3e20f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 5 Sep 2008 22:59:21 +0000 Subject: [PATCH] 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 --- lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp | 102 --------------- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 120 +++++++++++++++++- 2 files changed, 113 insertions(+), 109 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp index 21c12d3993f..8471a9a84f2 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp @@ -30,13 +30,6 @@ using namespace llvm; STATISTIC(NumCommutes, "Number of instructions commuted"); -namespace { - static cl::opt - 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 &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::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 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 VRBaseMap; DenseMap 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; } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index b4ba64ea279..a4bc5fbbb16 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -63,6 +63,10 @@ static cl::opt DisableFastISelAbort("fast-isel-no-abort", cl::Hidden, cl::desc("Use the SelectionDAGISel when \"fast\" instruction " "selection fails")); +static cl::opt +SchedLiveInCopies("schedule-livein-copies", + cl::desc("Schedule copies of livein registers"), + cl::init(false)); #ifndef NDEBUG static cl::opt @@ -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 &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::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 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(); - 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().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() && -- 2.34.1