mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
Save/restore VRSAVE once per function, not once per block.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26793 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
41ff717e85
commit
4bb1895072
@ -39,17 +39,21 @@ namespace {
|
||||
/// instructions for SelectionDAG operations.
|
||||
///
|
||||
class PPCDAGToDAGISel : public SelectionDAGISel {
|
||||
PPCTargetMachine &TM;
|
||||
PPCTargetLowering PPCLowering;
|
||||
unsigned GlobalBaseReg;
|
||||
public:
|
||||
PPCDAGToDAGISel(PPCTargetMachine &TM)
|
||||
: SelectionDAGISel(PPCLowering),
|
||||
PPCLowering(*TM.getTargetLowering()){}
|
||||
PPCDAGToDAGISel(PPCTargetMachine &tm)
|
||||
: SelectionDAGISel(PPCLowering), TM(tm),
|
||||
PPCLowering(*TM.getTargetLowering()) {}
|
||||
|
||||
virtual bool runOnFunction(Function &Fn) {
|
||||
// Make sure we re-emit a set of the global base reg if necessary
|
||||
GlobalBaseReg = 0;
|
||||
return SelectionDAGISel::runOnFunction(Fn);
|
||||
SelectionDAGISel::runOnFunction(Fn);
|
||||
|
||||
InsertVRSaveCode(Fn);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// getI32Imm - Return a target constant with the specified value, of type
|
||||
@ -121,6 +125,8 @@ namespace {
|
||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
|
||||
|
||||
void InsertVRSaveCode(Function &Fn);
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "PowerPC DAG->DAG Pattern Instruction Selection";
|
||||
}
|
||||
@ -199,13 +205,19 @@ void PPCDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||
|
||||
// Emit machine code to BB.
|
||||
ScheduleAndEmitDAG(DAG);
|
||||
|
||||
}
|
||||
|
||||
/// InsertVRSaveCode - Once the entire function has been instruction selected,
|
||||
/// all virtual registers are created and all machine instructions are built,
|
||||
/// check to see if we need to save/restore VRSAVE. If so, do it.
|
||||
void PPCDAGToDAGISel::InsertVRSaveCode(Function &F) {
|
||||
// Check to see if this function uses vector registers, which means we have to
|
||||
// save and restore the VRSAVE register and update it with the regs we use.
|
||||
//
|
||||
// In this case, there will be virtual registers of vector type type created
|
||||
// by the scheduler. Detect them now.
|
||||
SSARegMap *RegMap = DAG.getMachineFunction().getSSARegMap();
|
||||
MachineFunction &Fn = MachineFunction::get(&F);
|
||||
SSARegMap *RegMap = Fn.getSSARegMap();
|
||||
bool HasVectorVReg = false;
|
||||
for (unsigned i = MRegisterInfo::FirstVirtualRegister,
|
||||
e = RegMap->getLastVirtReg()+1; i != e; ++i)
|
||||
@ -213,7 +225,8 @@ void PPCDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||
HasVectorVReg = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!HasVectorVReg) return; // nothing to do.
|
||||
|
||||
// If we have a vector register, we want to emit code into the entry and exit
|
||||
// blocks to save and restore the VRSAVE register. We do this here (instead
|
||||
// of marking all vector instructions as clobbering VRSAVE) for two reasons:
|
||||
@ -223,41 +236,41 @@ void PPCDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||
// 2. This (more significantly) allows us to create a temporary virtual
|
||||
// register to hold the saved VRSAVE value, allowing this temporary to be
|
||||
// register allocated, instead of forcing it to be spilled to the stack.
|
||||
if (HasVectorVReg) {
|
||||
// Create two vregs - one to hold the VRSAVE register that is live-in to the
|
||||
// function and one for the value after having bits or'd into it.
|
||||
unsigned InVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
|
||||
unsigned UpdatedVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineBasicBlock &EntryBB = *MF.begin();
|
||||
// Emit the following code into the entry block:
|
||||
// InVRSAVE = MFVRSAVE
|
||||
// UpdatedVRSAVE = UPDATE_VRSAVE InVRSAVE
|
||||
// MTVRSAVE UpdatedVRSAVE
|
||||
MachineBasicBlock::iterator IP = EntryBB.begin(); // Insert Point
|
||||
BuildMI(EntryBB, IP, PPC::MFVRSAVE, 0, InVRSAVE);
|
||||
BuildMI(EntryBB, IP, PPC::UPDATE_VRSAVE, 1, UpdatedVRSAVE).addReg(InVRSAVE);
|
||||
BuildMI(EntryBB, IP, PPC::MTVRSAVE, 1).addReg(UpdatedVRSAVE);
|
||||
|
||||
// Find all return blocks, outputting a restore in each epilog.
|
||||
const TargetInstrInfo &TII = *DAG.getTarget().getInstrInfo();
|
||||
for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
|
||||
if (!BB->empty() && TII.isReturn(BB->back().getOpcode())) {
|
||||
IP = BB->end(); --IP;
|
||||
|
||||
// Skip over all terminator instructions, which are part of the return
|
||||
// sequence.
|
||||
MachineBasicBlock::iterator I2 = IP;
|
||||
while (I2 != BB->begin() && TII.isTerminatorInstr((--I2)->getOpcode()))
|
||||
IP = I2;
|
||||
|
||||
// Emit: MTVRSAVE InVRSave
|
||||
BuildMI(*BB, IP, PPC::MTVRSAVE, 1).addReg(InVRSAVE);
|
||||
}
|
||||
|
||||
// Create two vregs - one to hold the VRSAVE register that is live-in to the
|
||||
// function and one for the value after having bits or'd into it.
|
||||
unsigned InVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
|
||||
unsigned UpdatedVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
|
||||
|
||||
MachineBasicBlock &EntryBB = *Fn.begin();
|
||||
// Emit the following code into the entry block:
|
||||
// InVRSAVE = MFVRSAVE
|
||||
// UpdatedVRSAVE = UPDATE_VRSAVE InVRSAVE
|
||||
// MTVRSAVE UpdatedVRSAVE
|
||||
MachineBasicBlock::iterator IP = EntryBB.begin(); // Insert Point
|
||||
BuildMI(EntryBB, IP, PPC::MFVRSAVE, 0, InVRSAVE);
|
||||
BuildMI(EntryBB, IP, PPC::UPDATE_VRSAVE, 1, UpdatedVRSAVE).addReg(InVRSAVE);
|
||||
BuildMI(EntryBB, IP, PPC::MTVRSAVE, 1).addReg(UpdatedVRSAVE);
|
||||
|
||||
// Find all return blocks, outputting a restore in each epilog.
|
||||
const TargetInstrInfo &TII = *TM.getInstrInfo();
|
||||
for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
|
||||
if (!BB->empty() && TII.isReturn(BB->back().getOpcode())) {
|
||||
IP = BB->end(); --IP;
|
||||
|
||||
// Skip over all terminator instructions, which are part of the return
|
||||
// sequence.
|
||||
MachineBasicBlock::iterator I2 = IP;
|
||||
while (I2 != BB->begin() && TII.isTerminatorInstr((--I2)->getOpcode()))
|
||||
IP = I2;
|
||||
|
||||
// Emit: MTVRSAVE InVRSave
|
||||
BuildMI(*BB, IP, PPC::MTVRSAVE, 1).addReg(InVRSAVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// getGlobalBaseReg - Output the instructions required to put the
|
||||
/// base address to use for accessing globals into a register.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user