blob: 1a2878cbec33a5f5d30b94db21e23b5c2138ce56 [file] [log] [blame]
Che-Liang Chiou3278c422010-11-08 03:00:52 +00001//===- 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"
Justin Holewinski27f08fc2011-09-23 14:18:22 +000018#include "PTXParamManager.h"
Justin Holewinski297984d2011-09-22 16:45:40 +000019#include "PTXRegisterInfo.h"
20#include "llvm/ADT/DenseMap.h"
Justin Holewinskie0aef2d2011-06-16 17:50:00 +000021#include "llvm/ADT/DenseSet.h"
Justin Holewinski297984d2011-09-22 16:45:40 +000022#include "llvm/ADT/StringExtras.h"
Che-Liang Chiou3278c422010-11-08 03:00:52 +000023#include "llvm/CodeGen/MachineFunction.h"
Justin Holewinski5422a0f2011-09-22 16:45:46 +000024#include "llvm/Support/Debug.h"
25#include "llvm/Support/raw_ostream.h"
Che-Liang Chiou3278c422010-11-08 03:00:52 +000026
27namespace llvm {
Justin Holewinski5422a0f2011-09-22 16:45:46 +000028
Che-Liang Chiou3278c422010-11-08 03:00:52 +000029/// PTXMachineFunctionInfo - This class is derived from MachineFunction and
30/// contains private PTX target-specific information for each MachineFunction.
31///
32class PTXMachineFunctionInfo : public MachineFunctionInfo {
33private:
Justin Holewinskidc0baf92011-09-23 17:15:53 +000034 bool IsKernel;
35 DenseSet<unsigned> RegArgs;
36 DenseSet<unsigned> RegRets;
Che-Liang Chiou3278c422010-11-08 03:00:52 +000037
Justin Holewinskif47dfba2011-09-27 18:12:55 +000038 typedef DenseMap<int, std::string> FrameMap;
Justin Holewinski297984d2011-09-22 16:45:40 +000039
Justin Holewinskif47dfba2011-09-27 18:12:55 +000040 FrameMap FrameSymbols;
Justin Holewinski5422a0f2011-09-22 16:45:46 +000041
Justin Holewinski4c7ffb62011-12-06 17:39:48 +000042 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
Justin Holewinski27f08fc2011-09-23 14:18:22 +000054 PTXParamManager ParamManager;
55
Che-Liang Chiou3278c422010-11-08 03:00:52 +000056public:
Justin Holewinskidc0baf92011-09-23 17:15:53 +000057 typedef DenseSet<unsigned>::const_iterator reg_iterator;
Justin Holewinski5422a0f2011-09-22 16:45:46 +000058
Justin Holewinskidc0baf92011-09-23 17:15:53 +000059 PTXMachineFunctionInfo(MachineFunction &MF)
60 : IsKernel(false) {
Justin Holewinski4c7ffb62011-12-06 17:39:48 +000061 }
Che-Liang Chiou3278c422010-11-08 03:00:52 +000062
Justin Holewinskidc0baf92011-09-23 17:15:53 +000063 /// getParamManager - Returns the PTXParamManager instance for this function.
Justin Holewinski27f08fc2011-09-23 14:18:22 +000064 PTXParamManager& getParamManager() { return ParamManager; }
65 const PTXParamManager& getParamManager() const { return ParamManager; }
66
Justin Holewinskidc0baf92011-09-23 17:15:53 +000067 /// 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; }
Che-Liang Chiou3278c422010-11-08 03:00:52 +000071
Justin Holewinskidc0baf92011-09-23 17:15:53 +000072 /// 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(); }
Justin Holewinski5422a0f2011-09-22 16:45:46 +000076
Justin Holewinskidc0baf92011-09-23 17:15:53 +000077 /// 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(); }
Justin Holewinski5422a0f2011-09-22 16:45:46 +000081
Justin Holewinski4c7ffb62011-12-06 17:39:48 +000082 /// 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
Justin Holewinskidc0baf92011-09-23 17:15:53 +0000130 /// addRetReg - Adds a register to the set of return-value registers.
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000131 void addRetReg(unsigned Reg) {
Justin Holewinskidc0baf92011-09-23 17:15:53 +0000132 if (!RegRets.count(Reg)) {
133 RegRets.insert(Reg);
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000134 }
135 }
Justin Holewinski297984d2011-09-22 16:45:40 +0000136
Justin Holewinskidc0baf92011-09-23 17:15:53 +0000137 /// addArgReg - Adds a register to the set of function argument registers.
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000138 void addArgReg(unsigned Reg) {
Justin Holewinskidc0baf92011-09-23 17:15:53 +0000139 RegArgs.insert(Reg);
Justin Holewinski297984d2011-09-22 16:45:40 +0000140 }
141
Justin Holewinskidc0baf92011-09-23 17:15:53 +0000142 /// getRegisterName - Returns the name of the specified virtual register. This
143 /// name is used during PTX emission.
Justin Holewinski4c7ffb62011-12-06 17:39:48 +0000144 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 }
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000153 else if (Reg == PTX::NoRegister)
154 return "%noreg";
Justin Holewinski297984d2011-09-22 16:45:40 +0000155 else
156 llvm_unreachable("Register not in register name map");
157 }
158
Justin Holewinski4c7ffb62011-12-06 17:39:48 +0000159 /// 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");
Justin Holewinski297984d2011-09-22 16:45:40 +0000174 }
175
Justin Holewinskie37a83f2011-12-06 17:39:46 +0000176 /// getOffsetForRegister - Returns the offset of the virtual register
Justin Holewinski4c7ffb62011-12-06 17:39:48 +0000177 unsigned getOffsetForRegister(unsigned Reg) const {
178 if (RegInfo.count(Reg))
179 return RegInfo.lookup(Reg).Offset;
180 else
181 return 0;
Justin Holewinskie37a83f2011-12-06 17:39:46 +0000182 }
183
Justin Holewinskif47dfba2011-09-27 18:12:55 +0000184 /// 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 {
Justin Holewinskie37a83f2011-12-06 17:39:46 +0000189 std::string Name = "__local";
190 Name += utostr(FrameIndex);
Justin Holewinskif47dfba2011-09-27 18:12:55 +0000191 // 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.
Justin Holewinskie37a83f2011-12-06 17:39:46 +0000195 FrameSymbols[FrameIndex] = Name;
Justin Holewinskif47dfba2011-09-27 18:12:55 +0000196 return FrameSymbols[FrameIndex].c_str();
197 }
198 }
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000199}; // class PTXMachineFunctionInfo
200} // namespace llvm
201
202#endif // PTX_MACHINE_FUNCTION_INFO_H