PTX: Generalize handling of .param types
[oota-llvm.git] / lib / Target / PTX / PTXMachineFunctionInfo.h
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
27 namespace llvm {
28
29 /// PTXMachineFunctionInfo - This class is derived from MachineFunction and
30 /// contains private PTX target-specific information for each MachineFunction.
31 ///
32 class PTXMachineFunctionInfo : public MachineFunctionInfo {
33 private:
34   bool is_kernel;
35   DenseSet<unsigned> reg_local_var;
36   DenseSet<unsigned> reg_arg;
37   DenseSet<unsigned> reg_ret;
38   std::vector<unsigned> call_params;
39   bool _isDoneAddArg;
40
41   typedef std::vector<unsigned> RegisterList;
42   typedef DenseMap<const TargetRegisterClass*, RegisterList> RegisterMap;
43   typedef DenseMap<unsigned, std::string> RegisterNameMap;
44
45   RegisterMap usedRegs;
46   RegisterNameMap regNames;
47
48   SmallVector<unsigned, 8> argParams;
49
50   unsigned retParamSize;
51
52   PTXParamManager ParamManager;
53
54 public:
55   PTXMachineFunctionInfo(MachineFunction &MF)
56     : is_kernel(false), reg_ret(PTX::NoRegister), _isDoneAddArg(false) {
57       usedRegs[PTX::RegPredRegisterClass] = RegisterList();
58       usedRegs[PTX::RegI16RegisterClass] = RegisterList();
59       usedRegs[PTX::RegI32RegisterClass] = RegisterList();
60       usedRegs[PTX::RegI64RegisterClass] = RegisterList();
61       usedRegs[PTX::RegF32RegisterClass] = RegisterList();
62       usedRegs[PTX::RegF64RegisterClass] = RegisterList();
63
64       retParamSize = 0;
65     }
66
67   PTXParamManager& getParamManager() { return ParamManager; }
68   const PTXParamManager& getParamManager() const { return ParamManager; }
69
70   void setKernel(bool _is_kernel=true) { is_kernel = _is_kernel; }
71
72
73   void addLocalVarReg(unsigned reg) { reg_local_var.insert(reg); }
74
75
76   void doneAddArg(void) {
77     _isDoneAddArg = true;
78   }
79   void doneAddLocalVar(void) {}
80
81   bool isKernel() const { return is_kernel; }
82
83   typedef DenseSet<unsigned>::const_iterator         reg_iterator;
84   //typedef DenseSet<unsigned>::const_reverse_iterator reg_reverse_iterator;
85   typedef DenseSet<unsigned>::const_iterator         ret_iterator;
86   typedef std::vector<unsigned>::const_iterator         param_iterator;
87   typedef SmallVector<unsigned, 8>::const_iterator    argparam_iterator;
88
89   bool         argRegEmpty() const { return reg_arg.empty(); }
90   int          getNumArg() const { return reg_arg.size(); }
91   reg_iterator argRegBegin() const { return reg_arg.begin(); }
92   reg_iterator argRegEnd()   const { return reg_arg.end(); }
93   argparam_iterator argParamBegin() const { return argParams.begin(); }
94   argparam_iterator argParamEnd() const { return argParams.end(); }
95   //reg_reverse_iterator argRegReverseBegin() const { return reg_arg.rbegin(); }
96   //reg_reverse_iterator argRegReverseEnd() const { return reg_arg.rend(); }
97
98   bool         localVarRegEmpty() const { return reg_local_var.empty(); }
99   reg_iterator localVarRegBegin() const { return reg_local_var.begin(); }
100   reg_iterator localVarRegEnd()   const { return reg_local_var.end(); }
101
102   bool         retRegEmpty() const { return reg_ret.empty(); }
103   int          getNumRet() const { return reg_ret.size(); }
104   ret_iterator retRegBegin() const { return reg_ret.begin(); }
105   ret_iterator retRegEnd()   const { return reg_ret.end(); }
106
107   param_iterator paramBegin() const { return call_params.begin(); }
108   param_iterator paramEnd() const { return call_params.end(); }
109   unsigned       getNextParam(unsigned size) {
110     call_params.push_back(size);
111     return call_params.size()-1;
112   }
113
114   bool isArgReg(unsigned reg) const {
115     return std::find(reg_arg.begin(), reg_arg.end(), reg) != reg_arg.end();
116   }
117
118   /*bool isRetReg(unsigned reg) const {
119     return std::find(reg_ret.begin(), reg_ret.end(), reg) != reg_ret.end();
120   }*/
121
122   bool isLocalVarReg(unsigned reg) const {
123     return std::find(reg_local_var.begin(), reg_local_var.end(), reg)
124       != reg_local_var.end();
125   }
126
127   void addRetReg(unsigned Reg) {
128     if (!reg_ret.count(Reg)) {
129       reg_ret.insert(Reg);
130       std::string name;
131       name = "%ret";
132       name += utostr(reg_ret.size() - 1);
133       regNames[Reg] = name;
134     }
135   }
136
137   void setRetParamSize(unsigned SizeInBits) {
138     retParamSize = SizeInBits;
139   }
140
141   unsigned getRetParamSize() const {
142     return retParamSize;
143   }
144
145   void addArgReg(unsigned Reg) {
146     reg_arg.insert(Reg);
147     std::string name;
148     name = "%param";
149     name += utostr(reg_arg.size() - 1);
150     regNames[Reg] = name;
151   }
152
153   void addArgParam(unsigned SizeInBits) {
154     argParams.push_back(SizeInBits);
155   }
156
157   void addVirtualRegister(const TargetRegisterClass *TRC, unsigned Reg) {
158     std::string name;
159
160     if (!reg_ret.count(Reg) && !reg_arg.count(Reg)) {
161       usedRegs[TRC].push_back(Reg);
162       if (TRC == PTX::RegPredRegisterClass)
163         name = "%p";
164       else if (TRC == PTX::RegI16RegisterClass)
165         name = "%rh";
166       else if (TRC == PTX::RegI32RegisterClass)
167         name = "%r";
168       else if (TRC == PTX::RegI64RegisterClass)
169         name = "%rd";
170       else if (TRC == PTX::RegF32RegisterClass)
171         name = "%f";
172       else if (TRC == PTX::RegF64RegisterClass)
173         name = "%fd";
174       else
175         llvm_unreachable("Invalid register class");
176
177       name += utostr(usedRegs[TRC].size() - 1);
178       regNames[Reg] = name;
179     }
180   }
181
182   std::string getRegisterName(unsigned Reg) const {
183     if (regNames.count(Reg))
184       return regNames.lookup(Reg);
185     else if (Reg == PTX::NoRegister)
186       return "%noreg";
187     else
188       llvm_unreachable("Register not in register name map");
189   }
190
191   unsigned getNumRegistersForClass(const TargetRegisterClass *TRC) const {
192     return usedRegs.lookup(TRC).size();
193   }
194
195 }; // class PTXMachineFunctionInfo
196 } // namespace llvm
197
198 #endif // PTX_MACHINE_FUNCTION_INFO_H