PTX: Use .param space for device function return values on SM 2.0+, and attempt
to fix up parameter passing on SM < 2.0
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140309 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/PTX/PTXMachineFunctionInfo.h b/lib/Target/PTX/PTXMachineFunctionInfo.h
index 16e5e7b..93189bb 100644
--- a/lib/Target/PTX/PTXMachineFunctionInfo.h
+++ b/lib/Target/PTX/PTXMachineFunctionInfo.h
@@ -20,16 +20,20 @@
#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 is_kernel;
- std::vector<unsigned> reg_arg, reg_local_var;
- std::vector<unsigned> reg_ret;
+ DenseSet<unsigned> reg_local_var;
+ DenseSet<unsigned> reg_arg;
+ DenseSet<unsigned> reg_ret;
std::vector<unsigned> call_params;
bool _isDoneAddArg;
@@ -40,29 +44,28 @@
RegisterMap usedRegs;
RegisterNameMap regNames;
+ SmallVector<unsigned, 8> argParams;
+
+ unsigned retParamSize;
+
public:
PTXMachineFunctionInfo(MachineFunction &MF)
: is_kernel(false), reg_ret(PTX::NoRegister), _isDoneAddArg(false) {
- reg_arg.reserve(8);
- reg_local_var.reserve(32);
-
usedRegs[PTX::RegPredRegisterClass] = RegisterList();
usedRegs[PTX::RegI16RegisterClass] = RegisterList();
usedRegs[PTX::RegI32RegisterClass] = RegisterList();
usedRegs[PTX::RegI64RegisterClass] = RegisterList();
usedRegs[PTX::RegF32RegisterClass] = RegisterList();
usedRegs[PTX::RegF64RegisterClass] = RegisterList();
+
+ retParamSize = 0;
}
void setKernel(bool _is_kernel=true) { is_kernel = _is_kernel; }
- void addArgReg(unsigned reg) { reg_arg.push_back(reg); }
- void addLocalVarReg(unsigned reg) { reg_local_var.push_back(reg); }
- void addRetReg(unsigned reg) {
- if (!isRetReg(reg)) {
- reg_ret.push_back(reg);
- }
- }
+
+ void addLocalVarReg(unsigned reg) { reg_local_var.insert(reg); }
+
void doneAddArg(void) {
_isDoneAddArg = true;
@@ -71,17 +74,20 @@
bool isKernel() const { return is_kernel; }
- typedef std::vector<unsigned>::const_iterator reg_iterator;
- typedef std::vector<unsigned>::const_reverse_iterator reg_reverse_iterator;
- typedef std::vector<unsigned>::const_iterator ret_iterator;
+ typedef DenseSet<unsigned>::const_iterator reg_iterator;
+ //typedef DenseSet<unsigned>::const_reverse_iterator reg_reverse_iterator;
+ typedef DenseSet<unsigned>::const_iterator ret_iterator;
typedef std::vector<unsigned>::const_iterator param_iterator;
+ typedef SmallVector<unsigned, 8>::const_iterator argparam_iterator;
bool argRegEmpty() const { return reg_arg.empty(); }
int getNumArg() const { return reg_arg.size(); }
reg_iterator argRegBegin() const { return reg_arg.begin(); }
reg_iterator argRegEnd() const { return reg_arg.end(); }
- reg_reverse_iterator argRegReverseBegin() const { return reg_arg.rbegin(); }
- reg_reverse_iterator argRegReverseEnd() const { return reg_arg.rend(); }
+ argparam_iterator argParamBegin() const { return argParams.begin(); }
+ argparam_iterator argParamEnd() const { return argParams.end(); }
+ //reg_reverse_iterator argRegReverseBegin() const { return reg_arg.rbegin(); }
+ //reg_reverse_iterator argRegReverseEnd() const { return reg_arg.rend(); }
bool localVarRegEmpty() const { return reg_local_var.empty(); }
reg_iterator localVarRegBegin() const { return reg_local_var.begin(); }
@@ -103,42 +109,75 @@
return std::find(reg_arg.begin(), reg_arg.end(), reg) != reg_arg.end();
}
- bool isRetReg(unsigned reg) const {
+ /*bool isRetReg(unsigned reg) const {
return std::find(reg_ret.begin(), reg_ret.end(), reg) != reg_ret.end();
- }
+ }*/
bool isLocalVarReg(unsigned reg) const {
return std::find(reg_local_var.begin(), reg_local_var.end(), reg)
!= reg_local_var.end();
}
- void addVirtualRegister(const TargetRegisterClass *TRC, unsigned Reg) {
- usedRegs[TRC].push_back(Reg);
+ void addRetReg(unsigned Reg) {
+ if (!reg_ret.count(Reg)) {
+ reg_ret.insert(Reg);
+ std::string name;
+ name = "%ret";
+ name += utostr(reg_ret.size() - 1);
+ regNames[Reg] = name;
+ }
+ }
+ void setRetParamSize(unsigned SizeInBits) {
+ retParamSize = SizeInBits;
+ }
+
+ unsigned getRetParamSize() const {
+ return retParamSize;
+ }
+
+ void addArgReg(unsigned Reg) {
+ reg_arg.insert(Reg);
+ std::string name;
+ name = "%param";
+ name += utostr(reg_arg.size() - 1);
+ regNames[Reg] = name;
+ }
+
+ void addArgParam(unsigned SizeInBits) {
+ argParams.push_back(SizeInBits);
+ }
+
+ void addVirtualRegister(const TargetRegisterClass *TRC, unsigned Reg) {
std::string name;
- 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");
+ if (!reg_ret.count(Reg) && !reg_arg.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;
+ name += utostr(usedRegs[TRC].size() - 1);
+ regNames[Reg] = name;
+ }
}
std::string getRegisterName(unsigned Reg) const {
if (regNames.count(Reg))
return regNames.lookup(Reg);
+ else if (Reg == PTX::NoRegister)
+ return "%noreg";
else
llvm_unreachable("Register not in register name map");
}