1 //===-- MBlazeMachineFunctionInfo.h - Private data --------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file declares the MBlaze specific subclass of MachineFunctionInfo. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef MBLAZE_MACHINE_FUNCTION_INFO_H 15 #define MBLAZE_MACHINE_FUNCTION_INFO_H 16 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/CodeGen/MachineFrameInfo.h" 20 #include "llvm/CodeGen/MachineFunction.h" 21 22 namespace llvm { 23 24 /// MBlazeFunctionInfo - This class is derived from MachineFunction private 25 /// MBlaze target-specific information for each MachineFunction. 26 class MBlazeFunctionInfo : public MachineFunctionInfo { 27 virtual void anchor(); 28 29 /// Holds for each function where on the stack the Frame Pointer must be 30 /// saved. This is used on Prologue and Epilogue to emit FP save/restore 31 int FPStackOffset; 32 33 /// Holds for each function where on the stack the Return Address must be 34 /// saved. This is used on Prologue and Epilogue to emit RA save/restore 35 int RAStackOffset; 36 37 /// MBlazeFIHolder - Holds a FrameIndex and it's Stack Pointer Offset 38 struct MBlazeFIHolder { 39 40 int FI; 41 int SPOffset; 42 MBlazeFIHolderMBlazeFIHolder43 MBlazeFIHolder(int FrameIndex, int StackPointerOffset) 44 : FI(FrameIndex), SPOffset(StackPointerOffset) {} 45 }; 46 47 /// When PIC is used the GP must be saved on the stack on the function 48 /// prologue and must be reloaded from this stack location after every 49 /// call. A reference to its stack location and frame index must be kept 50 /// to be used on emitPrologue and processFunctionBeforeFrameFinalized. 51 MBlazeFIHolder GPHolder; 52 53 /// On LowerFormalArguments the stack size is unknown, so the Stack 54 /// Pointer Offset calculation of "not in register arguments" must be 55 /// postponed to emitPrologue. 56 SmallVector<MBlazeFIHolder, 16> FnLoadArgs; 57 bool HasLoadArgs; 58 59 // When VarArgs, we must write registers back to caller stack, preserving 60 // on register arguments. Since the stack size is unknown on 61 // LowerFormalArguments, the Stack Pointer Offset calculation must be 62 // postponed to emitPrologue. 63 SmallVector<MBlazeFIHolder, 4> FnStoreVarArgs; 64 bool HasStoreVarArgs; 65 66 // When determining the final stack layout some of the frame indexes may 67 // be replaced by new frame indexes that reside in the caller's stack 68 // frame. The replacements are recorded in this structure. 69 DenseMap<int,int> FIReplacements; 70 71 /// SRetReturnReg - Some subtargets require that sret lowering includes 72 /// returning the value of the returned struct in a register. This field 73 /// holds the virtual register into which the sret argument is passed. 74 unsigned SRetReturnReg; 75 76 /// GlobalBaseReg - keeps track of the virtual register initialized for 77 /// use as the global base register. This is used for PIC in some PIC 78 /// relocation models. 79 unsigned GlobalBaseReg; 80 81 // VarArgsFrameIndex - FrameIndex for start of varargs area. 82 int VarArgsFrameIndex; 83 84 /// LiveInFI - keeps track of the frame indexes in a callers stack 85 /// frame that are live into a function. 86 SmallVector<int, 16> LiveInFI; 87 88 public: MBlazeFunctionInfo(MachineFunction & MF)89 MBlazeFunctionInfo(MachineFunction& MF) 90 : FPStackOffset(0), RAStackOffset(0), GPHolder(-1,-1), HasLoadArgs(false), 91 HasStoreVarArgs(false), SRetReturnReg(0), GlobalBaseReg(0), 92 VarArgsFrameIndex(0), LiveInFI() 93 {} 94 getFPStackOffset()95 int getFPStackOffset() const { return FPStackOffset; } setFPStackOffset(int Off)96 void setFPStackOffset(int Off) { FPStackOffset = Off; } 97 getRAStackOffset()98 int getRAStackOffset() const { return RAStackOffset; } setRAStackOffset(int Off)99 void setRAStackOffset(int Off) { RAStackOffset = Off; } 100 getGPStackOffset()101 int getGPStackOffset() const { return GPHolder.SPOffset; } getGPFI()102 int getGPFI() const { return GPHolder.FI; } setGPStackOffset(int Off)103 void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; } setGPFI(int FI)104 void setGPFI(int FI) { GPHolder.FI = FI; } needGPSaveRestore()105 bool needGPSaveRestore() const { return GPHolder.SPOffset != -1; } 106 hasLoadArgs()107 bool hasLoadArgs() const { return HasLoadArgs; } hasStoreVarArgs()108 bool hasStoreVarArgs() const { return HasStoreVarArgs; } 109 recordLiveIn(int FI)110 void recordLiveIn(int FI) { 111 LiveInFI.push_back(FI); 112 } 113 isLiveIn(int FI)114 bool isLiveIn(int FI) { 115 for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) 116 if (FI == LiveInFI[i]) return true; 117 118 return false; 119 } 120 getLiveIn()121 const SmallVector<int, 16>& getLiveIn() const { return LiveInFI; } 122 recordReplacement(int OFI,int NFI)123 void recordReplacement(int OFI, int NFI) { 124 FIReplacements.insert(std::make_pair(OFI,NFI)); 125 } 126 hasReplacement(int OFI)127 bool hasReplacement(int OFI) const { 128 return FIReplacements.find(OFI) != FIReplacements.end(); 129 } 130 getReplacement(int OFI)131 int getReplacement(int OFI) const { 132 return FIReplacements.lookup(OFI); 133 } 134 recordLoadArgsFI(int FI,int SPOffset)135 void recordLoadArgsFI(int FI, int SPOffset) { 136 if (!HasLoadArgs) HasLoadArgs=true; 137 FnLoadArgs.push_back(MBlazeFIHolder(FI, SPOffset)); 138 } 139 recordStoreVarArgsFI(int FI,int SPOffset)140 void recordStoreVarArgsFI(int FI, int SPOffset) { 141 if (!HasStoreVarArgs) HasStoreVarArgs=true; 142 FnStoreVarArgs.push_back(MBlazeFIHolder(FI, SPOffset)); 143 } 144 adjustLoadArgsFI(MachineFrameInfo * MFI)145 void adjustLoadArgsFI(MachineFrameInfo *MFI) const { 146 if (!hasLoadArgs()) return; 147 for (unsigned i = 0, e = FnLoadArgs.size(); i != e; ++i) 148 MFI->setObjectOffset(FnLoadArgs[i].FI, FnLoadArgs[i].SPOffset); 149 } 150 adjustStoreVarArgsFI(MachineFrameInfo * MFI)151 void adjustStoreVarArgsFI(MachineFrameInfo *MFI) const { 152 if (!hasStoreVarArgs()) return; 153 for (unsigned i = 0, e = FnStoreVarArgs.size(); i != e; ++i) 154 MFI->setObjectOffset(FnStoreVarArgs[i].FI, FnStoreVarArgs[i].SPOffset); 155 } 156 getSRetReturnReg()157 unsigned getSRetReturnReg() const { return SRetReturnReg; } setSRetReturnReg(unsigned Reg)158 void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; } 159 getGlobalBaseReg()160 unsigned getGlobalBaseReg() const { return GlobalBaseReg; } setGlobalBaseReg(unsigned Reg)161 void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; } 162 getVarArgsFrameIndex()163 int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } setVarArgsFrameIndex(int Index)164 void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; } 165 }; 166 167 } // end of namespace llvm 168 169 #endif // MBLAZE_MACHINE_FUNCTION_INFO_H 170