Index: include/llvm/ADT/Triple.h =================================================================== --- include/llvm/ADT/Triple.h (revision 164777) +++ include/llvm/ADT/Triple.h (working copy) @@ -65,7 +65,8 @@ nvptx, // NVPTX: 32-bit nvptx64, // NVPTX: 64-bit le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten) - amdil // amdil: amd IL + amdil, // amdil: amd IL + spir, // SPIR: standard portable IR for OpenCL }; enum VendorType { UnknownVendor, Index: include/llvm/CallingConv.h =================================================================== --- include/llvm/CallingConv.h (revision 164777) +++ include/llvm/CallingConv.h (working copy) @@ -94,7 +94,25 @@ /// MBLAZE_INTR - Calling convention used for MBlaze interrupt support /// routines (i.e. GCC's save_volatiles attribute). - MBLAZE_SVOL = 74 + MBLAZE_SVOL = 74, + + /// SPIRFNC - Calling convention for SPIR non-kernel device functions. + /// No lowering or expansion of arguments. + /// Structures are passed as a pointer to a struct with the byval attribute. + /// Functions can only call SPIRFNC and SPIRKRNL functions. + /// Functions can only have zero or one return values. + /// Variable arguments are not allowed, except for printf. + /// How arguments/return values are lowered are not specified. + /// Functions are only visible to the devices. + SPIRFNC = 75, + + /// SPIRKRNL - Calling convention for SPIR kernel functions. + /// Inherits the restrictions of SPIRFNC, except + /// Cannot have non-void return values. + /// Cannot have variable arguments. + /// Can also be called by the host. + /// Is externally visible. + SPIRKRNL = 76 }; } // End CallingConv namespace Index: lib/AsmParser/LLLexer.cpp =================================================================== --- lib/AsmParser/LLLexer.cpp (revision 164777) +++ lib/AsmParser/LLLexer.cpp (working copy) @@ -525,6 +525,8 @@ KEYWORD(msp430_intrcc); KEYWORD(ptx_kernel); KEYWORD(ptx_device); + KEYWORD(spirkrnl); + KEYWORD(spirfunc); KEYWORD(cc); KEYWORD(c); Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp (revision 164777) +++ lib/AsmParser/LLParser.cpp (working copy) @@ -1066,6 +1066,8 @@ /// ::= 'msp430_intrcc' /// ::= 'ptx_kernel' /// ::= 'ptx_device' +/// ::= 'spirfnc' +/// ::= 'spirkrnl' /// ::= 'cc' UINT /// bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { @@ -1083,6 +1085,8 @@ 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_spirkrnl: CC = CallingConv::SPIRKRNL; break; + case lltok::kw_spirfnc: CC = CallingConv::SPIRFNC; break; case lltok::kw_cc: { unsigned ArbitraryCC; Lex.Lex(); Index: lib/AsmParser/LLToken.h =================================================================== --- lib/AsmParser/LLToken.h (revision 164777) +++ lib/AsmParser/LLToken.h (working copy) @@ -81,6 +81,7 @@ kw_arm_apcscc, kw_arm_aapcscc, kw_arm_aapcs_vfpcc, kw_msp430_intrcc, kw_ptx_kernel, kw_ptx_device, + kw_spirkrnl, kw_spirfnc, kw_signext, kw_zeroext, Index: lib/Support/Triple.cpp =================================================================== --- lib/Support/Triple.cpp (revision 164777) +++ lib/Support/Triple.cpp (working copy) @@ -42,6 +42,7 @@ case nvptx64: return "nvptx64"; case le32: return "le32"; case amdil: return "amdil"; + case spir: return "spir"; } llvm_unreachable("Invalid ArchType!"); @@ -83,6 +84,7 @@ case nvptx64: return "nvptx"; case le32: return "le32"; case amdil: return "amdil"; + case spir: return "spir"; } } @@ -171,6 +173,7 @@ .Case("nvptx64", nvptx64) .Case("le32", le32) .Case("amdil", amdil) + .Case("spir", spir) .Default(UnknownArch); } @@ -202,6 +205,7 @@ .Case("nvptx", Triple::nvptx) .Case("nvptx64", Triple::nvptx64) .Case("amdil", Triple::amdil) + .Case("spir", Triple::spir) .Default(Triple::UnknownArch); } @@ -226,6 +230,7 @@ .Case("nvptx64", "nvptx64") .Case("le32", "le32") .Case("amdil", "amdil") + .Case("spir", "spir") .Default(NULL); } @@ -260,6 +265,7 @@ .Case("nvptx64", Triple::nvptx64) .Case("le32", Triple::le32) .Case("amdil", Triple::amdil) + .Case("spir", Triple::spir) .Default(Triple::UnknownArch); } @@ -670,6 +676,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { switch (Arch) { + case llvm::Triple::spir: case llvm::Triple::UnknownArch: return 0; @@ -726,6 +733,7 @@ break; case Triple::amdil: + case Triple::spir: case Triple::arm: case Triple::cellspu: case Triple::hexagon: @@ -772,6 +780,7 @@ T.setArch(UnknownArch); break; + case Triple::spir: case Triple::mips64: case Triple::mips64el: case Triple::nvptx64: Index: test/Other/spir_cc.ll =================================================================== --- test/Other/spir_cc.ll (revision 0) +++ test/Other/spir_cc.ll (working copy) @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s | llvm-dis > %t1.ll +; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll +; RUN: diff %t1.ll %t2.ll + +define spirfnc void @foo() { + ret void +} + +define spirkrnl void @bar() { + call spirfnc void @foo( ) + call spirkrnl void @bar( ) + ret void +}