Add ret instruction to PTX backend
authorChe-Liang Chiou <clchiou@gmail.com>
Sat, 25 Sep 2010 07:46:17 +0000 (07:46 +0000)
committerChe-Liang Chiou <clchiou@gmail.com>
Sat, 25 Sep 2010 07:46:17 +0000 (07:46 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114788 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CallingConv.h
lib/AsmParser/LLLexer.cpp
lib/AsmParser/LLParser.cpp
lib/AsmParser/LLToken.h
lib/Target/PTX/PTXISelLowering.cpp
lib/Target/PTX/PTXISelLowering.h
lib/Target/PTX/PTXInstrInfo.td
lib/VMCore/AsmWriter.cpp
lib/VMCore/Verifier.cpp
test/CodeGen/PTX/exit.ll
utils/vim/llvm.vim

index b3ad8428d287a8aa17591efe0ebaf363a313adab..2679cb71396c1bb8aabfaee7265dbc1b3e9bbd63 100644 (file)
@@ -79,7 +79,15 @@ namespace CallingConv {
     /// X86_ThisCall - Similar to X86_StdCall. Passes first argument in ECX,
     /// others via stack. Callee is responsible for stack cleaning. MSVC uses
     /// this by default for methods in its ABI.
     /// X86_ThisCall - Similar to X86_StdCall. Passes first argument in ECX,
     /// others via stack. Callee is responsible for stack cleaning. MSVC uses
     /// this by default for methods in its ABI.
-    X86_ThisCall = 70
+    X86_ThisCall = 70,
+
+    /// PTX_Kernel - Call to a PTX kernel.
+    /// Passes all arguments in parameter space.
+    PTX_Kernel = 71,
+
+    /// PTX_Device - Call to a PTX device function.
+    /// Passes all arguments in register or parameter space.
+    PTX_Device = 72
   };
 } // End CallingConv namespace
 
   };
 } // End CallingConv namespace
 
index 34595e7a4eefdfc905b4070ef545d7ca2908499e..23ffd9d26b1a90d32e7ccbf6eb886c50622b188c 100644 (file)
@@ -544,6 +544,8 @@ lltok::Kind LLLexer::LexIdentifier() {
   KEYWORD(arm_aapcscc);
   KEYWORD(arm_aapcs_vfpcc);
   KEYWORD(msp430_intrcc);
   KEYWORD(arm_aapcscc);
   KEYWORD(arm_aapcs_vfpcc);
   KEYWORD(msp430_intrcc);
+  KEYWORD(ptx_kernel);
+  KEYWORD(ptx_device);
 
   KEYWORD(cc);
   KEYWORD(c);
 
   KEYWORD(cc);
   KEYWORD(c);
index f21a065473b6297d818eb1a3720f0e6bf31bbd0e..3a9c47c8f51f97a2847c32859b33a11cabeb653f 100644 (file)
@@ -1084,6 +1084,8 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) {
 ///   ::= 'arm_aapcscc'
 ///   ::= 'arm_aapcs_vfpcc'
 ///   ::= 'msp430_intrcc'
 ///   ::= 'arm_aapcscc'
 ///   ::= 'arm_aapcs_vfpcc'
 ///   ::= 'msp430_intrcc'
+///   ::= 'ptx_kernel'
+///   ::= 'ptx_device'
 ///   ::= 'cc' UINT
 ///
 bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
 ///   ::= 'cc' UINT
 ///
 bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
@@ -1099,6 +1101,8 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
   case lltok::kw_arm_aapcscc:    CC = CallingConv::ARM_AAPCS; break;
   case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break;
   case lltok::kw_msp430_intrcc:  CC = CallingConv::MSP430_INTR; break;
   case lltok::kw_arm_aapcscc:    CC = CallingConv::ARM_AAPCS; break;
   case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break;
   case lltok::kw_msp430_intrcc:  CC = CallingConv::MSP430_INTR; break;
+  case lltok::kw_ptx_kernel:     CC = CallingConv::PTX_Kernel; break;
+  case lltok::kw_ptx_device:     CC = CallingConv::PTX_Device; break;
   case lltok::kw_cc: {
       unsigned ArbitraryCC;
       Lex.Lex();
   case lltok::kw_cc: {
       unsigned ArbitraryCC;
       Lex.Lex();
index 61f93a4274981fa34fa60a08acc910b73509fe88..8a8663e739ab609ceee8577c34b9e9f14bdfe481 100644 (file)
@@ -72,6 +72,7 @@ namespace lltok {
     kw_x86_stdcallcc, kw_x86_fastcallcc, kw_x86_thiscallcc,
     kw_arm_apcscc, kw_arm_aapcscc, kw_arm_aapcs_vfpcc,
     kw_msp430_intrcc,
     kw_x86_stdcallcc, kw_x86_fastcallcc, kw_x86_thiscallcc,
     kw_arm_apcscc, kw_arm_aapcscc, kw_arm_aapcs_vfpcc,
     kw_msp430_intrcc,
+    kw_ptx_kernel, kw_ptx_device,
 
     kw_signext,
     kw_zeroext,
 
     kw_signext,
     kw_zeroext,
index 9d7e34434e2eb79d762b72a0b089f2ca0186a1a9..d38abf1a3c902c9127072581892dd7b640131329 100644 (file)
@@ -32,6 +32,7 @@ const char *PTXTargetLowering::getTargetNodeName(unsigned Opcode) const {
   switch (Opcode) {
     default:           llvm_unreachable("Unknown opcode");
     case PTXISD::EXIT: return "PTXISD::EXIT";
   switch (Opcode) {
     default:           llvm_unreachable("Unknown opcode");
     case PTXISD::EXIT: return "PTXISD::EXIT";
+    case PTXISD::RET:  return "PTXISD::RET";
   }
 }
 
   }
 }
 
@@ -58,5 +59,25 @@ SDValue PTXTargetLowering::
               const SmallVectorImpl<SDValue> &OutVals,
               DebugLoc dl,
               SelectionDAG &DAG) const {
               const SmallVectorImpl<SDValue> &OutVals,
               DebugLoc dl,
               SelectionDAG &DAG) const {
-  return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain);
+  assert(!isVarArg && "PTX does not support var args.");
+
+  switch (CallConv) {
+    default:
+      llvm_unreachable("Unsupported calling convention.");
+    case CallingConv::PTX_Kernel:
+      assert(Outs.size() == 0 && "Kernel must return void.");
+      return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain);
+    case CallingConv::PTX_Device:
+      assert(Outs.size() <= 1 && "Can at most return one value.");
+      break;
+  }
+
+  // PTX_Device
+
+  if (Outs.size() == 0)
+    return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain);
+
+  // TODO: allocate return register
+  SDValue Flag;
+  return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain, Flag);
 }
 }
index d0978e76a8bc50472fb92675007dbd14630e71d4..68badf538cebde15413df4621c9df8ddc3e3acce 100644 (file)
@@ -24,7 +24,8 @@ class PTXTargetMachine;
 namespace PTXISD {
   enum NodeType {
     FIRST_NUMBER = ISD::BUILTIN_OP_END,
 namespace PTXISD {
   enum NodeType {
     FIRST_NUMBER = ISD::BUILTIN_OP_END,
-    EXIT
+    EXIT,
+    RET
   };
 } // namespace PTXISD
 
   };
 } // namespace PTXISD
 
index 758eff67ba2adea7974c6c4cbc79b444a9d0a5e8..3698c9dfc402f8d30ad4bd87ecd128392c231c5b 100644 (file)
@@ -23,6 +23,8 @@ include "PTXInstrFormats.td"
 
 def PTXexit
   : SDNode<"PTXISD::EXIT", SDTNone, [SDNPHasChain]>;
 
 def PTXexit
   : SDNode<"PTXISD::EXIT", SDTNone, [SDNPHasChain]>;
+def PTXret
+  : SDNode<"PTXISD::RET",  SDTNone, [SDNPHasChain]>;
 
 //===----------------------------------------------------------------------===//
 // Instructions
 
 //===----------------------------------------------------------------------===//
 // Instructions
@@ -30,4 +32,5 @@ def PTXexit
 
 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
   def EXIT : InstPTX<(outs), (ins), "exit", [(PTXexit)]>;
 
 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
   def EXIT : InstPTX<(outs), (ins), "exit", [(PTXexit)]>;
+  def RET  : InstPTX<(outs), (ins), "ret",  [(PTXret)]>;
 }
 }
index adba594e287a2126a986d938e50af2ef69ece85e..7a1b7dd4e84ad16de1e62073644968fb0c5c59c2 100644 (file)
@@ -1579,6 +1579,8 @@ void AssemblyWriter::printFunction(const Function *F) {
   case CallingConv::ARM_AAPCS:    Out << "arm_aapcscc "; break;
   case CallingConv::ARM_AAPCS_VFP:Out << "arm_aapcs_vfpcc "; break;
   case CallingConv::MSP430_INTR:  Out << "msp430_intrcc "; break;
   case CallingConv::ARM_AAPCS:    Out << "arm_aapcscc "; break;
   case CallingConv::ARM_AAPCS_VFP:Out << "arm_aapcs_vfpcc "; break;
   case CallingConv::MSP430_INTR:  Out << "msp430_intrcc "; break;
+  case CallingConv::PTX_Kernel:   Out << "ptx_kernel"; break;
+  case CallingConv::PTX_Device:   Out << "ptx_device"; break;
   default: Out << "cc" << F->getCallingConv() << " "; break;
   }
 
   default: Out << "cc" << F->getCallingConv() << " "; break;
   }
 
@@ -1847,6 +1849,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     case CallingConv::ARM_AAPCS:    Out << " arm_aapcscc "; break;
     case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
     case CallingConv::MSP430_INTR:  Out << " msp430_intrcc "; break;
     case CallingConv::ARM_AAPCS:    Out << " arm_aapcscc "; break;
     case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
     case CallingConv::MSP430_INTR:  Out << " msp430_intrcc "; break;
+    case CallingConv::PTX_Kernel:   Out << " ptx_kernel"; break;
+    case CallingConv::PTX_Device:   Out << " ptx_device"; break;
     default: Out << " cc" << CI->getCallingConv(); break;
     }
 
     default: Out << " cc" << CI->getCallingConv(); break;
     }
 
@@ -1901,6 +1905,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     case CallingConv::ARM_AAPCS:    Out << " arm_aapcscc "; break;
     case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
     case CallingConv::MSP430_INTR:  Out << " msp430_intrcc "; break;
     case CallingConv::ARM_AAPCS:    Out << " arm_aapcscc "; break;
     case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
     case CallingConv::MSP430_INTR:  Out << " msp430_intrcc "; break;
+    case CallingConv::PTX_Kernel:   Out << " ptx_kernel"; break;
+    case CallingConv::PTX_Device:   Out << " ptx_device"; break;
     default: Out << " cc" << II->getCallingConv(); break;
     }
 
     default: Out << " cc" << II->getCallingConv(); break;
     }
 
index e3ecc979bf128fb837668fcc5825ffc68a23dd0a..7216891c8270a8728715efaa07d5f569ca2f77d5 100644 (file)
@@ -685,6 +685,8 @@ void Verifier::visitFunction(Function &F) {
   case CallingConv::Cold:
   case CallingConv::X86_FastCall:
   case CallingConv::X86_ThisCall:
   case CallingConv::Cold:
   case CallingConv::X86_FastCall:
   case CallingConv::X86_ThisCall:
+  case CallingConv::PTX_Kernel:
+  case CallingConv::PTX_Device:
     Assert1(!F.isVarArg(),
             "Varargs functions must have C calling conventions!", &F);
     break;
     Assert1(!F.isVarArg(),
             "Varargs functions must have C calling conventions!", &F);
     break;
index e2b3857e369ef24b24e6ff6f00e12799ea005b5a..1fb297c74694a19ac1079f77aa28649c9a56071f 100644 (file)
@@ -1,6 +1,6 @@
 ; RUN: llc < %s -march=ptx | FileCheck %s
 
 ; RUN: llc < %s -march=ptx | FileCheck %s
 
-define void @t1() {
+define ptx_kernel void @t1() {
 ;CHECK: exit;
        ret void
 }
 ;CHECK: exit;
        ret void
 }
index 28ab2e3d7aaa8a17a9c15eb09e587987bb8331e0..23802f49afa9d6d5769cd003556e774fc652aba1 100644 (file)
@@ -49,6 +49,7 @@ syn keyword llvmKeyword hidden protected default
 syn keyword llvmKeyword except deplibs
 syn keyword llvmKeyword volatile fastcc coldcc cc ccc
 syn keyword llvmKeyword x86_stdcallcc x86_fastcallcc
 syn keyword llvmKeyword except deplibs
 syn keyword llvmKeyword volatile fastcc coldcc cc ccc
 syn keyword llvmKeyword x86_stdcallcc x86_fastcallcc
+syn keyword llvmKeyword ptx_kernel ptx_device
 syn keyword llvmKeyword signext zeroext inreg sret nounwind noreturn
 syn keyword llvmKeyword nocapture byval nest readnone readonly noalias
 syn keyword llvmKeyword inlinehint noinline alwaysinline optsize ssp sspreq
 syn keyword llvmKeyword signext zeroext inreg sret nounwind noreturn
 syn keyword llvmKeyword nocapture byval nest readnone readonly noalias
 syn keyword llvmKeyword inlinehint noinline alwaysinline optsize ssp sspreq