diff options
author | Che-Liang Chiou <clchiou@gmail.com> | 2011-03-02 07:36:48 +0000 |
---|---|---|
committer | Che-Liang Chiou <clchiou@gmail.com> | 2011-03-02 07:36:48 +0000 |
commit | f48817cbf98472c4007e38ff7dad57126531a6e0 (patch) | |
tree | 38fce9a67e8b3d03581fd6aa8cc9b7c64bb46499 /lib/Target/PTX | |
parent | 38c4e535493363b96eac47af9e7c056530137bea (diff) | |
download | external_llvm-f48817cbf98472c4007e38ff7dad57126531a6e0.zip external_llvm-f48817cbf98472c4007e38ff7dad57126531a6e0.tar.gz external_llvm-f48817cbf98472c4007e38ff7dad57126531a6e0.tar.bz2 |
Add 64-bit addressing to PTX backend
- 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
Diffstat (limited to 'lib/Target/PTX')
-rw-r--r-- | lib/Target/PTX/PTX.td | 3 | ||||
-rw-r--r-- | lib/Target/PTX/PTXAsmPrinter.cpp | 11 | ||||
-rw-r--r-- | lib/Target/PTX/PTXISelDAGToDAG.cpp | 8 | ||||
-rw-r--r-- | lib/Target/PTX/PTXInstrInfo.td | 98 | ||||
-rw-r--r-- | lib/Target/PTX/PTXMachineFunctionInfo.h | 11 | ||||
-rw-r--r-- | lib/Target/PTX/PTXSubtarget.cpp | 4 | ||||
-rw-r--r-- | lib/Target/PTX/PTXSubtarget.h | 5 | ||||
-rw-r--r-- | lib/Target/PTX/PTXTargetMachine.cpp | 17 | ||||
-rw-r--r-- | lib/Target/PTX/PTXTargetMachine.h | 8 |
9 files changed, 121 insertions, 44 deletions
diff --git a/lib/Target/PTX/PTX.td b/lib/Target/PTX/PTX.td index 9f62aa1..12febcb 100644 --- a/lib/Target/PTX/PTX.td +++ b/lib/Target/PTX/PTX.td @@ -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", diff --git a/lib/Target/PTX/PTXAsmPrinter.cpp b/lib/Target/PTX/PTXAsmPrinter.cpp index 35eeadc..2249d86 100644 --- a/lib/Target/PTX/PTXAsmPrinter.cpp +++ b/lib/Target/PTX/PTXAsmPrinter.cpp @@ -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) diff --git a/lib/Target/PTX/PTXISelDAGToDAG.cpp b/lib/Target/PTX/PTXISelDAGToDAG.cpp index 1e6a53f..fe2d25a 100644 --- a/lib/Target/PTX/PTXISelDAGToDAG.cpp +++ b/lib/Target/PTX/PTXISelDAGToDAG.cpp @@ -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>(); +} + diff --git a/lib/Target/PTX/PTXInstrInfo.td b/lib/Target/PTX/PTXInstrInfo.td index fce6da6..7325b70 100644 --- a/lib/Target/PTX/PTXInstrInfo.td +++ b/lib/Target/PTX/PTXInstrInfo.td @@ -18,6 +18,13 @@ 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> { diff --git a/lib/Target/PTX/PTXMachineFunctionInfo.h b/lib/Target/PTX/PTXMachineFunctionInfo.h index 56d044b..b5b3c3b 100644 --- a/lib/Target/PTX/PTXMachineFunctionInfo.h +++ b/lib/Target/PTX/PTXMachineFunctionInfo.h @@ -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(); } diff --git a/lib/Target/PTX/PTXSubtarget.cpp b/lib/Target/PTX/PTXSubtarget.cpp index 18a9305..ef4060d 100644 --- a/lib/Target/PTX/PTXSubtarget.cpp +++ b/lib/Target/PTX/PTXSubtarget.cpp @@ -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); } diff --git a/lib/Target/PTX/PTXSubtarget.h b/lib/Target/PTX/PTXSubtarget.h index 9a9ada2..23aa3a3 100644 --- a/lib/Target/PTX/PTXSubtarget.h +++ b/lib/Target/PTX/PTXSubtarget.h @@ -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 diff --git a/lib/Target/PTX/PTXTargetMachine.cpp b/lib/Target/PTX/PTXTargetMachine.cpp index b263813..371510f 100644 --- a/lib/Target/PTX/PTXTargetMachine.cpp +++ b/lib/Target/PTX/PTXTargetMachine.cpp @@ -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, diff --git a/lib/Target/PTX/PTXTargetMachine.h b/lib/Target/PTX/PTXTargetMachine.h index 728e36f..2add713 100644 --- a/lib/Target/PTX/PTXTargetMachine.h +++ b/lib/Target/PTX/PTXTargetMachine.h @@ -25,11 +25,11 @@ 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, |