mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-09 03:56:28 +00:00
Move the code for emitting livein copies out of SelectionDAGISel.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101254 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
67894a3d02
commit
98708260f5
@ -261,6 +261,12 @@ public:
|
|||||||
bool isLiveIn(unsigned Reg) const;
|
bool isLiveIn(unsigned Reg) const;
|
||||||
bool isLiveOut(unsigned Reg) const;
|
bool isLiveOut(unsigned Reg) const;
|
||||||
|
|
||||||
|
/// EmitLiveInCopies - Emit copies to initialize livein virtual registers
|
||||||
|
/// into the given entry block.
|
||||||
|
void EmitLiveInCopies(MachineBasicBlock *EntryMBB,
|
||||||
|
const TargetRegisterInfo &TRI,
|
||||||
|
const TargetInstrInfo &TII);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void HandleVRegListReallocation();
|
void HandleVRegListReallocation();
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
MachineRegisterInfo::MachineRegisterInfo(const TargetRegisterInfo &TRI) {
|
MachineRegisterInfo::MachineRegisterInfo(const TargetRegisterInfo &TRI) {
|
||||||
@ -144,6 +146,110 @@ bool MachineRegisterInfo::isLiveOut(unsigned Reg) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cl::opt<bool>
|
||||||
|
SchedLiveInCopies("schedule-livein-copies", cl::Hidden,
|
||||||
|
cl::desc("Schedule copies of livein registers"),
|
||||||
|
cl::init(false));
|
||||||
|
|
||||||
|
/// 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, SrcSubReg, DstSubReg;
|
||||||
|
if (NumUses == 1 &&
|
||||||
|
TII.isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Emitted = TII.copyRegToReg(*MBB, Pos, VirtReg, PhysReg, RC, RC);
|
||||||
|
assert(Emitted && "Unable to issue a live-in copy instruction!\n");
|
||||||
|
(void) Emitted;
|
||||||
|
|
||||||
|
CopyRegMap.insert(std::make_pair(prior(Pos), VirtReg));
|
||||||
|
if (Coalesced) {
|
||||||
|
if (&*InsertPos == UseMI) ++InsertPos;
|
||||||
|
MBB->erase(UseMI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// EmitLiveInCopies - Emit copies to initialize livein virtual registers
|
||||||
|
/// into the given entry block.
|
||||||
|
void
|
||||||
|
MachineRegisterInfo::EmitLiveInCopies(MachineBasicBlock *EntryMBB,
|
||||||
|
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 = livein_begin(),
|
||||||
|
E = livein_end(); LI != E; ++LI)
|
||||||
|
if (LI->second) {
|
||||||
|
const TargetRegisterClass *RC = getRegClass(LI->second);
|
||||||
|
EmitLiveInCopy(EntryMBB, InsertPos, LI->second, LI->first,
|
||||||
|
RC, CopyRegMap, *this, TRI, TII);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Emit the copies into the top of the block.
|
||||||
|
for (MachineRegisterInfo::livein_iterator LI = livein_begin(),
|
||||||
|
E = livein_end(); LI != E; ++LI)
|
||||||
|
if (LI->second) {
|
||||||
|
const TargetRegisterClass *RC = getRegClass(LI->second);
|
||||||
|
bool Emitted = TII.copyRegToReg(*EntryMBB, EntryMBB->begin(),
|
||||||
|
LI->second, LI->first, RC, RC);
|
||||||
|
assert(Emitted && "Unable to issue a live-in copy instruction!\n");
|
||||||
|
(void) Emitted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void MachineRegisterInfo::dumpUses(unsigned Reg) const {
|
void MachineRegisterInfo::dumpUses(unsigned Reg) const {
|
||||||
for (use_iterator I = use_begin(Reg), E = use_end(); I != E; ++I)
|
for (use_iterator I = use_begin(Reg), E = use_end(); I != E; ++I)
|
||||||
|
@ -69,10 +69,6 @@ EnableFastISelVerbose("fast-isel-verbose", cl::Hidden,
|
|||||||
static cl::opt<bool>
|
static cl::opt<bool>
|
||||||
EnableFastISelAbort("fast-isel-abort", cl::Hidden,
|
EnableFastISelAbort("fast-isel-abort", cl::Hidden,
|
||||||
cl::desc("Enable abort calls when \"fast\" instruction fails"));
|
cl::desc("Enable abort calls when \"fast\" instruction fails"));
|
||||||
static cl::opt<bool>
|
|
||||||
SchedLiveInCopies("schedule-livein-copies", cl::Hidden,
|
|
||||||
cl::desc("Schedule copies of livein registers"),
|
|
||||||
cl::init(false));
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
static cl::opt<bool>
|
static cl::opt<bool>
|
||||||
@ -173,106 +169,6 @@ MachineBasicBlock *TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
|||||||
return 0;
|
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, SrcSubReg, DstSubReg;
|
|
||||||
if (NumUses == 1 &&
|
|
||||||
TII.isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Emitted = TII.copyRegToReg(*MBB, Pos, VirtReg, PhysReg, RC, RC);
|
|
||||||
assert(Emitted && "Unable to issue a live-in copy instruction!\n");
|
|
||||||
(void) Emitted;
|
|
||||||
|
|
||||||
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);
|
|
||||||
bool Emitted = TII.copyRegToReg(*EntryMBB, EntryMBB->begin(),
|
|
||||||
LI->second, LI->first, RC, RC);
|
|
||||||
assert(Emitted && "Unable to issue a live-in copy instruction!\n");
|
|
||||||
(void) Emitted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// SelectionDAGISel code
|
// SelectionDAGISel code
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -337,7 +233,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
// If the first basic block in the function has live ins that need to be
|
// 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
|
// copied into vregs, emit the copies into the top of the block before
|
||||||
// emitting the code for the block.
|
// emitting the code for the block.
|
||||||
EmitLiveInCopies(MF->begin(), *RegInfo, TRI, TII);
|
RegInfo->EmitLiveInCopies(MF->begin(), TRI, TII);
|
||||||
|
|
||||||
// Add function live-ins to entry block live-in set.
|
// Add function live-ins to entry block live-in set.
|
||||||
for (MachineRegisterInfo::livein_iterator I = RegInfo->livein_begin(),
|
for (MachineRegisterInfo::livein_iterator I = RegInfo->livein_begin(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user