Home | History | Annotate | Download | only in PTX
      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 
     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