Changes in directory llvm/lib/Target/PowerPC:
PPCISelDAGToDAG.cpp updated: 1.167 -> 1.168 --- Log message: Save/restore VRSAVE once per function, not once per block. --- Diffs of the changes: (+52 -39) PPCISelDAGToDAG.cpp | 91 +++++++++++++++++++++++++++++----------------------- 1 files changed, 52 insertions(+), 39 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.167 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.168 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.167 Tue Mar 14 11:56:49 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu Mar 16 12:25:23 2006 @@ -39,17 +39,21 @@ /// 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 @@ /// 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 @@ // 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 @@ 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 @@ // 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. /// _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits