131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- MBlazeMachineFunctionInfo.h - Private data --------------*- C++ -*-===//
2a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//
3a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//                     The LLVM Compiler Infrastructure
4a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//
5a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// This file is distributed under the University of Illinois Open Source
6a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// License. See LICENSE.TXT for details.
7a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//
8a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===//
9a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//
10a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// This file declares the MBlaze specific subclass of MachineFunctionInfo.
11a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//
12a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===//
13a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
14a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#ifndef MBLAZE_MACHINE_FUNCTION_INFO_H
15a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#define MBLAZE_MACHINE_FUNCTION_INFO_H
16a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
173d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck#include "llvm/ADT/DenseMap.h"
18a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/ADT/SmallVector.h"
19a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineFrameInfo.h"
20a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "llvm/CodeGen/MachineFunction.h"
21a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
22a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Pecknamespace llvm {
23a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
24a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// MBlazeFunctionInfo - This class is derived from MachineFunction private
25a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// MBlaze target-specific information for each MachineFunction.
26a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckclass MBlazeFunctionInfo : public MachineFunctionInfo {
272d24e2a396a1d211baaeedf32148a3b657240170David Blaikie  virtual void anchor();
28a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
290a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  /// Holds for each function where on the stack the Frame Pointer must be
30a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  /// saved. This is used on Prologue and Epilogue to emit FP save/restore
31a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  int FPStackOffset;
32a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
330a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  /// Holds for each function where on the stack the Return Address must be
34a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  /// saved. This is used on Prologue and Epilogue to emit RA save/restore
35a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  int RAStackOffset;
36a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
37a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  /// MBlazeFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
38a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  struct MBlazeFIHolder {
39a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
40a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    int FI;
41a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    int SPOffset;
42a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
43a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    MBlazeFIHolder(int FrameIndex, int StackPointerOffset)
44a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck      : FI(FrameIndex), SPOffset(StackPointerOffset) {}
45a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  };
46a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
470a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  /// When PIC is used the GP must be saved on the stack on the function
480a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  /// prologue and must be reloaded from this stack location after every
490a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  /// call. A reference to its stack location and frame index must be kept
50a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  /// to be used on emitPrologue and processFunctionBeforeFrameFinalized.
51a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  MBlazeFIHolder GPHolder;
52a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
53a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  /// On LowerFormalArguments the stack size is unknown, so the Stack
540a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  /// Pointer Offset calculation of "not in register arguments" must be
550a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  /// postponed to emitPrologue.
56a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  SmallVector<MBlazeFIHolder, 16> FnLoadArgs;
57a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  bool HasLoadArgs;
58a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
590a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // When VarArgs, we must write registers back to caller stack, preserving
600a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // on register arguments. Since the stack size is unknown on
61a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  // LowerFormalArguments, the Stack Pointer Offset calculation must be
620a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  // postponed to emitPrologue.
63a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  SmallVector<MBlazeFIHolder, 4> FnStoreVarArgs;
64a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  bool HasStoreVarArgs;
65a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
663d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck  // When determining the final stack layout some of the frame indexes may
673d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck  // be replaced by new frame indexes that reside in the caller's stack
683d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck  // frame. The replacements are recorded in this structure.
693d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck  DenseMap<int,int> FIReplacements;
703d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck
71a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  /// SRetReturnReg - Some subtargets require that sret lowering includes
72a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  /// returning the value of the returned struct in a register. This field
73a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  /// holds the virtual register into which the sret argument is passed.
74a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  unsigned SRetReturnReg;
75a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
76a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  /// GlobalBaseReg - keeps track of the virtual register initialized for
77a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  /// use as the global base register. This is used for PIC in some PIC
78a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  /// relocation models.
79a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  unsigned GlobalBaseReg;
80a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
811e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  // VarArgsFrameIndex - FrameIndex for start of varargs area.
821e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  int VarArgsFrameIndex;
831e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman
84eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck  /// LiveInFI - keeps track of the frame indexes in a callers stack
85eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck  /// frame that are live into a function.
86eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck  SmallVector<int, 16> LiveInFI;
87eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck
88a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckpublic:
890a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  MBlazeFunctionInfo(MachineFunction& MF)
90b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck  : FPStackOffset(0), RAStackOffset(0), GPHolder(-1,-1), HasLoadArgs(false),
91b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck    HasStoreVarArgs(false), SRetReturnReg(0), GlobalBaseReg(0),
92b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck    VarArgsFrameIndex(0), LiveInFI()
93a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  {}
94a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
95a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  int getFPStackOffset() const { return FPStackOffset; }
96a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  void setFPStackOffset(int Off) { FPStackOffset = Off; }
97a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
98a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  int getRAStackOffset() const { return RAStackOffset; }
99a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  void setRAStackOffset(int Off) { RAStackOffset = Off; }
100a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
101a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  int getGPStackOffset() const { return GPHolder.SPOffset; }
102a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  int getGPFI() const { return GPHolder.FI; }
103a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; }
104a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  void setGPFI(int FI) { GPHolder.FI = FI; }
105a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  bool needGPSaveRestore() const { return GPHolder.SPOffset != -1; }
106a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
107a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  bool hasLoadArgs() const { return HasLoadArgs; }
1080a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck  bool hasStoreVarArgs() const { return HasStoreVarArgs; }
109a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
110eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck  void recordLiveIn(int FI) {
111eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck    LiveInFI.push_back(FI);
112eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck  }
113eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck
114eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck  bool isLiveIn(int FI) {
115eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck    for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i)
116eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck      if (FI == LiveInFI[i]) return true;
117eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck
118eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck    return false;
119eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck  }
120eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck
121eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck  const SmallVector<int, 16>& getLiveIn() const { return LiveInFI; }
122eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck
1233d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck  void recordReplacement(int OFI, int NFI) {
1243d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck    FIReplacements.insert(std::make_pair(OFI,NFI));
1253d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck  }
1263d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck
1273d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck  bool hasReplacement(int OFI) const {
1283d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck    return FIReplacements.find(OFI) != FIReplacements.end();
1293d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck  }
1303d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck
1313d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck  int getReplacement(int OFI) const {
1323d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck    return FIReplacements.lookup(OFI);
1333d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck  }
1343d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck
135a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  void recordLoadArgsFI(int FI, int SPOffset) {
136a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    if (!HasLoadArgs) HasLoadArgs=true;
137a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    FnLoadArgs.push_back(MBlazeFIHolder(FI, SPOffset));
138a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  }
139b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck
140a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  void recordStoreVarArgsFI(int FI, int SPOffset) {
141a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    if (!HasStoreVarArgs) HasStoreVarArgs=true;
142a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    FnStoreVarArgs.push_back(MBlazeFIHolder(FI, SPOffset));
143a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  }
144a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
145a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  void adjustLoadArgsFI(MachineFrameInfo *MFI) const {
146a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    if (!hasLoadArgs()) return;
1470a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    for (unsigned i = 0, e = FnLoadArgs.size(); i != e; ++i)
1480a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      MFI->setObjectOffset(FnLoadArgs[i].FI, FnLoadArgs[i].SPOffset);
149a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  }
150b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck
151a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  void adjustStoreVarArgsFI(MachineFrameInfo *MFI) const {
1520a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    if (!hasStoreVarArgs()) return;
1530a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck    for (unsigned i = 0, e = FnStoreVarArgs.size(); i != e; ++i)
1540a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck      MFI->setObjectOffset(FnStoreVarArgs[i].FI, FnStoreVarArgs[i].SPOffset);
155a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  }
156a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
157a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  unsigned getSRetReturnReg() const { return SRetReturnReg; }
158a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
159a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
160a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
161a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
1621e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman
1631e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
1641e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
165a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck};
166a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
167a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} // end of namespace llvm
168a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
169a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#endif // MBLAZE_MACHINE_FUNCTION_INFO_H
170