PTXMachineFunctionInfo.h revision 2d24e2a396a1d211baaeedf32148a3b657240170
1//===- PTXMachineFuctionInfo.h - PTX machine function info -------*- 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 PTX-specific per-machine-function information.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef PTX_MACHINE_FUNCTION_INFO_H
15#define PTX_MACHINE_FUNCTION_INFO_H
16
17#include "PTX.h"
18#include "PTXParamManager.h"
19#include "PTXRegisterInfo.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/DenseSet.h"
22#include "llvm/ADT/StringExtras.h"
23#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/raw_ostream.h"
26
27namespace llvm {
28
29/// PTXMachineFunctionInfo - This class is derived from MachineFunction and
30/// contains private PTX target-specific information for each MachineFunction.
31///
32class PTXMachineFunctionInfo : public MachineFunctionInfo {
33  virtual void anchor();
34  bool IsKernel;
35  DenseSet<unsigned> RegArgs;
36  DenseSet<unsigned> RegRets;
37
38  typedef DenseMap<int, std::string> FrameMap;
39
40  FrameMap FrameSymbols;
41
42  struct RegisterInfo {
43    unsigned Reg;
44    unsigned Type;
45    unsigned Space;
46    unsigned Offset;
47    unsigned Encoded;
48  };
49
50  typedef DenseMap<unsigned, RegisterInfo> RegisterInfoMap;
51
52  RegisterInfoMap RegInfo;
53
54  PTXParamManager ParamManager;
55
56public:
57  typedef DenseSet<unsigned>::const_iterator reg_iterator;
58
59  PTXMachineFunctionInfo(MachineFunction &MF)
60    : IsKernel(false) {
61  }
62
63  /// getParamManager - Returns the PTXParamManager instance for this function.
64  PTXParamManager& getParamManager() { return ParamManager; }
65  const PTXParamManager& getParamManager() const { return ParamManager; }
66
67  /// setKernel/isKernel - Gets/sets a flag that indicates if this function is
68  /// a PTX kernel function.
69  void setKernel(bool _IsKernel=true) { IsKernel = _IsKernel; }
70  bool isKernel() const { return IsKernel; }
71
72  /// argreg_begin/argreg_end - Returns iterators to the set of registers
73  /// containing function arguments.
74  reg_iterator argreg_begin() const { return RegArgs.begin(); }
75  reg_iterator argreg_end()   const { return RegArgs.end(); }
76
77  /// retreg_begin/retreg_end - Returns iterators to the set of registers
78  /// containing the function return values.
79  reg_iterator retreg_begin() const { return RegRets.begin(); }
80  reg_iterator retreg_end()   const { return RegRets.end(); }
81
82  /// addRegister - Adds a virtual register to the set of all used registers
83  void addRegister(unsigned Reg, unsigned RegType, unsigned RegSpace) {
84    if (!RegInfo.count(Reg)) {
85      RegisterInfo Info;
86      Info.Reg = Reg;
87      Info.Type = RegType;
88      Info.Space = RegSpace;
89
90      // Determine register offset
91      Info.Offset = 0;
92      for(RegisterInfoMap::const_iterator i = RegInfo.begin(),
93          e = RegInfo.end(); i != e; ++i) {
94        const RegisterInfo& RI = i->second;
95        if (RI.Space == RegSpace)
96          if (RI.Space != PTXRegisterSpace::Reg || RI.Type == Info.Type)
97            Info.Offset++;
98      }
99
100      // Encode the register data into a single register number
101      Info.Encoded = (Info.Offset << 6) | (Info.Type << 3) | Info.Space;
102
103      RegInfo[Reg] = Info;
104
105      if (RegSpace == PTXRegisterSpace::Argument)
106        RegArgs.insert(Reg);
107      else if (RegSpace == PTXRegisterSpace::Return)
108        RegRets.insert(Reg);
109    }
110  }
111
112  /// countRegisters - Returns the number of registers of the given type and
113  /// space.
114  unsigned countRegisters(unsigned RegType, unsigned RegSpace) const {
115    unsigned Count = 0;
116    for(RegisterInfoMap::const_iterator i = RegInfo.begin(), e = RegInfo.end();
117        i != e; ++i) {
118      const RegisterInfo& RI = i->second;
119      if (RI.Type == RegType && RI.Space == RegSpace)
120        Count++;
121    }
122    return Count;
123  }
124
125  /// getEncodedRegister - Returns the encoded value of the register.
126  unsigned getEncodedRegister(unsigned Reg) const {
127    return RegInfo.lookup(Reg).Encoded;
128  }
129
130  /// addRetReg - Adds a register to the set of return-value registers.
131  void addRetReg(unsigned Reg) {
132    if (!RegRets.count(Reg)) {
133      RegRets.insert(Reg);
134    }
135  }
136
137  /// addArgReg - Adds a register to the set of function argument registers.
138  void addArgReg(unsigned Reg) {
139    RegArgs.insert(Reg);
140  }
141
142  /// getRegisterName - Returns the name of the specified virtual register. This
143  /// name is used during PTX emission.
144  std::string getRegisterName(unsigned Reg) const {
145    if (RegInfo.count(Reg)) {
146      const RegisterInfo& RI = RegInfo.lookup(Reg);
147      std::string Name;
148      raw_string_ostream NameStr(Name);
149      decodeRegisterName(NameStr, RI.Encoded);
150      NameStr.flush();
151      return Name;
152    }
153    else if (Reg == PTX::NoRegister)
154      return "%noreg";
155    else
156      llvm_unreachable("Register not in register name map");
157  }
158
159  /// getEncodedRegisterName - Returns the name of the encoded register.
160  std::string getEncodedRegisterName(unsigned EncodedReg) const {
161    std::string Name;
162    raw_string_ostream NameStr(Name);
163    decodeRegisterName(NameStr, EncodedReg);
164    NameStr.flush();
165    return Name;
166  }
167
168  /// getRegisterType - Returns the type of the specified virtual register.
169  unsigned getRegisterType(unsigned Reg) const {
170    if (RegInfo.count(Reg))
171      return RegInfo.lookup(Reg).Type;
172    else
173      llvm_unreachable("Unknown register");
174  }
175
176  /// getOffsetForRegister - Returns the offset of the virtual register
177  unsigned getOffsetForRegister(unsigned Reg) const {
178    if (RegInfo.count(Reg))
179      return RegInfo.lookup(Reg).Offset;
180    else
181      return 0;
182  }
183
184  /// getFrameSymbol - Returns the symbol name for the given FrameIndex.
185  const char* getFrameSymbol(int FrameIndex) {
186    if (FrameSymbols.count(FrameIndex)) {
187      return FrameSymbols.lookup(FrameIndex).c_str();
188    } else {
189      std::string Name          = "__local";
190      Name                     += utostr(FrameIndex);
191      // The whole point of caching this name is to ensure the pointer we pass
192      // to any getExternalSymbol() calls will remain valid for the lifetime of
193      // the back-end instance. This is to work around an issue in SelectionDAG
194      // where symbol names are expected to be life-long strings.
195      FrameSymbols[FrameIndex]  = Name;
196      return FrameSymbols[FrameIndex].c_str();
197    }
198  }
199}; // class PTXMachineFunctionInfo
200} // namespace llvm
201
202#endif // PTX_MACHINE_FUNCTION_INFO_H
203