[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Thu Mar 16 10:25:35 PST 2006
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.
///
More information about the llvm-commits
mailing list