Add 64-bit addressing to PTX backend
authorChe-Liang Chiou <clchiou@gmail.com>
Wed, 2 Mar 2011 07:36:48 +0000 (07:36 +0000)
committerChe-Liang Chiou <clchiou@gmail.com>
Wed, 2 Mar 2011 07:36:48 +0000 (07:36 +0000)
- Add '64bit' sub-target option.
- Select 32-bit/64-bit loads/stores based on '64bit' option.
- Fix function parameter order.

Patch by Justin Holewinski

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126837 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PTX/PTX.td
lib/Target/PTX/PTXAsmPrinter.cpp
lib/Target/PTX/PTXISelDAGToDAG.cpp
lib/Target/PTX/PTXInstrInfo.td
lib/Target/PTX/PTXMachineFunctionInfo.h
lib/Target/PTX/PTXSubtarget.cpp
lib/Target/PTX/PTXSubtarget.h
lib/Target/PTX/PTXTargetMachine.cpp
lib/Target/PTX/PTXTargetMachine.h

index 9f62aa16f828f2926640ee7f1482af1e918d4b29..12febcb13decf79793082bd97148128129aa6831 100644 (file)
@@ -24,6 +24,9 @@ include "llvm/Target/Target.td"
 def FeatureDouble : SubtargetFeature<"double", "SupportsDouble", "true",
                                      "Do not demote .f64 to .f32">;
 
+def Feature64Bit : SubtargetFeature<"64bit", "Use64BitAddresses", "true",
+                                    "Use 64-bit integer types for addresses.">;
+
 //===- PTX Version --------------------------------------------------------===//
 
 def FeaturePTX14 : SubtargetFeature<"ptx14", "PTXVersion", "PTX_VERSION_1_4",
index 35eeadce2d2347a83c26b71964f0005f20d7c89f..2249d86830502e246a37d21fd0fbcd99a631499f 100644 (file)
@@ -360,20 +360,21 @@ void PTXAsmPrinter::EmitFunctionDeclaration() {
     if (isKernel) {
       unsigned cnt = 0;
       //for (int i = 0, e = MFI->getNumArg(); i != e; ++i) {
-      for(PTXMachineFunctionInfo::reg_iterator
-          i = MFI->argRegBegin(), e = MFI->argRegEnd(), b = i; i != e; ++i) {
+      for(PTXMachineFunctionInfo::reg_reverse_iterator
+          i = MFI->argRegReverseBegin(), e = MFI->argRegReverseEnd(), b = i; i != e; ++i) {
         reg = *i;
         assert(reg != PTX::NoRegister && "Not a valid register!");
         if (i != b)
           decl += ", ";
-        decl += ".param .u32";  // TODO: Parse type from register map
+        decl += ".param .";
+        decl += getRegisterTypeName(reg);
         decl += " ";
         decl += PARAM_PREFIX;
         decl += utostr(++cnt);
       }
     } else {
-      for (PTXMachineFunctionInfo::reg_iterator
-           i = MFI->argRegBegin(), e = MFI->argRegEnd(), b = i; i != e; ++i) {
+      for (PTXMachineFunctionInfo::reg_reverse_iterator
+           i = MFI->argRegReverseBegin(), e = MFI->argRegReverseEnd(), b = i; i != e; ++i) {
         reg = *i;
         assert(reg != PTX::NoRegister && "Not a valid register!");
         if (i != b)
index 1e6a53fee91cc407c6bb91315336637dd905f4f1..fe2d25a3b43c43e6618fbf499dd6ff97a435c3d3 100644 (file)
@@ -45,6 +45,8 @@ class PTXDAGToDAGISel : public SelectionDAGISel {
 
     bool isImm(const SDValue &operand);
     bool SelectImm(const SDValue &operand, SDValue &imm);
+
+    const PTXSubtarget& getSubtarget() const;
 }; // class PTXDAGToDAGISel
 } // namespace
 
@@ -170,3 +172,9 @@ bool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) {
   imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(), MVT::i32);
   return true;
 }
+
+const PTXSubtarget& PTXDAGToDAGISel::getSubtarget() const
+{
+  return TM.getSubtarget<PTXSubtarget>();
+}
+
index fce6da66efffd10409938fbede62b1d0fc839f4d..7325b705186e3d159446ada3b03c9348d64d38ba 100644 (file)
 
 include "PTXInstrFormats.td"
 
+//===----------------------------------------------------------------------===//
+// Code Generation Predicates
+//===----------------------------------------------------------------------===//
+
+def Use32BitAddresses : Predicate<"!getSubtarget().use64BitAddresses()">;
+def Use64BitAddresses : Predicate<"getSubtarget().use64BitAddresses()">;
+
 //===----------------------------------------------------------------------===//
 // Instruction Pattern Stuff
 //===----------------------------------------------------------------------===//
@@ -107,24 +114,39 @@ def store_shared
 }]>;
 
 // Addressing modes.
-def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
-def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [], []>;
-def ADDRii : ComplexPattern<i32, 2, "SelectADDRii", [], []>;
+def ADDRrr32 : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
+def ADDRrr64 : ComplexPattern<i64, 2, "SelectADDRrr", [], []>;
+def ADDRri32 : ComplexPattern<i32, 2, "SelectADDRri", [], []>;
+def ADDRri64 : ComplexPattern<i64, 2, "SelectADDRri", [], []>;
+def ADDRii32 : ComplexPattern<i32, 2, "SelectADDRii", [], []>;
+def ADDRii64 : ComplexPattern<i64, 2, "SelectADDRii", [], []>;
+
 
 // Address operands
-def MEMri : Operand<i32> {
+def MEMri32 : Operand<i32> {
   let PrintMethod = "printMemOperand";
   let MIOperandInfo = (ops RRegu32, i32imm);
 }
-def MEMii : Operand<i32> {
+def MEMri64 : Operand<i64> {
+  let PrintMethod = "printMemOperand";
+  let MIOperandInfo = (ops RRegu64, i64imm);
+}
+def MEMii32 : Operand<i32> {
   let PrintMethod = "printMemOperand";
   let MIOperandInfo = (ops i32imm, i32imm);
 }
+def MEMii64 : Operand<i64> {
+  let PrintMethod = "printMemOperand";
+  let MIOperandInfo = (ops i64imm, i64imm);
+}
+// The operand here does not correspond to an actual address, so we
+// can use i32 in 64-bit address modes.
 def MEMpi : Operand<i32> {
   let PrintMethod = "printParamOperand";
   let MIOperandInfo = (ops i32imm);
 }
 
+
 //===----------------------------------------------------------------------===//
 // PTX Specific Node Definitions
 //===----------------------------------------------------------------------===//
@@ -207,18 +229,30 @@ multiclass INT3ntnc<string opcstr, SDNode opnode> {
 }
 
 multiclass PTX_LD<string opstr, string typestr, RegisterClass RC, PatFrag pat_load> {
-  def rr : InstPTX<(outs RC:$d),
-                   (ins MEMri:$a),
-                   !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
-                   [(set RC:$d, (pat_load ADDRrr:$a))]>;
-  def ri : InstPTX<(outs RC:$d),
-                   (ins MEMri:$a),
-                   !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
-                   [(set RC:$d, (pat_load ADDRri:$a))]>;
-  def ii : InstPTX<(outs RC:$d),
-                   (ins MEMii:$a),
-                   !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
-                   [(set RC:$d, (pat_load ADDRii:$a))]>;
+  def rr32 : InstPTX<(outs RC:$d),
+                     (ins MEMri32:$a),
+                     !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
+                     [(set RC:$d, (pat_load ADDRrr32:$a))]>, Requires<[Use32BitAddresses]>;
+  def rr64 : InstPTX<(outs RC:$d),
+                     (ins MEMri64:$a),
+                     !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
+                     [(set RC:$d, (pat_load ADDRrr64:$a))]>, Requires<[Use64BitAddresses]>;
+  def ri32 : InstPTX<(outs RC:$d),
+                     (ins MEMri32:$a),
+                     !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
+                     [(set RC:$d, (pat_load ADDRri32:$a))]>, Requires<[Use32BitAddresses]>;
+  def ri64 : InstPTX<(outs RC:$d),
+                     (ins MEMri64:$a),
+                     !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
+                     [(set RC:$d, (pat_load ADDRri64:$a))]>, Requires<[Use64BitAddresses]>;
+  def ii32 : InstPTX<(outs RC:$d),
+                     (ins MEMii32:$a),
+                     !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
+                     [(set RC:$d, (pat_load ADDRii32:$a))]>, Requires<[Use32BitAddresses]>;
+  def ii64 : InstPTX<(outs RC:$d),
+                     (ins MEMii64:$a),
+                     !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
+                     [(set RC:$d, (pat_load ADDRii64:$a))]>, Requires<[Use64BitAddresses]>;
 }
 
 multiclass PTX_LD_ALL<string opstr, PatFrag pat_load> {
@@ -230,18 +264,30 @@ multiclass PTX_LD_ALL<string opstr, PatFrag pat_load> {
 }
 
 multiclass PTX_ST<string opstr, string typestr, RegisterClass RC, PatFrag pat_store> {
-  def rr : InstPTX<(outs),
-                   (ins RC:$d, MEMri:$a),
+  def rr32 : InstPTX<(outs),
+                     (ins RC:$d, MEMri32:$a),
+                     !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
+                     [(pat_store RC:$d, ADDRrr32:$a)]>, Requires<[Use32BitAddresses]>;
+  def rr64 : InstPTX<(outs),
+                     (ins RC:$d, MEMri64:$a),
+                     !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
+                     [(pat_store RC:$d, ADDRrr64:$a)]>, Requires<[Use64BitAddresses]>;
+  def ri32 : InstPTX<(outs),
+                   (ins RC:$d, MEMri32:$a),
+                   !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
+                   [(pat_store RC:$d, ADDRri32:$a)]>, Requires<[Use32BitAddresses]>;
+  def ri64 : InstPTX<(outs),
+                   (ins RC:$d, MEMri64:$a),
                    !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
-                   [(pat_store RC:$d, ADDRrr:$a)]>;
-  def ri : InstPTX<(outs),
-                   (ins RC:$d, MEMri:$a),
+                   [(pat_store RC:$d, ADDRri64:$a)]>, Requires<[Use64BitAddresses]>;
+  def ii32 : InstPTX<(outs),
+                   (ins RC:$d, MEMii32:$a),
                    !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
-                   [(pat_store RC:$d, ADDRri:$a)]>;
-  def ii : InstPTX<(outs),
-                   (ins RC:$d, MEMii:$a),
+                   [(pat_store RC:$d, ADDRii32:$a)]>, Requires<[Use32BitAddresses]>;
+  def ii64 : InstPTX<(outs),
+                   (ins RC:$d, MEMii64:$a),
                    !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
-                   [(pat_store RC:$d, ADDRii:$a)]>;
+                   [(pat_store RC:$d, ADDRii64:$a)]>, Requires<[Use64BitAddresses]>;
 }
 
 multiclass PTX_ST_ALL<string opstr, PatFrag pat_store> {
index 56d044b5fc0d2600e47d387544df2eec0acc454d..b5b3c3be17b8a8eebf9126c82db49072959c8172 100644 (file)
@@ -53,14 +53,17 @@ public:
 
   bool isKernel() const { return is_kernel; }
 
-  typedef std::vector<unsigned>::const_iterator reg_iterator;
+  typedef std::vector<unsigned>::const_iterator         reg_iterator;
+  typedef std::vector<unsigned>::const_reverse_iterator reg_reverse_iterator;
 
-  bool argRegEmpty() const { return reg_arg.empty(); }
-  int getNumArg() const { return reg_arg.size(); }
+  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(); }
 
-  bool localVarRegEmpty() const { return reg_local_var.empty(); }
+  bool         localVarRegEmpty() const { return reg_local_var.empty(); }
   reg_iterator localVarRegBegin() const { return reg_local_var.begin(); }
   reg_iterator localVarRegEnd()   const { return reg_local_var.end(); }
 
index 18a93052c99310c0d603f18df58ced4f1e768615..ef4060d6f015b75bec6da0277b45cfa4b61ce465 100644 (file)
@@ -18,7 +18,9 @@ using namespace llvm;
 
 PTXSubtarget::PTXSubtarget(const std::string &TT, const std::string &FS)
   : PTXShaderModel(PTX_SM_1_0),
-    PTXVersion(PTX_VERSION_1_4) {
+    PTXVersion(PTX_VERSION_1_4),
+    SupportsDouble(false),
+    Use64BitAddresses(false) {
   std::string TARGET = "generic";
   ParseSubtargetFeatures(FS, TARGET);
 }
index 9a9ada2af6d40356e141d9651f84a36b6d89ca22..23aa3a349f98f43407b895541e7d7e735bdf396f 100644 (file)
@@ -40,6 +40,9 @@ namespace llvm {
       // The native .f64 type is supported on the hardware.
       bool SupportsDouble;
 
+      // Use .u64 instead of .u32 for addresses.
+      bool Use64BitAddresses;
+
     public:
       PTXSubtarget(const std::string &TT, const std::string &FS);
 
@@ -49,6 +52,8 @@ namespace llvm {
 
       bool supportsDouble() const { return SupportsDouble; }
 
+      bool use64BitAddresses() const { return Use64BitAddresses; }
+
       std::string ParseSubtargetFeatures(const std::string &FS,
                                          const std::string &CPU);
   }; // class PTXSubtarget
index b263813cb4e78eb6de84ce1e4f0f793d9367240f..371510fe3250fb86a551e49774929ba1760d6b9c 100644 (file)
@@ -16,6 +16,7 @@
 #include "PTXTargetMachine.h"
 #include "llvm/PassManager.h"
 #include "llvm/Target/TargetRegistry.h"
+#include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 
@@ -34,16 +35,24 @@ extern "C" void LLVMInitializePTXTarget() {
   TargetRegistry::RegisterAsmStreamer(ThePTXTarget, createPTXAsmStreamer);
 }
 
+namespace {
+  const char* DataLayout32 = "e-p:32:32-i64:32:32-f64:32:32-v128:32:128-v64:32:64-n32:64";
+  const char* DataLayout64 = "e-p:64:64-i64:32:32-f64:32:32-v128:32:128-v64:32:64-n32:64";
+}
+
 // DataLayout and FrameLowering are filled with dummy data
 PTXTargetMachine::PTXTargetMachine(const Target &T,
                                    const std::string &TT,
                                    const std::string &FS)
-  : LLVMTargetMachine(T, TT),
-    DataLayout("e-p:32:32-i64:32:32-f64:32:32-v128:32:128-v64:32:64-n32:64"),
+  : Subtarget(TT, FS),
+    // FIXME: This feels like a dirty hack, but Subtarget does not appear to be
+    //        initialized at this point, and we need to finish initialization of
+    //        DataLayout.
+    DataLayout((FS.find("64bit") != FS.npos) ? DataLayout64 : DataLayout32),
+    LLVMTargetMachine(T, TT),
     FrameLowering(Subtarget),
-    InstrInfo(*this),
     TLInfo(*this),
-    Subtarget(TT, FS) {
+    InstrInfo(*this) {
 }
 
 bool PTXTargetMachine::addInstSelector(PassManagerBase &PM,
index 728e36f56f019bbd67f4a97666295f1bd00fc22a..2add7134baef8f24694b5a03109d5209e47fb7b6 100644 (file)
 namespace llvm {
 class PTXTargetMachine : public LLVMTargetMachine {
   private:
-    const TargetData DataLayout;
-    PTXFrameLowering FrameLowering;
-    PTXInstrInfo InstrInfo;
+    const TargetData  DataLayout;
+    PTXFrameLowering  FrameLowering;
+    PTXInstrInfo      InstrInfo;
     PTXTargetLowering TLInfo;
-    PTXSubtarget Subtarget;
+    PTXSubtarget      Subtarget;
 
   public:
     PTXTargetMachine(const Target &T, const std::string &TT,