98391dce5f9a7641c104d83659e0e53b82e1846e
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9PrologEpilogInserter.cpp
1 //===-- PrologEpilogCodeInserter.cpp - Insert Prolog & Epilog code for fn -===//
2 //
3 // Insert SAVE/RESTORE instructions for the function
4 //
5 // Insert prolog code at the unique function entry point.
6 // Insert epilog code at each function exit point.
7 // InsertPrologEpilog invokes these only if the function is not compiled
8 // with the leaf function optimization.
9 //
10 //===----------------------------------------------------------------------===//
11
12 #include "SparcInternals.h"
13 #include "SparcRegClassInfo.h"
14 #include "llvm/CodeGen/MachineFunctionPass.h"
15 #include "llvm/CodeGen/MachineFunctionInfo.h"
16 #include "llvm/CodeGen/MachineCodeForInstruction.h"
17 #include "llvm/CodeGen/MachineInstrBuilder.h"
18 #include "llvm/Pass.h"
19 #include "llvm/Function.h"
20
21 namespace {
22   struct InsertPrologEpilogCode : public MachineFunctionPass {
23     const char *getPassName() const { return "Sparc Prolog/Epilog Inserter"; }
24     
25     bool runOnMachineFunction(MachineFunction &F) {
26       if (!F.getInfo()->isCompiledAsLeafMethod()) {
27         InsertPrologCode(F);
28         InsertEpilogCode(F);
29       }
30       return false;
31     }
32     
33     void InsertPrologCode(MachineFunction &F);
34     void InsertEpilogCode(MachineFunction &F);
35   };
36
37 }  // End anonymous namespace
38
39 //------------------------------------------------------------------------ 
40 //   Create prolog and epilog code for procedure entry and exit
41 //------------------------------------------------------------------------ 
42
43 void InsertPrologEpilogCode::InsertPrologCode(MachineFunction &MF)
44 {
45   std::vector<MachineInstr*> mvec;
46   const TargetMachine &TM = MF.getTarget();
47   const TargetFrameInfo& frameInfo = TM.getFrameInfo();
48   
49   // The second operand is the stack size. If it does not fit in the
50   // immediate field, we have to use a free register to hold the size.
51   // See the comments below for the choice of this register.
52   // 
53   unsigned staticStackSize = MF.getInfo()->getStaticStackSize();
54   
55   if (staticStackSize < (unsigned) frameInfo.getMinStackFrameSize())
56     staticStackSize = (unsigned) frameInfo.getMinStackFrameSize();
57
58   if (unsigned padsz = (staticStackSize %
59                         (unsigned) frameInfo.getStackFrameSizeAlignment()))
60     staticStackSize += frameInfo.getStackFrameSizeAlignment() - padsz;
61   
62   int32_t C = - (int) staticStackSize;
63   int SP = TM.getRegInfo().getStackPointer();
64   if (TM.getInstrInfo().constantFitsInImmedField(SAVE, staticStackSize)) {
65     mvec.push_back(BuildMI(SAVE, 3).addMReg(SP).addSImm(C).addMReg(SP,
66                                                                    MOTy::Def));
67   } else {
68     // We have to put the stack size value into a register before SAVE.
69     // Use register %g1 since it is volatile across calls.  Note that the
70     // local (%l) and in (%i) registers cannot be used before the SAVE!
71     // Do this by creating a code sequence equivalent to:
72     //        SETSW -(stackSize), %g1
73     int uregNum = TM.getRegInfo().getUnifiedRegNum(
74                          TM.getRegInfo().getRegClassIDOfType(Type::IntTy),
75                          SparcIntRegClass::g1);
76
77     MachineInstr* M = BuildMI(SETHI, 2).addSImm(C).addMReg(uregNum, MOTy::Def);
78     M->setOperandHi32(0);
79     mvec.push_back(M);
80     
81     M = BuildMI(OR, 3).addMReg(uregNum).addSImm(C).addMReg(uregNum, MOTy::Def);
82     M->setOperandLo32(1);
83     mvec.push_back(M);
84     
85     M = BuildMI(SRA, 3).addMReg(uregNum).addZImm(0).addMReg(uregNum, MOTy::Def);
86     mvec.push_back(M);
87     
88     // Now generate the SAVE using the value in register %g1
89     M = BuildMI(SAVE, 3).addMReg(SP).addMReg(uregNum).addMReg(SP, MOTy::Def);
90     mvec.push_back(M);
91   }
92
93   MF.front().insert(MF.front().begin(), mvec.begin(), mvec.end());
94 }
95
96 void InsertPrologEpilogCode::InsertEpilogCode(MachineFunction &MF)
97 {
98   const TargetMachine &TM = MF.getTarget();
99   const TargetInstrInfo &MII = TM.getInstrInfo();
100
101   for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
102     MachineBasicBlock &MBB = *I;
103     BasicBlock &BB = *I->getBasicBlock();
104     Instruction *TermInst = (Instruction*)BB.getTerminator();
105     if (TermInst->getOpcode() == Instruction::Ret)
106       {
107         int ZR = TM.getRegInfo().getZeroRegNum();
108         MachineInstr *Restore =
109           BuildMI(RESTORE, 3).addMReg(ZR).addSImm(0).addMReg(ZR, MOTy::Def);
110         
111         MachineCodeForInstruction &termMvec =
112           MachineCodeForInstruction::get(TermInst);
113         
114         // Remove the NOPs in the delay slots of the return instruction
115         unsigned numNOPs = 0;
116         while (termMvec.back()->getOpCode() == NOP)
117           {
118             assert( termMvec.back() == MBB.back());
119             delete MBB.pop_back();
120             termMvec.pop_back();
121             ++numNOPs;
122           }
123         assert(termMvec.back() == MBB.back());
124         
125         // Check that we found the right number of NOPs and have the right
126         // number of instructions to replace them.
127         unsigned ndelays = MII.getNumDelaySlots(termMvec.back()->getOpCode());
128         assert(numNOPs == ndelays && "Missing NOPs in delay slots?");
129         assert(ndelays == 1 && "Cannot use epilog code for delay slots?");
130         
131         // Append the epilog code to the end of the basic block.
132         MBB.push_back(Restore);
133       }
134   }
135 }
136
137 Pass* UltraSparc::getPrologEpilogInsertionPass() {
138   return new InsertPrologEpilogCode();
139 }