aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Target/PTX/PTXMachineFunctionInfo.h
blob: 3b985f7dd6b004646c91cc7badfe7d373932fd1e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//===- PTXMachineFuctionInfo.h - PTX machine function info -------*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares PTX-specific per-machine-function information.
//
//===----------------------------------------------------------------------===//

#ifndef PTX_MACHINE_FUNCTION_INFO_H
#define PTX_MACHINE_FUNCTION_INFO_H

#include "PTX.h"
#include "PTXParamManager.h"
#include "PTXRegisterInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

namespace llvm {

/// PTXMachineFunctionInfo - This class is derived from MachineFunction and
/// contains private PTX target-specific information for each MachineFunction.
///
class PTXMachineFunctionInfo : public MachineFunctionInfo {
private:
  bool IsKernel;
  DenseSet<unsigned> RegArgs;
  DenseSet<unsigned> RegRets;

  typedef std::vector<unsigned> RegisterList;
  typedef DenseMap<const TargetRegisterClass*, RegisterList> RegisterMap;
  typedef DenseMap<unsigned, std::string> RegisterNameMap;
  typedef DenseMap<int, std::string> FrameMap;

  RegisterMap UsedRegs;
  RegisterNameMap RegNames;
  FrameMap FrameSymbols;

  PTXParamManager ParamManager;

public:
  typedef DenseSet<unsigned>::const_iterator reg_iterator;

  PTXMachineFunctionInfo(MachineFunction &MF)
    : IsKernel(false) {
      UsedRegs[PTX::RegPredRegisterClass] = RegisterList();
      UsedRegs[PTX::RegI16RegisterClass] = RegisterList();
      UsedRegs[PTX::RegI32RegisterClass] = RegisterList();
      UsedRegs[PTX::RegI64RegisterClass] = RegisterList();
      UsedRegs[PTX::RegF32RegisterClass] = RegisterList();
      UsedRegs[PTX::RegF64RegisterClass] = RegisterList();
    }

  /// getParamManager - Returns the PTXParamManager instance for this function.
  PTXParamManager& getParamManager() { return ParamManager; }
  const PTXParamManager& getParamManager() const { return ParamManager; }

  /// setKernel/isKernel - Gets/sets a flag that indicates if this function is
  /// a PTX kernel function.
  void setKernel(bool _IsKernel=true) { IsKernel = _IsKernel; }
  bool isKernel() const { return IsKernel; }

  /// argreg_begin/argreg_end - Returns iterators to the set of registers
  /// containing function arguments.
  reg_iterator argreg_begin() const { return RegArgs.begin(); }
  reg_iterator argreg_end()   const { return RegArgs.end(); }

  /// retreg_begin/retreg_end - Returns iterators to the set of registers
  /// containing the function return values.
  reg_iterator retreg_begin() const { return RegRets.begin(); }
  reg_iterator retreg_end()   const { return RegRets.end(); }

  /// addRetReg - Adds a register to the set of return-value registers.
  void addRetReg(unsigned Reg) {
    if (!RegRets.count(Reg)) {
      RegRets.insert(Reg);
      std::string name;
      name = "%ret";
      name += utostr(RegRets.size() - 1);
      RegNames[Reg] = name;
    }
  }

  /// addArgReg - Adds a register to the set of function argument registers.
  void addArgReg(unsigned Reg) {
    RegArgs.insert(Reg);
    std::string name;
    name = "%param";
    name += utostr(RegArgs.size() - 1);
    RegNames[Reg] = name;
  }

  /// addVirtualRegister - Adds a virtual register to the set of all used
  /// registers in the function.
  void addVirtualRegister(const TargetRegisterClass *TRC, unsigned Reg) {
    std::string name;

    // Do not count registers that are argument/return registers.
    if (!RegRets.count(Reg) && !RegArgs.count(Reg)) {
      UsedRegs[TRC].push_back(Reg);
      if (TRC == PTX::RegPredRegisterClass)
        name = "%p";
      else if (TRC == PTX::RegI16RegisterClass)
        name = "%rh";
      else if (TRC == PTX::RegI32RegisterClass)
        name = "%r";
      else if (TRC == PTX::RegI64RegisterClass)
        name = "%rd";
      else if (TRC == PTX::RegF32RegisterClass)
        name = "%f";
      else if (TRC == PTX::RegF64RegisterClass)
        name = "%fd";
      else
        llvm_unreachable("Invalid register class");

      name += utostr(UsedRegs[TRC].size() - 1);
      RegNames[Reg] = name;
    }
  }

  /// getRegisterName - Returns the name of the specified virtual register. This
  /// name is used during PTX emission.
  const char *getRegisterName(unsigned Reg) const {
    if (RegNames.count(Reg))
      return RegNames.find(Reg)->second.c_str();
    else if (Reg == PTX::NoRegister)
      return "%noreg";
    else
      llvm_unreachable("Register not in register name map");
  }

  /// getNumRegistersForClass - Returns the number of virtual registers that are
  /// used for the specified register class.
  unsigned getNumRegistersForClass(const TargetRegisterClass *TRC) const {
    return UsedRegs.lookup(TRC).size();
  }

  /// getFrameSymbol - Returns the symbol name for the given FrameIndex.
  const char* getFrameSymbol(int FrameIndex) {
    if (FrameSymbols.count(FrameIndex)) {
      return FrameSymbols.lookup(FrameIndex).c_str();
    } else {
      std::string Name = "__local";
      Name += utostr(FrameIndex);
      // The whole point of caching this name is to ensure the pointer we pass
      // to any getExternalSymbol() calls will remain valid for the lifetime of
      // the back-end instance. This is to work around an issue in SelectionDAG
      // where symbol names are expected to be life-long strings.
      FrameSymbols[FrameIndex] = Name;
      return FrameSymbols[FrameIndex].c_str();
    }
  }
}; // class PTXMachineFunctionInfo
} // namespace llvm

#endif // PTX_MACHINE_FUNCTION_INFO_H