• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   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 
56 public:
57   typedef DenseSet<unsigned>::const_iterator reg_iterator;
58 
PTXMachineFunctionInfo(MachineFunction & MF)59   PTXMachineFunctionInfo(MachineFunction &MF)
60     : IsKernel(false) {
61   }
62 
63   /// getParamManager - Returns the PTXParamManager instance for this function.
getParamManager()64   PTXParamManager& getParamManager() { return ParamManager; }
getParamManager()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; }
isKernel()70   bool isKernel() const { return IsKernel; }
71 
72   /// argreg_begin/argreg_end - Returns iterators to the set of registers
73   /// containing function arguments.
argreg_begin()74   reg_iterator argreg_begin() const { return RegArgs.begin(); }
argreg_end()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.
retreg_begin()79   reg_iterator retreg_begin() const { return RegRets.begin(); }
retreg_end()80   reg_iterator retreg_end()   const { return RegRets.end(); }
81 
82   /// addRegister - Adds a virtual register to the set of all used registers
addRegister(unsigned Reg,unsigned RegType,unsigned RegSpace)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.
countRegisters(unsigned RegType,unsigned RegSpace)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.
getEncodedRegister(unsigned Reg)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.
addRetReg(unsigned Reg)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.
addArgReg(unsigned Reg)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.
getRegisterName(unsigned Reg)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.
getEncodedRegisterName(unsigned EncodedReg)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.
getRegisterType(unsigned Reg)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
getOffsetForRegister(unsigned Reg)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.
getFrameSymbol(int 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